From 77a2c354eff5ebfad39b683381cd9aeabb1893fb Mon Sep 17 00:00:00 2001
From: Markus Malkusch <markus@malkusch.de>
Date: Fri, 17 Feb 2017 22:41:23 +0100
Subject: [PATCH 01/55] Upgrade to PHPUnit-6

As PHPUnit-6 doesn't support PHP-5 I, have to drop that support here as
well. Therefore this commit requires a major release. Older PHPUnit
versions cannot be supported any more. Refer to version 1 if you need
support for PHP-5, PHPUnit-4 or PHPUnit-5.

See also: #14
---
 .travis.yml                   | 39 +----------------------------------
 classes/MockDisabler.php      | 10 +++++----
 composer.json                 |  9 +++-----
 tests/MockDisablerTest.php    |  3 ++-
 tests/MockObjectProxyTest.php |  3 ++-
 tests/PHPMockTest.php         |  3 ++-
 6 files changed, 16 insertions(+), 51 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 349d29e..10797dc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,29 +8,11 @@ cache:
 
 env:
   - PHPUNIT_VERSION=dev-master
-  - PHPUNIT_VERSION=~5.7.0
-  - PHPUNIT_VERSION=~5.6.0
-  - PHPUNIT_VERSION=~5.5.0
-  - PHPUNIT_VERSION=~5.4.0
-  - PHPUNIT_VERSION=~5.3.0
-  - PHPUNIT_VERSION=~5.2.0
-  - PHPUNIT_VERSION=~5.1.0
-  - PHPUNIT_VERSION=~5.0.0
-  - PHPUNIT_VERSION=~4.8.0
-  - PHPUNIT_VERSION=~4.7.0
-  - PHPUNIT_VERSION=~4.6.0
-  - PHPUNIT_VERSION=~4.5.0
-  - PHPUNIT_VERSION=~4.4.0
-  - PHPUNIT_VERSION=~4.3.0
-  - PHPUNIT_VERSION=~4.2.0
-  - PHPUNIT_VERSION=~4.1.0
-  - PHPUNIT_VERSION=~4.0.0
+  - PHPUNIT_VERSION=~6.0.0
 
 php:
   - 7.1
   - 7.0
-  - 5.6
-  - 5.5
   - hhvm
 
 matrix:
@@ -38,25 +20,6 @@ matrix:
   allow_failures:
     - php: hhvm
     - env: PHPUNIT_VERSION=dev-master
-  exclude:
-    - env: PHPUNIT_VERSION=~5.0.0
-      php: 5.5
-    - env: PHPUNIT_VERSION=~5.1.0
-      php: 5.5
-    - env: PHPUNIT_VERSION=~5.2.0
-      php: 5.5
-    - env: PHPUNIT_VERSION=~5.3.0
-      php: 5.5
-    - env: PHPUNIT_VERSION=~5.4.0
-      php: 5.5
-    - env: PHPUNIT_VERSION=~5.5.0
-      php: 5.5
-    - env: PHPUNIT_VERSION=~5.6.0
-      php: 5.5
-    - env: PHPUNIT_VERSION=~5.7.0
-      php: 5.5
-    - env: PHPUNIT_VERSION=dev-master
-      php: 5.5
 
 install:
   - composer require phpunit/phpunit:${PHPUNIT_VERSION}
diff --git a/classes/MockDisabler.php b/classes/MockDisabler.php
index 4cb88b8..2bac2aa 100644
--- a/classes/MockDisabler.php
+++ b/classes/MockDisabler.php
@@ -3,6 +3,8 @@
 namespace phpmock\phpunit;
 
 use phpmock\Deactivatable;
+use PHPUnit\Framework\BaseTestListener;
+use PHPUnit\Framework\Test;
 
 /**
  * Test listener for PHPUnit integration.
@@ -14,7 +16,7 @@
  * @license http://www.wtfpl.net/txt/copying/ WTFPL
  * @internal
  */
-class MockDisabler extends \PHPUnit_Framework_BaseTestListener
+class MockDisabler extends BaseTestListener
 {
 
     /**
@@ -35,12 +37,12 @@ public function __construct(Deactivatable $deactivatable)
     /**
      * Disables the function mocks.
      *
-     * @param \PHPUnit_Framework_Test $test The test.
-     * @param int                     $time The test duration.
+     * @param Test $test The test.
+     * @param int  $time The test duration.
      *
      * @see Mock::disable()
      */
-    public function endTest(\PHPUnit_Framework_Test $test, $time)
+    public function endTest(Test $test, $time)
     {
         parent::endTest($test, $time);
         
diff --git a/composer.json b/composer.json
index 9a1aa20..3739c14 100644
--- a/composer.json
+++ b/composer.json
@@ -17,14 +17,11 @@
         "psr-4": {"phpmock\\phpunit\\": "classes/"}
     },
     "require": {
-        "php": ">=5.5",
-        "phpunit/phpunit": "^4.0.0 || ^5.0.0",
-        "php-mock/php-mock-integration": "^1"
+        "php": ">=7",
+        "phpunit/phpunit": "^6",
+        "php-mock/php-mock-integration": "^2"
     },
     "archive": {
         "exclude": ["/tests"]
-    },
-    "conflict": {
-        "phpunit/phpunit-mock-objects": "3.2.0"
     }
 }
diff --git a/tests/MockDisablerTest.php b/tests/MockDisablerTest.php
index 03f6ccb..ba7a805 100644
--- a/tests/MockDisablerTest.php
+++ b/tests/MockDisablerTest.php
@@ -3,6 +3,7 @@
 namespace phpmock\phpunit;
 
 use phpmock\Mock;
+use PHPUnit\Framework\TestCase;
 
 /**
  * Tests MockDisabler.
@@ -12,7 +13,7 @@
  * @license http://www.wtfpl.net/txt/copying/ WTFPL
  * @see MockDisabler
  */
-class MockDisablerTest extends \PHPUnit_Framework_TestCase
+class MockDisablerTest extends TestCase
 {
 
     /**
diff --git a/tests/MockObjectProxyTest.php b/tests/MockObjectProxyTest.php
index 0652c05..d7de226 100644
--- a/tests/MockObjectProxyTest.php
+++ b/tests/MockObjectProxyTest.php
@@ -3,6 +3,7 @@
 namespace phpmock\phpunit;
 
 use \PHPUnit_Framework_MockObject_Builder_InvocationMocker as InvocationMocker;
+use PHPUnit\Framework\TestCase;
 use phpmock\integration\MockDelegateFunctionBuilder;
 
 /**
@@ -14,7 +15,7 @@
  * @see MockObjectProxy
  * @requires PHPUnit 4.5.0
  */
-class MockObjectProxyTest extends \PHPUnit_Framework_TestCase
+class MockObjectProxyTest extends TestCase
 {
 
     /**
diff --git a/tests/PHPMockTest.php b/tests/PHPMockTest.php
index dbd2d5a..88d7207 100644
--- a/tests/PHPMockTest.php
+++ b/tests/PHPMockTest.php
@@ -3,6 +3,7 @@
 namespace phpmock\phpunit;
 
 use phpmock\AbstractMockTest;
+use PHPUnit\Framework\ExpectationFailedException;
 
 /**
  * Tests PHPMock.
@@ -58,7 +59,7 @@ public function testFunctionMockFailsExpectation()
 
             $time->__phpunit_verify();
             $this->fail("Expectation should fail");
-        } catch (\PHPUnit_Framework_ExpectationFailedException $e) {
+        } catch (ExpectationFailedException $e) {
             time(); // satisfy the expectation
         }
     }

From 173781abdc632c59200253e12e2b991ae6a4574f Mon Sep 17 00:00:00 2001
From: Markus Malkusch <markus@malkusch.de>
Date: Fri, 17 Feb 2017 23:44:30 +0100
Subject: [PATCH 02/55] Update documentation to PHPUnit-6 API

---
 README.md           |  6 ++----
 classes/PHPMock.php | 20 +++++++++-----------
 2 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/README.md b/README.md
index cbd403c..74d273e 100644
--- a/README.md
+++ b/README.md
@@ -26,12 +26,10 @@ PHPUnit mock:
 
 namespace foo;
 
-use phpmock\phpunit\PHPMock;
-
-class BuiltinTest extends \PHPUnit_Framework_TestCase
+class BuiltinTest extends \PHPUnit\Framework\TestCase
 {
 
-    use PHPMock;
+    use \phpmock\phpunit\PHPMock;
 
     public function testTime()
     {
diff --git a/classes/PHPMock.php b/classes/PHPMock.php
index 0bfcee1..3746ad2 100644
--- a/classes/PHPMock.php
+++ b/classes/PHPMock.php
@@ -7,20 +7,18 @@
 use phpmock\Deactivatable;
 
 /**
- * Adds building a function mock functionality into PHPUnit_Framework_TestCase.
+ * Adds building a function mock functionality into \PHPUnit\Framework\TestCase.
  *
- * Use this trait in your PHPUnit_Framework_TestCase:
+ * Use this trait in your \PHPUnit\Framework\TestCase:
  * <code>
  * <?php
  *
  * namespace foo;
  *
- * use phpmock\phpunit\PHPMock;
- *
- * class FooTest extends \PHPUnit_Framework_TestCase
+ * class FooTest extends \PHPUnit\Framework\TestCase
  * {
  *
- *     use PHPMock;
+ *     use \phpmock\phpunit\PHPMock;
  *
  *     public function testBar()
  *     {
@@ -41,11 +39,11 @@ trait PHPMock
     /**
      * Returns a builder object to create mock objects using a fluent interface.
      *
-     * This method exists in PHPUnit_Framework_TestCase.
+     * This method exists in \PHPUnit\Framework\TestCase.
      *
      * @param string $className Name of the class to mock.
      * @return \PHPUnit_Framework_MockObject_MockBuilder
-     * @see \PHPUnit_Framework_TestCase::getMockBuilder()
+     * @see \PHPUnit\Framework\TestCase::getMockBuilder()
      * @internal
      */
     abstract protected function getMockBuilder($className);
@@ -53,10 +51,10 @@ abstract protected function getMockBuilder($className);
     /**
      * Returns the test result.
      *
-     * This method exists in PHPUnit_Framework_TestCase.
+     * This method exists in \PHPUnit\Framework\TestCase.
      *
-     * @return \PHPUnit_Framework_TestResult The test result.
-     * @see \PHPUnit_Framework_TestCase::getTestResultObject()
+     * @return \PHPUnit\Framework\TestResult The test result.
+     * @see \PHPUnit\Framework\TestCase::getTestResultObject()
      * @internal
      */
     abstract protected function getTestResultObject();

From 3d007767dc433acccae5bd581b8bc496037cafcd Mon Sep 17 00:00:00 2001
From: Markus Malkusch <markus@malkusch.de>
Date: Tue, 26 Sep 2017 09:07:00 +0200
Subject: [PATCH 03/55] Test up to PHPUnit-6.3

---
 .travis.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 10797dc..18b6467 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,6 +9,9 @@ cache:
 env:
   - PHPUNIT_VERSION=dev-master
   - PHPUNIT_VERSION=~6.0.0
+  - PHPUNIT_VERSION=~6.1.0
+  - PHPUNIT_VERSION=~6.2.0
+  - PHPUNIT_VERSION=~6.3.0
 
 php:
   - 7.1

From 9b52b603af9d5c16ecdff1d1a6447bd68d8e9bc3 Mon Sep 17 00:00:00 2001
From: Markus Malkusch <markus@malkusch.de>
Date: Fri, 13 Oct 2017 11:48:48 +0200
Subject: [PATCH 04/55] Test up to PHPUnit-6.4

---
 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index 18b6467..a207061 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,6 +12,7 @@ env:
   - PHPUNIT_VERSION=~6.1.0
   - PHPUNIT_VERSION=~6.2.0
   - PHPUNIT_VERSION=~6.3.0
+  - PHPUNIT_VERSION=~6.4.0
 
 php:
   - 7.1

From df3ac2f86e267b9cdf98661eb96508bdf3d9a215 Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Fri, 1 Dec 2017 22:48:17 +0000
Subject: [PATCH 05/55] Test against PHP 7.2

---
 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index a207061..11ef379 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,6 +15,7 @@ env:
   - PHPUNIT_VERSION=~6.4.0
 
 php:
+  - 7.2
   - 7.1
   - 7.0
   - hhvm

From b42fc41ecb7538564067527f6c30b8854f149d32 Mon Sep 17 00:00:00 2001
From: Markus Malkusch <markus@malkusch.de>
Date: Sat, 2 Dec 2017 10:49:02 +0100
Subject: [PATCH 06/55] Exclude PHPUnit-6.5

PHPUnit-6.5 did change the signature of TestCase::getMockBuilder() by
returning an object from phpunit-mock-object-5 instead of
phpunit-mock-object-4. This broke this library:

  PHP Fatal error: Interface 'PHPUnit_Framework_MockObject_Matcher_Invocation'
  not found in /.../vendor/php-mock/php-mock-phpunit/classes/DefaultArgumentRemover.php
  on line 15

This commit adds a <phpunit-6.5 constraint to fix the current release.
PHPUnit-6.5 is currently not supported by this library. I wait for
sebastianbergmann/phpunit#2893 to decide how to support PHPUnit-6.5.

See also: #21
See also: sebastianbergmann/phpunit#2893
---
 composer.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/composer.json b/composer.json
index 3739c14..bdb2f92 100644
--- a/composer.json
+++ b/composer.json
@@ -18,7 +18,7 @@
     },
     "require": {
         "php": ">=7",
-        "phpunit/phpunit": "^6",
+        "phpunit/phpunit": "^6 <6.5",
         "php-mock/php-mock-integration": "^2"
     },
     "archive": {

From 2de999a279fd9f557f7fc1dc119b298da1bd491b Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Thu, 22 Mar 2018 14:35:41 +0000
Subject: [PATCH 07/55] Added support for PHPUnit 6.5 and 7.0

---
 .travis.yml                                   |  9 +++-
 autoload.php                                  | 42 +++++++++++++++
 classes/DefaultArgumentRemover.php            | 31 +++++++++--
 ...kDisabler.php => MockDisablerPHPUnit6.php} |  2 +-
 classes/MockDisablerPHPUnit7.php              | 51 +++++++++++++++++++
 classes/MockObjectProxy.php                   |  5 +-
 classes/PHPMock.php                           | 27 +---------
 compatibility/BaseTestListener.php            | 13 +++++
 composer.json                                 |  3 +-
 tests/MockObjectProxyTest.php                 | 12 +++--
 10 files changed, 155 insertions(+), 40 deletions(-)
 create mode 100644 autoload.php
 rename classes/{MockDisabler.php => MockDisablerPHPUnit6.php} (95%)
 create mode 100644 classes/MockDisablerPHPUnit7.php
 create mode 100644 compatibility/BaseTestListener.php

diff --git a/.travis.yml b/.travis.yml
index 11ef379..3562af7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,15 +13,22 @@ env:
   - PHPUNIT_VERSION=~6.2.0
   - PHPUNIT_VERSION=~6.3.0
   - PHPUNIT_VERSION=~6.4.0
+  - PHPUNIT_VERSION=~6.5.0
+  - PHPUNIT_VERSION=~7.0.0
 
 php:
   - 7.2
   - 7.1
-  - 7.0
+  - 7
   - hhvm
 
 matrix:
   fast_finish: true
+  exclude:
+    - php: 7
+      env: PHPUNIT_VERSION=dev-master
+    - php: 7
+      env: PHPUNIT_VERSION=~7.0.0
   allow_failures:
     - php: hhvm
     - env: PHPUNIT_VERSION=dev-master
diff --git a/autoload.php b/autoload.php
new file mode 100644
index 0000000..06fc33b
--- /dev/null
+++ b/autoload.php
@@ -0,0 +1,42 @@
+<?php
+
+if (! interface_exists(\PHPUnit\Framework\MockObject\Matcher\Invocation::class)) {
+    class_alias(
+        \PHPUnit_Framework_MockObject_Matcher_Invocation::class,
+        \PHPUnit\Framework\MockObject\Matcher\Invocation::class
+    );
+}
+
+if (! interface_exists(\PHPUnit\Framework\MockObject\Invocation::class)) {
+    class_alias(
+        \PHPUnit_Framework_MockObject_Invocation::class,
+        \PHPUnit\Framework\MockObject\Invocation::class
+    );
+}
+
+if (! interface_exists(\PHPUnit\Framework\MockObject\MockObject::class)) {
+    class_alias(
+        \PHPUnit_Framework_MockObject_MockObject::class,
+        \PHPUnit\Framework\MockObject\MockObject::class
+    );
+}
+
+if (! class_exists(\PHPUnit\Framework\MockObject\Builder\InvocationMocker::class)) {
+    class_alias(
+        \PHPUnit_Framework_MockObject_Builder_InvocationMocker::class,
+        \PHPUnit\Framework\MockObject\Builder\InvocationMocker::class
+    );
+}
+
+if (! class_exists(\PHPUnit\Framework\BaseTestListener::class)) {
+    include __DIR__ . '/compatibility/BaseTestListener.php';
+    class_alias(
+        phpmock\phpunit\MockDisablerPHPUnit7::class,
+        phpmock\phpunit\MockDisabler::class
+    );
+} else {
+    class_alias(
+        phpmock\phpunit\MockDisablerPHPUnit6::class,
+        phpmock\phpunit\MockDisabler::class
+    );
+}
diff --git a/classes/DefaultArgumentRemover.php b/classes/DefaultArgumentRemover.php
index 1b0f15e..caf0751 100644
--- a/classes/DefaultArgumentRemover.php
+++ b/classes/DefaultArgumentRemover.php
@@ -3,6 +3,8 @@
 namespace phpmock\phpunit;
 
 use phpmock\generator\MockFunctionGenerator;
+use PHPUnit\Framework\MockObject\Invocation;
+use PHPUnit\Framework\MockObject\Matcher\Invocation as InvocationInterface;
 
 /**
  * Removes default arguments from the invocation.
@@ -12,22 +14,27 @@
  * @license http://www.wtfpl.net/txt/copying/ WTFPL
  * @internal
  */
-class DefaultArgumentRemover implements \PHPUnit_Framework_MockObject_Matcher_Invocation
+class DefaultArgumentRemover implements InvocationInterface
 {
 
     /**
      * @SuppressWarnings(PHPMD)
      */
-    public function invoked(\PHPUnit_Framework_MockObject_Invocation $invocation)
+    public function invoked(Invocation $invocation)
     {
     }
 
     /**
      * @SuppressWarnings(PHPMD)
      */
-    public function matches(\PHPUnit_Framework_MockObject_Invocation $invocation)
+    public function matches(Invocation $invocation)
     {
-        MockFunctionGenerator::removeDefaultArguments($invocation->parameters);
+        if ($invocation instanceof Invocation\StaticInvocation) {
+            $this->removeDefaultArguments($invocation);
+        } else {
+            MockFunctionGenerator::removeDefaultArguments($invocation->parameters);
+        }
+
         return false;
     }
 
@@ -47,8 +54,22 @@ public function hasMatchers()
         return false;
     }
 
-    public function toString()
+    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/MockDisabler.php b/classes/MockDisablerPHPUnit6.php
similarity index 95%
rename from classes/MockDisabler.php
rename to classes/MockDisablerPHPUnit6.php
index 2bac2aa..ed8ab10 100644
--- a/classes/MockDisabler.php
+++ b/classes/MockDisablerPHPUnit6.php
@@ -16,7 +16,7 @@
  * @license http://www.wtfpl.net/txt/copying/ WTFPL
  * @internal
  */
-class MockDisabler extends BaseTestListener
+class MockDisablerPHPUnit6 extends BaseTestListener
 {
 
     /**
diff --git a/classes/MockDisablerPHPUnit7.php b/classes/MockDisablerPHPUnit7.php
new file mode 100644
index 0000000..c2722f4
--- /dev/null
+++ b/classes/MockDisablerPHPUnit7.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace phpmock\phpunit;
+
+use phpmock\Deactivatable;
+use PHPUnit\Framework\BaseTestListener;
+use PHPUnit\Framework\Test;
+
+/**
+ * Test listener for PHPUnit integration.
+ *
+ * This class disables mock functions after a test was run.
+ *
+ * @author Markus Malkusch <markus@malkusch.de>
+ * @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
+ * @license http://www.wtfpl.net/txt/copying/ WTFPL
+ * @internal
+ */
+class MockDisablerPHPUnit7 extends BaseTestListener
+{
+
+    /**
+     * @var Deactivatable The function mocks.
+     */
+    private $deactivatable;
+    
+    /**
+     * Sets the function mocks.
+     *
+     * @param Deactivatable $deactivatable The function mocks.
+     */
+    public function __construct(Deactivatable $deactivatable)
+    {
+        $this->deactivatable = $deactivatable;
+    }
+    
+    /**
+     * Disables the function mocks.
+     *
+     * @param Test $test The test.
+     * @param int  $time The test duration.
+     *
+     * @see Mock::disable()
+     */
+    public function endTest(Test $test, float $time) : void
+    {
+        parent::endTest($test, $time);
+        
+        $this->deactivatable->disable();
+    }
+}
diff --git a/classes/MockObjectProxy.php b/classes/MockObjectProxy.php
index 4776822..0132be0 100644
--- a/classes/MockObjectProxy.php
+++ b/classes/MockObjectProxy.php
@@ -2,7 +2,8 @@
 
 namespace phpmock\phpunit;
 
-use PHPUnit_Framework_MockObject_MockObject as MockObject;
+use PHPUnit\Framework\MockObject\Matcher\Invocation;
+use PHPUnit\Framework\MockObject\MockObject;
 use phpmock\integration\MockDelegateFunctionBuilder;
 
 /**
@@ -61,7 +62,7 @@ public function __phpunit_verify()
         return $this->mockObject->__phpunit_verify();
     }
 
-    public function expects(\PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+    public function expects(Invocation $matcher)
     {
         return $this->mockObject->expects($matcher)->method(MockDelegateFunctionBuilder::METHOD);
     }
diff --git a/classes/PHPMock.php b/classes/PHPMock.php
index 3746ad2..603fbc6 100644
--- a/classes/PHPMock.php
+++ b/classes/PHPMock.php
@@ -5,6 +5,7 @@
 use phpmock\integration\MockDelegateFunctionBuilder;
 use phpmock\MockBuilder;
 use phpmock\Deactivatable;
+use PHPUnit\Framework\MockObject\MockObject;
 
 /**
  * Adds building a function mock functionality into \PHPUnit\Framework\TestCase.
@@ -35,30 +36,6 @@
  */
 trait PHPMock
 {
-
-    /**
-     * Returns a builder object to create mock objects using a fluent interface.
-     *
-     * This method exists in \PHPUnit\Framework\TestCase.
-     *
-     * @param string $className Name of the class to mock.
-     * @return \PHPUnit_Framework_MockObject_MockBuilder
-     * @see \PHPUnit\Framework\TestCase::getMockBuilder()
-     * @internal
-     */
-    abstract protected function getMockBuilder($className);
-
-    /**
-     * Returns the test result.
-     *
-     * This method exists in \PHPUnit\Framework\TestCase.
-     *
-     * @return \PHPUnit\Framework\TestResult The test result.
-     * @see \PHPUnit\Framework\TestCase::getTestResultObject()
-     * @internal
-     */
-    abstract protected function getTestResultObject();
-
     /**
      * Returns the enabled function mock.
      *
@@ -67,7 +44,7 @@ abstract protected function getTestResultObject();
      * @param string $namespace The function namespace.
      * @param string $name      The function name.
      *
-     * @return \PHPUnit_Framework_MockObject_MockObject The PHPUnit mock.
+     * @return MockObject The PHPUnit mock.
      */
     public function getFunctionMock($namespace, $name)
     {
diff --git a/compatibility/BaseTestListener.php b/compatibility/BaseTestListener.php
new file mode 100644
index 0000000..1ddd1a9
--- /dev/null
+++ b/compatibility/BaseTestListener.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace PHPUnit\Framework;
+
+/**
+ * Compatibility class to work with PHPUnit 7
+ *
+ * @internal
+ */
+abstract class BaseTestListener implements TestListener
+{
+    use TestListenerDefaultImplementation;
+}
diff --git a/composer.json b/composer.json
index bdb2f92..5a93b9d 100644
--- a/composer.json
+++ b/composer.json
@@ -14,11 +14,12 @@
         }
     ],
     "autoload": {
+        "files": ["autoload.php"],
         "psr-4": {"phpmock\\phpunit\\": "classes/"}
     },
     "require": {
         "php": ">=7",
-        "phpunit/phpunit": "^6 <6.5",
+        "phpunit/phpunit": "^6 || ^7",
         "php-mock/php-mock-integration": "^2"
     },
     "archive": {
diff --git a/tests/MockObjectProxyTest.php b/tests/MockObjectProxyTest.php
index d7de226..950005b 100644
--- a/tests/MockObjectProxyTest.php
+++ b/tests/MockObjectProxyTest.php
@@ -2,9 +2,11 @@
 
 namespace phpmock\phpunit;
 
-use \PHPUnit_Framework_MockObject_Builder_InvocationMocker as InvocationMocker;
 use PHPUnit\Framework\TestCase;
 use phpmock\integration\MockDelegateFunctionBuilder;
+use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
+use PHPUnit\Framework\MockObject\Matcher\Invocation;
+use PHPUnit\Framework\MockObject\MockObject;
 
 /**
  * Tests MockObjectProxyTest.
@@ -25,13 +27,13 @@ class MockObjectProxyTest extends TestCase
      */
     public function testExpects()
     {
-        $matcher = $this->getMockBuilder(\PHPUnit_Framework_MockObject_Matcher_Invocation::class)->getMock();
+        $matcher = $this->getMockBuilder(Invocation::class)->getMock();
 
         $invocationMocker = $this->getMockBuilder(InvocationMocker::class)->disableOriginalConstructor()->getMock();
         $invocationMocker->expects($this->once())->method("method")
                 ->with(MockDelegateFunctionBuilder::METHOD)->willReturn($invocationMocker);
 
-        $prophecy = $this->prophesize(\PHPUnit_Framework_MockObject_MockObject::class);
+        $prophecy = $this->prophesize(MockObject::class);
         $prophecy->expects($matcher)->willReturn($invocationMocker);
         $mock = $prophecy->reveal();
 
@@ -53,7 +55,7 @@ public function testExpects()
      */
     public function testHasMatcher()
     {
-        $prophecy = $this->prophesize(\PHPUnit_Framework_MockObject_MockObject::class);
+        $prophecy = $this->prophesize(MockObject::class);
         $prophecy->__phpunit_hasMatchers()->willReturn("foo");
         $mock = $prophecy->reveal();
 
@@ -74,7 +76,7 @@ public function testHasMatcher()
      */
     public function testProxiedMethods($method, array $arguments = [], $expected = "foo")
     {
-        $prophecy = $this->prophesize(\PHPUnit_Framework_MockObject_MockObject::class);
+        $prophecy = $this->prophesize(MockObject::class);
         call_user_func_array([$prophecy, $method], $arguments)->willReturn($expected);
         $mock = $prophecy->reveal();
 

From 50107e7d42ffd374fb777c78f216bb6fd7cab13d Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Fri, 6 Apr 2018 14:32:36 +0100
Subject: [PATCH 08/55] Added PHPUnit 7.1 support

---
 .travis.yml                 |  3 +++
 classes/MockObjectProxy.php | 10 ++++++++++
 2 files changed, 13 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 3562af7..e9b9799 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,6 +15,7 @@ env:
   - PHPUNIT_VERSION=~6.4.0
   - PHPUNIT_VERSION=~6.5.0
   - PHPUNIT_VERSION=~7.0.0
+  - PHPUNIT_VERSION=~7.1.0
 
 php:
   - 7.2
@@ -27,6 +28,8 @@ matrix:
   exclude:
     - php: 7
       env: PHPUNIT_VERSION=dev-master
+    - php: 7
+      env: PHPUNIT_VERSION=~7.1.0
     - php: 7
       env: PHPUNIT_VERSION=~7.0.0
   allow_failures:
diff --git a/classes/MockObjectProxy.php b/classes/MockObjectProxy.php
index 0132be0..7fd9ccc 100644
--- a/classes/MockObjectProxy.php
+++ b/classes/MockObjectProxy.php
@@ -79,4 +79,14 @@ public function __phpunit_hasMatchers()
         // @codingStandardsIgnoreEnd
         return $this->mockObject->__phpunit_hasMatchers();
     }
+
+    /**
+     * @SuppressWarnings(PHPMD)
+     */
+    // @codingStandardsIgnoreStart
+    public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration)
+    {
+        // @codingStandardsIgnoreEnd
+        return $this->mockObject->__phpunit_setReturnValueGeneration($returnValueGeneration);
+    }
 }

From f33361db261f92b52eceffba0f95e35caaea917c Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Mon, 4 Jun 2018 14:34:18 +0100
Subject: [PATCH 09/55] Added PHPUnit 7.2 to Travis CI configuration

---
 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index e9b9799..4d44aab 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,6 +16,7 @@ env:
   - PHPUNIT_VERSION=~6.5.0
   - PHPUNIT_VERSION=~7.0.0
   - PHPUNIT_VERSION=~7.1.0
+  - PHPUNIT_VERSION=~7.2.0
 
 php:
   - 7.2

From 3258a20324a974d9d637abe816830f7ce0f9c640 Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Mon, 4 Jun 2018 14:44:30 +0100
Subject: [PATCH 10/55] Disabled PHPUnit 7.2 on PHP 7

---
 .travis.yml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 4d44aab..3da1269 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -29,6 +29,8 @@ matrix:
   exclude:
     - php: 7
       env: PHPUNIT_VERSION=dev-master
+    - php: 7
+      env: PHPUNIT_VERSION=~7.2.0
     - php: 7
       env: PHPUNIT_VERSION=~7.1.0
     - php: 7

From 92d32f47aa52e45de1cbef68a3363466eca32b3b Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Mon, 20 Aug 2018 10:53:00 +0100
Subject: [PATCH 11/55] Added PHPUnit 7.3 to Travis CI configuration

---
 .travis.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 3da1269..674311c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,6 +17,7 @@ env:
   - PHPUNIT_VERSION=~7.0.0
   - PHPUNIT_VERSION=~7.1.0
   - PHPUNIT_VERSION=~7.2.0
+  - PHPUNIT_VERSION=~7.3.0
 
 php:
   - 7.2
@@ -29,6 +30,8 @@ matrix:
   exclude:
     - php: 7
       env: PHPUNIT_VERSION=dev-master
+    - php: 7
+      env: PHPUNIT_VERSION=~7.3.0
     - php: 7
       env: PHPUNIT_VERSION=~7.2.0
     - php: 7

From 0aa59dfa8066d0680a67916e3df2407f0bda3453 Mon Sep 17 00:00:00 2001
From: Chris Minett <chris@minett.me.uk>
Date: Fri, 5 Oct 2018 15:29:56 +0100
Subject: [PATCH 12/55] Add PHPUnit 7.4 to Travis config

---
 .travis.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 674311c..dcf09aa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,6 +18,7 @@ env:
   - PHPUNIT_VERSION=~7.1.0
   - PHPUNIT_VERSION=~7.2.0
   - PHPUNIT_VERSION=~7.3.0
+  - PHPUNIT_VERSION=~7.4.0
 
 php:
   - 7.2
@@ -30,6 +31,8 @@ matrix:
   exclude:
     - php: 7
       env: PHPUNIT_VERSION=dev-master
+    - php: 7
+      env: PHPUNIT_VERSION=~7.4.0
     - php: 7
       env: PHPUNIT_VERSION=~7.3.0
     - php: 7

From e98c3f5cccc19e181af16c08555374ecf1278098 Mon Sep 17 00:00:00 2001
From: Chris Minett <chris@minett.me.uk>
Date: Fri, 5 Oct 2018 15:24:55 +0100
Subject: [PATCH 13/55] Update __phpunit_verify() method signature for PHPUnit
 7.4

PHPUnit 7.4 has added a parameter to the public interface which breaks implementation compatibility when missing.
It does not affect PHPUnit <7.3 when having the parameter in the implementation but not the interface.
---
 classes/MockObjectProxy.php   | 4 ++--
 tests/MockObjectProxyTest.php | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/classes/MockObjectProxy.php b/classes/MockObjectProxy.php
index 7fd9ccc..21550de 100644
--- a/classes/MockObjectProxy.php
+++ b/classes/MockObjectProxy.php
@@ -56,10 +56,10 @@ public function __phpunit_setOriginalObject($originalObject)
      * @SuppressWarnings(PHPMD)
      */
     // @codingStandardsIgnoreStart
-    public function __phpunit_verify()
+    public function __phpunit_verify(bool $unsetInvocationMocker = true)
     {
         // @codingStandardsIgnoreEnd
-        return $this->mockObject->__phpunit_verify();
+        return $this->mockObject->__phpunit_verify($unsetInvocationMocker);
     }
 
     public function expects(Invocation $matcher)
diff --git a/tests/MockObjectProxyTest.php b/tests/MockObjectProxyTest.php
index 950005b..5587d0f 100644
--- a/tests/MockObjectProxyTest.php
+++ b/tests/MockObjectProxyTest.php
@@ -96,7 +96,7 @@ public function provideTestProxiedMethods()
         return [
             ["__phpunit_getInvocationMocker"],
             ["__phpunit_setOriginalObject", ["bar"]],
-            ["__phpunit_verify"],
+            ["__phpunit_verify", [true]],
         ];
     }
 }

From c11139a936b80d193eb1c27c60777c9db4774137 Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Mon, 15 Oct 2018 11:07:15 +0100
Subject: [PATCH 14/55] Test against PHP 7.3

---
 .travis.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index dcf09aa..c8b6287 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -21,6 +21,7 @@ env:
   - PHPUNIT_VERSION=~7.4.0
 
 php:
+  - 7.3
   - 7.2
   - 7.1
   - 7
@@ -54,4 +55,3 @@ script:
   - vendor/bin/phpunit
   - vendor/bin/phpcs --standard=PSR2 classes/ tests/
   - vendor/bin/phpmd classes/ text cleancode,codesize,controversial,design,naming,unusedcode
-

From a728a0e30a40f2d153a9b19c5a3e5f6771781e1a Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Sat, 2 Feb 2019 00:22:21 +0000
Subject: [PATCH 15/55] Added PHPUnit 8 support

---
 .travis.yml | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index c8b6287..4da042a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,6 +19,8 @@ env:
   - PHPUNIT_VERSION=~7.2.0
   - PHPUNIT_VERSION=~7.3.0
   - PHPUNIT_VERSION=~7.4.0
+  - PHPUNIT_VERSION=~7.5.0
+  - PHPUNIT_VERSION=~8.0.0
 
 php:
   - 7.3
@@ -30,8 +32,16 @@ php:
 matrix:
   fast_finish: true
   exclude:
+    - php: 7.1
+      env: PHPUNIT_VERSION=dev-master
+    - php: 7.1
+      env: PHPUNIT_VERSION=~8.0.0
     - php: 7
       env: PHPUNIT_VERSION=dev-master
+    - php: 7
+      env: PHPUNIT_VERSION=~8.0.0
+    - php: 7
+      env: PHPUNIT_VERSION=~7.5.0
     - php: 7
       env: PHPUNIT_VERSION=~7.4.0
     - php: 7

From bb84d59cf54a204f6c17f925d60a6b8c5505c14c Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Mon, 4 Mar 2019 21:16:32 +0000
Subject: [PATCH 16/55] Updated composer.json to allow PHPUnit 8

---
 composer.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/composer.json b/composer.json
index 5a93b9d..cfc2c6a 100644
--- a/composer.json
+++ b/composer.json
@@ -19,7 +19,7 @@
     },
     "require": {
         "php": ">=7",
-        "phpunit/phpunit": "^6 || ^7",
+        "phpunit/phpunit": "^6 || ^7 || ^8",
         "php-mock/php-mock-integration": "^2"
     },
     "archive": {

From 16e630cdd601792235cc09134143f596757f9227 Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Mon, 4 Mar 2019 21:17:20 +0000
Subject: [PATCH 17/55] Updated tests to work with PHPUnit 8

InvocationMocker is marked as final and cannot be mocked anymore.
---
 autoload.php                  | 14 ++++++++++++++
 tests/MockObjectProxyTest.php | 15 ++++++++++++---
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/autoload.php b/autoload.php
index 06fc33b..67c8e93 100644
--- a/autoload.php
+++ b/autoload.php
@@ -28,6 +28,20 @@ class_alias(
     );
 }
 
