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