Skip to content

Commit

Permalink
Fixes PHPUnit 8.4 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
MasterOdin committed Oct 5, 2019
1 parent 04f78fe commit 07a05d4
Show file tree
Hide file tree
Showing 9 changed files with 287 additions and 32 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.phpunit.result.cache
vendor/
composer.lock
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ cache:

env:
- PHPUNIT_VERSION=dev-master
- PHPUNIT_VERSION=~8.4.0
- PHPUNIT_VERSION=~8.3.0
- PHPUNIT_VERSION=~8.2.0
- PHPUNIT_VERSION=~8.1.0
- PHPUNIT_VERSION=~8.0.0
Expand Down Expand Up @@ -36,6 +38,10 @@ matrix:
exclude:
- php: 7.1
env: PHPUNIT_VERSION=dev-master
- php: 7.1
env: PHPUNIT_VERSION=~8.4.0
- php: 7.1
env: PHPUNIT_VERSION=~8.3.0
- php: 7.1
env: PHPUNIT_VERSION=~8.2.0
- php: 7.1
Expand All @@ -44,6 +50,10 @@ matrix:
env: PHPUNIT_VERSION=~8.0.0
- php: 7
env: PHPUNIT_VERSION=dev-master
- php: 7
env: PHPUNIT_VERSION=~8.4.0
- php: 7
env: PHPUNIT_VERSION=~8.3.0
- php: 7
env: PHPUNIT_VERSION=~8.2.0
- php: 7
Expand Down
26 changes: 23 additions & 3 deletions autoload.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<?php

