@@ -76,4 +76,92 @@ protected function invariantAlwaysFailTwo(): bool
7676 };
7777})
7878 ->group ('Unit ' )
79- ->throws (InvariantViolation::class, 'always fail one, always fail two ' );
79+ ->throws (InvariantViolation::class, 'Multiple invariant violations (2) ' );
80+
81+ test ('InvariantViolation should support multiple violations aggregation ' , function () {
82+ try {
83+ new class () {
84+ use HasInvariants;
85+
86+ public function __construct ()
87+ {
88+ $ this ->check ();
89+ }
90+
91+ protected function invariantAlwaysFailOne (): bool
92+ {
93+ return false ;
94+ }
95+
96+ protected function invariantAlwaysFailTwo (): bool
97+ {
98+ return false ;
99+ }
100+
101+ protected function invariantAlwaysFailThree (): bool
102+ {
103+ return false ;
104+ }
105+ };
106+ } catch (InvariantViolation $ e ) {
107+ expect ($ e ->hasMultipleViolations ())->toBeTrue ()
108+ ->and ($ e ->getViolationCount ())->toBe (3 )
109+ ->and ($ e ->getViolations ())->toHaveCount (3 )
110+ ->and ($ e ->getViolations ())->toContain ('always fail one ' )
111+ ->and ($ e ->getViolations ())->toContain ('always fail two ' )
112+ ->and ($ e ->getViolations ())->toContain ('always fail three ' )
113+ ->and ($ e ->getMessage ())->toContain ('Multiple invariant violations (3) ' );
114+ }
115+ })
116+ ->group ('Unit ' );
117+
118+ test ('InvariantViolation::fromViolations should handle single violation cleanly ' , function () {
119+ try {
120+ new class () {
121+ use HasInvariants;
122+
123+ public function __construct ()
124+ {
125+ $ this ->check ();
126+ }
127+
128+ protected function invariantSingleFailure (): bool
129+ {
130+ return false ;
131+ }
132+ };
133+ } catch (InvariantViolation $ e ) {
134+ expect ($ e ->hasMultipleViolations ())->toBeFalse ()
135+ ->and ($ e ->getViolationCount ())->toBe (1 )
136+ ->and ($ e ->getViolations ())->toBe (['single failure ' ])
137+ ->and ($ e ->getMessage ())->toBe ('single failure ' )
138+ ->and ($ e ->getMessage ())->not ->toContain ('Multiple invariant violations ' );
139+ }
140+ })
141+ ->group ('Unit ' );
142+
143+ test ('InvariantViolation::fromViolations should format multiple violations ' , function () {
144+ $ violations = ['First error ' , 'Second error ' , 'Third error ' ];
145+ $ exception = InvariantViolation::fromViolations ($ violations );
146+
147+ expect ($ exception )->toBeInstanceOf (InvariantViolation::class)
148+ ->and ($ exception ->hasMultipleViolations ())->toBeTrue ()
149+ ->and ($ exception ->getViolationCount ())->toBe (3 )
150+ ->and ($ exception ->getViolations ())->toBe ($ violations )
151+ ->and ($ exception ->getMessage ())->toContain ('Multiple invariant violations (3) ' )
152+ ->and ($ exception ->getMessage ())->toContain ('First error ' )
153+ ->and ($ exception ->getMessage ())->toContain ('Second error ' )
154+ ->and ($ exception ->getMessage ())->toContain ('Third error ' );
155+ })
156+ ->group ('Unit ' );
157+
158+ test ('InvariantViolation::fromViolations with single violation should not show count ' , function () {
159+ $ exception = InvariantViolation::fromViolations (['Single error message ' ]);
160+
161+ expect ($ exception )->toBeInstanceOf (InvariantViolation::class)
162+ ->and ($ exception ->hasMultipleViolations ())->toBeFalse ()
163+ ->and ($ exception ->getViolationCount ())->toBe (1 )
164+ ->and ($ exception ->getViolations ())->toBe (['Single error message ' ])
165+ ->and ($ exception ->getMessage ())->toBe ('Single error message ' );
166+ })
167+ ->group ('Unit ' );
0 commit comments