1 /*
2  * Copyright (c) 2015, 2018, 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 package test.java.lang.StringBuilder;
25 
26 import java.util.Arrays;
27 
28 import org.testng.annotations.Test;
29 
30 import static org.testng.Assert.assertEquals;
31 import static org.testng.Assert.assertTrue;
32 
33 /*
34  * @test
35  * @bug 8054307 8077559
36  * @summary Tests Compact String. This test is testing StringBuilder
37  *          behavior related to Compact String.
38  * @run testng/othervm -XX:+CompactStrings CompactStringBuilder
39  * @run testng/othervm -XX:-CompactStrings CompactStringBuilder
40  */
41 
42 public class CompactStringBuilder {
43 
44     /*
45      * Tests for "A"
46      */
47     @Test
testCompactStringBuilderForLatinA()48     public void testCompactStringBuilderForLatinA() {
49         final String ORIGIN = "A";
50         /*
51          * Because right now ASCII is the default encoding parameter for source
52          * code in JDK build environment, so we escape them. same as below.
53          */
54         check(new StringBuilder(ORIGIN).append(new char[] { '\uFF21' }),
55                 "A\uFF21");
56         check(new StringBuilder(ORIGIN).append(new StringBuffer("\uFF21")),
57                 "A\uFF21");
58         check(new StringBuilder(ORIGIN).append("\uFF21"), "A\uFF21");
59         check(new StringBuilder(ORIGIN).append(new StringBuffer("\uFF21")),
60                 "A\uFF21");
61         check(new StringBuilder(ORIGIN).delete(0, 1), "");
62         check(new StringBuilder(ORIGIN).delete(0, 0), "A");
63         check(new StringBuilder(ORIGIN).deleteCharAt(0), "");
64         assertEquals(new StringBuilder(ORIGIN).indexOf("A", 0), 0);
65         assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 0), -1);
66         assertEquals(new StringBuilder(ORIGIN).indexOf("", 0), 0);
67         assertEquals(new StringBuilder(ORIGIN).insert(1, "\uD801\uDC00")
68                 .indexOf("A", 0), 0);
69         assertEquals(new StringBuilder(ORIGIN).insert(0, "\uD801\uDC00")
70                 .indexOf("A", 0), 2);
71         check(new StringBuilder(ORIGIN).insert(0, new char[] {}), "A");
72         check(new StringBuilder(ORIGIN).insert(1, new char[] { '\uFF21' }),
73                 "A\uFF21");
74         check(new StringBuilder(ORIGIN).insert(0, new char[] { '\uFF21' }),
75                 "\uFF21A");
76         check(new StringBuilder(ORIGIN).insert(0, new StringBuffer("\uFF21")),
77                 "\uFF21A");
78         check(new StringBuilder(ORIGIN).insert(1, new StringBuffer("\uFF21")),
79                 "A\uFF21");
80         check(new StringBuilder(ORIGIN).insert(0, ""), "A");
81         check(new StringBuilder(ORIGIN).insert(0, "\uFF21"), "\uFF21A");
82         check(new StringBuilder(ORIGIN).insert(1, "\uFF21"), "A\uFF21");
83         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 0);
84         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), -1);
85         assertEquals(new StringBuilder(ORIGIN).lastIndexOf(""), 1);
86         check(new StringBuilder(ORIGIN).replace(0, 0, "\uFF21"), "\uFF21A");
87         check(new StringBuilder(ORIGIN).replace(0, 1, "\uFF21"), "\uFF21");
88         checkSetCharAt(new StringBuilder(ORIGIN), 0, '\uFF21', "\uFF21");
89         checkSetLength(new StringBuilder(ORIGIN), 0, "");
90         checkSetLength(new StringBuilder(ORIGIN), 1, "A");
91         check(new StringBuilder(ORIGIN).substring(0), "A");
92         check(new StringBuilder(ORIGIN).substring(1), "");
93     }
94 
95     /*
96      * Tests for "\uFF21"
97      */
98     @Test
testCompactStringBuilderForNonLatinA()99     public void testCompactStringBuilderForNonLatinA() {
100         final String ORIGIN = "\uFF21";
101         check(new StringBuilder(ORIGIN).append(new char[] { 'A' }), "\uFF21A");
102         check(new StringBuilder(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
103         check(new StringBuilder(ORIGIN).append("A"), "\uFF21A");
104         check(new StringBuilder(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
105         check(new StringBuilder(ORIGIN).delete(0, 1), "");
106         check(new StringBuilder(ORIGIN).delete(0, 0), "\uFF21");
107         check(new StringBuilder(ORIGIN).deleteCharAt(0), "");
108         assertEquals(new StringBuilder(ORIGIN).indexOf("A", 0), -1);
109         assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 0), 0);
110         assertEquals(new StringBuilder(ORIGIN).indexOf("", 0), 0);
111         check(new StringBuilder(ORIGIN).insert(0, new char[] {}), "\uFF21");
112         check(new StringBuilder(ORIGIN).insert(1, new char[] { 'A' }), "\uFF21A");
113         check(new StringBuilder(ORIGIN).insert(0, new char[] { 'A' }), "A\uFF21");
114         check(new StringBuilder(ORIGIN).insert(0, new StringBuffer("A")),
115                 "A\uFF21");
116         check(new StringBuilder(ORIGIN).insert(1, new StringBuffer("A")),
117                 "\uFF21A");
118         check(new StringBuilder(ORIGIN).insert(0, ""), "\uFF21");
119         check(new StringBuilder(ORIGIN).insert(0, "A"), "A\uFF21");
120         check(new StringBuilder(ORIGIN).insert(1, "A"), "\uFF21A");
121         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), -1);
122         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 0);
123         assertEquals(new StringBuilder(ORIGIN).lastIndexOf(""), 1);
124         check(new StringBuilder(ORIGIN).replace(0, 0, "A"), "A\uFF21");
125         check(new StringBuilder(ORIGIN).replace(0, 1, "A"), "A");
126         checkSetCharAt(new StringBuilder(ORIGIN), 0, 'A', "A");
127         checkSetLength(new StringBuilder(ORIGIN), 0, "");
128         checkSetLength(new StringBuilder(ORIGIN), 1, "\uFF21");
129         check(new StringBuilder(ORIGIN).substring(0), "\uFF21");
130         check(new StringBuilder(ORIGIN).substring(1), "");
131     }
132 
133     /*
134      * Tests for "\uFF21A"
135      */
136     @Test
testCompactStringBuilderForMixedA1()137     public void testCompactStringBuilderForMixedA1() {
138         final String ORIGIN = "\uFF21A";
139         check(new StringBuilder(ORIGIN).delete(0, 1), "A");
140         check(new StringBuilder(ORIGIN).delete(1, 2), "\uFF21");
141         check(new StringBuilder(ORIGIN).deleteCharAt(1), "\uFF21");
142         check(new StringBuilder(ORIGIN).deleteCharAt(0), "A");
143         assertEquals(new StringBuilder(ORIGIN).indexOf("A", 0), 1);
144         assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 0), 0);
145         assertEquals(new StringBuilder(ORIGIN).indexOf("", 0), 0);
146         check(new StringBuilder(ORIGIN).insert(1, new char[] { 'A' }),
147                 "\uFF21AA");
148         check(new StringBuilder(ORIGIN).insert(0, new char[] { '\uFF21' }),
149                 "\uFF21\uFF21A");
150         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 1);
151         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 0);
152         assertEquals(new StringBuilder(ORIGIN).lastIndexOf(""), 2);
153         check(new StringBuilder(ORIGIN).replace(0, 0, "A"), "A\uFF21A");
154         check(new StringBuilder(ORIGIN).replace(0, 1, "A"), "AA");
155         checkSetCharAt(new StringBuilder(ORIGIN), 0, 'A', "AA");
156         checkSetLength(new StringBuilder(ORIGIN), 0, "");
157         checkSetLength(new StringBuilder(ORIGIN), 1, "\uFF21");
158         check(new StringBuilder(ORIGIN).substring(0), "\uFF21A");
159         check(new StringBuilder(ORIGIN).substring(1), "A");
160     }
161 
162     /*
163      * Tests for "A\uFF21"
164      */
165     @Test
testCompactStringBuilderForMixedA2()166     public void testCompactStringBuilderForMixedA2() {
167         final String ORIGIN = "A\uFF21";
168         check(new StringBuilder(ORIGIN).replace(1, 2, "A"), "AA");
169         checkSetLength(new StringBuilder(ORIGIN), 1, "A");
170         check(new StringBuilder(ORIGIN).substring(0), "A\uFF21");
171         check(new StringBuilder(ORIGIN).substring(1), "\uFF21");
172         check(new StringBuilder(ORIGIN).substring(0, 1), "A");
173     }
174 
175     /*
176      * Tests for "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A"
177      */
178     @Test
testCompactStringBuilderForDuplicatedMixedA1()179     public void testCompactStringBuilderForDuplicatedMixedA1() {
180         final String ORIGIN = "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A";
181         checkSetLength(new StringBuilder(ORIGIN), 1, "\uFF21");
182         assertEquals(new StringBuilder(ORIGIN).indexOf("A", 5), 5);
183         assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 5), 6);
184         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 9);
185         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 8);
186         assertEquals(new StringBuilder(ORIGIN).lastIndexOf(""), 10);
187         check(new StringBuilder(ORIGIN).substring(9), "A");
188         check(new StringBuilder(ORIGIN).substring(8), "\uFF21A");
189     }
190 
191     /*
192      * Tests for "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21"
193      */
194     @Test
testCompactStringBuilderForDuplicatedMixedA2()195     public void testCompactStringBuilderForDuplicatedMixedA2() {
196         final String ORIGIN = "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21";
197         checkSetLength(new StringBuilder(ORIGIN), 1, "A");
198         assertEquals(new StringBuilder(ORIGIN).indexOf("A", 5), 6);
199         assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 5), 5);
200         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 8);
201         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 9);
202         check(new StringBuilder(ORIGIN).substring(9), "\uFF21");
203         check(new StringBuilder(ORIGIN).substring(8), "A\uFF21");
204     }
205 
206     /*
207      * Tests for "\uD801\uDC00\uD801\uDC01"
208      */
209     @Test
testCompactStringForSupplementaryCodePoint()210     public void testCompactStringForSupplementaryCodePoint() {
211         final String ORIGIN = "\uD801\uDC00\uD801\uDC01";
212         check(new StringBuilder(ORIGIN).append("A"), "\uD801\uDC00\uD801\uDC01A");
213         check(new StringBuilder(ORIGIN).append("\uFF21"),
214                 "\uD801\uDC00\uD801\uDC01\uFF21");
215         check(new StringBuilder(ORIGIN).appendCodePoint('A'),
216                 "\uD801\uDC00\uD801\uDC01A");
217         check(new StringBuilder(ORIGIN).appendCodePoint('\uFF21'),
218                 "\uD801\uDC00\uD801\uDC01\uFF21");
219         assertEquals(new StringBuilder(ORIGIN).charAt(0), '\uD801');
220         assertEquals(new StringBuilder(ORIGIN).codePointAt(0),
221                 Character.codePointAt(ORIGIN, 0));
222         assertEquals(new StringBuilder(ORIGIN).codePointAt(1),
223                 Character.codePointAt(ORIGIN, 1));
224         assertEquals(new StringBuilder(ORIGIN).codePointBefore(2),
225                 Character.codePointAt(ORIGIN, 0));
226         assertEquals(new StringBuilder(ORIGIN).codePointCount(1, 3), 2);
227         check(new StringBuilder(ORIGIN).delete(0, 2), "\uD801\uDC01");
228         check(new StringBuilder(ORIGIN).delete(0, 3), "\uDC01");
229         check(new StringBuilder(ORIGIN).deleteCharAt(1), "\uD801\uD801\uDC01");
230         checkGetChars(new StringBuilder(ORIGIN), 0, 3, new char[] { '\uD801',
231                 '\uDC00', '\uD801' });
232         assertEquals(new StringBuilder(ORIGIN).indexOf("\uD801\uDC01"), 2);
233         assertEquals(new StringBuilder(ORIGIN).indexOf("\uDC01"), 3);
234         assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21"), -1);
235         assertEquals(new StringBuilder(ORIGIN).indexOf("A"), -1);
236         check(new StringBuilder(ORIGIN).insert(0, "\uFF21"),
237                 "\uFF21\uD801\uDC00\uD801\uDC01");
238         check(new StringBuilder(ORIGIN).insert(1, "\uFF21"),
239                 "\uD801\uFF21\uDC00\uD801\uDC01");
240         check(new StringBuilder(ORIGIN).insert(1, "A"),
241                 "\uD801A\uDC00\uD801\uDC01");
242         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uDC00\uD801"), 1);
243         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uD801"), 2);
244         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), -1);
245         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), -1);
246         assertEquals(new StringBuilder(ORIGIN).length(), 4);
247         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 2);
248         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 2);
249         check(new StringBuilder(ORIGIN).replace(0, 2, "A"), "A\uD801\uDC01");
250         check(new StringBuilder(ORIGIN).replace(0, 3, "A"), "A\uDC01");
251         check(new StringBuilder(ORIGIN).replace(0, 2, "\uFF21"),
252                 "\uFF21\uD801\uDC01");
253         check(new StringBuilder(ORIGIN).replace(0, 3, "\uFF21"), "\uFF21\uDC01");
254         check(new StringBuilder(ORIGIN).reverse(), "\uD801\uDC01\uD801\uDC00");
255         checkSetCharAt(new StringBuilder(ORIGIN), 1, '\uDC01',
256                 "\uD801\uDC01\uD801\uDC01");
257         checkSetCharAt(new StringBuilder(ORIGIN), 1, 'A', "\uD801A\uD801\uDC01");
258         checkSetLength(new StringBuilder(ORIGIN), 2, "\uD801\uDC00");
259         checkSetLength(new StringBuilder(ORIGIN), 3, "\uD801\uDC00\uD801");
260         check(new StringBuilder(ORIGIN).substring(1, 3), "\uDC00\uD801");
261     }
262 
263     /*
264      * Tests for "A\uD801\uDC00\uFF21"
265      */
266     @Test
testCompactStringForSupplementaryCodePointMixed1()267     public void testCompactStringForSupplementaryCodePointMixed1() {
268         final String ORIGIN = "A\uD801\uDC00\uFF21";
269         assertEquals(new StringBuilder(ORIGIN).codePointBefore(3),
270                 Character.codePointAt(ORIGIN, 1));
271         assertEquals(new StringBuilder(ORIGIN).codePointBefore(2), '\uD801');
272         assertEquals(new StringBuilder(ORIGIN).codePointBefore(1), 'A');
273         assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 3), 2);
274         assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 4), 3);
275         check(new StringBuilder(ORIGIN).delete(0, 1), "\uD801\uDC00\uFF21");
276         check(new StringBuilder(ORIGIN).delete(0, 1).delete(2, 3),
277                 "\uD801\uDC00");
278         check(new StringBuilder(ORIGIN).deleteCharAt(3).deleteCharAt(0),
279                 "\uD801\uDC00");
280         assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21"), 3);
281         assertEquals(new StringBuilder(ORIGIN).indexOf("A"), 0);
282         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 3);
283         assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 0);
284         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 1);
285         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 3);
286         check(new StringBuilder(ORIGIN).replace(1, 3, "A"), "AA\uFF21");
287         check(new StringBuilder(ORIGIN).replace(1, 4, "A"), "AA");
288         check(new StringBuilder(ORIGIN).replace(1, 4, ""), "A");
289         check(new StringBuilder(ORIGIN).reverse(), "\uFF21\uD801\uDC00A");
290         checkSetLength(new StringBuilder(ORIGIN), 1, "A");
291         check(new StringBuilder(ORIGIN).substring(0, 1), "A");
292     }
293 
294     /*
295      * Tests for "\uD801\uDC00\uFF21A"
296      */
297     @Test
testCompactStringForSupplementaryCodePointMixed2()298     public void testCompactStringForSupplementaryCodePointMixed2() {
299         final String ORIGIN = "\uD801\uDC00\uFF21A";
300         assertEquals(new StringBuilder(ORIGIN).codePointBefore(3),
301                 Character.codePointAt(ORIGIN, 2));
302         assertEquals(new StringBuilder(ORIGIN).codePointBefore(2),
303                 Character.codePointAt(ORIGIN, 0));
304         assertEquals(new StringBuilder(ORIGIN).codePointBefore(1), '\uD801');
305         assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 3), 2);
306         assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 4), 3);
307         check(new StringBuilder(ORIGIN).delete(0, 2), "\uFF21A");
308         check(new StringBuilder(ORIGIN).delete(0, 3), "A");
309         check(new StringBuilder(ORIGIN).deleteCharAt(0).deleteCharAt(0)
310                 .deleteCharAt(0), "A");
311         assertEquals(new StringBuilder(ORIGIN).indexOf("A"), 3);
312         assertEquals(new StringBuilder(ORIGIN).delete(0, 3).indexOf("A"), 0);
313         assertEquals(new StringBuilder(ORIGIN).replace(0, 3, "B").indexOf("A"),
314                 1);
315         assertEquals(new StringBuilder(ORIGIN).substring(3, 4).indexOf("A"), 0);
316         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 2);
317         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 2);
318         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(2, 1), 3);
319         check(new StringBuilder(ORIGIN).replace(0, 3, "B"), "BA");
320         check(new StringBuilder(ORIGIN).reverse(), "A\uFF21\uD801\uDC00");
321     }
322 
323     /*
324      * Tests for "\uD801A\uDC00\uFF21"
325      */
326     @Test
testCompactStringForSupplementaryCodePointMixed3()327     public void testCompactStringForSupplementaryCodePointMixed3() {
328         final String ORIGIN = "\uD801A\uDC00\uFF21";
329         assertEquals(new StringBuilder(ORIGIN).codePointAt(1), 'A');
330         assertEquals(new StringBuilder(ORIGIN).codePointAt(3), '\uFF21');
331         assertEquals(new StringBuilder(ORIGIN).codePointBefore(1), '\uD801');
332         assertEquals(new StringBuilder(ORIGIN).codePointBefore(2), 'A');
333         assertEquals(new StringBuilder(ORIGIN).codePointBefore(3), '\uDC00');
334         assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 3), 3);
335         assertEquals(new StringBuilder(ORIGIN).codePointCount(1, 3), 2);
336         assertEquals(new StringBuilder(ORIGIN).delete(0, 1).delete(1, 3)
337                 .indexOf("A"), 0);
338         assertEquals(
339                 new StringBuilder(ORIGIN).replace(0, 1, "B").replace(2, 4, "C")
340                         .indexOf("A"), 1);
341         assertEquals(new StringBuilder(ORIGIN).substring(1, 4).substring(0, 1)
342                 .indexOf("A"), 0);
343         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 1);
344         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 2);
345         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(2, 1), 3);
346         check(new StringBuilder(ORIGIN).reverse(), "\uFF21\uDC00A\uD801");
347     }
348 
349     /*
350      * Tests for "A\uDC01\uFF21\uD801"
351      */
352     @Test
testCompactStringForSupplementaryCodePointMixed4()353     public void testCompactStringForSupplementaryCodePointMixed4() {
354         final String ORIGIN = "A\uDC01\uFF21\uD801";
355         assertEquals(new StringBuilder(ORIGIN).codePointAt(1), '\uDC01');
356         assertEquals(new StringBuilder(ORIGIN).codePointAt(3), '\uD801');
357         assertEquals(new StringBuilder(ORIGIN).codePointBefore(1), 'A');
358         assertEquals(new StringBuilder(ORIGIN).codePointBefore(2), '\uDC01');
359         assertEquals(new StringBuilder(ORIGIN).codePointBefore(3), '\uFF21');
360         assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 3), 3);
361         assertEquals(new StringBuilder(ORIGIN).codePointCount(1, 3), 2);
362         assertEquals(new StringBuilder(ORIGIN).delete(1, 4).indexOf("A"), 0);
363         assertEquals(new StringBuilder(ORIGIN).replace(1, 4, "B").indexOf("A"),
364                 0);
365         assertEquals(new StringBuilder(ORIGIN).substring(0, 1).indexOf("A"), 0);
366         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 1);
367         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 2);
368         assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(2, 1), 3);
369         check(new StringBuilder(ORIGIN).reverse(), "\uD801\uFF21\uDC01A");
370     }
371 
checkGetChars(StringBuilder sb, int srcBegin, int srcEnd, char expected[])372     private void checkGetChars(StringBuilder sb, int srcBegin, int srcEnd,
373             char expected[]) {
374         char[] dst = new char[srcEnd - srcBegin];
375         sb.getChars(srcBegin, srcEnd, dst, 0);
376         assertTrue(Arrays.equals(dst, expected));
377     }
378 
checkSetCharAt(StringBuilder sb, int index, char ch, String expected)379     private void checkSetCharAt(StringBuilder sb, int index, char ch,
380             String expected) {
381         sb.setCharAt(index, ch);
382         check(sb, expected);
383     }
384 
checkSetLength(StringBuilder sb, int newLength, String expected)385     private void checkSetLength(StringBuilder sb, int newLength, String expected) {
386         sb.setLength(newLength);
387         check(sb, expected);
388     }
389 
check(StringBuilder sb, String expected)390     private void check(StringBuilder sb, String expected) {
391         check(sb.toString(), expected);
392     }
393 
check(String str, String expected)394     private void check(String str, String expected) {
395         assertTrue(str.equals(expected), String.format(
396                 "Get (%s) but expect (%s), ", escapeNonASCIIs(str),
397                 escapeNonASCIIs(expected)));
398     }
399 
400     /*
401      * Escape non-ASCII characters since not all systems support them.
402      */
escapeNonASCIIs(String str)403     private String escapeNonASCIIs(String str) {
404         StringBuilder sb = new StringBuilder();
405         for (int i = 0; i < str.length(); i++) {
406             char c = str.charAt(i);
407             if (c > 0x7F) {
408                 sb.append("\\u").append(Integer.toHexString((int) c));
409             } else {
410                 sb.append(c);
411             }
412         }
413         return sb.toString();
414     }
415 }
416