From d0a74931dda2b2219d874533418f97689161e829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20N=C3=BCrnberger?= Date: Fri, 19 Jun 2020 19:50:54 +0200 Subject: [PATCH 1/9] implemented support for PHPUnit's @depends --- src/Concerns/TestCase.php | 17 +++++++---- src/Factories/TestCaseFactory.php | 5 ++-- src/PendingObjects/TestCall.php | 14 +++++++++ src/Support/ExceptionTrace.php | 4 +-- src/Support/Mixed.php | 32 +++++++++++++++++++++ tests/.snapshots/success.txt | 13 +++++++-- tests/Features/Depends.php | 47 +++++++++++++++++++++++++++++++ 7 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 src/Support/Mixed.php create mode 100644 tests/Features/Depends.php diff --git a/src/Concerns/TestCase.php b/src/Concerns/TestCase.php index 5dbac402..8191256c 100644 --- a/src/Concerns/TestCase.php +++ b/src/Concerns/TestCase.php @@ -53,6 +53,11 @@ trait TestCase $this->setGroups($groups); } + public function addDependencies(array $tests): void + { + $this->setDependencies($tests); + } + /** * Returns the test case name. Note that, in Pest * we ignore withDataset argument as the description @@ -130,16 +135,16 @@ trait TestCase /** * Runs the test. */ - public function __test(): void + public function __test() { - $this->__callClosure($this->__test, func_get_args()); + return $this->__callClosure($this->__test, func_get_args()); } - private function __callClosure(Closure $closure, array $arguments): void + private function __callClosure(Closure $closure, array $arguments) { - ExceptionTrace::ensure(function () use ($closure, $arguments) { - call_user_func_array(Closure::bind($closure, $this, get_class($this)), $arguments); - }); + return ExceptionTrace::ensure(function () use ($closure, $arguments) { + return call_user_func_array(Closure::bind($closure, $this, get_class($this)), $arguments); + })->getValue(); } public function getPrintableTestCaseName(): string diff --git a/src/Factories/TestCaseFactory.php b/src/Factories/TestCaseFactory.php index 49c6eaad..88124936 100644 --- a/src/Factories/TestCaseFactory.php +++ b/src/Factories/TestCaseFactory.php @@ -132,10 +132,11 @@ final class TestCaseFactory $proxies = $this->proxies; $factoryTest = $this->test; - $test = function () use ($chains, $proxies, $factoryTest): void { + $test = function () use ($chains, $proxies, $factoryTest) { $proxies->proxy($this); $chains->chain($this); - call_user_func(Closure::bind($factoryTest, $this, get_class($this)), ...func_get_args()); + + return call_user_func(Closure::bind($factoryTest, $this, get_class($this)), ...func_get_args()); }; $className = $this->makeClassFromFilename($this->filename); diff --git a/src/PendingObjects/TestCall.php b/src/PendingObjects/TestCall.php index 7b7549ae..66703a50 100644 --- a/src/PendingObjects/TestCall.php +++ b/src/PendingObjects/TestCall.php @@ -84,6 +84,20 @@ final class TestCall return $this; } + public function dependsOn(string ...$tests): TestCall + { + $this->testCaseFactory + ->factoryProxies + ->add(Backtrace::file(), Backtrace::line(), 'addDependencies', [$tests]); + + return $this; + } + + public function depends(string ...$tests): TestCall + { + return $this->dependsOn(...$tests); + } + /** * Makes the test suite only this test case. */ diff --git a/src/Support/ExceptionTrace.php b/src/Support/ExceptionTrace.php index a7166f41..320716e0 100644 --- a/src/Support/ExceptionTrace.php +++ b/src/Support/ExceptionTrace.php @@ -18,10 +18,10 @@ final class ExceptionTrace * Ensures the given closure reports * the good execution context. */ - public static function ensure(Closure $closure): void + public static function ensure(Closure $closure): Mixed { try { - $closure(); + return new Mixed($closure()); } catch (Throwable $throwable) { if (Str::startsWith($message = $throwable->getMessage(), self::UNDEFINED_METHOD)) { $message = str_replace(self::UNDEFINED_METHOD, 'Call to undefined method ', $message); diff --git a/src/Support/Mixed.php b/src/Support/Mixed.php new file mode 100644 index 00000000..17ea6060 --- /dev/null +++ b/src/Support/Mixed.php @@ -0,0 +1,32 @@ +value = $value; + } + + /** + * @return mixed + */ + public function getValue() + { + return $this->value; + } +} diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index 961a0180..a0b846d0 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -42,6 +42,15 @@ ✓ eager registered wrapped datasets did the job right ✓ lazy named datasets with (Bar Object (...)) + PASS Tests\Features\Depends + ✓ first + ✓ second + ✓ dependsOn + ✓ dependsOn with ...params + ✓ dependsOn with defined arguments + ✓ dependsOn run test only once + ✓ depends alias for dependsOn + PASS Tests\Features\Exceptions ✓ it gives access the the underlying expectException ✓ it catch exceptions @@ -144,5 +153,5 @@ WARN Tests\Visual\Success s visual snapshot of test suite on success - Tests: 6 skipped, 79 passed - Time: 3.44s + Tests: 6 skipped, 86 passed + Time: 2.61s diff --git a/tests/Features/Depends.php b/tests/Features/Depends.php new file mode 100644 index 00000000..0bf30539 --- /dev/null +++ b/tests/Features/Depends.php @@ -0,0 +1,47 @@ +dependsOn('first', 'second'); + +test('dependsOn with ...params', function (string ...$params) { + assertEquals( + ['first', 'second'], + $params + ); +})->dependsOn('first', 'second'); + +test('dependsOn with defined arguments', function (string $first, string $second) { + assertEquals('first', $first); + assertEquals('second', $second); +})->dependsOn('first', 'second'); + +test('dependsOn run test only once', function () use (&$runCounter) { + assertEquals(2, $runCounter); +})->dependsOn('first', 'second'); + +test('depends alias for dependsOn', function (string ...$params) { + assertEquals( + ['first', 'second'], + $params + ); +})->depends('first', 'second'); From 75f7ee0acf5a54c85cb78b73434078667fbd764a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20N=C3=BCrnberger?= Date: Fri, 19 Jun 2020 20:39:09 +0200 Subject: [PATCH 2/9] added feedback from @nunomaduro --- src/Concerns/TestCase.php | 7 +------ src/PendingObjects/TestCall.php | 9 ++------- src/Support/ExceptionTrace.php | 4 ++-- src/Support/Mixed.php | 32 -------------------------------- tests/.snapshots/success.txt | 13 ++++++------- tests/Features/Depends.php | 31 ++++++++++++------------------- 6 files changed, 23 insertions(+), 73 deletions(-) delete mode 100644 src/Support/Mixed.php diff --git a/src/Concerns/TestCase.php b/src/Concerns/TestCase.php index 8191256c..369bb5d5 100644 --- a/src/Concerns/TestCase.php +++ b/src/Concerns/TestCase.php @@ -53,11 +53,6 @@ trait TestCase $this->setGroups($groups); } - public function addDependencies(array $tests): void - { - $this->setDependencies($tests); - } - /** * Returns the test case name. Note that, in Pest * we ignore withDataset argument as the description @@ -144,7 +139,7 @@ trait TestCase { return ExceptionTrace::ensure(function () use ($closure, $arguments) { return call_user_func_array(Closure::bind($closure, $this, get_class($this)), $arguments); - })->getValue(); + }); } public function getPrintableTestCaseName(): string diff --git a/src/PendingObjects/TestCall.php b/src/PendingObjects/TestCall.php index 66703a50..259d8654 100644 --- a/src/PendingObjects/TestCall.php +++ b/src/PendingObjects/TestCall.php @@ -84,20 +84,15 @@ final class TestCall return $this; } - public function dependsOn(string ...$tests): TestCall + public function depends(string ...$tests): TestCall { $this->testCaseFactory ->factoryProxies - ->add(Backtrace::file(), Backtrace::line(), 'addDependencies', [$tests]); + ->add(Backtrace::file(), Backtrace::line(), 'setDependencies', [$tests]); return $this; } - public function depends(string ...$tests): TestCall - { - return $this->dependsOn(...$tests); - } - /** * Makes the test suite only this test case. */ diff --git a/src/Support/ExceptionTrace.php b/src/Support/ExceptionTrace.php index 320716e0..e7c31d58 100644 --- a/src/Support/ExceptionTrace.php +++ b/src/Support/ExceptionTrace.php @@ -18,10 +18,10 @@ final class ExceptionTrace * Ensures the given closure reports * the good execution context. */ - public static function ensure(Closure $closure): Mixed + public static function ensure(Closure $closure) { try { - return new Mixed($closure()); + return $closure(); } catch (Throwable $throwable) { if (Str::startsWith($message = $throwable->getMessage(), self::UNDEFINED_METHOD)) { $message = str_replace(self::UNDEFINED_METHOD, 'Call to undefined method ', $message); diff --git a/src/Support/Mixed.php b/src/Support/Mixed.php deleted file mode 100644 index 17ea6060..00000000 --- a/src/Support/Mixed.php +++ /dev/null @@ -1,32 +0,0 @@ -value = $value; - } - - /** - * @return mixed - */ - public function getValue() - { - return $this->value; - } -} diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index a0b846d0..3e6832ec 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -45,11 +45,10 @@ PASS Tests\Features\Depends ✓ first ✓ second - ✓ dependsOn - ✓ dependsOn with ...params - ✓ dependsOn with defined arguments - ✓ dependsOn run test only once - ✓ depends alias for dependsOn + ✓ depends + ✓ depends with ...params + ✓ depends with defined arguments + ✓ depends run test only once PASS Tests\Features\Exceptions ✓ it gives access the the underlying expectException @@ -153,5 +152,5 @@ WARN Tests\Visual\Success s visual snapshot of test suite on success - Tests: 6 skipped, 86 passed - Time: 2.61s + Tests: 6 skipped, 85 passed + Time: 2.60s diff --git a/tests/Features/Depends.php b/tests/Features/Depends.php index 0bf30539..0e7ed5ea 100644 --- a/tests/Features/Depends.php +++ b/tests/Features/Depends.php @@ -16,32 +16,25 @@ test('second', function () use (&$runCounter) { return 'second'; }); -test('dependsOn', function () { +test('depends', function () { assertEquals( ['first', 'second'], func_get_args() ); -})->dependsOn('first', 'second'); +})->depends('first', 'second'); -test('dependsOn with ...params', function (string ...$params) { - assertEquals( - ['first', 'second'], - $params - ); -})->dependsOn('first', 'second'); - -test('dependsOn with defined arguments', function (string $first, string $second) { - assertEquals('first', $first); - assertEquals('second', $second); -})->dependsOn('first', 'second'); - -test('dependsOn run test only once', function () use (&$runCounter) { - assertEquals(2, $runCounter); -})->dependsOn('first', 'second'); - -test('depends alias for dependsOn', function (string ...$params) { +test('depends with ...params', function (string ...$params) { assertEquals( ['first', 'second'], $params ); })->depends('first', 'second'); + +test('depends with defined arguments', function (string $first, string $second) { + assertEquals('first', $first); + assertEquals('second', $second); +})->depends('first', 'second'); + +test('depends run test only once', function () use (&$runCounter) { + assertEquals(2, $runCounter); +})->depends('first', 'second'); From 5be1edd7b797f9cd43eb7a4dabfcc3ec803184c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20N=C3=BCrnberger?= Date: Fri, 19 Jun 2020 20:51:27 +0200 Subject: [PATCH 3/9] added missing return types --- src/Concerns/TestCase.php | 9 +++++++++ src/Factories/TestCaseFactory.php | 3 +++ src/Support/ExceptionTrace.php | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/src/Concerns/TestCase.php b/src/Concerns/TestCase.php index 369bb5d5..fecd488e 100644 --- a/src/Concerns/TestCase.php +++ b/src/Concerns/TestCase.php @@ -129,12 +129,21 @@ trait TestCase /** * Runs the test. + * + * @return mixed + * + * @throws \Throwable */ public function __test() { return $this->__callClosure($this->__test, func_get_args()); } + /** + * @return mixed + * + * @throws \Throwable + */ private function __callClosure(Closure $closure, array $arguments) { return ExceptionTrace::ensure(function () use ($closure, $arguments) { diff --git a/src/Factories/TestCaseFactory.php b/src/Factories/TestCaseFactory.php index 88124936..f3e8e282 100644 --- a/src/Factories/TestCaseFactory.php +++ b/src/Factories/TestCaseFactory.php @@ -132,6 +132,9 @@ final class TestCaseFactory $proxies = $this->proxies; $factoryTest = $this->test; + /** + * @return mixed + */ $test = function () use ($chains, $proxies, $factoryTest) { $proxies->proxy($this); $chains->chain($this); diff --git a/src/Support/ExceptionTrace.php b/src/Support/ExceptionTrace.php index e7c31d58..72a1d829 100644 --- a/src/Support/ExceptionTrace.php +++ b/src/Support/ExceptionTrace.php @@ -17,6 +17,10 @@ final class ExceptionTrace /** * Ensures the given closure reports * the good execution context. + * + * @return mixed + * + * @throws \Throwable */ public static function ensure(Closure $closure) { From 45b0d5d899f4bf58e1dd8f5e2dedcb3bbc8327ba Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Fri, 19 Jun 2020 21:39:01 +0200 Subject: [PATCH 4/9] feat(depends): adds phpdocs --- src/PendingObjects/TestCall.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/PendingObjects/TestCall.php b/src/PendingObjects/TestCall.php index 259d8654..e0b7f1c4 100644 --- a/src/PendingObjects/TestCall.php +++ b/src/PendingObjects/TestCall.php @@ -84,6 +84,9 @@ final class TestCall return $this; } + /** + * Sets the test depends. + */ public function depends(string ...$tests): TestCall { $this->testCaseFactory @@ -104,7 +107,7 @@ final class TestCall } /** - * Sets the test groups(s). + * Sets the test group(s). */ public function group(string ...$groups): TestCall { From 6aa03565704170ed5bef314e8a1f0a635e4f2f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20N=C3=BCrnberger?= Date: Fri, 19 Jun 2020 23:22:14 +0200 Subject: [PATCH 5/9] add more tests --- tests/.snapshots/success.txt | 8 +++++--- tests/Features/Depends.php | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index 3e6832ec..3f9845ae 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -42,13 +42,15 @@ ✓ eager registered wrapped datasets did the job right ✓ lazy named datasets with (Bar Object (...)) - PASS Tests\Features\Depends + WARN Tests\Features\Depends ✓ first ✓ second ✓ depends ✓ depends with ...params ✓ depends with defined arguments ✓ depends run test only once + s incomplete → incomplete + w depends on incomplete → This test depends on "P\Tests\Features\Depends::incomplete" which does not exist. PASS Tests\Features\Exceptions ✓ it gives access the the underlying expectException @@ -152,5 +154,5 @@ WARN Tests\Visual\Success s visual snapshot of test suite on success - Tests: 6 skipped, 85 passed - Time: 2.60s + Tests: 1 warnings, 7 skipped, 85 passed + Time: 2.65s diff --git a/tests/Features/Depends.php b/tests/Features/Depends.php index 0e7ed5ea..9a46034c 100644 --- a/tests/Features/Depends.php +++ b/tests/Features/Depends.php @@ -38,3 +38,7 @@ test('depends with defined arguments', function (string $first, string $second) test('depends run test only once', function () use (&$runCounter) { assertEquals(2, $runCounter); })->depends('first', 'second'); + +test('incomplete')->skip('incomplete'); + +test('depends on incomplete')->depends('incomplete')->doesNotPerformAssertions(); From d5a4008d3e30a7c68d9650784b3647874e57bf81 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Sun, 21 Jun 2020 17:40:17 +0200 Subject: [PATCH 6/9] chore: bumps dev dependencies --- composer.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index ce14bb71..509ee8e4 100644 --- a/composer.json +++ b/composer.json @@ -43,15 +43,15 @@ ] }, "require-dev": { - "ergebnis/phpstan-rules": "^0.14.4", + "ergebnis/phpstan-rules": "^0.15.0", "friendsofphp/php-cs-fixer": "^2.16.3", - "illuminate/console": "^7.10.3", - "illuminate/support": "^7.10.3", - "mockery/mockery": "^1.3.1", - "phpstan/phpstan": "^0.12.25", + "illuminate/console": "^7.16.1", + "illuminate/support": "^7.16.1", + "mockery/mockery": "^1.4.0", + "phpstan/phpstan": "^0.12.30", "phpstan/phpstan-strict-rules": "^0.12.2", - "rector/rector": "^0.7.25", - "symfony/var-dumper": "^5.0.8", + "rector/rector": "^0.7.37", + "symfony/var-dumper": "^5.1.2", "thecodingmachine/phpstan-strict-rules": "^0.12.0" }, "minimum-stability": "dev", @@ -70,7 +70,7 @@ "test:types": "phpstan analyse --ansi", "test:unit": "php bin/pest --colors=always --exclude-group=integration", "test:integration": "php bin/pest --colors=always --group=integration", - "test:update:snapshots": "REBUILD_SNAPSHOTS=true php bin/pest --colors=always", + "update:snapshots": "REBUILD_SNAPSHOTS=true php bin/pest --colors=always", "test": [ "@test:lint", "@test:types", From 5d58d58f7168fb889fd3c7e725b80efa2c2606ef Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Sun, 21 Jun 2020 17:40:29 +0200 Subject: [PATCH 7/9] chore: updates phpstan config --- phpstan.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index 866178f7..e133d425 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -15,9 +15,9 @@ parameters: reportUnmatchedIgnoredErrors: true ignoreErrors: + - "#Undefined variable: \\$this#" - "#is not allowed to extend#" - "#Language construct eval#" - "# with null as default value#" - - "#Using \\$this in static method#" - "#has parameter \\$closure with default value.#" - "#has parameter \\$description with default value.#" From 211f5c24334327aeaace728dc58d7b49f117ec70 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Sun, 21 Jun 2020 17:40:41 +0200 Subject: [PATCH 8/9] tests: makes incomplete tests success --- tests/.snapshots/success.txt | 9 +++------ tests/Features/Depends.php | 4 ---- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index eae1f6cc..57e655aa 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -49,15 +49,13 @@ ✓ it creates unique test case names with ('Name 1', Pest\Plugin Object (), true) #3 ✓ it creates unique test case names - count - WARN Tests\Features\Depends + PASS Tests\Features\Depends ✓ first ✓ second ✓ depends ✓ depends with ...params ✓ depends with defined arguments ✓ depends run test only once - s incomplete → incomplete - w depends on incomplete → This test depends on "P\Tests\Features\Depends::incomplete" which does not exist. PASS Tests\Features\Exceptions ✓ it gives access the the underlying expectException @@ -161,6 +159,5 @@ WARN Tests\Visual\Success s visual snapshot of test suite on success - Tests: 1 warnings, 7 skipped, 85 passed - Time: 2.65s - + Tests: 6 skipped, 92 passed + Time: 3.40s diff --git a/tests/Features/Depends.php b/tests/Features/Depends.php index 9a46034c..0e7ed5ea 100644 --- a/tests/Features/Depends.php +++ b/tests/Features/Depends.php @@ -38,7 +38,3 @@ test('depends with defined arguments', function (string $first, string $second) test('depends run test only once', function () use (&$runCounter) { assertEquals(2, $runCounter); })->depends('first', 'second'); - -test('incomplete')->skip('incomplete'); - -test('depends on incomplete')->depends('incomplete')->doesNotPerformAssertions(); From 15edde8e87f6793bf6dd20d7db88b5d159f6ce95 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Sun, 21 Jun 2020 17:43:28 +0200 Subject: [PATCH 9/9] docs: updates changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d1fdfc2..9d1344c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [v0.2.2 (2020-06-21)](https://github.com/pestphp/pest/compare/v0.2.1...v0.2.2) +### Added +- `depends` phpunit feature ([#103](https://github.com/pestphp/pest/pull/103)) + +### Fixes +- datasets name conflit ([#101](https://github.com/pestphp/pest/pull/101)) + ## [v0.2.1 (2020-06-17)](https://github.com/pestphp/pest/compare/v0.2.0...v0.2.1) ### Fixes - Multiple `uses` in the same path override previous `uses` ([#97](https://github.com/pestphp/pest/pull/97))