public class RuleMatcherTest extends TestCase {

	public void testFind() {
		SrxDocument document = new SrxDocument();
		Rule rule = new Rule(true, "ab+", "ca+");
		String text = "abaabbcabcabcaa";
		RuleMatcher matcher = new RuleMatcher(document, rule, text);
		assertFalse(matcher.hitEnd());
		assertTrue(matcher.find());
		assertFalse(matcher.hitEnd());
		assertEquals(3, matcher.getStartPosition());
		assertEquals(6, matcher.getBreakPosition());
		assertEquals(8, matcher.getEndPosition());
		assertTrue(matcher.find());
		assertFalse(matcher.hitEnd());
		assertEquals(7, matcher.getStartPosition());
		assertEquals(9, matcher.getBreakPosition());
		assertEquals(11, matcher.getEndPosition());
		assertTrue(matcher.find());
		assertFalse(matcher.hitEnd());
		assertEquals(10, matcher.getStartPosition());
		assertEquals(12, matcher.getBreakPosition());
		assertEquals(15, matcher.getEndPosition());
		assertFalse(matcher.find());
		assertTrue(matcher.hitEnd());
		assertTrue(matcher.find(6));
		assertEquals(7, matcher.getStartPosition());
		assertEquals(9, matcher.getBreakPosition());
		assertEquals(11, matcher.getEndPosition());

	}
	
} public class SrxDocumentTest extends TestCase {

	public void testDocument() {
		SrxDocument document = new SrxDocument();

		LanguageRule languageRule1 = new LanguageRule("1");
		LanguageRule languageRule2 = new LanguageRule("2");
		LanguageRule languageRule3 = new LanguageRule("3");

		document.addLanguageMap("aaa", languageRule1);
		document.addLanguageMap("ab", languageRule2);
		document.addLanguageMap("a+", languageRule3);

		document.setCascade(true);

		List<LanguageRule> languageRuleList = document
				.getLanguageRuleList("aaa");
		assertEquals(2, languageRuleList.size());
		assertEquals(languageRule1, languageRuleList.get(0));
		assertEquals(languageRule3, languageRuleList.get(1));

		languageRuleList = document.getLanguageRuleList("xxx");
		assertEquals(0, languageRuleList.size());

		document.setCascade(false);

		languageRuleList = document.getLanguageRuleList("aaa");
		assertEquals(1, languageRuleList.size());
		assertEquals(languageRule1, languageRuleList.get(0));
	}

} public class SrxTextIteratorReaderTest extends AbstractSrxTextIteratorTest {

	private static final int BUFFER_SIZE = 60;
	
	private static final int MARGIN = 10;
	
	protected TextIterator getTextIterator(SrxDocument document,
			String languageCode, String text) {
		StringReader reader = new StringReader(text);
		Map<String, Object> parameterMap = new HashMap<String, Object>();
		parameterMap.put(SrxTextIterator.BUFFER_LENGTH_PARAMETER, BUFFER_SIZE);
		parameterMap.put(SrxTextIterator.MARGIN_PARAMETER, MARGIN);
		return new SrxTextIterator(document, languageCode, reader, parameterMap);
	}
	
} public class SrxTextIteratorStringTest extends AbstractSrxTextIteratorTest {
	
	protected TextIterator getTextIterator(SrxDocument document,
			String languageCode, String text) {
		return new SrxTextIterator(document, languageCode, text);
	}
	
	public static final String[] MAX_LOOKBEHIND_CONSTRUCT_LENGTH_RESULT = 
		new String[] {"XAAA.", "XBB.XC"};

	public static final SrxDocument MAX_LOOKBEHIND_CONSTRUCT_LENGTH_DOCUMENT = 
		createMaxLookbehindConstructLengthDocument();
	
	public static SrxDocument createMaxLookbehindConstructLengthDocument() {
		LanguageRule languageRule = new LanguageRule("");
		languageRule.addRule(new Rule(false, "XA+\\.", ""));
		languageRule.addRule(new Rule(false, "XB+\\.", ""));
		languageRule.addRule(new Rule(true, "\\.", ""));
		SrxDocument document = new SrxDocument();
		document.addLanguageMap(".*", languageRule);
		return document;
	}
	
	/**
	 * Test if setting 
	 * {@link SrxTextIterator#MAX_LOOKBEHIND_CONSTRUCT_LENGTH_PARAMETER} works.
	 */
	@Test
	public void testMaxLookbehindConstructLength() {
		Map<String, Object> parameterMap = new HashMap<String, Object>();
		parameterMap.put(SrxTextIterator.MAX_LOOKBEHIND_CONSTRUCT_LENGTH_PARAMETER, 2);
		
		String text = merge(MAX_LOOKBEHIND_CONSTRUCT_LENGTH_RESULT);
		TextIterator textIterator = 
			new SrxTextIterator(MAX_LOOKBEHIND_CONSTRUCT_LENGTH_DOCUMENT, 
					"", text, parameterMap);
		List<String> segmentList = segment(textIterator);
		String[] segmentArray = segmentList.toArray(new String[segmentList.size()]); 

		assertEquals(MAX_LOOKBEHIND_CONSTRUCT_LENGTH_RESULT, segmentArray);
	}
	
} public class SrxVersionTest extends TestCase {

	public static final String SRX_1_DOCUMENT_NAME = "net/loomchild/segment/res/test/example1.srx";
	public static final String SRX_2_DOCUMENT_NAME = "net/loomchild/segment/res/test/example2.srx";
	public static final String NO_SRX_DOCUMENT_NAME = "net/loomchild/segment/res/test/some.xml";
	public static final String SRX_NOVERSION_DOCUMENT_NAME = "net/loomchild/segment/res/test/invalid.srx";

	public void testGetSrxVersion() {
		BufferedReader reader = new BufferedReader(
				getReader(getResourceStream(SRX_1_DOCUMENT_NAME)));
		SrxVersion version = SrxVersion.parse(reader);
		assertEquals(SrxVersion.VERSION_1_0, version);

		reader = new BufferedReader(
				getReader(getResourceStream(SRX_2_DOCUMENT_NAME)));
		version = SrxVersion.parse(reader);
		assertEquals(SrxVersion.VERSION_2_0, version);

		try {
			reader = new BufferedReader(
					getReader(getResourceStream(NO_SRX_DOCUMENT_NAME)));
			SrxVersion.parse(reader);
			fail("Recognized version of non SRX document.");
		} catch (XmlException e) {
			// OK
		}

		try {
			reader = new BufferedReader(
					getReader(getResourceStream(SRX_NOVERSION_DOCUMENT_NAME)));
			SrxVersion.parse(reader);
			fail("Recognized version of SRX document without version.");
		} catch (XmlException e) {
			// OK
		}
	}

} public class BufferTest {

	@Test
	public void testWorking() {
		Buffer charQueue = new Buffer(3);
		assertEquals(3, charQueue.getCapacity());
		assertEquals(0, charQueue.length());
		charQueue.forceEnqueue('a');
		charQueue.enqueue('b');
		assertEquals(2, charQueue.length());
		assertEquals('a', charQueue.charAt(0));
		assertEquals('b', charQueue.charAt(1));
		charQueue.enqueue('c');
		charQueue.dequeue();
		assertEquals('b', charQueue.charAt(0));
		charQueue.dequeue();
		assertEquals(1, charQueue.length());
		charQueue.enqueue('d');
		charQueue.enqueue('e');
		assertEquals(3, charQueue.length());
		assertEquals('c', charQueue.charAt(0));
		assertEquals('d', charQueue.charAt(1));
		assertEquals('e', charQueue.charAt(2));
		charQueue.dequeue();
		charQueue.forceEnqueue('f');
		charQueue.forceEnqueue('g');
		assertEquals(3, charQueue.length());
		assertEquals('e', charQueue.charAt(0));
		assertEquals('f', charQueue.charAt(1));
		assertEquals('g', charQueue.charAt(2));
	}

	@Test(expected = IllegalStateException.class)
	public void testOverflow() {
		Buffer charQueue = new Buffer(3);
		charQueue.enqueue('a');
		charQueue.enqueue('b');
		charQueue.enqueue('c');
		charQueue.enqueue('d');
	}

	@Test(expected = IllegalStateException.class)
	public void testUnderflow() {
		Buffer charQueue = new Buffer(3);
		charQueue.enqueue('a');
		charQueue.dequeue();
		charQueue.dequeue();
	}

	@Test(expected = IndexOutOfBoundsException.class)
	public void testIndexOutOfBounds() {
		Buffer charQueue = new Buffer(3);
		charQueue.enqueue('a');
		charQueue.charAt(2);
	}

} public class ReaderMatcherTest {

	private static final String REGEX_DATA = "abcde - fghijklmno pqrstuvw - x -";

	private static final Pattern REGEX = Pattern.compile(" - ");

	@Test
	public void testSimple() {
		StringReader reader = new StringReader(REGEX_DATA);
		CharSequence text = new ReaderCharSequence(reader);
		ReaderMatcher matcher = new ReaderMatcher(REGEX, text);
		boolean found;
		found = matcher.find();
		assertTrue(found);
		assertEquals(5, matcher.start());
		found = matcher.find();
		assertTrue(found);
		assertEquals(27, matcher.start());
		found = matcher.find();
		assertFalse(found);
		assertTrue(matcher.hitEnd());
	}

	private static final Pattern REGEX_WHOLE = Pattern.compile(".*");

	@Test
	public void testWhole() {
		StringReader reader = new StringReader(REGEX_DATA);
		CharSequence text = new ReaderCharSequence(reader);
		ReaderMatcher matcher = new ReaderMatcher(REGEX_WHOLE, text);
		boolean found = matcher.find();
		assertTrue(found);
		assertEquals(REGEX_DATA, matcher.group());
	}

	private static final Pattern REGEX_ALTERNATIVE = Pattern.compile("b|bc");

	@Test
	public void testAlternative() {
		StringReader reader = new StringReader(REGEX_DATA);
		CharSequence text = new ReaderCharSequence(reader);
		ReaderMatcher matcher = new ReaderMatcher(REGEX_ALTERNATIVE, text);
		boolean found = matcher.find();
		assertTrue(found);
		assertEquals(1, matcher.start());
		assertEquals(2, matcher.end());
		found = matcher.find();
		assertFalse(found);
	}

	private static final Pattern REGEX_LOOKING_AT = Pattern.compile("bcd");

	@Test
	public void testLookingAt() {
		StringReader reader = new StringReader(REGEX_DATA);
		CharSequence text = new ReaderCharSequence(reader);
		ReaderMatcher matcher = new ReaderMatcher(REGEX_LOOKING_AT, text);
		matcher.region(1, text.length());
		assertTrue(matcher.lookingAt());
		matcher.region(2, text.length());
		assertFalse(matcher.lookingAt());
	}

} public class UtilTest extends TestCase {

	public static final String QUOTED_PATTERN = "\\Q\\a\\Qaa\\\\Ebb\\Q\\E\\Qcc\\Edd";
	public static final String EXPECTED_UNQUOTED_PATTERN = "\\\\\\a\\\\\\Q\\a\\a\\\\bb\\c\\cdd";

	public void testRemoveBlockQuotes() {
		String unqotedPattern = Util.removeBlockQuotes(QUOTED_PATTERN);
		assertEquals(EXPECTED_UNQUOTED_PATTERN, unqotedPattern);
	}

	public static final String INFINITE_PATTERN = "a*b\\*\\\\+c+d\\+\\\\\\\\*e++f{1,4}+g{3,}+h{1}+\\Qa+\\E";
	public static final String EXPECTED_FINITE_PATTERN = "a{0,100}b\\*\\\\{1,100}c{1,100}d\\+\\\\\\\\{0,100}e{1,100}+f{1,4}+g{3,100}+h{1}+\\a\\+";

	public void testFinitize() {
		String finitePattern = Util.finitize(INFINITE_PATTERN, 100);
		assertEquals(EXPECTED_FINITE_PATTERN, finitePattern);
	}

	public static final String CAPTURING_GROUPS_PATTERN = "(aa)\\(bb\\\\(cc(dd))ee(?:ff)\\Q()\\E";
	public static final String EXPECTED_NONCAPTURING_GROUPS_PATTERN = "(?:aa)\\(bb\\\\(?:cc(?:dd))ee(?:ff)\\(\\)";

	public void testRemoveCapturingGroups() {
		String noncapturingGroupsPattern = 
				Util.removeCapturingGroups(CAPTURING_GROUPS_PATTERN);
		assertEquals(EXPECTED_NONCAPTURING_GROUPS_PATTERN,
				noncapturingGroupsPattern);
	}
	
} public class LanguageMapTest extends TestCase {

	public void testMatches() {
		LanguageMap map = new LanguageMap("PL.*", null);
		assertTrue(map.matches("PL_pl"));
		assertFalse(map.matches("EN_us"));
	}

} public class TextManagerTest {

	@Test
	public void testCharSequence() {
		TextManager manager = new TextManager("text");
		assertEquals("text", manager.getText().toString());
		assertEquals(4, manager.getBufferLength());
		assertEquals(false, manager.hasMoreText());
	}
	
	@Test
	public void testEmptyString() {
		TextManager manager = new TextManager("");
		assertEquals("", manager.getText().toString());
		assertEquals(0, manager.getBufferLength());
		assertEquals(false, manager.hasMoreText());
	}

	@Test(expected=IllegalStateException.class)
	public void testCannotReadCharSequence() {
		TextManager manager = new TextManager("text");
		manager.readText(1);
	}
	
	@Test
	public void testReader() {
		
		StringReader reader = new StringReader("text");
		TextManager manager = new TextManager(reader, 2);
		assertEquals(2, manager.getBufferLength());

		assertEquals("te", manager.getText().toString());
		assertEquals(true, manager.hasMoreText());		

		manager.readText(1);
		assertEquals("ex", manager.getText().toString());
		assertEquals(true, manager.hasMoreText());		

		manager.readText(1);
		assertEquals("xt", manager.getText().toString());
		assertEquals(false, manager.hasMoreText());		

	}
	
	@Test
	public void testEmptyReader() {
		StringReader reader = new StringReader("");
		TextManager manager = new TextManager(reader, 2);
		assertEquals("", manager.getText().toString());
		assertEquals(2, manager.getBufferLength());
		assertEquals(false, manager.hasMoreText());
	}

	@Test(expected=IllegalArgumentException.class)
	public void testBufferZeroLength() {
		StringReader reader = new StringReader("");
		new TextManager(reader, 0);
	}

} public class SrxParsersTest {
	
	private static final SrxParser ONE = new Srx1Parser();
	private static final SrxParser TWO = new Srx2Parser();
	private static final SrxParser ANY = new SrxAnyParser();
	private static final SrxParser SAX = new Srx2SaxParser();
	private static final SrxParser STAX = new Srx2StaxParser();
	

	@Test
	public void testSrx1One() {
		testSrx1(ONE);
	}

	@Test
	public void testSrx1Any() {
		testSrx1(ANY);
	}
	
	@Test
	public void testSrx1Compare() {
		testCompare(SRX_1_DOCUMENT_NAME, new SrxParser[] {ONE, ANY});
	}

	private static final String SRX_1_DOCUMENT_NAME = "net/loomchild/segment/res/test/example1.srx";

	private void testSrx1(SrxParser parser) {
		Reader reader = getReader(getResourceStream(SRX_1_DOCUMENT_NAME));

		SrxDocument document = parser.parse(reader);

		assertFalse(document.getCascade());

		List<LanguageRule> languageRuleList = document
				.getLanguageRuleList("en");
		assertEquals(1, languageRuleList.size());

		LanguageRule languageRule = languageRuleList.get(0);
		assertEquals("Default", languageRule.getName());

		List<Rule> ruleList = languageRule.getRuleList();
		assertEquals(5, ruleList.size());

		Rule rule = ruleList.get(1);
		assertEquals("[Ee][Tt][Cc]\\.", rule.getBeforePattern());
		assertEquals("\\s[a-z]", rule.getAfterPattern());
	}
	
	
	@Test
	public void testSrx2Two() {
		testSrx2(TWO);
	}

	@Test
	public void testSrx2Sax() {
		testSrx2(SAX);
	}

	@Test
	public void testSrx2Stax() {
		testSrx2(STAX);
	}

	@Test
	public void testSrx2Any() {
		testSrx2(ANY);
	}

	@Test
	public void testSrx2Compare() {
		testCompare(SRX_2_DOCUMENT_NAME, new SrxParser[] {TWO, SAX, STAX, ANY});
	}

	private static final String SRX_2_DOCUMENT_NAME = "net/loomchild/segment/res/test/example.srx";

	private void testSrx2(SrxParser parser) {
		Reader reader = getReader(getResourceStream(SRX_2_DOCUMENT_NAME));

		SrxDocument document = parser.parse(reader);

		assertTrue(document.getCascade());

		List<LanguageRule> languageRuleList = document
				.getLanguageRuleList("fr_FR");
		assertEquals(2, languageRuleList.size());

		LanguageRule languageRule = languageRuleList.get(0);
		assertEquals("French", languageRule.getName());

		List<Rule> ruleList = languageRule.getRuleList();
		assertEquals(4, ruleList.size());

		Rule rule0 = ruleList.get(0);
		assertEquals(" [Mm]lle\\.", rule0.getBeforePattern());
		assertEquals("\\s", rule0.getAfterPattern());

		Rule rule1 = ruleList.get(1);
		assertEquals("\\s[Mm]lles\\.", rule1.getBeforePattern());
		assertEquals("\\s", rule1.getAfterPattern());
	}


	@Test(expected = XmlException.class)
	public void testSrx2InvalidTwo() {
		testSrx2Invalid(TWO);
	}

	@Test(expected = XmlException.class)
	public void testSrx2InvalidSax() {
		testSrx2Invalid(SAX);
	}

	@Test(expected = XmlException.class)
	public void testSrx2InvalidAny() {
		testSrx2Invalid(ANY);
	}
		
	public static final String INVALID_DOCUMENT_NAME = "net/loomchild/segment/res/test/invalid.srx";

	private void testSrx2Invalid(SrxParser parser) {
	    Reader reader = getReader(getResourceStream(INVALID_DOCUMENT_NAME));
	    parser.parse(reader);
	}

	
	@Test
	public void testSrx2Ticket1Two() {
		testSrx2Ticket1(TWO);
	}

	@Test
	public void testSrx2Ticket1Sax() {
		testSrx2Ticket1(SAX);
	}

	@Test
	public void testSrx2Ticket1Stax() {
		testSrx2Ticket1(STAX);
	}

	@Test
	public void testSrx2Ticket1Any() {
		testSrx2Ticket1(ANY);
	}

	@Test
	public void testSrx2Ticket1Compare() {
		testCompare(TICKET_1_DOCUMENT_NAME, new SrxParser[] {TWO, SAX, STAX, ANY});
	}
	
	public static final String TICKET_1_DOCUMENT_NAME = "net/loomchild/segment/res/test/ticket1.srx";

	private void testSrx2Ticket1(SrxParser parser) {
	    Reader reader = getReader(getResourceStream(TICKET_1_DOCUMENT_NAME));

	    SrxDocument document = parser.parse(reader);

	    assertTrue(document.getCascade());

	    List<LanguageRule> languageRuleList = document
	    .getLanguageRuleList("en");
	    
	    LanguageRule languageRule = languageRuleList.get(0);
	    assertEquals("Default", languageRule.getName());

	    List<Rule> ruleList = languageRule.getRuleList();
	    assertEquals(1, ruleList.size());    

	    Rule rule = ruleList.get(0);
	    assertEquals("[\\.!?…]['»\"”\\)\\]\\}]?\\u0002?\\s", rule.getBeforePattern());
	    assertEquals("", rule.getAfterPattern());
	}
	
	
	public void testCompare(String documentName, SrxParser[] parsers) {
		SrxDocument previousDocument = null;
		for (SrxParser parser : parsers) {
		    Reader reader = getReader(getResourceStream(documentName));
		    SrxDocument document = parser.parse(reader);
		    
			if (previousDocument != null) {
				assertSrxDocumentEquals(previousDocument, document);
			}
			
			previousDocument = document;
		}
	}
	
	private void assertSrxDocumentEquals(SrxDocument leftDocument, SrxDocument rightDocument) {
		assertEquals(leftDocument.getCascade(), rightDocument.getCascade());
		
		List<LanguageMap> leftLanguageMapList = leftDocument.getLanguageMapList();
		List<LanguageMap> rightLanguageMapList = rightDocument.getLanguageMapList();
		assertEquals(leftLanguageMapList.size(), rightLanguageMapList.size());
		
		for (int i = 0; i < leftLanguageMapList.size(); ++i) {
			LanguageMap leftLanguageMap = leftLanguageMapList.get(i);
			LanguageMap rightLanguageMap = rightLanguageMapList.get(i);
			
			assertEquals(leftLanguageMap.getLanguagePattern().pattern(), 
					rightLanguageMap.getLanguagePattern().pattern());
			
			LanguageRule leftLanguageRule = leftLanguageMap.getLanguageRule();
			LanguageRule rightLanguageRule = rightLanguageMap.getLanguageRule();
			
			assertEquals(leftLanguageRule.getName(), rightLanguageRule.getName());
			
			List<Rule> leftRuleList = leftLanguageRule.getRuleList();
			List<Rule> rightRuleList = rightLanguageRule.getRuleList();
			
			assertEquals(leftRuleList.size(), rightRuleList.size());
			
			for (int k = 0; k < leftRuleList.size(); ++ k) {
				Rule leftRule = leftRuleList.get(k);
				Rule rightRule = rightRuleList.get(k);
				
				assertEquals(leftRule.isBreak(), rightRule.isBreak());
				assertEquals(leftRule.getBeforePattern(), rightRule.getBeforePattern());
				assertEquals(leftRule.getAfterPattern(), rightRule.getAfterPattern());
			}
			
		}
		
	}

} public class SrxTransformersTest extends TestCase {

	public static final String SRX_1_DOCUMENT_NAME = "net/loomchild/segment/res/test/example1.srx";

	public static final String SRX_2_DOCUMENT_NAME = "net/loomchild/segment/res/test/example2.srx";

	public static final String STYLESHEET = "net/loomchild/segment/res/xml/strip-space.xsl";

	private static final Templates templates = getTemplates(getReader(getResourceStream(STYLESHEET)));

	public void testSrx1Transformer() {
		SrxTransformer transformer = new Srx1Transformer();
		Map<String, Object> parameterMap = new HashMap<String, Object>();

		testTransformer(SRX_2_DOCUMENT_NAME, SRX_1_DOCUMENT_NAME, transformer,
				parameterMap);

		parameterMap.put(Srx1Transformer.MAP_RULE_NAME, (Object) "Default");
		testTransformer(SRX_2_DOCUMENT_NAME, SRX_1_DOCUMENT_NAME, transformer,
				parameterMap);
	}

	public void testSrx2Transformer() {
		SrxTransformer transformer = new Srx2Transformer();
		Map<String, Object> parameterMap = new HashMap<String, Object>();

		testTransformer(SRX_2_DOCUMENT_NAME, SRX_2_DOCUMENT_NAME, transformer,
				parameterMap);
	}

	private void testTransformer(String expectedDocumentName,
			String sourceDocumentName, SrxTransformer transformer,
			Map<String, Object> parameterMap) {

		Reader reader = getReader(getResourceStream(expectedDocumentName));
		String expectedDocument = removeWhitespaces(reader);

		reader = getReader(getResourceStream(sourceDocumentName));
		reader = transformer.transform(reader, parameterMap);
		String actualDocument = removeWhitespaces(reader);
		assertEquals(expectedDocument, actualDocument);

		reader = getReader(getResourceStream(sourceDocumentName));
		Writer writer = new StringWriter();
		transformer.transform(reader, writer, parameterMap);
		reader = new StringReader(writer.toString());
		actualDocument = removeWhitespaces(reader);
		assertEquals(expectedDocument, actualDocument);

	}

	private String removeWhitespaces(Reader reader) {
		
		StringWriter writer = new StringWriter();
		transform(templates, reader, writer);

		// Java 1.5 requires this because transformation does not work properly.
		StringReader stringReader = new StringReader(writer.toString());
		StringBuilder builder = new StringBuilder();
		try {
			int i;
			while ((i = stringReader.read()) != -1) {
				char c = (char)i;
				if ((c != ' ' && c != '\t' && c != '\r' && c != '\n' && c != '\f')) {
					builder.append((char)c);
				}
			}
		} catch (IOException e) {
			throw new IORuntimeException(e);
		}
		
		return builder.toString();
	}
	
} public class AccurateSrxTextIteratorStringTest extends AbstractSrxTextIteratorTest {
	
	protected TextIterator getTextIterator(SrxDocument document,
			String languageCode, String text) {
		return new AccurateSrxTextIterator(document, languageCode, text);
	}
} public class FastTextIteratorReaderTest extends AbstractSrxTextIteratorTest {

	private static final int BUFFER_SIZE = 60;
	
	protected TextIterator getTextIterator(SrxDocument document,
			String languageCode, String text) {
		StringReader reader = new StringReader(text);
		CharSequence charSequence = new ReaderCharSequence(reader, BUFFER_SIZE);
		return new FastTextIterator(document, languageCode, charSequence);
	}
	
	@Ignore
	@Test
	public void testOverlappingBreakRules() {
	}

} public class FastTextIteratorStringTest extends AbstractSrxTextIteratorTest {

	protected TextIterator getTextIterator(SrxDocument document,
			String languageCode, String text) {
		return new FastTextIterator(document, languageCode, text);
	}
	
	@Ignore
	@Test
	public void testOverlappingBreakRules() {
	}

} public class ReaderCharSequenceTest {

	private static final String DATA = "abcde";

	private ReaderCharSequence sequence;

	@Before
	public void setUp() {
		StringReader reader = new StringReader(DATA);
		this.sequence = new ReaderCharSequence(reader, 3, DATA.length());
	}

	@Test
	public void testWorking() {
		assertEquals(5, sequence.length());
		assertEquals('a', sequence.charAt(0));
		assertEquals('b', sequence.charAt(1));
		assertEquals('c', sequence.charAt(2));
		assertEquals('d', sequence.charAt(3));
		assertEquals("cde", sequence.subSequence(2, 5).toString());
		assertEquals('e', sequence.charAt(4));
		assertEquals("de", sequence.subSequence(3, 5).toString());
		assertEquals('d', sequence.charAt(3));
	}

	public void testZeroLengthSubsequence() {
		assertEquals(0, sequence.subSequence(1, 1).length());
	}

	@Test(expected = IllegalStateException.class)
	public void testSubsequenceLongerThanBuffer() {
		assertEquals("abcde", sequence.subSequence(0, 5).toString());
	}

	@Test(expected = IllegalStateException.class)
	public void testReadBack() {
		sequence.charAt(4);
		sequence.charAt(0);
	}

	@Test(expected = IllegalStateException.class)
	public void testWindowTooNarrow() {
		sequence.subSequence(0, 5);
	}

	@Test(expected = IndexOutOfBoundsException.class)
	public void testIndexPastEnd() {
		sequence.charAt(5);
	}

	@Test(expected = IndexOutOfBoundsException.class)
	public void testIndexNegative() {
		sequence.charAt(-1);
	}

	@Test(expected = IndexOutOfBoundsException.class)
	public void testEndBeforeStart() {
		sequence.subSequence(2, 1);
	}

	@Test(expected = IndexOutOfBoundsException.class)
	public void testStartNegative() {
		sequence.subSequence(-1, 1);
	}

	@Test(expected = IndexOutOfBoundsException.class)
	public void testEndPastEnd() {
		sequence.subSequence(1, 6);
	}

	@Test
	public void testInfiniteStream() {
		StringReader reader = new StringReader(DATA);
		ReaderCharSequence infiniteSequence = new ReaderCharSequence(
				reader, 3, ReaderCharSequence.INFINITE_LENGTH, 2);
		assertEquals('c', infiniteSequence.charAt(2));
		assertEquals('e', infiniteSequence.charAt(4));
		assertEquals(5, infiniteSequence.length());
		try {
			infiniteSequence.charAt(5);
			fail();
		} catch (IndexOutOfBoundsException e) {
			
		}
	}

	@Test
	public void testAllSubsequence() {
		StringReader reader = new StringReader(DATA);
		ReaderCharSequence infiniteSequence = new ReaderCharSequence(
				reader, 5, ReaderCharSequence.INFINITE_LENGTH, 2);
		CharSequence subsequence = 
			infiniteSequence.subSequence(0, infiniteSequence.length()); 
		assertEquals(DATA, subsequence.toString());
	}

	@Test
	public void testIterate() {
		StringReader reader = new StringReader(DATA);
		ReaderCharSequence infiniteSequence = new ReaderCharSequence(reader, 3);
		for (int i = 0; i < infiniteSequence.length(); ++i) {
			assertEquals(DATA.charAt(i), infiniteSequence.charAt(i));
		}
	}

}
import net.loomchild.segment.srx.RuleMatcherTest;
import net.loomchild.segment.srx.SrxDocumentTest;
import net.loomchild.segment.srx.SrxTextIteratorReaderTest;
import net.loomchild.segment.srx.SrxTextIteratorStringTest;
import net.loomchild.segment.srx.io.SrxVersionTest;
import net.loomchild.segment.srx.legacy.BufferTest;
import net.loomchild.segment.srx.legacy.ReaderMatcherTest;
import net.loomchild.segment.util.UtilTest;
import net.loomchild.segment.srx.LanguageMapTest;
import net.loomchild.segment.srx.TextManagerTest;
import net.loomchild.segment.srx.io.SrxParsersTest;
import net.loomchild.segment.srx.io.SrxTransformersTest;
import net.loomchild.segment.srx.legacy.AccurateSrxTextIteratorStringTest;
import net.loomchild.segment.srx.legacy.FastTextIteratorReaderTest;
import net.loomchild.segment.srx.legacy.FastTextIteratorStringTest;
import net.loomchild.segment.srx.legacy.ReaderCharSequenceTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
package net.loomchild.segment;




@RunWith(Suite.class)
@Suite.SuiteClasses({
	LanguageMapTest.class, 
	SrxDocumentTest.class,
	TextManagerTest.class,
	SrxVersionTest.class,
	SrxParsersTest.class, 
	SrxTransformersTest.class,
	UtilTest.class,
	SrxTextIteratorStringTest.class,
	SrxTextIteratorReaderTest.class,

	RuleMatcherTest.class,
	BufferTest.class,
	ReaderCharSequenceTest.class,
	ReaderMatcherTest.class,
	AccurateSrxTextIteratorStringTest.class,
	FastTextIteratorStringTest.class, 