1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.text;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24 import static org.junit.jupiter.api.Assertions.fail;
25
26 import java.util.Arrays;
27 import java.util.function.IntUnaryOperator;
28
29 import org.apache.commons.lang3.ArraySorter;
30 import org.apache.commons.text.RandomStringGenerator.Builder;
31 import org.junit.jupiter.api.Test;
32 import org.junit.jupiter.params.ParameterizedTest;
33 import org.junit.jupiter.params.provider.ValueSource;
34
35
36
37
38 class RandomStringGeneratorTest {
39
40 private static final CharacterPredicate A_FILTER = codePoint -> codePoint == 'a';
41 private static final CharacterPredicate B_FILTER = codePoint -> codePoint == 'b';
42
43 private static int codePointLength(final String s) {
44 return s.codePointCount(0, s.length());
45 }
46
47 @Test
48 void testBadMaximumCodePoint() {
49 assertThrowsExactly(IllegalArgumentException.class, () -> RandomStringGenerator.builder().withinRange(0, Character.MAX_CODE_POINT + 1));
50 }
51
52 @Test
53 void testBadMinAndMax() {
54 assertThrowsExactly(IllegalArgumentException.class, () -> RandomStringGenerator.builder().withinRange(2, 1));
55 }
56
57 @Test
58 void testBadMinimumCodePoint() {
59 assertThrowsExactly(IllegalArgumentException.class, () -> RandomStringGenerator.builder().withinRange(-1, 1));
60 }
61
62 @Test
63 void testBuildDeprecated() {
64 final RandomStringGenerator.Builder builder = RandomStringGenerator.builder().withinRange('a', 'z').filteredBy(A_FILTER);
65 final String str = builder.filteredBy(B_FILTER).build().generate(100);
66 for (final char c : str.toCharArray()) {
67 assertEquals('b', c);
68 }
69 }
70
71 @Test
72 void testChangeOfFilter() {
73 final RandomStringGenerator.Builder builder = RandomStringGenerator.builder().withinRange('a', 'z').filteredBy(A_FILTER);
74 final String str = builder.filteredBy(B_FILTER).get().generate(100);
75 for (final char c : str.toCharArray()) {
76 assertEquals('b', c);
77 }
78 }
79
80 @Test
81 void testGenerateMinMaxLength() {
82 final int minLength = 0;
83 final int maxLength = 3;
84 final RandomStringGenerator generator = RandomStringGenerator.builder().get();
85 final String str = generator.generate(minLength, maxLength);
86 final int codePointLength = codePointLength(str);
87 assertTrue(codePointLength >= minLength && codePointLength <= maxLength);
88 }
89
90 @Test
91 void testGenerateMinMaxLengthInvalidLength() {
92 assertThrowsExactly(IllegalArgumentException.class, () -> {
93 final RandomStringGenerator generator = RandomStringGenerator.builder().get();
94 generator.generate(-1, 0);
95 });
96 }
97
98 @Test
99 void testGenerateMinMaxLengthMinGreaterThanMax() {
100 assertThrowsExactly(IllegalArgumentException.class, () -> {
101 final RandomStringGenerator generator = RandomStringGenerator.builder().get();
102 generator.generate(1, 0);
103 });
104 }
105
106 @Test
107 void testGenerateTakingIntThrowsNullPointerException() {
108 assertThrowsExactly(NullPointerException.class, () -> {
109 final RandomStringGenerator.Builder randomStringGeneratorBuilder = RandomStringGenerator.builder();
110 final CharacterPredicate[] characterPredicateArray = new CharacterPredicate[2];
111 randomStringGeneratorBuilder.filteredBy(characterPredicateArray);
112 final RandomStringGenerator randomStringGenerator = randomStringGeneratorBuilder.get();
113 randomStringGenerator.generate(18);
114 });
115 }
116
117 @Test
118 void testInvalidLength() {
119 assertThrowsExactly(IllegalArgumentException.class, () -> RandomStringGenerator.builder().get().generate(-1));
120 }
121
122 @Test
123 void testMultipleFilters() {
124 final String str = RandomStringGenerator.builder().withinRange('a', 'd').filteredBy(A_FILTER, B_FILTER).get().generate(5000);
125 boolean aFound = false;
126 boolean bFound = false;
127 for (final char c : str.toCharArray()) {
128 if (c == 'a') {
129 aFound = true;
130 } else if (c == 'b') {
131 bFound = true;
132 } else {
133 fail("Invalid character");
134 }
135 }
136 assertTrue(aFound && bFound);
137 }
138
139 @Test
140 void testNoLoneSurrogates() {
141 final int length = 5000;
142 final String str = RandomStringGenerator.builder().get().generate(length);
143 char lastChar = str.charAt(0);
144 for (int i = 1; i < str.length(); i++) {
145 final char c = str.charAt(i);
146 if (Character.isLowSurrogate(c)) {
147 assertTrue(Character.isHighSurrogate(lastChar));
148 }
149 if (Character.isHighSurrogate(lastChar)) {
150 assertTrue(Character.isLowSurrogate(c));
151 }
152 if (Character.isHighSurrogate(c)) {
153
154 assertTrue(i + 1 < str.length());
155 }
156 lastChar = c;
157 }
158 }
159
160 @Test
161 void testNoPrivateCharacters() {
162 final int startOfPrivateBMPChars = 0xE000;
163
164
165 final String str = RandomStringGenerator.builder().withinRange(startOfPrivateBMPChars, Character.MIN_SUPPLEMENTARY_CODE_POINT - 1).get()
166 .generate(5000);
167 int i = 0;
168 do {
169 final int codePoint = str.codePointAt(i);
170 assertFalse(Character.getType(codePoint) == Character.PRIVATE_USE);
171 i += Character.charCount(codePoint);
172 } while (i < str.length());
173 }
174
175 @Test
176 void testPasswordExample() {
177 final char[] punctuation = ArraySorter
178 .sort(new char[] { '!', '"', '#', '$', '&', '\'', '(', ')', ',', '.', ':', ';', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' });
179
180 final RandomStringGenerator generator = RandomStringGenerator.builder()
181 .setAccumulate(true)
182 .withinRange('a', 'z')
183 .withinRange('A', 'Z')
184 .withinRange('0', '9')
185 .selectFrom(punctuation)
186 .get();
187
188 final String randomText = generator.generate(10);
189 for (final char c : randomText.toCharArray()) {
190 assertTrue(Character.isLetter(c) || Character.isDigit(c) || Arrays.binarySearch(punctuation, c) >= 0);
191 }
192 }
193
194 @Test
195 void testRemoveFilters() {
196 final RandomStringGenerator.Builder builder = RandomStringGenerator.builder().withinRange('a', 'z').filteredBy(A_FILTER);
197 builder.filteredBy();
198 final String str = builder.get().generate(100);
199 for (final char c : str.toCharArray()) {
200 if (c != 'a') {
201
202 return;
203 }
204 }
205 fail("Filter appears to have remained in place");
206 }
207
208 @Test
209 void testSelectFromCharArray() {
210 final String str = "abc";
211 final char[] charArray = str.toCharArray();
212 final RandomStringGenerator generator = RandomStringGenerator.builder().selectFrom(charArray).get();
213 final String randomText = generator.generate(5);
214 for (final char c : randomText.toCharArray()) {
215 assertTrue(str.indexOf(c) != -1);
216 }
217 }
218
219 @Test
220 void testSelectFromCharVarargs() {
221 final String str = "abc";
222 final RandomStringGenerator generator = RandomStringGenerator.builder().selectFrom('a', 'b', 'c').get();
223 final String randomText = generator.generate(5);
224 for (final char c : randomText.toCharArray()) {
225 assertTrue(str.indexOf(c) != -1);
226 }
227 }
228
229 @ParameterizedTest
230 @ValueSource(booleans = {false, true})
231 void testSelectFromCharVarargs2(final boolean accumulate) {
232 final String str = "abcde";
233
234 final RandomStringGenerator generator = RandomStringGenerator.builder()
235 .setAccumulate(accumulate)
236 .selectFrom()
237 .selectFrom(null)
238 .selectFrom('a', 'b')
239 .selectFrom('a', 'b', 'c')
240 .selectFrom('a', 'b', 'c', 'd')
241 .selectFrom('a', 'b', 'c', 'd', 'e')
242 .get();
243
244 final String randomText = generator.generate(10);
245 for (final char c : randomText.toCharArray()) {
246 assertTrue(str.indexOf(c) != -1);
247 }
248 }
249
250 @ParameterizedTest
251 @ValueSource(booleans = {false, true})
252 void testSelectFromCharVarargs3(final boolean accumulate) {
253 final String str = "abcde";
254
255 final RandomStringGenerator generator = RandomStringGenerator.builder()
256 .setAccumulate(accumulate)
257 .selectFrom('a', 'b', 'c', 'd', 'e')
258 .selectFrom('a', 'b', 'c', 'd')
259 .selectFrom('a', 'b', 'c')
260 .selectFrom('a', 'b')
261 .selectFrom(null)
262 .selectFrom()
263 .get();
264
265 final String randomText = generator.generate(10);
266 for (final char c : randomText.toCharArray()) {
267 assertEquals(accumulate, str.indexOf(c) != -1);
268 }
269 }
270
271 @Test
272 void testSelectFromCharVarargSize1() {
273 final RandomStringGenerator generator = RandomStringGenerator.builder().selectFrom('a').get();
274 final String randomText = generator.generate(5);
275 for (final char c : randomText.toCharArray()) {
276 assertEquals('a', c);
277 }
278 }
279
280 @Test
281 void testSelectFromEmptyCharVarargs() {
282 final RandomStringGenerator generator = RandomStringGenerator.builder().selectFrom().get();
283 final String randomText = generator.generate(5);
284 for (final char c : randomText.toCharArray()) {
285 assertTrue(c >= Character.MIN_CODE_POINT && c <= Character.MAX_CODE_POINT);
286 }
287 }
288
289 @Test
290 void testSelectFromNullCharVarargs() {
291 final int length = 5;
292 RandomStringGenerator generator = RandomStringGenerator.builder().selectFrom(null).get();
293 String randomText = generator.generate(length);
294 assertEquals(length, codePointLength(randomText));
295 for (final char c : randomText.toCharArray()) {
296 assertTrue(c >= Character.MIN_CODE_POINT && c <= Character.MAX_CODE_POINT);
297 }
298
299 final Builder builder = RandomStringGenerator.builder().selectFrom('a');
300 generator = builder.get();
301 randomText = generator.generate(length);
302 for (final char c : randomText.toCharArray()) {
303 assertEquals('a', c);
304 }
305
306 generator = builder.selectFrom(null).get();
307 randomText = generator.generate(length);
308 assertEquals(length, codePointLength(randomText));
309 for (final char c : randomText.toCharArray()) {
310 assertTrue(c >= Character.MIN_CODE_POINT && c <= Character.MAX_CODE_POINT);
311 }
312 }
313
314 @Test
315 void testSetLength() {
316 final int length = 99;
317 final RandomStringGenerator generator = RandomStringGenerator.builder().get();
318 final String str = generator.generate(length);
319 assertEquals(length, codePointLength(str));
320 }
321
322 @Test
323 void testUsingRandomIntUnaryOperator() {
324 final char testChar = 'a';
325 final IntUnaryOperator testRandom = n -> testChar;
326 final String str = RandomStringGenerator.builder().usingRandom(testRandom).get().generate(10);
327 for (final char c : str.toCharArray()) {
328 assertEquals(testChar, c);
329 }
330 }
331
332 @Test
333 void testUsingRandomTextRandomProvider() {
334 final char testChar = 'a';
335 final TextRandomProvider testRandom = n -> testChar;
336 final String str = RandomStringGenerator.builder().usingRandom(testRandom).get().generate(10);
337 for (final char c : str.toCharArray()) {
338 assertEquals(testChar, c);
339 }
340 }
341
342 @Test
343 void testWithinMultipleRanges() {
344 final int length = 5000;
345 final char[][] pairs = { { 'a', 'z' }, { '0', '9' } };
346
347 final RandomStringGenerator generator = RandomStringGenerator.builder()
348 .withinRange()
349 .withinRange((char[][]) null)
350 .withinRange(pairs)
351 .get();
352
353 final String str = generator.generate(length);
354 int minimumCodePoint = 0, maximumCodePoint = 0;
355 for (final char[] pair : pairs) {
356 minimumCodePoint = Math.min(minimumCodePoint, pair[0]);
357 maximumCodePoint = Math.max(maximumCodePoint, pair[1]);
358 }
359 int i = 0;
360 do {
361 final int codePoint = str.codePointAt(i);
362 assertTrue(codePoint >= minimumCodePoint && codePoint <= maximumCodePoint);
363 i += Character.charCount(codePoint);
364 } while (i < str.length());
365 }
366
367 @Test
368 void testWithinRange() {
369 final int length = 5000;
370 final int minimumCodePoint = 'a';
371 final int maximumCodePoint = 'z';
372 final RandomStringGenerator generator = RandomStringGenerator.builder().withinRange(minimumCodePoint, maximumCodePoint).get();
373 final String str = generator.generate(length);
374 int i = 0;
375 do {
376 final int codePoint = str.codePointAt(i);
377 assertTrue(codePoint >= minimumCodePoint && codePoint <= maximumCodePoint);
378 i += Character.charCount(codePoint);
379 } while (i < str.length());
380 }
381
382 @Test
383 void testZeroLength() {
384 final RandomStringGenerator generator = RandomStringGenerator.builder().get();
385 assertEquals("", generator.generate(0));
386 }
387 }