1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.junit.bct;
18
19 import static org.apache.juneau.junit.bct.BctAssertions.*;
20 import static org.apache.juneau.junit.bct.Utils.*;
21 import static org.junit.jupiter.api.Assertions.*;
22
23 import java.util.*;
24 import java.util.regex.*;
25
26 import org.apache.juneau.*;
27 import org.junit.jupiter.api.*;
28
29
30
31
32
33
34
35
36 @DisplayName("Utility Methods")
37 class Utils_Test extends TestBase {
38
39
40
41
42
43 @Test
44 @DisplayName("arrayToList() - Basic array conversion")
45 void a01_arrayToListBasicConversion() {
46
47 int[] intArray = {1, 2, 3, 4, 5};
48 var result = arrayToList(intArray);
49 assertEquals(5, result.size());
50 assertEquals(1, result.get(0));
51 assertEquals(2, result.get(1));
52 assertEquals(3, result.get(2));
53 assertEquals(4, result.get(3));
54 assertEquals(5, result.get(4));
55
56
57 String[] stringArray = {"hello", "world", "test"};
58 result = arrayToList(stringArray);
59 assertEquals(3, result.size());
60 assertEquals("hello", result.get(0));
61 assertEquals("world", result.get(1));
62 assertEquals("test", result.get(2));
63 }
64
65 @Test
66 @DisplayName("arrayToList() - Empty and single element arrays")
67 void a02_arrayToListEdgeCases() {
68
69 int[] emptyArray = {};
70 var result = arrayToList(emptyArray);
71 assertEmpty(result);
72
73
74 String[] singleElement = {"single"};
75 result = arrayToList(singleElement);
76 assertList(result, "single");
77 }
78
79 @Test
80 @DisplayName("arrayToList() - Null values in array")
81 void a03_arrayToListWithNulls() {
82 String[] arrayWithNulls = {"first", null, "third", null};
83 var result = arrayToList(arrayWithNulls);
84 assertEquals(4, result.size());
85 assertEquals("first", result.get(0));
86 assertNull(result.get(1));
87 assertEquals("third", result.get(2));
88 assertNull(result.get(3));
89 }
90
91 @Test
92 @DisplayName("arrayToList() - Different primitive types")
93 void a04_arrayToListPrimitiveTypes() {
94
95 boolean[] boolArray = {true, false, true};
96 var result = arrayToList(boolArray);
97 assertList(result, "true","false","true");
98
99
100 double[] doubleArray = {1.5, 2.7, 3.14};
101 result = arrayToList(doubleArray);
102 assertList(result, "1.5","2.7","3.14");
103 }
104
105
106
107
108
109 @Test
110 @DisplayName("assertArg() - Valid expressions")
111 void b01_assertArgValidExpressions() {
112
113 assertDoesNotThrow(() -> assertArg(true, "Should not fail"));
114 assertDoesNotThrow(() -> assertArg(5 > 3, "Math should work"));
115 assertDoesNotThrow(() -> assertArg("test".length() == 4, "Length check"));
116 }
117
118 @Test
119 @DisplayName("assertArg() - Invalid expressions")
120 void b02_assertArgInvalidExpressions() {
121
122 var e = assertThrows(IllegalArgumentException.class, () -> assertArg(false, "This should fail"));
123 assertEquals("This should fail", e.getMessage());
124
125
126 e = assertThrows(IllegalArgumentException.class, () -> assertArg(5 < 3, "Value {0} should be greater than {1}", 5, 3));
127 assertEquals("Value 5 should be greater than 3", e.getMessage());
128 }
129
130 @Test
131 @DisplayName("assertArg() - Message formatting")
132 void b03_assertArgMessageFormatting() {
133 var e = assertThrows(IllegalArgumentException.class, () -> assertArg(false, "User {0} has invalid age {1}", "Alice", -5));
134 assertEquals("User Alice has invalid age -5", e.getMessage());
135 }
136
137 @Test
138 @DisplayName("assertArgNotNull() - Valid arguments")
139 void b04_assertArgNotNullValid() {
140 var result = assertArgNotNull("testParam", "validValue");
141 assertEquals("validValue", result);
142
143 var intResult = assertArgNotNull("number", 42);
144 assertEquals(Integer.valueOf(42), intResult);
145
146 var list = new ArrayList<>();
147 var listResult = assertArgNotNull("list", list);
148 assertSame(list, listResult);
149 }
150
151 @Test
152 @DisplayName("assertArgNotNull() - Null arguments")
153 void b05_assertArgNotNullInvalid() {
154 var e = assertThrows(IllegalArgumentException.class, () -> assertArgNotNull("username", null));
155 assertEquals("Argument 'username' cannot be null.", e.getMessage());
156
157 e = assertThrows(IllegalArgumentException.class, () -> assertArgNotNull("data", null));
158 assertEquals("Argument 'data' cannot be null.", e.getMessage());
159 }
160
161
162
163
164
165 @Test
166 @DisplayName("assertEqualsFailed() - Basic error creation")
167 void c01_assertEqualsFailedBasic() {
168 var error = assertEqualsFailed("expected", "actual", null);
169 assertContains("expected: <expected>", error.getMessage());
170 assertContains("but was: <actual>", error.getMessage());
171 assertEquals("expected", error.getExpected().getValue());
172 assertEquals("actual", error.getActual().getValue());
173 }
174
175 @Test
176 @DisplayName("assertEqualsFailed() - With custom message")
177 void c02_assertEqualsFailedWithMessage() {
178 var msgSupplier = fs("Custom context message");
179 var error = assertEqualsFailed(100, 200, msgSupplier);
180 assertContains("Custom context message", error.getMessage());
181 }
182
183 @Test
184 @DisplayName("assertEqualsFailed() - Null values")
185 void c03_assertEqualsFailedNullValues() {
186 var error = assertEqualsFailed(null, "actual", null);
187 assertContains("expected: <null>", error.getMessage());
188 assertContains("but was: <actual>", error.getMessage());
189
190 error = assertEqualsFailed("expected", null, null);
191 assertContains("expected: <expected>", error.getMessage());
192 assertContains("but was: <null>", error.getMessage());
193 }
194
195
196
197
198
199 @Test
200 @DisplayName("eq() - Basic equality with Objects.equals()")
201 void d01_eqBasicEquality() {
202 assertTrue(eq("hello", "hello"));
203 assertTrue(eq(null, null));
204 assertTrue(eq(42, 42));
205
206 assertFalse(eq("hello", "world"));
207 assertFalse(eq(null, "test"));
208 assertFalse(eq("test", null));
209 assertFalse(eq(42, 43));
210 }
211
212 @Test
213 @DisplayName("eq() - Custom predicate equality")
214 void d02_eqCustomPredicate() {
215
216 assertTrue(eq("HELLO", "hello", (s1, s2) -> s1.equalsIgnoreCase(s2)));
217 assertFalse(eq("HELLO", "world", (s1, s2) -> s1.equalsIgnoreCase(s2)));
218
219
220 var bean1 = new TestBean("Alice", 25, true);
221 var bean2 = new TestBean("Bob", 25, false);
222 assertTrue(eq(bean1, bean2, (b1, b2) -> b1.getAge() == b2.getAge()));
223 assertFalse(eq(bean1, bean2, (b1, b2) -> b1.getName().equals(b2.getName())));
224 }
225
226 @Test
227 @DisplayName("eq() - Null handling with custom predicate")
228 void d03_eqCustomPredicateNulls() {
229
230 assertTrue(eq(null, null, (s1, s2) -> s1.equals(s2)));
231
232
233 assertFalse(eq(null, "test", (s1, s2) -> s1.equals(s2)));
234 assertFalse(eq("test", null, (s1, s2) -> s1.equals(s2)));
235 }
236
237 @Test
238 @DisplayName("eq() - Reference equality optimization")
239 void d04_eqReferenceEquality() {
240 var same = "test";
241 assertTrue(eq(same, same, (s1, s2) -> { throw new RuntimeException("Should not be called"); }));
242 }
243
244 @Test
245 @DisplayName("ne() - Negation of equality")
246 void d05_neNegation() {
247 assertTrue(ne("hello", "world"));
248 assertTrue(ne(null, "test"));
249 assertTrue(ne("test", null));
250
251 assertFalse(ne("hello", "hello"));
252 assertFalse(ne(null, null));
253 assertFalse(ne(42, 42));
254 }
255
256
257
258
259
260 @Test
261 @DisplayName("escapeForJava() - Basic escape sequences")
262 void e01_escapeForJavaBasicEscapes() {
263 assertEquals("\\\"", escapeForJava("\""));
264 assertEquals("\\\\", escapeForJava("\\"));
265 assertEquals("\\n", escapeForJava("\n"));
266 assertEquals("\\r", escapeForJava("\r"));
267 assertEquals("\\t", escapeForJava("\t"));
268 assertEquals("\\f", escapeForJava("\f"));
269 assertEquals("\\b", escapeForJava("\b"));
270 }
271
272 @Test
273 @DisplayName("escapeForJava() - Combined sequences")
274 void e02_escapeForJavaCombined() {
275 var input = "Hello\nWorld\"Test\"";
276 var expected = "Hello\\nWorld\\\"Test\\\"";
277 assertEquals(expected, escapeForJava(input));
278
279 input = "Line1\r\nLine2\tTabbed";
280 expected = "Line1\\r\\nLine2\\tTabbed";
281 assertEquals(expected, escapeForJava(input));
282 }
283
284 @Test
285 @DisplayName("escapeForJava() - Unicode escapes")
286 void e03_escapeForJavaUnicode() {
287
288 assertEquals("\\u0001", escapeForJava("\u0001"));
289 assertEquals("\\u001f", escapeForJava("\u001f"));
290
291
292 assertEquals("\\u007f", escapeForJava("\u007f"));
293 assertEquals("\\u0080", escapeForJava("\u0080"));
294 assertEquals("\\u00ff", escapeForJava("\u00ff"));
295 }
296
297 @Test
298 @DisplayName("escapeForJava() - Normal characters unchanged")
299 void e04_escapeForJavaNormalChars() {
300 var normal = "ABCabc123!@#$%^&*()_+-=[]{}|;':,.<>?";
301 assertEquals(normal, escapeForJava(normal));
302 }
303
304 @Test
305 @DisplayName("escapeForJava() - Empty string")
306 void e05_escapeForJavaEmpty() {
307 assertEquals("", escapeForJava(""));
308 }
309
310
311
312
313
314 @Test
315 @DisplayName("f() - No parameters")
316 void f01_fNoParameters() {
317 assertEquals("Simple message", f("Simple message"));
318 assertEquals("", f(""));
319 }
320
321 @Test
322 @DisplayName("f() - With parameters")
323 void f02_fWithParameters() {
324 assertEquals("User Alice has 5 items", f("User {0} has {1} items", "Alice", 5));
325 assertEquals("Value: 42", f("Value: {0}", 42));
326 assertEquals("a, b, c", f("{0}, {1}, {2}", "a", "b", "c"));
327 }
328
329 @Test
330 @DisplayName("f() - Complex parameter types")
331 void f03_fComplexParameters() {
332
333 assertString(f("Flag: {0}", true), "Flag: true");
334 assertString(f("Flag: {0}", false), "Flag: false");
335
336
337 var list = Arrays.asList("a", "b", "c");
338 assertString(f("List: {0}", list), "List: [a, b, c]");
339
340
341 assertString(f("User {0} (age {1}) is active: {2}", "Alice", 25, true), "User Alice (age 25) is active: true");
342 }
343
344 @Test
345 @DisplayName("f() - Edge cases and special characters")
346 void f04_fEdgeCases() {
347
348 assertEquals("Pattern: .*items=\\[a,b\\].*", f("Pattern: {0}", ".*items=\\[a,b\\].*"));
349 assertEquals("Simple: no braces here", f("Simple: {0}", "no braces here"));
350 assertEquals("Mixed: string with data and 42", f("Mixed: {0} and {1}", "string with data", 42));
351
352
353 assertEquals("Number: 42", f("Number: {0}", 42));
354 assertEquals("Boolean: true", f("Boolean: {0}", true));
355
356
357 assertEquals("Text with 'single quotes'", f("Text with {0}", "'single quotes'"));
358 }
359
360 @Test
361 @DisplayName("fs() - Supplier creation")
362 void f05_fsSupplierCreation() {
363 var supplier = fs("User {0} has {1} items", "Bob", 3);
364 assertEquals("User Bob has 3 items", supplier.get());
365
366
367 assertEquals("User Bob has 3 items", supplier.get());
368 }
369
370 @Test
371 @DisplayName("fs() - No parameters supplier")
372 void f06_fsNoParameters() {
373 assertEquals("Static message", fs("Static message").get());
374 }
375
376
377
378
379
380 @Test
381 @DisplayName("getGlobMatchPattern() - Basic wildcard patterns")
382 void g01_getGlobMatchPatternBasicWildcards() {
383 var pattern = getGlobMatchPattern("user_*_temp");
384 assertTrue(pattern.matcher("user_alice_temp").matches());
385 assertTrue(pattern.matcher("user_bob_temp").matches());
386 assertTrue(pattern.matcher("user__temp").matches());
387 assertFalse(pattern.matcher("admin_alice_temp").matches());
388 assertFalse(pattern.matcher("user_alice_data").matches());
389 }
390
391 @Test
392 @DisplayName("getGlobMatchPattern() - Question mark patterns")
393 void g02_getGlobMatchPatternQuestionMark() {
394 var pattern = getGlobMatchPattern("file?.txt");
395 assertTrue(pattern.matcher("file1.txt").matches());
396 assertTrue(pattern.matcher("fileA.txt").matches());
397 assertTrue(pattern.matcher("file_.txt").matches());
398 assertFalse(pattern.matcher("file.txt").matches());
399 assertFalse(pattern.matcher("file12.txt").matches());
400 }
401
402 @Test
403 @DisplayName("getGlobMatchPattern() - Combined wildcards")
404 void g03_getGlobMatchPatternCombined() {
405 var pattern = getGlobMatchPattern("test_*.?");
406 assertTrue(pattern.matcher("test_data.1").matches());
407 assertTrue(pattern.matcher("test_long_filename.x").matches());
408 assertTrue(pattern.matcher("test_.a").matches());
409 assertFalse(pattern.matcher("test_data").matches());
410 assertFalse(pattern.matcher("test_data.ab").matches());
411 }
412
413 @Test
414 @DisplayName("getGlobMatchPattern() - Special regex characters")
415 void g04_getGlobMatchPatternSpecialChars() {
416
417 var pattern = getGlobMatchPattern("file[1].txt");
418 assertTrue(pattern.matcher("file[1].txt").matches());
419 assertFalse(pattern.matcher("file1.txt").matches());
420
421 pattern = getGlobMatchPattern("amount$100");
422 assertTrue(pattern.matcher("amount$100").matches());
423 assertFalse(pattern.matcher("amount100").matches());
424 }
425
426 @Test
427 @DisplayName("getGlobMatchPattern() - With flags")
428 void g05_getGlobMatchPatternWithFlags() {
429 var pattern = getGlobMatchPattern("USER_*", Pattern.CASE_INSENSITIVE);
430 assertTrue(pattern.matcher("user_alice").matches());
431 assertTrue(pattern.matcher("USER_BOB").matches());
432 assertTrue(pattern.matcher("User_Charlie").matches());
433 }
434
435 @Test
436 @DisplayName("getGlobMatchPattern() - Null input")
437 void g06_getGlobMatchPatternNull() {
438 assertNull(getGlobMatchPattern(null));
439 assertNull(getGlobMatchPattern(null, Pattern.CASE_INSENSITIVE));
440 }
441
442 @Test
443 @DisplayName("getGlobMatchPattern() - Empty and edge cases")
444 void g07_getGlobMatchPatternEdgeCases() {
445
446 var pattern = getGlobMatchPattern("");
447 assertTrue(pattern.matcher("").matches());
448 assertFalse(pattern.matcher("a").matches());
449
450
451 pattern = getGlobMatchPattern("*");
452 assertTrue(pattern.matcher("").matches());
453 assertTrue(pattern.matcher("anything").matches());
454
455 pattern = getGlobMatchPattern("?");
456 assertTrue(pattern.matcher("a").matches());
457 assertFalse(pattern.matcher("").matches());
458 assertFalse(pattern.matcher("ab").matches());
459 }
460
461
462
463
464
465 @Test
466 @DisplayName("safe() - Successful execution")
467 void h01_safeSuccessfulExecution() {
468 assertEquals("success", safe(() -> "success"));
469 assertEquals(Integer.valueOf(42), safe(() -> 42));
470 }
471
472 @Test
473 @DisplayName("safe() - Runtime exception passthrough")
474 void h02_safeRuntimeExceptionPassthrough() {
475 var original = new RuntimeException("Test runtime exception");
476 var thrown = assertThrows(RuntimeException.class, () -> safe(() -> { throw original; }));
477 assertSame(original, thrown);
478
479 var argException = new IllegalArgumentException("Invalid arg");
480 var thrownArg = assertThrows(IllegalArgumentException.class, () -> safe(() -> { throw argException; }));
481 assertSame(argException, thrownArg);
482 }
483
484 @Test
485 @DisplayName("safe() - Checked exception wrapping")
486 void h03_safeCheckedExceptionWrapping() {
487 var checkedException = new Exception("Checked exception");
488 var thrown = assertThrows(RuntimeException.class, () -> safe(() -> { throw checkedException; }));
489 assertSame(checkedException, thrown.getCause());
490 assertEquals(RuntimeException.class, thrown.getClass());
491 }
492
493
494
495
496
497 @Test
498 @DisplayName("t() - Various object types")
499 void i01_tVariousTypes() {
500 assertString(t("hello"), "String");
501 assertString(t(42), "Integer");
502 assertString(t(new ArrayList<>()), "ArrayList");
503 assertString(t(new HashMap<>()), "HashMap");
504 assertString(t(Pattern.compile("test")), "Pattern");
505 }
506
507 @Test
508 @DisplayName("t() - Null input")
509 void i02_tNullInput() {
510 assertNull(t(null));
511 }
512
513 @Test
514 @DisplayName("t() - Array types")
515 void i03_tArrayTypes() {
516 assertString(t(new String[0]), "String[]");
517 assertString(t(new int[0]), "int[]");
518 assertString(t(new Object[0]), "Object[]");
519 }
520
521
522
523
524
525 @Test
526 @DisplayName("tokenize() - Basic tokenization")
527 void j01_tokenizeBasic() {
528
529
530 assertNotNull(tokenize("name,age"));
531
532 }
533
534 @Test
535 @DisplayName("tokenize() - Nested fields")
536 void j02_tokenizeNested() {
537
538 assertNotNull(tokenize("name,address{street,city}"));
539
540 }
541
542
543
544
545
546
547
548
549 public static class TestBean {
550 private final String name;
551 private final int age;
552 private final boolean active;
553
554 public TestBean(String name, int age, boolean active) {
555 this.name = name;
556 this.age = age;
557 this.active = active;
558 }
559
560 public String getName() { return name; }
561 public int getAge() { return age; }
562 public boolean isActive() { return active; }
563
564 @Override
565 public boolean equals(Object obj) {
566 return (obj instanceof TestBean other) && eq(this, other, (x,y) -> eq(x.age, y.age) && eq(x.active, y.active) && eq(x.name, y.name));
567 }
568
569 @Override
570 public int hashCode() {
571 return Objects.hash(name, age, active);
572 }
573
574 @Override
575 public String toString() {
576 return f("TestBean{name=''{0}'', age=''{1}'', active=''{2}''}", name, age, active);
577 }
578 }
579 }