+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)) {
+    class_alias(
+        \PHPUnit_Framework_MockObject_Stub_MatcherCollection::class,
+        \PHPUnit\Framework\MockObject\Stub\MatcherCollection::class
+    );
+}
+
 if (! class_exists(\PHPUnit\Framework\BaseTestListener::class)) {
     include __DIR__ . '/compatibility/BaseTestListener.php';
     class_alias(
diff --git a/tests/MockObjectProxyTest.php b/tests/MockObjectProxyTest.php
index 5587d0f..ad4a0f3 100644
--- a/tests/MockObjectProxyTest.php
+++ b/tests/MockObjectProxyTest.php
@@ -2,6 +2,8 @@
 
 namespace phpmock\phpunit;
 
+use PHPUnit\Framework\MockObject\Matcher\MethodName;
+use PHPUnit\Framework\MockObject\Stub\MatcherCollection;
 use PHPUnit\Framework\TestCase;
 use phpmock\integration\MockDelegateFunctionBuilder;
 use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
@@ -29,9 +31,11 @@ public function testExpects()
     {
         $matcher = $this->getMockBuilder(Invocation::class)->getMock();
 
-        $invocationMocker = $this->getMockBuilder(InvocationMocker::class)->disableOriginalConstructor()->getMock();
-        $invocationMocker->expects($this->once())->method("method")
-                ->with(MockDelegateFunctionBuilder::METHOD)->willReturn($invocationMocker);
+        $invocationMocker = new InvocationMocker(
+            $this->prophesize(MatcherCollection::class)->reveal(),
+            $this->prophesize(Invocation::class)->reveal(),
+            [MockDelegateFunctionBuilder::METHOD]
+        );
 
         $prophecy = $this->prophesize(MockObject::class);
         $prophecy->expects($matcher)->willReturn($invocationMocker);
@@ -41,6 +45,11 @@ public function testExpects()
 
         $result = $proxy->expects($matcher);
         $this->assertEquals($invocationMocker, $result);
+
+        $this->assertSame(
+            (new MethodName(MockDelegateFunctionBuilder::METHOD))->toString(),
+            ($invocationMocker->getMatcher()->methodNameMatcher ?? $invocationMocker->getMatcher()->getMethodNameMatcher())->toString()
+        );
     }
 
     /**

From a25b10bf265bc10bc0a3c9e76b4346d85b4a5bdd Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Mon, 4 Mar 2019 21:29:33 +0000
Subject: [PATCH 18/55] CS fix - wrap long lines

---
 tests/MockObjectProxyTest.php | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/MockObjectProxyTest.php b/tests/MockObjectProxyTest.php
index ad4a0f3..8f28d1c 100644
--- a/tests/MockObjectProxyTest.php
+++ b/tests/MockObjectProxyTest.php
@@ -48,7 +48,8 @@ public function testExpects()
 
         $this->assertSame(
             (new MethodName(MockDelegateFunctionBuilder::METHOD))->toString(),
-            ($invocationMocker->getMatcher()->methodNameMatcher ?? $invocationMocker->getMatcher()->getMethodNameMatcher())->toString()
+            ($invocationMocker->getMatcher()->methodNameMatcher
+                ?? $invocationMocker->getMatcher()->getMethodNameMatcher())->toString()
         );
     }
 

From e49762cd80d69049de4dfee5bdf4e86c227a3661 Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Fri, 5 Apr 2019 23:21:31 +0100
Subject: [PATCH 19/55] 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 @@
+<?php
+
+namespace phpmock\phpunit;
+
+use phpmock\generator\MockFunctionGenerator;
+use PHPUnit\Framework\MockObject\Invocation;
+use PHPUnit\Framework\MockObject\Matcher\Invocation as InvocationInterface;
+
+/**
+ * Removes default arguments from the invocation.
+ *
+ * @author Markus Malkusch <markus@malkusch.de>
+ * @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 @@
+<?php
+
+namespace phpmock\phpunit;
+
+use PHPUnit\Framework\MockObject\Builder\InvocationMocker as BuilderInvocationMocker;
+use PHPUnit\Framework\MockObject\InvocationMocker;
+use PHPUnit\Framework\MockObject\Matcher\Invocation;
+use PHPUnit\Framework\MockObject\MockObject;
+use phpmock\integration\MockDelegateFunctionBuilder;
+
+/**
+ * Proxy for PHPUnit's PHPUnit_Framework_MockObject_MockObject.
+ *
+ * @author Markus Malkusch <markus@malkusch.de>
+ * @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 <contact@webimpress.com>
Date: Fri, 5 Apr 2019 23:28:50 +0100
Subject: [PATCH 20/55] 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(

From 1b30d6e6a66ab55562d4229501c44549c6f233db Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Fri, 7 Jun 2019 10:44:56 +0100
Subject: [PATCH 21/55] Updated Travis CI configuration

Runs tests against PHPUnit 8.2
Adds PHP 7.4-snapshot
Removes HHVM support
---
 .travis.yml | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index f0d9d8e..9ccc839 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,25 +22,30 @@ env:
   - PHPUNIT_VERSION=~7.5.0
   - PHPUNIT_VERSION=~8.0.0
   - PHPUNIT_VERSION=~8.1.0
+  - PHPUNIT_VERSION=~8.2.0
 
 php:
+  - 7.4-snapshot
   - 7.3
   - 7.2
   - 7.1
   - 7
-  - hhvm
 
 matrix:
   fast_finish: true
   exclude:
     - php: 7.1
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.1
+      env: PHPUNIT_VERSION=~8.2.0
     - 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.2.0
     - php: 7
       env: PHPUNIT_VERSION=~8.1.0
     - php: 7
@@ -58,7 +63,7 @@ matrix:
     - php: 7
       env: PHPUNIT_VERSION=~7.0.0
   allow_failures:
-    - php: hhvm
+    - php: 7.4-snapshot
     - env: PHPUNIT_VERSION=dev-master
 
 install:

From f9f3d9dd5220ceae39eb7c37cad9c61638845b46 Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Fri, 7 Jun 2019 12:29:55 +0100
Subject: [PATCH 22/55] Fixes PHPUnit 8.2 compatibility

---
 autoload.php                                  |  4 +++-
 classes/DefaultArgumentRemoverReturnTypes.php | 15 +++++++++++----
 tests/MockObjectProxyTest.php                 | 17 +++++++++++++----
 3 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/autoload.php b/autoload.php
index 9de6a88..72867bb 100644
--- a/autoload.php
+++ b/autoload.php
@@ -7,7 +7,9 @@ class_alias(
     );
 }
 
-if (! interface_exists(\PHPUnit\Framework\MockObject\Invocation::class)) {
+if (! interface_exists(\PHPUnit\Framework\MockObject\Invocation::class)
+    && interface_exists(\PHPUnit\Framework\MockObject\Invocation::class)
+) {
     class_alias(
         \PHPUnit_Framework_MockObject_Invocation::class,
         \PHPUnit\Framework\MockObject\Invocation::class
diff --git a/classes/DefaultArgumentRemoverReturnTypes.php b/classes/DefaultArgumentRemoverReturnTypes.php
index 1a8adf5..bfdadfe 100644
--- a/classes/DefaultArgumentRemoverReturnTypes.php
+++ b/classes/DefaultArgumentRemoverReturnTypes.php
@@ -29,8 +29,15 @@ public function invoked(Invocation $invocation)
      */
     public function matches(Invocation $invocation) : bool
     {
-        if ($invocation instanceof Invocation\StaticInvocation) {
-            $this->removeDefaultArguments($invocation);
+        $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);
         }
@@ -64,12 +71,12 @@ public function toString() : string
      *
      * @SuppressWarnings(PHPMD)
      */
-    private function removeDefaultArguments(Invocation\StaticInvocation $invocation)
+    private function removeDefaultArguments(Invocation $invocation, string $class)
     {
         $remover = function () {
             MockFunctionGenerator::removeDefaultArguments($this->parameters);
         };
 
-        $remover->bindTo($invocation, Invocation\StaticInvocation::class)();
+        $remover->bindTo($invocation, $class)();
     }
 }
diff --git a/tests/MockObjectProxyTest.php b/tests/MockObjectProxyTest.php
index 317b763..244ab67 100644
--- a/tests/MockObjectProxyTest.php
+++ b/tests/MockObjectProxyTest.php
@@ -2,13 +2,15 @@
 
 namespace phpmock\phpunit;
 
-use PHPUnit\Framework\MockObject\Matcher\MethodName;
-use PHPUnit\Framework\MockObject\Stub\MatcherCollection;
-use PHPUnit\Framework\TestCase;
 use phpmock\integration\MockDelegateFunctionBuilder;
 use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
+use PHPUnit\Framework\MockObject\ConfigurableMethod;
 use PHPUnit\Framework\MockObject\Matcher\Invocation;
+use PHPUnit\Framework\MockObject\Matcher\MethodName;
 use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\Stub\MatcherCollection;
+use PHPUnit\Framework\TestCase;
+use SebastianBergmann\Type\Type;
 
 /**
  * Tests MockObjectProxyTest.
@@ -31,10 +33,17 @@ public function testExpects()
     {
         $matcher = $this->getMockBuilder(Invocation::class)->getMock();
 
+        $methods = class_exists(ConfigurableMethod::class)
+            ? new ConfigurableMethod(
+                MockDelegateFunctionBuilder::METHOD,
+                $this->prophesize(Type::class)->reveal()
+            )
+            : [MockDelegateFunctionBuilder::METHOD];
+
         $invocationMocker = new InvocationMocker(
             $this->prophesize(MatcherCollection::class)->reveal(),
             $this->prophesize(Invocation::class)->reveal(),
-            [MockDelegateFunctionBuilder::METHOD]
+            $methods
         );
 
         $prophecy = $this->prophesize(MockObject::class);

From 7f6e19a99e4f5fe8513f7ed947b9f3da787bf55e Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Fri, 7 Jun 2019 12:31:51 +0100
Subject: [PATCH 23/55] Fixes Travis CI configuration

- reorder PHPUnit versions that we run the latests first
- 7.4snapshot instead of 7.4-snapshot
---
 .travis.yml | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 9ccc839..0f53079 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,24 +8,24 @@ cache:
 
 env:
   - PHPUNIT_VERSION=dev-master
-  - PHPUNIT_VERSION=~6.0.0
-  - PHPUNIT_VERSION=~6.1.0
-  - PHPUNIT_VERSION=~6.2.0
-  - PHPUNIT_VERSION=~6.3.0
-  - PHPUNIT_VERSION=~6.4.0
-  - PHPUNIT_VERSION=~6.5.0
-  - PHPUNIT_VERSION=~7.0.0
-  - PHPUNIT_VERSION=~7.1.0
-  - PHPUNIT_VERSION=~7.2.0
-  - PHPUNIT_VERSION=~7.3.0
-  - PHPUNIT_VERSION=~7.4.0
-  - PHPUNIT_VERSION=~7.5.0
-  - PHPUNIT_VERSION=~8.0.0
-  - PHPUNIT_VERSION=~8.1.0
   - PHPUNIT_VERSION=~8.2.0
+  - PHPUNIT_VERSION=~8.1.0
+  - PHPUNIT_VERSION=~8.0.0
+  - PHPUNIT_VERSION=~7.5.0
+  - PHPUNIT_VERSION=~7.4.0
+  - PHPUNIT_VERSION=~7.3.0
+  - PHPUNIT_VERSION=~7.2.0
+  - PHPUNIT_VERSION=~7.1.0
+  - PHPUNIT_VERSION=~7.0.0
+  - PHPUNIT_VERSION=~6.5.0
+  - PHPUNIT_VERSION=~6.4.0
+  - PHPUNIT_VERSION=~6.3.0
+  - PHPUNIT_VERSION=~6.2.0
+  - PHPUNIT_VERSION=~6.1.0
+  - PHPUNIT_VERSION=~6.0.0
 
 php:
-  - 7.4-snapshot
+  - 7.4snapshot
   - 7.3
   - 7.2
   - 7.1
@@ -63,7 +63,7 @@ matrix:
     - php: 7
       env: PHPUNIT_VERSION=~7.0.0
   allow_failures:
-    - php: 7.4-snapshot
+    - php: 7.4snapshot
     - env: PHPUNIT_VERSION=dev-master
 
 install:

From 8ef45f319edd6b9c268b5857e0c12f219e333dbb Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Fri, 7 Jun 2019 13:00:37 +0100
Subject: [PATCH 24/55] Fixed typo in autoloader

---
 autoload.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/autoload.php b/autoload.php
index 72867bb..5eb1a7e 100644
--- a/autoload.php
+++ b/autoload.php
@@ -8,7 +8,7 @@ class_alias(
 }
 
 if (! interface_exists(\PHPUnit\Framework\MockObject\Invocation::class)
-    && interface_exists(\PHPUnit\Framework\MockObject\Invocation::class)
+    && interface_exists(\PHPUnit_Framework_MockObject_Invocation::class)
 ) {
     class_alias(
         \PHPUnit_Framework_MockObject_Invocation::class,

From 07a05d4399fc4ae7ca2d6fca4faae791282e15ef Mon Sep 17 00:00:00 2001
From: Matthew Peveler <matt.peveler@gmail.com>
Date: Sat, 5 Oct 2019 12:20:27 -0300
Subject: [PATCH 25/55] Fixes PHPUnit 8.4 compatibility

---
 .gitignore                                    |  3 +
 .travis.yml                                   | 10 ++
 autoload.php                                  | 26 +++++-
 .../DefaultArgumentRemoverReturnTypes84.php   | 81 ++++++++++++++++
 classes/MockObjectProxyReturnTypes84.php      | 93 +++++++++++++++++++
 classes/PHPMock.php                           | 33 +++++--
 composer.json                                 |  2 +-
 tests/MockObjectProxyTest.php                 | 59 +++++++++---
 tests/PHPMockTest.php                         | 12 +--
 9 files changed, 287 insertions(+), 32 deletions(-)
 create mode 100644 .gitignore
 create mode 100644 classes/DefaultArgumentRemoverReturnTypes84.php
 create mode 100644 classes/MockObjectProxyReturnTypes84.php

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1816ab1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.phpunit.result.cache
+vendor/
+composer.lock
diff --git a/.travis.yml b/.travis.yml
index 0f53079..9386e57 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -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
@@ -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
@@ -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
diff --git a/autoload.php b/autoload.php
index 5eb1a7e..a560fc1 100644
--- a/autoload.php
+++ b/autoload.php
@@ -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
@@ -30,6 +36,13 @@ 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,
@@ -37,14 +50,16 @@ class_alias(
     );
 }
 
-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
@@ -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);
diff --git a/classes/DefaultArgumentRemoverReturnTypes84.php b/classes/DefaultArgumentRemoverReturnTypes84.php
new file mode 100644
index 0000000..6b5c6cf
--- /dev/null
+++ b/classes/DefaultArgumentRemoverReturnTypes84.php
@@ -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 <markus@malkusch.de>
+ * @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)();
+    }
+}
diff --git a/classes/MockObjectProxyReturnTypes84.php b/classes/MockObjectProxyReturnTypes84.php
new file mode 100644
index 0000000..9cbc51f
--- /dev/null
+++ b/classes/MockObjectProxyReturnTypes84.php
@@ -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 <markus@malkusch.de>
+ * @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);
+    }
+}
diff --git a/classes/PHPMock.php b/classes/PHPMock.php
index 603fbc6..9adbfd1 100644
--- a/classes/PHPMock.php
+++ b/classes/PHPMock.php
@@ -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.
      *
@@ -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.
      *
diff --git a/composer.json b/composer.json
index cfc2c6a..55cf224 100644
--- a/composer.json
+++ b/composer.json
@@ -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": {
diff --git a/tests/MockObjectProxyTest.php b/tests/MockObjectProxyTest.php
index 244ab67..41ace7e 100644
--- a/tests/MockObjectProxyTest.php
+++ b/tests/MockObjectProxyTest.php
@@ -5,6 +5,7 @@
 use phpmock\integration\MockDelegateFunctionBuilder;
 use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
 use PHPUnit\Framework\MockObject\ConfigurableMethod;
+use PHPUnit\Framework\MockObject\InvocationHandler;
 use PHPUnit\Framework\MockObject\Matcher\Invocation;
 use PHPUnit\Framework\MockObject\Matcher\MethodName;
 use PHPUnit\Framework\MockObject\MockObject;
@@ -40,11 +41,18 @@ public function testExpects()
             )
             : [MockDelegateFunctionBuilder::METHOD];
 
-        $invocationMocker = new InvocationMocker(
-            $this->prophesize(MatcherCollection::class)->reveal(),
-            $this->prophesize(Invocation::class)->reveal(),
-            $methods
-        );
+        if (class_exists(\PHPUnit\Runner\Version::class)
+            && version_compare(\PHPUnit\Runner\Version::id(), '8.4.0') >= 0
+        ) {
+            $invocationHandler = new InvocationHandler([$methods], false);
+            $invocationMocker = $invocationHandler->expects($matcher);
+        } else {
+            $invocationMocker = new InvocationMocker(
+                $this->prophesize(MatcherCollection::class)->reveal(),
+                $this->prophesize(Invocation::class)->reveal(),
+                $methods
+            );
+        }
 
         $prophecy = $this->prophesize(MockObject::class);
         $prophecy->expects($matcher)->willReturn($invocationMocker);
@@ -57,11 +65,25 @@ public function testExpects()
 
         $this->assertSame(
             (new MethodName(MockDelegateFunctionBuilder::METHOD))->toString(),
-            ($invocationMocker->getMatcher()->methodNameMatcher
-                ?? $invocationMocker->getMatcher()->getMethodNameMatcher())->toString()
+            $this->getMethodMatcher($invocationMocker)->toString()
         );
     }
 
+    private function getMethodMatcher($invocationMocker)
+    {
+        if (class_exists(\PHPUnit\Runner\Version::class)
+            && version_compare(\PHPUnit\Runner\Version::id(), '8.4.0') >= 0
+        ) {
+            $reflection = new \ReflectionClass(InvocationMocker::class);
+            $property = $reflection->getProperty('matcher');
+            $property->setAccessible(true);
+            return $property->getValue($invocationMocker)->getMethodNameRule();
+        }
+
+        return $invocationMocker->getMatcher()->methodNameMatcher ??
+            $invocationMocker->getMatcher()->getMethodNameMatcher();
+    }
+
     /**
      * Tests delegation of __phpunit_hasMatchers().
      *
@@ -116,13 +138,26 @@ public function testProxiedMethods($method, array $arguments = [], $expected = n
      * Returns the test cases for testProxiedMethods().
      *
      * @return array Test cases.
+     *
+     * @SuppressWarnings(PHPMD)
      */
     public function provideTestProxiedMethods()
     {
-        return [
-            ['__phpunit_getInvocationMocker', [], new \PHPUnit\Framework\MockObject\InvocationMocker([], true)],
-            ['__phpunit_setOriginalObject', ['bar']],
-            ['__phpunit_verify', [true]],
-        ];
+        $return = [];
+        if (class_exists(\PHPUnit\Runner\Version::class)
+            && version_compare(\PHPUnit\Runner\Version::id(), '8.4.0') >= 0
+        ) {
+            $return[] = ['__phpunit_getInvocationHandler', [], new InvocationHandler([], false)];
+        } else {
+            $return[] = [
+                '__phpunit_getInvocationMocker',
+                [],
+                new \PHPUnit\Framework\MockObject\InvocationMocker([], true)
+            ];
+        }
+
+        $return[] = ['__phpunit_setOriginalObject', ['bar']];
+        $return[] = ['__phpunit_verify', [true]];
+        return $return;
     }
 }
