1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.lang3; 18 19 import static org.hamcrest.MatcherAssert.assertThat; 20 import static org.hamcrest.Matchers.allOf; 21 import static org.hamcrest.Matchers.greaterThanOrEqualTo; 22 import static org.hamcrest.Matchers.is; 23 import static org.hamcrest.Matchers.lessThanOrEqualTo; 24 import static org.junit.jupiter.api.Assertions.assertEquals; 25 import static org.junit.jupiter.api.Assertions.assertFalse; 26 import static org.junit.jupiter.api.Assertions.assertNotNull; 27 import static org.junit.jupiter.api.Assertions.assertThrows; 28 import static org.junit.jupiter.api.Assertions.assertTrue; 29 import static org.junit.jupiter.api.Assertions.fail; 30 31 import java.lang.reflect.Constructor; 32 import java.lang.reflect.Modifier; 33 import java.nio.charset.Charset; 34 import java.nio.charset.StandardCharsets; 35 import java.util.Random; 36 37 import org.junit.jupiter.api.Test; 38 39 /** 40 * Unit tests {@link org.apache.commons.lang3.RandomStringUtils}. 41 */ 42 public class RandomStringUtilsTest extends AbstractLangTest { 43 44 @Test testConstructor()45 public void testConstructor() { 46 assertNotNull(new RandomStringUtils()); 47 final Constructor<?>[] cons = RandomStringUtils.class.getDeclaredConstructors(); 48 assertEquals(1, cons.length); 49 assertTrue(Modifier.isPublic(cons[0].getModifiers())); 50 assertTrue(Modifier.isPublic(RandomStringUtils.class.getModifiers())); 51 assertFalse(Modifier.isFinal(RandomStringUtils.class.getModifiers())); 52 } 53 54 /** 55 * Test the implementation 56 */ 57 @Test testRandomStringUtils()58 public void testRandomStringUtils() { 59 String r1 = RandomStringUtils.random(50); 60 assertEquals(50, r1.length(), "random(50) length"); 61 String r2 = RandomStringUtils.random(50); 62 assertEquals(50, r2.length(), "random(50) length"); 63 assertFalse(r1.equals(r2), "!r1.equals(r2)"); 64 65 r1 = RandomStringUtils.randomAscii(50); 66 assertEquals(50, r1.length(), "randomAscii(50) length"); 67 for (int i = 0; i < r1.length(); i++) { 68 assertTrue(r1.charAt(i) >= 32 && r1.charAt(i) <= 127, "char between 32 and 127"); 69 } 70 r2 = RandomStringUtils.randomAscii(50); 71 assertFalse(r1.equals(r2), "!r1.equals(r2)"); 72 73 r1 = RandomStringUtils.randomAlphabetic(50); 74 assertEquals(50, r1.length(), "randomAlphabetic(50)"); 75 for (int i = 0; i < r1.length(); i++) { 76 assertTrue(Character.isLetter(r1.charAt(i)) && !Character.isDigit(r1.charAt(i)), "r1 contains alphabetic"); 77 } 78 r2 = RandomStringUtils.randomAlphabetic(50); 79 assertFalse(r1.equals(r2), "!r1.equals(r2)"); 80 81 r1 = RandomStringUtils.randomAlphanumeric(50); 82 assertEquals(50, r1.length(), "randomAlphanumeric(50)"); 83 for (int i = 0; i < r1.length(); i++) { 84 assertTrue(Character.isLetterOrDigit(r1.charAt(i)), "r1 contains alphanumeric"); 85 } 86 r2 = RandomStringUtils.randomAlphabetic(50); 87 assertFalse(r1.equals(r2), "!r1.equals(r2)"); 88 89 r1 = RandomStringUtils.randomGraph(50); 90 assertEquals(50, r1.length(), "randomGraph(50) length"); 91 for (int i = 0; i < r1.length(); i++) { 92 assertTrue(r1.charAt(i) >= 33 && r1.charAt(i) <= 126, "char between 33 and 126"); 93 } 94 r2 = RandomStringUtils.randomGraph(50); 95 assertFalse(r1.equals(r2), "!r1.equals(r2)"); 96 97 r1 = RandomStringUtils.randomNumeric(50); 98 assertEquals(50, r1.length(), "randomNumeric(50)"); 99 for (int i = 0; i < r1.length(); i++) { 100 assertTrue(Character.isDigit(r1.charAt(i)) && !Character.isLetter(r1.charAt(i)), "r1 contains numeric"); 101 } 102 r2 = RandomStringUtils.randomNumeric(50); 103 assertFalse(r1.equals(r2), "!r1.equals(r2)"); 104 105 r1 = RandomStringUtils.randomPrint(50); 106 assertEquals(50, r1.length(), "randomPrint(50) length"); 107 for (int i = 0; i < r1.length(); i++) { 108 assertTrue(r1.charAt(i) >= 32 && r1.charAt(i) <= 126, "char between 32 and 126"); 109 } 110 r2 = RandomStringUtils.randomPrint(50); 111 assertFalse(r1.equals(r2), "!r1.equals(r2)"); 112 113 String set = "abcdefg"; 114 r1 = RandomStringUtils.random(50, set); 115 assertEquals(50, r1.length(), "random(50, \"abcdefg\")"); 116 for (int i = 0; i < r1.length(); i++) { 117 assertTrue(set.indexOf(r1.charAt(i)) > -1, "random char in set"); 118 } 119 r2 = RandomStringUtils.random(50, set); 120 assertFalse(r1.equals(r2), "!r1.equals(r2)"); 121 122 r1 = RandomStringUtils.random(50, (String) null); 123 assertEquals(50, r1.length(), "random(50) length"); 124 r2 = RandomStringUtils.random(50, (String) null); 125 assertEquals(50, r2.length(), "random(50) length"); 126 assertFalse(r1.equals(r2), "!r1.equals(r2)"); 127 128 set = "stuvwxyz"; 129 r1 = RandomStringUtils.random(50, set.toCharArray()); 130 assertEquals(50, r1.length(), "random(50, \"stuvwxyz\")"); 131 for (int i = 0; i < r1.length(); i++) { 132 assertTrue(set.indexOf(r1.charAt(i)) > -1, "random char in set"); 133 } 134 r2 = RandomStringUtils.random(50, set); 135 assertFalse(r1.equals(r2), "!r1.equals(r2)"); 136 137 r1 = RandomStringUtils.random(50, (char[]) null); 138 assertEquals(50, r1.length(), "random(50) length"); 139 r2 = RandomStringUtils.random(50, (char[]) null); 140 assertEquals(50, r2.length(), "random(50) length"); 141 assertFalse(r1.equals(r2), "!r1.equals(r2)"); 142 143 final long seedMillis = System.currentTimeMillis(); 144 r1 = RandomStringUtils.random(50, 0, 0, true, true, null, new Random(seedMillis)); 145 r2 = RandomStringUtils.random(50, 0, 0, true, true, null, new Random(seedMillis)); 146 assertEquals(r1, r2, "r1.equals(r2)"); 147 148 r1 = RandomStringUtils.random(0); 149 assertEquals("", r1, "random(0).equals(\"\")"); 150 } 151 152 @Test testLANG805()153 public void testLANG805() { 154 final long seedMillis = System.currentTimeMillis(); 155 assertEquals("aaa", RandomStringUtils.random(3, 0, 0, false, false, new char[]{'a'}, new Random(seedMillis))); 156 } 157 158 @Test testLANG807()159 public void testLANG807() { 160 final IllegalArgumentException ex = 161 assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(3, 5, 5, false, false)); 162 final String msg = ex.getMessage(); 163 assertTrue(msg.contains("start"), "Message (" + msg + ") must contain 'start'"); 164 assertTrue(msg.contains("end"), "Message (" + msg + ") must contain 'end'"); 165 } 166 167 @Test testExceptions()168 public void testExceptions() { 169 final char[] DUMMY = {'a'}; // valid char array 170 assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1)); 171 assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, true, true)); 172 assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, DUMMY)); 173 assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(1, new char[0])); 174 assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, "")); 175 assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, (String) null)); 176 assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, 'a', 'z', false, false)); 177 assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(-1, 'a', 'z', false, false, DUMMY)); 178 assertThrows( 179 IllegalArgumentException.class, 180 () -> RandomStringUtils.random(-1, 'a', 'z', false, false, DUMMY, new Random())); 181 assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(8, 32, 48, false, true)); 182 assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(8, 32, 65, true, false)); 183 } 184 185 /** 186 * Make sure boundary alphanumeric characters are generated by randomAlphaNumeric 187 * This test will fail randomly with probability = 6 * (61/62)**1000 ~ 5.2E-7 188 */ 189 @Test testRandomAlphaNumeric()190 public void testRandomAlphaNumeric() { 191 final char[] testChars = {'a', 'z', 'A', 'Z', '0', '9'}; 192 final boolean[] found = {false, false, false, false, false, false}; 193 for (int i = 0; i < 100; i++) { 194 final String randString = RandomStringUtils.randomAlphanumeric(10); 195 for (int j = 0; j < testChars.length; j++) { 196 if (randString.indexOf(testChars[j]) > 0) { 197 found[j] = true; 198 } 199 } 200 } 201 for (int i = 0; i < testChars.length; i++) { 202 assertTrue(found[i], 203 "alphanumeric character not generated in 1000 attempts: " + 204 testChars[i] + " -- repeated failures indicate a problem "); 205 } 206 } 207 208 /** 209 * Make sure '0' and '9' are generated by randomNumeric 210 * This test will fail randomly with probability = 2 * (9/10)**1000 ~ 3.5E-46 211 */ 212 @Test testRandomNumeric()213 public void testRandomNumeric() { 214 final char[] testChars = {'0', '9'}; 215 final boolean[] found = {false, false}; 216 for (int i = 0; i < 100; i++) { 217 final String randString = RandomStringUtils.randomNumeric(10); 218 for (int j = 0; j < testChars.length; j++) { 219 if (randString.indexOf(testChars[j]) > 0) { 220 found[j] = true; 221 } 222 } 223 } 224 for (int i = 0; i < testChars.length; i++) { 225 assertTrue(found[i], 226 "digit not generated in 1000 attempts: " + testChars[i] + 227 " -- repeated failures indicate a problem "); 228 } 229 } 230 231 /** 232 * Make sure boundary alpha characters are generated by randomAlphabetic 233 * This test will fail randomly with probability = 4 * (51/52)**1000 ~ 1.58E-8 234 */ 235 @Test testRandomAlphabetic()236 public void testRandomAlphabetic() { 237 final char[] testChars = {'a', 'z', 'A', 'Z'}; 238 final boolean[] found = {false, false, false, false}; 239 for (int i = 0; i < 100; i++) { 240 final String randString = RandomStringUtils.randomAlphabetic(10); 241 for (int j = 0; j < testChars.length; j++) { 242 if (randString.indexOf(testChars[j]) > 0) { 243 found[j] = true; 244 } 245 } 246 } 247 for (int i = 0; i < testChars.length; i++) { 248 assertTrue(found[i], 249 "alphanumeric character not generated in 1000 attempts: " + testChars[i] + 250 " -- repeated failures indicate a problem "); 251 } 252 } 253 254 /** 255 * Make sure 32 and 127 are generated by randomNumeric 256 * This test will fail randomly with probability = 2*(95/96)**1000 ~ 5.7E-5 257 */ 258 @Test testRandomAscii()259 public void testRandomAscii() { 260 final char[] testChars = {(char) 32, (char) 126}; 261 final boolean[] found = {false, false}; 262 for (int i = 0; i < 100; i++) { 263 final String randString = RandomStringUtils.randomAscii(10); 264 for (int j = 0; j < testChars.length; j++) { 265 if (randString.indexOf(testChars[j]) > 0) { 266 found[j] = true; 267 } 268 } 269 } 270 for (int i = 0; i < testChars.length; i++) { 271 assertTrue(found[i], 272 "ascii character not generated in 1000 attempts: " + (int) testChars[i] + 273 " -- repeated failures indicate a problem"); 274 } 275 } 276 277 @Test testRandomAsciiRange()278 public void testRandomAsciiRange() { 279 final int expectedMinLengthInclusive = 1; 280 final int expectedMaxLengthExclusive = 11; 281 final String pattern = "^\\p{ASCII}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$"; 282 283 int maxCreatedLength = expectedMinLengthInclusive; 284 int minCreatedLength = expectedMaxLengthExclusive - 1; 285 for (int i = 0; i < 1000; i++) { 286 final String s = RandomStringUtils.randomAscii(expectedMinLengthInclusive, expectedMaxLengthExclusive); 287 assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1))); 288 assertTrue(s.matches(pattern), s); 289 290 if (s.length() < minCreatedLength) { 291 minCreatedLength = s.length(); 292 } 293 294 if (s.length() > maxCreatedLength) { 295 maxCreatedLength = s.length(); 296 } 297 } 298 assertThat("min generated, may fail randomly rarely", minCreatedLength, is(expectedMinLengthInclusive)); 299 assertThat("max generated, may fail randomly rarely", maxCreatedLength, is(expectedMaxLengthExclusive - 1)); 300 } 301 302 @Test testRandomAlphabeticRange()303 public void testRandomAlphabeticRange() { 304 final int expectedMinLengthInclusive = 1; 305 final int expectedMaxLengthExclusive = 11; 306 final String pattern = "^\\p{Alpha}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$"; 307 308 int maxCreatedLength = expectedMinLengthInclusive; 309 int minCreatedLength = expectedMaxLengthExclusive - 1; 310 for (int i = 0; i < 1000; i++) { 311 final String s = RandomStringUtils.randomAlphabetic(expectedMinLengthInclusive, expectedMaxLengthExclusive); 312 assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1))); 313 assertTrue(s.matches(pattern), s); 314 315 if (s.length() < minCreatedLength) { 316 minCreatedLength = s.length(); 317 } 318 319 if (s.length() > maxCreatedLength) { 320 maxCreatedLength = s.length(); 321 } 322 } 323 assertThat("min generated, may fail randomly rarely", minCreatedLength, is(expectedMinLengthInclusive)); 324 assertThat("max generated, may fail randomly rarely", maxCreatedLength, is(expectedMaxLengthExclusive - 1)); 325 } 326 327 @Test testRandomAlphanumericRange()328 public void testRandomAlphanumericRange() { 329 final int expectedMinLengthInclusive = 1; 330 final int expectedMaxLengthExclusive = 11; 331 final String pattern = "^\\p{Alnum}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$"; 332 333 int maxCreatedLength = expectedMinLengthInclusive; 334 int minCreatedLength = expectedMaxLengthExclusive - 1; 335 for (int i = 0; i < 1000; i++) { 336 final String s = RandomStringUtils.randomAlphanumeric(expectedMinLengthInclusive, expectedMaxLengthExclusive); 337 assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1))); 338 assertTrue(s.matches(pattern), s); 339 340 if (s.length() < minCreatedLength) { 341 minCreatedLength = s.length(); 342 } 343 344 if (s.length() > maxCreatedLength) { 345 maxCreatedLength = s.length(); 346 } 347 } 348 assertThat("min generated, may fail randomly rarely", minCreatedLength, is(expectedMinLengthInclusive)); 349 assertThat("max generated, may fail randomly rarely", maxCreatedLength, is(expectedMaxLengthExclusive - 1)); 350 } 351 352 @Test testRandomGraphRange()353 public void testRandomGraphRange() { 354 final int expectedMinLengthInclusive = 1; 355 final int expectedMaxLengthExclusive = 11; 356 final String pattern = "^\\p{Graph}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$"; 357 358 int maxCreatedLength = expectedMinLengthInclusive; 359 int minCreatedLength = expectedMaxLengthExclusive - 1; 360 for (int i = 0; i < 1000; i++) { 361 final String s = RandomStringUtils.randomGraph(expectedMinLengthInclusive, expectedMaxLengthExclusive); 362 assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1))); 363 assertTrue(s.matches(pattern), s); 364 365 if (s.length() < minCreatedLength) { 366 minCreatedLength = s.length(); 367 } 368 369 if (s.length() > maxCreatedLength) { 370 maxCreatedLength = s.length(); 371 } 372 } 373 assertThat("min generated, may fail randomly rarely", minCreatedLength, is(expectedMinLengthInclusive)); 374 assertThat("max generated, may fail randomly rarely", maxCreatedLength, is(expectedMaxLengthExclusive - 1)); 375 } 376 377 @Test testRandomNumericRange()378 public void testRandomNumericRange() { 379 final int expectedMinLengthInclusive = 1; 380 final int expectedMaxLengthExclusive = 11; 381 final String pattern = "^\\p{Digit}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$"; 382 383 int maxCreatedLength = expectedMinLengthInclusive; 384 int minCreatedLength = expectedMaxLengthExclusive - 1; 385 for (int i = 0; i < 1000; i++) { 386 final String s = RandomStringUtils.randomNumeric(expectedMinLengthInclusive, expectedMaxLengthExclusive); 387 assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1))); 388 assertTrue(s.matches(pattern), s); 389 390 if (s.length() < minCreatedLength) { 391 minCreatedLength = s.length(); 392 } 393 394 if (s.length() > maxCreatedLength) { 395 maxCreatedLength = s.length(); 396 } 397 } 398 assertThat("min generated, may fail randomly rarely", minCreatedLength, is(expectedMinLengthInclusive)); 399 assertThat("max generated, may fail randomly rarely", maxCreatedLength, is(expectedMaxLengthExclusive - 1)); 400 } 401 402 @Test testRandomPrintRange()403 public void testRandomPrintRange() { 404 final int expectedMinLengthInclusive = 1; 405 final int expectedMaxLengthExclusive = 11; 406 final String pattern = "^\\p{Print}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$"; 407 408 int maxCreatedLength = expectedMinLengthInclusive; 409 int minCreatedLength = expectedMaxLengthExclusive - 1; 410 for (int i = 0; i < 1000; i++) { 411 final String s = RandomStringUtils.randomPrint(expectedMinLengthInclusive, expectedMaxLengthExclusive); 412 assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1))); 413 assertTrue(s.matches(pattern), s); 414 415 if (s.length() < minCreatedLength) { 416 minCreatedLength = s.length(); 417 } 418 419 if (s.length() > maxCreatedLength) { 420 maxCreatedLength = s.length(); 421 } 422 } 423 assertThat("min generated, may fail randomly rarely", minCreatedLength, is(expectedMinLengthInclusive)); 424 assertThat("max generated, may fail randomly rarely", maxCreatedLength, is(expectedMaxLengthExclusive - 1)); 425 } 426 427 /** 428 * Test homogeneity of random strings generated -- 429 * i.e., test that characters show up with expected frequencies 430 * in generated strings. Will fail randomly about 1 in 1000 times. 431 * Repeated failures indicate a problem. 432 */ 433 @Test testRandomStringUtilsHomog()434 public void testRandomStringUtilsHomog() { 435 final String set = "abc"; 436 final char[] chars = set.toCharArray(); 437 String gen = ""; 438 final int[] counts = {0, 0, 0}; 439 final int[] expected = {200, 200, 200}; 440 for (int i = 0; i< 100; i++) { 441 gen = RandomStringUtils.random(6, chars); 442 for (int j = 0; j < 6; j++) { 443 switch (gen.charAt(j)) { 444 case 'a': { 445 counts[0]++; 446 break; 447 } 448 case 'b': { 449 counts[1]++; 450 break; 451 } 452 case 'c': { 453 counts[2]++; 454 break; 455 } 456 default: { 457 fail("generated character not in set"); 458 } 459 } 460 } 461 } 462 // Perform chi-square test with df = 3-1 = 2, testing at .001 level 463 assertTrue(chiSquare(expected, counts) < 13.82, "test homogeneity -- will fail about 1 in 1000 times"); 464 } 465 466 /** 467 * Computes Chi-Square statistic given observed and expected counts 468 * @param observed array of observed frequency counts 469 * @param expected array of expected frequency counts 470 */ 471 private double chiSquare(final int[] expected, final int[] observed) { 472 double sumSq = 0.0d; 473 double dev = 0.0d; 474 for (int i = 0; i < observed.length; i++) { 475 dev = observed[i] - expected[i]; 476 sumSq += dev * dev / expected[i]; 477 } 478 return sumSq; 479 } 480 481 /** 482 * Checks if the string got by {@link RandomStringUtils#random(int)} 483 * can be converted to UTF-8 and back without loss. 484 * 485 * @see <a href="https://issues.apache.org/jira/browse/LANG-100">LANG-100</a> 486 */ 487 @Test 488 public void testLang100() { 489 final int size = 5000; 490 final Charset charset = StandardCharsets.UTF_8; 491 final String orig = RandomStringUtils.random(size); 492 final byte[] bytes = orig.getBytes(charset); 493 final String copy = new String(bytes, charset); 494 495 // for a verbose compare: 496 for (int i=0; i < orig.length() && i < copy.length(); i++) { 497 final char o = orig.charAt(i); 498 final char c = copy.charAt(i); 499 assertEquals(o, c, 500 "differs at " + i + "(" + Integer.toHexString(Character.valueOf(o).hashCode()) + "," + 501 Integer.toHexString(Character.valueOf(c).hashCode()) + ")"); 502 } 503 // compare length also 504 assertEquals(orig.length(), copy.length()); 505 // just to be complete 506 assertEquals(orig, copy); 507 } 508 509 510 /** 511 * Test for LANG-1286. Creates situation where old code would 512 * overflow a char and result in a code point outside the specified 513 * range. 514 */ 515 @Test 516 public void testCharOverflow() { 517 final int start = Character.MAX_VALUE; 518 final int end = Integer.MAX_VALUE; 519 520 @SuppressWarnings("serial") 521 final 522 Random fixedRandom = new Random() { 523 @Override 524 public int nextInt(final int n) { 525 // Prevents selection of 'start' as the character 526 return super.nextInt(n - 1) + 1; 527 } 528 }; 529 530 final String result = RandomStringUtils.random(2, start, end, false, false, null, fixedRandom); 531 final int c = result.codePointAt(0); 532 assertTrue(c >= start && c < end, String.format("Character '%d' not in range [%d,%d).", c, start, end)); 533 } 534 } 535 536