From 9e5b779abc74e7d4a8045a4b96fcf7802f4bbaf0 Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 16 Jun 2021 00:52:31 -0500 Subject: [PATCH 01/40] feat: add helper function for mapping a function's arguments --- src/Support/Reflection.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Support/Reflection.php b/src/Support/Reflection.php index c25709b9..1fac05b7 100644 --- a/src/Support/Reflection.php +++ b/src/Support/Reflection.php @@ -153,4 +153,21 @@ final class Reflection return $name; } + + /** + * Receive a map of function argument names to their types. + * + * @return array + */ + public static function getFunctionArguments(Closure $function): array + { + $parameters = (new ReflectionFunction($function))->getParameters(); + $arguments = []; + + foreach ($parameters as $parameter) { + $arguments[$parameter->getName()] = ($parameter->hasType()) ? $parameter->getType() : 'mixed'; + } + + return $arguments; + } } From 99040945908c97219f03b0714ceb23e0644e395d Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 16 Jun 2021 00:53:17 -0500 Subject: [PATCH 02/40] feat: add new exception for missing datasets on tests with arguments --- src/Exceptions/DatasetMissing.php | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/Exceptions/DatasetMissing.php diff --git a/src/Exceptions/DatasetMissing.php b/src/Exceptions/DatasetMissing.php new file mode 100644 index 00000000..5613d02e --- /dev/null +++ b/src/Exceptions/DatasetMissing.php @@ -0,0 +1,36 @@ + $args A map of argument names to their typee + */ + public function __construct(string $file, string $name, array $args) + { + parent::__construct(sprintf( + "A test with the description '%s' has %d argument(s) ([%s]) and no dataset(s) provided in %s", + $name, + count($args), + implode(', ', array_map(static function (string $arg, string $type): string { + return sprintf('%s $%s', $type, $arg); + }, array_keys($args), $args)), + $file, + )); + } +} From 9bf141f698169839761ff32628ac2175b37ea277 Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 16 Jun 2021 00:54:22 -0500 Subject: [PATCH 03/40] style: formatting & linting --- src/Exceptions/DatasetMissing.php | 2 +- src/Support/Reflection.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Exceptions/DatasetMissing.php b/src/Exceptions/DatasetMissing.php index 5613d02e..b8f0cb2d 100644 --- a/src/Exceptions/DatasetMissing.php +++ b/src/Exceptions/DatasetMissing.php @@ -10,7 +10,7 @@ use NunoMaduro\Collision\Contracts\RenderlessTrace; use Symfony\Component\Console\Exception\ExceptionInterface; /** - * Creates a new instance of dataset is not present for test that has arguments + * Creates a new instance of dataset is not present for test that has arguments. * * @internal */ diff --git a/src/Support/Reflection.php b/src/Support/Reflection.php index 1fac05b7..8fdd08fd 100644 --- a/src/Support/Reflection.php +++ b/src/Support/Reflection.php @@ -162,7 +162,7 @@ final class Reflection public static function getFunctionArguments(Closure $function): array { $parameters = (new ReflectionFunction($function))->getParameters(); - $arguments = []; + $arguments = []; foreach ($parameters as $parameter) { $arguments[$parameter->getName()] = ($parameter->hasType()) ? $parameter->getType() : 'mixed'; From 64e780cf7278d3354610d70dbd16df7960dd3d16 Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 16 Jun 2021 00:58:46 -0500 Subject: [PATCH 04/40] fix: types --- src/Support/Reflection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Support/Reflection.php b/src/Support/Reflection.php index 8fdd08fd..1ad05804 100644 --- a/src/Support/Reflection.php +++ b/src/Support/Reflection.php @@ -165,7 +165,7 @@ final class Reflection $arguments = []; foreach ($parameters as $parameter) { - $arguments[$parameter->getName()] = ($parameter->hasType()) ? $parameter->getType() : 'mixed'; + $arguments[$parameter->getName()] = ($parameter->hasType()) ? (string) $parameter->getType() : 'mixed'; } return $arguments; From 9d66893d5a65faec6823f932e00fab319ef56ade Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 16 Jun 2021 01:00:23 -0500 Subject: [PATCH 05/40] feat: add boolean property to signal dependency proxy calls --- src/Factories/TestCaseFactory.php | 7 +++++++ src/PendingObjects/TestCall.php | 2 ++ 2 files changed, 9 insertions(+) diff --git a/src/Factories/TestCaseFactory.php b/src/Factories/TestCaseFactory.php index 6efe63f4..63eafaff 100644 --- a/src/Factories/TestCaseFactory.php +++ b/src/Factories/TestCaseFactory.php @@ -66,6 +66,13 @@ final class TestCaseFactory */ public $datasets = []; + /** + * Has the current test been marked dependent on others? + * + * @var bool + */ + public $dependent = false; + /** * The FQN of the test case class. * diff --git a/src/PendingObjects/TestCall.php b/src/PendingObjects/TestCall.php index 39486565..6cf9f0f3 100644 --- a/src/PendingObjects/TestCall.php +++ b/src/PendingObjects/TestCall.php @@ -97,6 +97,8 @@ final class TestCall ->factoryProxies ->add(Backtrace::file(), Backtrace::line(), 'addDependencies', [$tests]); + $this->testCaseFactory->dependent = true; + return $this; } From 6a7ee90ff5d80edac9339dc5107c48f0ebf18124 Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 16 Jun 2021 01:01:34 -0500 Subject: [PATCH 06/40] feat: throw user-friendly exception for missing argument data --- src/Repositories/TestRepository.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Repositories/TestRepository.php b/src/Repositories/TestRepository.php index b2eb4893..305dc127 100644 --- a/src/Repositories/TestRepository.php +++ b/src/Repositories/TestRepository.php @@ -5,11 +5,13 @@ declare(strict_types=1); namespace Pest\Repositories; use Closure; +use Pest\Exceptions\DatasetMissing; use Pest\Exceptions\ShouldNotHappen; use Pest\Exceptions\TestAlreadyExist; use Pest\Exceptions\TestCaseAlreadyInUse; use Pest\Exceptions\TestCaseClassOrTraitNotFound; use Pest\Factories\TestCaseFactory; +use Pest\Support\Reflection; use Pest\Support\Str; use Pest\TestSuite; use PHPUnit\Framework\TestCase; @@ -140,6 +142,14 @@ final class TestRepository throw new TestAlreadyExist($test->filename, $test->description); } + if ($test->dependent === false && count($test->datasets) === 0) { + $arguments = Reflection::getFunctionArguments($test->test); + + if (count($arguments) > 0) { + throw new DatasetMissing($test->filename, $test->description, $arguments); + } + } + $this->state[sprintf('%s%s%s', $test->filename, self::SEPARATOR, $test->description)] = $test; } } From e21e3080e0bc4f6ff2ebff50bbbb3796d3edaafd Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 16 Jun 2021 14:04:50 -0500 Subject: [PATCH 07/40] test: add new exception check & update snapshots --- tests/.snapshots/success.txt | 3 ++- tests/Unit/TestSuite.php | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index 9f57d4fa..6328d9a5 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -527,6 +527,7 @@ PASS Tests\Unit\TestSuite ✓ it does not allow to add the same test description twice + ✓ it alerts users about tests with arguments but no input PASS Tests\Visual\Help ✓ visual snapshot of help command output @@ -554,5 +555,5 @@ ✓ it is a test ✓ it uses correct parent class - Tests: 4 incompleted, 7 skipped, 340 passed + Tests: 4 incompleted, 7 skipped, 341 passed \ No newline at end of file diff --git a/tests/Unit/TestSuite.php b/tests/Unit/TestSuite.php index 74d9c092..c26149c8 100644 --- a/tests/Unit/TestSuite.php +++ b/tests/Unit/TestSuite.php @@ -1,5 +1,6 @@ expectExceptionMessage(sprintf('A test with the description `%s` already exist in the filename `%s`.', 'foo', __FILE__)); $testSuite->tests->set(new \Pest\Factories\TestCaseFactory(__FILE__, 'foo', $test)); }); + +it('alerts users about tests with arguments but no input', function () { + $testSuite = new TestSuite(getcwd(), 'tests'); + $test = function (int $arg) {}; + $this->expectException(DatasetMissing::class); + $this->expectExceptionMessage(sprintf("A test with the description '%s' has %d argument(s) ([%s]) and no dataset(s) provided in %s", 'foo', 1, 'int $arg', __FILE__)); + $testSuite->tests->set(new \Pest\Factories\TestCaseFactory(__FILE__, 'foo', $test)); +}); From 2e7192ab9565598c550ff53cd4a945db90639908 Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 16 Jun 2021 14:42:51 -0500 Subject: [PATCH 08/40] chore: static analysis adjustments - deprecation RE: ReflectionType::__toString --- src/Support/Reflection.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Support/Reflection.php b/src/Support/Reflection.php index 1ad05804..7d46ece9 100644 --- a/src/Support/Reflection.php +++ b/src/Support/Reflection.php @@ -165,7 +165,9 @@ final class Reflection $arguments = []; foreach ($parameters as $parameter) { - $arguments[$parameter->getName()] = ($parameter->hasType()) ? (string) $parameter->getType() : 'mixed'; + /** @var ReflectionNamedType|null $type */ + $type = ($parameter->hasType()) ? $parameter->getType() : null; + $arguments[$parameter->getName()] = (is_null($type)) ? 'mixed' : $type->getName(); } return $arguments; From 553b45306fe50ed3aa51db521d2b501c1e2b69e7 Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 16 Jun 2021 21:29:08 -0500 Subject: [PATCH 09/40] feat: handle unions (PHP 8) --- src/Support/Reflection.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Support/Reflection.php b/src/Support/Reflection.php index 7d46ece9..1719b9f6 100644 --- a/src/Support/Reflection.php +++ b/src/Support/Reflection.php @@ -12,6 +12,7 @@ use ReflectionException; use ReflectionFunction; use ReflectionNamedType; use ReflectionParameter; +use ReflectionUnionType; /** * @internal @@ -165,9 +166,23 @@ final class Reflection $arguments = []; foreach ($parameters as $parameter) { - /** @var ReflectionNamedType|null $type */ - $type = ($parameter->hasType()) ? $parameter->getType() : null; - $arguments[$parameter->getName()] = (is_null($type)) ? 'mixed' : $type->getName(); + /** @var ReflectionNamedType|ReflectionUnionType|null $types */ + $types = ($parameter->hasType()) ? $parameter->getType() : null; + + if (is_null($types)) { + $arguments[$parameter->getName()] = 'mixed'; + + continue; + } + + $arguments[$parameter->getName()] = implode('|', array_map( + static function (ReflectionNamedType $type): string { + return $type->getName(); + }, + ($types instanceof ReflectionNamedType) + ? [$types] // NOTE: normalize as list of to handle unions + : $types->getTypes(), + )); } return $arguments; From e64856c664f9cb530a4c70eb779187ed125e3710 Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Thu, 17 Jun 2021 13:33:11 -0500 Subject: [PATCH 10/40] test: use throws method instead of assert --- tests/Unit/TestSuite.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/Unit/TestSuite.php b/tests/Unit/TestSuite.php index c26149c8..62cc724d 100644 --- a/tests/Unit/TestSuite.php +++ b/tests/Unit/TestSuite.php @@ -8,15 +8,17 @@ it('does not allow to add the same test description twice', function () { $testSuite = new TestSuite(getcwd(), 'tests'); $test = function () {}; $testSuite->tests->set(new \Pest\Factories\TestCaseFactory(__FILE__, 'foo', $test)); - $this->expectException(TestAlreadyExist::class); - $this->expectExceptionMessage(sprintf('A test with the description `%s` already exist in the filename `%s`.', 'foo', __FILE__)); $testSuite->tests->set(new \Pest\Factories\TestCaseFactory(__FILE__, 'foo', $test)); -}); +})->throws( + TestAlreadyExist::class, + sprintf('A test with the description `%s` already exist in the filename `%s`.', 'foo', __FILE__), +); it('alerts users about tests with arguments but no input', function () { $testSuite = new TestSuite(getcwd(), 'tests'); $test = function (int $arg) {}; - $this->expectException(DatasetMissing::class); - $this->expectExceptionMessage(sprintf("A test with the description '%s' has %d argument(s) ([%s]) and no dataset(s) provided in %s", 'foo', 1, 'int $arg', __FILE__)); $testSuite->tests->set(new \Pest\Factories\TestCaseFactory(__FILE__, 'foo', $test)); -}); +})->throws( + DatasetMissing::class, + sprintf("A test with the description '%s' has %d argument(s) ([%s]) and no dataset(s) provided in %s", 'foo', 1, 'int $arg', __FILE__), +); From dc75b34deb3b969831888abc4bf450fef6106c69 Mon Sep 17 00:00:00 2001 From: Jordan Brauer Date: Wed, 30 Jun 2021 09:51:49 -0500 Subject: [PATCH 11/40] refactor: move logic into boolean method in TestCaseFactory --- src/Factories/TestCaseFactory.php | 8 ++++++++ src/Repositories/TestRepository.php | 2 +- tests/.snapshots/success.txt | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Factories/TestCaseFactory.php b/src/Factories/TestCaseFactory.php index 63eafaff..e849f95e 100644 --- a/src/Factories/TestCaseFactory.php +++ b/src/Factories/TestCaseFactory.php @@ -235,4 +235,12 @@ final class TestCaseFactory return $classFQN; } + + /** + * Determine if the test case will receive argument input from Pest, or not. + */ + public function receivesArguments(): bool + { + return $this->dependent === true || count($this->datasets) > 0; + } } diff --git a/src/Repositories/TestRepository.php b/src/Repositories/TestRepository.php index 305dc127..47684548 100644 --- a/src/Repositories/TestRepository.php +++ b/src/Repositories/TestRepository.php @@ -142,7 +142,7 @@ final class TestRepository throw new TestAlreadyExist($test->filename, $test->description); } - if ($test->dependent === false && count($test->datasets) === 0) { + if (!$test->receivesArguments()) { $arguments = Reflection::getFunctionArguments($test->test); if (count($arguments) > 0) { diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index 0a79e4e9..aa5966c7 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -580,5 +580,5 @@ ✓ it is a test ✓ it uses correct parent class - Tests: 4 incompleted, 7 skipped, 363 passed + Tests: 4 incompleted, 7 skipped, 364 passed \ No newline at end of file From 771b5b2e53a2979169d7969194b1158c108de921 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Fri, 16 Jul 2021 22:12:19 +0100 Subject: [PATCH 12/40] Adds Spatie --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 765fcafe..d3e3f16c 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,9 @@ We would like to extend our thanks to the following sponsors for funding Pest de ### Premium Sponsors -- **[Scout APM](https://scoutapm.com)** - **[Akaunting](https://akaunting.com)** +- **[Scout APM](https://scoutapm.com)** - **[Meema](https://meema.io/)** - +- **[Spatie](https://spatie.be/)** +- Pest was created by **[Nuno Maduro](https://twitter.com/enunomaduro)** under the **[Sponsorware license](https://github.com/sponsorware/docs)**. It got open-sourced and is now licensed under the **[MIT license](https://opensource.org/licenses/MIT)**. From 47ceb2419bd1e3211b2a212e4168becaece5e58e Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Fri, 16 Jul 2021 22:12:31 +0100 Subject: [PATCH 13/40] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d3e3f16c..6823ffee 100644 --- a/README.md +++ b/README.md @@ -25,5 +25,5 @@ We would like to extend our thanks to the following sponsors for funding Pest de - **[Scout APM](https://scoutapm.com)** - **[Meema](https://meema.io/)** - **[Spatie](https://spatie.be/)** -- + Pest was created by **[Nuno Maduro](https://twitter.com/enunomaduro)** under the **[Sponsorware license](https://github.com/sponsorware/docs)**. It got open-sourced and is now licensed under the **[MIT license](https://opensource.org/licenses/MIT)**. From 371620d16147e1e562a1c65e2b1f2912d06a02c1 Mon Sep 17 00:00:00 2001 From: luke Date: Wed, 21 Jul 2021 07:40:19 +0100 Subject: [PATCH 14/40] Adds support for receiving datasets in higher order tests --- src/Support/HigherOrderCallables.php | 4 ++-- src/Support/Reflection.php | 15 +++++++++++++++ tests/Features/HigherOrderTests.php | 9 +++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Support/HigherOrderCallables.php b/src/Support/HigherOrderCallables.php index 8b4dc817..b3bb633e 100644 --- a/src/Support/HigherOrderCallables.php +++ b/src/Support/HigherOrderCallables.php @@ -35,7 +35,7 @@ final class HigherOrderCallables */ public function expect($value) { - return new Expectation($value instanceof Closure ? Reflection::bindCallable($value) : $value); + return new Expectation($value instanceof Closure ? Reflection::bindCallableWithData($value) : $value); } /** @@ -59,7 +59,7 @@ final class HigherOrderCallables */ public function tap(callable $callable) { - Reflection::bindCallable($callable); + Reflection::bindCallableWithData($callable); return $this->target; } diff --git a/src/Support/Reflection.php b/src/Support/Reflection.php index fbe7ba40..e06b0280 100644 --- a/src/Support/Reflection.php +++ b/src/Support/Reflection.php @@ -60,6 +60,21 @@ final class Reflection return Closure::fromCallable($callable)->bindTo(TestSuite::getInstance()->test)(...$args); } + /** + * Bind a callable to the TestCase and return the result, + * passing in the current dataset values as arguments. + * + * @return mixed + */ + public static function bindCallableWithData(callable $callable) + { + $test = TestSuite::getInstance()->test; + + return $test === null + ? static::bindCallable($callable) + : Closure::fromCallable($callable)->bindTo($test)(...$test->getProvidedData()); + } + /** * Infers the file name from the given closure. */ diff --git a/tests/Features/HigherOrderTests.php b/tests/Features/HigherOrderTests.php index b45568e9..ba716f17 100644 --- a/tests/Features/HigherOrderTests.php +++ b/tests/Features/HigherOrderTests.php @@ -27,4 +27,13 @@ it('can tap into the test') ->toBe('foo') ->and('hello world')->toBeString(); +it('can pass datasets into the expect callables') + ->with([[1, 2, 3]]) + ->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') + ->with([[1, 2, 3]]) + ->tap(function (...$numbers) { expect($numbers)->toBe([1, 2, 3]); }); + afterEach()->assertTrue(true); From 3bdba9210d19575bec6613f3af430ba72fbd0e3a Mon Sep 17 00:00:00 2001 From: luke Date: Wed, 21 Jul 2021 07:44:05 +0100 Subject: [PATCH 15/40] Adds another test --- tests/Features/HigherOrderTests.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/Features/HigherOrderTests.php b/tests/Features/HigherOrderTests.php index ba716f17..e2ff0686 100644 --- a/tests/Features/HigherOrderTests.php +++ b/tests/Features/HigherOrderTests.php @@ -36,4 +36,11 @@ it('can pass datasets into the tap callable') ->with([[1, 2, 3]]) ->tap(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(); }) + ->toBeInt(); + afterEach()->assertTrue(true); From 82c18d38486fa16042efd9f2f7b2d77d07d0e2db Mon Sep 17 00:00:00 2001 From: luke Date: Wed, 21 Jul 2021 07:58:05 +0100 Subject: [PATCH 16/40] Type fixes --- src/Support/Reflection.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Support/Reflection.php b/src/Support/Reflection.php index e06b0280..819ad4a5 100644 --- a/src/Support/Reflection.php +++ b/src/Support/Reflection.php @@ -109,10 +109,6 @@ final class Reflection } } - if ($reflectionProperty === null) { - throw ShouldNotHappen::fromMessage('Reflection property not found.'); - } - $reflectionProperty->setAccessible(true); return $reflectionProperty->getValue($object); @@ -143,10 +139,6 @@ final class Reflection } } - if ($reflectionProperty === null) { - throw ShouldNotHappen::fromMessage('Reflection property not found.'); - } - $reflectionProperty->setAccessible(true); $reflectionProperty->setValue($object, $value); } From 09682dd393225c9d1cb29b9439ec500531c09dfc Mon Sep 17 00:00:00 2001 From: luke Date: Wed, 21 Jul 2021 08:16:54 +0100 Subject: [PATCH 17/40] Alters test to prove order doesn't matter --- tests/Features/HigherOrderTests.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Features/HigherOrderTests.php b/tests/Features/HigherOrderTests.php index e2ff0686..5505c8a0 100644 --- a/tests/Features/HigherOrderTests.php +++ b/tests/Features/HigherOrderTests.php @@ -37,10 +37,10 @@ it('can pass datasets into the tap callable') ->tap(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(); }) - ->toBeInt(); + ->toBeInt() + ->with('numbers.closure.wrapped'); afterEach()->assertTrue(true); From 4c8c42cd203dd14de90b4a5d3169d2a5147ec0c3 Mon Sep 17 00:00:00 2001 From: luke Date: Wed, 21 Jul 2021 08:47:55 +0100 Subject: [PATCH 18/40] Refactor --- tests/Features/HigherOrderTests.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Features/HigherOrderTests.php b/tests/Features/HigherOrderTests.php index 5505c8a0..e2ff0686 100644 --- a/tests/Features/HigherOrderTests.php +++ b/tests/Features/HigherOrderTests.php @@ -37,10 +37,10 @@ it('can pass datasets into the tap callable') ->tap(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(); }) - ->toBeInt() - ->with('numbers.closure.wrapped'); + ->toBeInt(); afterEach()->assertTrue(true); From 7ec3460d733f607870630788c69c16c0994b09f3 Mon Sep 17 00:00:00 2001 From: Reza Amini Date: Wed, 21 Jul 2021 13:02:09 +0430 Subject: [PATCH 19/40] Add --force flag to pest:test command --- src/Laravel/Commands/PestTestCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Laravel/Commands/PestTestCommand.php b/src/Laravel/Commands/PestTestCommand.php index 55d9dc3a..5c6196a5 100644 --- a/src/Laravel/Commands/PestTestCommand.php +++ b/src/Laravel/Commands/PestTestCommand.php @@ -21,7 +21,7 @@ final class PestTestCommand extends Command * * @var string */ - protected $signature = 'pest:test {name : The name of the file} {--unit : Create a unit test} {--dusk : Create a Dusk test} {--test-directory=tests : The name of the tests directory}'; + protected $signature = 'pest:test {name : The name of the file} {--unit : Create a unit test} {--dusk : Create a Dusk test} {--test-directory=tests : The name of the tests directory} {--force : Force create}'; /** * The console command description. @@ -56,7 +56,7 @@ final class PestTestCommand extends Command File::makeDirectory(dirname($target), 0777, true, true); } - if (File::exists($target)) { + if (File::exists($target) and !$this->option('force')) { throw new InvalidConsoleArgument(sprintf('%s already exist', $target)); } From 5e0a0855ea685872fe64602c4e7a01a48ab16492 Mon Sep 17 00:00:00 2001 From: Reza Amini Date: Wed, 21 Jul 2021 14:38:11 +0430 Subject: [PATCH 20/40] Add a better description --- src/Laravel/Commands/PestTestCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Laravel/Commands/PestTestCommand.php b/src/Laravel/Commands/PestTestCommand.php index 5c6196a5..c8eebcba 100644 --- a/src/Laravel/Commands/PestTestCommand.php +++ b/src/Laravel/Commands/PestTestCommand.php @@ -21,7 +21,7 @@ final class PestTestCommand extends Command * * @var string */ - protected $signature = 'pest:test {name : The name of the file} {--unit : Create a unit test} {--dusk : Create a Dusk test} {--test-directory=tests : The name of the tests directory} {--force : Force create}'; + protected $signature = 'pest:test {name : The name of the file} {--unit : Create a unit test} {--dusk : Create a Dusk test} {--test-directory=tests : The name of the tests directory} {--force : Overwrite the existing test file with the same name}'; /** * The console command description. From 328427bfdb1c21687afff0eb83c64e417b4539c6 Mon Sep 17 00:00:00 2001 From: luke Date: Wed, 21 Jul 2021 12:59:45 +0100 Subject: [PATCH 21/40] docs: update changelog --- CHANGELOG.md | 10 ++++++++++ src/Pest.php | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e602ee99..51343a9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [v1.11.0 (2021-07-21)](https://github.com/pestphp/pest/compare/v1.10.0...v1.11.0) +### Added +- Support for interacting with datasets in higher order tests ([#352](https://github.com/pestphp/pest/pull/352)) + +### Changed +- The unit test stub now uses the expectation API ([#348](https://github.com/pestphp/pest/pull/348)) + +### Fixed +- PhpStorm will no longer show 0 assertions in the output ([#349](https://github.com/pestphp/pest/pull/349)) + ## [v1.10.0 (2021-07-12)](https://github.com/pestphp/pest/compare/v1.9.1...v1.10.0) ### Added - The ability to use higher order expectations inside higher order tests ([#341](https://github.com/pestphp/pest/pull/341)) diff --git a/src/Pest.php b/src/Pest.php index e694346c..cdc57677 100644 --- a/src/Pest.php +++ b/src/Pest.php @@ -6,7 +6,7 @@ namespace Pest; function version(): string { - return '1.10.0'; + return '1.11.0'; } function testDirectory(string $file = ''): string From 595bbe32a48b8e419e70b3fb9d26076d46a05ba2 Mon Sep 17 00:00:00 2001 From: Reza Amini Date: Thu, 22 Jul 2021 01:41:12 +0430 Subject: [PATCH 22/40] Add bool to the condition --- src/Laravel/Commands/PestTestCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Laravel/Commands/PestTestCommand.php b/src/Laravel/Commands/PestTestCommand.php index c8eebcba..7561355b 100644 --- a/src/Laravel/Commands/PestTestCommand.php +++ b/src/Laravel/Commands/PestTestCommand.php @@ -56,7 +56,7 @@ final class PestTestCommand extends Command File::makeDirectory(dirname($target), 0777, true, true); } - if (File::exists($target) and !$this->option('force')) { + if (File::exists($target) and !(bool) $this->option('force')) { throw new InvalidConsoleArgument(sprintf('%s already exist', $target)); } From 79ff332afeb8e9ae88d966084e6569b7271e64ea Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 21 Jul 2021 20:32:39 -0500 Subject: [PATCH 23/40] test: global "all" hooks must only run once (#351) in other words, they can only run once per file --- tests/Hooks/AfterAllTest.php | 30 +++++++++++++++++++++++--- tests/Hooks/BeforeAllTest.php | 40 +++++++++++++++++++++++++++++------ tests/Pest.php | 5 ++++- 3 files changed, 65 insertions(+), 10 deletions(-) diff --git a/tests/Hooks/AfterAllTest.php b/tests/Hooks/AfterAllTest.php index a34a5847..fb8a71d4 100644 --- a/tests/Hooks/AfterAllTest.php +++ b/tests/Hooks/AfterAllTest.php @@ -2,26 +2,50 @@ global $globalHook; +// NOTE: this test does not have a $globalHook->calls offset since it is first +// in the directory and thus will always run before the others. See also the +// BeforeAllTest.php for details. + uses()->afterAll(function () use ($globalHook) { expect($globalHook) ->toHaveProperty('afterAll') ->and($globalHook->afterAll) - ->toBe(0); + ->toBe(0) + ->and($globalHook->calls) + ->afterAll + ->toBe(1); $globalHook->afterAll = 1; + $globalHook->calls->afterAll++; }); afterAll(function () use ($globalHook) { expect($globalHook) ->toHaveProperty('afterAll') ->and($globalHook->afterAll) - ->toBe(1); + ->toBe(1) + ->and($globalHook->calls) + ->afterAll + ->toBe(2); $globalHook->afterAll = 2; + $globalHook->calls->afterAll++; }); test('global afterAll execution order', function () use ($globalHook) { expect($globalHook) ->not() - ->toHaveProperty('afterAll'); + ->toHaveProperty('afterAll') + ->and($globalHook->calls) + ->afterAll + ->toBe(0); +}); + +test('it only gets called once per file', function () use ($globalHook) { + expect($globalHook) + ->not() + ->toHaveProperty('afterAll') + ->and($globalHook->calls) + ->afterAll + ->toBe(0); }); diff --git a/tests/Hooks/BeforeAllTest.php b/tests/Hooks/BeforeAllTest.php index 11c996c5..838d7c14 100644 --- a/tests/Hooks/BeforeAllTest.php +++ b/tests/Hooks/BeforeAllTest.php @@ -1,28 +1,56 @@ beforeAll(function () use ($globalHook) { +// HACK: we have to determine our $globalHook->calls baseline. This is because +// two other tests are executed before this one due to filename ordering. +$args = $_SERVER['argv'] ?? []; +$single = isset($args[1]) && Str::endsWith(__FILE__, $args[1]); +$offset = $single ? 0 : 2; + +uses()->beforeAll(function () use ($globalHook, $offset) { expect($globalHook) ->toHaveProperty('beforeAll') ->and($globalHook->beforeAll) - ->toBe(0); + ->toBe(0) + ->and($globalHook->calls) + ->beforeAll + ->toBe(1 + $offset); $globalHook->beforeAll = 1; + $globalHook->calls->beforeAll++; }); -beforeAll(function () use ($globalHook) { +beforeAll(function () use ($globalHook, $offset) { expect($globalHook) ->toHaveProperty('beforeAll') ->and($globalHook->beforeAll) - ->toBe(1); + ->toBe(1) + ->and($globalHook->calls) + ->beforeAll + ->toBe(2 + $offset); $globalHook->beforeAll = 2; + $globalHook->calls->beforeAll++; }); -test('global beforeAll execution order', function () use ($globalHook) { +test('global beforeAll execution order', function () use ($globalHook, $offset) { expect($globalHook) ->toHaveProperty('beforeAll') ->and($globalHook->beforeAll) - ->toBe(2); + ->toBe(2) + ->and($globalHook->calls) + ->beforeAll + ->toBe(3 + $offset); +}); + +it('only gets called once per file', function () use ($globalHook, $offset) { + expect($globalHook) + ->beforeAll + ->toBe(2) + ->and($globalHook->calls) + ->beforeAll + ->toBe(3 + $offset); }); diff --git a/tests/Pest.php b/tests/Pest.php index a8cd868d..d3fe584f 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -2,7 +2,8 @@ uses()->group('integration')->in('Visual'); -$globalHook = (object) []; // NOTE: global test value container to be mutated and checked across files, as needed +// NOTE: global test value container to be mutated and checked across files, as needed +$globalHook = (object) ['calls' => (object) ['beforeAll' => 0, 'afterAll' => 0]]; uses() ->beforeEach(function () { @@ -10,11 +11,13 @@ uses() }) ->beforeAll(function () use ($globalHook) { $globalHook->beforeAll = 0; + $globalHook->calls->beforeAll++; }) ->afterEach(function () { $this->ith = 0; }) ->afterAll(function () use ($globalHook) { $globalHook->afterAll = 0; + $globalHook->calls->afterAll++; }) ->in('Hooks'); From 60c0ad006f866f7e28dd45b6e324736d63692321 Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 21 Jul 2021 20:38:20 -0500 Subject: [PATCH 24/40] fix: prevent the global hooks from piling up (#351) this happens due to the global `*All()` hooks (before & after) being defined as static. We should be a good citizen and we need to clean up our mess for the next person in the test instance constructor --- src/Concerns/Testable.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Concerns/Testable.php b/src/Concerns/Testable.php index 5c72e0f3..91b73d72 100644 --- a/src/Concerns/Testable.php +++ b/src/Concerns/Testable.php @@ -73,6 +73,7 @@ trait Testable { $this->__test = $test; $this->__description = $description; + self::$beforeAll = self::$afterAll = null; parent::__construct('__test', $data); } From b6012862c4cbb02b85f8dd0193a4fc819180d83b Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 21 Jul 2021 20:43:21 -0500 Subject: [PATCH 25/40] style: run linter --- tests/Hooks/BeforeAllTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Hooks/BeforeAllTest.php b/tests/Hooks/BeforeAllTest.php index 838d7c14..05e57252 100644 --- a/tests/Hooks/BeforeAllTest.php +++ b/tests/Hooks/BeforeAllTest.php @@ -6,7 +6,7 @@ global $globalHook; // HACK: we have to determine our $globalHook->calls baseline. This is because // two other tests are executed before this one due to filename ordering. -$args = $_SERVER['argv'] ?? []; +$args = $_SERVER['argv'] ?? []; $single = isset($args[1]) && Str::endsWith(__FILE__, $args[1]); $offset = $single ? 0 : 2; From d217503a6abf126ce6617eb1c783fea0a72bb851 Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Wed, 21 Jul 2021 20:47:48 -0500 Subject: [PATCH 26/40] test: use consistent test descriptors --- tests/Hooks/AfterAllTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Hooks/AfterAllTest.php b/tests/Hooks/AfterAllTest.php index fb8a71d4..b9042815 100644 --- a/tests/Hooks/AfterAllTest.php +++ b/tests/Hooks/AfterAllTest.php @@ -41,7 +41,7 @@ test('global afterAll execution order', function () use ($globalHook) { ->toBe(0); }); -test('it only gets called once per file', function () use ($globalHook) { +it('only gets called once per file', function () use ($globalHook) { expect($globalHook) ->not() ->toHaveProperty('afterAll') From 863ddea50b5269a7b9b7e83067306169cb398b9b Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Thu, 22 Jul 2021 17:54:22 -0500 Subject: [PATCH 27/40] style: split assignment into two lines clarity --- src/Concerns/Testable.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Concerns/Testable.php b/src/Concerns/Testable.php index 91b73d72..d8137311 100644 --- a/src/Concerns/Testable.php +++ b/src/Concerns/Testable.php @@ -73,7 +73,8 @@ trait Testable { $this->__test = $test; $this->__description = $description; - self::$beforeAll = self::$afterAll = null; + self::$beforeAll = null; + self::$afterAll = null; parent::__construct('__test', $data); } From ca9d783cf942a2caabc85ff7a728c7f28350c67a Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Mon, 26 Jul 2021 22:02:57 +0100 Subject: [PATCH 28/40] chore: makes `phpunit/phpunit` requirement above `^9.3.7` --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 2224ac7f..bee8f8b7 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ "php": "^7.3 || ^8.0", "nunomaduro/collision": "^5.4.0", "pestphp/pest-plugin": "^1.0.0", - "phpunit/phpunit": ">= 9.3.7 <= 9.5.6" + "phpunit/phpunit": "^9.3.7" }, "autoload": { "psr-4": { From 09d2b16767e3e1c1a881e96129399cc268da45e4 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Mon, 26 Jul 2021 22:45:03 +0100 Subject: [PATCH 29/40] docs: updates changelog --- CHANGELOG.md | 8 ++++++++ src/Laravel/Commands/PestTestCommand.php | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51343a9f..3c59eb65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [v1.12.0 (2021-07-26)](https://github.com/pestphp/pest/compare/v1.11.0...v1.12.0) +### Added +- `--force` option to override tests in `pest:test` artisan command ([#353](https://github.com/pestphp/pest/pull/353)) +- Support for PHPUnit `^9.3.7` ([ca9d783](https://github.com/pestphp/pest/commit/ca9d783cf942a2caabc85ff7a728c7f28350c67a)) + +### Fixed +- `beforeAll` and `afterAll` behind called multiple times per test ([#357](https://github.com/pestphp/pest/pull/357)) + ## [v1.11.0 (2021-07-21)](https://github.com/pestphp/pest/compare/v1.10.0...v1.11.0) ### Added - Support for interacting with datasets in higher order tests ([#352](https://github.com/pestphp/pest/pull/352)) diff --git a/src/Laravel/Commands/PestTestCommand.php b/src/Laravel/Commands/PestTestCommand.php index 7561355b..ee18e076 100644 --- a/src/Laravel/Commands/PestTestCommand.php +++ b/src/Laravel/Commands/PestTestCommand.php @@ -56,7 +56,7 @@ final class PestTestCommand extends Command File::makeDirectory(dirname($target), 0777, true, true); } - if (File::exists($target) and !(bool) $this->option('force')) { + if (File::exists($target) && !(bool) $this->option('force')) { throw new InvalidConsoleArgument(sprintf('%s already exist', $target)); } From 4ebba1298ae9d4b50f455ed45a6c17706fe76d3d Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Mon, 26 Jul 2021 22:46:22 +0100 Subject: [PATCH 30/40] release: v1.12.0 --- src/Pest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pest.php b/src/Pest.php index cdc57677..38526338 100644 --- a/src/Pest.php +++ b/src/Pest.php @@ -6,7 +6,7 @@ namespace Pest; function version(): string { - return '1.11.0'; + return '1.12.0'; } function testDirectory(string $file = ''): string From 4813ab6ffb51632cd2a4f4752143602057585355 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Mon, 26 Jul 2021 23:18:55 +0100 Subject: [PATCH 31/40] Add sponsor --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6823ffee..1280737f 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,9 @@ We would like to extend our thanks to the following sponsors for funding Pest de ### Premium Sponsors - **[Akaunting](https://akaunting.com)** -- **[Scout APM](https://scoutapm.com)** +- **[Codecourse](https://codecourse.com/)** - **[Meema](https://meema.io/)** +- **[Scout APM](https://scoutapm.com)** - **[Spatie](https://spatie.be/)** Pest was created by **[Nuno Maduro](https://twitter.com/enunomaduro)** under the **[Sponsorware license](https://github.com/sponsorware/docs)**. It got open-sourced and is now licensed under the **[MIT license](https://opensource.org/licenses/MIT)**. From 6309e6818d8902e9600c719ac66b724f269d65e8 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Mon, 26 Jul 2021 23:19:51 +0100 Subject: [PATCH 32/40] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1280737f..541d9f24 100644 --- a/README.md +++ b/README.md @@ -27,4 +27,4 @@ We would like to extend our thanks to the following sponsors for funding Pest de - **[Scout APM](https://scoutapm.com)** - **[Spatie](https://spatie.be/)** -Pest was created by **[Nuno Maduro](https://twitter.com/enunomaduro)** under the **[Sponsorware license](https://github.com/sponsorware/docs)**. It got open-sourced and is now licensed under the **[MIT license](https://opensource.org/licenses/MIT)**. +Pest is an open-sourced software licensed under the **[MIT license](https://opensource.org/licenses/MIT)**. From 5f574ded814525931c6adc71448437581cdf07b5 Mon Sep 17 00:00:00 2001 From: freek Date: Wed, 28 Jul 2021 00:36:43 +0200 Subject: [PATCH 33/40] add toBeIn --- src/Expectation.php | 10 ++++++++++ tests/Features/Expect/toBeIn.php | 11 +++++++++++ 2 files changed, 21 insertions(+) create mode 100644 tests/Features/Expect/toBeIn.php diff --git a/src/Expectation.php b/src/Expectation.php index e41f21d0..2e92434e 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -371,6 +371,16 @@ final class Expectation return $this; } + /** + * Asserts that the value is one of the given values. + */ + public function toBeIn(array $possibleValues): Expectation + { + Assert::assertContains($this->value, $possibleValues); + + return $this; + } + /** * Asserts that the value is infinite. */ diff --git a/tests/Features/Expect/toBeIn.php b/tests/Features/Expect/toBeIn.php new file mode 100644 index 00000000..3d34f46a --- /dev/null +++ b/tests/Features/Expect/toBeIn.php @@ -0,0 +1,11 @@ +toBeIn(['a', 'b', 'c']); +}); + +test('failures', function () { + expect('d')->toBeIn(['a', 'b', 'c']); +})->throws(ExpectationFailedException::class); From 2dd77001b7cc8f2824a5ee2b5d754831212e440b Mon Sep 17 00:00:00 2001 From: freek Date: Wed, 28 Jul 2021 00:42:54 +0200 Subject: [PATCH 34/40] static analysis fix --- src/Expectation.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Expectation.php b/src/Expectation.php index 2e92434e..e32a8683 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -373,6 +373,8 @@ final class Expectation /** * Asserts that the value is one of the given values. + * + * @param array $possibleValues */ public function toBeIn(array $possibleValues): Expectation { From 671f3df115bcf5bcba67c59ed3a635abe0ebf755 Mon Sep 17 00:00:00 2001 From: freek Date: Wed, 28 Jul 2021 01:00:19 +0200 Subject: [PATCH 35/40] fix tests --- src/Expectation.php | 6 +++--- tests/Features/Expect/toBeIn.php | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Expectation.php b/src/Expectation.php index e32a8683..e76a30bd 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -374,11 +374,11 @@ final class Expectation /** * Asserts that the value is one of the given values. * - * @param array $possibleValues + * @param iterable $values */ - public function toBeIn(array $possibleValues): Expectation + public function toBeIn(iterable $values): Expectation { - Assert::assertContains($this->value, $possibleValues); + Assert::assertContains($this->value, $values); return $this; } diff --git a/tests/Features/Expect/toBeIn.php b/tests/Features/Expect/toBeIn.php index 3d34f46a..6636a51b 100644 --- a/tests/Features/Expect/toBeIn.php +++ b/tests/Features/Expect/toBeIn.php @@ -4,8 +4,13 @@ use PHPUnit\Framework\ExpectationFailedException; test('passes', function () { expect('a')->toBeIn(['a', 'b', 'c']); + expect('d')->not->toBeIn(['a', 'b', 'c']); }); test('failures', function () { expect('d')->toBeIn(['a', 'b', 'c']); })->throws(ExpectationFailedException::class); + +test('not failures', function () { + expect('a')->not->toBeIn(['a', 'b', 'c']); +})->throws(ExpectationFailedException::class); From 22b822ce87a3d19d84960fa5c93eb286820b525d Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Wed, 28 Jul 2021 01:57:13 +0100 Subject: [PATCH 36/40] fix: skip with a false condition being ignored --- src/PendingObjects/TestCall.php | 2 ++ tests/.snapshots/success.txt | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/PendingObjects/TestCall.php b/src/PendingObjects/TestCall.php index 81bf9243..de74cf99 100644 --- a/src/PendingObjects/TestCall.php +++ b/src/PendingObjects/TestCall.php @@ -148,6 +148,8 @@ final class TestCall ? $conditionOrMessage : $message; + $condition = $condition->bindTo(null); + $this->testCaseFactory ->chains ->addWhen($condition, Backtrace::file(), Backtrace::line(), 'markTestSkipped', [$message]); diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index d943da92..74ededc0 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -101,6 +101,7 @@ ✓ it gives access the the underlying expectException ✓ it catch exceptions ✓ it catch exceptions and messages + ✓ it can just define the message PASS Tests\Features\Expect\HigherOrder\methods ✓ it can access methods @@ -112,11 +113,14 @@ ✓ it works with sequence ✓ it can compose complex expectations ✓ it can handle nested method calls + ✓ it works with higher order tests PASS Tests\Features\Expect\HigherOrder\methodsAndProperties ✓ it can access methods and properties ✓ it can handle nested methods and properties + ✓ it works with higher order tests ✓ it can start a new higher order expectation using the and syntax + ✓ it can start a new higher order expectation using the and syntax in higher order tests PASS Tests\Features\Expect\HigherOrder\properties ✓ it allows properties to be accessed from the value @@ -128,6 +132,7 @@ ✓ it can compose complex expectations ✓ it works with objects ✓ it works with nested properties + ✓ it works with higher order tests PASS Tests\Features\Expect\each ✓ an exception is thrown if the the type is not iterable @@ -216,6 +221,11 @@ PASS Tests\Features\Expect\toBeGreatherThanOrEqual ✓ passes ✓ failures + ✓ not failures + + PASS Tests\Features\Expect\toBeIn + ✓ passes + ✓ failures ✓ not failures PASS Tests\Features\Expect\toBeInfinite @@ -411,7 +421,12 @@ ✓ it proxies calls to object ✓ it is capable doing multiple assertions ✓ it resolves expect callables correctly + ✓ does not treat method names as callables ✓ it can tap into the test + ✓ it can pass datasets into the expect callables with (1, 2, 3) + ✓ it can pass datasets into the tap callable with (1, 2, 3) + ✓ it can pass shared datasets into callables with (1) + ✓ it can pass shared datasets into callables with (2) WARN Tests\Features\Incompleted … incompleted @@ -444,6 +459,8 @@ ✓ it do not skips with falsy closure condition - it skips with condition and message → skipped because foo - it skips when skip after assertion + - it can use something in the test case as a condition → This test was skipped + - it can user higher order callables and skip PASS Tests\Features\Test ✓ a test @@ -457,12 +474,14 @@ PASS Tests\Hooks\AfterAllTest ✓ global afterAll execution order + ✓ it only gets called once per file PASS Tests\Hooks\AfterEachTest ✓ global afterEach execution order PASS Tests\Hooks\BeforeAllTest ✓ global beforeAll execution order + ✓ it only gets called once per file PASS Tests\Hooks\BeforeEachTest ✓ global beforeEach execution order @@ -581,5 +600,5 @@ ✓ it is a test ✓ it uses correct parent class - Tests: 4 incompleted, 7 skipped, 365 passed + Tests: 4 incompleted, 9 skipped, 380 passed \ No newline at end of file From 2b5355419a64ed031b5f07003b48d0c77dd68cf8 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Wed, 28 Jul 2021 01:59:47 +0100 Subject: [PATCH 37/40] chore: fixes types --- src/PendingObjects/TestCall.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PendingObjects/TestCall.php b/src/PendingObjects/TestCall.php index de74cf99..be839bff 100644 --- a/src/PendingObjects/TestCall.php +++ b/src/PendingObjects/TestCall.php @@ -148,6 +148,7 @@ final class TestCall ? $conditionOrMessage : $message; + /** @var callable(): bool $condition */ $condition = $condition->bindTo(null); $this->testCaseFactory From cd9d4acbc2b5e1db65f428037737aad1d2980063 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Wed, 28 Jul 2021 02:03:24 +0100 Subject: [PATCH 38/40] release: v1.13.0 --- CHANGELOG.md | 7 +++++++ src/Pest.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c59eb65..0b05a97d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [v1.13.0 (2021-07-28)](https://github.com/pestphp/pest/compare/v1.12.0...v1.13.0) +### Added +- `toBeIn` expectation ([#363](https://github.com/pestphp/pest/pull/363)) + +### Fixed +- `skip` with false condition marking test as skipped ([22b822c](https://github.com/pestphp/pest/commit/22b822ce87a3d19d84960fa5c93eb286820b525d)) + ## [v1.12.0 (2021-07-26)](https://github.com/pestphp/pest/compare/v1.11.0...v1.12.0) ### Added - `--force` option to override tests in `pest:test` artisan command ([#353](https://github.com/pestphp/pest/pull/353)) diff --git a/src/Pest.php b/src/Pest.php index 38526338..d9efe05f 100644 --- a/src/Pest.php +++ b/src/Pest.php @@ -6,7 +6,7 @@ namespace Pest; function version(): string { - return '1.12.0'; + return '1.13.0'; } function testDirectory(string $file = ''): string From 43920f79a902148325bf6da4573fdbea3bf1097d Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Tue, 27 Jul 2021 23:36:09 -0500 Subject: [PATCH 39/40] feat: add count method for checking message type presence --- src/Support/HigherOrderMessageCollection.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Support/HigherOrderMessageCollection.php b/src/Support/HigherOrderMessageCollection.php index b107bdba..a6634685 100644 --- a/src/Support/HigherOrderMessageCollection.php +++ b/src/Support/HigherOrderMessageCollection.php @@ -53,4 +53,20 @@ final class HigherOrderMessageCollection $message->call($target); } } + + /** + * Count the number of messages with the given name. + * + * @param string $name A higher order message name (usually a method name) + */ + public function count(string $name): int + { + return array_reduce( + $this->messages, + static function (int $total, HigherOrderMessage $message) use ($name): int { + return $total + (int) ($name === $message->name); + }, + 0, + ); + } } From 8d24b4a217f9421257c08ddff86bd639fe516697 Mon Sep 17 00:00:00 2001 From: jordanbrauer <18744334+jordanbrauer@users.noreply.github.com> Date: Tue, 27 Jul 2021 23:39:26 -0500 Subject: [PATCH 40/40] chore: replace prop set/check with method call --- src/Factories/TestCaseFactory.php | 10 ++-------- src/PendingObjects/TestCall.php | 2 -- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/Factories/TestCaseFactory.php b/src/Factories/TestCaseFactory.php index e849f95e..bc75f5c1 100644 --- a/src/Factories/TestCaseFactory.php +++ b/src/Factories/TestCaseFactory.php @@ -66,13 +66,6 @@ final class TestCaseFactory */ public $datasets = []; - /** - * Has the current test been marked dependent on others? - * - * @var bool - */ - public $dependent = false; - /** * The FQN of the test case class. * @@ -241,6 +234,7 @@ final class TestCaseFactory */ public function receivesArguments(): bool { - return $this->dependent === true || count($this->datasets) > 0; + return count($this->datasets) > 0 + || $this->factoryProxies->count('addDependencies') > 0; } } diff --git a/src/PendingObjects/TestCall.php b/src/PendingObjects/TestCall.php index d97f1ac2..be839bff 100644 --- a/src/PendingObjects/TestCall.php +++ b/src/PendingObjects/TestCall.php @@ -102,8 +102,6 @@ final class TestCall ->factoryProxies ->add(Backtrace::file(), Backtrace::line(), 'addDependencies', [$tests]); - $this->testCaseFactory->dependent = true; - return $this; }