diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed3020b..651be1b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: strategy: fail-fast: false matrix: - php: ['7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] + php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] min_stability: [''] name_suffix: [''] include: diff --git a/composer.json b/composer.json index a27bf91..873f852 100644 --- a/composer.json +++ b/composer.json @@ -12,9 +12,9 @@ } ], "require": { - "php": "^7.3 || ^8", - "phpspec/prophecy": "^1.18", - "phpunit/phpunit":"^9.1 || ^10.1 || ^11.0" + "php": "^5.6 || ^7 || ^8", + "phpspec/prophecy": "^1.3", + "phpunit/phpunit": "^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0" }, "autoload": { "psr-4": { diff --git a/fixtures/SpyFailure.php b/fixtures/SpyFailure.php index d7165c7..50c39b2 100644 --- a/fixtures/SpyFailure.php +++ b/fixtures/SpyFailure.php @@ -15,6 +15,7 @@ public function testMethod() $prophecy->reveal(); + // Native PHPUnit implementation don't add this to the assertion count. $prophecy->format('Y-m-d')->shouldHaveBeenCalled(); } } diff --git a/src/ProphecyTrait.php b/src/ProphecyTrait.php index db1676f..b0ba01a 100644 --- a/src/ProphecyTrait.php +++ b/src/ProphecyTrait.php @@ -1,125 +1,7 @@ -|null $classOrInterface - * @phpstan-return ($classOrInterface is null ? ObjectProphecy : ObjectProphecy) - * - * @not-deprecated - */ - protected function prophesize(?string $classOrInterface = null): ObjectProphecy - { - static $isPhpUnit9; - $isPhpUnit9 = $isPhpUnit9 ?? method_exists($this, 'recordDoubledType'); - - if (! $isPhpUnit9) { - // PHPUnit 10.1 - $this->registerFailureType(PredictionException::class); - } elseif (\is_string($classOrInterface)) { - // PHPUnit 9 - \assert($this instanceof TestCase); - $this->recordDoubledType($classOrInterface); - } - - return $this->getProphet()->prophesize($classOrInterface); - } - - /** - * @postCondition - */ - #[PostCondition] - protected function verifyProphecyDoubles(): void - { - if ($this->prophet === null) { - return; - } - - try { - $this->prophet->checkPredictions(); - } catch (PredictionException $e) { - throw new AssertionFailedError($e->getMessage()); - } finally { - $this->countProphecyAssertions(); - } - } - - /** - * @after - */ - #[After] - protected function tearDownProphecy(): void - { - if (null !== $this->prophet && !$this->prophecyAssertionsCounted) { - // Some Prophecy assertions may have been done in tests themselves even when a failure happened before checking mock objects. - $this->countProphecyAssertions(); - } - - $this->prophet = null; - } - - /** - * @internal - */ - private function countProphecyAssertions(): void - { - \assert($this instanceof TestCase); - $this->prophecyAssertionsCounted = true; - - foreach ($this->prophet->getProphecies() as $objectProphecy) { - foreach ($objectProphecy->getMethodProphecies() as $methodProphecies) { - foreach ($methodProphecies as $methodProphecy) { - \assert($methodProphecy instanceof MethodProphecy); - - $this->addToAssertionCount(\count($methodProphecy->getCheckedPredictions())); - } - } - } - } - - /** - * @internal - */ - private function getProphet(): Prophet - { - if ($this->prophet === null) { - $this->prophet = new Prophet; - } - - return $this->prophet; - } +if (PHP_VERSION_ID >= 70000) { + require_once __DIR__ . '/ProphecyTrait7.php'; +} else { + require_once __DIR__ . '/ProphecyTrait5.php'; } diff --git a/src/ProphecyTrait5.php b/src/ProphecyTrait5.php new file mode 100644 index 0000000..7f42a1a --- /dev/null +++ b/src/ProphecyTrait5.php @@ -0,0 +1,111 @@ +|null $classOrInterface + * @phpstan-return ($classOrInterface is null ? ObjectProphecy : ObjectProphecy) + * + * @not-deprecated + */ + protected function prophesize($classOrInterface = null) + { + static $hasFailureTypes; + + // PHPUnit 10.1.0+. + if ($hasFailureTypes === null) { + $hasFailureTypes = method_exists($this, 'registerFailureType'); + } + + if ($hasFailureTypes) { + $this->registerFailureType(PredictionException::class); + } + + return $this->getProphet()->prophesize($classOrInterface); + } + + /** + * @after + */ + #[After] + protected function tearDownProphecy() + { + if (null !== $this->prophet) { + $this->verifyProphecyDoubles(); + } + + $this->prophet = null; + } + + protected function verifyProphecyDoubles() + { + if ($this->prophet === null) { + return; + } + + try { + $this->prophet->checkPredictions(); + } catch (PredictionException $e) { + throw new AssertionFailedError($e->getMessage()); + } finally { + // Some Prophecy assertions may have been done in tests themselves even when a failure happened before checking mock objects. + $this->countProphecyAssertions(); + } + } + + /** + * @internal + */ + private function countProphecyAssertions() + { + \assert($this instanceof TestCase); + + foreach ($this->prophet->getProphecies() as $objectProphecy) { + foreach ($objectProphecy->getMethodProphecies() as $methodProphecies) { + foreach ($methodProphecies as $methodProphecy) { + \assert($methodProphecy instanceof MethodProphecy); + + $this->addToAssertionCount(\count($methodProphecy->getCheckedPredictions())); + } + } + } + } + + /** + * @internal + */ + private function getProphet() + { + if ($this->prophet === null) { + $this->prophet = new Prophet; + } + + return $this->prophet; + } +} diff --git a/src/ProphecyTrait7.php b/src/ProphecyTrait7.php new file mode 100644 index 0000000..e6beb23 --- /dev/null +++ b/src/ProphecyTrait7.php @@ -0,0 +1,111 @@ +|null $classOrInterface + * @phpstan-return ($classOrInterface is null ? ObjectProphecy : ObjectProphecy) + * + * @not-deprecated + */ + protected function prophesize($classOrInterface = null): ObjectProphecy + { + static $hasFailureTypes; + + // PHPUnit 10.1.0+. + if ($hasFailureTypes === null) { + $hasFailureTypes = method_exists($this, 'registerFailureType'); + } + + if ($hasFailureTypes) { + $this->registerFailureType(PredictionException::class); + } + + return $this->getProphet()->prophesize($classOrInterface); + } + + /** + * @after + */ + #[After] + protected function tearDownProphecy() + { + if (null !== $this->prophet) { + $this->verifyProphecyDoubles(); + } + + $this->prophet = null; + } + + protected function verifyProphecyDoubles() + { + if ($this->prophet === null) { + return; + } + + try { + $this->prophet->checkPredictions(); + } catch (PredictionException $e) { + throw new AssertionFailedError($e->getMessage()); + } finally { + // Some Prophecy assertions may have been done in tests themselves even when a failure happened before checking mock objects. + $this->countProphecyAssertions(); + } + } + + /** + * @internal + */ + private function countProphecyAssertions()/*: void*/ + { + \assert($this instanceof TestCase); + + foreach ($this->prophet->getProphecies() as $objectProphecy) { + foreach ($objectProphecy->getMethodProphecies() as $methodProphecies) { + foreach ($methodProphecies as $methodProphecy) { + \assert($methodProphecy instanceof MethodProphecy); + + $this->addToAssertionCount(\count($methodProphecy->getCheckedPredictions())); + } + } + } + } + + /** + * @internal + */ + private function getProphet(): Prophet + { + if ($this->prophet === null) { + $this->prophet = new Prophet; + } + + return $this->prophet; + } +} diff --git a/tests/MockFailure.phpt b/tests/MockFailure.phpt index d5647ea..446f593 100644 --- a/tests/MockFailure.phpt +++ b/tests/MockFailure.phpt @@ -25,7 +25,8 @@ Double\DateTime\P1: but 1 were made: - format("Y-m-d") @ fixtures/MockFailure.php:%d -%s/src/ProphecyTrait.php:%d +%s/src/ProphecyTrait%d.php:%d +%s/src/ProphecyTrait%d.php:%d %s/tests/run_test.php:%d FAILURES! diff --git a/tests/run_test.php b/tests/run_test.php index 5f1ec63..ff143e9 100644 --- a/tests/run_test.php +++ b/tests/run_test.php @@ -4,22 +4,26 @@ use PHPUnit\TextUI\Application; use PHPUnit\TextUI\Command; +use PHPUnit_TextUI_Command; require_once __DIR__ . '/xdebug_filter.php'; require_once dirname(__DIR__) . '/vendor/autoload.php'; -function runTest(string $fixtureName): void +function runTest($fixtureName) { $filename = dirname(__DIR__) . '/fixtures/' . $fixtureName . '.php'; if (!file_exists($filename)) { throw new \InvalidArgumentException('Unable to find test fixture at path ' . $filename); } - if (class_exists(Command::class)) { - // PHPUnit 9.x + if (class_exists(Application::class)) { + // PHPUnit 10.x+. + (new Application())->run(['phpunit', $filename, '--no-configuration']); + } elseif (class_exists(Command::class)) { + // PHPUnit 9.x-. (new Command())->run(['phpunit', $filename, '--verbose', '--no-configuration'], false); } else { - // PHPUnit 10.x - (new Application())->run(['phpunit', $filename, '--no-configuration']); + // PHPUnit 5.x-. + (new PHPUnit_TextUI_Command())->run(['phpunit', $filename, '--verbose', '--no-configuration'], false); } } diff --git a/tests/xdebug_filter.php b/tests/xdebug_filter.php index 6e4279d..b939d6b 100644 --- a/tests/xdebug_filter.php +++ b/tests/xdebug_filter.php @@ -1,5 +1,9 @@