From 3af60b874ef2c1433b282496f124a0f65f3cc135 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Tue, 28 Feb 2023 20:17:49 +0530 Subject: [PATCH 01/25] chore: upgrades deps --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 98bc3522..85a08447 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "nunomaduro/collision": "^7.0.5", "nunomaduro/termwind": "^1.15.1", "pestphp/pest-plugin": "^2.0.0", - "phpunit/phpunit": "^10.0.12" + "phpunit/phpunit": "^10.0.13" }, "conflict": { "brianium/paratest": "<7.0.6" @@ -49,7 +49,7 @@ "brianium/paratest": "^7.0.6", "pestphp/pest-dev-tools": "^2.4.0", "pestphp/pest-plugin-arch": "^2.0.0", - "symfony/process": "^6.2.5" + "symfony/process": "^6.2.7" }, "minimum-stability": "dev", "prefer-stable": true, From b15dc03d165f656963f38c7c6fa74bccc19f9a5a Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 14:09:05 +0000 Subject: [PATCH 02/25] chore: bumps dependencies --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 85a08447..11702093 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "nunomaduro/collision": "^7.0.5", "nunomaduro/termwind": "^1.15.1", "pestphp/pest-plugin": "^2.0.0", - "phpunit/phpunit": "^10.0.13" + "phpunit/phpunit": "^10.0.14" }, "conflict": { "brianium/paratest": "<7.0.6" @@ -46,7 +46,7 @@ ] }, "require-dev": { - "brianium/paratest": "^7.0.6", + "brianium/paratest": "^7.1.0", "pestphp/pest-dev-tools": "^2.4.0", "pestphp/pest-plugin-arch": "^2.0.0", "symfony/process": "^6.2.7" From e9f83dc0208c5f11c9641e9f74234d4dd3fdb55b Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 14:09:18 +0000 Subject: [PATCH 03/25] fix: discovering phpunit tests on parallel --- overrides/Runner/TestSuiteLoader.php | 21 +++++++++++++++++++++ tests/Visual/Parallel.php | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/overrides/Runner/TestSuiteLoader.php b/overrides/Runner/TestSuiteLoader.php index efc50b04..d997aeb0 100644 --- a/overrides/Runner/TestSuiteLoader.php +++ b/overrides/Runner/TestSuiteLoader.php @@ -128,6 +128,27 @@ final class TestSuiteLoader } } + if (! $testCaseFound) { + foreach (array_reverse($loadedClasses) as $loadedClass) { + $offset = 0 - strlen($suiteClassName); + + if (stripos(substr($loadedClass, $offset - 1), '\\'.$suiteClassName) === 0 || + stripos(substr($loadedClass, $offset - 1), '_'.$suiteClassName) === 0) { + try { + $class = new ReflectionClass($loadedClass); + // @codeCoverageIgnoreStart + } catch (ReflectionException) { + continue; + } + + $suiteClassName = $loadedClass; + $testCaseFound = true; + + break; + } + } + } + if (! $testCaseFound) { return $this->exceptionFor($suiteClassName, $suiteClassFile); } diff --git a/tests/Visual/Parallel.php b/tests/Visual/Parallel.php index 1fbe0ed3..be8b5c0b 100644 --- a/tests/Visual/Parallel.php +++ b/tests/Visual/Parallel.php @@ -15,6 +15,6 @@ $run = function () { }; test('parallel', function () use ($run) { - expect($run())->toContain('Tests: 4 incomplete, 4 todos, 15 skipped, 626 passed (1550 assertions)') + expect($run())->toContain('Tests: 4 incomplete, 4 todos, 15 skipped, 627 passed (1551 assertions)') ->toContain('Parallel: 3 processes'); }); From 62238b27147ed8c1485b2ac21cb8b43aa0d72003 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 16:24:16 +0000 Subject: [PATCH 04/25] fix: don't registers exception handlers --- src/Bootstrappers/BootExceptionHandler.php | 24 ---------------------- src/Kernel.php | 1 - tests/.snapshots/Failure.php.inc | 4 ++-- 3 files changed, 2 insertions(+), 27 deletions(-) delete mode 100644 src/Bootstrappers/BootExceptionHandler.php diff --git a/src/Bootstrappers/BootExceptionHandler.php b/src/Bootstrappers/BootExceptionHandler.php deleted file mode 100644 index bcebf5a6..00000000 --- a/src/Bootstrappers/BootExceptionHandler.php +++ /dev/null @@ -1,24 +0,0 @@ -register(); - } -} diff --git a/src/Kernel.php b/src/Kernel.php index debf1097..25f2aadd 100644 --- a/src/Kernel.php +++ b/src/Kernel.php @@ -27,7 +27,6 @@ final class Kernel */ private const BOOTSTRAPPERS = [ Bootstrappers\BootOverrides::class, - Bootstrappers\BootExceptionHandler::class, Bootstrappers\BootSubscribers::class, Bootstrappers\BootFiles::class, Bootstrappers\BootView::class, diff --git a/tests/.snapshots/Failure.php.inc b/tests/.snapshots/Failure.php.inc index 727211aa..cde5f942 100644 --- a/tests/.snapshots/Failure.php.inc +++ b/tests/.snapshots/Failure.php.inc @@ -1,6 +1,6 @@ ##teamcity[testSuiteStarted name='Tests/tests/Failure' locationHint='file://tests/.tests/Failure.php' flowId='1234'] ##teamcity[testStarted name='it can fail with comparison' locationHint='pest_qn://tests/.tests/Failure.php::it can fail with comparison' flowId='1234'] -##teamcity[testFailed name='it can fail with comparison' message='Failed asserting that true matches expected false.' details='at src/Mixins/Expectation.php:342|nat src/Support/ExpectationPipeline.php:75|nat src/Support/ExpectationPipeline.php:79|nat src/Expectation.php:300|nat tests/.tests/Failure.php:6|nat src/Factories/TestCaseMethodFactory.php:100|nat src/Concerns/Testable.php:262|nat src/Support/ExceptionTrace.php:28|nat src/Concerns/Testable.php:262|nat src/Concerns/Testable.php:217|nat src/Kernel.php:91' type='comparisonFailure' actual='true' expected='false' flowId='1234'] +##teamcity[testFailed name='it can fail with comparison' message='Failed asserting that true matches expected false.' details='at src/Mixins/Expectation.php:342|nat src/Support/ExpectationPipeline.php:75|nat src/Support/ExpectationPipeline.php:79|nat src/Expectation.php:300|nat tests/.tests/Failure.php:6|nat src/Factories/TestCaseMethodFactory.php:100|nat src/Concerns/Testable.php:262|nat src/Support/ExceptionTrace.php:28|nat src/Concerns/Testable.php:262|nat src/Concerns/Testable.php:217|nat src/Kernel.php:90' type='comparisonFailure' actual='true' expected='false' flowId='1234'] ##teamcity[testFinished name='it can fail with comparison' duration='100000' flowId='1234'] ##teamcity[testStarted name='it can be ignored because of no assertions' locationHint='pest_qn://tests/.tests/Failure.php::it can be ignored because of no assertions' flowId='1234'] ##teamcity[testIgnored name='it can be ignored because of no assertions' message='This test did not perform any assertions' details='' flowId='1234'] @@ -9,7 +9,7 @@ ##teamcity[testIgnored name='it can be ignored because it is skipped' message='This test was ignored.' details='' flowId='1234'] ##teamcity[testFinished name='it can be ignored because it is skipped' duration='100000' flowId='1234'] ##teamcity[testStarted name='it can fail' locationHint='pest_qn://tests/.tests/Failure.php::it can fail' flowId='1234'] -##teamcity[testFailed name='it can fail' message='oh noo' details='at tests/.tests/Failure.php:18|nat src/Factories/TestCaseMethodFactory.php:100|nat src/Concerns/Testable.php:262|nat src/Support/ExceptionTrace.php:28|nat src/Concerns/Testable.php:262|nat src/Concerns/Testable.php:217|nat src/Kernel.php:91' flowId='1234'] +##teamcity[testFailed name='it can fail' message='oh noo' details='at tests/.tests/Failure.php:18|nat src/Factories/TestCaseMethodFactory.php:100|nat src/Concerns/Testable.php:262|nat src/Support/ExceptionTrace.php:28|nat src/Concerns/Testable.php:262|nat src/Concerns/Testable.php:217|nat src/Kernel.php:90' flowId='1234'] ##teamcity[testFinished name='it can fail' duration='100000' flowId='1234'] ##teamcity[testStarted name='it is not done yet' locationHint='pest_qn://tests/.tests/Failure.php::it is not done yet' flowId='1234'] ##teamcity[testIgnored name='it is not done yet' message='This test was ignored.' details='' flowId='1234'] From e1bb1d8c2db3e5d517259e79f166df005001062d Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 17:50:36 +0000 Subject: [PATCH 05/25] fix: printer parallel not displaying progress of deprecations --- src/Plugins/Parallel/Support/CompactPrinter.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Plugins/Parallel/Support/CompactPrinter.php b/src/Plugins/Parallel/Support/CompactPrinter.php index ed25be77..16ae2388 100644 --- a/src/Plugins/Parallel/Support/CompactPrinter.php +++ b/src/Plugins/Parallel/Support/CompactPrinter.php @@ -38,6 +38,7 @@ final class CompactPrinter 'T' => ['cyan', 't'], 'I' => ['yellow', 'i'], 'N' => ['yellow', 'i'], + 'D' => ['yellow', '!'], 'R' => ['yellow', '!'], 'W' => ['yellow', '!'], 'E' => ['red', '⨯'], From 69a0c3ba99c3edabbdfd4409f7cfd7dd2e22b476 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 17:50:47 +0000 Subject: [PATCH 06/25] chore: dont fails on warnings --- phpunit.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml b/phpunit.xml index 13e5b2af..c7653639 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,7 +7,7 @@ bootstrap="vendor/autoload.php" colors="true" failOnRisky="true" - failOnWarning="true" + failOnWarning="false" processIsolation="false" stopOnError="false" stopOnFailure="false" From f25a9f5558c117863b06a4007bcb0ce12e08ea11 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 17:50:57 +0000 Subject: [PATCH 07/25] feat: warnings support --- src/Support/HigherOrderTapProxy.php | 23 ++++++++++------------- tests/Features/Warnings.php | 13 +++++++++++++ 2 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 tests/Features/Warnings.php diff --git a/src/Support/HigherOrderTapProxy.php b/src/Support/HigherOrderTapProxy.php index 1b5f12cf..8df75e3a 100644 --- a/src/Support/HigherOrderTapProxy.php +++ b/src/Support/HigherOrderTapProxy.php @@ -39,20 +39,17 @@ final class HigherOrderTapProxy */ public function __get(string $property) { - try { - return $this->target->{$property}; // @phpstan-ignore-line - } catch (Throwable $throwable) { // @phpstan-ignore-line - Reflection::setPropertyValue($throwable, 'file', Backtrace::file()); - Reflection::setPropertyValue($throwable, 'line', Backtrace::line()); - - if (Str::startsWith($message = $throwable->getMessage(), self::UNDEFINED_PROPERTY)) { - /** @var ReflectionClass $reflection */ - $reflection = (new ReflectionClass($this->target))->getParentClass(); - Reflection::setPropertyValue($throwable, 'message', sprintf('Undefined property %s::$%s', $reflection->getName(), $property)); - } - - throw $throwable; + if (property_exists($this->target, $property)) { + return $this->target->{$property}; } + + $className = (new ReflectionClass($this->target))->getName(); + + if (str_starts_with($className, "P\\")) { + $className = substr($className, 2); + } + + trigger_error(sprintf('Undefined property %s::$%s', $className, $property), E_USER_WARNING); } /** diff --git a/tests/Features/Warnings.php b/tests/Features/Warnings.php new file mode 100644 index 00000000..e638b3f0 --- /dev/null +++ b/tests/Features/Warnings.php @@ -0,0 +1,13 @@ +fooqwdfwqdfqw; + + expect(true)->toBeTrue(); +}); + +test('user warning', function () { + trigger_error('This is a warning description', E_USER_WARNING); + + expect(true)->toBeTrue(); +}); From a75e899d98367e4a5e6377cdba6ccd49aae9472b Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 17:51:10 +0000 Subject: [PATCH 08/25] chore: unsets collision on testing --- tests/Autoload.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/Autoload.php b/tests/Autoload.php index 1d53a325..2d3ce530 100644 --- a/tests/Autoload.php +++ b/tests/Autoload.php @@ -1,9 +1,5 @@ register(); -} - trait PluginTrait { public function assertPluginTraitGotRegistered(): void From 3df68b288ad98e7c12129c4b455b8ff517d2d2b4 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 17:51:21 +0000 Subject: [PATCH 09/25] tests: deprecations --- tests/Features/Deprecated.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/Features/Deprecated.php diff --git a/tests/Features/Deprecated.php b/tests/Features/Deprecated.php new file mode 100644 index 00000000..abf9430d --- /dev/null +++ b/tests/Features/Deprecated.php @@ -0,0 +1,13 @@ +toBeTrue(); +}); + +test('user deprecated', function () { + trigger_deprecation('foo', '1.0', 'This is a deprecation description'); + + expect(true)->toBeTrue(); +}); From 3f6b2e856ea27db50dc3876c4e84b39e88da3c39 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 17:51:34 +0000 Subject: [PATCH 10/25] tests: helpers fix --- tests/Features/Helpers.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Features/Helpers.php b/tests/Features/Helpers.php index ee34702e..90663554 100644 --- a/tests/Features/Helpers.php +++ b/tests/Features/Helpers.php @@ -10,9 +10,9 @@ it('can set/get properties on $this', function () { expect($this->user)->toBe('nuno'); }); -it('throws error if property do not exist', function () { - test()->user; -})->throws(\Whoops\Exception\ErrorException::class, 'Undefined property PHPUnit\Framework\TestCase::$user'); +it('gets null if property do not exist', function () { + expect(test()->wqdwqdqw)->toBe(null); +}); class User { From 1e61034e865c005f5f9d420ad147e762ebc8c532 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 20:37:18 +0000 Subject: [PATCH 11/25] feat: support for deprecated, notices, and warnings --- .../ProgressPrinter/TestSkippedSubscriber.php | 8 ++- phpunit.xml | 6 -- .../Parallel/Paratest/ResultPrinter.php | 27 ++++++- .../Parallel/Support/CompactPrinter.php | 8 ++- src/Support/HigherOrderTapProxy.php | 9 ++- src/Support/StateGenerator.php | 70 ++++++++++++++++--- tests/.snapshots/Failure.php.inc | 4 -- tests/.snapshots/SuccessOnly.php.inc | 4 -- tests/.snapshots/success.txt | 17 ++++- tests/Features/Notices.php | 7 ++ tests/Visual/Parallel.php | 2 +- 11 files changed, 124 insertions(+), 38 deletions(-) create mode 100644 tests/Features/Notices.php diff --git a/overrides/TextUI/Output/Default/ProgressPrinter/TestSkippedSubscriber.php b/overrides/TextUI/Output/Default/ProgressPrinter/TestSkippedSubscriber.php index 4e0521a3..80de0225 100644 --- a/overrides/TextUI/Output/Default/ProgressPrinter/TestSkippedSubscriber.php +++ b/overrides/TextUI/Output/Default/ProgressPrinter/TestSkippedSubscriber.php @@ -61,9 +61,11 @@ final class TestSkippedSubscriber extends Subscriber implements SkippedSubscribe */ public function notify(Skipped $event): void { - str_contains($event->message(), '__TODO__') - ? $this->printTodoItem() - : $this->printer()->testSkipped(); + if (str_contains($event->message(), '__TODO__')) { + $this->printTodoItem(); + } + + $this->printer()->testSkipped(); } /** diff --git a/phpunit.xml b/phpunit.xml index c7653639..c4d4343e 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -12,12 +12,6 @@ stopOnError="false" stopOnFailure="false" backupStaticProperties="false" - displayDetailsOnIncompleteTests="true" - displayDetailsOnSkippedTests="true" - displayDetailsOnTestsThatTriggerDeprecations="true" - displayDetailsOnTestsThatTriggerErrors="true" - displayDetailsOnTestsThatTriggerNotices="true" - displayDetailsOnTestsThatTriggerWarnings="true" > diff --git a/src/Plugins/Parallel/Paratest/ResultPrinter.php b/src/Plugins/Parallel/Paratest/ResultPrinter.php index 71134d1f..a0e0033e 100644 --- a/src/Plugins/Parallel/Paratest/ResultPrinter.php +++ b/src/Plugins/Parallel/Paratest/ResultPrinter.php @@ -12,6 +12,7 @@ use function fread; use function fseek; use function ftell; use function fwrite; +use NunoMaduro\Collision\Adapters\Phpunit\State; use ParaTest\Options; use Pest\Plugins\Parallel\Support\CompactPrinter; use Pest\Support\StateGenerator; @@ -27,11 +28,21 @@ use Symfony\Component\Console\Output\OutputInterface; /** @internal */ final class ResultPrinter { + /** + * If the test should be marked as todo. + */ + public bool $lastWasTodo = false; + /** * The "native" printer. */ public readonly Printer $printer; + /** + * The state. + */ + public int $passedTests = 0; + /** * The "compact" printer. */ @@ -140,7 +151,7 @@ final class ResultPrinter return; } - $state = (new StateGenerator())->fromPhpUnitTestResult($testResult); + $state = (new StateGenerator())->fromPhpUnitTestResult($this->passedTests, $testResult); $this->compactPrinter->errors($state); $this->compactPrinter->recap($state, $testResult, $duration, $this->options); @@ -148,6 +159,20 @@ final class ResultPrinter private function printFeedbackItem(string $item): void { + if ($this->lastWasTodo) { + $this->lastWasTodo = false; + + return; + } + + if ($item === 'T') { + $this->lastWasTodo = true; + } + + if ($item === '.') { + $this->passedTests++; + } + $this->compactPrinter->descriptionItem($item); } diff --git a/src/Plugins/Parallel/Support/CompactPrinter.php b/src/Plugins/Parallel/Support/CompactPrinter.php index 16ae2388..95aec81d 100644 --- a/src/Plugins/Parallel/Support/CompactPrinter.php +++ b/src/Plugins/Parallel/Support/CompactPrinter.php @@ -36,8 +36,8 @@ final class CompactPrinter '.' => ['gray', '.'], 'S' => ['yellow', 's'], 'T' => ['cyan', 't'], - 'I' => ['yellow', 'i'], - 'N' => ['yellow', 'i'], + 'I' => ['yellow', '!'], + 'N' => ['yellow', '!'], 'D' => ['yellow', '!'], 'R' => ['yellow', '!'], 'W' => ['yellow', '!'], @@ -106,7 +106,9 @@ final class CompactPrinter */ public function errors(State $state): void { - $this->style->writeErrorsSummary($state, false); + $this->output->writeln(''); + + $this->style->writeErrorsSummary($state); } /** diff --git a/src/Support/HigherOrderTapProxy.php b/src/Support/HigherOrderTapProxy.php index 8df75e3a..151b2b80 100644 --- a/src/Support/HigherOrderTapProxy.php +++ b/src/Support/HigherOrderTapProxy.php @@ -6,15 +6,12 @@ namespace Pest\Support; use PHPUnit\Framework\TestCase; use ReflectionClass; -use Throwable; /** * @internal */ final class HigherOrderTapProxy { - private const UNDEFINED_PROPERTY = 'Undefined property: P\\'; // @phpstan-ignore-line - /** * Create a new tap proxy instance. */ @@ -40,16 +37,18 @@ final class HigherOrderTapProxy public function __get(string $property) { if (property_exists($this->target, $property)) { - return $this->target->{$property}; + return $this->target->{$property}; // @phpstan-ignore-line } $className = (new ReflectionClass($this->target))->getName(); - if (str_starts_with($className, "P\\")) { + if (str_starts_with($className, 'P\\')) { $className = substr($className, 2); } trigger_error(sprintf('Undefined property %s::$%s', $className, $property), E_USER_WARNING); + + return null; } /** diff --git a/src/Support/StateGenerator.php b/src/Support/StateGenerator.php index 7d06b7b4..84065703 100644 --- a/src/Support/StateGenerator.php +++ b/src/Support/StateGenerator.php @@ -11,6 +11,7 @@ use PHPUnit\Event\Code\TestMethod; use PHPUnit\Event\Code\Throwable; use PHPUnit\Event\Test\Errored; use PHPUnit\Event\TestData\TestDataCollection; +use PHPUnit\Framework\Exception; use PHPUnit\Framework\IncompleteTestError; use PHPUnit\Framework\SkippedWithMessageException; use PHPUnit\Metadata\MetadataCollection; @@ -18,7 +19,7 @@ use PHPUnit\TestRunner\TestResult\TestResult as PHPUnitTestResult; final class StateGenerator { - public function fromPhpUnitTestResult(PHPUnitTestResult $testResult): State + public function fromPhpUnitTestResult(int $passedTests, PHPUnitTestResult $testResult): State { $state = new State(); @@ -74,16 +75,69 @@ final class StateGenerator )); } - $numberOfPassedTests = $testResult->numberOfTestsRun() - - $testResult->numberOfTestErroredEvents() - - $testResult->numberOfTestFailedEvents() - - $testResult->numberOfTestSkippedEvents() - - $testResult->numberOfTestsWithTestConsideredRiskyEvents() - - $testResult->numberOfTestMarkedIncompleteEvents(); + foreach ($testResult->testTriggeredDeprecationEvents() as $testResultEvent) { + $testResultEvent = $testResultEvent[0]; - for ($i = 0; $i < $numberOfPassedTests; $i++) { $state->add(TestResult::fromTestCase( + $testResultEvent->test(), + TestResult::DEPRECATED, + Throwable::from(new Exception($testResultEvent->message())) + )); + } + foreach ($testResult->testTriggeredPhpDeprecationEvents() as $testResultEvent) { + $testResultEvent = $testResultEvent[0]; + + $state->add(TestResult::fromTestCase( + $testResultEvent->test(), + TestResult::DEPRECATED, + Throwable::from(new Exception($testResultEvent->message())) + )); + } + + foreach ($testResult->testTriggeredNoticeEvents() as $testResultEvent) { + $testResultEvent = $testResultEvent[0]; + + $state->add(TestResult::fromTestCase( + $testResultEvent->test(), + TestResult::NOTICE, + Throwable::from(new Exception($testResultEvent->message())) + )); + } + + foreach ($testResult->testTriggeredPhpNoticeEvents() as $testResultEvent) { + $testResultEvent = $testResultEvent[0]; + + $state->add(TestResult::fromTestCase( + $testResultEvent->test(), + TestResult::NOTICE, + Throwable::from(new Exception($testResultEvent->message())) + )); + } + + foreach ($testResult->testTriggeredWarningEvents() as $testResultEvent) { + $testResultEvent = $testResultEvent[0]; + + $state->add(TestResult::fromTestCase( + $testResultEvent->test(), + TestResult::WARN, + Throwable::from(new Exception($testResultEvent->message())) + )); + } + + foreach ($testResult->testTriggeredPhpWarningEvents() as $testResultEvent) { + $testResultEvent = $testResultEvent[0]; + + $state->add(TestResult::fromTestCase( + $testResultEvent->test(), + TestResult::WARN, + Throwable::from(new Exception($testResultEvent->message())) + )); + } + + // for each test that passed, we need to add it to the state + for ($i = 0; $i < $passedTests; $i++) { + $state->add(TestResult::fromTestCase( new TestMethod( /** @phpstan-ignore-next-line */ "$i", diff --git a/tests/.snapshots/Failure.php.inc b/tests/.snapshots/Failure.php.inc index cde5f942..cc3837bd 100644 --- a/tests/.snapshots/Failure.php.inc +++ b/tests/.snapshots/Failure.php.inc @@ -18,7 +18,3 @@ ##teamcity[testIgnored name='build this one.' message='This test was ignored.' details='' flowId='1234'] ##teamcity[testFinished name='build this one.' duration='100000' flowId='1234'] ##teamcity[testSuiteFinished name='Tests/tests/Failure' flowId='1234'] - - Tests: 2 failed, 1 risky, 2 todos, 1 skipped (2 assertions) - Duration: 1.00s - diff --git a/tests/.snapshots/SuccessOnly.php.inc b/tests/.snapshots/SuccessOnly.php.inc index 21e8a362..5629be43 100644 --- a/tests/.snapshots/SuccessOnly.php.inc +++ b/tests/.snapshots/SuccessOnly.php.inc @@ -4,7 +4,3 @@ ##teamcity[testStarted name='can also pass' locationHint='pest_qn://tests/.tests/SuccessOnly.php::can also pass' flowId='1234'] ##teamcity[testFinished name='can also pass' duration='100000' flowId='1234'] ##teamcity[testSuiteFinished name='Tests/tests/SuccessOnly' flowId='1234'] - - Tests: 2 passed (2 assertions) - Duration: 1.00s - diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index 81ae5e23..d28df786 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -139,6 +139,10 @@ ✓ it is a test ✓ it uses correct parent class + DEPR Tests\Features\Deprecated + ! deprecated → str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated + ! user deprecated → Since foo 1.0: This is a deprecation description + PASS Tests\Features\Exceptions ✓ it gives access the the underlying expectException ✓ it catch exceptions @@ -646,9 +650,9 @@ ✓ it skips with falsy closure condition ✓ it can be used in higher order tests - PASS Tests\Features\Helpers + WARN Tests\Features\Helpers ✓ it can set/get properties on $this - ✓ it throws error if property do not exist + ! it gets null if property do not exist → Undefined property Tests\Features\Helpers::$wqdwqdqw ✓ it allows to call underlying protected/private methods ✓ it throws error if method do not exist ✓ it can forward unexpected calls to any global function @@ -678,6 +682,9 @@ ✓ it is a test ✓ it is a higher order message test + NOTI Tests\Features\Notices + ! notice → This is a notice description + PASS Tests\Features\PendingHigherOrderTests ✓ get 'foo' ✓ get 'foo' → get 'bar' → expect true → toBeTrue @@ -750,6 +757,10 @@ ↓ something todo later chained and with function body ✓ it does something within a file with a todo + WARN Tests\Features\Warnings + ! warning → Undefined property: P\Tests\Features\Warnings::$fooqwdfwqdfqw + ! user warning → This is a warning description + PASS Tests\Fixtures\DirectoryWithTests\ExampleTest ✓ it example 1 @@ -917,4 +928,4 @@ PASS Tests\Visual\Version ✓ visual snapshot of help command output - Tests: 4 incomplete, 4 todos, 18 skipped, 634 passed (1560 assertions) \ No newline at end of file + Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 18 skipped, 633 passed (1564 assertions) \ No newline at end of file diff --git a/tests/Features/Notices.php b/tests/Features/Notices.php new file mode 100644 index 00000000..dd245450 --- /dev/null +++ b/tests/Features/Notices.php @@ -0,0 +1,7 @@ +toBeTrue(); +}); diff --git a/tests/Visual/Parallel.php b/tests/Visual/Parallel.php index be8b5c0b..66726d7b 100644 --- a/tests/Visual/Parallel.php +++ b/tests/Visual/Parallel.php @@ -15,6 +15,6 @@ $run = function () { }; test('parallel', function () use ($run) { - expect($run())->toContain('Tests: 4 incomplete, 4 todos, 15 skipped, 627 passed (1551 assertions)') + expect($run())->toContain('Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 15 skipped, 626 passed (1555 assertions)') ->toContain('Parallel: 3 processes'); }); From ad97b202c4f8e7784ff882f3968ec3b21e8d11fd Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 21:24:05 +0000 Subject: [PATCH 12/25] fix: converter --- src/Logging/TeamCity/Converter.php | 9 ++++++++- src/Logging/TeamCity/TeamCityLogger.php | 1 - tests/.snapshots/Failure.php.inc | 4 ++++ tests/.snapshots/SuccessOnly.php.inc | 4 ++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Logging/TeamCity/Converter.php b/src/Logging/TeamCity/Converter.php index 1f0de446..120e2f82 100644 --- a/src/Logging/TeamCity/Converter.php +++ b/src/Logging/TeamCity/Converter.php @@ -180,6 +180,13 @@ final class Converter */ public function getStateFromResult(PhpUnitTestResult $result): State { - return $this->stateGenerator->fromPhpUnitTestResult($result); + $numberOfPassedTests = $result->numberOfTestsRun() + - $result->numberOfTestErroredEvents() + - $result->numberOfTestFailedEvents() + - $result->numberOfTestSkippedEvents() + - $result->numberOfTestsWithTestConsideredRiskyEvents() + - $result->numberOfTestMarkedIncompleteEvents(); + + return $this->stateGenerator->fromPhpUnitTestResult($numberOfPassedTests, $result); } } diff --git a/src/Logging/TeamCity/TeamCityLogger.php b/src/Logging/TeamCity/TeamCityLogger.php index 9e5d6312..85994a84 100644 --- a/src/Logging/TeamCity/TeamCityLogger.php +++ b/src/Logging/TeamCity/TeamCityLogger.php @@ -91,7 +91,6 @@ final class TeamCityLogger public function testMarkedIncomplete(MarkedIncomplete $event): never { - // TODO: when does this trigger? throw ShouldNotHappen::fromMessage('testMarkedIncomplete not implemented.'); } diff --git a/tests/.snapshots/Failure.php.inc b/tests/.snapshots/Failure.php.inc index cc3837bd..cde5f942 100644 --- a/tests/.snapshots/Failure.php.inc +++ b/tests/.snapshots/Failure.php.inc @@ -18,3 +18,7 @@ ##teamcity[testIgnored name='build this one.' message='This test was ignored.' details='' flowId='1234'] ##teamcity[testFinished name='build this one.' duration='100000' flowId='1234'] ##teamcity[testSuiteFinished name='Tests/tests/Failure' flowId='1234'] + + Tests: 2 failed, 1 risky, 2 todos, 1 skipped (2 assertions) + Duration: 1.00s + diff --git a/tests/.snapshots/SuccessOnly.php.inc b/tests/.snapshots/SuccessOnly.php.inc index 5629be43..21e8a362 100644 --- a/tests/.snapshots/SuccessOnly.php.inc +++ b/tests/.snapshots/SuccessOnly.php.inc @@ -4,3 +4,7 @@ ##teamcity[testStarted name='can also pass' locationHint='pest_qn://tests/.tests/SuccessOnly.php::can also pass' flowId='1234'] ##teamcity[testFinished name='can also pass' duration='100000' flowId='1234'] ##teamcity[testSuiteFinished name='Tests/tests/SuccessOnly' flowId='1234'] + + Tests: 2 passed (2 assertions) + Duration: 1.00s + From 813f63360b42a3a69ff7bccc6a8e30128979118a Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 21:57:46 +0000 Subject: [PATCH 13/25] feat: extends test outcome to state generator --- src/Support/StateGenerator.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Support/StateGenerator.php b/src/Support/StateGenerator.php index 84065703..23bf025a 100644 --- a/src/Support/StateGenerator.php +++ b/src/Support/StateGenerator.php @@ -6,13 +6,12 @@ namespace Pest\Support; use NunoMaduro\Collision\Adapters\Phpunit\State; use NunoMaduro\Collision\Adapters\Phpunit\TestResult; +use NunoMaduro\Collision\Exceptions\TestOutcome; use PHPUnit\Event\Code\TestDox; use PHPUnit\Event\Code\TestMethod; use PHPUnit\Event\Code\Throwable; use PHPUnit\Event\Test\Errored; use PHPUnit\Event\TestData\TestDataCollection; -use PHPUnit\Framework\Exception; -use PHPUnit\Framework\IncompleteTestError; use PHPUnit\Framework\SkippedWithMessageException; use PHPUnit\Metadata\MetadataCollection; use PHPUnit\TestRunner\TestResult\TestResult as PHPUnitTestResult; @@ -56,7 +55,7 @@ final class StateGenerator $state->add(TestResult::fromTestCase( $riskyEvent->test(), TestResult::RISKY, - Throwable::from(new IncompleteTestError($riskyEvent->message())) + Throwable::from(new TestOutcome($riskyEvent->message())) )); } } @@ -81,7 +80,7 @@ final class StateGenerator $state->add(TestResult::fromTestCase( $testResultEvent->test(), TestResult::DEPRECATED, - Throwable::from(new Exception($testResultEvent->message())) + Throwable::from(new TestOutcome($testResultEvent->message())) )); } @@ -91,7 +90,7 @@ final class StateGenerator $state->add(TestResult::fromTestCase( $testResultEvent->test(), TestResult::DEPRECATED, - Throwable::from(new Exception($testResultEvent->message())) + Throwable::from(new TestOutcome($testResultEvent->message())) )); } @@ -101,7 +100,7 @@ final class StateGenerator $state->add(TestResult::fromTestCase( $testResultEvent->test(), TestResult::NOTICE, - Throwable::from(new Exception($testResultEvent->message())) + Throwable::from(new TestOutcome($testResultEvent->message())) )); } @@ -111,7 +110,7 @@ final class StateGenerator $state->add(TestResult::fromTestCase( $testResultEvent->test(), TestResult::NOTICE, - Throwable::from(new Exception($testResultEvent->message())) + Throwable::from(new TestOutcome($testResultEvent->message())) )); } @@ -121,7 +120,7 @@ final class StateGenerator $state->add(TestResult::fromTestCase( $testResultEvent->test(), TestResult::WARN, - Throwable::from(new Exception($testResultEvent->message())) + Throwable::from(new TestOutcome($testResultEvent->message())) )); } @@ -131,7 +130,7 @@ final class StateGenerator $state->add(TestResult::fromTestCase( $testResultEvent->test(), TestResult::WARN, - Throwable::from(new Exception($testResultEvent->message())) + Throwable::from(new TestOutcome($testResultEvent->message())) )); } From 37d71adb4e55e07c88a57713ad3aeb937c7f837c Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 22:18:03 +0000 Subject: [PATCH 14/25] fix: cache directory --- src/Plugins/Cache.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Plugins/Cache.php b/src/Plugins/Cache.php index f1929b9d..b9413c63 100644 --- a/src/Plugins/Cache.php +++ b/src/Plugins/Cache.php @@ -30,12 +30,12 @@ final class Cache implements HandlesArguments */ public function handleArguments(array $arguments): array { - if (! $this->hasArgument('--parallel', $arguments)) { - $arguments = $this->pushArgument( - sprintf('--cache-directory=%s', realpath(self::TEMPORARY_FOLDER)), - $arguments - ); + $arguments = $this->pushArgument( + sprintf('--cache-directory=%s', realpath(self::TEMPORARY_FOLDER)), + $arguments + ); + if (! $this->hasArgument('--parallel', $arguments)) { $arguments = $this->pushArgument('--cache-result', $arguments); } From b939d94cda32b42a7b2125784adc824fcf874d0d Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 22:56:09 +0000 Subject: [PATCH 15/25] fix: non needded output --- .../Command/WarmCodeCoverageCacheCommand.php | 103 ++++++++++++++++++ src/Bootstrappers/BootOverrides.php | 1 + 2 files changed, 104 insertions(+) create mode 100644 overrides/TextUI/Command/WarmCodeCoverageCacheCommand.php diff --git a/overrides/TextUI/Command/WarmCodeCoverageCacheCommand.php b/overrides/TextUI/Command/WarmCodeCoverageCacheCommand.php new file mode 100644 index 00000000..42348229 --- /dev/null +++ b/overrides/TextUI/Command/WarmCodeCoverageCacheCommand.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\Command; + +use function printf; +use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry; +use PHPUnit\TextUI\Configuration\Configuration; +use PHPUnit\TextUI\Configuration\NoCoverageCacheDirectoryException; +use SebastianBergmann\CodeCoverage\StaticAnalysis\CacheWarmer; +use SebastianBergmann\Timer\NoActiveTimerException; +use SebastianBergmann\Timer\Timer; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class WarmCodeCoverageCacheCommand implements Command +{ + private readonly Configuration $configuration; + private readonly CodeCoverageFilterRegistry $codeCoverageFilterRegistry; + + public function __construct(Configuration $configuration, CodeCoverageFilterRegistry $codeCoverageFilterRegistry) + { + $this->configuration = $configuration; + $this->codeCoverageFilterRegistry = $codeCoverageFilterRegistry; + } + + /** + * @throws NoActiveTimerException + * @throws NoCoverageCacheDirectoryException + */ + public function execute(): Result + { + if (!$this->configuration->hasCoverageCacheDirectory()) { + return Result::from( + 'Cache for static analysis has not been configured' . PHP_EOL, + Result::FAILURE + ); + } + + $this->codeCoverageFilterRegistry->init($this->configuration); + + if (!$this->codeCoverageFilterRegistry->configured()) { + return Result::from( + 'Filter for code coverage has not been configured' . PHP_EOL, + Result::FAILURE + ); + } + + $timer = new Timer; + $timer->start(); + + (new CacheWarmer)->warmCache( + $this->configuration->coverageCacheDirectory(), + !$this->configuration->disableCodeCoverageIgnore(), + $this->configuration->ignoreDeprecatedCodeUnitsFromCodeCoverage(), + $this->codeCoverageFilterRegistry->get() + ); + + return Result::from(); + } +} diff --git a/src/Bootstrappers/BootOverrides.php b/src/Bootstrappers/BootOverrides.php index 7b3d2307..d25f935d 100644 --- a/src/Bootstrappers/BootOverrides.php +++ b/src/Bootstrappers/BootOverrides.php @@ -21,6 +21,7 @@ final class BootOverrides implements Bootstrapper 'Runner/Filter/NameFilterIterator.php', 'Runner/ResultCache/DefaultResultCache.php', 'Runner/TestSuiteLoader.php', + 'TextUI/Command/WarmCodeCoverageCacheCommand.php', 'TextUI/Output/Default/ProgressPrinter/TestSkippedSubscriber.php', ]; From f68e6cefd4abc974ea78b8b59c12775de9e23a35 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 22:58:11 +0000 Subject: [PATCH 16/25] chore: type checking --- .../Command/WarmCodeCoverageCacheCommand.php | 15 ++++++++------- src/Plugins/Cache.php | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/overrides/TextUI/Command/WarmCodeCoverageCacheCommand.php b/overrides/TextUI/Command/WarmCodeCoverageCacheCommand.php index 42348229..7137b5b8 100644 --- a/overrides/TextUI/Command/WarmCodeCoverageCacheCommand.php +++ b/overrides/TextUI/Command/WarmCodeCoverageCacheCommand.php @@ -42,9 +42,9 @@ declare(strict_types=1); * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ + namespace PHPUnit\TextUI\Command; -use function printf; use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry; use PHPUnit\TextUI\Configuration\Configuration; use PHPUnit\TextUI\Configuration\NoCoverageCacheDirectoryException; @@ -58,11 +58,12 @@ use SebastianBergmann\Timer\Timer; final class WarmCodeCoverageCacheCommand implements Command { private readonly Configuration $configuration; + private readonly CodeCoverageFilterRegistry $codeCoverageFilterRegistry; public function __construct(Configuration $configuration, CodeCoverageFilterRegistry $codeCoverageFilterRegistry) { - $this->configuration = $configuration; + $this->configuration = $configuration; $this->codeCoverageFilterRegistry = $codeCoverageFilterRegistry; } @@ -72,18 +73,18 @@ final class WarmCodeCoverageCacheCommand implements Command */ public function execute(): Result { - if (!$this->configuration->hasCoverageCacheDirectory()) { + if (! $this->configuration->hasCoverageCacheDirectory()) { return Result::from( - 'Cache for static analysis has not been configured' . PHP_EOL, + 'Cache for static analysis has not been configured'.PHP_EOL, Result::FAILURE ); } $this->codeCoverageFilterRegistry->init($this->configuration); - if (!$this->codeCoverageFilterRegistry->configured()) { + if (! $this->codeCoverageFilterRegistry->configured()) { return Result::from( - 'Filter for code coverage has not been configured' . PHP_EOL, + 'Filter for code coverage has not been configured'.PHP_EOL, Result::FAILURE ); } @@ -93,7 +94,7 @@ final class WarmCodeCoverageCacheCommand implements Command (new CacheWarmer)->warmCache( $this->configuration->coverageCacheDirectory(), - !$this->configuration->disableCodeCoverageIgnore(), + ! $this->configuration->disableCodeCoverageIgnore(), $this->configuration->ignoreDeprecatedCodeUnitsFromCodeCoverage(), $this->codeCoverageFilterRegistry->get() ); diff --git a/src/Plugins/Cache.php b/src/Plugins/Cache.php index b9413c63..f731e883 100644 --- a/src/Plugins/Cache.php +++ b/src/Plugins/Cache.php @@ -36,7 +36,7 @@ final class Cache implements HandlesArguments ); if (! $this->hasArgument('--parallel', $arguments)) { - $arguments = $this->pushArgument('--cache-result', $arguments); + return $this->pushArgument('--cache-result', $arguments); } return $arguments; From 60f82a21db37579b4afaec93a98703eaaee0f94f Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 2 Mar 2023 23:04:21 +0000 Subject: [PATCH 17/25] fix: buffer in paralllel combined with coverage --- src/Plugins/Parallel/Paratest/ResultPrinter.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Plugins/Parallel/Paratest/ResultPrinter.php b/src/Plugins/Parallel/Paratest/ResultPrinter.php index a0e0033e..eb23ccfe 100644 --- a/src/Plugins/Parallel/Paratest/ResultPrinter.php +++ b/src/Plugins/Parallel/Paratest/ResultPrinter.php @@ -67,7 +67,12 @@ final class ResultPrinter public function print(string $buffer): void { - $this->output->write(OutputFormatter::escape($buffer)); + $buffer = OutputFormatter::escape($buffer); + + if (! str_starts_with($buffer, "\nGenerating code coverage report") + && ! str_starts_with($buffer, 'done [')) { + $this->output->write(OutputFormatter::escape($buffer)); + } } public function flush(): void From 99436f94f946bd8cd40c47ec92ff46f145225a1c Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Fri, 3 Mar 2023 00:54:32 +0000 Subject: [PATCH 18/25] chore: uses unstable version of collision --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 11702093..ed4e7ae2 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ ], "require": { "php": "^8.1.0", - "nunomaduro/collision": "^7.0.5", + "nunomaduro/collision": "v7.x-dev", "nunomaduro/termwind": "^1.15.1", "pestphp/pest-plugin": "^2.0.0", "phpunit/phpunit": "^10.0.14" From 2876ac590d46079f94b2697e87bbfc11dd0d0f5a Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Fri, 3 Mar 2023 01:09:35 +0000 Subject: [PATCH 19/25] fix: todo in parallel --- bin/pest | 8 ++++---- src/Plugins/Parallel/Paratest/ResultPrinter.php | 10 ++++++---- tests/.snapshots/success.txt | 3 ++- tests/Visual/Todo.php | 14 ++++++++++---- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/bin/pest b/bin/pest index e99c09bb..9f51fa08 100755 --- a/bin/pest +++ b/bin/pest @@ -22,12 +22,12 @@ use Symfony\Component\Console\Output\OutputInterface; $todo = false; foreach ($args as $key => $value) { - if (str_contains($value, '--compact')) { + if ($value === '--compact') { $_SERVER['COLLISION_PRINTER_COMPACT'] = 'true'; unset($args[$key]); } - if (str_contains($value, '--profile')) { + if ($value === '--profile') { $_SERVER['COLLISION_PRINTER_PROFILE'] = 'true'; unset($args[$key]); } @@ -36,12 +36,12 @@ use Symfony\Component\Console\Output\OutputInterface; unset($args[$key]); } - if (str_contains($value, '--dirty')) { + if ($value === '--dirty') { $dirty = true; unset($args[$key]); } - if (str_contains($value, '--todo')) { + if ($value === '--todo') { $todo = true; unset($args[$key]); } diff --git a/src/Plugins/Parallel/Paratest/ResultPrinter.php b/src/Plugins/Parallel/Paratest/ResultPrinter.php index eb23ccfe..62297e1c 100644 --- a/src/Plugins/Parallel/Paratest/ResultPrinter.php +++ b/src/Plugins/Parallel/Paratest/ResultPrinter.php @@ -68,11 +68,13 @@ final class ResultPrinter public function print(string $buffer): void { $buffer = OutputFormatter::escape($buffer); - - if (! str_starts_with($buffer, "\nGenerating code coverage report") - && ! str_starts_with($buffer, 'done [')) { - $this->output->write(OutputFormatter::escape($buffer)); + if (str_starts_with($buffer, "\nGenerating code coverage report")) { + return; } + if (str_starts_with($buffer, 'done [')) { + return; + } + $this->output->write(OutputFormatter::escape($buffer)); } public function flush(): void diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index d28df786..1812c562 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -924,8 +924,9 @@ PASS Tests\Visual\Todo ✓ todo + ✓ todo in parallel PASS Tests\Visual\Version ✓ visual snapshot of help command output - Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 18 skipped, 633 passed (1564 assertions) \ No newline at end of file + Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 18 skipped, 634 passed (1567 assertions) \ No newline at end of file diff --git a/tests/Visual/Todo.php b/tests/Visual/Todo.php index ac4f3ba5..3a396a21 100644 --- a/tests/Visual/Todo.php +++ b/tests/Visual/Todo.php @@ -2,14 +2,16 @@ use Symfony\Component\Process\Process; -$run = function (string $target, $decorated = false) { - $process = new Process(['php', 'bin/pest', $target, '--colors=always'], dirname(__DIR__, 2), +$run = function (string $target, bool $parallel) { + $process = new Process(['php', 'bin/pest', $target, $parallel ? '--parallel' : '', '--colors=always'], dirname(__DIR__, 2), ['COLLISION_PRINTER' => 'DefaultPrinter', 'COLLISION_IGNORE_DURATION' => 'true'], ); $process->run(); - return $decorated ? $process->getOutput() : preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput()); + expect($process->getExitCode())->toBe(0); + + return preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput()); }; $snapshot = function ($name) { @@ -23,5 +25,9 @@ $snapshot = function ($name) { }; test('todo', function () use ($run, $snapshot) { - expect($run('--todo'))->toContain($snapshot('todo')); + expect($run('--todo', false))->toContain($snapshot('todo')); +})->skip(PHP_OS_FAMILY === 'Windows'); + +test('todo in parallel', function () use ($run, $snapshot) { + expect($run('--todo', true))->toContain($snapshot('todo')); })->skip(PHP_OS_FAMILY === 'Windows'); From eadc6f43074be7d42c50fe9989e7f2869914df2f Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Fri, 3 Mar 2023 09:50:41 +0000 Subject: [PATCH 20/25] chore: fix tests --- tests/Features/Deprecated.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Features/Deprecated.php b/tests/Features/Deprecated.php index abf9430d..bd25c1e1 100644 --- a/tests/Features/Deprecated.php +++ b/tests/Features/Deprecated.php @@ -1,5 +1,7 @@ Date: Fri, 3 Mar 2023 10:01:06 +0000 Subject: [PATCH 21/25] chore: uses stable version of collision --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ed4e7ae2..1ff755e8 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ ], "require": { "php": "^8.1.0", - "nunomaduro/collision": "v7.x-dev", + "nunomaduro/collision": "^7.1.0", "nunomaduro/termwind": "^1.15.1", "pestphp/pest-plugin": "^2.0.0", "phpunit/phpunit": "^10.0.14" From b6b8a72a6a01f09ac91ec780315d4ff96244f971 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Fri, 3 Mar 2023 10:23:56 +0000 Subject: [PATCH 22/25] docs: removes sponsor --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index eb08e57f..b63608fe 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,5 @@ We would like to extend our thanks to the following sponsors for funding Pest de - [Hyvor](https://hyvor.com/) - [Fathom Analytics](https://usefathom.com/) - [Meema](https://meema.io) -- [Scout APM](https://scoutapm.com) Pest is an open-sourced software licensed under the **[MIT license](https://opensource.org/licenses/MIT)**. From fc747c306d58f0150e8c8f26534174bd6c55be42 Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 3 Mar 2023 23:27:25 +0330 Subject: [PATCH 23/25] [2.x] shorter if condition --- src/Bootstrappers/BootFiles.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Bootstrappers/BootFiles.php b/src/Bootstrappers/BootFiles.php index e4fbbe26..98bb2dec 100644 --- a/src/Bootstrappers/BootFiles.php +++ b/src/Bootstrappers/BootFiles.php @@ -66,11 +66,7 @@ final class BootFiles implements Bootstrapper */ private function load(string $filename): void { - if (! Str::endsWith($filename, '.php')) { - return; - } - - if (! file_exists($filename)) { + if (! Str::endsWith($filename, '.php') || ! file_exists($filename)) { return; } From 730bc7d3b3faded6c9aa0bb8247b33a35cd63ce7 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Sun, 5 Mar 2023 01:48:07 +0000 Subject: [PATCH 24/25] chore: code style --- src/Bootstrappers/BootFiles.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Bootstrappers/BootFiles.php b/src/Bootstrappers/BootFiles.php index 98bb2dec..3add2a70 100644 --- a/src/Bootstrappers/BootFiles.php +++ b/src/Bootstrappers/BootFiles.php @@ -66,10 +66,12 @@ final class BootFiles implements Bootstrapper */ private function load(string $filename): void { - if (! Str::endsWith($filename, '.php') || ! file_exists($filename)) { + if (! Str::endsWith($filename, '.php')) { + return; + } + if (! file_exists($filename)) { return; } - include_once $filename; } From 0a76032b1b29225f9db6a68f0a8cbccf0198bf6c Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Thu, 9 Mar 2023 23:48:46 +0000 Subject: [PATCH 25/25] chore: bumps phpunit --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1ff755e8..aef95ae8 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "nunomaduro/collision": "^7.1.0", "nunomaduro/termwind": "^1.15.1", "pestphp/pest-plugin": "^2.0.0", - "phpunit/phpunit": "^10.0.14" + "phpunit/phpunit": "^10.0.15" }, "conflict": { "brianium/paratest": "<7.0.6"