diff --git a/hhast-lint.json b/hhast-lint.json index 6a389c6..d25f1dd 100644 --- a/hhast-lint.json +++ b/hhast-lint.json @@ -1,3 +1,4 @@ { + "builtinLinters": "all", "roots": [ "src/", "tests/" ] } diff --git a/src/Assert.php b/src/Assert.php index dc1ec6e..d01f91c 100644 --- a/src/Assert.php +++ b/src/Assert.php @@ -1,4 +1,4 @@ - $expected) { @@ -210,8 +220,8 @@ public function assertGreaterThan( } public function assertLessThan( - $expected, - $actual, + num $expected, + num $actual, string $message = '', ): void { if ($actual < $expected) { @@ -228,8 +238,8 @@ public function assertLessThan( } public function assertGreaterThanOrEqual( - $expected, - $actual, + num $expected, + num $actual, string $message = '', ): void { if ($actual >= $expected) { @@ -246,8 +256,8 @@ public function assertGreaterThanOrEqual( } public function assertLessThanOrEqual( - $expected, - $actual, + num $expected, + num $actual, string $message = '', ): void { if ($actual <= $expected) { @@ -265,13 +275,13 @@ public function assertLessThanOrEqual( public function assertInstanceOf( string $expected, - $actual, + mixed $actual, string $message = '', ): void { if (!\class_exists($expected) && !\interface_exists($expected)) { throw new InvalidArgumentException('Invalid class or interface name'); } - if ($actual instanceof $expected) { + if (\is_a($actual, $expected)) { return; } throw new ExpectationFailedException( @@ -286,13 +296,13 @@ public function assertInstanceOf( public function assertNotInstanceOf( string $expected, - $actual, + mixed $actual, string $message = '', ): void { if (!\class_exists($expected) && !\interface_exists($expected)) { throw new InvalidArgumentException('Invalid class or interface name'); } - if (!($actual instanceof $expected)) { + if (!\is_a($actual, $expected)) { return; } throw new ExpectationFailedException( @@ -310,7 +320,7 @@ public function assertNotInstanceOf( */ public function assertType( string $expected, - $actual, + mixed $actual, string $message = '', ): void { if (is_type($expected)) { @@ -336,7 +346,7 @@ public function assertType( */ public function assertNotType( string $expected, - $actual, + mixed $actual, string $message = '', ): void { if (is_type($expected)) { @@ -358,15 +368,12 @@ public function assertNotType( } public function assertContains( - $needle, - $haystack, + mixed $needle, + mixed $haystack, string $message = '', bool $ignoreCase = false, ): void { - if ( - \is_array($haystack) || - (\is_object($haystack) && $haystack instanceof Traversable) - ) { + if ($haystack is Traversable<_>) { if ((new Constraint\TraversableContains($needle))->matches($haystack)) { return; } @@ -399,15 +406,12 @@ public function assertContains( } public function assertNotContains( - $needle, - $haystack, + mixed $needle, + mixed $haystack, string $message = '', bool $ignoreCase = false, ): void { - if ( - \is_array($haystack) || - (\is_object($haystack) && $haystack instanceof Traversable) - ) { + if ($haystack is Traversable<_>) { if (!(new Constraint\TraversableContains($needle))->matches($haystack)) { return; } @@ -443,7 +447,7 @@ public function assertRegExp( string $expected, string $actual, string $message = '', - ) { + ): void { if (\preg_match($expected, $actual) === 1) { return; } @@ -461,7 +465,7 @@ public function assertNotRegExp( string $expected, string $actual, string $message = '', - ) { + ): void { if (\preg_match($expected, $actual) === 0) { return; } @@ -476,18 +480,18 @@ public function assertNotRegExp( } public function assertSubset( - $expected, - $actual, + dynamic $expected, + dynamic $actual, string $msg = '', string $path = '$actual', ): void { foreach ($expected as $key => $value) { - if (is_any_array($actual)) { + if ($actual is KeyedContainer<_, _>) { $actual_value = idx($actual, $key); $part = '['.\var_export($key, true).']'; } else if (is_object($actual)) { $actual_value = /* UNSAFE_EXPR */ $actual->$key; - $part = "->$key"; + $part = "->".$key; } else { $actual_value = null; $part = null; @@ -496,7 +500,7 @@ public function assertSubset( if (is_any_array($value) || is_object($value)) { $this->assertSubset($value, $actual_value, $msg, $path.$part); } else { - $this->assertEquals($value, $actual_value, $msg."\nKey: $path$part"); + $this->assertEquals($value, $actual_value, $msg."\nKey: ".$path.$part); } } } @@ -506,12 +510,12 @@ public function assertSubset( * that the contents of the two arrays are equal. */ public function assertKeyAndValueEquals( - array $expected, - array $actual, + KeyedContainer $expected, + KeyedContainer $actual, string $msg = '', ): void { - self::sortArrayRecursive(&$expected); - self::sortArrayRecursive(&$actual); + $expected = self::sortArrayRecursive($expected); + $actual = self::sortArrayRecursive($actual); $this->assertEquals($expected, $actual, $msg); } @@ -572,7 +576,7 @@ public function assertIsSorted( } if (($pair->count() === 2) && !$comparator($pair[0], $pair[1])) { - $main_message = $message ?: 'Collection is not sorted'; + $main_message = $message === '' ? 'Collection is not sorted' : $message; $failure_detail = \sprintf( 'at pos %d, %s and %s are in the wrong order', $index, @@ -616,13 +620,17 @@ public function assertIsSortedByKey( ); } - private static function sortArrayRecursive(array &$arr): void { - foreach ($arr as $codemod_inserted_key => $i) { - if (is_array($i)) { - self::sortArrayRecursive(&$i); + private static function sortArrayRecursive( + KeyedContainer $arr + ): dict { + $out = dict[]; + foreach ($arr as $k => $v) { + if ($v is KeyedContainer<_, _>) { + $v = self::sortArrayRecursive($v); } - $arr[$codemod_inserted_key] = $i; + $out[$k as arraykey] = $v; } + return $out; } private static function sorted(Traversable $x): ImmVector { diff --git a/src/Constraint/TraversableContains.php b/src/Constraint/TraversableContains.php index 1457585..1a5b724 100644 --- a/src/Constraint/TraversableContains.php +++ b/src/Constraint/TraversableContains.php @@ -1,4 +1,4 @@ - $other): bool { if ($other instanceof \SplObjectStorage) { return $other->contains($this->value); } diff --git a/src/ExpectObj.php b/src/ExpectObj.php index 5be49f1..4054f15 100644 --- a/src/ExpectObj.php +++ b/src/ExpectObj.php @@ -1,4 +1,4 @@ -> - public function toEqual($expected, string $msg = '', ...$args): void { + public function toEqual( + mixed $expected, + string $msg = '', + mixed ...$args + ): void { $this->toBePHPEqual($expected, $msg, ...$args); } @@ -34,7 +38,11 @@ public function toEqual($expected, string $msg = '', ...$args): void { * Note: Two objects are considered equal if * (string)$o1 == (string)$o2. */ - public function toBePHPEqual($expected, string $msg = '', ...$args): void { + public function toBePHPEqual( + mixed $expected, + string $msg = '', + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); $this->assertEquals($expected, $this->var, $msg); } @@ -43,12 +51,21 @@ public function toBePHPEqual($expected, string $msg = '', ...$args): void { * Float comparison can give false positives - this will only error if $actual * and $expected are not within $delta of each other. */ - public function toEqualWithDelta(num $expected, float $delta, string $msg = '', ...$args): void { + public function toEqualWithDelta( + num $expected, + float $delta, + string $msg = '', + mixed ...$args + ): void where T as num { $msg = \vsprintf($msg, $args); $this->assertEqualsWithDelta($expected, $this->var, $delta, $msg); } - public function toAlmostEqual($expected, string $msg = '', ...$args): void { + public function toAlmostEqual( + num $expected, + string $msg = '', + mixed ...$args + ): void where T as num { $msg = \vsprintf($msg, $args); $this->toEqualWithDelta( $expected, @@ -62,7 +79,7 @@ public function toAlmostEqual($expected, string $msg = '', ...$args): void { public function beEqualWithNANEqual( mixed $expected, string $msg = '', - ...$args + mixed ...$args ): void { $this->toBePHPEqualWithNANEqual($expected, $msg, ...$args); } @@ -71,9 +88,9 @@ public function beEqualWithNANEqual( * Same as toEqual() except treats NAN as equal to itself. */ public function toBePHPEqualWithNANEqual( - $expected, + mixed $expected, string $msg = '', - ...$args + mixed ...$args ): void { $msg = \vsprintf($msg, $args); @@ -95,63 +112,75 @@ public function toBePHPEqualWithNANEqual( * Note: Two objects are considered the same if they reference the same * instance */ - public function toBeSame($expected, string $msg = '', ...$args): void { + public function toBeSame( + mixed $expected, + string $msg = '', + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); $this->assertSame($expected, $this->var, $msg); } - // Asserts: $actual === true - public function toBeTrue(string $msg = '', ...$args): void { + // Asserts: $actual === true + public function toBeTrue(string $msg = '', mixed ...$args): void { $msg = \vsprintf($msg, $args); $this->assertTrue($this->var, $msg); } // Asserts: $actual === false - public function toBeFalse(string $msg = '', ...$args): void { + public function toBeFalse(string $msg = '', mixed ...$args): void { $msg = \vsprintf($msg, $args); $this->assertFalse($this->var, $msg); } // Asserts: $actual === null - public function toBeNull(string $msg = '', ...$args): void { + public function toBeNull(string $msg = '', mixed ...$args): void { $msg = \vsprintf($msg, $args); $this->assertNull($this->var, $msg); } // Asserts: empty($actual) == true - public function toBeEmpty(string $msg = '', ...$args): void { + public function toBeEmpty(string $msg = '', mixed ...$args): void { $msg = \vsprintf($msg, $args); $this->assertEmpty($this->var, $msg); } // Asserts: $actual > $expected - public function toBeGreaterThan($expected, string $msg = '', ...$args): void { + public function toBeGreaterThan( + num $expected, + string $msg = '', + mixed ...$args + ): void where T as num { $msg = \vsprintf($msg, $args); $this->assertGreaterThan($expected, $this->var, $msg); } // Asserts: $actual < $expected - public function toBeLessThan($expected, string $msg = '', ...$args): void { + public function toBeLessThan( + num $expected, + string $msg = '', + mixed ...$args + ): void where T as num { $msg = \vsprintf($msg, $args); $this->assertLessThan($expected, $this->var, $msg); } // Asserts: $actual <= $expected public function toBeLessThanOrEqualTo( - $expected, + num $expected, string $msg = '', - ...$args - ): void { + mixed ...$args + ): void where T as num { $msg = \vsprintf($msg, $args); $this->assertLessThanOrEqual($expected, $this->var, $msg); } // Asserts: $actual => $expected public function toBeGreaterThanOrEqualTo( - $expected, + num $expected, string $msg = '', - ...$args - ): void { + mixed ...$args + ): void where T as num { $msg = \vsprintf($msg, $args); $this->assertGreaterThanOrEqual($expected, $this->var, $msg); } @@ -160,22 +189,22 @@ public function toBeGreaterThanOrEqualTo( public function toBeInstanceOf( classname $class_or_interface, string $msg = '', - ...$args + mixed ...$args ): Tclass { $msg = \vsprintf($msg, $args); $obj = $this->var; - $this->assertInstanceOf( - $class_or_interface, - $obj, - $msg, - ); + $this->assertInstanceOf($class_or_interface, $obj, $msg); return /* HH_IGNORE_ERROR[4110] */ $obj; } // Asserts: $actual matches $expected regular expression - public function toMatchRegExp($expected, string $msg = '', ...$args): void { + public function toMatchRegExp( + string $expected, + string $msg = '', + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); - $this->assertRegExp($expected, (string) $this->var, $msg); + $this->assertRegExp($expected, (string)$this->var, $msg); } /** @@ -185,7 +214,11 @@ public function toMatchRegExp($expected, string $msg = '', ...$args): void { * * Example: expect($actual)->toBeType('string') would assert is_string($actual) */ - public function toBeType($type, string $msg = '', ...$args): void { + public function toBeType( + string $type, + string $msg = '', + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); $this->assertType($type, $this->var, $msg); } @@ -197,20 +230,24 @@ public function toBeType($type, string $msg = '', ...$args): void { * $needle. * Note: If $needle is an object, === will be used. */ - public function toContain($needle, string $msg = '', ...$args): void { + public function toContain( + mixed $needle, + string $msg = '', + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); - $this->assertContains( - $needle, - not_hack_array($this->var), - $msg, - ); + $this->assertContains($needle, not_hack_array($this->var), $msg); } /** * Assert: That the KeyedTraversible $key has a key set. * Note: If $key is a Set, use assertContains. */ - public function toContainKey($key, string $msg = '', mixed ...$args): void { + public function toContainKey( + mixed $key, + string $msg = '', + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); $obj = $this->var; invariant( @@ -234,7 +271,11 @@ public function toContainKey($key, string $msg = '', mixed ...$args): void { * * TODO: typehint $expected_subset to array and fix tests */ - public function toInclude($expected_subset, string $msg = '', ...$args): void { + public function toInclude( + mixed $expected_subset, + string $msg = '', + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); $this->assertSubset($expected_subset, $this->var, $msg); } @@ -244,15 +285,16 @@ public function toInclude($expected_subset, string $msg = '', ...$args): void { * key/values regardless of order. */ public function toHaveSameShapeAs( - $expected, + mixed $expected, string $msg = '', mixed ...$args ): void { + $expected = $expected as shape(...); $msg = \vsprintf($msg, $args); $value = $this->var; $this->assertKeyAndValueEquals( - $expected, + $expected as KeyedContainer<_, _>, is_array($value) ? $value : [], $msg, ); @@ -262,10 +304,13 @@ public function toHaveSameShapeAs( * Asserts: $actual has the same content as $expected, i.e. the same items * regardless of order. */ - public function toHaveSameContentAs($expected, string $msg = '', ...$args): void { + public function toHaveSameContentAs( + KeyedContainer $expected, + string $msg = '', + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); $value = $this->var; - $this->assertInstanceOf(Traversable::class, $value); assert($value instanceof Traversable); $this->assertContentsEqual($expected, $value, $msg); } @@ -273,14 +318,18 @@ public function toHaveSameContentAs($expected, string $msg = '', ...$args): void /** * Asserts: That a traversable is sorted according to a given comparator. */ - public function toBeSortedBy($comparator, string $msg = '', ...$args): void { + public function toBeSortedBy( + (function(Tv, Tv): bool) $comparator, + string $msg = '', + mixed ...$args + ): void where T as Container { $msg = \vsprintf($msg, $args); $actual = $this->var; invariant( $actual instanceof Traversable, 'ERROR: expect(...$args)->toBeSortedByKey only can be applied to '. - 'Traversables, not %s.', + 'Traversables, not %s.', print_type($actual), ); @@ -291,17 +340,14 @@ public function toBeSortedBy($comparator, string $msg = '', ...$args): void { * Asserts: That a traversable is sorted according to a given key extraction * function. */ - public function toBeSortedByKey($key_extractor, string $msg = '', ...$args): void { + public function toBeSortedByKey( + (function(Tv): arraykey) $key_extractor, + string $msg = '', + mixed ...$args + ): void where T as Traversable { $msg = \vsprintf($msg, $args); $actual = $this->var; - invariant( - $actual instanceof Traversable, - 'ERROR: expect(...$args)->toBeSortedByKey only can be applied to '. - 'Traversables, not %s.', - print_type($actual), - ); - $this->assertIsSortedByKey($actual, $key_extractor, $msg); } @@ -312,17 +358,28 @@ public function toBeSortedByKey($key_extractor, string $msg = '', ...$args): voi **************************************/ <<__Deprecated("Use toNotBeSame() or toNotBePHPEqual()")>> - public function toNotEqual($expected, string $msg = '', ...$args): void { + public function toNotEqual( + mixed $expected, + string $msg = '', + mixed ...$args + ): void { $this->toNotBePHPEqual($expected, $msg, ...$args); } - public function toNotBePHPEqual($expected, string $msg = '', ...$args): void { + public function toNotBePHPEqual( + mixed $expected, + string $msg = '', + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); $this->assertNotEquals($expected, $this->var, $msg); } // Asserts: $actual !== null - public function toNotBeNull(string $msg = '', ...$args): Tv where T = ?Tv { + public function toNotBeNull( + string $msg = '', + mixed ...$args + ): Tv where T = ?Tv { $msg = \vsprintf($msg, $args); $val = $this->var; $this->assertNotNull($val, $msg); @@ -337,7 +394,11 @@ public function toNotBeNull(string $msg = '', ...$args): Tv where T = ?Tv { * Example: expect($actual)->toNotBeType('string') would assert * !is_string($actual) */ - public function toNotBeType($type, string $msg = '', ...$args): void { + public function toNotBeType( + string $type, + string $msg = '', + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); $this->assertNotType($type, $this->var, $msg); } @@ -347,28 +408,29 @@ public function toNotBeType($type, string $msg = '', ...$args): void { * Note: Two objects are considered the same if they reference the same * instance */ - public function toNotBeSame($expected, string $msg = '', ...$args): void { + public function toNotBeSame( + mixed $expected, + string $msg = '', + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); $this->assertNotSame($expected, $this->var, $msg); } // Asserts: empty($actual) != true - public function toNotBeEmpty(string $msg = '', ...$args): void { + public function toNotBeEmpty(string $msg = '', mixed ...$args): void { $msg = \vsprintf($msg, $args); $this->assertNotEmpty($this->var, $msg); } // Asserts: !($actual instanceof $class_or_interface) - public function toNotBeInstanceOf( - $class_or_interface, + public function toNotBeInstanceOf( + classname $class_or_interface, string $msg = '', - ...$args): void { + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); - $this->assertNotInstanceOf( - $class_or_interface, - $this->var, - $msg - ); + $this->assertNotInstanceOf($class_or_interface, $this->var, $msg); } /** @@ -378,36 +440,30 @@ public function toNotBeInstanceOf( * element for which $element == $needle. * Note: If $needle is an object, === will be used. */ - public function toNotContain($expected, string $msg = '', ...$args): void { + public function toNotContain(mixed $expected, string $msg = '', mixed ...$args): void { $msg = \vsprintf($msg, $args); - $this->assertNotContains( - $expected, - not_hack_array($this->var), - $msg, - ); + $this->assertNotContains($expected, not_hack_array($this->var), $msg); } /** * Assert: That the KeyedTraversible $key has a key set. * Note: If $key is a Set, use assertContains. */ - public function toNotContainKey($key, string $msg = '', ...$args): void { + public function toNotContainKey(arraykey $key, string $msg = '', mixed ...$args): void where T as KeyedContainer { $msg = \vsprintf($msg, $args); $obj = $this->var; - invariant( - $obj instanceof KeyedContainer, - 'ERROR: expect(...$args)->toNotContainKey only can be applied to '. - 'KeyedContainers, not %s.', - print_type($obj), - ); - $this->assertFalse(isset($obj[$key]), $msg); + $this->assertFalse(\array_key_exists($key, $obj), $msg); } // Asserts: $actual does not match $expected regular expression - public function toNotMatchRegExp($expected, string $msg = '', ...$args): void { + public function toNotMatchRegExp( + string $expected, + string $msg = '', + mixed ...$args + ): void { $msg = \vsprintf($msg, $args); - $this->assertNotRegExp($expected, (string) $this->var, $msg); + $this->assertNotRegExp($expected, (string)$this->var, $msg); } /*************************************** @@ -430,10 +486,7 @@ public function toNotMatchRegExp($expected, string $msg = '', ...$args): void { * * expect( () ==> invariant_violation('...') )->notToThrow(); // would fail */ - public function notToThrow( - ?string $msg = null, - mixed ...$args - ): void { + public function notToThrow(?string $msg = null, mixed ...$args): void { $msg = \vsprintf($msg, $args); $e = $this->tryCallWithArgsReturnException(array(), \Exception::class); if ($e !== null) { @@ -442,7 +495,10 @@ public function notToThrow( \get_class($e), $msg, \implode("\n ", \array_map( - $t ==> \sprintf( '%s: %s', idx($t, 'file'), idx($t, 'line')), + $t ==> { + $t = $t as KeyedContainer<_, _>; + return \sprintf('%s: %s', idx($t, 'file'), idx($t, 'line')); + }, $e->getTrace(), )), ); @@ -466,14 +522,14 @@ public function toThrow( classname $exception_class, ?string $expected_exception_message = null, ?string $msg = null, - ...$args + mixed ...$args ): void { $msg = \vsprintf($msg, $args); $this->toThrowWhenCalledWith( array(), $exception_class, $expected_exception_message, - $msg + $msg, ); } @@ -488,28 +544,23 @@ classname $exception_class, * )->toThrowWhenCalledWith(array('foo'), 'InvariantViolationException'); */ public function toThrowWhenCalledWith( - array $args, + Container $args, classname $exception_class, ?string $expected_exception_message = null, - ?string $desc = null + ?string $desc = null, ): void { - $exception = - $this->tryCallWithArgsReturnException($args, $exception_class); + $exception = $this->tryCallWithArgsReturnException($args, $exception_class); if (!$exception) { throw new \Exception( - "$desc: Expected exception $exception_class wasn't thrown" + $desc.": Expected exception ".$exception_class." wasn't thrown", ); } if ($expected_exception_message !== null) { $message = $exception->getMessage(); - $this->assertContains( - $expected_exception_message, - $message, - $desc ?? '', - ); + $this->assertContains($expected_exception_message, $message, $desc ?? ''); } } @@ -519,9 +570,9 @@ classname $exception_class, *************************************** ***************************************/ private function tryCallWithArgsReturnException( - array $args, + Container $args, classname $expected_exception_type, - ) { + ): ?Tclass { try { $callable = $this->var; $returned = \call_user_func_array($callable, $args); @@ -530,7 +581,7 @@ classname $expected_exception_type, $ret = \HH\Asio\join($returned); } } catch (\Exception $e) { - expect($e)->toBeInstanceOf( + $e = expect($e)->toBeInstanceOf( $expected_exception_type, 'Expected to throw "%s", but instead got <%s> with message "%s"', $expected_exception_type, diff --git a/tests/ExpectObjTest.php b/tests/ExpectObjTest.php index 40f5704..0feb114 100644 --- a/tests/ExpectObjTest.php +++ b/tests/ExpectObjTest.php @@ -1,4 +1,4 @@ -> { $o = new \stdClass(); - return array( + return vec[ array('toBePHPEqual', false, true), array('toNotBePHPEqual', false, false), array('toBeGreaterThan', 1, 1), @@ -176,59 +176,56 @@ public function provideFailureCases() { dict['k1' => 'v1', 'k2' => 'v2'], dict['k1' => 'v2'], ), - ); + ]; } <> - public function testBasicFailure( - $func, - $values, - $expected = self::EMPTY_VALUE, + string $func, + mixed $actual, + mixed $expected = self::EMPTY_VALUE, ): void { + $obj = expect($actual); + $rm = new \ReflectionMethod($obj, $func); + if ($expected === self::EMPTY_VALUE) { - expect(() ==> call_user_func(array(expect($values), $func)))->toThrow( + expect(() ==> $rm->invoke($obj))->toThrow( ExpectationFailedException::class, ); } else { - expect(() ==> call_user_func(array(expect($values), $func), $expected)) + expect(() ==> $rm->invokeArgs($obj, [$expected])) ->toThrow(ExpectationFailedException::class); } } <> - public function testFailureWithCustomMsg( - $func, - $value, - $expected = self::EMPTY_VALUE, + string $func, + mixed $actual, + mixed $expected = self::EMPTY_VALUE, ): void { + $obj = expect($actual); + $rm = new \ReflectionMethod($obj, $func); if ($expected === self::EMPTY_VALUE) { - expect(() ==> call_user_func(array(expect($value), $func), 'custom msg')) + expect(() ==> $rm->invokeArgs($obj, ['custom msg'])) ->toThrow(ExpectationFailedException::class, 'custom msg'); } else { - expect( - () ==> - call_user_func(array(expect($value), $func), $expected, 'custom msg'), - )->toThrow(ExpectationFailedException::class, 'custom msg'); + expect(() ==> $rm->invokeArgs($obj, [$expected, 'custom msg']))->toThrow( + ExpectationFailedException::class, + 'custom msg', + ); ; } // And with funky sprintfification if ($expected === self::EMPTY_VALUE) { - expect( - () ==> \call_user_func_array( - array(expect($value), $func), - array('custom %s %d %f', 'msg', 1, 2.1), - ), - )->toThrow(ExpectationFailedException::class, 'custom msg 1 2.1'); + expect(() ==> $rm->invokeArgs($obj, ['custom %s %d %f', 'msg', 1, 2.1])) + ->toThrow(ExpectationFailedException::class, 'custom msg 1 2.1'); } else { expect( - () ==> \call_user_func_array( - array(expect($value), $func), - array($expected, 'custom %s %d %f', 'msg', 1, 2.1), - ), + () ==> + $rm->invokeArgs($obj, [$expected, 'custom %s %d %f', 'msg', 1, 2.1]), )->toThrow(ExpectationFailedException::class, 'custom msg 1 2.1'); } } @@ -250,8 +247,10 @@ function() { )->toThrow(\Exception::class); expect( - function($class) { - throw new $class(); + (classname<\Exception> $class) ==> { + if ($class === ExpectObjTestException::class) { + throw new ExpectObjTestException(); + } }, )->toThrowWhenCalledWith( array(ExpectObjTestException::class), @@ -290,9 +289,11 @@ private static function stopEagerExecution(): RescheduleWaitHandle { public function testAwaitableFunctionGetsPrepped(): void { expect( - async function($class) { + async (mixed $class) ==> { await self::stopEagerExecution(); - throw new $class(); + if ($class === ExpectObjTestException::class) { + throw new ExpectObjTestException(); + } }, )->toThrowWhenCalledWith( array(ExpectObjTestException::class), @@ -323,14 +324,14 @@ public function testToHaveSameShapeAsSuccess(): void { public function testToHaveSameContentAsSuccess(): void { expect( () ==> { - expect(Set { 1, 2 })->toHaveSameContentAs(Vector { 2, 1 }); - expect(array(3))->toHaveSameContentAs(Map { 1 => 3 }); + expect(Set {1, 2})->toHaveSameContentAs(Vector {2, 1}); + expect(array(3))->toHaveSameContentAs(Map {1 => 3}); }, )->notToThrow(); } public function testToHaveSameContentAsFailure(): void { - expect(() ==> expect(array(1, 2))->toHaveSameContentAs(Vector { 1 })) + expect(() ==> expect(array(1, 2))->toHaveSameContentAs(Vector {1})) ->toThrow(ExpectationFailedException::class); }