]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_8_1_1/main/tests/core/src/com/ibm/icu/dev/test/rbbi/RBBITest.java
Added flags.
[Dictionary.git] / jars / icu4j-4_8_1_1 / main / tests / core / src / com / ibm / icu / dev / test / rbbi / RBBITest.java
1 /*
2  *******************************************************************************
3  * Copyright (C) 1996-2010, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7 package com.ibm.icu.dev.test.rbbi;
8  
9 //Regression testing of RuleBasedBreakIterator
10 //
11 //  TODO:  These tests should be mostly retired.
12 //          Much of the test data that was originally here was removed when the RBBI rules
13 //            were updated to match the Unicode boundary TRs, and the data was found to be invalid.
14 //          Much of the remaining data has been moved into the rbbitst.txt test data file,
15 //            which is common between ICU4C and ICU4J.  The remaining test data should also be moved,
16 //            or simply retired if it is no longer interesting.
17 import java.text.CharacterIterator;
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import com.ibm.icu.dev.test.TestFmwk;
22 import com.ibm.icu.text.BreakIterator;
23 import com.ibm.icu.text.DictionaryBasedBreakIterator;
24 import com.ibm.icu.text.RuleBasedBreakIterator;
25 import com.ibm.icu.util.ULocale;
26
27 public class RBBITest extends TestFmwk {  
28     
29     public static void main(String[] args) throws Exception {
30         new RBBITest().run(args);
31     }
32
33     public RBBITest() {
34     }
35   
36     private static final String halfNA = "\u0928\u094d\u200d"; /*
37                                                                 * halfform NA = devanigiri NA + virama(supresses
38                                                                 * inherent vowel)+ zero width joiner
39                                                                 */
40
41     // tests default rules based character iteration.
42     // Builds a new iterator from the source rules in the default (prebuilt) iterator.
43     //
44     public void TestDefaultRuleBasedCharacterIteration() {
45         RuleBasedBreakIterator rbbi = (RuleBasedBreakIterator) BreakIterator.getCharacterInstance();
46         logln("Testing the RBBI for character iteration by using default rules");
47
48         // fetch the rules used to create the above RuleBasedBreakIterator
49         String defaultRules = rbbi.toString();
50
51         RuleBasedBreakIterator charIterDefault = null;
52         try {
53             charIterDefault = new RuleBasedBreakIterator(defaultRules);
54         } catch (IllegalArgumentException iae) {
55             errln("ERROR: failed construction in TestDefaultRuleBasedCharacterIteration()" + iae.toString());
56         }
57
58         List<String> chardata = new ArrayList<String>();
59         chardata.add("H");
60         chardata.add("e");
61         chardata.add("l");
62         chardata.add("l");
63         chardata.add("o");
64         chardata.add("e\u0301"); // acuteE
65         chardata.add("&");
66         chardata.add("e\u0303"); // tildaE
67         // devanagiri characters for Hindi support
68         chardata.add("\u0906"); // devanagiri AA
69         // chardata.add("\u093e\u0901"); //devanagiri vowelsign AA+ chandrabindhu
70         chardata.add("\u0916\u0947"); // devanagiri KHA+vowelsign E
71         chardata.add("\u0938\u0941\u0902"); // devanagiri SA+vowelsign U + anusvara(bindu)
72         chardata.add("\u0926"); // devanagiri consonant DA
73         chardata.add("\u0930"); // devanagiri consonant RA
74         // chardata.add("\u0939\u094c"); //devanagiri HA+vowel sign AI
75         chardata.add("\u0964"); // devanagiri danda
76         // end hindi characters
77         chardata.add("A\u0302"); // circumflexA
78         chardata.add("i\u0301"); // acuteBelowI
79         // conjoining jamo...
80         chardata.add("\u1109\u1161\u11bc");
81         chardata.add("\u1112\u1161\u11bc");
82         chardata.add("\n");
83         chardata.add("\r\n"); // keep CRLF sequences together
84         chardata.add("S\u0300"); // graveS
85         chardata.add("i\u0301"); // acuteBelowI
86         chardata.add("!");
87
88         // What follows is a string of Korean characters (I found it in the Yellow Pages
89         // ad for the Korean Presbyterian Church of San Francisco, and I hope I transcribed
90         // it correctly), first as precomposed syllables, and then as conjoining jamo.
91         // Both sequences should be semantically identical and break the same way.
92         // precomposed syllables...
93         chardata.add("\uc0c1");
94         chardata.add("\ud56d");
95         chardata.add(" ");
96         chardata.add("\ud55c");
97         chardata.add("\uc778");
98         chardata.add(" ");
99         chardata.add("\uc5f0");
100         chardata.add("\ud569");
101         chardata.add(" ");
102         chardata.add("\uc7a5");
103         chardata.add("\ub85c");
104         chardata.add("\uad50");
105         chardata.add("\ud68c");
106         chardata.add(" ");
107         // conjoining jamo...
108         chardata.add("\u1109\u1161\u11bc");
109         chardata.add("\u1112\u1161\u11bc");
110         chardata.add(" ");
111         chardata.add("\u1112\u1161\u11ab");
112         chardata.add("\u110b\u1175\u11ab");
113         chardata.add(" ");
114         chardata.add("\u110b\u1167\u11ab");
115         chardata.add("\u1112\u1161\u11b8");
116         chardata.add(" ");
117         chardata.add("\u110c\u1161\u11bc");
118         chardata.add("\u1105\u1169");
119         chardata.add("\u1100\u116d");
120         chardata.add("\u1112\u116c");
121
122         generalIteratorTest(charIterDefault, chardata);
123
124     }
125
126     public void TestDefaultRuleBasedWordIteration() {
127         logln("Testing the RBBI for word iteration using default rules");
128         RuleBasedBreakIterator rbbi = (RuleBasedBreakIterator) BreakIterator.getWordInstance();
129         // fetch the rules used to create the above RuleBasedBreakIterator
130         String defaultRules = rbbi.toString();
131
132         RuleBasedBreakIterator wordIterDefault = null;
133         try {
134             wordIterDefault = new RuleBasedBreakIterator(defaultRules);
135         } catch (IllegalArgumentException iae) {
136             errln("ERROR: failed construction in TestDefaultRuleBasedWordIteration() -- custom rules" + iae.toString());
137         }
138
139         List<String> worddata = new ArrayList<String>();
140         worddata.add("Write");
141         worddata.add(" ");
142         worddata.add("wordrules");
143         worddata.add(".");
144         worddata.add(" ");
145         // worddata.add("alpha-beta-gamma");
146         worddata.add(" ");
147         worddata.add("\u092f\u0939");
148         worddata.add(" ");
149         worddata.add("\u0939\u093f" + halfNA + "\u0926\u0940");
150         worddata.add(" ");
151         worddata.add("\u0939\u0948");
152         // worddata.add("\u0964"); //danda followed by a space
153         worddata.add(" ");
154         worddata.add("\u0905\u093e\u092a");
155         worddata.add(" ");
156         worddata.add("\u0938\u093f\u0916\u094b\u0917\u0947");
157         worddata.add("?");
158         worddata.add(" ");
159         worddata.add("\r");
160         worddata.add("It's");
161         worddata.add(" ");
162         // worddata.add("$30.10");
163         worddata.add(" ");
164         worddata.add(" ");
165         worddata.add("Badges");
166         worddata.add("?");
167         worddata.add(" ");
168         worddata.add("BADGES");
169         worddata.add("!");
170         worddata.add("1000,233,456.000");
171         worddata.add(" ");
172
173         generalIteratorTest(wordIterDefault, worddata);
174     }
175
176 //    private static final String kParagraphSeparator = "\u2029";
177     private static final String kLineSeparator      = "\u2028";
178
179     public void TestDefaultRuleBasedSentenceIteration() {
180         logln("Testing the RBBI for sentence iteration using default rules");
181         RuleBasedBreakIterator rbbi = (RuleBasedBreakIterator) BreakIterator.getSentenceInstance();
182
183         // fetch the rules used to create the above RuleBasedBreakIterator
184         String defaultRules = rbbi.toString();
185         RuleBasedBreakIterator sentIterDefault = null;
186         try {
187             sentIterDefault = new RuleBasedBreakIterator(defaultRules);
188         } catch (IllegalArgumentException iae) {
189             errln("ERROR: failed construction in TestDefaultRuleBasedSentenceIteration()" + iae.toString());
190         }
191
192         List<String> sentdata = new ArrayList<String>();
193         sentdata.add("(This is it.) ");
194         sentdata.add("Testing the sentence iterator. ");
195         sentdata.add("\"This isn\'t it.\" ");
196         sentdata.add("Hi! ");
197         sentdata.add("This is a simple sample sentence. ");
198         sentdata.add("(This is it.) ");
199         sentdata.add("This is a simple sample sentence. ");
200         sentdata.add("\"This isn\'t it.\" ");
201         sentdata.add("Hi! ");
202         sentdata.add("This is a simple sample sentence. ");
203         sentdata.add("It does not have to make any sense as you can see. ");
204         sentdata.add("Nel mezzo del cammin di nostra vita, mi ritrovai in una selva oscura. ");
205         sentdata.add("Che la dritta via aveo smarrita. ");
206
207         generalIteratorTest(sentIterDefault, sentdata);
208     }
209
210     public void TestDefaultRuleBasedLineIteration() {
211         logln("Testing the RBBI for line iteration using default rules");
212         RuleBasedBreakIterator rbbi = (RuleBasedBreakIterator) RuleBasedBreakIterator.getLineInstance();
213         // fetch the rules used to create the above RuleBasedBreakIterator
214         String defaultRules = rbbi.toString();
215         RuleBasedBreakIterator lineIterDefault = null;
216         try {
217             lineIterDefault = new RuleBasedBreakIterator(defaultRules);
218         } catch (IllegalArgumentException iae) {
219             errln("ERROR: failed construction in TestDefaultRuleBasedLineIteration()" + iae.toString());
220         }
221
222         List<String> linedata = new ArrayList<String>();
223         linedata.add("Multi-");
224         linedata.add("Level ");
225         linedata.add("example ");
226         linedata.add("of ");
227         linedata.add("a ");
228         linedata.add("semi-");
229         linedata.add("idiotic ");
230         linedata.add("non-");
231         linedata.add("sensical ");
232         linedata.add("(non-");
233         linedata.add("important) ");
234         linedata.add("sentence. ");
235
236         linedata.add("Hi  ");
237         linedata.add("Hello ");
238         linedata.add("How\n");
239         linedata.add("are\r");
240         linedata.add("you" + kLineSeparator);
241         linedata.add("fine.\t");
242         linedata.add("good.  ");
243
244         linedata.add("Now\r");
245         linedata.add("is\n");
246         linedata.add("the\r\n");
247         linedata.add("time\n");
248         linedata.add("\r");
249         linedata.add("for\r");
250         linedata.add("\r");
251         linedata.add("all");
252
253         generalIteratorTest(lineIterDefault, linedata);
254
255     }
256  
257     // =========================================================================
258     // general test subroutines
259     // =========================================================================
260
261     private void generalIteratorTest(RuleBasedBreakIterator rbbi, List<String> expectedResult) {
262         StringBuffer buffer = new StringBuffer();
263         String text;
264         for (int i = 0; i < expectedResult.size(); i++) {
265             text = expectedResult.get(i);
266             buffer.append(text);
267         }
268         text = buffer.toString();
269         if (rbbi == null) {
270             errln("null iterator, test skipped.");
271             return;
272         }
273
274         rbbi.setText(text);
275
276         List<String> nextResults = _testFirstAndNext(rbbi, text);
277         List<String> previousResults = _testLastAndPrevious(rbbi, text);
278
279         logln("comparing forward and backward...");
280         int errs = getErrorCount();
281         compareFragmentLists("forward iteration", "backward iteration", nextResults, previousResults);
282         if (getErrorCount() == errs) {
283             logln("comparing expected and actual...");
284             compareFragmentLists("expected result", "actual result", expectedResult, nextResults);
285         }
286
287         int[] boundaries = new int[expectedResult.size() + 3];
288         boundaries[0] = RuleBasedBreakIterator.DONE;
289         boundaries[1] = 0;
290         for (int i = 0; i < expectedResult.size(); i++) {
291             boundaries[i + 2] = boundaries[i + 1] + (expectedResult.get(i).length());
292         }
293
294         boundaries[boundaries.length - 1] = RuleBasedBreakIterator.DONE;
295
296         _testFollowing(rbbi, text, boundaries);
297         _testPreceding(rbbi, text, boundaries);
298         _testIsBoundary(rbbi, text, boundaries);
299
300         doMultipleSelectionTest(rbbi, text);
301     }
302
303      private List<String> _testFirstAndNext(RuleBasedBreakIterator rbbi, String text) {
304          int p = rbbi.first();
305          int lastP = p;
306          List<String> result = new ArrayList<String>();
307
308          if (p != 0) {
309              errln("first() returned " + p + " instead of 0");
310          }
311
312          while (p != RuleBasedBreakIterator.DONE) {
313              p = rbbi.next();
314              if (p != RuleBasedBreakIterator.DONE) {
315                  if (p <= lastP) {
316                      errln("next() failed to move forward: next() on position "
317                                      + lastP + " yielded " + p);
318                  }
319                  result.add(text.substring(lastP, p));
320              }
321              else {
322                  if (lastP != text.length()) {
323                      errln("next() returned DONE prematurely: offset was "
324                                      + lastP + " instead of " + text.length());
325                  }
326              }
327              lastP = p;
328          }
329          return result;
330      }
331
332      private List<String> _testLastAndPrevious(RuleBasedBreakIterator rbbi, String text) {
333          int p = rbbi.last();
334          int lastP = p;
335          List<String> result = new ArrayList<String>();
336
337          if (p != text.length()) {
338              errln("last() returned " + p + " instead of " + text.length());
339          }
340
341          while (p != RuleBasedBreakIterator.DONE) {
342              p = rbbi.previous();
343              if (p != RuleBasedBreakIterator.DONE) {
344                  if (p >= lastP) {
345                      errln("previous() failed to move backward: previous() on position "
346                                      + lastP + " yielded " + p);
347                  }
348
349                  result.add(0, text.substring(p, lastP));
350              }
351              else {
352                  if (lastP != 0) {
353                      errln("previous() returned DONE prematurely: offset was "
354                                      + lastP + " instead of 0");
355                  }
356              }
357              lastP = p;
358          }
359          return result;
360      }
361
362      private void compareFragmentLists(String f1Name, String f2Name, List<String> f1, List<String> f2) {
363          int p1 = 0;
364          int p2 = 0;
365          String s1;
366          String s2;
367          int t1 = 0;
368          int t2 = 0;
369
370          while (p1 < f1.size() && p2 < f2.size()) {
371              s1 = f1.get(p1);
372              s2 = f2.get(p2);
373              t1 += s1.length();
374              t2 += s2.length();
375
376              if (s1.equals(s2)) {
377                  debugLogln("   >" + s1 + "<");
378                  ++p1;
379                  ++p2;
380              }
381              else {
382                  int tempT1 = t1;
383                  int tempT2 = t2;
384                  int tempP1 = p1;
385                  int tempP2 = p2;
386
387                  while (tempT1 != tempT2 && tempP1 < f1.size() && tempP2 < f2.size()) {
388                      while (tempT1 < tempT2 && tempP1 < f1.size()) {
389                          tempT1 += (f1.get(tempP1)).length();
390                          ++tempP1;
391                      }
392                      while (tempT2 < tempT1 && tempP2 < f2.size()) {
393                          tempT2 += (f2.get(tempP2)).length();
394                          ++tempP2;
395                      }
396                  }
397                  logln("*** " + f1Name + " has:");
398                  while (p1 <= tempP1 && p1 < f1.size()) {
399                      s1 = f1.get(p1);
400                      t1 += s1.length();
401                      debugLogln(" *** >" + s1 + "<");
402                      ++p1;
403                  }
404                  logln("***** " + f2Name + " has:");
405                  while (p2 <= tempP2 && p2 < f2.size()) {
406                      s2 = f2.get(p2);
407                      t2 += s2.length();
408                      debugLogln(" ***** >" + s2 + "<");
409                      ++p2;
410                  }
411                  errln("Discrepancy between " + f1Name + " and " + f2Name);
412              }
413          }
414      }
415
416     private void _testFollowing(RuleBasedBreakIterator rbbi, String text, int[] boundaries) {
417        logln("testFollowing():");
418        int p = 2;
419        for(int i = 0; i <= text.length(); i++) {
420            if (i == boundaries[p])
421                ++p;
422            int b = rbbi.following(i);
423            logln("rbbi.following(" + i + ") -> " + b);
424            if (b != boundaries[p])
425                errln("Wrong result from following() for " + i + ": expected " + boundaries[p]
426                                + ", got " + b);
427        }
428    }
429
430    private void _testPreceding(RuleBasedBreakIterator rbbi, String text, int[] boundaries) {
431        logln("testPreceding():");
432        int p = 0;
433        for(int i = 0; i <= text.length(); i++) {
434            int b = rbbi.preceding(i);
435            logln("rbbi.preceding(" + i + ") -> " + b);
436            if (b != boundaries[p])
437                errln("Wrong result from preceding() for " + i + ": expected " + boundaries[p]
438                               + ", got " + b);
439            if (i == boundaries[p + 1])
440                ++p;
441        }
442    }
443
444    private void _testIsBoundary(RuleBasedBreakIterator rbbi, String text, int[] boundaries) {
445        logln("testIsBoundary():");
446        int p = 1;
447        boolean isB;
448        for(int i = 0; i <= text.length(); i++) {
449            isB = rbbi.isBoundary(i);
450            logln("rbbi.isBoundary(" + i + ") -> " + isB);
451            if(i == boundaries[p]) {
452                if (!isB)
453                    errln("Wrong result from isBoundary() for " + i + ": expected true, got false");
454                ++p;
455            }
456            else {
457                if(isB)
458                    errln("Wrong result from isBoundary() for " + i + ": expected false, got true");
459            }
460        }
461    }
462    private void doMultipleSelectionTest(RuleBasedBreakIterator iterator, String testText)
463    {
464        logln("Multiple selection test...");
465        RuleBasedBreakIterator testIterator = (RuleBasedBreakIterator)iterator.clone();
466        int offset = iterator.first();
467        int testOffset;
468        int count = 0;
469
470        do {
471            testOffset = testIterator.first();
472            testOffset = testIterator.next(count);
473            logln("next(" + count + ") -> " + testOffset);
474            if (offset != testOffset)
475                errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
476
477            if (offset != RuleBasedBreakIterator.DONE) {
478                count++;
479                offset = iterator.next();
480            }
481        } while (offset != RuleBasedBreakIterator.DONE);
482
483        // now do it backwards...
484        offset = iterator.last();
485        count = 0;
486
487        do {
488            testOffset = testIterator.last();
489            testOffset = testIterator.next(count);
490            logln("next(" + count + ") -> " + testOffset);
491            if (offset != testOffset)
492                errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
493
494            if (offset != RuleBasedBreakIterator.DONE) {
495                count--;
496                offset = iterator.previous();
497            }
498        } while (offset != RuleBasedBreakIterator.DONE);
499    }
500
501    private void debugLogln(String s) {
502         final String zeros = "0000";
503         String temp;
504         StringBuffer out = new StringBuffer();
505         for (int i = 0; i < s.length(); i++) {
506             char c = s.charAt(i);
507             if (c >= ' ' && c < '\u007f')
508                 out.append(c);
509             else {
510                 out.append("\\u");
511                 temp = Integer.toHexString((int)c);
512                 out.append(zeros.substring(0, 4 - temp.length()));
513                 out.append(temp);
514             }
515         }
516          logln(out.toString());
517     }
518    
519    public void TestThaiDictionaryBreakIterator() {
520        int position;
521        int index;
522        int result[] = { 1, 2, 5, 10, 11, 12, 11, 10, 5, 2, 1, 0 };
523        char ctext[] = { 
524                0x0041, 0x0020,
525                0x0E01, 0x0E32, 0x0E23, 0x0E17, 0x0E14, 0x0E25, 0x0E2D, 0x0E07,
526                0x0020, 0x0041
527                };
528        String text = new String(ctext);
529        
530        ULocale locale = ULocale.createCanonical("th");
531        BreakIterator b = BreakIterator.getWordInstance(locale);
532        
533        b.setText(text);
534        
535        index = 0;
536        // Test forward iteration
537        while ((position = b.next())!= BreakIterator.DONE) {
538            if (position != result[index++]) {
539                errln("Error with ThaiDictionaryBreakIterator forward iteration test at " + position + ".\nShould have been " + result[index-1]);
540            }
541        }
542        
543        // Test backward iteration
544        while ((position = b.previous())!= BreakIterator.DONE) {
545            if (position != result[index++]) {
546                errln("Error with ThaiDictionaryBreakIterator backward iteration test at " + position + ".\nShould have been " + result[index-1]);
547            }
548        }
549        
550        //Test invalid sequence and spaces
551        char text2[] = {
552                0x0E01, 0x0E39, 0x0020, 0x0E01, 0x0E34, 0x0E19, 0x0E01, 0x0E38, 0x0E49, 0x0E07, 0x0020, 0x0E1B, 
553                0x0E34, 0x0E49, 0x0E48, 0x0E07, 0x0E2D, 0x0E22, 0x0E39, 0x0E48, 0x0E43, 0x0E19, 
554                0x0E16, 0x0E49, 0x0E33
555        };
556        int expectedWordResult[] = {
557                2, 3, 6, 10, 11, 15, 17, 20, 22
558        };
559        int expectedLineResult[] = {
560                3, 6, 11, 15, 17, 20, 22
561        };
562        BreakIterator brk = BreakIterator.getWordInstance(new ULocale("th"));
563        brk.setText(new String(text2));
564        position = index = 0;
565        while ((position = brk.next()) != BreakIterator.DONE && position < text2.length) {
566            if (position != expectedWordResult[index++]) {
567                errln("Incorrect break given by thai word break iterator. Expected: " + expectedWordResult[index-1] + " Got: " + position);
568            }
569        }
570       
571        brk = BreakIterator.getLineInstance(new ULocale("th"));
572        brk.setText(new String(text2));
573        position = index = 0;
574        while ((position = brk.next()) != BreakIterator.DONE && position < text2.length) {
575            if (position != expectedLineResult[index++]) {
576                errln("Incorrect break given by thai line break iterator. Expected: " + expectedLineResult[index-1] + " Got: " + position);
577            }
578        }
579        // Improve code coverage
580        if (brk.preceding(expectedLineResult[1]) != expectedLineResult[0]) {
581            errln("Incorrect preceding position.");
582        }
583        if (brk.following(expectedLineResult[1]) != expectedLineResult[2]) {
584            errln("Incorrect following position.");
585        }
586        int []fillInArray = new int[2];
587        if (((DictionaryBasedBreakIterator)brk).getRuleStatusVec(fillInArray) != 1 || fillInArray[0] != 0) {
588            errln("Error: Since getRuleStatusVec is not supported in DictionaryBasedBreakIterator, it should return 1 and fillInArray[0] == 0.");
589        }
590    }
591   
592     public void TestTailoredBreaks() {
593         class TBItem {
594             private int     type;
595             private ULocale locale;
596             private String  text;
597             private int[]   expectOffsets;
598             TBItem(int typ, ULocale loc, String txt, int[] eOffs) {
599                 type          = typ;
600                 locale        = loc;
601                 text          = txt;
602                 expectOffsets = eOffs;
603             }
604             private static final int maxOffsetCount = 128;
605             private boolean offsetsMatchExpected(int[] foundOffsets, int foundOffsetsLength) {
606                 if ( foundOffsetsLength != expectOffsets.length ) {
607                     return false;
608                 }
609                 for (int i = 0; i < foundOffsetsLength; i++) {
610                     if ( foundOffsets[i] != expectOffsets[i] ) {
611                         return false;
612                     }
613                 }
614                 return true;
615             }
616             private String formatOffsets(int[] offsets, int length) {
617                 StringBuffer buildString = new StringBuffer(4*maxOffsetCount);
618                 for (int i = 0; i < length; i++) {
619                     buildString.append(" " + offsets[i]);
620                 }
621                 return buildString.toString();
622             }
623             public void doTest() {
624                 BreakIterator brkIter;
625                 switch( type ) {
626                     case BreakIterator.KIND_CHARACTER: brkIter = BreakIterator.getCharacterInstance(locale); break;
627                     case BreakIterator.KIND_WORD:      brkIter = BreakIterator.getWordInstance(locale); break;
628                     case BreakIterator.KIND_LINE:      brkIter = BreakIterator.getLineInstance(locale); break;
629                     case BreakIterator.KIND_SENTENCE:  brkIter = BreakIterator.getSentenceInstance(locale); break;
630                     default: errln("Unsupported break iterator type " + type); return;
631                 }
632                 brkIter.setText(text);
633                 int[] foundOffsets = new int[maxOffsetCount];
634                 int offset, foundOffsetsCount = 0;
635                 // do forwards iteration test
636                 while ( foundOffsetsCount < maxOffsetCount && (offset = brkIter.next()) != BreakIterator.DONE ) {
637                     foundOffsets[foundOffsetsCount++] = offset;
638                 }
639                 if ( !offsetsMatchExpected(foundOffsets, foundOffsetsCount) ) {
640                     // log error for forwards test
641                     String textToDisplay = (text.length() <= 16)? text: text.substring(0,16);
642                     errln("For type " + type + " " + locale + ", text \"" + textToDisplay + "...\"" +
643                             "; expect " + expectOffsets.length + " offsets:" + formatOffsets(expectOffsets, expectOffsets.length) +
644                             "; found " + foundOffsetsCount + " offsets fwd:" + formatOffsets(foundOffsets, foundOffsetsCount) );
645                 } else {
646                     // do backwards iteration test
647                     --foundOffsetsCount; // back off one from the end offset
648                     while ( foundOffsetsCount > 0 ) {
649                         offset = brkIter.previous();
650                         if ( offset != foundOffsets[--foundOffsetsCount] ) {
651                             // log error for backwards test
652                             String textToDisplay = (text.length() <= 16)? text: text.substring(0,16);
653                             errln("For type " + type + " " + locale + ", text \"" + textToDisplay + "...\"" +
654                                     "; expect " + expectOffsets.length + " offsets:" + formatOffsets(expectOffsets, expectOffsets.length) +
655                                     "; found rev offset " + offset + " where expect " + foundOffsets[foundOffsetsCount] );
656                             break;
657                         }
658                     }
659                 }
660             }
661         }
662         // KIND_WORD "en_US_POSIX"
663         final String posxWordText     = "Can't have breaks in xx:yy or struct.field for CS-types.";
664         final int[]  posxWordTOffsets = { 5, 6, 10, 11, 17, 18, 20, 21, 23, 24, 26, 27, 29, 30, 36, 37, 42, 43, 46, 47, 49, 50, 55, 56 };
665         final int[]  posxWordROffsets = { 5, 6, 10, 11, 17, 18, 20, 21,         26, 27, 29, 30,         42, 43, 46, 47, 49, 50, 55, 56 };
666         // KIND_WORD "ja"
667         final String jaWordText     = "\u79C1\u9054\u306B\u4E00\u3007\u3007\u3007\u306E\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF" +
668                                       "\u304C\u3042\u308B\u3002\u5948\u3005\u306F\u30EF\u30FC\u30C9\u3067\u3042\u308B\u3002";
669         final int[]  jaWordTOffsets = {    2, 3,          7, 8, 14,         17, 18,     20, 21, 24,         27, 28 };
670         final int[]  jaWordROffsets = { 1, 2, 3, 4, 5, 6, 7, 8, 14, 15, 16, 17, 18, 19, 20, 21, 24, 25, 26, 27, 28 };
671         // KIND_SENTENCE "el"
672         final String elSentText     = "\u0391\u03B2, \u03B3\u03B4; \u0395 \u03B6\u03B7\u037E \u0398 \u03B9\u03BA. " +
673                                       "\u039B\u03BC \u03BD\u03BE! \u039F\u03C0, \u03A1\u03C2? \u03A3";
674         final int[]  elSentTOffsets = { 8, 14, 20, 27, 35, 36 };
675         final int[]  elSentROffsets = {        20, 27, 35, 36 };
676         // KIND_CHARACTER "th"
677         final String thCharText     = "\u0E01\u0E23\u0E30\u0E17\u0E48\u0E2D\u0E21\u0E23\u0E08\u0E19\u0E32 " +
678                                       "(\u0E2A\u0E38\u0E0A\u0E32\u0E15\u0E34-\u0E08\u0E38\u0E11\u0E32\u0E21\u0E32\u0E28) " +
679                                       "\u0E40\u0E14\u0E47\u0E01\u0E21\u0E35\u0E1B\u0E31\u0E0D\u0E2B\u0E32 ";
680         final int[]  thCharTOffsets = { 1, 2, 3, 5, 6, 7, 8, 9, 10, 11,
681                                         12, 13, 15, 16, 17, 19, 20, 22, 23, 24, 25, 26, 27, 28,
682                                         29, 30, 32, 33, 35, 37, 38, 39, 40, 41 };
683         final int[]  thCharROffsets = { 1,    3, 5, 6, 7, 8, 9,     11,
684                                         12, 13, 15,     17, 19, 20, 22,     24,     26, 27, 28,
685                                         29,     32, 33, 35, 37, 38,     40, 41 };
686         
687         final TBItem[] tests = {
688             new TBItem( BreakIterator.KIND_WORD,      new ULocale("en_US_POSIX"), posxWordText, posxWordTOffsets ),
689             new TBItem( BreakIterator.KIND_WORD,      ULocale.ROOT,               posxWordText, posxWordROffsets ),
690             new TBItem( BreakIterator.KIND_WORD,      new ULocale("ja"),          jaWordText,   jaWordTOffsets   ),
691             new TBItem( BreakIterator.KIND_WORD,      ULocale.ROOT,               jaWordText,   jaWordROffsets   ),
692             new TBItem( BreakIterator.KIND_SENTENCE,  new ULocale("el"),          elSentText,   elSentTOffsets   ),
693             new TBItem( BreakIterator.KIND_SENTENCE,  ULocale.ROOT,               elSentText,   elSentROffsets   ),
694             new TBItem( BreakIterator.KIND_CHARACTER, new ULocale("th"),          thCharText,   thCharTOffsets   ),
695             new TBItem( BreakIterator.KIND_CHARACTER, ULocale.ROOT,               thCharText,   thCharROffsets   ),
696         };
697         for (int iTest = 0; iTest < tests.length; iTest++) {
698             tests[iTest].doTest();
699         }
700     }
701
702     /* Tests the method public Object clone() */
703     public void TestClone() {
704         RuleBasedBreakIterator rbbi = new RuleBasedBreakIterator();
705         try {
706             rbbi.setText((CharacterIterator) null);
707             if (((RuleBasedBreakIterator) rbbi.clone()).getText() != null)
708                 errln("RuleBasedBreakIterator.clone() was suppose to return "
709                         + "the same object because fText is set to null.");
710         } catch (Exception e) {
711             errln("RuleBasedBreakIterator.clone() was not suppose to return " + "an exception.");
712         }
713     }
714
715     /*
716      * Tests the method public boolean equals(Object that)
717      */
718     public void TestEquals() {
719         RuleBasedBreakIterator rbbi = new RuleBasedBreakIterator("");
720         RuleBasedBreakIterator rbbi1 = new RuleBasedBreakIterator("");
721
722         // TODO: Tests when "if (fRData != other.fRData && (fRData == null || other.fRData == null))" is true
723
724         // Tests when "if (fText == null || other.fText == null)" is true
725         rbbi.setText((CharacterIterator) null);
726         if (rbbi.equals(rbbi1)) {
727             errln("RuleBasedBreakIterator.equals(Object) was not suppose to return "
728                     + "true when the other object has a null fText.");
729         }
730
731         // Tests when "if (fText == null && other.fText == null)" is true
732         rbbi1.setText((CharacterIterator) null);
733         if (!rbbi.equals(rbbi1)) {
734             errln("RuleBasedBreakIterator.equals(Object) was not suppose to return "
735                     + "false when both objects has a null fText.");
736         }
737
738         // Tests when an exception occurs
739         if (rbbi.equals(0)) {
740             errln("RuleBasedBreakIterator.equals(Object) was suppose to return " + "false when comparing to integer 0.");
741         }
742         if (rbbi.equals(0.0)) {
743             errln("RuleBasedBreakIterator.equals(Object) was suppose to return " + "false when comparing to float 0.0.");
744         }
745         if (rbbi.equals("0")) {
746             errln("RuleBasedBreakIterator.equals(Object) was suppose to return "
747                     + "false when comparing to string '0'.");
748         }
749     }
750
751     /*
752      * Tests the method public void dump()
753      */
754     public void TestDump() {
755         RuleBasedBreakIterator rbbi = new RuleBasedBreakIterator();
756         try {
757             rbbi.dump();
758             errln("RuleBasedBreakIterator.dump() was suppose to return "
759                     + "an exception for a blank RuleBasedBreakIterator object.");
760         } catch (Exception e) {
761         }
762     }
763     
764     /*
765      * Tests the method public int first()
766      */
767     public void TestFirst() {
768         RuleBasedBreakIterator rbbi = new RuleBasedBreakIterator("");
769         // Tests when "if (fText == null)" is true
770         rbbi.setText((CharacterIterator) null);
771         if (rbbi.first() != BreakIterator.DONE) {
772             errln("RuleBasedBreakIterator.first() was suppose to return "
773                     + "BreakIterator.DONE when the object has a null fText.");
774         }
775     }
776     
777     /*
778      * Tests the method public int last()
779      */
780     public void TestLast() {
781         RuleBasedBreakIterator rbbi = new RuleBasedBreakIterator("");
782         // Tests when "if (fText == null)" is true
783         rbbi.setText((CharacterIterator) null);
784         if (rbbi.last() != BreakIterator.DONE) {
785             errln("RuleBasedBreakIterator.last() was suppose to return "
786                     + "BreakIterator.DONE when the object has a null fText.");
787         }
788     }
789     
790     /*
791      * Tests the method public int following(int offset)
792      */
793     public void TestFollowing() {
794         RuleBasedBreakIterator rbbi = new RuleBasedBreakIterator("");
795         // Tests when "else if (offset < fText.getBeginIndex())" is true
796         rbbi.setText("dummy");
797         if (rbbi.following(-1) != 0) {
798             errln("RuleBasedBreakIterator.following(-1) was suppose to return "
799                     + "0 when the object has a fText of dummy.");
800         }
801     }
802     
803     /*
804      * Tests the method public int preceding(int offset)
805      */
806     public void TestPreceding() {
807         RuleBasedBreakIterator rbbi = new RuleBasedBreakIterator("");
808         // Tests when "if (fText == null || offset > fText.getEndIndex())" is true
809         rbbi.setText((CharacterIterator)null);
810         if (rbbi.preceding(-1) != BreakIterator.DONE) {
811             errln("RuleBasedBreakIterator.preceding(-1) was suppose to return "
812                     + "0 when the object has a fText of null.");
813         }
814         
815         // Tests when "else if (offset < fText.getBeginIndex())" is true
816         rbbi.setText("dummy");
817         if (rbbi.preceding(-1) != 0) {
818             errln("RuleBasedBreakIterator.preceding(-1) was suppose to return "
819                     + "0 when the object has a fText of dummy.");
820         }
821     }
822     
823     /* Tests the method public int current() */
824     public void TestCurrent(){
825         RuleBasedBreakIterator rbbi = new RuleBasedBreakIterator("");
826         // Tests when "(fText != null) ? fText.getIndex() : BreakIterator.DONE" is true and false
827         rbbi.setText((CharacterIterator)null);
828         if(rbbi.current() != BreakIterator.DONE){
829             errln("RuleBasedBreakIterator.current() was suppose to return "
830                     + "BreakIterator.DONE when the object has a fText of null.");
831         }
832         rbbi.setText("dummy");
833         if(rbbi.current() != 0){
834             errln("RuleBasedBreakIterator.current() was suppose to return "
835                     + "0 when the object has a fText of dummy.");
836         }
837     }
838 }