1 /*
  2  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 /**
 25  * @test
 26  * @bug 4533872 4640853
 27  * @library /java/text/testlib
 28  * @summary Unit tests for supplementary character support (JSR-204) and Unicode 4.0 support
 29  */
 30 
 31 import java.text.BreakIterator;
 32 import java.util.Locale;
 33 
 34 public class Bug4533872 extends IntlTest {
 35 
 36     public static void main(String[] args) throws Exception {
 37         new Bug4533872().run(args);
 38     }
 39 
 40     static final String[] given = {
 41       /* Lu Nd    Lu     Ll    */
 42         "XYZ12345 ABCDE  abcde",
 43       /* Nd Lo          Nd  Lu Po    Lu   Ll    */
 44         "123\uD800\uDC00345 ABC\uFF61XYZ  abc",
 45       /* Nd Lo          Nd  Lu Po          Lu   Ll    */
 46         "123\uD800\uDC00345 ABC\uD800\uDD00XYZ  abc",
 47       /* Lu Ll Cs    Ll Cs    Lu Lo          Lu  */
 48         "ABCabc\uDC00xyz\uD800ABC\uD800\uDC00XYZ",
 49     };
 50 
 51     // Golden data for TestNext(), TestBoundar() and TestPrintEach*ward()
 52     static final String[][] expected = {
 53         {"XYZ12345", " ", "ABCDE", "  ", "abcde"},
 54         {"123\uD800\uDC00345", " ", "ABC", "\uFF61", "XYZ", "  ", "abc"},
 55         {"123\uD800\uDC00345", " ", "ABC", "\uD800\uDD00", "XYZ", "  ", "abc"},
 56         {"ABCabc", "\uDC00", "xyz", "\uD800", "ABC\uD800\uDC00XYZ"},
 57     };
 58 
 59     BreakIterator iter;
 60     int start, end, current;
 61 
 62     /*
 63      * Test for next(int n)
 64      */
 65     void TestNext() {
 66         iter = BreakIterator.getWordInstance(Locale.US);
 67 
 68         for (int i = 0; i < given.length; i++) {
 69             iter.setText(given[i]);
 70             start = iter.first();
 71             int j = expected[i].length - 1;
 72             start = iter.next(j);
 73             end = iter.next();
 74 
 75             if (!expected[i][j].equals(given[i].substring(start, end))) {
 76                 errln("Word break failure: printEachForward() expected:<" +
 77                       expected[i][j] + ">, got:<" +
 78                       given[i].substring(start, end) +
 79                       "> start=" + start + "  end=" + end);
 80             }
 81         }
 82     }
 83 
 84     /*
 85      * Test for isBoundary(int n)
 86      */
 87     void TestIsBoundary() {
 88         iter = BreakIterator.getWordInstance(Locale.US);
 89 
 90         for (int i = 0; i < given.length; i++) {
 91             iter.setText(given[i]);
 92 
 93             start = iter.first();
 94             end = iter.next();
 95 
 96             while (end < given[i].length()) {
 97                 if (!iter.isBoundary(end)) {
 98                     errln("Word break failure: isBoundary() This should be a boundary. Index=" +
 99                           end + " for " + given[i]);
100                 }
101                 end = iter.next();
102             }
103         }
104     }
105 
106 
107     /*
108      * The followig test cases were made based on examples in BreakIterator's
109      * API Doc.
110      */
111 
112     /*
113      * Test mainly for next() and current()
114      */
115     void TestPrintEachForward() {
116         iter = BreakIterator.getWordInstance(Locale.US);
117 
118         for (int i = 0; i < given.length; i++) {
119             iter.setText(given[i]);
120             start = iter.first();
121 
122             // Check current()'s return value - should be same as first()'s.
123             current = iter.current();
124             if (start != current) {
125                 errln("Word break failure: printEachForward() Unexpected current value: current()=" +
126                       current + ", expected(=first())=" + start);
127             }
128 
129             int j = 0;
130             for (end = iter.next();
131                  end != BreakIterator.DONE;
132                  start = end, end = iter.next(), j++) {
133 
134                 // Check current()'s return value - should be same as next()'s.
135                 current = iter.current();
136                 if (end != current) {
137                     errln("Word break failure: printEachForward() Unexpected current value: current()=" +
138                           current + ", expected(=next())=" + end);
139                 }
140 
141                 if (!expected[i][j].equals(given[i].substring(start, end))) {
142                     errln("Word break failure: printEachForward() expected:<" +
143                           expected[i][j] + ">, got:<" +
144                           given[i].substring(start, end) +
145                           "> start=" + start + "  end=" + end);
146                 }
147             }
148         }
149     }
150 
151     /*
152      * Test mainly for previous() and current()
153      */
154     void TestPrintEachBackward() {
155         iter = BreakIterator.getWordInstance(Locale.US);
156 
157         for (int i = 0; i < given.length; i++) {
158             iter.setText(given[i]);
159             end = iter.last();
160 
161             // Check current()'s return value - should be same as last()'s.
162             current = iter.current();
163             if (end != current) {
164                 errln("Word break failure: printEachBackward() Unexpected current value: current()=" +
165                       current + ", expected(=last())=" + end);
166             }
167 
168             int j;
169             for (start = iter.previous(), j = expected[i].length-1;
170                  start != BreakIterator.DONE;
171                  end = start, start = iter.previous(), j--) {
172 
173                 // Check current()'s return value - should be same as previous()'s.
174                 current = iter.current();
175                 if (start != current) {
176                     errln("Word break failure: printEachBackward() Unexpected current value: current()=" +
177                           current + ", expected(=previous())=" + start);
178                 }
179 
180                 if (!expected[i][j].equals(given[i].substring(start, end))) {
181                     errln("Word break failure: printEachBackward() expected:<" +
182                           expected[i][j] + ">, got:<" +
183                           given[i].substring(start, end) +
184                           "> start=" + start + "  end=" + end);
185                 }
186             }
187         }
188     }
189 
190     /*
191      * Test mainly for following() and previous()
192      */
193     void TestPrintAt_1() {
194         iter = BreakIterator.getWordInstance(Locale.US);
195 
196         int[][] index = {
197             {2, 8, 10, 15, 17},
198             {1, 8, 10, 12, 15, 17, 20},
199             {3, 8, 10, 13, 16, 18, 20},
200             {4, 6,  9, 10, 16},
201         };
202 
203         for (int i = 0; i < given.length; i++) {
204             iter.setText(given[i]);
205             for (int j = index[i].length-1; j >= 0; j--) {
206                 end = iter.following(index[i][j]);
207                 start = iter.previous();
208 
209                 if (!expected[i][j].equals(given[i].substring(start, end))) {
210                     errln("Word break failure: printAt_1() expected:<" +
211                           expected[i][j] + ">, got:<" +
212                           given[i].substring(start, end) +
213                           "> start=" + start + "  end=" + end);
214                 }
215             }
216         }
217     }
218 
219     /*
220      * Test mainly for preceding() and next()
221      */
222     void TestPrintAt_2() {
223         iter = BreakIterator.getWordInstance(Locale.US);
224 
225         int[][] index = {
226             {2, 9, 10, 15, 17},
227             {1, 9, 10, 13, 16, 18, 20},
228             {4, 9, 10, 13, 16, 18, 20},
229             {6, 7, 10, 11, 15},
230         };
231 
232         for (int i = 0; i < given.length; i++) {
233             iter.setText(given[i]);
234 
235             // Check preceding(0)'s return value - should equals BreakIterator.DONE.
236             if (iter.preceding(0) != BreakIterator.DONE) {
237                  errln("Word break failure: printAt_2() expected:-1(BreakIterator.DONE), got:" +
238                        iter.preceding(0));
239             }
240 
241             for (int j = 0; j < index[i].length; j++) {
242                 start = iter.preceding(index[i][j]);
243                 end = iter.next();
244 
245                 if (!expected[i][j].equals(given[i].substring(start, end))) {
246                     errln("Word break failure: printAt_2() expected:<" +
247                           expected[i][j] + ">, got:<" +
248                           given[i].substring(start, end) +
249                           "> start=" + start + "  end=" + end);
250                 }
251             }
252 
253             // Check next()'s return value - should equals BreakIterator.DONE.
254             end = iter.last();
255             start = iter.next();
256             if (start != BreakIterator.DONE) {
257                  errln("Word break failure: printAt_2() expected:-1(BreakIterator.DONE), got:" + start);
258             }
259         }
260     }
261 }