diff --git a/tests/PHPMockTest.php b/tests/PHPMockTest.php
index 88d7207..0cfef49 100644
--- a/tests/PHPMockTest.php
+++ b/tests/PHPMockTest.php
@@ -17,22 +17,22 @@ class PHPMockTest extends AbstractMockTest
 {
 
     use PHPMock;
-    
+
     protected function defineFunction($namespace, $functionName)
     {
         self::defineFunctionMock($namespace, $functionName);
     }
-    
+
     protected function mockFunction($namespace, $functionName, callable $function)
     {
         $mock = $this->getFunctionMock($namespace, $functionName);
         $mock->expects($this->any())->willReturnCallback($function);
     }
-    
+
     protected function disableMocks()
     {
     }
-    
+
     /**
      * Tests building a mock with arguments.
      *
@@ -42,10 +42,10 @@ public function testFunctionMockWithArguments()
     {
         $time = $this->getFunctionMock(__NAMESPACE__, "sqrt");
         $time->expects($this->once())->with(9)->willReturn(2);
-        
+
         $this->assertEquals(2, sqrt(9));
     }
-    
+
     /**
      * Tests failing an expectation.
      *

From f466523e6560125a4b42bedb608a78487887b2d3 Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Sat, 5 Oct 2019 22:42:06 +0100
Subject: [PATCH 26/55] Formatting fixes

---
 autoload.php                                    | 9 +++++----
 classes/DefaultArgumentRemoverNoReturnTypes.php | 1 -
 classes/DefaultArgumentRemoverReturnTypes.php   | 1 -
 classes/MockDisablerPHPUnit6.php                | 1 -
 classes/MockDisablerPHPUnit7.php                | 1 -
 classes/MockObjectProxyNoReturnTypes.php        | 1 -
 classes/MockObjectProxyReturnTypes.php          | 5 ++---
 classes/MockObjectProxyReturnTypes84.php        | 1 -
 8 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/autoload.php b/autoload.php
index a560fc1..b98a1fb 100644
--- a/autoload.php
+++ b/autoload.php
@@ -5,8 +5,7 @@ class_alias(
         \PHPUnit\Framework\MockObject\Rule\InvocationOrder::class,
         \PHPUnit\Framework\MockObject\Matcher\Invocation::class
     );
-}
-elseif (! interface_exists(\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
@@ -51,7 +50,8 @@ class_alias(
 }
 
 if (!class_exists(\PHPUnit\Framework\MockObject\InvocationHandler::class)
-    && !interface_exists(\PHPUnit\Framework\MockObject\Stub\MatcherCollection::class)) {
+    && !interface_exists(\PHPUnit\Framework\MockObject\Stub\MatcherCollection::class)
+) {
     class_alias(
         \PHPUnit_Framework_MockObject_Stub_MatcherCollection::class,
         \PHPUnit\Framework\MockObject\Stub\MatcherCollection::class
@@ -59,7 +59,8 @@ class_alias(
 }
 
 if (!class_exists(\PHPUnit\Framework\MockObject\InvocationHandler::class)
-    && !class_exists(\PHPUnit\Framework\MockObject\InvocationMocker::class)) {
+    && !class_exists(\PHPUnit\Framework\MockObject\InvocationMocker::class)
+) {
     class_alias(
         \PHPUnit_Framework_MockObject_InvocationMocker::class,
         \PHPUnit\Framework\MockObject\InvocationMocker::class
diff --git a/classes/DefaultArgumentRemoverNoReturnTypes.php b/classes/DefaultArgumentRemoverNoReturnTypes.php
index 0129334..84c1abe 100644
--- a/classes/DefaultArgumentRemoverNoReturnTypes.php
+++ b/classes/DefaultArgumentRemoverNoReturnTypes.php
@@ -16,7 +16,6 @@
  */
 class DefaultArgumentRemoverNoReturnTypes implements InvocationInterface
 {
-
     /**
      * @SuppressWarnings(PHPMD)
      */
diff --git a/classes/DefaultArgumentRemoverReturnTypes.php b/classes/DefaultArgumentRemoverReturnTypes.php
index bfdadfe..968b1f7 100644
--- a/classes/DefaultArgumentRemoverReturnTypes.php
+++ b/classes/DefaultArgumentRemoverReturnTypes.php
@@ -16,7 +16,6 @@
  */
 class DefaultArgumentRemoverReturnTypes implements InvocationInterface
 {
-
     /**
      * @SuppressWarnings(PHPMD)
      */
diff --git a/classes/MockDisablerPHPUnit6.php b/classes/MockDisablerPHPUnit6.php
index ed8ab10..3db2fcc 100644
--- a/classes/MockDisablerPHPUnit6.php
+++ b/classes/MockDisablerPHPUnit6.php
@@ -18,7 +18,6 @@
  */
 class MockDisablerPHPUnit6 extends BaseTestListener
 {
-
     /**
      * @var Deactivatable The function mocks.
      */
diff --git a/classes/MockDisablerPHPUnit7.php b/classes/MockDisablerPHPUnit7.php
index c2722f4..44c5141 100644
--- a/classes/MockDisablerPHPUnit7.php
+++ b/classes/MockDisablerPHPUnit7.php
@@ -18,7 +18,6 @@
  */
 class MockDisablerPHPUnit7 extends BaseTestListener
 {
-
     /**
      * @var Deactivatable The function mocks.
      */
diff --git a/classes/MockObjectProxyNoReturnTypes.php b/classes/MockObjectProxyNoReturnTypes.php
index f71c1a4..f6e186e 100644
--- a/classes/MockObjectProxyNoReturnTypes.php
+++ b/classes/MockObjectProxyNoReturnTypes.php
@@ -16,7 +16,6 @@
  */
 class MockObjectProxyNoReturnTypes implements MockObject
 {
-    
     /**
      * @var MockObject $mockObject The mock object.
      */
diff --git a/classes/MockObjectProxyReturnTypes.php b/classes/MockObjectProxyReturnTypes.php
index 6149401..77a46a1 100644
--- a/classes/MockObjectProxyReturnTypes.php
+++ b/classes/MockObjectProxyReturnTypes.php
@@ -18,12 +18,11 @@
  */
 class MockObjectProxyReturnTypes implements MockObject
 {
-    
     /**
      * @var MockObject $mockObject The mock object.
      */
     private $mockObject;
-    
+
     /**
      * Inject the subject.
      *
@@ -33,7 +32,7 @@ public function __construct(MockObject $mockObject)
     {
         $this->mockObject = $mockObject;
     }
-    
+
     /**
      * @SuppressWarnings(PHPMD)
      */
diff --git a/classes/MockObjectProxyReturnTypes84.php b/classes/MockObjectProxyReturnTypes84.php
index 9cbc51f..8c17e47 100644
--- a/classes/MockObjectProxyReturnTypes84.php
+++ b/classes/MockObjectProxyReturnTypes84.php
@@ -18,7 +18,6 @@
  */
 class MockObjectProxyReturnTypes84 implements MockObject
 {
-
     /**
      * @var MockObject $mockObject The mock object.
      */

From 50fb0a88e1633e996f94d3904e8f865c399d5e46 Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Sat, 5 Oct 2019 22:42:25 +0100
Subject: [PATCH 27/55] Optimize "or" conditions

---
 classes/DefaultArgumentRemoverReturnTypes.php   | 4 ++--
 classes/DefaultArgumentRemoverReturnTypes84.php | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/classes/DefaultArgumentRemoverReturnTypes.php b/classes/DefaultArgumentRemoverReturnTypes.php
index 968b1f7..32d928d 100644
--- a/classes/DefaultArgumentRemoverReturnTypes.php
+++ b/classes/DefaultArgumentRemoverReturnTypes.php
@@ -30,8 +30,8 @@ public function matches(Invocation $invocation) : bool
     {
         $iClass = class_exists(Invocation::class);
 
-        if ($invocation instanceof Invocation\StaticInvocation
-            || $iClass
+        if ($iClass
+            || $invocation instanceof Invocation\StaticInvocation
         ) {
             $this->removeDefaultArguments(
                 $invocation,
diff --git a/classes/DefaultArgumentRemoverReturnTypes84.php b/classes/DefaultArgumentRemoverReturnTypes84.php
index 6b5c6cf..4513ef5 100644
--- a/classes/DefaultArgumentRemoverReturnTypes84.php
+++ b/classes/DefaultArgumentRemoverReturnTypes84.php
@@ -30,8 +30,8 @@ public function matches(Invocation $invocation) : bool
     {
         $iClass = class_exists(Invocation::class);
 
-        if ($invocation instanceof Invocation\StaticInvocation
-            || $iClass
+        if ($iClass
+            || $invocation instanceof Invocation\StaticInvocation
         ) {
             $this->removeDefaultArguments(
                 $invocation,

From dc012f037f45994db55b5e5c4c7a5eccd5446bea Mon Sep 17 00:00:00 2001
From: webimpress <contact@webimpress.com>
Date: Sat, 5 Oct 2019 22:42:45 +0100
Subject: [PATCH 28/55] Allow PHPUnit ^6 || ^7 || ^8 in composer.json

---
 composer.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/composer.json b/composer.json
index 55cf224..cfc2c6a 100644
--- a/composer.json
+++ b/composer.json
@@ -19,7 +19,7 @@
     },
     "require": {
         "php": ">=7",
-        "phpunit/phpunit": "8.4.x-dev",
+        "phpunit/phpunit": "^6 || ^7 || ^8",
         "php-mock/php-mock-integration": "^2"
     },
     "archive": {

From fbfe968fb7db40978b11f12799ebc7b58eae9298 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Fri, 6 Dec 2019 08:54:05 +0000
Subject: [PATCH 29/55] Update Travis CI configuration - add builds with
 PHPUnit 8.5

---
 .travis.yml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 9386e57..5f7285b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,6 +8,7 @@ cache:
 
 env:
   - PHPUNIT_VERSION=dev-master
+  - PHPUNIT_VERSION=~8.5.0
   - PHPUNIT_VERSION=~8.4.0
   - PHPUNIT_VERSION=~8.3.0
   - PHPUNIT_VERSION=~8.2.0
@@ -38,6 +39,8 @@ matrix:
   exclude:
     - php: 7.1
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.1
+      env: PHPUNIT_VERSION=~8.5.0
     - php: 7.1
       env: PHPUNIT_VERSION=~8.4.0
     - php: 7.1
@@ -50,6 +53,8 @@ matrix:
       env: PHPUNIT_VERSION=~8.0.0
     - php: 7
       env: PHPUNIT_VERSION=dev-master
+    - php: 7
+      env: PHPUNIT_VERSION=~8.5.0
     - php: 7
       env: PHPUNIT_VERSION=~8.4.0
     - php: 7

From 841f648695c8af2271e15e04a08f09769e4d660b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Sat, 8 Feb 2020 14:45:59 +0000
Subject: [PATCH 30/55] Feature: PHPUnit 9 support

---
 .gitignore    |  6 +++---
 .travis.yml   | 12 ++++++++++--
 composer.json |  4 ++--
 3 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/.gitignore b/.gitignore
index 1816ab1..9c9d0d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
-.phpunit.result.cache
-vendor/
-composer.lock
+/.phpunit.result.cache
+/composer.lock
+/vendor/
diff --git a/.travis.yml b/.travis.yml
index 5f7285b..e4c6b1d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,6 +8,7 @@ cache:
 
 env:
   - PHPUNIT_VERSION=dev-master
+  - PHPUNIT_VERSION=~9.0.0
   - PHPUNIT_VERSION=~8.5.0
   - PHPUNIT_VERSION=~8.4.0
   - PHPUNIT_VERSION=~8.3.0
@@ -28,7 +29,7 @@ env:
   - PHPUNIT_VERSION=~6.0.0
 
 php:
-  - 7.4snapshot
+  - 7.4
   - 7.3
   - 7.2
   - 7.1
@@ -37,8 +38,14 @@ php:
 matrix:
   fast_finish: true
   exclude:
+    - php: 7.2
+      env: PHPUNIT_VERSION=dev-master
+    - php: 7.2
+      env: PHPUNIT_VERSION=~9.0.0
     - php: 7.1
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.1
+      env: PHPUNIT_VERSION=~9.0.0
     - php: 7.1
       env: PHPUNIT_VERSION=~8.5.0
     - php: 7.1
@@ -53,6 +60,8 @@ matrix:
       env: PHPUNIT_VERSION=~8.0.0
     - php: 7
       env: PHPUNIT_VERSION=dev-master
+    - php: 7
+      env: PHPUNIT_VERSION=~9.0.0
     - php: 7
       env: PHPUNIT_VERSION=~8.5.0
     - php: 7
@@ -78,7 +87,6 @@ matrix:
     - php: 7
       env: PHPUNIT_VERSION=~7.0.0
   allow_failures:
-    - php: 7.4snapshot
     - env: PHPUNIT_VERSION=dev-master
 
 install:
diff --git a/composer.json b/composer.json
index cfc2c6a..406f8cb 100644
--- a/composer.json
+++ b/composer.json
@@ -19,8 +19,8 @@
     },
     "require": {
         "php": ">=7",
-        "phpunit/phpunit": "^6 || ^7 || ^8",
-        "php-mock/php-mock-integration": "^2"
+        "phpunit/phpunit": "^6 || ^7 || ^8 || ^9",
+        "php-mock/php-mock-integration": "^2.1"
     },
     "archive": {
         "exclude": ["/tests"]

From bb852702e8f6a937a0966e2f310ce4fd7601e3fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Sat, 8 Feb 2020 15:15:29 +0000
Subject: [PATCH 31/55] Exclude tests on PHP 7.4 for not supported PHPUnit
 versions (<= 8.1)

---
 .travis.yml | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index e4c6b1d..3557d94 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,5 @@
 language: php
 
-sudo: false
-
 cache:
   directories:
     - $HOME/.composer/cache
@@ -38,6 +36,33 @@ php:
 matrix:
   fast_finish: true
   exclude:
+    - php: 7.4
+      env: PHPUNIT_VERSION=~8.1.0
+    - php: 7.4
+      env: PHPUNIT_VERSION=~8.0.0
+    - php: 7.4
+      env: PHPUNIT_VERSION=~7.4.0
+    - php: 7.4
+      env: PHPUNIT_VERSION=~7.3.0
+    - php: 7.4
+      env: PHPUNIT_VERSION=~7.2.0
+    - php: 7.4
+      env: PHPUNIT_VERSION=~7.1.0
+    - php: 7.4
+      env: PHPUNIT_VERSION=~7.0.0
+    - php: 7.4
+      env: PHPUNIT_VERSION=~6.5.0
+    - php: 7.4
+      env: PHPUNIT_VERSION=~6.4.0
+    - php: 7.4
+      env: PHPUNIT_VERSION=~6.3.0
+    - php: 7.4
+      env: PHPUNIT_VERSION=~6.2.0
+    - php: 7.4
+      env: PHPUNIT_VERSION=~6.1.0
+    - php: 7.4
+      env: PHPUNIT_VERSION=~6.0.0
+
     - php: 7.2
       env: PHPUNIT_VERSION=dev-master
     - php: 7.2
@@ -58,6 +83,7 @@ matrix:
       env: PHPUNIT_VERSION=~8.1.0
     - php: 7.1
       env: PHPUNIT_VERSION=~8.0.0
+
     - php: 7
       env: PHPUNIT_VERSION=dev-master
     - php: 7

From 308a7aa888422a4fc0f0ca998251c153523e2029 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Sat, 4 Apr 2020 09:20:58 +0100
Subject: [PATCH 32/55] Updates Travis CI configuration - adds builds with
 PHPUnit 9.1.0

---
 .travis.yml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 3557d94..a8fd280 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,6 +6,7 @@ cache:
 
 env:
   - PHPUNIT_VERSION=dev-master
+  - PHPUNIT_VERSION=~9.1.0
   - PHPUNIT_VERSION=~9.0.0
   - PHPUNIT_VERSION=~8.5.0
   - PHPUNIT_VERSION=~8.4.0
@@ -65,10 +66,15 @@ matrix:
 
     - php: 7.2
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.2
+      env: PHPUNIT_VERSION=~9.1.0
     - php: 7.2
       env: PHPUNIT_VERSION=~9.0.0
+
     - php: 7.1
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.1
+      env: PHPUNIT_VERSION=~9.1.0
     - php: 7.1
       env: PHPUNIT_VERSION=~9.0.0
     - php: 7.1
@@ -86,6 +92,8 @@ matrix:
 
     - php: 7
       env: PHPUNIT_VERSION=dev-master
+    - php: 7
+      env: PHPUNIT_VERSION=~9.1.0
     - php: 7
       env: PHPUNIT_VERSION=~9.0.0
     - php: 7

From 4fec5cf8f47d4303b445e41afbe5c6331be0b3ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Mon, 8 Jun 2020 10:48:45 +0100
Subject: [PATCH 33/55] Update Travis CI configuration - adds builds with
 PHPUnit ~9.2.0

---
 .travis.yml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index a8fd280..880210c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,6 +6,7 @@ cache:
 
 env:
   - PHPUNIT_VERSION=dev-master
+  - PHPUNIT_VERSION=~9.2.0
   - PHPUNIT_VERSION=~9.1.0
   - PHPUNIT_VERSION=~9.0.0
   - PHPUNIT_VERSION=~8.5.0
@@ -66,6 +67,8 @@ matrix:
 
     - php: 7.2
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.2
+      env: PHPUNIT_VERSION=~9.2.0
     - php: 7.2
       env: PHPUNIT_VERSION=~9.1.0
     - php: 7.2
@@ -73,6 +76,8 @@ matrix:
 
     - php: 7.1
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.1
+      env: PHPUNIT_VERSION=~9.2.0
     - php: 7.1
       env: PHPUNIT_VERSION=~9.1.0
     - php: 7.1
@@ -92,6 +97,8 @@ matrix:
 
     - php: 7
       env: PHPUNIT_VERSION=dev-master
+    - php: 7
+      env: PHPUNIT_VERSION=~9.2.0
     - php: 7
       env: PHPUNIT_VERSION=~9.1.0
     - php: 7

From f44e3c3c058d3398fcefdbbce000db823b7125bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Wed, 26 Aug 2020 08:43:42 +0100
Subject: [PATCH 34/55] Adds PHPUnit 9.3 to Travis CI matrix

---
 .travis.yml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 880210c..fed3a13 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,6 +6,7 @@ cache:
 
 env:
   - PHPUNIT_VERSION=dev-master
+  - PHPUNIT_VERSION=~9.3.0
   - PHPUNIT_VERSION=~9.2.0
   - PHPUNIT_VERSION=~9.1.0
   - PHPUNIT_VERSION=~9.0.0
@@ -67,6 +68,8 @@ matrix:
 
     - php: 7.2
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.2
+      env: PHPUNIT_VERSION=~9.3.0
     - php: 7.2
       env: PHPUNIT_VERSION=~9.2.0
     - php: 7.2
@@ -76,6 +79,8 @@ matrix:
 
     - php: 7.1
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.1
+      env: PHPUNIT_VERSION=~9.3.0
     - php: 7.1
       env: PHPUNIT_VERSION=~9.2.0
     - php: 7.1
@@ -97,6 +102,8 @@ matrix:
 
     - php: 7
       env: PHPUNIT_VERSION=dev-master
+    - php: 7
+      env: PHPUNIT_VERSION=~9.3.0
     - php: 7
       env: PHPUNIT_VERSION=~9.2.0
     - php: 7

From afc76d106e00e6c8fa038079fc52b060fcf8b529 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Wed, 14 Oct 2020 19:31:43 +0100
Subject: [PATCH 35/55] Adds PHPUnit 9.4.0 to Travis CI configuration matrix

---
 .travis.yml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index fed3a13..3970da0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,6 +6,7 @@ cache:
 
 env:
   - PHPUNIT_VERSION=dev-master
+  - PHPUNIT_VERSION=~9.4.0
   - PHPUNIT_VERSION=~9.3.0
   - PHPUNIT_VERSION=~9.2.0
   - PHPUNIT_VERSION=~9.1.0
@@ -68,6 +69,8 @@ matrix:
 
     - php: 7.2
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.2
+      env: PHPUNIT_VERSION=~9.4.0
     - php: 7.2
       env: PHPUNIT_VERSION=~9.3.0
     - php: 7.2
@@ -79,6 +82,8 @@ matrix:
 
     - php: 7.1
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.1
+      env: PHPUNIT_VERSION=~9.4.0
     - php: 7.1
       env: PHPUNIT_VERSION=~9.3.0
     - php: 7.1
@@ -102,6 +107,8 @@ matrix:
 
     - php: 7
       env: PHPUNIT_VERSION=dev-master
+    - php: 7
+      env: PHPUNIT_VERSION=~9.4.0
     - php: 7
       env: PHPUNIT_VERSION=~9.3.0
     - php: 7

From 1d02a35a1ef985cffaf217ac37f281eac93a7ff5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Fri, 11 Dec 2020 20:08:01 +0000
Subject: [PATCH 36/55] Update Travis CI configuration - PHP 8.0 and PHPUnit
 9.5.0

---
 .travis.yml | 73 +++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 54 insertions(+), 19 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 3970da0..2d556bc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,6 +6,7 @@ cache:
 
 env:
   - PHPUNIT_VERSION=dev-master
+  - PHPUNIT_VERSION=~9.5.0
   - PHPUNIT_VERSION=~9.4.0
   - PHPUNIT_VERSION=~9.3.0
   - PHPUNIT_VERSION=~9.2.0
@@ -31,15 +32,43 @@ env:
   - PHPUNIT_VERSION=~6.0.0
 
 php:
+  - 8.0
   - 7.4
   - 7.3
   - 7.2
   - 7.1
-  - 7
+  - 7.0
 
 matrix:
   fast_finish: true
   exclude:
+    - php: 8.0
+      env: PHPUNIT_VERSION=~8.1.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~8.0.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~7.4.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~7.3.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~7.2.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~7.1.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~7.0.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~6.5.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~6.4.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~6.3.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~6.2.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~6.1.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~6.0.0
+
     - php: 7.4
       env: PHPUNIT_VERSION=~8.1.0
     - php: 7.4
@@ -69,6 +98,8 @@ matrix:
 
     - php: 7.2
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.2
+      env: PHPUNIT_VERSION=~9.5.0
     - php: 7.2
       env: PHPUNIT_VERSION=~9.4.0
     - php: 7.2
@@ -82,6 +113,8 @@ matrix:
 
     - php: 7.1
       env: PHPUNIT_VERSION=dev-master
+    - php: 7.1
+      env: PHPUNIT_VERSION=~9.5.0
     - php: 7.1
       env: PHPUNIT_VERSION=~9.4.0
     - php: 7.1
@@ -105,41 +138,43 @@ matrix:
     - php: 7.1
       env: PHPUNIT_VERSION=~8.0.0
 
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=dev-master
-    - php: 7
+    - php: 7.0
+      env: PHPUNIT_VERSION=~9.5.0
+    - php: 7.0
       env: PHPUNIT_VERSION=~9.4.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~9.3.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~9.2.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~9.1.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~9.0.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~8.5.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~8.4.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~8.3.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~8.2.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~8.1.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~8.0.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~7.5.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~7.4.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~7.3.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~7.2.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~7.1.0
-    - php: 7
+    - php: 7.0
       env: PHPUNIT_VERSION=~7.0.0
   allow_failures:
     - env: PHPUNIT_VERSION=dev-master

From 481a68476b05261046c99d09dea0597dd5bb5dc9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Fri, 11 Dec 2020 20:27:34 +0000
Subject: [PATCH 37/55] Exclude some builds on PHP 8.0

Only PHPUnit 8.5+ and 9.3+ are compatible with PHP 8.0
---
 .travis.yml | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 2d556bc..01b8204 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -42,10 +42,24 @@ php:
 matrix:
   fast_finish: true
   exclude:
+    - php: 8.0
+      env: PHPUNIT_VERSION=~9.2.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~9.1.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~9.0.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~8.4.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~8.3.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~8.2.0
     - php: 8.0
       env: PHPUNIT_VERSION=~8.1.0
     - php: 8.0
       env: PHPUNIT_VERSION=~8.0.0
+    - php: 8.0
+      env: PHPUNIT_VERSION=~7.5.0
     - php: 8.0
       env: PHPUNIT_VERSION=~7.4.0
     - php: 8.0

From 775e5eef5b2af36d898366538813f3e945773c71 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Tue, 25 Jan 2022 19:57:54 +0000
Subject: [PATCH 38/55] Adds PHP 8.1 to Travis CI matrix

---
 .travis.yml | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 01b8204..3e4a54a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -32,6 +32,7 @@ env:
   - PHPUNIT_VERSION=~6.0.0
 
 php:
+  - 8.1
   - 8.0
   - 7.4
   - 7.3
@@ -42,6 +43,51 @@ php:
 matrix:
   fast_finish: true
   exclude:
+    - php: 8.1
+      env: PHPUNIT_VERSION=~9.4.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~9.3.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~9.2.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~9.1.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~9.0.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~8.4.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~8.3.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~8.2.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~8.1.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~8.0.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~7.5.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~7.4.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~7.3.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~7.2.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~7.1.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~7.0.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~6.5.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~6.4.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~6.3.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~6.2.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~6.1.0
+    - php: 8.1
+      env: PHPUNIT_VERSION=~6.0.0
+  
     - php: 8.0
       env: PHPUNIT_VERSION=~9.2.0
     - php: 8.0

From 3f7dc3680b77ad4ace9628bf24eeb3445e6f0dfa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Tue, 25 Jan 2022 20:34:17 +0000
Subject: [PATCH 39/55] GHA Workflow instead of Travis CI (#49)

---
 .github/workflows/tests.yml | 265 ++++++++++++++++++++++++++++++++++++
 .travis.yml                 | 250 ----------------------------------
 README.md                   |  17 +--
 3 files changed, 272 insertions(+), 260 deletions(-)
 create mode 100644 .github/workflows/tests.yml
 delete mode 100644 .travis.yml

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 0000000..3c59690
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,265 @@
+on:
+  pull_request:
+  schedule:
+    - cron:  "0 0 * * *"
+
+concurrency:
+  group: ${{ github.head_ref || 'cron' }}
+  cancel-in-progress: true
+
+jobs:
+  tests:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        php-version:
+          - '8.1'
+          - '8.0'
+          - '7.4'
+          - '7.3'
+          - '7.2'
+          - '7.1'
+          - '7.0'
+        phpunit-version:
+          - '9.5.0'
+          - '9.4.0'
+          - '9.3.0'
+          - '9.2.0'
+          - '9.1.0'
+          - '9.0.0'
+          - '8.4.0'
+          - '8.3.0'
+          - '8.2.0'
+          - '8.1.0'
+          - '8.0.0'
+          - '7.5.0'
+          - '7.4.0'
+          - '7.3.0'
+          - '7.2.0'
+          - '7.1.0'
+          - '7.0.0'
+          - '6.5.0'
+          - '6.4.0'
+          - '6.3.0'
+          - '6.2.0'
+          - '6.1.0'
+          - '6.0.0'
+
+        exclude:
+          # PHP 8.1 Exclusions
+          - php-version: '8.1'
+            phpunit-version: '9.4.0'
+          - php-version: '8.1'
+            phpunit-version: '9.3.0'
+          - php-version: '8.1'
+            phpunit-version: '9.2.0'
+          - php-version: '8.1'
+            phpunit-version: '9.1.0'
+          - php-version: '8.1'
+            phpunit-version: '9.0.0'
+          - php-version: '8.1'
+            phpunit-version: '8.4.0'
+          - php-version: '8.1'
+            phpunit-version: '8.3.0'
+          - php-version: '8.1'
+            phpunit-version: '8.2.0'
+          - php-version: '8.1'
+            phpunit-version: '8.1.0'
+          - php-version: '8.1'
+            phpunit-version: '8.0.0'
+          - php-version: '8.1'
+            phpunit-version: '7.5.0'
+          - php-version: '8.1'
+            phpunit-version: '7.4.0'
+          - php-version: '8.1'
+            phpunit-version: '7.3.0'
+          - php-version: '8.1'
+            phpunit-version: '7.2.0'
+          - php-version: '8.1'
+            phpunit-version: '7.1.0'
+          - php-version: '8.1'
+            phpunit-version: '7.0.0'
+          - php-version: '8.1'
+            phpunit-version: '6.5.0'
+          - php-version: '8.1'
+            phpunit-version: '6.4.0'
+          - php-version: '8.1'
+            phpunit-version: '6.3.0'
+          - php-version: '8.1'
+            phpunit-version: '6.2.0'
+          - php-version: '8.1'
+            phpunit-version: '6.1.0'
+          - php-version: '8.1'
+            phpunit-version: '6.0.0'
+
+          # PHP 8.0 Exclusions
+          - php-version: '8.0'
+            phpunit-version: '9.2.0'
+          - php-version: '8.0'
+            phpunit-version: '9.1.0'
+          - php-version: '8.0'
+            phpunit-version: '9.0.0'
+          - php-version: '8.0'
+            phpunit-version: '8.4.0'
+          - php-version: '8.0'
+            phpunit-version: '8.3.0'
+          - php-version: '8.0'
+            phpunit-version: '8.2.0'
+          - php-version: '8.0'
+            phpunit-version: '8.1.0'
+          - php-version: '8.0'
+            phpunit-version: '8.0.0'
+          - php-version: '8.0'
+            phpunit-version: '7.5.0'
+          - php-version: '8.0'
+            phpunit-version: '7.4.0'
+          - php-version: '8.0'
+            phpunit-version: '7.3.0'
+          - php-version: '8.0'
+            phpunit-version: '7.2.0'
+          - php-version: '8.0'
+            phpunit-version: '7.1.0'
+          - php-version: '8.0'
+            phpunit-version: '7.0.0'
+          - php-version: '8.0'
+            phpunit-version: '6.5.0'
+          - php-version: '8.0'
+            phpunit-version: '6.4.0'
+          - php-version: '8.0'
+            phpunit-version: '6.3.0'
+          - php-version: '8.0'
+            phpunit-version: '6.2.0'
+          - php-version: '8.0'
+            phpunit-version: '6.1.0'
+          - php-version: '8.0'
+            phpunit-version: '6.0.0'
+            
+          # PHP 7.4 Exclusions
+          - php-version: '7.4'
+            phpunit-version: '8.1.0'
+          - php-version: '7.4'
+            phpunit-version: '8.0.0'
+          - php-version: '7.4'
+            phpunit-version: '7.4.0'
+          - php-version: '7.4'
+            phpunit-version: '7.3.0'
+          - php-version: '7.4'
+            phpunit-version: '7.2.0'
+          - php-version: '7.4'
+            phpunit-version: '7.1.0'
+          - php-version: '7.4'
+            phpunit-version: '7.0.0'
+          - php-version: '7.4'
+            phpunit-version: '6.5.0'
+          - php-version: '7.4'
+            phpunit-version: '6.4.0'
+          - php-version: '7.4'
+            phpunit-version: '6.3.0'
+          - php-version: '7.4'
+            phpunit-version: '6.2.0'
+          - php-version: '7.4'
+            phpunit-version: '6.1.0'
+          - php-version: '7.4'
+            phpunit-version: '6.0.0'
+          
+          # PHP 7.2 Exclusions
+          - php-version: '7.2'
+            phpunit-version: '9.5.0'
+          - php-version: '7.2'
+            phpunit-version: '9.4.0'
+          - php-version: '7.2'
+            phpunit-version: '9.3.0'
+          - php-version: '7.2'
+            phpunit-version: '9.2.0'
+          - php-version: '7.2'
+            phpunit-version: '9.1.0'
+          - php-version: '7.2'
+            phpunit-version: '9.0.0'
+          
+          # PHP 7.1 Exclusions
+          - php-version: '7.1'
+            phpunit-version: '9.5.0'
+          - php-version: '7.1'
+            phpunit-version: '9.4.0'
+          - php-version: '7.1'
+            phpunit-version: '9.3.0'
+          - php-version: '7.1'
+            phpunit-version: '9.2.0'
+          - php-version: '7.1'
+            phpunit-version: '9.1.0'
+          - php-version: '7.1'
+            phpunit-version: '9.0.0'
+          - php-version: '7.1'
+            phpunit-version: '8.5.0'
+          - php-version: '7.1'
+            phpunit-version: '8.4.0'
+          - php-version: '7.1'
+            phpunit-version: '8.3.0'
+          - php-version: '7.1'
+            phpunit-version: '8.2.0'
+          - php-version: '7.1'
+            phpunit-version: '8.1.0'
+          - php-version: '7.1'
+            phpunit-version: '8.0.0'
+      
+          # PHP 7.0 Exclusions
+          - php-version: '7.0'
+            phpunit-version: '9.5.0'
+          - php-version: '7.0'
+            phpunit-version: '9.4.0'
+          - php-version: '7.0'
+            phpunit-version: '9.3.0'
+          - php-version: '7.0'
+            phpunit-version: '9.2.0'
+          - php-version: '7.0'
+            phpunit-version: '9.1.0'
+          - php-version: '7.0'
+            phpunit-version: '9.0.0'
+          - php-version: '7.0'
+            phpunit-version: '8.5.0'
+          - php-version: '7.0'
+            phpunit-version: '8.4.0'
+          - php-version: '7.0'
+            phpunit-version: '8.3.0'
+          - php-version: '7.0'
+            phpunit-version: '8.2.0'
+          - php-version: '7.0'
+            phpunit-version: '8.1.0'
+          - php-version: '7.0'
+            phpunit-version: '8.0.0'
+          - php-version: '7.0'
+            phpunit-version: '7.5.0'
+          - php-version: '7.0'
+            phpunit-version: '7.4.0'
+          - php-version: '7.0'
+            phpunit-version: '7.3.0'
+          - php-version: '7.0'
+            phpunit-version: '7.2.0'
+          - php-version: '7.0'
+            phpunit-version: '7.1.0'
+          - php-version: '7.0'
+            phpunit-version: '7.0.0'
+
+    name: PHPUnit ${{ matrix.phpunit-version }} on PHP ${{ matrix.php-version }}
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+        with:
+          ref: ${{ github.head_ref }}
+
+      - name: Install PHP
+        uses: shivammathur/setup-php@v2
+        with:
+          php-version: ${{ matrix.php-version }}
+
+      - name: Install Dependencies
+        run: composer require phpunit/phpunit:~${{ matrix.phpunit-version }} squizlabs/php_codesniffer phpmd/phpmd
+
+      - name: PHPUnit
+        run: vendor/bin/phpunit
+
+      - name: PHPCS
+        run: vendor/bin/phpcs --standard=PSR2 classes/ tests/
+
+      - name: PHPMD
+        run: vendor/bin/phpmd classes/ text cleancode,codesize,controversial,design,naming,unusedcode
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 3e4a54a..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,250 +0,0 @@
-language: php
-
-cache:
-  directories:
-    - $HOME/.composer/cache
-
-env:
-  - PHPUNIT_VERSION=dev-master
-  - PHPUNIT_VERSION=~9.5.0
-  - PHPUNIT_VERSION=~9.4.0
-  - PHPUNIT_VERSION=~9.3.0
-  - PHPUNIT_VERSION=~9.2.0
-  - PHPUNIT_VERSION=~9.1.0
-  - PHPUNIT_VERSION=~9.0.0
-  - PHPUNIT_VERSION=~8.5.0
-  - 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
-  - PHPUNIT_VERSION=~7.5.0
-  - PHPUNIT_VERSION=~7.4.0
-  - PHPUNIT_VERSION=~7.3.0
-  - PHPUNIT_VERSION=~7.2.0
-  - PHPUNIT_VERSION=~7.1.0
-  - PHPUNIT_VERSION=~7.0.0
-  - PHPUNIT_VERSION=~6.5.0
-  - PHPUNIT_VERSION=~6.4.0
-  - PHPUNIT_VERSION=~6.3.0
-  - PHPUNIT_VERSION=~6.2.0
-  - PHPUNIT_VERSION=~6.1.0
-  - PHPUNIT_VERSION=~6.0.0
-
-php:
-  - 8.1
-  - 8.0
-  - 7.4
-  - 7.3
-  - 7.2
-  - 7.1
-  - 7.0
-
-matrix:
-  fast_finish: true
-  exclude:
-    - php: 8.1
-      env: PHPUNIT_VERSION=~9.4.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~9.3.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~9.2.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~9.1.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~9.0.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~8.4.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~8.3.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~8.2.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~8.1.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~8.0.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~7.5.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~7.4.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~7.3.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~7.2.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~7.1.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~7.0.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~6.5.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~6.4.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~6.3.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~6.2.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~6.1.0
-    - php: 8.1
-      env: PHPUNIT_VERSION=~6.0.0
-  
-    - php: 8.0
-      env: PHPUNIT_VERSION=~9.2.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~9.1.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~9.0.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~8.4.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~8.3.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~8.2.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~8.1.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~8.0.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~7.5.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~7.4.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~7.3.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~7.2.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~7.1.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~7.0.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~6.5.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~6.4.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~6.3.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~6.2.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~6.1.0
-    - php: 8.0
-      env: PHPUNIT_VERSION=~6.0.0
-
-    - php: 7.4
-      env: PHPUNIT_VERSION=~8.1.0
-    - php: 7.4
-      env: PHPUNIT_VERSION=~8.0.0
-    - php: 7.4
-      env: PHPUNIT_VERSION=~7.4.0
-    - php: 7.4
-      env: PHPUNIT_VERSION=~7.3.0
-    - php: 7.4
-      env: PHPUNIT_VERSION=~7.2.0
-    - php: 7.4
-      env: PHPUNIT_VERSION=~7.1.0
-    - php: 7.4
-      env: PHPUNIT_VERSION=~7.0.0
-    - php: 7.4
-      env: PHPUNIT_VERSION=~6.5.0
-    - php: 7.4
-      env: PHPUNIT_VERSION=~6.4.0
-    - php: 7.4
-      env: PHPUNIT_VERSION=~6.3.0
-    - php: 7.4
-      env: PHPUNIT_VERSION=~6.2.0
-    - php: 7.4
-      env: PHPUNIT_VERSION=~6.1.0
-    - php: 7.4
-      env: PHPUNIT_VERSION=~6.0.0
-
-    - php: 7.2
-      env: PHPUNIT_VERSION=dev-master
-    - php: 7.2
-      env: PHPUNIT_VERSION=~9.5.0
-    - php: 7.2
-      env: PHPUNIT_VERSION=~9.4.0
-    - php: 7.2
-      env: PHPUNIT_VERSION=~9.3.0
-    - php: 7.2
-      env: PHPUNIT_VERSION=~9.2.0
-    - php: 7.2
-      env: PHPUNIT_VERSION=~9.1.0
-    - php: 7.2
-      env: PHPUNIT_VERSION=~9.0.0
-
-    - php: 7.1
-      env: PHPUNIT_VERSION=dev-master
-    - php: 7.1
-      env: PHPUNIT_VERSION=~9.5.0
-    - php: 7.1
-      env: PHPUNIT_VERSION=~9.4.0
-    - php: 7.1
-      env: PHPUNIT_VERSION=~9.3.0
-    - php: 7.1
-      env: PHPUNIT_VERSION=~9.2.0
-    - php: 7.1
-      env: PHPUNIT_VERSION=~9.1.0
-    - php: 7.1
-      env: PHPUNIT_VERSION=~9.0.0
-    - php: 7.1
-      env: PHPUNIT_VERSION=~8.5.0
-    - 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
-      env: PHPUNIT_VERSION=~8.1.0
-    - php: 7.1
-      env: PHPUNIT_VERSION=~8.0.0
-
-    - php: 7.0
-      env: PHPUNIT_VERSION=dev-master
-    - php: 7.0
-      env: PHPUNIT_VERSION=~9.5.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~9.4.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~9.3.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~9.2.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~9.1.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~9.0.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~8.5.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~8.4.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~8.3.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~8.2.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~8.1.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~8.0.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~7.5.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~7.4.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~7.3.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~7.2.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~7.1.0
-    - php: 7.0
-      env: PHPUNIT_VERSION=~7.0.0
-  allow_failures:
-    - env: PHPUNIT_VERSION=dev-master
-
-install:
-  - composer require phpunit/phpunit:${PHPUNIT_VERSION}
-  - composer require squizlabs/php_codesniffer
-  - composer require phpmd/phpmd
-
-script:
-  - vendor/bin/phpunit
-  - vendor/bin/phpcs --standard=PSR2 classes/ tests/
-  - vendor/bin/phpmd classes/ text cleancode,codesize,controversial,design,naming,unusedcode
diff --git a/README.md b/README.md
index 74d273e..016a872 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,11 @@
+[![.github/workflows/tests.yml](https://github.com/php-mock/php-mock-phpunit/actions/workflows/tests.yml/badge.svg)](https://github.com/php-mock/php-mock-phpunit/actions/workflows/tests.yml)
+
 # Mock PHP built-in functions with PHPUnit
 
 This package integrates the function mock library
 [PHP-Mock](https://github.com/php-mock/php-mock) with PHPUnit.
 
-# Installation
+## Installation
 
 Use [Composer](https://getcomposer.org/):
 
@@ -11,7 +13,7 @@ Use [Composer](https://getcomposer.org/):
 composer require --dev php-mock/php-mock-phpunit
 ```
 
-# Usage
+## Usage
 
 PHP-Mock integrates with the trait
 [`PHPMock`](http://php-mock.github.io/php-mock-phpunit/api/class-phpmock.phpunit.PHPMock.html)
@@ -22,8 +24,6 @@ With this method you can build a mock in the way you are used to build a
 PHPUnit mock:
 
 ```php
-<?php
-
 namespace foo;
 
 class BuiltinTest extends \PHPUnit\Framework\TestCase
@@ -60,7 +60,7 @@ class BuiltinTest extends \PHPUnit\Framework\TestCase
 There's no need to disable the mocked function. The PHPUnit integration does
 that for you.
 
-## Restrictions
+### Restrictions
 
 This library comes with the same restrictions as the underlying
 [`php-mock`](https://github.com/php-mock/php-mock#requirements-and-restrictions):
@@ -77,15 +77,12 @@ This library comes with the same restrictions as the underlying
   This would define a side effectless namespaced function. Another effective
   approach is running your test in an isolated process (e.g. with `@runInSeparateProcess`).
 
-# License and authors
+## License and authors
 
 This project is free and under the WTFPL.
 Responsable for this project is Markus Malkusch markus@malkusch.de.
 
-## Donations
+### Donations
 
 If you like this project and feel generous donate a few Bitcoins here:
 [1335STSwu9hST4vcMRppEPgENMHD2r1REK](bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK)
-
-[![Build Status](https://travis-ci.org/php-mock/php-mock-phpunit.svg?branch=master)](https://travis-ci.org/php-mock/php-mock-phpunit)
-

From b9ba2db21e7e1c7deba98bc86dcfc6425fb4647d Mon Sep 17 00:00:00 2001
From: Athos Ribeiro <athoscribeiro@gmail.com>
Date: Wed, 7 Sep 2022 17:40:07 -0300
Subject: [PATCH 40/55] Require phpspec/prophecy as dev dependency (#51)

* Require phpspec/prophecy as dev dependency

https://github.com/sebastianbergmann/phpunit/issues/5033 changed phpunit
to no longer depend on phpspec/prophecy. This results in the need to add
a development dependency for phpspec/prophecy. Doing so results in a
warning, since PHPUnit\Framework\TestCase::prophesize() is deprecated
and will be removed in PHPUnit 10. While we could use the trait provided
by phpspec/prophecy-phpunit instead, it would break PHP < 7.3 support.

* Closes #50
---
 .github/workflows/tests.yml | 2 +-
 composer.json               | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 3c59690..83dbe1e 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -243,7 +243,7 @@ jobs:
     name: PHPUnit ${{ matrix.phpunit-version }} on PHP ${{ matrix.php-version }}
     steps:
       - name: Checkout
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           ref: ${{ github.head_ref }}
 
diff --git a/composer.json b/composer.json
index 406f8cb..ef911d4 100644
--- a/composer.json
+++ b/composer.json
@@ -22,6 +22,9 @@
         "phpunit/phpunit": "^6 || ^7 || ^8 || ^9",
         "php-mock/php-mock-integration": "^2.1"
     },
+    "require-dev": {
+        "phpspec/prophecy": "^1.10.3"
+    },
     "archive": {
         "exclude": ["/tests"]
     }

From 97b3278e65863e53066f31adb85d92334c0ea07b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Mon, 6 Mar 2023 17:25:07 +0000
Subject: [PATCH 41/55] feat: Support for PHPUnit 10 (#56)

---
 .github/workflows/tests.yml                   | 71 +++++++++++++-
 autoload.php                                  | 20 +++-
 .../DefaultArgumentRemoverReturnTypes100.php  | 81 ++++++++++++++++
 classes/MockDisablerPHPUnit10.php             | 48 ++++++++++
 classes/MockObjectProxyReturnTypes100.php     | 92 +++++++++++++++++++
 classes/PHPMock.php                           | 18 ++++
 composer.json                                 |  6 +-
 tests/MockObjectProxyTest.php                 | 42 +++++----
 tests/PHPMockTest.php                         |  4 +-
 9 files changed, 355 insertions(+), 27 deletions(-)
 create mode 100644 classes/DefaultArgumentRemoverReturnTypes100.php
 create mode 100644 classes/MockDisablerPHPUnit10.php
 create mode 100644 classes/MockObjectProxyReturnTypes100.php

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 83dbe1e..0fed7f4 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -13,6 +13,7 @@ jobs:
     strategy:
       matrix:
         php-version:
+          - '8.2'
           - '8.1'
           - '8.0'
           - '7.4'
@@ -21,6 +22,8 @@ jobs:
           - '7.1'
           - '7.0'
         phpunit-version:
+          - '10.0.0'
+          - '9.6.0'
           - '9.5.0'
           - '9.4.0'
           - '9.3.0'
@@ -46,6 +49,52 @@ jobs:
           - '6.0.0'
 
         exclude:
+          # PHP 8.2 Exclusions
+          - php-version: '8.2'
+            phpunit-version: '9.4.0'
+          - php-version: '8.2'
+            phpunit-version: '9.3.0'
+          - php-version: '8.2'
+            phpunit-version: '9.2.0'
+          - php-version: '8.2'
+            phpunit-version: '9.1.0'
+          - php-version: '8.2'
+            phpunit-version: '9.0.0'
+          - php-version: '8.2'
+            phpunit-version: '8.4.0'
+          - php-version: '8.2'
+            phpunit-version: '8.3.0'
+          - php-version: '8.2'
+            phpunit-version: '8.2.0'
+          - php-version: '8.2'
+            phpunit-version: '8.1.0'
+          - php-version: '8.2'
+            phpunit-version: '8.0.0'
+          - php-version: '8.2'
+            phpunit-version: '7.5.0'
+          - php-version: '8.2'
+            phpunit-version: '7.4.0'
+          - php-version: '8.2'
+            phpunit-version: '7.3.0'
+          - php-version: '8.2'
+            phpunit-version: '7.2.0'
+          - php-version: '8.2'
+            phpunit-version: '7.1.0'
+          - php-version: '8.2'
+            phpunit-version: '7.0.0'
+          - php-version: '8.2'
+            phpunit-version: '6.5.0'
+          - php-version: '8.2'
+            phpunit-version: '6.4.0'
+          - php-version: '8.2'
+            phpunit-version: '6.3.0'
+          - php-version: '8.2'
+            phpunit-version: '6.2.0'
+          - php-version: '8.2'
+            phpunit-version: '6.1.0'
+          - php-version: '8.2'
+            phpunit-version: '6.0.0'
+
           # PHP 8.1 Exclusions
           - php-version: '8.1'
             phpunit-version: '9.4.0'
@@ -93,6 +142,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.0 Exclusions
+          - php-version: '8.0'
+            phpunit-version: '10.0.0'
           - php-version: '8.0'
             phpunit-version: '9.2.0'
           - php-version: '8.0'
@@ -135,6 +186,8 @@ jobs:
             phpunit-version: '6.0.0'
             
           # PHP 7.4 Exclusions
+          - php-version: '7.4'
+            phpunit-version: '10.0.0'
           - php-version: '7.4'
             phpunit-version: '8.1.0'
           - php-version: '7.4'
@@ -161,8 +214,16 @@ jobs:
             phpunit-version: '6.1.0'
           - php-version: '7.4'
             phpunit-version: '6.0.0'
+
+          # PHP 7.3 Exclusions
+          - php-version: '7.3'
+            phpunit-version: '10.0.0'
           
           # PHP 7.2 Exclusions
+          - php-version: '7.2'
+            phpunit-version: '10.0.0'
+          - php-version: '7.2'
+            phpunit-version: '9.6.0'
           - php-version: '7.2'
             phpunit-version: '9.5.0'
           - php-version: '7.2'
@@ -177,6 +238,10 @@ jobs:
             phpunit-version: '9.0.0'
           
           # PHP 7.1 Exclusions
+          - php-version: '7.1'
+            phpunit-version: '10.0.0'
+          - php-version: '7.1'
+            phpunit-version: '9.6.0'
           - php-version: '7.1'
             phpunit-version: '9.5.0'
           - php-version: '7.1'
@@ -203,6 +268,10 @@ jobs:
             phpunit-version: '8.0.0'
       
           # PHP 7.0 Exclusions
+          - php-version: '7.0'
+            phpunit-version: '10.0.0'
+          - php-version: '7.0'
+            phpunit-version: '9.6.0'
           - php-version: '7.0'
             phpunit-version: '9.5.0'
           - php-version: '7.0'
@@ -244,8 +313,6 @@ jobs:
     steps:
       - name: Checkout
         uses: actions/checkout@v3
-        with:
-          ref: ${{ github.head_ref }}
 
       - name: Install PHP
         uses: shivammathur/setup-php@v2
diff --git a/autoload.php b/autoload.php
index b98a1fb..e59f8ca 100644
--- a/autoload.php
+++ b/autoload.php
@@ -67,7 +67,16 @@ class_alias(
     );
 }
 
-if (! class_exists(\PHPUnit\Framework\BaseTestListener::class)) {
+$hasVersion = class_exists(\PHPUnit\Runner\Version::class);
+
+if ($hasVersion
+    && version_compare(\PHPUnit\Runner\Version::id(), '10.0.0') >= 0
+) {
+    class_alias(
+        phpmock\phpunit\MockDisablerPHPUnit10::class,
+        phpmock\phpunit\MockDisabler::class
+    );
+} elseif (! class_exists(\PHPUnit\Framework\BaseTestListener::class)) {
     include __DIR__ . '/compatibility/BaseTestListener.php';
     class_alias(
         phpmock\phpunit\MockDisablerPHPUnit7::class,
@@ -80,12 +89,17 @@ class_alias(
     );
 }
 
-if (class_exists(\PHPUnit\Runner\Version::class)
+if ($hasVersion
+    && version_compare(\PHPUnit\Runner\Version::id(), '10.0.0') >= 0
+) {
+    class_alias(\phpmock\phpunit\DefaultArgumentRemoverReturnTypes100::class, \phpmock\phpunit\DefaultArgumentRemover::class);
+    class_alias(\phpmock\phpunit\MockObjectProxyReturnTypes100::class, \phpmock\phpunit\MockObjectProxy::class);
+} elseif ($hasVersion
     && 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)
+} elseif ($hasVersion
     && version_compare(\PHPUnit\Runner\Version::id(), '8.1.0') >= 0
 ) {
     class_alias(\phpmock\phpunit\DefaultArgumentRemoverReturnTypes::class, \phpmock\phpunit\DefaultArgumentRemover::class);
diff --git a/classes/DefaultArgumentRemoverReturnTypes100.php b/classes/DefaultArgumentRemoverReturnTypes100.php
new file mode 100644
index 0000000..41fdcba
--- /dev/null
+++ b/classes/DefaultArgumentRemoverReturnTypes100.php
@@ -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 <markus@malkusch.de>
+ * @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
+ * @license http://www.wtfpl.net/txt/copying/ WTFPL
+ * @internal
+ */
+class DefaultArgumentRemoverReturnTypes100 extends InvocationOrder
+{
+    /**
+     * @SuppressWarnings(PHPMD)
+     */
+    public function invokedDo(Invocation $invocation): void
+    {
+    }
+
+    /**
+     * @SuppressWarnings(PHPMD)
+     */
+    public function matches(Invocation $invocation) : bool
+    {
+        $iClass = class_exists(Invocation::class);
+
+        if ($iClass
+            || $invocation instanceof Invocation\StaticInvocation
+        ) {
+            $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)();
+    }
+}
diff --git a/classes/MockDisablerPHPUnit10.php b/classes/MockDisablerPHPUnit10.php
new file mode 100644
index 0000000..be536b0
--- /dev/null
+++ b/classes/MockDisablerPHPUnit10.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace phpmock\phpunit;
+
+use phpmock\Deactivatable;
+use PHPUnit\Event\Test\Finished;
+use PHPUnit\Event\Test\FinishedSubscriber;
+
+/**
+ * Test listener for PHPUnit integration.
+ *
+ * This class disables mock functions after a test was run.
+ *
+ * @author Markus Malkusch <markus@malkusch.de>
+ * @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
+ * @license http://www.wtfpl.net/txt/copying/ WTFPL
+ * @internal
+ */
+class MockDisablerPHPUnit10 implements FinishedSubscriber
+{
+    /**
+     * @var Deactivatable The function mocks.
+     */
+    private $deactivatable;
+    
+    /**
+     * Sets the function mocks.
+     *
+     * @param Deactivatable $deactivatable The function mocks.
+     */
+    public function __construct(Deactivatable $deactivatable)
+    {
+        $this->deactivatable = $deactivatable;
+    }
+
+    /**
+     * @SuppressWarnings(PHPMD)
+     */
+    public function notify(Finished $event) : void
+    {
+        $this->deactivatable->disable();
+    }
+
+    public function endTest(): void
+    {
+        $this->deactivatable->disable();
+    }
+}
diff --git a/classes/MockObjectProxyReturnTypes100.php b/classes/MockObjectProxyReturnTypes100.php
new file mode 100644
index 0000000..d6e8977
--- /dev/null
+++ b/classes/MockObjectProxyReturnTypes100.php
@@ -0,0 +1,92 @@
+<?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 <markus@malkusch.de>
+ * @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
+ * @license http://www.wtfpl.net/txt/copying/ WTFPL
+ * @internal
+ */
+class MockObjectProxyReturnTypes100 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(object $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);
+    }
+}
diff --git a/classes/PHPMock.php b/classes/PHPMock.php
index 9adbfd1..40f08b8 100644
--- a/classes/PHPMock.php
+++ b/classes/PHPMock.php
@@ -5,7 +5,9 @@
 use phpmock\integration\MockDelegateFunctionBuilder;
 use phpmock\MockBuilder;
 use phpmock\Deactivatable;
+use PHPUnit\Event\Facade;
 use PHPUnit\Framework\MockObject\MockObject;
+use ReflectionProperty;
 
 /**
  * Adds building a function mock functionality into \PHPUnit\Framework\TestCase.
@@ -90,9 +92,25 @@ private function addMatcher($mock, $name)
      * directly created with PHPMock's API.
      *
      * @param Deactivatable $deactivatable The function mocks.
+     *
+     * @SuppressWarnings(PHPMD.StaticAccess)
      */
     public function registerForTearDown(Deactivatable $deactivatable)
     {
+        if (class_exists(Facade::class)) {
+            $property = new ReflectionProperty(Facade::class, 'sealed');
+            $property->setAccessible(true);
+            $property->setValue(false);
+
+            Facade::registerSubscriber(
+                new MockDisabler($deactivatable)
+            );
+
+            $property->setValue(true);
+
+            return;
+        }
+
         $result = $this->getTestResultObject();
         $result->addListener(new MockDisabler($deactivatable));
     }
diff --git a/composer.json b/composer.json
index ef911d4..3683e25 100644
--- a/composer.json
+++ b/composer.json
@@ -19,11 +19,11 @@
     },
     "require": {
         "php": ">=7",
-        "phpunit/phpunit": "^6 || ^7 || ^8 || ^9",
-        "php-mock/php-mock-integration": "^2.1"
+        "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10",
+        "php-mock/php-mock-integration": "^2.2.1"
     },
     "require-dev": {
-        "phpspec/prophecy": "^1.10.3"
+        "mockery/mockery": "^1.3.6"
     },
     "archive": {
         "exclude": ["/tests"]
diff --git a/tests/MockObjectProxyTest.php b/tests/MockObjectProxyTest.php
index 41ace7e..e9020d4 100644
--- a/tests/MockObjectProxyTest.php
+++ b/tests/MockObjectProxyTest.php
@@ -2,6 +2,7 @@
 
 namespace phpmock\phpunit;
 
+use Mockery;
 use phpmock\integration\MockDelegateFunctionBuilder;
 use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
 use PHPUnit\Framework\MockObject\ConfigurableMethod;
@@ -24,7 +25,6 @@
  */
 class MockObjectProxyTest extends TestCase
 {
-
     /**
      * Tests expects()
      *
@@ -37,7 +37,7 @@ public function testExpects()
         $methods = class_exists(ConfigurableMethod::class)
             ? new ConfigurableMethod(
                 MockDelegateFunctionBuilder::METHOD,
-                $this->prophesize(Type::class)->reveal()
+                Mockery::mock(Type::class)
             )
             : [MockDelegateFunctionBuilder::METHOD];
 
@@ -48,15 +48,14 @@ public function testExpects()
             $invocationMocker = $invocationHandler->expects($matcher);
         } else {
             $invocationMocker = new InvocationMocker(
-                $this->prophesize(MatcherCollection::class)->reveal(),
-                $this->prophesize(Invocation::class)->reveal(),
+                $this->getMockBuilder(MatcherCollection::class)->getMock(),
+                $this->getMockBuilder(Invocation::class)->getMock(),
                 $methods
             );
         }
 
-        $prophecy = $this->prophesize(MockObject::class);
-        $prophecy->expects($matcher)->willReturn($invocationMocker);
-        $mock = $prophecy->reveal();
+        $mock = Mockery::mock(MockObject::class);
+        $mock->shouldReceive('expects')->with($matcher)->andReturn($invocationMocker);
 
         $proxy = new MockObjectProxy($mock);
 
@@ -71,7 +70,18 @@ public function testExpects()
 
     private function getMethodMatcher($invocationMocker)
     {
-        if (class_exists(\PHPUnit\Runner\Version::class)
+        $hasVersion = class_exists(\PHPUnit\Runner\Version::class);
+
+        if ($hasVersion
+            && version_compare(\PHPUnit\Runner\Version::id(), '10.0.0') >= 0
+        ) {
+            $reflection = new \ReflectionClass(InvocationMocker::class);
+            $property = $reflection->getProperty('matcher');
+            $property->setAccessible(true);
+            return $property->getValue($invocationMocker)->methodNameRule();
+        }
+
+        if ($hasVersion
             && version_compare(\PHPUnit\Runner\Version::id(), '8.4.0') >= 0
         ) {
             $reflection = new \ReflectionClass(InvocationMocker::class);
@@ -96,9 +106,8 @@ private function getMethodMatcher($invocationMocker)
      */
     public function testHasMatcher()
     {
-        $prophecy = $this->prophesize(MockObject::class);
-        $prophecy->__phpunit_hasMatchers()->willReturn(true);
-        $mock = $prophecy->reveal();
+        $mock = Mockery::mock(MockObject::class);
+        $mock->shouldReceive('__phpunit_hasMatchers')->andReturn(true);
 
         $proxy = new MockObjectProxy($mock);
 
@@ -117,13 +126,12 @@ public function testHasMatcher()
      */
     public function testProxiedMethods($method, array $arguments = [], $expected = null)
     {
-        $prophecy = $this->prophesize(MockObject::class);
+        $mock = Mockery::mock(MockObject::class);
         if ($expected) {
-            call_user_func_array([$prophecy, $method], $arguments)->willReturn($expected)->shouldBeCalledTimes(1);
+            $mock->shouldReceive($method)->withArgs($arguments)->andReturn($expected)->times(1);
         } else {
-            call_user_func_array([$prophecy, $method], $arguments)->shouldBeCalledTimes(1);
+            $mock->shouldReceive($method)->withArgs($arguments)->times(1);
         }
-        $mock = $prophecy->reveal();
 
         $proxy = new MockObjectProxy($mock);
 
@@ -141,7 +149,7 @@ public function testProxiedMethods($method, array $arguments = [], $expected = n
      *
      * @SuppressWarnings(PHPMD)
      */
-    public function provideTestProxiedMethods()
+    public static function provideTestProxiedMethods()
     {
         $return = [];
         if (class_exists(\PHPUnit\Runner\Version::class)
@@ -156,7 +164,7 @@ public function provideTestProxiedMethods()
             ];
         }
 
-        $return[] = ['__phpunit_setOriginalObject', ['bar']];
+        $return[] = ['__phpunit_setOriginalObject', [new \stdClass()]];
         $return[] = ['__phpunit_verify', [true]];
         return $return;
     }
diff --git a/tests/PHPMockTest.php b/tests/PHPMockTest.php
index 0cfef49..da26159 100644
--- a/tests/PHPMockTest.php
+++ b/tests/PHPMockTest.php
@@ -2,7 +2,7 @@
 
 namespace phpmock\phpunit;
 
-use phpmock\AbstractMockTest;
+use phpmock\AbstractMockTestCase;
 use PHPUnit\Framework\ExpectationFailedException;
 
 /**
@@ -13,7 +13,7 @@
  * @license http://www.wtfpl.net/txt/copying/ WTFPL
  * @see PHPMock
  */
-class PHPMockTest extends AbstractMockTest
+class PHPMockTest extends AbstractMockTestCase
 {
 
     use PHPMock;

From dc4cf8896bf47647080dc5709a2c67ee9d437c21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Tue, 21 Mar 2023 07:55:31 +0100
Subject: [PATCH 42/55] fix: PHPUnit 10.0.17 compatibility (#57)

---
 classes/PHPMock.php | 8 +++++---
 composer.json       | 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/classes/PHPMock.php b/classes/PHPMock.php
index 40f08b8..166d9d2 100644
--- a/classes/PHPMock.php
+++ b/classes/PHPMock.php
@@ -98,15 +98,17 @@ private function addMatcher($mock, $name)
     public function registerForTearDown(Deactivatable $deactivatable)
     {
         if (class_exists(Facade::class)) {
+            $facade = Facade::instance();
+
             $property = new ReflectionProperty(Facade::class, 'sealed');
             $property->setAccessible(true);
-            $property->setValue(false);
+            $property->setValue($facade, false);
 
-            Facade::registerSubscriber(
+            $facade->registerSubscriber(
                 new MockDisabler($deactivatable)
             );
 
-            $property->setValue(true);
+            $property->setValue($facade, true);
 
             return;
         }
diff --git a/composer.json b/composer.json
index 3683e25..8b8e15f 100644
--- a/composer.json
+++ b/composer.json
@@ -19,7 +19,7 @@
     },
     "require": {
         "php": ">=7",
-        "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10",
+        "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10.0.17",
         "php-mock/php-mock-integration": "^2.2.1"
     },
     "require-dev": {

From 8cd8fc626f964f5f8a29034078797be235203ccf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Fri, 14 Apr 2023 10:09:14 +0200
Subject: [PATCH 43/55] qa: Update GHA workflow for PHPUnit 10.1 (#59)

---
 .github/workflows/tests.yml | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 0fed7f4..1b7fc6b 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -22,6 +22,7 @@ jobs:
           - '7.1'
           - '7.0'
         phpunit-version:
+          - '10.1.0'
           - '10.0.0'
           - '9.6.0'
           - '9.5.0'
@@ -142,6 +143,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.0 Exclusions
+          - php-version: '8.0'
+            phpunit-version: '10.1.0'
           - php-version: '8.0'
             phpunit-version: '10.0.0'
           - php-version: '8.0'
@@ -186,6 +189,8 @@ jobs:
             phpunit-version: '6.0.0'
             
           # PHP 7.4 Exclusions
+          - php-version: '7.4'
+            phpunit-version: '10.1.0'
           - php-version: '7.4'
             phpunit-version: '10.0.0'
           - php-version: '7.4'
@@ -216,10 +221,14 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 7.3 Exclusions
+          - php-version: '7.3'
+            phpunit-version: '10.1.0'
           - php-version: '7.3'
             phpunit-version: '10.0.0'
           
           # PHP 7.2 Exclusions
+          - php-version: '7.2'
+            phpunit-version: '10.1.0'
           - php-version: '7.2'
             phpunit-version: '10.0.0'
           - php-version: '7.2'
@@ -238,6 +247,8 @@ jobs:
             phpunit-version: '9.0.0'
           
           # PHP 7.1 Exclusions
+          - php-version: '7.1'
+            phpunit-version: '10.1.0'
           - php-version: '7.1'
             phpunit-version: '10.0.0'
           - php-version: '7.1'
@@ -268,6 +279,8 @@ jobs:
             phpunit-version: '8.0.0'
       
           # PHP 7.0 Exclusions
+          - php-version: '7.0'
+            phpunit-version: '10.1.0'
           - php-version: '7.0'
             phpunit-version: '10.0.0'
           - php-version: '7.0'

From 33a99c190d078e77864b8d74cdc91cc4e5342598 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Tue, 13 Jun 2023 08:46:04 +0100
Subject: [PATCH 44/55] qa: Add "testing" keyword to composer.json (#60)

See: https://github.com/php-mock/php-mock/pull/48
---
 composer.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/composer.json b/composer.json
index 8b8e15f..5c64c89 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,7 @@
     "name": "php-mock/php-mock-phpunit",
     "type": "library",
     "description": "Mock built-in PHP functions (e.g. time()) with PHPUnit. This package relies on PHP's namespace fallback policy. No further extension is needed.",
-    "keywords": ["phpunit", "mock", "stub", "test double", "function", "test", "TDD", "BDD"],
+    "keywords": ["phpunit", "mock", "stub", "test double", "function", "test", "testing", "TDD", "BDD"],
     "homepage": "https://github.com/php-mock/php-mock-phpunit",
     "license": "WTFPL",
     "authors": [

From 56edee85ad3232caa0202f98f2a3c899ab16bdb7 Mon Sep 17 00:00:00 2001
From: Marcos Coelho <503693+marcoscoelho@users.noreply.github.com>
Date: Mon, 30 Oct 2023 04:06:12 -0300
Subject: [PATCH 45/55] feat: PHPUnit 10.4 support (#63)

Fixes #61
---
 .github/workflows/tests.yml                   |  39 +++++
 .../DefaultArgumentRemoverReturnTypes100.php  |  55 ++++++-
 classes/PHPMock.php                           | 141 +++++++++++++++++-
 3 files changed, 232 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 1b7fc6b..4a19e1f 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -22,6 +22,9 @@ jobs:
           - '7.1'
           - '7.0'
         phpunit-version:
+          - '10.4.0'
+          - '10.3.0'
+          - '10.2.0'
           - '10.1.0'
           - '10.0.0'
           - '9.6.0'
@@ -143,6 +146,12 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.0 Exclusions
+          - php-version: '8.0'
+            phpunit-version: '10.4.0'
+          - php-version: '8.0'
+            phpunit-version: '10.3.0'
+          - php-version: '8.0'
+            phpunit-version: '10.2.0'
           - php-version: '8.0'
             phpunit-version: '10.1.0'
           - php-version: '8.0'
@@ -189,6 +198,12 @@ jobs:
             phpunit-version: '6.0.0'
             
           # PHP 7.4 Exclusions
+          - php-version: '7.4'
+            phpunit-version: '10.4.0'
+          - php-version: '7.4'
+            phpunit-version: '10.3.0'
+          - php-version: '7.4'
+            phpunit-version: '10.2.0'
           - php-version: '7.4'
             phpunit-version: '10.1.0'
           - php-version: '7.4'
@@ -221,12 +236,24 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 7.3 Exclusions
+          - php-version: '7.3'
+            phpunit-version: '10.4.0'
+          - php-version: '7.3'
+            phpunit-version: '10.3.0'
+          - php-version: '7.3'
+            phpunit-version: '10.2.0'
           - php-version: '7.3'
             phpunit-version: '10.1.0'
           - php-version: '7.3'
             phpunit-version: '10.0.0'
           
           # PHP 7.2 Exclusions
+          - php-version: '7.2'
+            phpunit-version: '10.4.0'
+          - php-version: '7.2'
+            phpunit-version: '10.3.0'
+          - php-version: '7.2'
+            phpunit-version: '10.2.0'
           - php-version: '7.2'
             phpunit-version: '10.1.0'
           - php-version: '7.2'
@@ -247,6 +274,12 @@ jobs:
             phpunit-version: '9.0.0'
           
           # PHP 7.1 Exclusions
+          - php-version: '7.1'
+            phpunit-version: '10.4.0'
+          - php-version: '7.1'
+            phpunit-version: '10.3.0'
+          - php-version: '7.1'
+            phpunit-version: '10.2.0'
           - php-version: '7.1'
             phpunit-version: '10.1.0'
           - php-version: '7.1'
@@ -279,6 +312,12 @@ jobs:
             phpunit-version: '8.0.0'
       
           # PHP 7.0 Exclusions
+          - php-version: '7.0'
+            phpunit-version: '10.4.0'
+          - php-version: '7.0'
+            phpunit-version: '10.3.0'
+          - php-version: '7.0'
+            phpunit-version: '10.2.0'
           - php-version: '7.0'
             phpunit-version: '10.1.0'
           - php-version: '7.0'
diff --git a/classes/DefaultArgumentRemoverReturnTypes100.php b/classes/DefaultArgumentRemoverReturnTypes100.php
index 41fdcba..c32dcbb 100644
--- a/classes/DefaultArgumentRemoverReturnTypes100.php
+++ b/classes/DefaultArgumentRemoverReturnTypes100.php
@@ -5,6 +5,7 @@
 use phpmock\generator\MockFunctionGenerator;
 use PHPUnit\Framework\MockObject\Invocation;
 use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
+use ReflectionClass;
 
 /**
  * Removes default arguments from the invocation.
@@ -37,7 +38,7 @@ public function matches(Invocation $invocation) : bool
                 $invocation,
                 $iClass ? Invocation::class : Invocation\StaticInvocation::class
             );
-        } else {
+        } elseif (!$this->shouldRemoveDefaultArgumentsWithReflection($invocation)) {
             MockFunctionGenerator::removeDefaultArguments($invocation->parameters);
         }
 
@@ -72,10 +73,62 @@ public function toString() : string
      */
     private function removeDefaultArguments(Invocation $invocation, string $class)
     {
+        if ($this->shouldRemoveDefaultArgumentsWithReflection($invocation)) {
+            return;
+        }
+
         $remover = function () {
             MockFunctionGenerator::removeDefaultArguments($this->parameters);
         };
 
         $remover->bindTo($invocation, $class)();
     }
+
+    /**
+     * Alternative to remove default arguments from StaticInvocation or its children (hack)
+     *
+     * @SuppressWarnings(PHPMD.StaticAccess)
+     */
+    public static function removeDefaultArgumentsWithReflection(Invocation $invocation): Invocation
+    {
+        if (!(new self())->shouldRemoveDefaultArgumentsWithReflection($invocation)) {
+            return $invocation;
+        }
+
+        $reflection = new ReflectionClass($invocation);
+
+        $reflectionReturnType = $reflection->getProperty('returnType');
+        $reflectionReturnType->setAccessible(true);
+
+        $reflectionIsOptional = $reflection->getProperty('isReturnTypeNullable');
+        $reflectionIsOptional->setAccessible(true);
+
+        $reflectionIsProxied = $reflection->getProperty('proxiedCall');
+        $reflectionIsProxied->setAccessible(true);
+
+        $returnType = $reflectionReturnType->getValue($invocation);
+        $proxiedCall = $reflectionIsProxied->getValue($invocation);
+
+        if ($reflectionIsOptional->getValue($invocation)) {
+            $returnType = '?' . $returnType;
+        }
+
+        $parameters = $invocation->parameters();
+        MockFunctionGenerator::removeDefaultArguments($parameters);
+
+        return new Invocation(
+            $invocation->className(),
+            $invocation->methodName(),
+            $parameters,
+            $returnType,
+            $invocation->object(),
+            false,
+            $proxiedCall
+        );
+    }
+
+    protected function shouldRemoveDefaultArgumentsWithReflection(Invocation $invocation)
+    {
+        return method_exists($invocation, 'parameters');
+    }
 }
diff --git a/classes/PHPMock.php b/classes/PHPMock.php
index 166d9d2..2a12b03 100644
--- a/classes/PHPMock.php
+++ b/classes/PHPMock.php
@@ -2,12 +2,15 @@
 
 namespace phpmock\phpunit;
 
+use DirectoryIterator;
 use phpmock\integration\MockDelegateFunctionBuilder;
 use phpmock\MockBuilder;
 use phpmock\Deactivatable;
 use PHPUnit\Event\Facade;
 use PHPUnit\Framework\MockObject\MockObject;
+use ReflectionClass;
 use ReflectionProperty;
+use SebastianBergmann\Template\Template;
 
 /**
  * Adds building a function mock functionality into \PHPUnit\Framework\TestCase.
@@ -38,6 +41,13 @@
  */
 trait PHPMock
 {
+    public static $templatesPath = '/tmp';
+
+    private $phpunitVersionClass = '\\PHPUnit\\Runner\\Version';
+    private $openInvocation = 'new \\PHPUnit\\Framework\\MockObject\\Invocation(';
+    private $openWrapper = '\\phpmock\\phpunit\\DefaultArgumentRemover::removeDefaultArgumentsWithReflection(';
+    private $closeFunc = ')';
+
     /**
      * Returns the enabled function mock.
      *
@@ -50,6 +60,8 @@ trait PHPMock
      */
     public function getFunctionMock($namespace, $name)
     {
+        $this->prepareCustomTemplates();
+
         $delegateBuilder = new MockDelegateFunctionBuilder();
         $delegateBuilder->build($name);
 
@@ -70,8 +82,7 @@ public function getFunctionMock($namespace, $name)
 
         $this->registerForTearDown($functionMock);
 
-        $proxy = new MockObjectProxy($mock);
-        return $proxy;
+        return new MockObjectProxy($mock);
     }
 
     private function addMatcher($mock, $name)
@@ -145,4 +156,130 @@ public static function defineFunctionMock($namespace, $name)
                             ->build()
                             ->define();
     }
+
+    /**
+     * Adds a wrapper method to the Invocable object instance that makes it
+     * possible to remove optional parameters when it is declared read-only.
+     *
+     * @return void
+     *
+     * @SuppressWarnings(PHPMD.StaticAccess)
+     * @SuppressWarnings(PHPMD.IfStatementAssignment)
+     */
+    private function prepareCustomTemplates()
+    {
+        if (!($this->shouldPrepareCustomTemplates() &&
+            is_dir(static::$templatesPath) &&
+            ($phpunitTemplatesDir = $this->getPhpunitTemplatesDir())
+        )) {
+            return;
+        }
+
+        $templatesDir = realpath(static::$templatesPath);
+        $directoryIterator = new DirectoryIterator($phpunitTemplatesDir);
+
+        $templates = [];
+
+        $prefix = 'phpmock-phpunit-' . $this->getPhpUnitVersion() . '-';
+
+        foreach ($directoryIterator as $fileinfo) {
+            if ($fileinfo->getExtension() !== 'tpl') {
+                continue;
+            }
+
+            $filename = $fileinfo->getFilename();
+            $customTemplateFile = $templatesDir . DIRECTORY_SEPARATOR . $prefix . $filename;
+            $templateFile = $phpunitTemplatesDir . DIRECTORY_SEPARATOR . $filename;
+
+            $this->createCustomTemplateFile($templateFile, $customTemplateFile);
+
+            if (file_exists($customTemplateFile)) {
+                $templates[$templateFile] = new Template($customTemplateFile);
+            }
+        }
+
+        $mockMethodClasses = [
+            'PHPUnit\\Framework\\MockObject\\Generator\\MockMethod',
+            'PHPUnit\\Framework\\MockObject\\MockMethod',
+        ];
+
+        foreach ($mockMethodClasses as $mockMethodClass) {
+            if (class_exists($mockMethodClass)) {
+                $reflection = new ReflectionClass($mockMethodClass);
+
+                $reflectionTemplates = $reflection->getProperty('templates');
+                $reflectionTemplates->setAccessible(true);
+
+                $reflectionTemplates->setValue($templates);
+
+                break;
+            }
+        }
+    }
+
+    private function shouldPrepareCustomTemplates()
+    {
+        return class_exists($this->phpunitVersionClass)
+            && version_compare($this->getPhpUnitVersion(), '10.0.0') >= 0;
+    }
+
+    private function getPhpUnitVersion()
+    {
+        return call_user_func([$this->phpunitVersionClass, 'id']);
+    }
+
+    /**
+     * Detects the PHPUnit templates dir
+     *
+     * @return string|null
+     */
+    private function getPhpunitTemplatesDir()
+    {
+        $phpunitLocations = [
+            __DIR__ . '/../../',
+            __DIR__ . '/../vendor/',
+        ];
+
+        $phpunitRelativePath = '/phpunit/phpunit/src/Framework/MockObject/Generator';
+
+        foreach ($phpunitLocations as $prefix) {
+            $possibleDirs = [
+                $prefix . $phpunitRelativePath . '/templates',
+                $prefix . $phpunitRelativePath,
+            ];
+
+            foreach ($possibleDirs as $dir) {
+                if (is_dir($dir)) {
+                    return realpath($dir);
+                }
+            }
+        }
+    }
+
+    /**
+     * Clones original template with the wrapper
+     *
+     * @param string $templateFile Template filename
+     * @param string $customTemplateFile Custom template filename
+     *
+     * @return void
+     *
+     * @SuppressWarnings(PHPMD.IfStatementAssignment)
+     */
+    private function createCustomTemplateFile(string $templateFile, string $customTemplateFile)
+    {
+        $template = file_get_contents($templateFile);
+
+        if (($start = strpos($template, $this->openInvocation)) !== false &&
+            ($end = strpos($template, $this->closeFunc, $start)) !== false
+        ) {
+            $template = substr_replace($template, $this->closeFunc, $end, 0);
+            $template = substr_replace($template, $this->openWrapper, $start, 0);
+
+            if ($file = fopen($customTemplateFile, 'w+')) {
+                fputs($file, $template);
+                fclose($file);
+            }
+        }
+    }
 }

From 0a77111fa94748f5ecace58c81c6c86ac84d9190 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Sat, 25 Nov 2023 09:14:26 +0000
Subject: [PATCH 46/55] qa: Run unit tests on PHP 8.3 (#64)

---
 .github/workflows/tests.yml | 47 +++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 4a19e1f..efd4bcc 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -13,6 +13,7 @@ jobs:
     strategy:
       matrix:
         php-version:
+          - '8.3'
           - '8.2'
           - '8.1'
           - '8.0'
@@ -53,6 +54,52 @@ jobs:
           - '6.0.0'
 
         exclude:
+          # PHP 8.3 Exclusions
+          - php-version: '8.3'
+            phpunit-version: '9.4.0'
+          - php-version: '8.3'
+            phpunit-version: '9.3.0'
+          - php-version: '8.3'
+            phpunit-version: '9.2.0'
+          - php-version: '8.3'
+            phpunit-version: '9.1.0'
+          - php-version: '8.3'
+            phpunit-version: '9.0.0'
+          - php-version: '8.3'
+            phpunit-version: '8.4.0'
+          - php-version: '8.3'
+            phpunit-version: '8.3.0'
+          - php-version: '8.3'
+            phpunit-version: '8.2.0'
+          - php-version: '8.3'
+            phpunit-version: '8.1.0'
+          - php-version: '8.3'
+            phpunit-version: '8.0.0'
+          - php-version: '8.3'
+            phpunit-version: '7.5.0'
+          - php-version: '8.3'
+            phpunit-version: '7.4.0'
+          - php-version: '8.3'
+            phpunit-version: '7.3.0'
+          - php-version: '8.3'
+            phpunit-version: '7.2.0'
+          - php-version: '8.3'
+            phpunit-version: '7.1.0'
+          - php-version: '8.3'
+            phpunit-version: '7.0.0'
+          - php-version: '8.3'
+            phpunit-version: '6.5.0'
+          - php-version: '8.3'
+            phpunit-version: '6.4.0'
+          - php-version: '8.3'
+            phpunit-version: '6.3.0'
+          - php-version: '8.3'
+            phpunit-version: '6.2.0'
+          - php-version: '8.3'
+            phpunit-version: '6.1.0'
+          - php-version: '8.3'
+            phpunit-version: '6.0.0'
+
           # PHP 8.2 Exclusions
           - php-version: '8.2'
             phpunit-version: '9.4.0'

From 3dabfd474d43da4d1d2fee5260c634457c5da344 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Fri, 1 Dec 2023 21:50:22 +0000
Subject: [PATCH 47/55] Adds PHPUnit 10.5 support (#65)

---
 .github/workflows/coding-standards.yml | 26 ++++++++++++++++++++++++++
 .github/workflows/phpmd.yml            | 26 ++++++++++++++++++++++++++
 .github/workflows/tests.yml            | 23 +++++++++++++++--------
 classes/PHPMock.php                    |  2 +-
 tests/MockObjectProxyTest.php          | 25 +++++++++++++++++++------
 5 files changed, 87 insertions(+), 15 deletions(-)
 create mode 100644 .github/workflows/coding-standards.yml
 create mode 100644 .github/workflows/phpmd.yml

diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml
new file mode 100644
index 0000000..52cc8ac
--- /dev/null
+++ b/.github/workflows/coding-standards.yml
@@ -0,0 +1,26 @@
+name: "Check Coding Standards"
+
+on:
+  pull_request:
+
+jobs:
+  coding-standards:
+    name: "Check Coding Standards"
+
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: Setup PHP
+        uses: shivammathur/setup-php@v2
+        with:
+          php-version: "7.4"
+          tools: composer:v2, cs2pr
+
+      - name: Install dependencies
+        run: composer require phpcsstandards/php_codesniffer --no-interaction --no-progress
+
+      - name: "Run phpcs"
+        run: vendor/bin/phpcs -q --standard=PSR2 classes/ tests/ --report=checkstyle | cs2pr
diff --git a/.github/workflows/phpmd.yml b/.github/workflows/phpmd.yml
new file mode 100644
index 0000000..4854690
--- /dev/null
+++ b/.github/workflows/phpmd.yml
@@ -0,0 +1,26 @@
+name: "Check phpmd"
+
+on:
+  pull_request:
+
+jobs:
+  coding-standards:
+    name: "Check phpmd"
+
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: Setup PHP
+        uses: shivammathur/setup-php@v2
+        with:
+          php-version: "7.4"
+          tools: composer:v2
+
+      - name: Install dependencies
+        run: composer require phpmd/phpmd --no-interaction --no-progress
+
+      - name: Run phpmd
+        run: vendor/bin/phpmd classes/ text cleancode,codesize,controversial,design,naming,unusedcode
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index efd4bcc..a6eb00d 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -23,6 +23,7 @@ jobs:
           - '7.1'
           - '7.0'
         phpunit-version:
+          - '10.5.0'
           - '10.4.0'
           - '10.3.0'
           - '10.2.0'
@@ -193,6 +194,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.0 Exclusions
+          - php-version: '8.0'
+            phpunit-version: '10.5.0'
           - php-version: '8.0'
             phpunit-version: '10.4.0'
           - php-version: '8.0'
@@ -245,6 +248,8 @@ jobs:
             phpunit-version: '6.0.0'
             
           # PHP 7.4 Exclusions
+          - php-version: '7.4'
+            phpunit-version: '10.5.0'
           - php-version: '7.4'
             phpunit-version: '10.4.0'
           - php-version: '7.4'
@@ -283,6 +288,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 7.3 Exclusions
+          - php-version: '7.3'
+            phpunit-version: '10.5.0'
           - php-version: '7.3'
             phpunit-version: '10.4.0'
           - php-version: '7.3'
@@ -295,6 +302,8 @@ jobs:
             phpunit-version: '10.0.0'
           
           # PHP 7.2 Exclusions
+          - php-version: '7.2'
+            phpunit-version: '10.5.0'
           - php-version: '7.2'
             phpunit-version: '10.4.0'
           - php-version: '7.2'
@@ -321,6 +330,8 @@ jobs:
             phpunit-version: '9.0.0'
           
           # PHP 7.1 Exclusions
+          - php-version: '7.1'
+            phpunit-version: '10.5.0'
           - php-version: '7.1'
             phpunit-version: '10.4.0'
           - php-version: '7.1'
@@ -359,6 +370,8 @@ jobs:
             phpunit-version: '8.0.0'
       
           # PHP 7.0 Exclusions
+          - php-version: '7.0'
+            phpunit-version: '10.5.0'
           - php-version: '7.0'
             phpunit-version: '10.4.0'
           - php-version: '7.0'
@@ -411,7 +424,7 @@ jobs:
     name: PHPUnit ${{ matrix.phpunit-version }} on PHP ${{ matrix.php-version }}
     steps:
       - name: Checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Install PHP
         uses: shivammathur/setup-php@v2
@@ -419,13 +432,7 @@ jobs:
           php-version: ${{ matrix.php-version }}
 
       - name: Install Dependencies
-        run: composer require phpunit/phpunit:~${{ matrix.phpunit-version }} squizlabs/php_codesniffer phpmd/phpmd
+        run: composer require phpunit/phpunit:~${{ matrix.phpunit-version }} --no-interaction --no-progress
 
       - name: PHPUnit
         run: vendor/bin/phpunit
-
-      - name: PHPCS
-        run: vendor/bin/phpcs --standard=PSR2 classes/ tests/
-
-      - name: PHPMD
-        run: vendor/bin/phpmd classes/ text cleancode,codesize,controversial,design,naming,unusedcode
diff --git a/classes/PHPMock.php b/classes/PHPMock.php
index 2a12b03..543db17 100644
--- a/classes/PHPMock.php
+++ b/classes/PHPMock.php
@@ -210,7 +210,7 @@ private function prepareCustomTemplates()
                 $reflectionTemplates = $reflection->getProperty('templates');
                 $reflectionTemplates->setAccessible(true);
 
-                $reflectionTemplates->setValue($templates);
+                $reflectionTemplates->setValue(null, $templates);
 
                 break;
             }
diff --git a/tests/MockObjectProxyTest.php b/tests/MockObjectProxyTest.php
index e9020d4..482e052 100644
--- a/tests/MockObjectProxyTest.php
+++ b/tests/MockObjectProxyTest.php
@@ -34,12 +34,25 @@ public function testExpects()
     {
         $matcher = $this->getMockBuilder(Invocation::class)->getMock();
 
-        $methods = class_exists(ConfigurableMethod::class)
-            ? new ConfigurableMethod(
-                MockDelegateFunctionBuilder::METHOD,
-                Mockery::mock(Type::class)
-            )
-            : [MockDelegateFunctionBuilder::METHOD];
+        if (class_exists(ConfigurableMethod::class)) {
+            if (class_exists(\PHPUnit\Runner\Version::class)
+                && version_compare(\PHPUnit\Runner\Version::id(), '10.5.0') >= 0
+            ) {
+                $methods = new ConfigurableMethod(
+                    MockDelegateFunctionBuilder::METHOD,
+                    [],
+                    0,
+                    Mockery::mock(Type::class)
+                );
+            } else {
+                $methods = new ConfigurableMethod(
+                    MockDelegateFunctionBuilder::METHOD,
+                    Mockery::mock(Type::class)
+                );
+            }
+        } else {
+            $methods = [MockDelegateFunctionBuilder::METHOD];
+        }
 
         if (class_exists(\PHPUnit\Runner\Version::class)
             && version_compare(\PHPUnit\Runner\Version::id(), '8.4.0') >= 0

From 5610b3619368c0bf07805b5d6ed8fe075df4dd3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Sat, 23 Dec 2023 13:21:03 +0100
Subject: [PATCH 48/55] chore: squizlabs/php_codesniffer 3.8.0 (#66)

---
 .github/workflows/coding-standards.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml
index 52cc8ac..6775731 100644
--- a/.github/workflows/coding-standards.yml
+++ b/.github/workflows/coding-standards.yml
@@ -20,7 +20,7 @@ jobs:
           tools: composer:v2, cs2pr
 
       - name: Install dependencies
-        run: composer require phpcsstandards/php_codesniffer --no-interaction --no-progress
+        run: composer require squizlabs/php_codesniffer --no-interaction --no-progress
 
       - name: "Run phpcs"
         run: vendor/bin/phpcs -q --standard=PSR2 classes/ tests/ --report=checkstyle | cs2pr

From e1f7e795990b00937376e345883ea68ca3bda7e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Sun, 11 Feb 2024 07:24:16 +0000
Subject: [PATCH 49/55] feat: Support PHPUnit 11 (#67)

---
 .github/workflows/tests.yml | 15 +++++++++++++++
 composer.json               |  4 ++--
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index a6eb00d..4ed3092 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -23,6 +23,7 @@ jobs:
           - '7.1'
           - '7.0'
         phpunit-version:
+          - '11.0.0'
           - '10.5.0'
           - '10.4.0'
           - '10.3.0'
@@ -148,6 +149,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.1 Exclusions
+          - php-version: '8.1'
+            phpunit-version: '11.0.0'
           - php-version: '8.1'
             phpunit-version: '9.4.0'
           - php-version: '8.1'
@@ -194,6 +197,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.0 Exclusions
+          - php-version: '8.0'
+            phpunit-version: '11.0.0'
           - php-version: '8.0'
             phpunit-version: '10.5.0'
           - php-version: '8.0'
@@ -248,6 +253,8 @@ jobs:
             phpunit-version: '6.0.0'
             
           # PHP 7.4 Exclusions
+          - php-version: '7.4'
+            phpunit-version: '11.0.0'
           - php-version: '7.4'
             phpunit-version: '10.5.0'
           - php-version: '7.4'
@@ -288,6 +295,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 7.3 Exclusions
+          - php-version: '7.3'
+            phpunit-version: '11.0.0'
           - php-version: '7.3'
             phpunit-version: '10.5.0'
           - php-version: '7.3'
@@ -302,6 +311,8 @@ jobs:
             phpunit-version: '10.0.0'
           
           # PHP 7.2 Exclusions
+          - php-version: '7.2'
+            phpunit-version: '11.0.0'
           - php-version: '7.2'
             phpunit-version: '10.5.0'
           - php-version: '7.2'
@@ -330,6 +341,8 @@ jobs:
             phpunit-version: '9.0.0'
           
           # PHP 7.1 Exclusions
+          - php-version: '7.1'
+            phpunit-version: '11.0.0'
           - php-version: '7.1'
             phpunit-version: '10.5.0'
           - php-version: '7.1'
@@ -370,6 +383,8 @@ jobs:
             phpunit-version: '8.0.0'
       
           # PHP 7.0 Exclusions
+          - php-version: '7.0'
+            phpunit-version: '11.0.0'
           - php-version: '7.0'
             phpunit-version: '10.5.0'
           - php-version: '7.0'
diff --git a/composer.json b/composer.json
index 5c64c89..9218934 100644
--- a/composer.json
+++ b/composer.json
@@ -19,8 +19,8 @@
     },
     "require": {
         "php": ">=7",
-        "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10.0.17",
-        "php-mock/php-mock-integration": "^2.2.1"
+        "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10.0.17 || ^11",
+        "php-mock/php-mock-integration": "^2.3"
     },
     "require-dev": {
         "mockery/mockery": "^1.3.6"

From 62e0af433e49a8b0145fc19a3dddfc2646d001b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Wed, 17 Apr 2024 17:24:58 +0100
Subject: [PATCH 50/55] QA: Run tests on PHPUnit ~11.1.0 (#69)

---
 .github/workflows/tests.yml | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 4ed3092..a77b200 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -23,6 +23,7 @@ jobs:
           - '7.1'
           - '7.0'
         phpunit-version:
+          - '11.1.0'
           - '11.0.0'
           - '10.5.0'
           - '10.4.0'
@@ -149,6 +150,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.1 Exclusions
+          - php-version: '8.1'
+            phpunit-version: '11.1.0'
           - php-version: '8.1'
             phpunit-version: '11.0.0'
           - php-version: '8.1'
@@ -197,6 +200,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.0 Exclusions
+          - php-version: '8.0'
+            phpunit-version: '11.1.0'
           - php-version: '8.0'
             phpunit-version: '11.0.0'
           - php-version: '8.0'
@@ -253,6 +258,8 @@ jobs:
             phpunit-version: '6.0.0'
             
           # PHP 7.4 Exclusions
+          - php-version: '7.4'
+            phpunit-version: '11.1.0'
           - php-version: '7.4'
             phpunit-version: '11.0.0'
           - php-version: '7.4'
@@ -295,6 +302,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 7.3 Exclusions
+          - php-version: '7.3'
+            phpunit-version: '11.1.0'
           - php-version: '7.3'
             phpunit-version: '11.0.0'
           - php-version: '7.3'
@@ -311,6 +320,8 @@ jobs:
             phpunit-version: '10.0.0'
           
           # PHP 7.2 Exclusions
+          - php-version: '7.2'
+            phpunit-version: '11.1.0'
           - php-version: '7.2'
             phpunit-version: '11.0.0'
           - php-version: '7.2'
@@ -341,6 +352,8 @@ jobs:
             phpunit-version: '9.0.0'
           
           # PHP 7.1 Exclusions
+          - php-version: '7.1'
+            phpunit-version: '11.1.0'
           - php-version: '7.1'
             phpunit-version: '11.0.0'
           - php-version: '7.1'
@@ -383,6 +396,8 @@ jobs:
             phpunit-version: '8.0.0'
       
           # PHP 7.0 Exclusions
+          - php-version: '7.0'
+            phpunit-version: '11.1.0'
           - php-version: '7.0'
             phpunit-version: '11.0.0'
           - php-version: '7.0'

From c1d0c2fbad486a9034a26fad170af7aa585b4e44 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Fri, 7 Jun 2024 21:50:52 +0100
Subject: [PATCH 51/55] QA: PHPUnit 11.2 testing (#72)

---
 .github/workflows/tests.yml | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index a77b200..29053d3 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -23,6 +23,7 @@ jobs:
           - '7.1'
           - '7.0'
         phpunit-version:
+          - '11.2.0'
           - '11.1.0'
           - '11.0.0'
           - '10.5.0'
@@ -150,6 +151,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.1 Exclusions
+          - php-version: '8.1'
+            phpunit-version: '11.2.0'
           - php-version: '8.1'
             phpunit-version: '11.1.0'
           - php-version: '8.1'
@@ -200,6 +203,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.0 Exclusions
+          - php-version: '8.0'
+            phpunit-version: '11.2.0'
           - php-version: '8.0'
             phpunit-version: '11.1.0'
           - php-version: '8.0'
@@ -258,6 +263,8 @@ jobs:
             phpunit-version: '6.0.0'
             
           # PHP 7.4 Exclusions
+          - php-version: '7.4'
+            phpunit-version: '11.2.0'
           - php-version: '7.4'
             phpunit-version: '11.1.0'
           - php-version: '7.4'
@@ -302,6 +309,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 7.3 Exclusions
+          - php-version: '7.3'
+            phpunit-version: '11.2.0'
           - php-version: '7.3'
             phpunit-version: '11.1.0'
           - php-version: '7.3'
@@ -320,6 +329,8 @@ jobs:
             phpunit-version: '10.0.0'
           
           # PHP 7.2 Exclusions
+          - php-version: '7.2'
+            phpunit-version: '11.2.0'
           - php-version: '7.2'
             phpunit-version: '11.1.0'
           - php-version: '7.2'
@@ -352,6 +363,8 @@ jobs:
             phpunit-version: '9.0.0'
           
           # PHP 7.1 Exclusions
+          - php-version: '7.1'
+            phpunit-version: '11.2.0'
           - php-version: '7.1'
             phpunit-version: '11.1.0'
           - php-version: '7.1'
@@ -396,6 +409,8 @@ jobs:
             phpunit-version: '8.0.0'
       
           # PHP 7.0 Exclusions
+          - php-version: '7.0'
+            phpunit-version: '11.2.0'
           - php-version: '7.0'
             phpunit-version: '11.1.0'
           - php-version: '7.0'

From e01b2885af682bf34beb28edd1a98997d4e59294 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Viktor=20Djupsj=C3=B6backa?=
 <crocodele@users.noreply.github.com>
Date: Sat, 8 Mar 2025 21:55:19 +0200
Subject: [PATCH 52/55] Support PHPUnit 12 by avoiding removed methods
 getMockForAbstractClass() and addMethods() (#75)

---
 .github/workflows/tests.yml                   | 109 +++++++++++++++
 autoload.php                                  |   5 +
 .../DefaultArgumentRemoverReturnTypes120.php  | 128 ++++++++++++++++++
 classes/MockObjectProxyReturnTypes120.php     | 100 ++++++++++++++
 classes/PHPMock.php                           |  13 +-
 composer.json                                 |   4 +-
 tests/MockObjectProxyTest.php                 |   2 +
 7 files changed, 354 insertions(+), 7 deletions(-)
 create mode 100644 classes/DefaultArgumentRemoverReturnTypes120.php
 create mode 100644 classes/MockObjectProxyReturnTypes120.php

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 29053d3..e5d071b 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -13,6 +13,7 @@ jobs:
     strategy:
       matrix:
         php-version:
+          - '8.4'
           - '8.3'
           - '8.2'
           - '8.1'
@@ -23,6 +24,10 @@ jobs:
           - '7.1'
           - '7.0'
         phpunit-version:
+          - '12.0.0'
+          - '11.5.0'
+          - '11.4.0'
+          - '11.3.0'
           - '11.2.0'
           - '11.1.0'
           - '11.0.0'
@@ -58,6 +63,52 @@ jobs:
           - '6.0.0'
 
         exclude:
+          # PHP 8.4 Exclusions
+          - php-version: '8.4'
+            phpunit-version: '9.4.0'
+          - php-version: '8.4'
+            phpunit-version: '9.3.0'
+          - php-version: '8.4'
+            phpunit-version: '9.2.0'
+          - php-version: '8.4'
+            phpunit-version: '9.1.0'
+          - php-version: '8.4'
+            phpunit-version: '9.0.0'
+          - php-version: '8.4'
+            phpunit-version: '8.4.0'
+          - php-version: '8.4'
+            phpunit-version: '8.3.0'
+          - php-version: '8.4'
+            phpunit-version: '8.2.0'
+          - php-version: '8.4'
+            phpunit-version: '8.1.0'
+          - php-version: '8.4'
+            phpunit-version: '8.0.0'
+          - php-version: '8.4'
+            phpunit-version: '7.5.0'
+          - php-version: '8.4'
+            phpunit-version: '7.4.0'
+          - php-version: '8.4'
+            phpunit-version: '7.3.0'
+          - php-version: '8.4'
+            phpunit-version: '7.2.0'
+          - php-version: '8.4'
+            phpunit-version: '7.1.0'
+          - php-version: '8.4'
+            phpunit-version: '7.0.0'
+          - php-version: '8.4'
+            phpunit-version: '6.5.0'
+          - php-version: '8.4'
+            phpunit-version: '6.4.0'
+          - php-version: '8.4'
+            phpunit-version: '6.3.0'
+          - php-version: '8.4'
+            phpunit-version: '6.2.0'
+          - php-version: '8.4'
+            phpunit-version: '6.1.0'
+          - php-version: '8.4'
+            phpunit-version: '6.0.0'
+        
           # PHP 8.3 Exclusions
           - php-version: '8.3'
             phpunit-version: '9.4.0'
@@ -105,6 +156,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.2 Exclusions
+          - php-version: '8.2'
+            phpunit-version: '12.0.0'
           - php-version: '8.2'
             phpunit-version: '9.4.0'
           - php-version: '8.2'
@@ -151,6 +204,14 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.1 Exclusions
+          - php-version: '8.1'
+            phpunit-version: '12.0.0'
+          - php-version: '8.1'
+            phpunit-version: '11.5.0'
+          - php-version: '8.1'
+            phpunit-version: '11.4.0'
+          - php-version: '8.1'
+            phpunit-version: '11.3.0'
           - php-version: '8.1'
             phpunit-version: '11.2.0'
           - php-version: '8.1'
@@ -203,6 +264,14 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.0 Exclusions
+          - php-version: '8.0'
+            phpunit-version: '12.0.0'
+          - php-version: '8.0'
+            phpunit-version: '11.5.0'
+          - php-version: '8.0'
+            phpunit-version: '11.4.0'
+          - php-version: '8.0'
+            phpunit-version: '11.3.0'
           - php-version: '8.0'
             phpunit-version: '11.2.0'
           - php-version: '8.0'
@@ -263,6 +332,14 @@ jobs:
             phpunit-version: '6.0.0'
             
           # PHP 7.4 Exclusions
+          - php-version: '7.4'
+            phpunit-version: '12.0.0'
+          - php-version: '7.4'
+            phpunit-version: '11.5.0'
+          - php-version: '7.4'
+            phpunit-version: '11.4.0'
+          - php-version: '7.4'
+            phpunit-version: '11.3.0'
           - php-version: '7.4'
             phpunit-version: '11.2.0'
           - php-version: '7.4'
@@ -309,6 +386,14 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 7.3 Exclusions
+          - php-version: '7.3'
+            phpunit-version: '12.0.0'
+          - php-version: '7.3'
+            phpunit-version: '11.5.0'
+          - php-version: '7.3'
+            phpunit-version: '11.4.0'
+          - php-version: '7.3'
+            phpunit-version: '11.3.0'
           - php-version: '7.3'
             phpunit-version: '11.2.0'
           - php-version: '7.3'
@@ -329,6 +414,14 @@ jobs:
             phpunit-version: '10.0.0'
           
           # PHP 7.2 Exclusions
+          - php-version: '7.2'
+            phpunit-version: '12.0.0'
+          - php-version: '7.2'
+            phpunit-version: '11.5.0'
+          - php-version: '7.2'
+            phpunit-version: '11.4.0'
+          - php-version: '7.2'
+            phpunit-version: '11.3.0'
           - php-version: '7.2'
             phpunit-version: '11.2.0'
           - php-version: '7.2'
@@ -363,6 +456,14 @@ jobs:
             phpunit-version: '9.0.0'
           
           # PHP 7.1 Exclusions
+          - php-version: '7.1'
+            phpunit-version: '12.0.0'
+          - php-version: '7.1'
+            phpunit-version: '11.5.0'
+          - php-version: '7.1'
+            phpunit-version: '11.4.0'
+          - php-version: '7.1'
+            phpunit-version: '11.3.0'
           - php-version: '7.1'
             phpunit-version: '11.2.0'
           - php-version: '7.1'
@@ -409,6 +510,14 @@ jobs:
             phpunit-version: '8.0.0'
       
           # PHP 7.0 Exclusions
+          - php-version: '7.0'
+            phpunit-version: '12.0.0'
+          - php-version: '7.0'
+            phpunit-version: '11.5.0'
+          - php-version: '7.0'
+            phpunit-version: '11.4.0'
+          - php-version: '7.0'
+            phpunit-version: '11.3.0'
           - php-version: '7.0'
             phpunit-version: '11.2.0'
           - php-version: '7.0'
diff --git a/autoload.php b/autoload.php
index e59f8ca..f567a6a 100644
--- a/autoload.php
+++ b/autoload.php
@@ -90,6 +90,11 @@ class_alias(
 }
 
 if ($hasVersion
+    && version_compare(\PHPUnit\Runner\Version::id(), '12.0.0') >= 0
+) {
+    class_alias(\phpmock\phpunit\DefaultArgumentRemoverReturnTypes120::class, \phpmock\phpunit\DefaultArgumentRemover::class);
+    class_alias(\phpmock\phpunit\MockObjectProxyReturnTypes120::class, \phpmock\phpunit\MockObjectProxy::class);
+} elseif ($hasVersion
     && version_compare(\PHPUnit\Runner\Version::id(), '10.0.0') >= 0
 ) {
     class_alias(\phpmock\phpunit\DefaultArgumentRemoverReturnTypes100::class, \phpmock\phpunit\DefaultArgumentRemover::class);
diff --git a/classes/DefaultArgumentRemoverReturnTypes120.php b/classes/DefaultArgumentRemoverReturnTypes120.php
new file mode 100644
index 0000000..8cce8fa
--- /dev/null
+++ b/classes/DefaultArgumentRemoverReturnTypes120.php
@@ -0,0 +1,128 @@
+<?php
+
+namespace phpmock\phpunit;
+
+use phpmock\generator\MockFunctionGenerator;
+use PHPUnit\Framework\MockObject\Invocation;
+use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
+use ReflectionClass;
+
+/**
+ * Removes default arguments from the invocation.
+ *
+ * @author Markus Malkusch <markus@malkusch.de>
+ * @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
+ * @license http://www.wtfpl.net/txt/copying/ WTFPL
+ * @internal
+ */
+class DefaultArgumentRemoverReturnTypes120 extends InvocationOrder
+{
+    /**
+     * @SuppressWarnings(PHPMD)
+     */
+    public function invokedDo(Invocation $invocation): void
+    {
+    }
+
+    /**
+     * @SuppressWarnings(PHPMD)
+     */
+    public function matches(Invocation $invocation) : bool
+    {
+        $iClass = class_exists(Invocation::class);
+
+        if ($iClass
+            || $invocation instanceof Invocation\StaticInvocation
+        ) {
+            $this->removeDefaultArguments(
+                $invocation,
+                $iClass ? Invocation::class : Invocation\StaticInvocation::class
+            );
+        } elseif (!$this->shouldRemoveDefaultArgumentsWithReflection($invocation)) {
+            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)
+    {
+        if ($this->shouldRemoveDefaultArgumentsWithReflection($invocation)) {
+            return;
+        }
+
+        $remover = function () {
+            MockFunctionGenerator::removeDefaultArguments($this->parameters);
+        };
+
+        $remover->bindTo($invocation, $class)();
+    }
+
+    /**
+     * Alternative to remove default arguments from StaticInvocation or its children (hack)
+     *
+     * @SuppressWarnings(PHPMD.StaticAccess)
+     */
+    public static function removeDefaultArgumentsWithReflection(Invocation $invocation): Invocation
+    {
+        if (!(new self())->shouldRemoveDefaultArgumentsWithReflection($invocation)) {
+            return $invocation;
+        }
+
+        $reflection = new ReflectionClass($invocation);
+
+        $reflectionReturnType = $reflection->getProperty('returnType');
+        $reflectionReturnType->setAccessible(true);
+
+        $reflectionIsOptional = $reflection->getProperty('isReturnTypeNullable');
+        $reflectionIsOptional->setAccessible(true);
+
+        $returnType = $reflectionReturnType->getValue($invocation);
+
+        if ($reflectionIsOptional->getValue($invocation)) {
+            $returnType = '?' . $returnType;
+        }
+
+        $parameters = $invocation->parameters();
+        MockFunctionGenerator::removeDefaultArguments($parameters);
+
+        return new Invocation(
+            $invocation->className(),
+            $invocation->methodName(),
+            $parameters,
+            $returnType,
+            $invocation->object()
+        );
+    }
+
+    protected function shouldRemoveDefaultArgumentsWithReflection(Invocation $invocation)
+    {
+        return method_exists($invocation, 'parameters');
+    }
+}
diff --git a/classes/MockObjectProxyReturnTypes120.php b/classes/MockObjectProxyReturnTypes120.php
new file mode 100644
index 0000000..f30503e
--- /dev/null
+++ b/classes/MockObjectProxyReturnTypes120.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace phpmock\phpunit;
+
+use phpmock\integration\MockDelegateFunctionBuilder;
+use PHPUnit\Framework\Constraint\Constraint;
+use PHPUnit\Framework\MockObject\Builder\InvocationMocker as BuilderInvocationMocker;
+use PHPUnit\Framework\MockObject\Builder\InvocationStubber;
+use PHPUnit\Framework\MockObject\InvocationHandler;
+use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
+use PHPUnit\Framework\MockObject\Runtime\PropertyHook;
+
+/**
+ * Proxy for PHPUnit's PHPUnit_Framework_MockObject_MockObject.
+ *
+ * @author Markus Malkusch <markus@malkusch.de>
+ * @link bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK Donations
+ * @license http://www.wtfpl.net/txt/copying/ WTFPL
+ * @internal
+ */
+class MockObjectProxyReturnTypes120 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(object $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);
+    }
+
+    public function method(Constraint|PropertyHook|string $constraint): InvocationStubber
+    {
+        return $this->mockObject->method($constraint);
+    }
+
+    /**
+     * 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/classes/PHPMock.php b/classes/PHPMock.php
index 543db17..4575504 100644
--- a/classes/PHPMock.php
+++ b/classes/PHPMock.php
@@ -66,10 +66,12 @@ public function getFunctionMock($namespace, $name)
         $delegateBuilder->build($name);
 
         $builder = $this->getMockBuilder($delegateBuilder->getFullyQualifiedClassName());
-        if (is_callable([$builder, 'addMethods'])) {
-            $builder->addMethods([$name]);
+        if (is_callable([$builder, 'onlyMethods'])) {
+            $builder->onlyMethods([MockDelegateFunctionBuilder::METHOD, $name]);
+        } elseif (is_callable([$builder, 'setMethods'])) {
+            $builder->setMethods([MockDelegateFunctionBuilder::METHOD, $name]);
         }
-        $mock = $builder->getMockForAbstractClass();
+        $mock = $builder->getMock();
         $this->addMatcher($mock, $name);
 
         $functionMockBuilder = new MockBuilder();
@@ -199,8 +201,9 @@ private function prepareCustomTemplates()
         }
 
         $mockMethodClasses = [
-            'PHPUnit\\Framework\\MockObject\\Generator\\MockMethod',
-            'PHPUnit\\Framework\\MockObject\\MockMethod',
+            'PHPUnit\\Framework\\MockObject\\Generator\\DoubledMethod', // PHPUnit 12
+            'PHPUnit\\Framework\\MockObject\\Generator\\MockMethod',    // PHPUnit 10-11
+            'PHPUnit\\Framework\\MockObject\\MockMethod',               // PHPUnit 9
         ];
 
         foreach ($mockMethodClasses as $mockMethodClass) {
diff --git a/composer.json b/composer.json
index 9218934..702ebe8 100644
--- a/composer.json
+++ b/composer.json
@@ -19,8 +19,8 @@
     },
     "require": {
         "php": ">=7",
-        "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10.0.17 || ^11",
-        "php-mock/php-mock-integration": "^2.3"
+        "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10.0.17 || ^11 || ^12",
+        "php-mock/php-mock-integration": "^3.0"
     },
     "require-dev": {
         "mockery/mockery": "^1.3.6"
diff --git a/tests/MockObjectProxyTest.php b/tests/MockObjectProxyTest.php
index 482e052..e9f35e4 100644
--- a/tests/MockObjectProxyTest.php
+++ b/tests/MockObjectProxyTest.php
@@ -4,6 +4,7 @@
 
 use Mockery;
 use phpmock\integration\MockDelegateFunctionBuilder;
+use PHPUnit\Framework\Attributes\DataProvider;
 use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
 use PHPUnit\Framework\MockObject\ConfigurableMethod;
 use PHPUnit\Framework\MockObject\InvocationHandler;
@@ -137,6 +138,7 @@ public function testHasMatcher()
      * @test
      * @dataProvider provideTestProxiedMethods
      */
+    #[DataProvider('provideTestProxiedMethods')]
     public function testProxiedMethods($method, array $arguments = [], $expected = null)
     {
         $mock = Mockery::mock(MockObject::class);

From 17f68c14b4a4d7e3b0b01ae116c9f3c84031184d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Wed, 12 Mar 2025 15:12:11 +0000
Subject: [PATCH 53/55] feat: Clean-up listener/subscriber after the test (#78)

Fixes #74
---
 classes/MockDisablerPHPUnit10.php | 16 ++++++++-
 classes/MockDisablerPHPUnit6.php  | 13 ++++++-
 classes/MockDisablerPHPUnit7.php  | 13 ++++++-
 classes/PHPMock.php               | 32 +++++++++++++++--
 tests/MockDisablerTest.php        | 19 ++++++++++
 tests/PHPMockTest.php             | 60 +++++++++++++++++++++++++++++++
 6 files changed, 148 insertions(+), 5 deletions(-)

diff --git a/classes/MockDisablerPHPUnit10.php b/classes/MockDisablerPHPUnit10.php
index be536b0..853e387 100644
--- a/classes/MockDisablerPHPUnit10.php
+++ b/classes/MockDisablerPHPUnit10.php
@@ -2,6 +2,7 @@
 
 namespace phpmock\phpunit;
 
+use Closure;
 use phpmock\Deactivatable;
 use PHPUnit\Event\Test\Finished;
 use PHPUnit\Event\Test\FinishedSubscriber;
@@ -22,15 +23,22 @@ class MockDisablerPHPUnit10 implements FinishedSubscriber
      * @var Deactivatable The function mocks.
      */
     private $deactivatable;
+
+    /**
+     * @var Closure|null The callback to execute after the test.
+     */
+    private $callback;
     
     /**
      * Sets the function mocks.
      *
      * @param Deactivatable $deactivatable The function mocks.
+     * @param Closure|null $callback       The callback to execute after the test.
      */
-    public function __construct(Deactivatable $deactivatable)
+    public function __construct(Deactivatable $deactivatable, ?Closure $callback = null)
     {
         $this->deactivatable = $deactivatable;
+        $this->callback = $callback;
     }
 
     /**
@@ -39,10 +47,16 @@ public function __construct(Deactivatable $deactivatable)
     public function notify(Finished $event) : void
     {
         $this->deactivatable->disable();
+        if ($this->callback !== null) {
+            ($this->callback)($this);
+        }
     }
 
     public function endTest(): void
     {
         $this->deactivatable->disable();
+        if ($this->callback !== null) {
+            ($this->callback)($this);
+        }
     }
 }
diff --git a/classes/MockDisablerPHPUnit6.php b/classes/MockDisablerPHPUnit6.php
index 3db2fcc..c2926ab 100644
--- a/classes/MockDisablerPHPUnit6.php
+++ b/classes/MockDisablerPHPUnit6.php
@@ -2,6 +2,7 @@
 
 namespace phpmock\phpunit;
 
+use Closure;
 use phpmock\Deactivatable;
 use PHPUnit\Framework\BaseTestListener;
 use PHPUnit\Framework\Test;
@@ -22,15 +23,22 @@ class MockDisablerPHPUnit6 extends BaseTestListener
      * @var Deactivatable The function mocks.
      */
     private $deactivatable;
+
+    /**
+     * @var Closure|null The callback to execute after the test.
+     */
+    private $callback;
     
     /**
      * Sets the function mocks.
      *
      * @param Deactivatable $deactivatable The function mocks.
+     * @param Closure|null $callback       The callback to execute after the test.
      */
-    public function __construct(Deactivatable $deactivatable)
+    public function __construct(Deactivatable $deactivatable, Closure $callback = null)
     {
         $this->deactivatable = $deactivatable;
+        $this->callback = $callback;
     }
     
     /**
@@ -46,5 +54,8 @@ public function endTest(Test $test, $time)
         parent::endTest($test, $time);
         
         $this->deactivatable->disable();
+        if ($this->callback !== null) {
+            ($this->callback)($this);
+        }
     }
 }
diff --git a/classes/MockDisablerPHPUnit7.php b/classes/MockDisablerPHPUnit7.php
index 44c5141..41def45 100644
--- a/classes/MockDisablerPHPUnit7.php
+++ b/classes/MockDisablerPHPUnit7.php
@@ -2,6 +2,7 @@
 
 namespace phpmock\phpunit;
 
+use Closure;
 use phpmock\Deactivatable;
 use PHPUnit\Framework\BaseTestListener;
 use PHPUnit\Framework\Test;
@@ -22,15 +23,22 @@ class MockDisablerPHPUnit7 extends BaseTestListener
      * @var Deactivatable The function mocks.
      */
     private $deactivatable;
+
+    /**
+     * @var Closure|null The callback to execute after the test.
+     */
+    private $callback;
     
     /**
      * Sets the function mocks.
      *
      * @param Deactivatable $deactivatable The function mocks.
+     * @param Closure|null $callback       The callback to execute after the test.
      */
-    public function __construct(Deactivatable $deactivatable)
+    public function __construct(Deactivatable $deactivatable, Closure $callback = null)
     {
         $this->deactivatable = $deactivatable;
+        $this->callback = $callback;
     }
     
     /**
@@ -46,5 +54,8 @@ public function endTest(Test $test, float $time) : void
         parent::endTest($test, $time);
         
         $this->deactivatable->disable();
+        if ($this->callback !== null) {
+            ($this->callback)($this);
+        }
     }
 }
diff --git a/classes/PHPMock.php b/classes/PHPMock.php
index 4575504..c75a9d3 100644
--- a/classes/PHPMock.php
+++ b/classes/PHPMock.php
@@ -7,8 +7,10 @@
 use phpmock\MockBuilder;
 use phpmock\Deactivatable;
 use PHPUnit\Event\Facade;
+use PHPUnit\Event\Test\Finished;
 use PHPUnit\Framework\MockObject\MockObject;
 use ReflectionClass;
+use ReflectionMethod;
 use ReflectionProperty;
 use SebastianBergmann\Template\Template;
 
@@ -117,8 +119,32 @@ public function registerForTearDown(Deactivatable $deactivatable)
             $property->setAccessible(true);
             $property->setValue($facade, false);
 
+            $method = new ReflectionMethod($facade, 'deferredDispatcher');
+            $method->setAccessible(true);
+            $dispatcher = $method->invoke($facade);
+
+            $propDispatcher = new ReflectionProperty($dispatcher, 'dispatcher');
+            $propDispatcher->setAccessible(true);
+            $directDispatcher = $propDispatcher->getValue($dispatcher);
+
+            $propSubscribers = new ReflectionProperty($directDispatcher, 'subscribers');
+            $propSubscribers->setAccessible(true);
+
             $facade->registerSubscriber(
-                new MockDisabler($deactivatable)
+                new MockDisabler(
+                    $deactivatable,
+                    static function (MockDisabler $original) use ($directDispatcher, $propSubscribers) {
+                        $subscribers = $propSubscribers->getValue($directDispatcher);
+
+                        foreach ($subscribers[Finished::class] as $key => $subscriber) {
+                            if ($original === $subscriber) {
+                                unset($subscribers[Finished::class][$key]);
+                            }
+                        }
+
+                        $propSubscribers->setValue($directDispatcher, $subscribers);
+                    }
+                )
             );
 
             $property->setValue($facade, true);
@@ -127,7 +153,9 @@ public function registerForTearDown(Deactivatable $deactivatable)
         }
 
         $result = $this->getTestResultObject();
-        $result->addListener(new MockDisabler($deactivatable));
+        $result->addListener(new MockDisabler($deactivatable, static function (MockDisabler $listener) use ($result) {
+            $result->removeListener($listener);
+        }));
     }
 
     /**
diff --git a/tests/MockDisablerTest.php b/tests/MockDisablerTest.php
index ba7a805..4dbadca 100644
--- a/tests/MockDisablerTest.php
+++ b/tests/MockDisablerTest.php
@@ -2,6 +2,7 @@
 
 namespace phpmock\phpunit;
 
+use phpmock\Deactivatable;
 use phpmock\Mock;
 use PHPUnit\Framework\TestCase;
 
@@ -32,4 +33,22 @@ public function testEndTest()
         
         $this->assertEquals(1, min(1, 9));
     }
+
+    public function testCallback()
+    {
+        $executed = false;
+        $executedWith = null;
+        $mock = $this->createMock(Deactivatable::class);
+        $disabler = new MockDisabler($mock, static function ($disabler) use (&$executed, &$executedWith) {
+            self::assertInstanceOf(MockDisabler::class, $disabler);
+
+            $executed = true;
+            $executedWith = $disabler;
+        });
+
+        $disabler->endTest($this, 1);
+
+        self::assertTrue($executed);
+        self::assertSame($executedWith, $disabler);
+    }
 }
diff --git a/tests/PHPMockTest.php b/tests/PHPMockTest.php
index da26159..582b1c7 100644
--- a/tests/PHPMockTest.php
+++ b/tests/PHPMockTest.php
@@ -3,6 +3,7 @@
 namespace phpmock\phpunit;
 
 use phpmock\AbstractMockTestCase;
+use phpmock\Deactivatable;
 use PHPUnit\Framework\ExpectationFailedException;
 
 /**
@@ -63,4 +64,63 @@ public function testFunctionMockFailsExpectation()
             time(); // satisfy the expectation
         }
     }
+
+    /**
+     * Register a Deactivatable for a tear down.
+     *
+     * @test
+     */
+    public function testRegisterForTearDownRegistered()
+    {
+        $obj = new \stdClass();
+        $obj->count = 0;
+
+        $class = new class ($obj) implements Deactivatable
+        {
+            private $obj;
+
+            public function __construct($obj)
+            {
+                $this->obj = $obj;
+            }
+
+            public function disable()
+            {
+                ++$this->obj->count;
+            }
+        };
+        $this->registerForTearDown($class);
+
+        self::assertSame(0, $obj->count);
+
+        return $obj;
+    }
+
+    /**
+     * Check the Deactivatable was executed on a tear down of dependent test.
+     *
+     * @test
+     *
+     * @depends testRegisterForTearDownRegistered
+     */
+    #[\PHPUnit\Framework\Attributes\Depends('testRegisterForTearDownRegistered')]
+    public function testRegisterForTearDownExecuted($obj)
+    {
+        self::assertSame(1, $obj->count);
+
+        return $obj;
+    }
+
+    /**
+     * Check the Deactivatable was unregistered after executing, so it is not executed again.
+     *
+     * @test
+     *
+     * @depends testRegisterForTearDownExecuted
+     */
+    #[\PHPUnit\Framework\Attributes\Depends('testRegisterForTearDownExecuted')]
+    public function testRegisterForTearDownRemoved($obj)
+    {
+        self::assertSame(1, $obj->count);
+    }
 }

From 498e5e25ee7824570332581304c2bb7e37d75e80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Wed, 19 Mar 2025 20:58:51 +0000
Subject: [PATCH 54/55] feat: Support for PHPUnit 12.0.9 (#80)

Closes #79
---
 autoload.php                              | 15 +++++++++++----
 classes/MockObjectProxyReturnTypes120.php |  4 ++--
 composer.json                             |  2 +-
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/autoload.php b/autoload.php
index f567a6a..e16fa67 100644
--- a/autoload.php
+++ b/autoload.php
@@ -29,10 +29,17 @@ class_alias(
 }
 
 if (! class_exists(\PHPUnit\Framework\MockObject\Builder\InvocationMocker::class)) {
-    class_alias(
-        \PHPUnit_Framework_MockObject_Builder_InvocationMocker::class,
-        \PHPUnit\Framework\MockObject\Builder\InvocationMocker::class
-    );
+    if (class_exists(\PHPUnit\Framework\MockObject\InvocationStubberImplementation::class)) {
+        class_alias(
+            \PHPUnit\Framework\MockObject\InvocationStubberImplementation::class,
+            \PHPUnit\Framework\MockObject\Builder\InvocationMocker::class
+        );
+    } else {
+        class_alias(
+            \PHPUnit_Framework_MockObject_Builder_InvocationMocker::class,
+            \PHPUnit\Framework\MockObject\Builder\InvocationMocker::class
+        );
+    }
 }
 
 if (class_exists(\PHPUnit\Framework\MockObject\Rule\MethodName::class)) {
diff --git a/classes/MockObjectProxyReturnTypes120.php b/classes/MockObjectProxyReturnTypes120.php
index f30503e..8cb79b8 100644
--- a/classes/MockObjectProxyReturnTypes120.php
+++ b/classes/MockObjectProxyReturnTypes120.php
@@ -4,8 +4,8 @@
 
 use phpmock\integration\MockDelegateFunctionBuilder;
 use PHPUnit\Framework\Constraint\Constraint;
-use PHPUnit\Framework\MockObject\Builder\InvocationMocker as BuilderInvocationMocker;
-use PHPUnit\Framework\MockObject\Builder\InvocationStubber;
+use PHPUnit\Framework\MockObject\InvocationStubberImplementation as BuilderInvocationMocker;
+use PHPUnit\Framework\MockObject\InvocationStubber;
 use PHPUnit\Framework\MockObject\InvocationHandler;
 use PHPUnit\Framework\MockObject\MockObject;
 use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
diff --git a/composer.json b/composer.json
index 702ebe8..bbd0703 100644
--- a/composer.json
+++ b/composer.json
@@ -19,7 +19,7 @@
     },
     "require": {
         "php": ">=7",
-        "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10.0.17 || ^11 || ^12",
+        "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10.0.17 || ^11 || ^12.0.9",
         "php-mock/php-mock-integration": "^3.0"
     },
     "require-dev": {

From 1a9855f236ad501b409eb65aa4ab39c7fd76b8ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Bundyra?= <contact@webimpress.com>
Date: Fri, 4 Apr 2025 07:35:38 +0100
Subject: [PATCH 55/55] qa: Run tests with PHPUnit ~12.1.0 (#81)

See: https://github.com/sebastianbergmann/phpunit/releases/tag/12.1.0
---
 .github/workflows/tests.yml | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index e5d071b..62c6a59 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -24,6 +24,7 @@ jobs:
           - '7.1'
           - '7.0'
         phpunit-version:
+          - '12.1.0'
           - '12.0.0'
           - '11.5.0'
           - '11.4.0'
@@ -156,6 +157,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.2 Exclusions
+          - php-version: '8.2'
+            phpunit-version: '12.1.0'
           - php-version: '8.2'
             phpunit-version: '12.0.0'
           - php-version: '8.2'
@@ -204,6 +207,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.1 Exclusions
+          - php-version: '8.1'
+            phpunit-version: '12.1.0'
           - php-version: '8.1'
             phpunit-version: '12.0.0'
           - php-version: '8.1'
@@ -264,6 +269,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 8.0 Exclusions
+          - php-version: '8.0'
+            phpunit-version: '12.1.0'
           - php-version: '8.0'
             phpunit-version: '12.0.0'
           - php-version: '8.0'
@@ -332,6 +339,8 @@ jobs:
             phpunit-version: '6.0.0'
             
           # PHP 7.4 Exclusions
+          - php-version: '7.4'
+            phpunit-version: '12.1.0'
           - php-version: '7.4'
             phpunit-version: '12.0.0'
           - php-version: '7.4'
@@ -386,6 +395,8 @@ jobs:
             phpunit-version: '6.0.0'
 
           # PHP 7.3 Exclusions
+          - php-version: '7.3'
+            phpunit-version: '12.1.0'
           - php-version: '7.3'
             phpunit-version: '12.0.0'
           - php-version: '7.3'
@@ -414,6 +425,8 @@ jobs:
             phpunit-version: '10.0.0'
           
           # PHP 7.2 Exclusions
+          - php-version: '7.2'
+            phpunit-version: '12.1.0'
           - php-version: '7.2'
             phpunit-version: '12.0.0'
           - php-version: '7.2'
@@ -456,6 +469,8 @@ jobs:
             phpunit-version: '9.0.0'
           
           # PHP 7.1 Exclusions
+          - php-version: '7.1'
+            phpunit-version: '12.1.0'
           - php-version: '7.1'
             phpunit-version: '12.0.0'
           - php-version: '7.1'
@@ -510,6 +525,8 @@ jobs:
             phpunit-version: '8.0.0'
       
           # PHP 7.0 Exclusions
+          - php-version: '7.0'
+            phpunit-version: '12.1.0'
           - php-version: '7.0'
             phpunit-version: '12.0.0'
           - php-version: '7.0'
