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.junit.jupiter.api.Assertions.*;
21
22 import java.util.*;
23 import java.util.function.*;
24 import java.util.stream.*;
25
26 import org.apache.juneau.*;
27 import org.junit.jupiter.api.*;
28 import org.opentest4j.*;
29
30
31
32
33
34
35
36
37 class BctAssertions_Test extends TestBase {
38
39
40
41
42
43 @Nested
44 class A_assertionArgs extends TestBase {
45
46 @Test
47 void a01_args() {
48 var args = args();
49 assertNotNull(args);
50 assertTrue(args.getBeanConverter().isEmpty());
51 assertNull(args.getMessage());
52 }
53 }
54
55
56
57
58
59 @Nested
60 class B_assertBean extends TestBase {
61
62 @Test
63 void b01_basicAssertion() {
64 var person = new TestPerson("Alice", 25);
65
66
67 assertDoesNotThrow(() -> assertBean(person, "name", "Alice"));
68 }
69
70 @Test
71 void b02_withCustomArgs() {
72 var person = new TestPerson("Bob", 30);
73 var args = args().setMessage("Custom message");
74
75 assertDoesNotThrow(() -> assertBean(args, person, "name", "Bob"));
76 }
77
78 @Test
79 void b03_nullObject() {
80 var e = assertThrows(AssertionFailedError.class, () -> assertBean(null, "name", "test"));
81 assertContains("Actual was null", e.getMessage());
82 }
83
84 @Test
85 void b04_assertionFailure() {
86 var person = new TestPerson("Eve", 28);
87
88 var e = assertThrows(AssertionFailedError.class, () -> assertBean(person, "name", "Wrong"));
89 assertContains("expected: <Wrong>", e.getMessage());
90 assertContains("but was: <Eve>", e.getMessage());
91 }
92
93 @Test
94 void b05_customMessage() {
95 var person = new TestPerson("Charlie", 35);
96 var args = args().setMessage("Custom error message");
97
98 var e = assertThrows(AssertionFailedError.class, () -> assertBean(args, person, "name", "Wrong"));
99 assertContains("Custom error message", e.getMessage());
100 }
101 }
102
103
104
105
106
107 @Nested
108 class C_assertBeans extends TestBase {
109
110 @Test
111 void c01_basicBeansAssertion() {
112 var people = List.of(new TestPerson("Alice", 25), new TestPerson("Bob", 30));
113
114 assertDoesNotThrow(() -> assertBeans(people, "name", "Alice", "Bob"));
115 }
116
117 @Test
118 void c02_withCustomArgs() {
119 var people = List.of(new TestPerson("Charlie", 35));
120 var args = args().setMessage("Custom beans message");
121
122 assertDoesNotThrow(() -> assertBeans(args, people, "name", "Charlie"));
123 }
124
125 @Test
126 void c03_emptyCollection() {
127 assertDoesNotThrow(() -> assertBeans(List.of(), "name"));
128 }
129
130 @Test
131 void c04_sizeMismatch() {
132 var people = List.of(new TestPerson("Dave", 40));
133
134 var e = assertThrows(AssertionFailedError.class, () -> assertBeans(people, "name", "Dave", "Extra"));
135 assertContains("Wrong number of beans", e.getMessage());
136 }
137
138 @Test
139 void c05_contentMismatch() {
140 var people = List.of(new TestPerson("Eve", 28));
141
142 var e = assertThrows(AssertionFailedError.class, () -> assertBeans(people, "name", "Wrong"));
143 assertContains("Bean at row", e.getMessage());
144 }
145
146 @Test
147 void c06_nullCollection() {
148 var e = assertThrows(AssertionFailedError.class, () -> assertBeans((Object)null, "name", "test"));
149 assertContains("Value was null", e.getMessage());
150 }
151 }
152
153
154
155
156
157 @Nested
158 class D_assertMapped extends TestBase {
159
160 @Test
161 void d01_basicMapping() {
162 var person = new TestPerson("Grace", 27);
163 BiFunction<TestPerson, String, Object> mapper = (p, prop) -> p.getName().toUpperCase();
164
165 assertDoesNotThrow(() -> assertMapped(person, mapper, "upperName", "GRACE"));
166 }
167
168 @Test
169 void d02_withCustomArgs() {
170 var person = new TestPerson("Henry", 45);
171 var args = args().setMessage("Custom mapped message");
172 BiFunction<TestPerson, String, Object> mapper = (p, prop) -> p.getName();
173
174 assertDoesNotThrow(() -> assertMapped(args, person, mapper, "name", "Henry"));
175 }
176
177 @Test
178 void d03_mappingMismatch() {
179 var person = new TestPerson("Jack", 50);
180 BiFunction<TestPerson, String, Object> mapper = (p, prop) -> p.getName();
181
182 var e = assertThrows(AssertionFailedError.class, () -> assertMapped(person, mapper, "name", "Wrong"));
183 assertContains("expected: <Wrong>", e.getMessage());
184 assertContains("but was: <Jack>", e.getMessage());
185 }
186 }
187
188
189
190
191
192 @Nested
193 class E_assertContains extends TestBase {
194
195 @Test
196 void e01_basicContains() {
197 assertDoesNotThrow(() -> assertContains("Hello", "Hello World"));
198 }
199
200 @Test
201 void e02_withCustomArgs() {
202 var args = args().setMessage("Custom contains message");
203
204 assertDoesNotThrow(() -> assertContains(args, "Test", "Test String"));
205 }
206
207 @Test
208 void e03_doesNotContain() {
209 var e = assertThrows(AssertionFailedError.class, () -> assertContains("Missing", "Hello World"));
210 assertContains("String did not contain expected substring", e.getMessage());
211 }
212
213 @Test
214 void e04_nullValue() {
215 var e = assertThrows(IllegalArgumentException.class, () -> assertContains("test", null));
216 assertContains("cannot be null", e.getMessage());
217 }
218 }
219
220
221
222
223
224 @Nested
225 class F_assertContainsAll extends TestBase {
226
227 @Test
228 void f01_basicContainsAll() {
229 assertDoesNotThrow(() -> assertContainsAll("Hello World", "Hello", "World"));
230 }
231
232 @Test
233 void f02_withCustomArgs() {
234 var args = args().setMessage("Custom contains all message");
235
236 assertDoesNotThrow(() -> assertContainsAll(args, (Object)"Testing", "Test"));
237 }
238
239 @Test
240 void f03_missingSubstring() {
241 var e = assertThrows(AssertionFailedError.class, () -> assertContainsAll("Hello World", "Hello", "Missing"));
242 assertContains("String did not contain expected substring", e.getMessage());
243 assertContains("Missing", e.getMessage());
244 }
245
246 @Test
247 void f04_nullValue() {
248 var e = assertThrows(AssertionFailedError.class, () -> assertContainsAll((Object)null, "test"));
249 assertContains("Value was null", e.getMessage());
250 }
251
252 @Test
253 void f05_multipleErrors() {
254
255 var text = "Hello World Testing";
256 var expected = new String[]{"Hello", "Missing1", "World", "Missing2", "Testing"};
257
258 var e = assertThrows(AssertionFailedError.class, () -> assertContainsAll(text, expected));
259
260
261 var message = e.getMessage();
262 assertContains("2 substring assertions failed", message);
263 assertContains("String did not contain expected substring", message);
264
265
266 assertContains("Missing1", message);
267 assertContains("Missing2", message);
268
269
270 assertContains("Hello World Testing", message);
271 }
272
273 @Test
274 void f06_singleError() {
275
276 var text = "Hello World";
277 var expected = new String[]{"Hello", "Missing", "World"};
278
279 var e = assertThrows(AssertionFailedError.class, () -> assertContainsAll(text, expected));
280
281
282 var message = e.getMessage();
283 assertDoesNotThrow(() -> assertTrue(!message.contains("1 substring assertions failed")));
284 assertContains("String did not contain expected substring", message);
285 assertContains("Missing", message);
286 }
287 }
288
289
290
291
292
293 @Nested
294 class G_assertEmpty extends TestBase {
295
296 @Test
297 void g01_basicEmpty() {
298 assertDoesNotThrow(() -> assertEmpty(List.of()));
299 assertDoesNotThrow(() -> assertEmpty(new String[0]));
300 }
301
302 @Test
303 void g02_withCustomArgs() {
304 var args = args().setMessage("Custom empty message");
305
306 assertDoesNotThrow(() -> assertEmpty(args, List.of()));
307 }
308
309 @Test
310 void g03_notEmpty() {
311 var e = assertThrows(AssertionFailedError.class, () -> assertEmpty(List.of("item")));
312 assertContains("Value was not empty", e.getMessage());
313 }
314
315 @Test
316 void g04_nullValue() {
317 var e = assertThrows(AssertionError.class, () -> assertEmpty(null));
318 assertContains("Value was null", e.getMessage());
319 }
320 }
321
322
323
324
325
326 @Nested
327 class H_assertList extends TestBase {
328
329 @Test
330 void h01_basicList() {
331 assertDoesNotThrow(() -> assertList(List.of("a", "b", "c"), "a", "b", "c"));
332 }
333
334 @Test
335 void h02_withCustomArgs() {
336 var args = args().setMessage("Custom list message");
337
338 assertDoesNotThrow(() -> assertList(args, List.of(1, 2), 1, 2));
339 }
340
341 @Test
342 void h03_sizeMismatch() {
343 var e = assertThrows(AssertionFailedError.class, () -> assertList(List.of("a", "b"), "a", "b", "c"));
344 assertContains("Wrong list length", e.getMessage());
345 }
346
347 @Test
348 void h04_elementMismatch() {
349 var e = assertThrows(AssertionFailedError.class, () -> assertList(List.of("a", "b"), "a", "wrong"));
350 assertContains("Element at index 1 did not match", e.getMessage());
351 }
352
353 @Test
354 void h05_nullValue() {
355 var e = assertThrows(IllegalArgumentException.class, () -> assertList(null, "test"));
356 assertContains("cannot be null", e.getMessage());
357 }
358
359 @Test
360 void h06_predicateValidation() {
361
362 var args = args().setMessage("Custom predicate message");
363 var numbers = Arrays.asList(1, 2, 3, 4, 5);
364
365
366 assertDoesNotThrow(() -> assertList(args, numbers,
367 (Predicate<Integer>) x -> x == 1,
368 (Predicate<Integer>) x -> x > 1,
369 "3",
370 (Predicate<Integer>) x -> x % 2 == 0,
371 (Predicate<Integer>) x -> x == 5
372 ));
373
374
375 var singleNumber = Arrays.asList(1);
376 var e = assertThrows(AssertionFailedError.class, () ->
377 assertList(args, singleNumber, (Predicate<Integer>) x -> x == 99));
378 assertContains("Element at index 0 did not pass predicate", e.getMessage());
379 assertContains("actual: <1>", e.getMessage());
380 }
381
382 @Test
383 void h07_multipleErrors() {
384
385 var list = Arrays.asList("a", "wrong1", "c", "wrong2", "e");
386 var expected = new Object[]{"a", "b", "c", "d", "e"};
387
388 var e = assertThrows(AssertionFailedError.class, () -> assertList(list, expected));
389
390
391 var message = e.getMessage();
392 assertContains("2 list assertions failed", message);
393 assertContains("Element at index 1 did not match", message);
394 assertContains("Element at index 3 did not match", message);
395
396
397 assertContains("expected: <b>", message);
398 assertContains("but was: <wrong1>", message);
399 assertContains("expected: <d>", message);
400 assertContains("but was: <wrong2>", message);
401 }
402
403 @Test
404 void h08_singleError() {
405
406 var list = Arrays.asList("a", "wrong", "c");
407 var expected = new Object[]{"a", "b", "c"};
408
409 var e = assertThrows(AssertionFailedError.class, () -> assertList(list, expected));
410
411
412 var message = e.getMessage();
413 assertDoesNotThrow(() -> assertTrue(!message.contains("1 list assertions failed")));
414 assertContains("Element at index 1 did not match", message);
415 }
416 }
417
418
419
420
421
422 @Nested
423 class H_assertMap extends TestBase {
424
425 @Test
426 void h01_basicMap() {
427 assertDoesNotThrow(() -> assertMap(Map.of("a", "1", "b", "2"), "a=1", "b=2"));
428 }
429
430 @Test
431 void h02_withCustomArgs() {
432 var args = args().setMessage("Custom map message");
433 assertDoesNotThrow(() -> assertMap(args, Map.of("key", "value"), "key=value"));
434 }
435
436 @Test
437 void h03_sizeMismatch() {
438 var e = assertThrows(AssertionFailedError.class, () -> assertMap(Map.of("a", "1"), "a=1", "b=2"));
439 assertContains("Wrong list length", e.getMessage());
440 }
441
442 @Test
443 void h04_elementMismatch() {
444 var e = assertThrows(AssertionFailedError.class, () -> assertMap(Map.of("a", "1", "b", "2"), "a=1", "b=wrong"));
445 assertContains("Element at index 1 did not match", e.getMessage());
446 }
447
448 @Test
449 void h05_nullValue() {
450 var e = assertThrows(AssertionFailedError.class, () -> assertMap(null, "test"));
451 assertContains("Value was null", e.getMessage());
452 }
453
454 @Test
455 void h06_predicateValidation() {
456
457 var args = args().setMessage("Custom predicate message");
458 var map = Map.of("count", 42, "enabled", true);
459
460
461 assertDoesNotThrow(() -> assertMap(args, map,
462 (Predicate<Map.Entry<String, Object>>) entry -> entry.getKey().equals("count") && entry.getValue().equals(42),
463 (Predicate<Map.Entry<String, Object>>) entry -> entry.getKey().equals("enabled") && entry.getValue().equals(true)
464 ));
465
466
467 var singleEntryMap = Map.of("count", 1);
468 var e = assertThrows(AssertionFailedError.class, () ->
469 assertMap(args, singleEntryMap, (Predicate<Map.Entry<String, Object>>) entry -> entry.getValue().equals(99)));
470 assertContains("Element at index 0 did not pass predicate", e.getMessage());
471 assertContains("actual: <count=1>", e.getMessage());
472 }
473
474 @Test
475 void h07_multipleErrors() {
476
477 var map = Map.of("a", "1", "b", "wrong1", "c", "3", "d", "wrong2");
478 var expected = new Object[]{"a=1", "b=2", "c=3", "d=4"};
479
480 var e = assertThrows(AssertionFailedError.class, () -> assertMap(map, expected));
481
482
483 var message = e.getMessage();
484 assertContains("2 list assertions failed", message);
485 assertContains("Element at index 1 did not match", message);
486 assertContains("Element at index 3 did not match", message);
487
488
489 assertContains("expected: <b=2>", message);
490 assertContains("but was: <b=wrong1>", message);
491 assertContains("expected: <d=4>", message);
492 assertContains("but was: <d=wrong2>", message);
493 }
494
495 @Test
496 void h08_singleError() {
497
498 var map = Map.of("a", "1", "b", "wrong");
499 var e = assertThrows(AssertionFailedError.class, () -> assertMap(map, "a=1", "b=2"));
500
501
502 var message = e.getMessage();
503 assertDoesNotThrow(() -> assertContains("Element at index 1 did not match", message));
504 assertDoesNotThrow(() -> assertContains("expected: <b=2>", message));
505 assertDoesNotThrow(() -> assertContains("but was: <b=wrong>", message));
506 }
507
508 @Test
509 void h09_nestedMaps() {
510
511 var nestedMap = Map.of("a", Map.of("b", 1));
512 assertDoesNotThrow(() -> assertMap(nestedMap, "a={b=1}"));
513 }
514
515 @Test
516 void h10_mapsWithArrays() {
517
518 var mapWithArrays = Map.of("a", Map.of("b", new Integer[]{1, 2}));
519 assertDoesNotThrow(() -> assertMap(mapWithArrays, "a={b=[1,2]}"));
520 }
521
522 @Test
523 void h11_mapOrdering() {
524
525 var unorderedMap = new HashMap<String, String>();
526 unorderedMap.put("z", "last");
527 unorderedMap.put("a", "first");
528 unorderedMap.put("m", "middle");
529
530
531 assertDoesNotThrow(() -> assertMap(unorderedMap, "a=first", "m=middle", "z=last"));
532 }
533
534 @Test
535 void h12_linkedHashMapOrdering() {
536
537 var linkedMap = new LinkedHashMap<String, String>();
538 linkedMap.put("first", "1");
539 linkedMap.put("second", "2");
540 linkedMap.put("third", "3");
541
542 assertDoesNotThrow(() -> assertMap(linkedMap, "first=1", "second=2", "third=3"));
543 }
544
545 @Test
546 void h13_treeMapOrdering() {
547
548 var treeMap = new TreeMap<String, String>();
549 treeMap.put("zebra", "last");
550 treeMap.put("apple", "first");
551 treeMap.put("monkey", "middle");
552
553
554 assertDoesNotThrow(() -> assertMap(treeMap, "apple=first", "monkey=middle", "zebra=last"));
555 }
556 }
557
558
559
560
561
562 @Nested
563 class I_assertNotEmpty extends TestBase {
564
565 @Test
566 void i01_basicNotEmpty() {
567 assertDoesNotThrow(() -> assertNotEmpty(List.of("item")));
568 assertDoesNotThrow(() -> assertNotEmpty(new String[]{"item"}));
569 }
570
571 @Test
572 void i02_withCustomArgs() {
573 var args = args().setMessage("Custom not empty message");
574
575 assertDoesNotThrow(() -> assertNotEmpty(args, List.of("content")));
576 }
577
578 @Test
579 void i03_actuallyEmpty() {
580 var e = assertThrows(AssertionFailedError.class, () -> assertNotEmpty(List.of()));
581 assertContains("Value was empty", e.getMessage());
582 }
583
584 @Test
585 void i04_nullValue() {
586 var e = assertThrows(AssertionError.class, () -> assertNotEmpty(null));
587 assertContains("Value was null", e.getMessage());
588 }
589 }
590
591
592
593
594
595 @Nested
596 class J_assertSize extends TestBase {
597
598 @Test
599 void j01_basicSizes() {
600 assertDoesNotThrow(() -> assertSize(3, List.of("a", "b", "c")));
601 assertDoesNotThrow(() -> assertSize(5, "hello"));
602 }
603
604 @Test
605 void j02_withCustomArgs() {
606 var args = args().setMessage("Custom size message");
607
608 assertDoesNotThrow(() -> assertSize(args, 2, List.of("a", "b")));
609 }
610
611 @Test
612 void j03_wrongSize() {
613 var e = assertThrows(AssertionFailedError.class, () -> assertSize(5, List.of("a", "b", "c")));
614 assertContains("Value not expected size", e.getMessage());
615 }
616
617 @Test
618 void j04_nullValue() {
619 var e = assertThrows(AssertionError.class, () -> assertSize(0, null));
620 assertContains("Value was null", e.getMessage());
621 }
622 }
623
624
625
626
627
628 @Nested
629 class K_assertString extends TestBase {
630
631 @Test
632 void k01_basicString() {
633 assertDoesNotThrow(() -> assertString("hello", "hello"));
634 }
635
636 @Test
637 void k02_withCustomArgs() {
638 var args = args().setMessage("Custom string message");
639
640 assertDoesNotThrow(() -> assertString(args, "test", "test"));
641 }
642
643 @Test
644 void k03_stringMismatch() {
645 var e = assertThrows(AssertionFailedError.class, () -> assertString("expected", "actual"));
646 assertContains("expected: <expected>", e.getMessage());
647 assertContains("but was: <actual>", e.getMessage());
648 }
649
650 @Test
651 void k04_nullValue() {
652 var e = assertThrows(AssertionError.class, () -> assertString("test", null));
653 assertContains("Value was null", e.getMessage());
654 }
655 }
656
657
658
659
660
661 @Nested
662 class L_assertMatchesGlob extends TestBase {
663
664 @Test
665 void l01_basicGlobPatterns() {
666 assertDoesNotThrow(() -> assertMatchesGlob("hello*", "hello world"));
667 assertDoesNotThrow(() -> assertMatchesGlob("h?llo", "hello"));
668 }
669
670 @Test
671 void l02_withCustomArgs() {
672 var args = args().setMessage("Custom glob message");
673
674 assertDoesNotThrow(() -> assertMatchesGlob(args, "test*", "testing"));
675 }
676
677 @Test
678 void l03_patternMismatch() {
679 var e = assertThrows(AssertionFailedError.class, () -> assertMatchesGlob("hello*", "goodbye"));
680 assertContains("Pattern didn't match", e.getMessage());
681 assertContains("pattern: <hello*>", e.getMessage());
682 assertContains("but was: <goodbye>", e.getMessage());
683 }
684
685 @Test
686 void l04_nullValue() {
687 var e = assertThrows(AssertionError.class, () -> assertMatchesGlob("*", null));
688 assertContains("Value was null", e.getMessage());
689 }
690
691 @Test
692 void l05_nullPattern() {
693 var e = assertThrows(IllegalArgumentException.class, () -> assertMatchesGlob(null, "test"));
694 assertContains("cannot be null", e.getMessage());
695 }
696 }
697
698
699
700
701
702 static class TestPerson {
703 private final String name;
704 private final int age;
705 private TestAddress address;
706
707 TestPerson(String name, int age) {
708 this(name, age, null);
709 }
710
711 TestPerson(String name, int age, TestAddress address) {
712 this.name = name;
713 this.age = age;
714 this.address = address;
715 }
716
717 String getName() { return name; }
718 int getAge() { return age; }
719 TestAddress getAddress() { return address; }
720 void setAddress(TestAddress address) { this.address = address; }
721
722 @Override
723 public String toString() {
724 return "TestPerson{name='" + name + "', age=" + age + "}";
725 }
726 }
727
728 static class TestAddress {
729 private final String street;
730 private final String city;
731
732 TestAddress(String street, String city) {
733 this.street = street;
734 this.city = city;
735 }
736
737 String getStreet() { return street; }
738 String getCity() { return city; }
739
740 @Override
741 public String toString() {
742 return "TestAddress{street='" + street + "', city='" + city + "'}";
743 }
744 }
745
746
747
748
749
750 @Nested
751 class H_enhancedEdgeCases extends TestBase {
752
753 @Test
754 void h01_assertListWithMixedTypes() {
755
756 var mixedList = Arrays.asList("string", 42, true, 3.14, null);
757
758 assertList(mixedList, "string", 42, true, 3.14, null);
759 assertSize(5, mixedList);
760 assertContains("42", mixedList);
761 assertContains("true", mixedList);
762 }
763
764 @Test
765 void h02_assertMatchesGlobWithComplexPatterns() {
766
767 var testStrings = Arrays.asList(
768 "hello.txt", "test_file.log", "document.pdf",
769 "IMG_001.jpg", "data.xml", "script.js"
770 );
771
772 assertMatchesGlob("*.txt", testStrings.get(0));
773 assertMatchesGlob("test_*", testStrings.get(1));
774 assertMatchesGlob("*.pdf", testStrings.get(2));
775 assertMatchesGlob("IMG_???.jpg", testStrings.get(3));
776 assertMatchesGlob("*.xml", testStrings.get(4));
777 assertMatchesGlob("script.*", testStrings.get(5));
778 }
779
780 @Test
781 void h03_assertEmptyWithVariousEmptyTypes() {
782
783 assertEmpty(Arrays.asList());
784 assertEmpty(new HashMap<>());
785 assertEmpty(new HashSet<>());
786 assertEmpty(Optional.empty());
787 }
788
789 @Test
790 void h04_assertNotEmptyWithVariousNonEmptyTypes() {
791
792 assertNotEmpty(Arrays.asList("item"));
793 assertNotEmpty(Map.of("key", "value"));
794 assertNotEmpty(Set.of("element"));
795 assertNotEmpty(Optional.of("value"));
796 }
797
798 @Test
799 void h05_assertContainsAllWithPartialMatches() {
800
801 var text = "The quick brown fox jumps over the lazy dog";
802
803 assertContainsAll(text, "quick", "fox", "lazy");
804 assertContainsAll(text, "The", "dog");
805
806
807 var complexObj = Map.of(
808 "description", "This is a test with multiple keywords: alpha, beta, gamma"
809 );
810 assertContainsAll(complexObj, "alpha", "beta", "gamma", "keywords");
811 }
812
813 @Test
814 void h06_assertSizeWithCustomListifiableObjects() {
815
816 var stringArray = new String[]{"a", "b", "c"};
817 var intArray = new int[]{1, 2, 3, 4, 5};
818
819 assertSize(3, stringArray);
820 assertSize(5, intArray);
821
822
823 assertSize(4, Stream.of("w", "x", "y", "z"));
824 }
825 }
826 }