@@ -193,6 +193,117 @@ void rewardsButDoesNotPenalize() {
193193 .hasMessageContaining ("Expected penalty" );
194194 }
195195
196+ @ Test
197+ void hasNoImpact () {
198+ var solution = TestdataConstraintVerifierSolution .generateSolution (2 , 3 );
199+
200+ // Test with no entities - should have no impact
201+ assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::penalizeEveryEntity )
202+ .given ()
203+ .hasNoImpact ("There should be no impact" )).doesNotThrowAnyException ();
204+
205+ // Test without custom message - no entities
206+ assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::penalizeEveryEntity )
207+ .given ()
208+ .hasNoImpact ()).doesNotThrowAnyException ();
209+
210+ // Test with entities that trigger penalties - should fail
211+ assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::penalizeEveryEntity )
212+ .given (solution .getEntityList ().toArray ())
213+ .hasNoImpact ("There should be no impact" ))
214+ .isInstanceOf (AssertionError .class )
215+ .hasMessageContaining ("There should be no impact" )
216+ .hasMessageContaining ("Constraint" )
217+ .hasMessageContaining ("Expected" )
218+ .hasMessageContaining ("no impact" )
219+ .hasMessageContaining ("Actual impact" );
220+
221+ // Test with entities that trigger penalties - without custom message
222+ assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::penalizeEveryEntity )
223+ .given (solution .getEntityList ().toArray ())
224+ .hasNoImpact ())
225+ .hasMessageContaining ("Broken expectation" )
226+ .hasMessageContaining ("Constraint" )
227+ .hasMessageContaining ("Expected" )
228+ .hasMessageContaining ("no impact" )
229+ .hasMessageContaining ("Actual impact" );
230+
231+ // Test with entities that trigger rewards - should fail
232+ assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::rewardEveryEntity )
233+ .given (solution .getEntityList ().toArray ())
234+ .hasNoImpact ("There should be no impact" ))
235+ .isInstanceOf (AssertionError .class )
236+ .hasMessageContaining ("There should be no impact" )
237+ .hasMessageContaining ("Constraint" )
238+ .hasMessageContaining ("Expected" )
239+ .hasMessageContaining ("no impact" )
240+ .hasMessageContaining ("Actual impact" );
241+
242+ // Test with entities that trigger rewards - without custom message
243+ assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::rewardEveryEntity )
244+ .given (solution .getEntityList ().toArray ())
245+ .hasNoImpact ())
246+ .hasMessageContaining ("Broken expectation" )
247+ .hasMessageContaining ("Constraint" )
248+ .hasMessageContaining ("Expected" )
249+ .hasMessageContaining ("no impact" )
250+ .hasMessageContaining ("Actual impact" );
251+ }
252+
253+ @ Test
254+ void hasNoImpactWithMixedConstraint () {
255+ // Test mixed constraint with no entities - should have no impact
256+ assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::impactEveryEntity )
257+ .given ()
258+ .hasNoImpact ()).doesNotThrowAnyException ();
259+
260+ assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::impactEveryEntity )
261+ .given ()
262+ .hasNoImpact ("There should be no impact" )).doesNotThrowAnyException ();
263+
264+ // Test mixed constraint with entities that cause penalties - should fail
265+ assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::impactEveryEntity )
266+ .given (new TestdataConstraintVerifierFirstEntity ("A" , new TestdataValue ()))
267+ .hasNoImpact ("There should be no impact" ))
268+ .isInstanceOf (AssertionError .class )
269+ .hasMessageContaining ("There should be no impact" )
270+ .hasMessageContaining ("Constraint" )
271+ .hasMessageContaining ("Expected" )
272+ .hasMessageContaining ("no impact" )
273+ .hasMessageContaining ("Actual impact" );
274+
275+ // Test mixed constraint with entities that cause penalties - without custom message
276+ assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::impactEveryEntity )
277+ .given (new TestdataConstraintVerifierFirstEntity ("A" , new TestdataValue ()))
278+ .hasNoImpact ())
279+ .hasMessageContaining ("Broken expectation" )
280+ .hasMessageContaining ("Constraint" )
281+ .hasMessageContaining ("Expected" )
282+ .hasMessageContaining ("no impact" )
283+ .hasMessageContaining ("Actual impact" );
284+
285+ // Test mixed constraint with entities that cause rewards - should fail
286+ assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::impactEveryEntity )
287+ .given (new TestdataConstraintVerifierFirstEntity ("B" , new TestdataValue ()))
288+ .hasNoImpact ("There should be no impact" ))
289+ .isInstanceOf (AssertionError .class )
290+ .hasMessageContaining ("There should be no impact" )
291+ .hasMessageContaining ("Constraint" )
292+ .hasMessageContaining ("Expected" )
293+ .hasMessageContaining ("no impact" )
294+ .hasMessageContaining ("Actual impact" );
295+
296+ // Test mixed constraint with entities that cause rewards - without custom message
297+ assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::impactEveryEntity )
298+ .given (new TestdataConstraintVerifierFirstEntity ("B" , new TestdataValue ()))
299+ .hasNoImpact ())
300+ .hasMessageContaining ("Broken expectation" )
301+ .hasMessageContaining ("Constraint" )
302+ .hasMessageContaining ("Expected" )
303+ .hasMessageContaining ("no impact" )
304+ .hasMessageContaining ("Actual impact" );
305+ }
306+
196307 @ Test
197308 void impacts () {
198309 assertThatCode (() -> constraintVerifier .verifyThat (TestdataConstraintVerifierConstraintProvider ::impactEveryEntity )
0 commit comments