1616
1717package br .com .fluentvalidator ;
1818
19+ import br .com .fluentvalidator .context .Error ;
20+ import br .com .fluentvalidator .context .ProcessorContext ;
21+ import br .com .fluentvalidator .context .ValidationResult ;
22+ import br .com .fluentvalidator .model .Bill ;
23+ import br .com .fluentvalidator .model .Boy ;
24+ import br .com .fluentvalidator .model .Girl ;
25+ import br .com .fluentvalidator .model .Parent ;
26+ import br .com .fluentvalidator .validator .ValidatorBill ;
27+ import br .com .fluentvalidator .validator .ValidatorErrorPredicate ;
28+ import br .com .fluentvalidator .validator .ValidatorParent ;
29+ import org .junit .jupiter .api .Test ;
30+
31+ import java .time .LocalDate ;
32+ import java .util .ArrayList ;
33+ import java .util .Arrays ;
34+ import java .util .Collection ;
35+ import java .util .List ;
36+ import java .util .concurrent .ConcurrentLinkedQueue ;
37+ import java .util .concurrent .ExecutionException ;
38+ import java .util .concurrent .ExecutorService ;
39+ import java .util .concurrent .Executors ;
40+ import java .util .concurrent .TimeUnit ;
41+
1942import static br .com .fluentvalidator .predicate .LogicalPredicate .not ;
2043import static br .com .fluentvalidator .predicate .StringPredicate .stringEmptyOrNull ;
2144import static org .hamcrest .MatcherAssert .assertThat ;
2750import static org .hamcrest .Matchers .hasSize ;
2851import static org .hamcrest .Matchers .not ;
2952import static org .hamcrest .Matchers .nullValue ;
53+ import static org .junit .jupiter .api .Assertions .assertEquals ;
3054import static org .junit .jupiter .api .Assertions .assertFalse ;
55+ import static org .junit .jupiter .api .Assertions .assertThrows ;
3156import static org .junit .jupiter .api .Assertions .assertTrue ;
3257
33- import java .time .LocalDate ;
34- import java .util .ArrayList ;
35- import java .util .Arrays ;
36- import java .util .Collection ;
37- import java .util .List ;
38- import java .util .concurrent .ConcurrentLinkedQueue ;
39- import java .util .concurrent .ExecutionException ;
40- import java .util .concurrent .ExecutorService ;
41- import java .util .concurrent .Executors ;
42- import java .util .concurrent .TimeUnit ;
43-
44- import org .junit .jupiter .api .Test ;
45-
46- import br .com .fluentvalidator .context .Error ;
47- import br .com .fluentvalidator .context .ValidationResult ;
48- import br .com .fluentvalidator .model .Bill ;
49- import br .com .fluentvalidator .model .Boy ;
50- import br .com .fluentvalidator .model .Girl ;
51- import br .com .fluentvalidator .model .Parent ;
52- import br .com .fluentvalidator .validator .ValidatorBill ;
53- import br .com .fluentvalidator .validator .ValidatorParent ;
54-
5558class ValidatorTest {
5659
5760 @ Test
@@ -671,7 +674,44 @@ void testSuccessWhenBillDueDateIsExactlyThreeYears() {
671674 assertTrue (validate .isValid ());
672675 }
673676
674- class StringValidator extends AbstractValidator <String > {
677+ @ Test
678+ public void testSuccessWhenBrokenPredicate () {
679+ final Validator <Bill > validator = new ValidatorErrorPredicate ();
680+
681+ // First validation: bill with null description causes NullPointerException
682+ // This simulates a corrupted or incomplete data scenario
683+ final Bill billWithNullDescription = new Bill (null , 0F , LocalDate .now ());
684+
685+ assertThrows (NullPointerException .class , () -> validator .validate (billWithNullDescription ));
686+
687+ // Second validation: valid electricity bill with numeric code
688+ // ValidationContext and ProcessorContext should be clean after the exception
689+ final Bill electricityBill = new Bill ("12345" , 150.75F , LocalDate .now ().plusDays (30 ));
690+
691+ assertTrue (validator .validate (electricityBill ).isValid ());
692+
693+ }
694+
695+ @ Test
696+ public void testSuccessWhenBrokenCollectionPredicate () {
697+ final Validator <Bill > validator = new ValidatorErrorPredicate ();
698+
699+ // First validation: bill with non-numeric description causes NumberFormatException
700+ // when the validator tries to parse it as integer in the collection rule
701+ final Bill billWithInvalidCodes = new Bill ("WATER-BILL" , 85.50F , LocalDate .now ());
702+
703+ assertThrows (NumberFormatException .class , () -> validator .validate (billWithInvalidCodes ));
704+
705+ // Second validation: valid bill with numeric service codes separated by comma
706+ // ValidationContext and ProcessorContext should be clean after the exception
707+ final Bill billWithValidCodes = new Bill ("100,200,300" , 250.00F , LocalDate .now ().plusDays (15 ));
708+
709+ assertEquals (0 , (int ) ProcessorContext .get ().get ());
710+ assertTrue (validator .validate (billWithValidCodes ).isValid ());
711+
712+ }
713+
714+ static class StringValidator extends AbstractValidator <String > {
675715
676716 @ Override
677717 public void rules () {
@@ -687,7 +727,7 @@ public void rules() {
687727
688728 }
689729
690- class String2Validator extends AbstractValidator <String > {
730+ static class String2Validator extends AbstractValidator <String > {
691731
692732 @ Override
693733 public void rules () {
@@ -698,7 +738,7 @@ public void rules() {
698738
699739 }
700740
701- class String3Validator extends AbstractValidator <Collection <String >> {
741+ static class String3Validator extends AbstractValidator <Collection <String >> {
702742
703743 @ Override
704744 public void rules () {
0 commit comments