From 543b9542ae56e4e2a0661561cc02e3f651519a83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mert=20A=C5=9Fan?= Date: Thu, 23 Sep 2021 06:55:28 +0300 Subject: [PATCH 1/7] add new `match()` method --- src/Expectation.php | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/Expectation.php b/src/Expectation.php index 253b1e1ef..1d8403ac6 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -177,6 +177,56 @@ public function sequence(...$callbacks): Expectation return $this; } + /** + * If the subject matches one of the expressions, the callback in the expression is run. + * + * @template TMatchValue + * + * @param Closure|bool|string $subject + * @param array $expressions + * + * @return \Pest\Expectation + */ + public function match($subject, array $expressions): Expectation + { + $subject = is_callable($subject) + ? $subject + : function () use ($subject) { + return $subject; + }; + + $subject = $subject(); + $keys = array_keys($expressions); + $matched = false; + + if (in_array($subject, ['0', '1', false, true], true)) { + $subject = (int) $subject; + } + + foreach ($expressions as $key => $callback) { + if ($subject !== $key) { + continue; + } + + $matched = true; + + if (is_callable($callback)) { + $callback(new self($this->value)); + continue; + } + + (new self($this->value))->toEqual($callback); + + break; + } + + if (!$matched) { + test()->addWarning('No item found matching "' . $subject . '".'); + } + + return $this; + } + /** * Asserts that two variables have the same type and * value. Used on objects, it asserts that two From f6131d042b53761b1c827bb811c74d20e8e97314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mert=20A=C5=9Fan?= Date: Thu, 23 Sep 2021 06:56:47 +0300 Subject: [PATCH 2/7] add tests The filename is not accepted as `match.php` --- tests/Features/Expect/matchExpectation.php | 160 +++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 tests/Features/Expect/matchExpectation.php diff --git a/tests/Features/Expect/matchExpectation.php b/tests/Features/Expect/matchExpectation.php new file mode 100644 index 000000000..ba397b11d --- /dev/null +++ b/tests/Features/Expect/matchExpectation.php @@ -0,0 +1,160 @@ +matched = null; +}); + +it('pass', function () { + expect('baz') + ->match('foo', [ + 'bar' => function ($value) { + $this->matched = 'bar'; + + return $value->toEqual('bar'); + }, + 'foo' => function ($value) { + $this->matched = 'baz'; + + return $value->toEqual('baz'); + }, + ] + ) + ->toEqual($this->matched); + + expect(static::getCount())->toBe(2); +}); + +it('failures', function () { + expect(true) + ->match('foo', [ + 'bar' => function ($value) { + return $value->toBeTrue(); + }, + 'foo' => function ($value) { + return $value->toBeFalse(); + }, + ] + ); +})->throws(ExpectationFailedException::class, 'true is false'); + +it('adds a warning if no match is found', function () { + expect(true) + ->match('bar', [ + 'foo' => function ($value) { + return $value->toBeFalse(); + }, + ] + ); +}); + +it('runs with truthy', function () { + expect('foo') + ->match(1, [ + 'bar' => function ($value) { + $this->matched = 'bar'; + + return $value->toEqual('bar'); + }, + true => function ($value) { + $this->matched = 'foo'; + + return $value->toEqual('foo'); + }, + ] + ) + ->toEqual($this->matched); + + expect(static::getCount())->toBe(2); +}); + +it('runs with falsy', function () { + expect('foo') + ->match(false, [ + 'bar' => function ($value) { + $this->matched = 'bar'; + + return $value->toEqual('bar'); + }, + false => function ($value) { + $this->matched = 'foo'; + + return $value->toEqual('foo'); + }, + ] + ) + ->toEqual($this->matched); + + expect(static::getCount())->toBe(2); +}); + +it('runs with truthy closure condition', function () { + expect('foo') + ->match( + function () { return '1'; }, [ + 'bar' => function ($value) { + $this->matched = 'bar'; + + return $value->toEqual('bar'); + }, + true => function ($value) { + $this->matched = 'foo'; + + return $value->toEqual('foo'); + }, + ] + ) + ->toEqual($this->matched); + + expect(static::getCount())->toBe(2); +}); + +it('runs with falsy closure condition', function () { + expect('foo') + ->match( + function () { return '0'; }, [ + 'bar' => function ($value) { + $this->matched = 'bar'; + + return $value->toEqual('bar'); + }, + false => function ($value) { + $this->matched = 'foo'; + + return $value->toEqual('foo'); + }, + ] + ) + ->toEqual($this->matched); + + expect(static::getCount())->toBe(2); +}); + +it('can be passed non-callable values', function () { + expect('foo') + ->match('pest', [ + 'bar' => 'foo', + 'pest' => 'baz', + ] + ); +})->throws(ExpectationFailedException::class, 'two strings are equal'); + +it('passes with empty data', function () { + expect('foo') + ->match('bar', []) + ->toEqual('foo'); +}); + +it('can be used in higher order tests') + ->expect(true) + ->match( + function () { return true; }, [ + false => function ($value) { + return $value->toBeFalse(); + }, + true => function ($value) { + return $value->toBeTrue(); + }, + ] + ); From fec11928cfaa5238f2f068f26e470e64b50836fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mert=20A=C5=9Fan?= Date: Thu, 23 Sep 2021 06:57:07 +0300 Subject: [PATCH 3/7] update snapshots --- tests/.snapshots/success.txt | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index 4442bbb9f..c360b31ee 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -158,6 +158,18 @@ ✓ it properly parses json string ✓ fails with broken json string + WARN Tests\Features\Expect\matchExpectation + ✓ it pass + ✓ it failures + ! it adds a warning if no match is found → No item found matching "bar". + ✓ it runs with truthy + ✓ it runs with falsy + ✓ it runs with truthy closure condition + ✓ it runs with falsy closure condition + ✓ it can be passed non-callable values + ! it passes with empty data → No item found matching "bar". + ✓ it can be used in higher order tests + PASS Tests\Features\Expect\not ✓ not property calls @@ -681,5 +693,5 @@ ✓ it is a test ✓ it uses correct parent class - Tests: 4 incompleted, 9 skipped, 447 passed + Tests: 2 warnings, 4 incompleted, 9 skipped, 455 passed \ No newline at end of file From da258fa89f0f2f78f472ed39e0ed42d1f2b6868d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mert=20A=C5=9Fan?= Date: Fri, 24 Sep 2021 13:55:16 +0300 Subject: [PATCH 4/7] remove the warning --- src/Expectation.php | 7 ------- tests/Features/Expect/matchExpectation.php | 10 ---------- 2 files changed, 17 deletions(-) diff --git a/src/Expectation.php b/src/Expectation.php index 1d8403ac6..f903bbd6b 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -197,7 +197,6 @@ public function match($subject, array $expressions): Expectation $subject = $subject(); $keys = array_keys($expressions); - $matched = false; if (in_array($subject, ['0', '1', false, true], true)) { $subject = (int) $subject; @@ -208,8 +207,6 @@ public function match($subject, array $expressions): Expectation continue; } - $matched = true; - if (is_callable($callback)) { $callback(new self($this->value)); continue; @@ -220,10 +217,6 @@ public function match($subject, array $expressions): Expectation break; } - if (!$matched) { - test()->addWarning('No item found matching "' . $subject . '".'); - } - return $this; } diff --git a/tests/Features/Expect/matchExpectation.php b/tests/Features/Expect/matchExpectation.php index ba397b11d..f577cedc4 100644 --- a/tests/Features/Expect/matchExpectation.php +++ b/tests/Features/Expect/matchExpectation.php @@ -39,16 +39,6 @@ ); })->throws(ExpectationFailedException::class, 'true is false'); -it('adds a warning if no match is found', function () { - expect(true) - ->match('bar', [ - 'foo' => function ($value) { - return $value->toBeFalse(); - }, - ] - ); -}); - it('runs with truthy', function () { expect('foo') ->match(1, [ From 7f214f9e129579bb60237582a63fca6585848b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mert=20A=C5=9Fan?= Date: Fri, 24 Sep 2021 13:59:00 +0300 Subject: [PATCH 5/7] use `and()` instead of `new self` --- src/Expectation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Expectation.php b/src/Expectation.php index f903bbd6b..641b09e4b 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -212,7 +212,7 @@ public function match($subject, array $expressions): Expectation continue; } - (new self($this->value))->toEqual($callback); + $this->and($this->value)->toEqual($callback); break; } From 8d96f975e002b8a959935409f99cf6e81202376a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mert=20A=C5=9Fan?= Date: Fri, 24 Sep 2021 14:37:01 +0300 Subject: [PATCH 6/7] update snapshots --- tests/.snapshots/success.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index c360b31ee..082bdccec 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -158,16 +158,15 @@ ✓ it properly parses json string ✓ fails with broken json string - WARN Tests\Features\Expect\matchExpectation + PASS Tests\Features\Expect\matchExpectation ✓ it pass ✓ it failures - ! it adds a warning if no match is found → No item found matching "bar". ✓ it runs with truthy ✓ it runs with falsy ✓ it runs with truthy closure condition ✓ it runs with falsy closure condition ✓ it can be passed non-callable values - ! it passes with empty data → No item found matching "bar". + ✓ it passes with empty data ✓ it can be used in higher order tests PASS Tests\Features\Expect\not @@ -693,5 +692,5 @@ ✓ it is a test ✓ it uses correct parent class - Tests: 2 warnings, 4 incompleted, 9 skipped, 455 passed + Tests: 4 incompleted, 9 skipped, 456 passed \ No newline at end of file From c99f8f196e162086ac47c1f44d04cd3acaf7297d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mert=20A=C5=9Fan?= Date: Fri, 24 Sep 2021 14:42:26 +0300 Subject: [PATCH 7/7] lint --- src/Expectation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Expectation.php b/src/Expectation.php index 68336471b..2e581802f 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -219,7 +219,7 @@ public function match($subject, array $expressions): Expectation return $this; } - + /** * It skips the tests in the callback if the condition is not truthy. *