From e49762cd80d69049de4dfee5bdf4e86c227a3661 Mon Sep 17 00:00:00 2001 From: webimpress Date: Fri, 5 Apr 2019 23:21:31 +0100 Subject: [PATCH 1/2] Added PHPUnit 8.1 support Resolves #34 --- .travis.yml | 5 + autoload.php | 10 ++ ...> DefaultArgumentRemoverNoReturnTypes.php} | 2 +- classes/DefaultArgumentRemoverReturnTypes.php | 75 +++++++++++++++ ...y.php => MockObjectProxyNoReturnTypes.php} | 2 +- classes/MockObjectProxyReturnTypes.php | 94 +++++++++++++++++++ tests/MockObjectProxyTest.php | 23 +++-- 7 files changed, 201 insertions(+), 10 deletions(-) rename classes/{DefaultArgumentRemover.php => DefaultArgumentRemoverNoReturnTypes.php} (96%) create mode 100644 classes/DefaultArgumentRemoverReturnTypes.php rename classes/{MockObjectProxy.php => MockObjectProxyNoReturnTypes.php} (97%) create mode 100644 classes/MockObjectProxyReturnTypes.php diff --git a/.travis.yml b/.travis.yml index 4da042a..f0d9d8e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,7 @@ env: - PHPUNIT_VERSION=~7.4.0 - PHPUNIT_VERSION=~7.5.0 - PHPUNIT_VERSION=~8.0.0 + - PHPUNIT_VERSION=~8.1.0 php: - 7.3 @@ -34,10 +35,14 @@ matrix: exclude: - php: 7.1 env: PHPUNIT_VERSION=dev-master + - php: 7.1 + env: PHPUNIT_VERSION=~8.1.0 - php: 7.1 env: PHPUNIT_VERSION=~8.0.0 - php: 7 env: PHPUNIT_VERSION=dev-master + - php: 7 + env: PHPUNIT_VERSION=~8.1.0 - php: 7 env: PHPUNIT_VERSION=~8.0.0 - php: 7 diff --git a/autoload.php b/autoload.php index 67c8e93..8230601 100644 --- a/autoload.php +++ b/autoload.php @@ -54,3 +54,13 @@ class_alias( phpmock\phpunit\MockDisabler::class ); } + +if (class_exists(\PHPUnit\Runner\Version::class) + && version_compare(\PHPUnit\Runner\Version::id(), '8.1.0') >= 0 +) { + class_alias(\phpmock\phpunit\DefaultArgumentRemoverReturnTypes::class, \phpmock\phpunit\DefaultArgumentRemover::class); + class_alias(\phpmock\phpunit\MockObjectProxyReturnTypes::class, \phpmock\phpunit\MockObjectProxy::class); +} else { + class_alias(\phpmock\phpunit\DefaultArgumentRemoverNoReturnTypes::class, \phpmock\phpunit\DefaultArgumentRemover::class); + class_alias(\phpmock\phpunit\MockObjectProxyNoReturnTypes::class, \phpmock\phpunit\MockObjectProxy::class); +} diff --git a/classes/DefaultArgumentRemover.php b/classes/DefaultArgumentRemoverNoReturnTypes.php similarity index 96% rename from classes/DefaultArgumentRemover.php rename to classes/DefaultArgumentRemoverNoReturnTypes.php index caf0751..0129334 100644 --- a/classes/DefaultArgumentRemover.php +++ b/classes/DefaultArgumentRemoverNoReturnTypes.php @@ -14,7 +14,7 @@ * @license http://www.wtfpl.net/txt/copying/ WTFPL * @internal */ -class DefaultArgumentRemover implements InvocationInterface +class DefaultArgumentRemoverNoReturnTypes implements InvocationInterface { /** diff --git a/classes/DefaultArgumentRemoverReturnTypes.php b/classes/DefaultArgumentRemoverReturnTypes.php new file mode 100644 index 0000000..1a8adf5 --- /dev/null +++ b/classes/DefaultArgumentRemoverReturnTypes.php @@ -0,0 +1,75 @@ + + * @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations + * @license http://www.wtfpl.net/txt/copying/ WTFPL + * @internal + */ +class DefaultArgumentRemoverReturnTypes implements InvocationInterface +{ + + /** + * @SuppressWarnings(PHPMD) + */ + public function invoked(Invocation $invocation) + { + } + + /** + * @SuppressWarnings(PHPMD) + */ + public function matches(Invocation $invocation) : bool + { + if ($invocation instanceof Invocation\StaticInvocation) { + $this->removeDefaultArguments($invocation); + } else { + MockFunctionGenerator::removeDefaultArguments($invocation->parameters); + } + + return false; + } + + public function verify() : void + { + } + + /** + * This method is not defined in the interface, but used in + * PHPUnit_Framework_MockObject_InvocationMocker::hasMatchers(). + * + * @return boolean + * @see \PHPUnit_Framework_MockObject_InvocationMocker::hasMatchers() + */ + public function hasMatchers() + { + return false; + } + + public function toString() : string + { + return __CLASS__; + } + + /** + * Remove default arguments from StaticInvocation or its children (hack) + * + * @SuppressWarnings(PHPMD) + */ + private function removeDefaultArguments(Invocation\StaticInvocation $invocation) + { + $remover = function () { + MockFunctionGenerator::removeDefaultArguments($this->parameters); + }; + + $remover->bindTo($invocation, Invocation\StaticInvocation::class)(); + } +} diff --git a/classes/MockObjectProxy.php b/classes/MockObjectProxyNoReturnTypes.php similarity index 97% rename from classes/MockObjectProxy.php rename to classes/MockObjectProxyNoReturnTypes.php index 21550de..f71c1a4 100644 --- a/classes/MockObjectProxy.php +++ b/classes/MockObjectProxyNoReturnTypes.php @@ -14,7 +14,7 @@ * @license http://www.wtfpl.net/txt/copying/ WTFPL * @internal */ -class MockObjectProxy implements MockObject +class MockObjectProxyNoReturnTypes implements MockObject { /** diff --git a/classes/MockObjectProxyReturnTypes.php b/classes/MockObjectProxyReturnTypes.php new file mode 100644 index 0000000..6149401 --- /dev/null +++ b/classes/MockObjectProxyReturnTypes.php @@ -0,0 +1,94 @@ + + * @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations + * @license http://www.wtfpl.net/txt/copying/ WTFPL + * @internal + */ +class MockObjectProxyReturnTypes implements MockObject +{ + + /** + * @var MockObject $mockObject The mock object. + */ + private $mockObject; + + /** + * Inject the subject. + * + * @param MockObject $mockObject The subject. + */ + public function __construct(MockObject $mockObject) + { + $this->mockObject = $mockObject; + } + + /** + * @SuppressWarnings(PHPMD) + */ + // @codingStandardsIgnoreStart + public function __phpunit_getInvocationMocker() : InvocationMocker + { + // @codingStandardsIgnoreEnd + return $this->mockObject->__phpunit_getInvocationMocker(); + } + + /** + * @SuppressWarnings(PHPMD) + */ + // @codingStandardsIgnoreStart + public function __phpunit_setOriginalObject($originalObject) : void + { + // @codingStandardsIgnoreEnd + $this->mockObject->__phpunit_setOriginalObject($originalObject); + } + + /** + * @SuppressWarnings(PHPMD) + */ + // @codingStandardsIgnoreStart + public function __phpunit_verify(bool $unsetInvocationMocker = true) : void + { + // @codingStandardsIgnoreEnd + $this->mockObject->__phpunit_verify($unsetInvocationMocker); + } + + public function expects(Invocation $matcher) : BuilderInvocationMocker + { + return $this->mockObject->expects($matcher)->method(MockDelegateFunctionBuilder::METHOD); + } + + /** + * This method is not part of the contract but was found in + * PHPUnit's mocked_class.tpl.dist. + * + * @SuppressWarnings(PHPMD) + */ + // @codingStandardsIgnoreStart + public function __phpunit_hasMatchers() : bool + { + // @codingStandardsIgnoreEnd + return $this->mockObject->__phpunit_hasMatchers(); + } + + /** + * @SuppressWarnings(PHPMD) + */ + // @codingStandardsIgnoreStart + public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration) : void + { + // @codingStandardsIgnoreEnd + $this->mockObject->__phpunit_setReturnValueGeneration($returnValueGeneration); + } +} diff --git a/tests/MockObjectProxyTest.php b/tests/MockObjectProxyTest.php index 8f28d1c..317b763 100644 --- a/tests/MockObjectProxyTest.php +++ b/tests/MockObjectProxyTest.php @@ -66,13 +66,13 @@ public function testExpects() public function testHasMatcher() { $prophecy = $this->prophesize(MockObject::class); - $prophecy->__phpunit_hasMatchers()->willReturn("foo"); + $prophecy->__phpunit_hasMatchers()->willReturn(true); $mock = $prophecy->reveal(); $proxy = new MockObjectProxy($mock); $result = $proxy->__phpunit_hasMatchers(); - $this->assertEquals("foo", $result); + $this->assertTrue($result); } /** @@ -84,16 +84,23 @@ public function testHasMatcher() * @test * @dataProvider provideTestProxiedMethods */ - public function testProxiedMethods($method, array $arguments = [], $expected = "foo") + public function testProxiedMethods($method, array $arguments = [], $expected = null) { $prophecy = $this->prophesize(MockObject::class); - call_user_func_array([$prophecy, $method], $arguments)->willReturn($expected); + if ($expected) { + call_user_func_array([$prophecy, $method], $arguments)->willReturn($expected)->shouldBeCalledTimes(1); + } else { + call_user_func_array([$prophecy, $method], $arguments)->shouldBeCalledTimes(1); + } $mock = $prophecy->reveal(); $proxy = new MockObjectProxy($mock); $result = call_user_func_array([$proxy, $method], $arguments); - $this->assertEquals($expected, $result); + + if ($expected) { + $this->assertSame($expected, $result); + } } /** @@ -104,9 +111,9 @@ public function testProxiedMethods($method, array $arguments = [], $expected = " public function provideTestProxiedMethods() { return [ - ["__phpunit_getInvocationMocker"], - ["__phpunit_setOriginalObject", ["bar"]], - ["__phpunit_verify", [true]], + ['__phpunit_getInvocationMocker', [], new \PHPUnit\Framework\MockObject\InvocationMocker([], true)], + ['__phpunit_setOriginalObject', ['bar']], + ['__phpunit_verify', [true]], ]; } } From f53e5e585d0d9fb44f3d7fda790d3494424b9962 Mon Sep 17 00:00:00 2001 From: webimpress Date: Fri, 5 Apr 2019 23:28:50 +0100 Subject: [PATCH 2/2] Added alias for InvocationMocker in autoload.php --- autoload.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/autoload.php b/autoload.php index 8230601..9de6a88 100644 --- a/autoload.php +++ b/autoload.php @@ -42,6 +42,13 @@ class_alias( ); } +if (! class_exists(\PHPUnit\Framework\MockObject\InvocationMocker::class)) { + class_alias( + \PHPUnit_Framework_MockObject_InvocationMocker::class, + \PHPUnit\Framework\MockObject\InvocationMocker::class + ); +} + if (! class_exists(\PHPUnit\Framework\BaseTestListener::class)) { include __DIR__ . '/compatibility/BaseTestListener.php'; class_alias(