@@ -183,16 +183,40 @@ public function invalidSubjects(): array
183183 ];
184184 }
185185
186+ /**
187+ * Methods that use assertThat(logicalOr()) in order to perform negative assertions.
188+ */
189+ public function logicalOrMethods (): array
190+ {
191+ return [[
192+ 'finite ' ,
193+ [
194+ 'isNan ' => 'is nan ' ,
195+ 'isInfinite ' => 'is infinite ' ,
196+ ],
197+ ], [
198+ 'infinite ' ,
199+ [
200+ 'isNan ' => 'is nan ' ,
201+ 'isFinite ' => 'is finite ' ,
202+ ],
203+ ], [
204+ 'nan ' ,
205+ [
206+ 'isFinite ' => 'is finite ' ,
207+ 'isInfinite ' => 'is infinite ' ,
208+ ],
209+ ]];
210+ }
211+
186212 /**
187213 * Verify methods that cannot be used with a negative condition.
188214 */
189215 public function methodsWithoutNegativeCondition (): array
190216 {
191217 return [
192218 ['equalToXmlStructure ' , new DOMElement ('foo ' )],
193- ['json ' ],
194219 ['subset ' ],
195- ['nan ' ],
196220 ];
197221 }
198222
@@ -226,9 +250,7 @@ public function noParamMethods(): array
226250 [false , 'callable ' , 'assertIsNotCallable ' ],
227251 [false , 'empty ' , 'assertNotEmpty ' ],
228252 [false , 'false ' , 'assertNotFalse ' ],
229- [false , 'finite ' , 'assertInfinite ' ],
230253 [false , 'float ' , 'assertIsNotFloat ' ],
231- [false , 'infinite ' , 'assertFinite ' ],
232254 [false , 'int ' , 'assertIsNotInt ' ],
233255 [false , 'iterable ' , 'assertIsNotIterable ' ],
234256 [false , 'null ' , 'assertNotNull ' ],
@@ -312,6 +334,41 @@ public function testAttribute(bool $modifierCondition, $actualValue, string $ass
312334 $ this ->assertSame ($ this ->subject , $ this ->subject ->attribute ('attribute_name ' ));
313335 }
314336
337+ /**
338+ * Test methods that use logicalOr in order to do inverse assertions.
339+ *
340+ * @param array<string, string> $methods
341+ *
342+ * @dataProvider logicalOrMethods
343+ * @runInSeparateProcess
344+ *
345+ * @return void
346+ */
347+ public function testCompositeLogicMethods (string $ verifyMethod , array $ methods )
348+ {
349+ PHPMockery::mock ('BeBat \\Verify ' , 'method_exists ' )->andReturn (true );
350+
351+ $ this ->setModifierCondition (false );
352+
353+ foreach ($ methods as $ methodName => $ result ) {
354+ $ this ->mockAssert ->shouldReceive ($ methodName )
355+ ->with ()
356+ ->once ()
357+ ->andReturn ($ result );
358+ }
359+
360+ $ this ->mockAssert ->shouldReceive ('logicalOr ' )
361+ ->withArgs (static function ($ argument ) use ($ methods ): bool {
362+ return \in_array ($ argument , $ methods , true );
363+ })->once ()
364+ ->andReturn ('logical or ' );
365+ $ this ->mockAssert ->shouldReceive ('assertThat ' )
366+ ->with ('actual value ' , 'logical or ' , 'some message ' )
367+ ->once ();
368+
369+ $ this ->assertSame ($ this ->subject , $ this ->subject ->{$ verifyMethod }());
370+ }
371+
315372 /**
316373 * Test exception for invalid conjunction.
317374 *
@@ -778,6 +835,32 @@ public function testMissingAttributeThrowsException($subject, string $exceptionM
778835 $ this ->subject ->attributeNamed ('some_attribute ' )->true ();
779836 }
780837
838+ /**
839+ * Test asserting that value is not JSON using assertThat(logicalNot()).
840+ *
841+ * @return void
842+ */
843+ public function testNotJson ()
844+ {
845+ PHPMockery::mock ('BeBat \\Verify ' , 'method_exists ' )->andReturn (true );
846+
847+ $ this ->setModifierCondition (false );
848+
849+ $ this ->mockAssert ->shouldReceive ('isJson ' )
850+ ->with ()
851+ ->once ()
852+ ->andReturn ('is json ' );
853+ $ this ->mockAssert ->shouldReceive ('logicalNot ' )
854+ ->with ('is json ' )
855+ ->once ()
856+ ->andReturn ('logical not ' );
857+ $ this ->mockAssert ->shouldReceive ('assertThat ' )
858+ ->with ('actual value ' , 'logical not ' , 'some message ' )
859+ ->once ();
860+
861+ $ this ->assertSame ($ this ->subject , $ this ->subject ->json ());
862+ }
863+
781864 /**
782865 * Test validation of subject when trying to read an attribute.
783866 *
0 commit comments