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