Skip to content

Commit 07a05d4

Browse files
committed
Fixes PHPUnit 8.4 compatibility
1 parent 04f78fe commit 07a05d4

9 files changed

+287
-32
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.phpunit.result.cache
2+
vendor/
3+
composer.lock

.travis.yml

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ cache:
88

99
env:
1010
- PHPUNIT_VERSION=dev-master
11+
- PHPUNIT_VERSION=~8.4.0
12+
- PHPUNIT_VERSION=~8.3.0
1113
- PHPUNIT_VERSION=~8.2.0
1214
- PHPUNIT_VERSION=~8.1.0
1315
- PHPUNIT_VERSION=~8.0.0
@@ -36,6 +38,10 @@ matrix:
3638
exclude:
3739
- php: 7.1
3840
env: PHPUNIT_VERSION=dev-master
41+
- php: 7.1
42+
env: PHPUNIT_VERSION=~8.4.0
43+
- php: 7.1
44+
env: PHPUNIT_VERSION=~8.3.0
3945
- php: 7.1
4046
env: PHPUNIT_VERSION=~8.2.0
4147
- php: 7.1
@@ -44,6 +50,10 @@ matrix:
4450
env: PHPUNIT_VERSION=~8.0.0
4551
- php: 7
4652
env: PHPUNIT_VERSION=dev-master
53+
- php: 7
54+
env: PHPUNIT_VERSION=~8.4.0
55+
- php: 7
56+
env: PHPUNIT_VERSION=~8.3.0
4757
- php: 7
4858
env: PHPUNIT_VERSION=~8.2.0
4959
- php: 7

autoload.php

+23-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
<?php
22