if (! interface_exists(\PHPUnit\Framework\MockObject\Matcher\Invocation::class)) {
if (class_exists(\PHPUnit\Framework\MockObject\Rule\InvocationOrder::class)) {
class_alias(
\PHPUnit\Framework\MockObject\Rule\InvocationOrder::class,
\PHPUnit\Framework\MockObject\Matcher\Invocation::class
);
}
elseif (! interface_exists(\PHPUnit\Framework\MockObject\Matcher\Invocation::class)) {
class_alias(
\PHPUnit_Framework_MockObject_Matcher_Invocation::class,
\PHPUnit\Framework\MockObject\Matcher\Invocation::class
Expand Down Expand Up @@ -30,21 +36,30 @@ class_alias(
);
}

if (class_exists(\PHPUnit\Framework\MockObject\Rule\MethodName::class)) {
class_alias(
\PHPUnit\Framework\MockObject\Rule\MethodName::class,
\PHPUnit\Framework\MockObject\Matcher\MethodName::class
);
}

if (! class_exists(\PHPUnit\Framework\MockObject\Matcher\MethodName::class)) {
class_alias(
\PHPUnit_Framework_MockObject_Matcher_MethodName::class,
\PHPUnit\Framework\MockObject\Matcher\MethodName::class
);
}

if (! interface_exists(\PHPUnit\Framework\MockObject\Stub\MatcherCollection::class)) {
if (!class_exists(\PHPUnit\Framework\MockObject\InvocationHandler::class)
&& !interface_exists(\PHPUnit\Framework\MockObject\Stub\MatcherCollection::class)) {
class_alias(
\PHPUnit_Framework_MockObject_Stub_MatcherCollection::class,
\PHPUnit\Framework\MockObject\Stub\MatcherCollection::class
);
}

if (! class_exists(\PHPUnit\Framework\MockObject\InvocationMocker::class)) {
if (!class_exists(\PHPUnit\Framework\MockObject\InvocationHandler::class)
&& !class_exists(\PHPUnit\Framework\MockObject\InvocationMocker::class)) {
class_alias(
\PHPUnit_Framework_MockObject_InvocationMocker::class,
\PHPUnit\Framework\MockObject\InvocationMocker::class
Expand All @@ -65,6 +80,11 @@ class_alias(
}

if (class_exists(\PHPUnit\Runner\Version::class)
&& version_compare(\PHPUnit\Runner\Version::id(), '8.4.0') >= 0
) {
class_alias(\phpmock\phpunit\DefaultArgumentRemoverReturnTypes84::class, \phpmock\phpunit\DefaultArgumentRemover::class);
class_alias(\phpmock\phpunit\MockObjectProxyReturnTypes84::class, \phpmock\phpunit\MockObjectProxy::class);
} elseif (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);
Expand Down
81 changes: 81 additions & 0 deletions classes/DefaultArgumentRemoverReturnTypes84.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace phpmock\phpunit;

use phpmock\generator\MockFunctionGenerator;
use PHPUnit\Framework\MockObject\Invocation;
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;

/**
* Removes default arguments from the invocation.
*
* @author Markus Malkusch <[email protected]>
* @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
* @license http://www.wtfpl.net/txt/copying/ WTFPL
* @internal
*/
class DefaultArgumentRemoverReturnTypes84 extends InvocationOrder
{
/**
* @SuppressWarnings(PHPMD)
*/
public function invokedDo(Invocation $invocation)
{
}

/**
* @SuppressWarnings(PHPMD)
*/
public function matches(Invocation $invocation) : bool
{
$iClass = class_exists(Invocation::class);

if ($invocation instanceof Invocation\StaticInvocation
|| $iClass
) {
$this->removeDefaultArguments(
$invocation,
$iClass ? Invocation::class : Invocation\StaticInvocation::class
);
} 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 $invocation, string $class)
{
$remover = function () {
MockFunctionGenerator::removeDefaultArguments($this->parameters);
};

$remover->bindTo($invocation, $class)();
}
}
93 changes: 93 additions & 0 deletions classes/MockObjectProxyReturnTypes84.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace phpmock\phpunit;

use PHPUnit\Framework\MockObject\Builder\InvocationMocker as BuilderInvocationMocker;
use PHPUnit\Framework\MockObject\InvocationHandler;
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
use PHPUnit\Framework\MockObject\MockObject;
use phpmock\integration\MockDelegateFunctionBuilder;

/**
* Proxy for PHPUnit's PHPUnit_Framework_MockObject_MockObject.
*
* @author Markus Malkusch <[email protected]>
* @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
* @license http://www.wtfpl.net/txt/copying/ WTFPL
* @internal
*/
class MockObjectProxyReturnTypes84 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_getInvocationHandler(): InvocationHandler
{
return $this->mockObject->__phpunit_getInvocationHandler();
}

/**
* @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(InvocationOrder $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);
}
}
33 changes: 23 additions & 10 deletions classes/PHPMock.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,38 @@ public function getFunctionMock($namespace, $name)
{
$delegateBuilder = new MockDelegateFunctionBuilder();
$delegateBuilder->build($name);

$mock = $this->getMockBuilder($delegateBuilder->getFullyQualifiedClassName())->getMockForAbstractClass();

$mock->__phpunit_getInvocationMocker()->addMatcher(new DefaultArgumentRemover());


$builder = $this->getMockBuilder($delegateBuilder->getFullyQualifiedClassName());
if (is_callable([$builder, 'addMethods'])) {
$builder->addMethods([$name]);
}
$mock = $builder->getMockForAbstractClass();
$this->addMatcher($mock, $name);

$functionMockBuilder = new MockBuilder();
$functionMockBuilder->setNamespace($namespace)
->setName($name)
->setFunctionProvider($mock);

$functionMock = $functionMockBuilder->build();
$functionMock->enable();

$this->registerForTearDown($functionMock);

$proxy = new MockObjectProxy($mock);
return $proxy;
}


private function addMatcher($mock, $name)
{
if (is_callable([$mock, '__phpunit_getInvocationHandler'])) {
$mocker = $mock->__phpunit_getInvocationHandler()->expects(new DefaultArgumentRemover());
$mocker->method($name);
return;
}
$mock->__phpunit_getInvocationMocker()->addMatcher(new DefaultArgumentRemover());
}

/**
* Automatically disable function mocks after the test was run.
*
Expand All @@ -83,7 +96,7 @@ public function registerForTearDown(Deactivatable $deactivatable)
$result = $this->getTestResultObject();
$result->addListener(new MockDisabler($deactivatable));
}

/**
* Defines the mocked function in the given namespace.
*
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
},
"require": {
"php": ">=7",
"phpunit/phpunit": "^6 || ^7 || ^8",
"phpunit/phpunit": "8.4.x-dev",
"php-mock/php-mock-integration": "^2"
},
"archive": {
Expand Down
Loading

0 comments on commit 07a05d4

Please sign in to comment.