001: /*
002: * TestTokenizerProperties.java: JUnit test for TokenizerProperties implementations
003: *
004: * Copyright (C) 2002 Heiko Blau
005: *
006: * This file belongs to the JTopas test suite.
007: * The JTopas test suite is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as published by the
009: * Free Software Foundation; either version 2.1 of the License, or (at your option)
010: * any later version.
011: *
012: * This software is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE.
015: * See the GNU Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License along
018: * with the JTopas test suite. If not, write to the
019: *
020: * Free Software Foundation, Inc.
021: * 59 Temple Place, Suite 330,
022: * Boston, MA 02111-1307
023: * USA
024: *
025: * or check the Internet: http://www.fsf.org
026: *
027: * The JTopas test suite uses the test framework JUnit by Kent Beck and Erich Gamma.
028: * You should have received a copy of their JUnit licence agreement along with
029: * the JTopas test suite.
030: *
031: * We do NOT provide the JUnit archive junit.jar nessecary to compile and run
032: * our tests, since we assume, that You either have it already or would like
033: * to get the current release Yourself.
034: * Please visit either:
035: * http://sourceforge.net/projects/junit
036: * or
037: * http://junit.org
038: * to obtain JUnit.
039: *
040: * Contact:
041: * email: heiko@susebox.de
042: */
043:
044: package de.susebox.jtopas;
045:
046: //-----------------------------------------------------------------------------
047: // Imports
048: //
049: import java.util.Iterator;
050:
051: import junit.framework.Test;
052: import junit.framework.TestCase;
053: import junit.framework.TestSuite;
054:
055: import de.susebox.TestUtilities;
056: import de.susebox.jtopas.spi.DataProvider;
057: import de.susebox.jtopas.spi.PatternHandler;
058:
059: //-----------------------------------------------------------------------------
060: // Class TestTokenizerProperties
061: //
062:
063: /**<p>
064: * This class tests the implementations of {@link TokenizerProperties}.
065: *</p>
066: *
067: * @see TokenizerProperties
068: * @see TokenizerPropertyListener
069: * @author Heiko Blau
070: */
071: public class TestTokenizerProperties extends TestCase implements
072: TokenizerPropertyListener {
073:
074: //---------------------------------------------------------------------------
075: // main method
076: //
077:
078: /**
079: * call this method to invoke the tests
080: */
081: public static void main(String[] args) {
082: String[] tests = { TestTokenizerProperties.class.getName() };
083:
084: TestUtilities.run(tests, args);
085: }
086:
087: //---------------------------------------------------------------------------
088: // suite method
089: //
090:
091: /**
092: * Implementation of the JUnit method <code>suite</code>. For each set of test
093: * properties one or more tests are instantiated.
094: *
095: * @return a test suite
096: */
097: public static Test suite() {
098: TestSuite suite = new TestSuite(TestTokenizerProperties.class
099: .getName());
100:
101: suite
102: .addTest(new TestTokenizerProperties(
103: "testAddingSequences"));
104: suite
105: .addTest(new TestTokenizerProperties(
106: "testAddingKeywords"));
107: suite.addTest(new TestTokenizerProperties(
108: "testGenericProperties"));
109: suite.addTest(new TestTokenizerProperties("testDataHandlers"));
110: return suite;
111: }
112:
113: //---------------------------------------------------------------------------
114: // Constructor
115: //
116:
117: /**
118: * Default constructor. Standard input {@link java.lang.System#in} is used
119: * to construct the input stream reader.
120: */
121: public TestTokenizerProperties(String test) {
122: super (test);
123: }
124:
125: //---------------------------------------------------------------------------
126: // Fixture setup and release
127: //
128:
129: /**
130: * Sets up the fixture, for example, open a network connection.
131: * This method is called before a test is executed.
132: */
133: protected void setUp() throws Exception {
134: _properties = new StandardTokenizerProperties();
135: _properties.addTokenizerPropertyListener(this );
136: }
137:
138: /**
139: * Tears down the fixture, for example, close a network connection.
140: * This method is called after a test is executed.
141: */
142: protected void tearDown() throws Exception {
143: _properties = null;
144: }
145:
146: //---------------------------------------------------------------------------
147: // test cases
148: //
149:
150: /**
151: * Checking the property handler faculties like {@link de.susebox.jtopas.spi.KeywordHandler}
152: * and {@link de.susebox.jtopas.spi.SequenceHandler}.
153: */
154: public void testDataHandlers() throws Throwable {
155: // add all the properties
156: for (int index = 0; index < _testProperties.length; ++index) {
157: TokenizerProperty prop = _testProperties[index];
158:
159: _properties.addProperty(prop);
160: switch (prop.getType()) {
161: case Token.KEYWORD:
162: assertTrue("Keyword not found: " + prop, _properties
163: .keywordExists(prop.getImages()[0]));
164: break;
165: case Token.STRING:
166: assertTrue("String not found: " + prop, _properties
167: .stringExists(prop.getImages()[0]));
168: break;
169: case Token.BLOCK_COMMENT:
170: assertTrue(
171: "Block comment not found: " + prop,
172: _properties
173: .blockCommentExists(prop.getImages()[0]));
174: break;
175: case Token.LINE_COMMENT:
176: assertTrue("Line comment not found: " + prop,
177: _properties
178: .lineCommentExists(prop.getImages()[0]));
179: break;
180: case Token.SPECIAL_SEQUENCE:
181: assertTrue("Special sequence not found: " + prop,
182: _properties.specialSequenceExists(prop
183: .getImages()[0]));
184: break;
185: case Token.PATTERN:
186: assertTrue("Pattern not found: " + prop, _properties
187: .patternExists(prop.getImages()[0]));
188: break;
189: }
190: }
191:
192: // check all non-pattern properties
193: de.susebox.jtopas.spi.KeywordHandler kh = (de.susebox.jtopas.spi.KeywordHandler) _properties;
194: de.susebox.jtopas.spi.SequenceHandler sh = (de.susebox.jtopas.spi.SequenceHandler) _properties;
195:
196: for (int index = 0; index < _testProperties.length; ++index) {
197: TokenizerProperty prop = _testProperties[index];
198:
199: if (prop.getType() == Token.PATTERN) {
200: continue;
201: }
202:
203: // all properties except pattern
204: String image = prop.getImages()[0];
205: TokenizerProperty isKeyword;
206: TokenizerProperty isSequence;
207: TokenizerProperty isPattern;
208:
209: _currDataLength = image.length();
210: System.arraycopy(image.toCharArray(), 0, _currData,
211: _currStartPos, _currDataLength);
212:
213: isKeyword = kh.isKeyword(new LocalDataProvider(this ));
214: isSequence = sh
215: .startsWithSequenceCommentOrString(new LocalDataProvider(
216: this ));
217:
218: switch (prop.getType()) {
219: case Token.KEYWORD:
220: assertTrue("Keyword not found: " + prop,
221: isKeyword != null);
222: assertTrue("Unexpectedly found sequence: " + prop,
223: isSequence == null);
224: assertTrue("Expected keyword: " + prop + ", found: "
225: + isKeyword, prop.equals(isKeyword));
226: break;
227: case Token.STRING:
228: case Token.BLOCK_COMMENT:
229: case Token.LINE_COMMENT:
230: case Token.SPECIAL_SEQUENCE:
231: assertTrue("Sequence not found: " + prop,
232: isSequence != null);
233: assertTrue("Unexpectedly found keyword: " + prop,
234: isKeyword == null);
235: assertTrue("Expected sequence: " + prop + ", found: "
236: + isSequence, prop.equals(isSequence));
237: break;
238: }
239:
240: _currStartPos += _currDataLength;
241: }
242:
243: // check all pattern properties
244: PatternHandler ph = (PatternHandler) _properties;
245: PatternHandler.Result result;
246:
247: _currStartPos = 0;
248: for (int index = 0; index < _patternMatchingStrings.length; ++index) {
249: String image = _patternMatchingStrings[index];
250: char[] complete = { ';' };
251:
252: _currDataLength = image.length();
253: System.arraycopy(image.toCharArray(), 0, _currData,
254: _currStartPos, _currDataLength);
255: result = ph.matches(new LocalDataProvider(this ));
256: assertTrue("Pattern matching failed for: " + image,
257: result != null);
258: assertTrue("Pattern matching returned wrong length: "
259: + result.getLengthOfMatch(), result
260: .getLengthOfMatch() == image.length());
261: System.arraycopy(complete, 0, _currData, _currStartPos
262: + _currDataLength, complete.length);
263: _currDataLength += complete.length;
264: result = ph.matches(new LocalDataProvider(this ));
265: assertTrue("Pattern matching failed for: " + image,
266: result != null);
267: assertTrue("Pattern matching returned wrong length: "
268: + result.getLengthOfMatch(), result
269: .getLengthOfMatch() == image.length());
270: _currStartPos += _currDataLength;
271: }
272: }
273:
274: /**
275: * Adding and removing of line and block comments and special sequences.
276: */
277: public void testAddingSequences() throws Throwable {
278: // adding sequences
279: _properties.addString("'", "'", "\\");
280: _properties.addString("\"", "\"", "\\");
281: _properties.addLineComment("rem", null, Flags.F_NO_CASE);
282: _properties.addBlockComment("/*", "*/");
283: _properties.addBlockComment("<!--", "-->");
284: _properties.addSpecialSequence("<<");
285: _properties.addSpecialSequence(">>");
286: _properties.addSpecialSequence(">>>");
287: _properties.addSpecialSequence("<H1>", null, Flags.F_NO_CASE);
288: _properties.addSpecialSequence("<H2>", null, Flags.F_NO_CASE);
289: _properties.addSpecialSequence("\u20AC", null, Flags.F_NO_CASE); // Euro sign
290: _properties.addSpecialSequence("\u20ACuro", null,
291: Flags.F_NO_CASE); // Euro
292: _properties.addSpecialSequence("\u00A3", null, Flags.F_NO_CASE); // GBP sign
293:
294: assertTrue("Couldn't find \"'\".", _properties
295: .stringExists("'"));
296: assertTrue("Couldn't find \"\"\".", _properties
297: .stringExists("\""));
298: assertTrue("Couldn't find \"rem\".", _properties
299: .lineCommentExists("rem"));
300: assertTrue("Couldn't find \"REM\".", _properties
301: .lineCommentExists("REM"));
302: assertTrue("Couldn't find \"Rem\".", _properties
303: .lineCommentExists("Rem"));
304: assertTrue("Couldn't find \"/*\".", _properties
305: .blockCommentExists("/*"));
306: assertTrue("Couldn't find \"<!--\".", _properties
307: .blockCommentExists("<!--"));
308: assertTrue("Couldn't find \"<<\".", _properties
309: .specialSequenceExists("<<"));
310: assertTrue("Couldn't find \">>\".", _properties
311: .specialSequenceExists(">>"));
312: assertTrue("Couldn't find \">>>\".", _properties
313: .specialSequenceExists(">>>"));
314: assertTrue("Couldn't find \"<H1>\".", _properties
315: .specialSequenceExists("<H1>"));
316: assertTrue("Couldn't find \"<h1>\".", _properties
317: .specialSequenceExists("<h1>"));
318: assertTrue("Couldn't find \"<H2>\".", _properties
319: .specialSequenceExists("<H2>"));
320: assertTrue("Couldn't find \"<h2>\".", _properties
321: .specialSequenceExists("<h2>"));
322: assertTrue("Couldn't find \"\u20AC\".", _properties
323: .specialSequenceExists("\u20AC"));
324: assertTrue("Couldn't find \"\u20ACuro\".", _properties
325: .specialSequenceExists("\u20ACuro"));
326: assertTrue("Couldn't find \"\u20ACURO\".", _properties
327: .specialSequenceExists("\u20ACURO"));
328: assertTrue("Couldn't find \"\u00A3\".", _properties
329: .specialSequenceExists("\u00A3"));
330:
331: // check for almost the same sequences
332: assertTrue("Unexpectedly found \"''\".", !_properties
333: .stringExists("''"));
334: assertTrue("Unexpectedly found \"\"\"\".", !_properties
335: .stringExists("\"\""));
336: assertTrue("Unexpectedly found \"re\".", !_properties
337: .lineCommentExists("re"));
338: assertTrue("Unexpectedly found \"RE\".", !_properties
339: .lineCommentExists("RE"));
340: assertTrue("Unexpectedly found \"Re\".", !_properties
341: .lineCommentExists("Re"));
342: assertTrue("Unexpectedly found \"*\".", !_properties
343: .blockCommentExists("*"));
344: assertTrue("Unexpectedly found \"<!-\".", !_properties
345: .blockCommentExists("<!-"));
346: assertTrue("Unexpectedly found \"<\".", !_properties
347: .specialSequenceExists("<"));
348: assertTrue("Unexpectedly found \">\".", !_properties
349: .specialSequenceExists(">"));
350: assertTrue("Unexpectedly found \">>>>\".", !_properties
351: .specialSequenceExists(">>>>"));
352: assertTrue("Unexpectedly found \"<H1\".", !_properties
353: .specialSequenceExists("<H1"));
354: assertTrue("Unexpectedly found \"h1>\".", !_properties
355: .specialSequenceExists("h1>"));
356: assertTrue("Unexpectedly found \"<H>\".", !_properties
357: .specialSequenceExists("<H>"));
358: assertTrue("Unexpectedly found \"<h2\".", !_properties
359: .specialSequenceExists("<h2"));
360: assertTrue("Unexpectedly found \"<<H>\".", !_properties
361: .specialSequenceExists("<<H>"));
362: assertTrue("Unexpectedly found \"<h2>>\".", !_properties
363: .specialSequenceExists("<h2>>"));
364: assertTrue("Unexpectedly found \"\u20ACur\".", !_properties
365: .specialSequenceExists("\u20ACur"));
366:
367: // check enumeration
368: Iterator iter;
369: int count;
370:
371: iter = _properties.getStrings();
372: count = 0;
373: while (iter.hasNext()) {
374: iter.next();
375: count++;
376: }
377: assertTrue("Expected 2 strings, got " + count, count == 2);
378:
379: iter = _properties.getLineComments();
380: count = 0;
381: while (iter.hasNext()) {
382: iter.next();
383: count++;
384: }
385: assertTrue("Expected 1 line comment, got " + count, count == 1);
386:
387: iter = _properties.getBlockComments();
388: count = 0;
389: while (iter.hasNext()) {
390: iter.next();
391: count++;
392: }
393: assertTrue("Expected 2 block comments, got " + count,
394: count == 2);
395:
396: iter = _properties.getSpecialSequences();
397: count = 0;
398: while (iter.hasNext()) {
399: iter.next();
400: count++;
401: }
402: assertTrue("Expected 8 special sequences, got " + count,
403: count == 8);
404:
405: // removing sequences
406: _properties.removeString("'");
407: assertTrue("Still found \"'\".", !_properties.stringExists("'"));
408:
409: _properties.removeString("\"");
410: assertTrue("Still found \"\"\".", !_properties
411: .stringExists("\""));
412:
413: _properties.removeLineComment("rem");
414: assertTrue("Still found \"rem\".", !_properties
415: .lineCommentExists("rem"));
416:
417: _properties.removeBlockComment("/*");
418: assertTrue("Still found \"/*\".", !_properties
419: .blockCommentExists("/*"));
420:
421: _properties.removeBlockComment("<!--");
422: assertTrue("Still found \"<!--\".", !_properties
423: .blockCommentExists("<!--"));
424:
425: _properties.removeSpecialSequence("<<");
426: assertTrue("Still found \"<<\".", !_properties
427: .specialSequenceExists("<<"));
428:
429: _properties.removeSpecialSequence(">>");
430: assertTrue("Still found \">>\".", !_properties
431: .specialSequenceExists(">>"));
432:
433: _properties.removeSpecialSequence(">>>");
434: assertTrue("Still found \">>>\".", !_properties
435: .specialSequenceExists(">>>"));
436:
437: _properties.removeSpecialSequence("<H1>");
438: assertTrue("Still found \"<H1>\".", !_properties
439: .specialSequenceExists("<H1>"));
440:
441: _properties.removeSpecialSequence("<H2>");
442: assertTrue("Still found \"<H2>\".", !_properties
443: .specialSequenceExists("<H2>"));
444:
445: _properties.removeSpecialSequence("\u20AC");
446: assertTrue("Still found \"\u20AC\".", !_properties
447: .specialSequenceExists("\u20AC"));
448:
449: _properties.removeSpecialSequence("\u20ACuro");
450: assertTrue("Still found \"\u20ACuro\".", !_properties
451: .specialSequenceExists("\u20ACuro"));
452:
453: _properties.removeSpecialSequence("\u00A3");
454: assertTrue("Still found \"\u00A3\".", !_properties
455: .specialSequenceExists("\u00A3"));
456:
457: // check enumeration
458: iter = _properties.getStrings();
459: assertTrue("Still contains strings.", !iter.hasNext());
460:
461: iter = _properties.getLineComments();
462: assertTrue("Still contains line comments.", !iter.hasNext());
463:
464: iter = _properties.getBlockComments();
465: assertTrue("Still contains block comments.", !iter.hasNext());
466:
467: iter = _properties.getSpecialSequences();
468: assertTrue("Still contains special sequences.", !iter.hasNext());
469: }
470:
471: /**
472: * This test adds a set of keywords, both case-sensitive and not, then tries
473: * to retrieve them, then removes them
474: */
475: public void testAddingKeywords() throws Throwable {
476: final String[] keywordsCase = { "if", "else", "elsif", "end",
477: "integ", "while", "loop", "case", "switch", "return",
478: "break" };
479: final String[] keywordsNoCase = { "char", "int", "class",
480: "interface", "integer" };
481:
482: // insert keywords
483: for (int index = 0; index < keywordsCase.length; ++index) {
484: _currEvent = null;
485: _properties.addKeyword(keywordsCase[index]);
486: assertTrue("No TokenizerPropertyEvent happened.",
487: _currEvent != null);
488: assertTrue(
489: "Wrong type of event: " + _currEvent.getType(),
490: _currEvent.getType() == TokenizerPropertyEvent.PROPERTY_ADDED);
491: assertTrue("Wrong property type: "
492: + _currEvent.getProperty().getType(), _currEvent
493: .getProperty().getType() == Token.KEYWORD);
494: assertTrue("Wrong property image: "
495: + _currEvent.getProperty().getImages()[0],
496: keywordsCase[index].equals(_currEvent.getProperty()
497: .getImages()[0]));
498: }
499: for (int index = 0; index < keywordsNoCase.length; ++index) {
500: _currEvent = null;
501: _properties.addKeyword(keywordsNoCase[index], null,
502: Flags.F_NO_CASE);
503: assertTrue("No TokenizerPropertyEvent happened.",
504: _currEvent != null);
505: assertTrue(
506: "Wrong type of event: " + _currEvent.getType(),
507: _currEvent.getType() == TokenizerPropertyEvent.PROPERTY_ADDED);
508: assertTrue("Wrong property type: "
509: + _currEvent.getProperty().getType(), _currEvent
510: .getProperty().getType() == Token.KEYWORD);
511: assertTrue("Wrong property image: "
512: + _currEvent.getProperty().getImages()[0],
513: keywordsNoCase[index].equalsIgnoreCase(_currEvent
514: .getProperty().getImages()[0]));
515: }
516:
517: // search keywords
518: for (int index = 0; index < keywordsCase.length; ++index) {
519: String keyword = keywordsCase[index];
520: assertTrue("Couldn't find \"" + keyword + "\".",
521: _properties.keywordExists(keyword));
522: assertTrue("Unexpectedly found \"" + keyword.toUpperCase()
523: + "\".", !_properties.keywordExists(keyword
524: .toUpperCase()));
525: }
526: for (int index = 0; index < keywordsNoCase.length; ++index) {
527: String keyword = keywordsNoCase[index];
528: assertTrue("Couldn't find \"" + keyword + "\".",
529: _properties.keywordExists(keyword));
530: assertTrue("Couldn't find \"" + keyword.toUpperCase()
531: + "\".", _properties.keywordExists(keyword
532: .toUpperCase()));
533: assertTrue("Couldn't find \"" + keyword.toLowerCase()
534: + "\".", _properties.keywordExists(keyword
535: .toLowerCase()));
536: }
537:
538: // check enumeration
539: Iterator iter = _properties.getKeywords();
540: int count = 0;
541:
542: while (iter.hasNext()) {
543: iter.next();
544: count++;
545: }
546: assertTrue("More / less keywords than expected: " + count,
547: count == keywordsCase.length + keywordsNoCase.length);
548:
549: // check removal
550: for (int index = 0; index < keywordsCase.length; ++index) {
551: _currEvent = null;
552: _properties.removeKeyword(keywordsCase[index]);
553: assertTrue("No TokenizerPropertyEvent happened.",
554: _currEvent != null);
555: assertTrue(
556: "Wrong type of event: " + _currEvent.getType(),
557: _currEvent.getType() == TokenizerPropertyEvent.PROPERTY_REMOVED);
558: assertTrue("Wrong property type: "
559: + _currEvent.getProperty().getType(), _currEvent
560: .getProperty().getType() == Token.KEYWORD);
561: assertTrue("Wrong property image: "
562: + _currEvent.getProperty().getImages()[0],
563: keywordsCase[index].equals(_currEvent.getProperty()
564: .getImages()[0]));
565: }
566: for (int index = 0; index < keywordsNoCase.length; ++index) {
567: _currEvent = null;
568: _properties.removeKeyword(keywordsNoCase[index]);
569: assertTrue("No TokenizerPropertyEvent happened.",
570: _currEvent != null);
571: assertTrue(
572: "Wrong type of event: " + _currEvent.getType(),
573: _currEvent.getType() == TokenizerPropertyEvent.PROPERTY_REMOVED);
574: assertTrue("Wrong property type: "
575: + _currEvent.getProperty().getType(), _currEvent
576: .getProperty().getType() == Token.KEYWORD);
577: assertTrue("Wrong property image: "
578: + _currEvent.getProperty().getImages()[0],
579: keywordsNoCase[index].equalsIgnoreCase(_currEvent
580: .getProperty().getImages()[0]));
581: }
582: }
583:
584: /**
585: * Testing generic methods.
586: */
587: public void testGenericProperties() throws Throwable {
588: // insert properties
589: _properties.setWhitespaces(" ");
590: assertTrue(
591: "Wrong type of event.",
592: _currEvent.getType() == TokenizerPropertyEvent.PROPERTY_MODIFIED);
593: assertTrue("Wrong property type in event.", _currEvent
594: .getProperty().getType() == Token.WHITESPACE);
595: assertTrue("Wrong property in event.", _currEvent.getProperty()
596: .getImages()[0].equals(" "));
597:
598: _currEvent = null;
599: _properties
600: .setSeparators(TokenizerProperties.DEFAULT_SEPARATORS);
601: assertTrue("Unexpected event happened.", _currEvent == null);
602:
603: for (int index = 0; index < _testProperties.length; ++index) {
604: TokenizerProperty prop = _testProperties[index];
605:
606: _currEvent = null;
607: _properties.addProperty(prop);
608: assertTrue("No event.", _currEvent != null);
609: assertTrue(
610: "Wrong type of event.",
611: _currEvent.getType() == TokenizerPropertyEvent.PROPERTY_ADDED);
612: assertTrue("Wrong property type in event.", _currEvent
613: .getProperty().getType() == prop.getType());
614: if ((prop.getFlags() & Flags.F_NO_CASE) != 0) {
615: assertTrue("Wrong property in event.", _currEvent
616: .getProperty().getImages()[0]
617: .equalsIgnoreCase(prop.getImages()[0]));
618: } else {
619: assertTrue("Wrong property in event.", _currEvent
620: .getProperty().getImages()[0].equals(prop
621: .getImages()[0]));
622: }
623: assertTrue("Wrong companion in event.", _currEvent
624: .getProperty().getCompanion() == prop
625: .getCompanion());
626: }
627:
628: // re-register properties
629: for (int index = 0; index < _testProperties.length; ++index) {
630: TokenizerProperty prop = _testProperties[index];
631:
632: _currEvent = null;
633: _properties.addProperty(prop);
634: assertTrue(
635: "Unexpected event while re-registering property.",
636: _currEvent == null);
637: }
638:
639: // test iterator
640: Iterator iter = _properties.getProperties();
641: int count = 0;
642:
643: while (iter.hasNext()) {
644: TokenizerProperty prop = (TokenizerProperty) iter.next();
645: int index = 0;
646:
647: count++;
648: System.out.println(prop);
649: while (index < _testProperties.length) {
650: // Note that the TokenizerProperties might modify the flags of a property !
651: // Thats why we cannot use equals here.
652: if (prop.getType() == _testProperties[index].getType()
653: && prop.getCompanion() == _testProperties[index]
654: .getCompanion()
655: && prop.getImages().length == _testProperties[index]
656: .getImages().length) {
657: int imageIndex = 0;
658: boolean noCase = _properties.isFlagSet(prop,
659: Flags.F_NO_CASE);
660:
661: while (imageIndex < prop.getImages().length) {
662: if (noCase
663: && !(prop.getImages()[imageIndex]
664: .equalsIgnoreCase(_testProperties[index]
665: .getImages()[imageIndex]))) {
666: break;
667: } else if (!noCase
668: && !(prop.getImages()[imageIndex]
669: .equals(_testProperties[index]
670: .getImages()[imageIndex]))) {
671: break;
672: }
673: imageIndex++;
674: }
675: if (imageIndex >= prop.getImages().length) {
676: break;
677: }
678: }
679: index++;
680: }
681: assertTrue("Unexpected property " + prop.toString() + ".",
682: index < _testProperties.length);
683: }
684: assertTrue("Too many / few properties: " + count
685: + ". Expected were " + _testProperties.length,
686: count == _testProperties.length);
687:
688: // check if all properties are present
689: for (int index = 0; index < _testProperties.length; ++index) {
690: TokenizerProperty prop = _testProperties[index];
691:
692: assertTrue("Could't find property: " + prop, _properties
693: .propertyExists(prop));
694: }
695:
696: // test removal of properties
697: iter = _properties.getProperties();
698: count = 0;
699: while (iter.hasNext()) {
700: TokenizerProperty prop = (TokenizerProperty) iter.next();
701:
702: count++;
703: System.out.println("Removing: " + prop);
704: _currEvent = null;
705: iter.remove();
706: assertTrue("No event.", _currEvent != null);
707: assertTrue(
708: "Wrong type of event.",
709: _currEvent.getType() == TokenizerPropertyEvent.PROPERTY_REMOVED);
710: assertTrue("Wrong property type in event.", _currEvent
711: .getProperty().getType() == prop.getType());
712: if ((prop.getFlags() & Flags.F_NO_CASE) != 0) {
713: assertTrue("Wrong property in event.", _currEvent
714: .getProperty().getImages()[0]
715: .equalsIgnoreCase(prop.getImages()[0]));
716: } else {
717: assertTrue("Wrong property in event.", _currEvent
718: .getProperty().getImages()[0].equals(prop
719: .getImages()[0]));
720: }
721: assertTrue("Wrong companion in event.", _currEvent
722: .getProperty().getCompanion() == prop
723: .getCompanion());
724: assertTrue("Property still exists: " + prop, !_properties
725: .propertyExists(prop));
726: }
727: assertTrue("Too many / few properties: " + count
728: + ". Expected were " + _testProperties.length,
729: count == _testProperties.length);
730:
731: // check if all properties have been removed
732: for (int index = 0; index < _testProperties.length; ++index) {
733: TokenizerProperty prop = _testProperties[index];
734:
735: assertTrue("Property still present: " + prop, !_properties
736: .propertyExists(prop));
737: }
738: }
739:
740: //---------------------------------------------------------------------------
741: // TokenizerPropertyListener implementation
742: //
743:
744: /**
745: * Event handler method. The given {@link TokenizerPropertyEvent} parameter
746: * contains the nessecary information about the property change.
747: *
748: * @param event the {@link TokenizerPropertyEvent} that describes the change
749: */
750: public void propertyChanged(TokenizerPropertyEvent event) {
751: _currEvent = event;
752: }
753:
754: //---------------------------------------------------------------------------
755: // DataProvider implementation
756: //
757:
758: /**
759: * A inner class is nessecary for the separate implementation of the
760: * {@link java.lang.Object#toString} method required as an addition to the
761: * {@link DataProvider} interface
762: */
763: private final class LocalDataProvider implements DataProvider {
764:
765: /**
766: * The constructor gets the constructing <code>TestTokenizerProperties</code>
767: * instanz
768: */
769: protected LocalDataProvider(TestTokenizerProperties parent) {
770: _parent = parent;
771: }
772:
773: /**
774: * See {@link de.susebox.jtopas.spi.DataProvider} for details.
775: *
776: * @return the character buffer to read data from
777: */
778: public char[] getData() {
779: return _parent._currData;
780: }
781:
782: /**
783: * See {@link de.susebox.jtopas.spi.DataProvider} for details.
784: *
785: * @return a copy of the valid data of this {@link DataProvider}
786: * @see #getData
787: */
788: public char[] getDataCopy() {
789: char[] dst = new char[_parent._currDataLength];
790:
791: System.arraycopy(_parent._currData, _parent._currStartPos,
792: dst, 0, _parent._currDataLength);
793: return dst;
794: }
795:
796: /**
797: * See {@link de.susebox.jtopas.spi.DataProvider} for details.
798: *
799: * @param testChar check this character
800: * @return <code>true</code> if the given character is a separator,
801: * <code>false</code> otherwise
802: */
803: public int getLength() {
804: return _parent._currDataLength;
805: }
806:
807: /**
808: * See {@link de.susebox.jtopas.spi.DataProvider} for details.
809: *
810: * @return index in the character array returned by {@link #getData}, where data starts
811: */
812: public int getStartPosition() {
813: return _parent._currStartPos;
814: }
815:
816: /**
817: * See {@link de.susebox.jtopas.spi.DataProvider} for details.
818: *
819: * @param index an index between 0 and {@link #getLength}
820: * @return the character at the given index
821: */
822: public char getCharAt(int index) {
823: return _parent._currData[_parent._currStartPos + index];
824: }
825:
826: /**
827: * The {@link de.susebox.jtopas.spi.DataProvider} interface requires a special
828: * implementation of the standard {@link java.lang.Object#toString} method.
829: *
830: * @return the currently available data as a string
831: */
832: public String toString() {
833: return new String(_parent._currData, _parent._currStartPos,
834: _parent._currDataLength);
835: }
836:
837: // members
838: private TestTokenizerProperties _parent;
839: }
840:
841: //---------------------------------------------------------------------------
842: // class members
843: //
844: static final Object _companion1 = new Object();
845: static final Object _companion2 = new Object();
846:
847: static final TokenizerProperty[] _testProperties = {
848: new TokenizerProperty(Token.KEYWORD, new String[] { "k1" },
849: null, Flags.F_NO_CASE),
850: new TokenizerProperty(Token.KEYWORD, new String[] { "k2" },
851: _companion1, Flags.F_NO_CASE),
852: new TokenizerProperty(Token.KEYWORD, new String[] { "k3" },
853: _companion2, Flags.F_NO_CASE),
854: new TokenizerProperty(Token.LINE_COMMENT,
855: new String[] { "//" }, null, 0, Flags.F_NO_CASE),
856: new TokenizerProperty(Token.LINE_COMMENT,
857: new String[] { "--" }, _companion1, 0,
858: Flags.F_NO_CASE),
859: new TokenizerProperty(Token.LINE_COMMENT,
860: new String[] { "#" }, _companion2, 0,
861: Flags.F_NO_CASE),
862: new TokenizerProperty(Token.LINE_COMMENT,
863: new String[] { "rem" }, null, Flags.F_NO_CASE),
864: new TokenizerProperty(Token.BLOCK_COMMENT, new String[] {
865: "/*", "*/" }, null, 0, Flags.F_NO_CASE),
866: new TokenizerProperty(Token.BLOCK_COMMENT, new String[] {
867: "/**", "*/" }, _companion1, 0, Flags.F_NO_CASE),
868: new TokenizerProperty(Token.BLOCK_COMMENT, new String[] {
869: "{", "}" }, _companion2, 0, Flags.F_NO_CASE),
870: new TokenizerProperty(Token.BLOCK_COMMENT, new String[] {
871: "[startBlockComment]", "[endBlockComment]" }, null,
872: Flags.F_NO_CASE),
873: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
874: new String[] { ":=" }, null, 0, Flags.F_NO_CASE),
875: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
876: new String[] { "<>" }, _companion1, 0,
877: Flags.F_NO_CASE),
878: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
879: new String[] { "!=" }, _companion2, 0,
880: Flags.F_NO_CASE),
881: new TokenizerProperty(Token.STRING, new String[] { "\"",
882: "\"", "\\" }, null, 0, Flags.F_NO_CASE),
883: new TokenizerProperty(Token.STRING, new String[] { "'",
884: "'", "\\" }, null, 0, Flags.F_NO_CASE),
885: new TokenizerProperty(Token.PATTERN,
886: new String[] { "[+\\-]?[0-9]+\\.?[0-9]*" },
887: _companion1, 0, Flags.F_NO_CASE),
888: new TokenizerProperty(Token.PATTERN,
889: new String[] { "[A-Z_][A-Z0-9_]*" }, _companion2,
890: Flags.F_NO_CASE),
891: new TokenizerProperty(Token.KEYWORD, new String[] { "if" },
892: new Object(), 0, Flags.F_NO_CASE),
893: new TokenizerProperty(Token.KEYWORD,
894: new String[] { "then" }, new Object(), 0,
895: Flags.F_NO_CASE),
896: new TokenizerProperty(Token.KEYWORD,
897: new String[] { "while" }, new Object(), 0,
898: Flags.F_NO_CASE),
899: new TokenizerProperty(Token.KEYWORD,
900: new String[] { "loop" }, new Object(), 0,
901: Flags.F_NO_CASE),
902: new TokenizerProperty(Token.KEYWORD,
903: new String[] { "class" }, new Object(), 0,
904: Flags.F_NO_CASE),
905: new TokenizerProperty(Token.KEYWORD,
906: new String[] { "interface" }, new Object(), 0,
907: Flags.F_NO_CASE),
908: new TokenizerProperty(Token.KEYWORD,
909: new String[] { "final" }, null, 0, Flags.F_NO_CASE),
910: new TokenizerProperty(Token.KEYWORD,
911: new String[] { "implements" }, null, 0,
912: Flags.F_NO_CASE),
913: new TokenizerProperty(Token.KEYWORD,
914: new String[] { "int" }, null, 0, Flags.F_NO_CASE),
915: new TokenizerProperty(Token.KEYWORD,
916: new String[] { "boolean" }, null, 0,
917: Flags.F_NO_CASE),
918: new TokenizerProperty(Token.KEYWORD,
919: new String[] { "void" }, null, 0, Flags.F_NO_CASE),
920: new TokenizerProperty(Token.KEYWORD, new String[] { "do" },
921: null, 0, Flags.F_NO_CASE),
922: new TokenizerProperty(Token.KEYWORD,
923: new String[] { "import" }, null, 0, Flags.F_NO_CASE),
924: new TokenizerProperty(Token.KEYWORD,
925: new String[] { "package" }, null, 0,
926: Flags.F_NO_CASE),
927: new TokenizerProperty(Token.KEYWORD,
928: new String[] { "static" }, null, 0, Flags.F_NO_CASE),
929: new TokenizerProperty(Token.KEYWORD, new String[] { "H1" },
930: null, Flags.F_NO_CASE),
931: new TokenizerProperty(Token.KEYWORD, new String[] { "H2" },
932: null, Flags.F_NO_CASE),
933: new TokenizerProperty(Token.KEYWORD, new String[] { "H3" },
934: null, Flags.F_NO_CASE),
935: new TokenizerProperty(Token.KEYWORD,
936: new String[] { "table" }, null, Flags.F_NO_CASE),
937: new TokenizerProperty(Token.KEYWORD,
938: new String[] { "span" }, null, Flags.F_NO_CASE),
939: new TokenizerProperty(Token.KEYWORD,
940: new String[] { "layer" }, null, Flags.F_NO_CASE),
941: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
942: new String[] { ">>>" }, new Object(), 0,
943: Flags.F_NO_CASE),
944: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
945: new String[] { ">>" }, null, 0, Flags.F_NO_CASE),
946: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
947: new String[] { "<<" }, new Object(), 0,
948: Flags.F_NO_CASE),
949: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
950: new String[] { "+=" }, null, 0, Flags.F_NO_CASE),
951: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
952: new String[] { "-=" }, new Object(), 0,
953: Flags.F_NO_CASE),
954: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
955: new String[] { "++" }, null, 0, Flags.F_NO_CASE),
956: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
957: new String[] { "+++" }, new Object(), 0,
958: Flags.F_NO_CASE),
959: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
960: new String[] { "*=" }, null, 0, Flags.F_NO_CASE),
961: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
962: new String[] { "**" }, null, 0, Flags.F_NO_CASE),
963: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
964: new String[] { "**=" }, null, 0, Flags.F_NO_CASE),
965: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
966: new String[] { "/=" }, null, 0, Flags.F_NO_CASE),
967: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
968: new String[] { "/" }, null, 0, Flags.F_NO_CASE),
969: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
970: new String[] { "+" }, null, 0, Flags.F_NO_CASE),
971: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
972: new String[] { "\u20AC" }, null, 0, Flags.F_NO_CASE), // Euro
973: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
974: new String[] { "@" }, null, 0, Flags.F_NO_CASE),
975: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
976: new String[] { "\u00C4" }, null, Flags.F_NO_CASE), // german ae letter
977: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
978: new String[] { "\u00D6" }, null, Flags.F_NO_CASE), // german oe letter
979: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
980: new String[] { "\u00DC" }, null, Flags.F_NO_CASE), // german ue letter
981: new TokenizerProperty(Token.SPECIAL_SEQUENCE,
982: new String[] { "\u00DF" }, null, Flags.F_NO_CASE) // german sz ligature
983: };
984:
985: static final String _patternMatchingStrings[] = { "1", "23.95",
986: "-10435.3394", "+2", "+34543", "+445.435345830", "003",
987: "0234.000023", "-0.0", "+0.0", "Gonzo", "kermit",
988: "Kermit2", "_myMuppet", "_9934abc", "_a_b_c_1_", "a__1",
989: "aA_123B_C", };
990:
991: //---------------------------------------------------------------------------
992: // Members
993: //
994: private TokenizerProperties _properties = null;
995: private TokenizerPropertyEvent _currEvent = null;
996: private char[] _currData = new char[8192];
997: private int _currStartPos = 0;
998: private int _currDataLength = 0;
999: }
|