diff --git a/src/Expectation.php b/src/Expectation.php index 300820c1..7703ebb8 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -62,7 +62,7 @@ final class Expectation /** * Creates a new expectation with the decoded JSON value. * - * @return self + * @return self|bool> */ public function json(): Expectation { @@ -70,7 +70,10 @@ final class Expectation InvalidExpectationValue::expected('string'); } - return $this->toBeJson()->and(json_decode($this->value, true)); + /** @var array|bool $value */ + $value = json_decode($this->value, true); + + return $this->toBeJson()->and($value); } /** diff --git a/src/Expectations/HigherOrderExpectation.php b/src/Expectations/HigherOrderExpectation.php index 7fb0300e..f3aa62e7 100644 --- a/src/Expectations/HigherOrderExpectation.php +++ b/src/Expectations/HigherOrderExpectation.php @@ -95,6 +95,16 @@ final class HigherOrderExpectation return new self($this->original, $this->original->value); } + /** + * Creates a new expectation with the decoded JSON value. + * + * @return self|bool> + */ + public function json(): self + { + return new self($this->original, $this->expectation->json()->value); + } + /** * Dynamically calls methods on the class with the given arguments. * diff --git a/src/Support/HigherOrderCallables.php b/src/Support/HigherOrderCallables.php index 9790d2cb..1ccf1f9f 100644 --- a/src/Support/HigherOrderCallables.php +++ b/src/Support/HigherOrderCallables.php @@ -52,9 +52,9 @@ final class HigherOrderCallables } /** - * Tap into the test case to perform an action and return the test case. + * Execute the given callable after the test has executed the setup method. */ - public function tap(callable $callable): object + public function defer(callable $callable): object { Reflection::bindCallableWithData($callable); diff --git a/tests/Features/Expect/HigherOrder/methods.php b/tests/Features/Expect/HigherOrder/methods.php index ad6cf952..3c03ddb5 100644 --- a/tests/Features/Expect/HigherOrder/methods.php +++ b/tests/Features/Expect/HigherOrder/methods.php @@ -91,8 +91,20 @@ it('can use the scoped method to lock into the given level for expectations', fu ); }); +it('works consistently with the json expectation method', function () { + expect(new HasMethods()) + ->jsonString()->json()->id->toBe(1) + ->jsonString()->json()->name->toBe('Has Methods')->toBeString() + ->jsonString()->json()->quantity->toBe(20)->toBeInt(); +}); + class HasMethods { + public function jsonString(): string + { + return '{ "id": 1, "name": "Has Methods", "quantity": 20 }'; + } + public function name() { return 'Has Methods'; diff --git a/tests/Features/HigherOrderTests.php b/tests/Features/HigherOrderTests.php index e2ff0686..7aafbaa5 100644 --- a/tests/Features/HigherOrderTests.php +++ b/tests/Features/HigherOrderTests.php @@ -21,9 +21,9 @@ it('resolves expect callables correctly') test('does not treat method names as callables') ->expect('it')->toBeString(); -it('can tap into the test') +it('can defer a method until after test setup') ->expect('foo')->toBeString() - ->tap(function () { expect($this)->toBeInstanceOf(TestCase::class); }) + ->defer(function () { expect($this)->toBeInstanceOf(TestCase::class); }) ->toBe('foo') ->and('hello world')->toBeString(); @@ -32,15 +32,15 @@ it('can pass datasets into the expect callables') ->expect(function (...$numbers) { return $numbers; })->toBe([1, 2, 3]) ->and(function (...$numbers) { return $numbers; })->toBe([1, 2, 3]); -it('can pass datasets into the tap callable') +it('can pass datasets into the defer callable') ->with([[1, 2, 3]]) - ->tap(function (...$numbers) { expect($numbers)->toBe([1, 2, 3]); }); + ->defer(function (...$numbers) { expect($numbers)->toBe([1, 2, 3]); }); it('can pass shared datasets into callables') ->with('numbers.closure.wrapped') ->expect(function ($value) { return $value; }) ->and(function ($value) { return $value; }) - ->tap(function ($value) { expect($value)->toBeInt(); }) + ->defer(function ($value) { expect($value)->toBeInt(); }) ->toBeInt(); afterEach()->assertTrue(true);