3-
if (! interface_exists(\PHPUnit\Framework\MockObject\Matcher\Invocation::class)) {
3+
if (class_exists(\PHPUnit\Framework\MockObject\Rule\InvocationOrder::class)) {
4+
class_alias(
5+
\PHPUnit\Framework\MockObject\Rule\InvocationOrder::class,
6+
\PHPUnit\Framework\MockObject\Matcher\Invocation::class
7+
);
8+
}
9+
elseif (! interface_exists(\PHPUnit\Framework\MockObject\Matcher\Invocation::class)) {
410
class_alias(
511
\PHPUnit_Framework_MockObject_Matcher_Invocation::class,
612
\PHPUnit\Framework\MockObject\Matcher\Invocation::class
@@ -30,21 +36,30 @@ class_alias(
3036
);
3137
}
3238

39+
if (class_exists(\PHPUnit\Framework\MockObject\Rule\MethodName::class)) {
40+
class_alias(
41+
\PHPUnit\Framework\MockObject\Rule\MethodName::class,
42+
\PHPUnit\Framework\MockObject\Matcher\MethodName::class
43+
);
44+
}
45+
3346
if (! class_exists(\PHPUnit\Framework\MockObject\Matcher\MethodName::class)) {
3447
class_alias(
3548
\PHPUnit_Framework_MockObject_Matcher_MethodName::class,
3649
\PHPUnit\Framework\MockObject\Matcher\MethodName::class
3750
);
3851
}
3952

40-
if (! interface_exists(\PHPUnit\Framework\MockObject\Stub\MatcherCollection::class)) {
53+
if (!class_exists(\PHPUnit\Framework\MockObject\InvocationHandler::class)
54+
&& !interface_exists(\PHPUnit\Framework\MockObject\Stub\MatcherCollection::class)) {
4155
class_alias(
4256
\PHPUnit_Framework_MockObject_Stub_MatcherCollection::class,
4357
\PHPUnit\Framework\MockObject\Stub\MatcherCollection::class
4458
);
4559
}
4660

47-
if (! class_exists(\PHPUnit\Framework\MockObject\InvocationMocker::class)) {
61+
if (!class_exists(\PHPUnit\Framework\MockObject\InvocationHandler::class)
62+
&& !class_exists(\PHPUnit\Framework\MockObject\InvocationMocker::class)) {
4863
class_alias(
4964
\PHPUnit_Framework_MockObject_InvocationMocker::class,
5065
\PHPUnit\Framework\MockObject\InvocationMocker::class
@@ -65,6 +80,11 @@ class_alias(
6580
}
6681

6782
if (class_exists(\PHPUnit\Runner\Version::class)
83+
&& version_compare(\PHPUnit\Runner\Version::id(), '8.4.0') >= 0
84+
) {
85+
class_alias(\phpmock\phpunit\DefaultArgumentRemoverReturnTypes84::class, \phpmock\phpunit\DefaultArgumentRemover::class);
86+
class_alias(\phpmock\phpunit\MockObjectProxyReturnTypes84::class, \phpmock\phpunit\MockObjectProxy::class);
87+
} elseif (class_exists(\PHPUnit\Runner\Version::class)
6888
&& version_compare(\PHPUnit\Runner\Version::id(), '8.1.0') >= 0
6989
) {
7090
class_alias(\phpmock\phpunit\DefaultArgumentRemoverReturnTypes::class, \phpmock\phpunit\DefaultArgumentRemover::class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
namespace phpmock\phpunit;
4+
5+
use phpmock\generator\MockFunctionGenerator;
6+
use PHPUnit\Framework\MockObject\Invocation;
7+
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
8+
9+
/**
10+
* Removes default arguments from the invocation.
11+
*
12+
* @author Markus Malkusch <[email protected]>
13+
* @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
14+
* @license http://www.wtfpl.net/txt/copying/ WTFPL
15+
* @internal
16+
*/
17+
class DefaultArgumentRemoverReturnTypes84 extends InvocationOrder
18+
{
19+
/**
20+
* @SuppressWarnings(PHPMD)
21+
*/
22+
public function invokedDo(Invocation $invocation)
23+
{
24+
}
25+
26+
/**
27+
* @SuppressWarnings(PHPMD)
28+
*/
29+
public function matches(Invocation $invocation) : bool
30+
{
31+
$iClass = class_exists(Invocation::class);
32+
33+
if ($invocation instanceof Invocation\StaticInvocation
34+
|| $iClass
35+
) {
36+
$this->removeDefaultArguments(
37+
$invocation,
38+
$iClass ? Invocation::class : Invocation\StaticInvocation::class
39+
);
40+
} else {
41+
MockFunctionGenerator::removeDefaultArguments($invocation->parameters);
42+
}
43+
44+
return false;
45+
}
46+
47+
public function verify() : void
48+
{
49+
}
50+
51+
/**
52+
* This method is not defined in the interface, but used in
53+
* PHPUnit_Framework_MockObject_InvocationMocker::hasMatchers().
54+
*
55+
* @return boolean
56+
* @see \PHPUnit_Framework_MockObject_InvocationMocker::hasMatchers()
57+
*/
58+
public function hasMatchers()
59+
{
60+
return false;
61+
}
62+
63+
public function toString() : string
64+
{
65+
return __CLASS__;
66+
}
67+
68+
/**
69+
* Remove default arguments from StaticInvocation or its children (hack)
70+
*
71+
* @SuppressWarnings(PHPMD)
72+
*/
73+
private function removeDefaultArguments(Invocation $invocation, string $class)
74+
{
75+
$remover = function () {
76+
MockFunctionGenerator::removeDefaultArguments($this->parameters);
77+
};
78+
79+
$remover->bindTo($invocation, $class)();
80+
}
81+
}
+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
namespace phpmock\phpunit;
4+
5+
use PHPUnit\Framework\MockObject\Builder\InvocationMocker as BuilderInvocationMocker;
6+
use PHPUnit\Framework\MockObject\InvocationHandler;
7+
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
8+
use PHPUnit\Framework\MockObject\MockObject;
9+
use phpmock\integration\MockDelegateFunctionBuilder;
10+
11+
/**
12+
* Proxy for PHPUnit's PHPUnit_Framework_MockObject_MockObject.
13+
*
14+
* @author Markus Malkusch <[email protected]>
15+
* @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
16+
* @license http://www.wtfpl.net/txt/copying/ WTFPL
17+
* @internal
18+
*/
19+
class MockObjectProxyReturnTypes84 implements MockObject
20+
{
21+
22+
/**
23+
* @var MockObject $mockObject The mock object.
24+
*/
25+
private $mockObject;
26+
27+
/**
28+
* Inject the subject.
29+
*
30+
* @param MockObject $mockObject The subject.
31+
*/
32+
public function __construct(MockObject $mockObject)
33+
{
34+
$this->mockObject = $mockObject;
35+
}
36+
37+
/**
38+
* @SuppressWarnings(PHPMD)
39+
*/
40+
// @codingStandardsIgnoreStart
41+
public function __phpunit_getInvocationHandler(): InvocationHandler
42+
{
43+
return $this->mockObject->__phpunit_getInvocationHandler();
44+
}
45+
46+
/**
47+
* @SuppressWarnings(PHPMD)
48+
*/
49+
// @codingStandardsIgnoreStart
50+
public function __phpunit_setOriginalObject($originalObject) : void
51+
{
52+
// @codingStandardsIgnoreEnd
53+
$this->mockObject->__phpunit_setOriginalObject($originalObject);
54+
}
55+
56+
/**
57+
* @SuppressWarnings(PHPMD)
58+
*/
59+
// @codingStandardsIgnoreStart
60+
public function __phpunit_verify(bool $unsetInvocationMocker = true) : void
61+
{
62+
// @codingStandardsIgnoreEnd
63+
$this->mockObject->__phpunit_verify($unsetInvocationMocker);
64+
}
65+
66+
public function expects(InvocationOrder $matcher) : BuilderInvocationMocker
67+
{
68+
return $this->mockObject->expects($matcher)->method(MockDelegateFunctionBuilder::METHOD);
69+
}
70+
71+
/**
72+
* This method is not part of the contract but was found in
73+
* PHPUnit's mocked_class.tpl.dist.
74+
*
75+
* @SuppressWarnings(PHPMD)
76+
*/
77+
// @codingStandardsIgnoreStart
78+
public function __phpunit_hasMatchers() : bool
79+
{
80+
// @codingStandardsIgnoreEnd
81+
return $this->mockObject->__phpunit_hasMatchers();
82+
}
83+
84+
/**
85+
* @SuppressWarnings(PHPMD)
86+
*/
87+
// @codingStandardsIgnoreStart
88+
public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration) : void
89+
{
90+
// @codingStandardsIgnoreEnd
91+
$this->mockObject->__phpunit_setReturnValueGeneration($returnValueGeneration);
92+
}
93+
}

classes/PHPMock.php

+23-10
Original file line numberDiff line numberDiff line change
@@ -50,25 +50,38 @@ public function getFunctionMock($namespace, $name)
5050
{
5151
$delegateBuilder = new MockDelegateFunctionBuilder();
5252
$delegateBuilder->build($name);
53-
54-
$mock = $this->getMockBuilder($delegateBuilder->getFullyQualifiedClassName())->getMockForAbstractClass();
55-
56-
$mock->__phpunit_getInvocationMocker()->addMatcher(new DefaultArgumentRemover());
57-
53+
54+
$builder = $this->getMockBuilder($delegateBuilder->getFullyQualifiedClassName());
55+
if (is_callable([$builder, 'addMethods'])) {
56+
$builder->addMethods([$name]);
57+
}
58+
$mock = $builder->getMockForAbstractClass();
59+
$this->addMatcher($mock, $name);
60+
5861
$functionMockBuilder = new MockBuilder();
5962
$functionMockBuilder->setNamespace($namespace)
6063
->setName($name)
6164
->setFunctionProvider($mock);
62-
65+
6366
$functionMock = $functionMockBuilder->build();
6467
$functionMock->enable();
65-
68+
6669
$this->registerForTearDown($functionMock);
67-
70+
6871
$proxy = new MockObjectProxy($mock);
6972
return $proxy;
7073
}
71-
74+
75+
private function addMatcher($mock, $name)
76+
{
77+
if (is_callable([$mock, '__phpunit_getInvocationHandler'])) {
78+
$mocker = $mock->__phpunit_getInvocationHandler()->expects(new DefaultArgumentRemover());
79+
$mocker->method($name);
80+
return;
81+
}
82+
$mock->__phpunit_getInvocationMocker()->addMatcher(new DefaultArgumentRemover());
83+
}
84+
7285
/**
7386
* Automatically disable function mocks after the test was run.
7487
*
@@ -83,7 +96,7 @@ public function registerForTearDown(Deactivatable $deactivatable)
8396
$result = $this->getTestResultObject();
8497
$result->addListener(new MockDisabler($deactivatable));
8598
}
86-
99+
87100
/**
88101
* Defines the mocked function in the given namespace.
89102
*

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
},
2020
"require": {
2121
"php": ">=7",
22-
"phpunit/phpunit": "^6 || ^7 || ^8",
22+
"phpunit/phpunit": "8.4.x-dev",
2323
"php-mock/php-mock-integration": "^2"
2424
},
2525
"archive": {

0 commit comments

Comments
 (0)