diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 1a7b472..925a7d2 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -3,7 +3,7 @@ inherit: true build: environment: php: - version: 7.2 + version: 7.4 tests: override: - make test diff --git a/.travis.yml b/.travis.yml index 79d3e51..8acb904 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,11 @@ language: php matrix: include: - - php: 7.2 - env: EXECUTE_DEPLOYMENT=true - php: 7.3 - env: deps=low + env: EXECUTE_DEPLOYMENT=true - php: 7.4 + - php: 7.4 + env: deps=low fast_finish: true before_install: - phpenv config-rm xdebug.ini || echo "XDebug is not enabled" diff --git a/Makefile b/Makefile index bc6a906..c01fd98 100644 --- a/Makefile +++ b/Makefile @@ -75,7 +75,7 @@ package: tools/box cd build/phar && \ composer remove phpunit/phpunit --no-update && \ - composer config platform.php 7.2 && \ + composer config platform.php 7.3 && \ composer update --no-dev -o -a tools/box compile @@ -97,16 +97,16 @@ tools/deptrac: curl -Ls http://get.sensiolabs.de/deptrac.phar -o tools/deptrac && chmod +x tools/deptrac tools/infection: tools/infection.pubkey - curl -Ls https://github.com/infection/infection/releases/download/0.13.2/infection.phar -o tools/infection && chmod +x tools/infection + curl -Ls https://github.com/infection/infection/releases/download/0.16.1/infection.phar -o tools/infection && chmod +x tools/infection tools/infection.pubkey: - curl -Ls https://github.com/infection/infection/releases/download/0.13.2/infection.phar.pubkey -o tools/infection.pubkey + curl -Ls https://github.com/infection/infection/releases/download/0.16.1/infection.phar.pubkey -o tools/infection.pubkey tools/box: curl -Ls https://github.com/humbug/box/releases/download/3.8.4/box.phar -o tools/box && chmod +x tools/box tests/phar/tools/phpunit: - curl -Ls https://phar.phpunit.de/phpunit-8.phar -o tests/phar/tools/phpunit && chmod +x tests/phar/tools/phpunit + curl -Ls https://phar.phpunit.de/phpunit-9.phar -o tests/phar/tools/phpunit && chmod +x tests/phar/tools/phpunit tests/phar/tools/phpunit.d/zalas-phpunit-doubles-extension.phar: build/zalas-phpunit-doubles-extension.phar cp build/zalas-phpunit-doubles-extension.phar tests/phar/tools/phpunit.d/zalas-phpunit-doubles-extension.phar diff --git a/README.md b/README.md index 50a4cea..4a87424 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,8 @@ Remember to instruct PHPUnit to load extensions in your `phpunit.xml`: ## Usage -Include the `Zalas\PHPUnit\Doubles\TestCase\TestDoubles` trait to have your test doubles initialised -in one of the supported test doubling frameworks. +Include the `Zalas\PHPUnit\Doubles\TestCase\ProphecyTestDoubles` or `Zalas\PHPUnit\Doubles\TestCase\PHPUnitTestDoubles` +trait to have your test doubles initialised in one of the supported test doubling frameworks. Both the type of test double and the kind of test doubling framework are taken from the property type: @@ -54,11 +54,11 @@ Currently, two test doubling frameworks are supported: use PHPUnit\Framework\TestCase; use Prophecy\Prophecy\ObjectProphecy; -use Zalas\PHPUnit\Doubles\TestCase\TestDoubles; +use Zalas\PHPUnit\Doubles\TestCase\ProphecyTestDoubles; class DiscworldTest extends TestCase { - use TestDoubles; + use ProphecyTestDoubles; /** * @var Vimes|ObjectProphecy @@ -89,11 +89,11 @@ class DiscworldTest extends TestCase use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Zalas\PHPUnit\Doubles\TestCase\TestDoubles; +use Zalas\PHPUnit\Doubles\TestCase\PHPUnitTestDoubles; class DiscworldTest extends TestCase { - use TestDoubles; + use PHPUnitTestDoubles; /** * @var Vimes|MockObject diff --git a/composer.json b/composer.json index a378fe7..9d11438 100644 --- a/composer.json +++ b/composer.json @@ -3,11 +3,12 @@ "description": "Initialises test doubles in PHPUnit test cases for you", "type": "library", "require": { - "php": "^7.2,<8.0", - "phpunit/phpunit": "^8.5 || ^9.0", + "php": "^7.3,<8.0", + "phpunit/phpunit": "^9.1", "phpdocumentor/reflection-docblock": "^4.0.1" }, "require-dev": { + "phpspec/prophecy-phpunit": "dev-master" }, "autoload": { "psr-4": { diff --git a/infection.json.dist b/infection.json.dist index 088e1d5..6fd06dd 100644 --- a/infection.json.dist +++ b/infection.json.dist @@ -12,7 +12,8 @@ "@default": true, "ArrayItemRemoval": { "ignore": [ - "Zalas\\PHPUnit\\Doubles\\TestCase\\TestDoubles::initialiseTestDoubles" + "Zalas\\PHPUnit\\Doubles\\TestCase\\PHPUnitTestDoubles::initialisePHPUnitTestDoubles", + "Zalas\\PHPUnit\\Doubles\\TestCase\\ProphecyTestDoubles::initialiseProphecyTestDoubles" ] }, "IdenticalEqual": false, diff --git a/manifest.xml.in b/manifest.xml.in index 7fccb8a..dd7e0c6 100644 --- a/manifest.xml.in +++ b/manifest.xml.in @@ -1,7 +1,7 @@ - + @@ -10,6 +10,6 @@ - + diff --git a/src/TestCase/Doubler.php b/src/TestCase/Doubler.php index 2040231..dedd2e6 100644 --- a/src/TestCase/Doubler.php +++ b/src/TestCase/Doubler.php @@ -23,15 +23,21 @@ class Doubler private $injector; /** - * @var array + * @var callable */ - private $doubleFactories; + private $doubleFactory; - public function __construct(Extractor $extractor, Injector $injector, array $doubleFactories) + /** + * @var string + */ + private $doubleType; + + public function __construct(Extractor $extractor, Injector $injector, callable $doubleFactory, string $doubleType) { $this->extractor = $extractor; $this->injector = $injector; - $this->doubleFactories = $doubleFactories; + $this->doubleFactory = $doubleFactory; + $this->doubleType = $doubleType; } public function createDoubles(/*object */$testCase) @@ -43,11 +49,8 @@ public function createDoubles(/*object */$testCase) private function createTestDouble(Property $property) { - $doubleType = $this->getDoubleType($property); - $allDoubleTypes = \array_keys($this->doubleFactories); - - return $this->doubleFactories[$doubleType]($property->getTypesFiltered(function (string $type) use ($allDoubleTypes): bool { - return !\in_array($type, $allDoubleTypes); + return ($this->doubleFactory)($property->getTypesFiltered(function (string $type): bool { + return $type !== $this->doubleType; })); } @@ -58,28 +61,12 @@ private function createTestDouble(Property $property) */ private function getTestDoubleProperties(/*object */$testCase): array { - $supportedDoubles = \array_keys($this->doubleFactories); - - return $this->extractor->extract($testCase, function (Property $property) use ($supportedDoubles): bool { - $doubleTypes = $property->getTypesFiltered(function (string $type) use ($supportedDoubles): bool { - return \in_array($type, $supportedDoubles); + return $this->extractor->extract($testCase, function (Property $property): bool { + $doubleTypes = $property->getTypesFiltered(function (string $type): bool { + return $type === $this->doubleType; }); return \count($doubleTypes) > 0; }); } - - private function getDoubleType(Property $property): string - { - $supportedDoubles = \array_keys($this->doubleFactories); - $doubleTypes = $property->getTypesFiltered(function (string $type) use ($supportedDoubles): bool { - return \in_array($type, $supportedDoubles); - }); - - if (\count($doubleTypes) > 1) { - throw new \LogicException(\sprintf('Ambiguous test double definition for "%s": "%s".', $property->getName(), \implode('|', $property->getTypes()))); - } - - return \array_shift($doubleTypes); - } } diff --git a/src/TestCase/PHPUnitTestDoubles.php b/src/TestCase/PHPUnitTestDoubles.php new file mode 100644 index 0000000..f48e820 --- /dev/null +++ b/src/TestCase/PHPUnitTestDoubles.php @@ -0,0 +1,45 @@ +createTestDoubleWithPhpunit($types); + }, + MockObject::class + ); + $doubler->createDoubles($this); + } + + private function createTestDoubleWithPhpunit(array $types): MockObject + { + $normalisedTypes = \array_shift($types) ?? \stdClass::class; + + return $this->getMockBuilder($normalisedTypes) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->disableProxyingToOriginalMethods() + ->disallowMockingUnknownTypes() + ->getMock(); + } +} diff --git a/src/TestCase/ProphecyTestDoubles.php b/src/TestCase/ProphecyTestDoubles.php new file mode 100644 index 0000000..ab42c32 --- /dev/null +++ b/src/TestCase/ProphecyTestDoubles.php @@ -0,0 +1,45 @@ +createTestDoubleWithProphecy($types); + }, + ObjectProphecy::class + ); + $doubler->createDoubles($this); + } + + private function createTestDoubleWithProphecy(array $types): ObjectProphecy + { + $prophecy = $this->prophesize(\array_shift($types)); + + foreach ($types as $type) { + if (\interface_exists($type)) { + $prophecy->willImplement($type); + } else { + $prophecy->willExtend($type); + } + } + + return $prophecy; + } +} diff --git a/src/TestCase/TestDoubles.php b/src/TestCase/TestDoubles.php index 08f0088..9f65fbd 100644 --- a/src/TestCase/TestDoubles.php +++ b/src/TestCase/TestDoubles.php @@ -3,65 +3,11 @@ namespace Zalas\PHPUnit\Doubles\TestCase; -use PHPUnit\Framework\Assert; -use PHPUnit\Framework\MockObject\MockBuilder; -use PHPUnit\Framework\MockObject\MockObject; -use PHPUnit\Framework\TestCase; -use Prophecy\Prophecy\ObjectProphecy; -use Zalas\PHPUnit\Doubles\Injector\PropertyAccessInjector; -use Zalas\PHPUnit\Doubles\PhpDocumentor\ReflectionExtractor; - +/** + * @deprecated use one of the replacement traits: ProphecyTestDoubles, PHPUnitTestDoubles. + */ trait TestDoubles { - abstract public function getMockBuilder(string $className): MockBuilder; - - abstract protected function prophesize(?string $classOrInterface = null): ObjectProphecy; - - /** - * @before - */ - protected function initialiseTestDoubles(): void - { - $doubler = new Doubler( - new ReflectionExtractor([TestCase::class, Assert::class]), - new PropertyAccessInjector(), - [ - ObjectProphecy::class => function (array $types) { - return $this->createTestDoubleWithProphecy($types); - }, - MockObject::class => function (array $types) { - return $this->createTestDoubleWithPhpunit($types); - }, - ] - ); - $doubler->createDoubles($this); - } - - private function createTestDoubleWithProphecy(array $types): ObjectProphecy - { - $prophecy = $this->prophesize(\array_shift($types)); - - foreach ($types as $type) { - if (\interface_exists($type)) { - $prophecy->willImplement($type); - } else { - $prophecy->willExtend($type); - } - } - - return $prophecy; - } - - private function createTestDoubleWithPhpunit(array $types): MockObject - { - $normalisedTypes = \array_shift($types) ?? \stdClass::class; - - return $this->getMockBuilder($normalisedTypes) - ->disableOriginalConstructor() - ->disableOriginalClone() - ->disableArgumentCloning() - ->disableProxyingToOriginalMethods() - ->disallowMockingUnknownTypes() - ->getMock(); - } + use ProphecyTestDoubles; + use PHPUnitTestDoubles; } diff --git a/tests/TestCase/TestDoubles/AmbiguousDouble/AmbiguousDoubleRunner.php b/tests/TestCase/TestDoubles/AmbiguousDouble/AmbiguousDoubleRunner.php deleted file mode 100644 index 2df9a7c..0000000 --- a/tests/TestCase/TestDoubles/AmbiguousDouble/AmbiguousDoubleRunner.php +++ /dev/null @@ -1,25 +0,0 @@ -initialiseTestDoubles(); - } -} diff --git a/tests/TestCase/TestDoubles/AmbiguousDouble/AmbiguousDoubleTest.php b/tests/TestCase/TestDoubles/AmbiguousDouble/AmbiguousDoubleTest.php deleted file mode 100644 index 062351d..0000000 --- a/tests/TestCase/TestDoubles/AmbiguousDouble/AmbiguousDoubleTest.php +++ /dev/null @@ -1,16 +0,0 @@ -expectException(\LogicException::class); - - (new AmbiguousDoubleRunner())->callInitialiseTestDoubles(); - } -} diff --git a/tests/TestCase/TestDoubles/Inheritance/InheritanceTest.php b/tests/TestCase/TestDoubles/Inheritance/InheritanceTest.php index 7775bf7..7207b07 100644 --- a/tests/TestCase/TestDoubles/Inheritance/InheritanceTest.php +++ b/tests/TestCase/TestDoubles/Inheritance/InheritanceTest.php @@ -3,14 +3,16 @@ namespace Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Inheritance; +use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; -use Zalas\PHPUnit\Doubles\TestCase\TestDoubles; +use Zalas\PHPUnit\Doubles\TestCase\ProphecyTestDoubles; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Fred; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Vimes; class InheritanceTest extends BaseTestCase { - use TestDoubles; + use ProphecyTrait; + use ProphecyTestDoubles; use PropertyTrait; public function test_it_initialises_parent_private_properties() diff --git a/tests/TestCase/TestDoubles/MissingType/PhpunitTest.php b/tests/TestCase/TestDoubles/MissingType/PhpunitTest.php index c493860..a533274 100644 --- a/tests/TestCase/TestDoubles/MissingType/PhpunitTest.php +++ b/tests/TestCase/TestDoubles/MissingType/PhpunitTest.php @@ -5,11 +5,11 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Zalas\PHPUnit\Doubles\TestCase\TestDoubles; +use Zalas\PHPUnit\Doubles\TestCase\PHPUnitTestDoubles; class PhpunitTest extends TestCase { - use TestDoubles; + use PHPUnitTestDoubles; /** * @var MockObject diff --git a/tests/TestCase/TestDoubles/MissingType/ProphecyTest.php b/tests/TestCase/TestDoubles/MissingType/ProphecyTest.php index 90b856e..0e851cc 100644 --- a/tests/TestCase/TestDoubles/MissingType/ProphecyTest.php +++ b/tests/TestCase/TestDoubles/MissingType/ProphecyTest.php @@ -4,12 +4,14 @@ namespace Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\MissingType; use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; -use Zalas\PHPUnit\Doubles\TestCase\TestDoubles; +use Zalas\PHPUnit\Doubles\TestCase\ProphecyTestDoubles; class ProphecyTest extends TestCase { - use TestDoubles; + use ProphecyTrait; + use ProphecyTestDoubles; /** * @var ObjectProphecy diff --git a/tests/TestCase/TestDoubles/NotNull/PhpunitTest.php b/tests/TestCase/TestDoubles/NotNull/PhpunitTest.php index 8478f86..c032280 100644 --- a/tests/TestCase/TestDoubles/NotNull/PhpunitTest.php +++ b/tests/TestCase/TestDoubles/NotNull/PhpunitTest.php @@ -5,14 +5,14 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Zalas\PHPUnit\Doubles\TestCase\TestDoubles; +use Zalas\PHPUnit\Doubles\TestCase\PHPUnitTestDoubles; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Copper; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Fred; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Nobby; class PhpunitTest extends TestCase { - use TestDoubles; + use PHPUnitTestDoubles; /** * @var Nobby|MockObject diff --git a/tests/TestCase/TestDoubles/NotNull/ProphecyTest.php b/tests/TestCase/TestDoubles/NotNull/ProphecyTest.php index e2806cd..bb2ce9f 100644 --- a/tests/TestCase/TestDoubles/NotNull/ProphecyTest.php +++ b/tests/TestCase/TestDoubles/NotNull/ProphecyTest.php @@ -4,15 +4,17 @@ namespace Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\NotNull; use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; -use Zalas\PHPUnit\Doubles\TestCase\TestDoubles; +use Zalas\PHPUnit\Doubles\TestCase\ProphecyTestDoubles; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Copper; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Fred; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Nobby; class ProphecyTest extends TestCase { - use TestDoubles; + use ProphecyTrait; + use ProphecyTestDoubles; /** * @var Nobby|ObjectProphecy diff --git a/tests/TestCase/TestDoubles/PhpunitTest.php b/tests/TestCase/TestDoubles/PhpunitTest.php index 73c26e8..39a2d39 100644 --- a/tests/TestCase/TestDoubles/PhpunitTest.php +++ b/tests/TestCase/TestDoubles/PhpunitTest.php @@ -5,7 +5,7 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Zalas\PHPUnit\Doubles\TestCase\TestDoubles; +use Zalas\PHPUnit\Doubles\TestCase\PHPUnitTestDoubles; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Copper; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Death; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Discworld; @@ -13,7 +13,7 @@ class PhpunitTest extends TestCase { - use TestDoubles; + use PHPUnitTestDoubles; /** * @var Vimes|MockObject diff --git a/tests/TestCase/TestDoubles/ProphecyTest.php b/tests/TestCase/TestDoubles/ProphecyTest.php index 7535089..2d94f62 100644 --- a/tests/TestCase/TestDoubles/ProphecyTest.php +++ b/tests/TestCase/TestDoubles/ProphecyTest.php @@ -4,8 +4,9 @@ namespace Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles; use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; -use Zalas\PHPUnit\Doubles\TestCase\TestDoubles; +use Zalas\PHPUnit\Doubles\TestCase\ProphecyTestDoubles; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Copper; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Death; use Zalas\PHPUnit\Doubles\Tests\TestCase\TestDoubles\Fixtures\Discworld; @@ -16,7 +17,8 @@ class ProphecyTest extends TestCase { - use TestDoubles; + use ProphecyTrait; + use ProphecyTestDoubles; /** * @var Vimes|ObjectProphecy diff --git a/tests/phar/bootstrap.php b/tests/phar/bootstrap.php index b03b359..6262000 100644 --- a/tests/phar/bootstrap.php +++ b/tests/phar/bootstrap.php @@ -7,6 +7,13 @@ if (0 === \strpos($className, 'Zalas\PHPUnit\Doubles\Tests\TestCase\\TestDoubles\\')) { $path = \sprintf('%s/../%s.php', __DIR__, \strtr($className, ['\\' => '/', 'Zalas\PHPUnit\Doubles\Tests\\' => ''])); + if (\file_exists($path)) { + require_once $path; + } + } + if (0 === \strpos($className, 'Prophecy\PhpUnit\\')) { + $path = \sprintf('%s/../../vendor/phpspec/prophecy-phpunit/src/%s.php', __DIR__, \strtr($className, ['\\' => '/', 'Prophecy\PhpUnit\\' => ''])); + if (\file_exists($path)) { require_once $path; }