diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php index 91da81edf8..ca1a517d6a 100644 --- a/core/tests/Drupal/KernelTests/KernelTestBase.php +++ b/core/tests/Drupal/KernelTests/KernelTestBase.php @@ -20,7 +20,7 @@ use Drupal\simpletest\AssertContentTrait; use Drupal\Tests\AssertHelperTrait; use Drupal\Tests\ConfigTestTrait; -use Drupal\Tests\Phpunit5FCTrait; +use Drupal\Tests\PhpunitCompatibilityTrait; use Drupal\Tests\RandomGeneratorTrait; use Drupal\Tests\TestRequirementsTrait; use Drupal\simpletest\TestServiceProvider; @@ -77,7 +77,7 @@ use RandomGeneratorTrait; use ConfigTestTrait; use TestRequirementsTrait; - use Phpunit5FCTrait; + use PhpunitCompatibilityTrait; /** * {@inheritdoc} diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php index d9a8ba0cab..d1ab0a1ec2 100644 --- a/core/tests/Drupal/Tests/BrowserTestBase.php +++ b/core/tests/Drupal/Tests/BrowserTestBase.php @@ -66,7 +66,7 @@ createUser as drupalCreateUser; } use XdebugRequestTrait; - use Phpunit5FCTrait; + use PhpunitCompatibilityTrait; /** * The database prefix of this test run. diff --git a/core/tests/Drupal/Tests/Phpunit5FCTrait.php b/core/tests/Drupal/Tests/PhpunitCompatibilityTrait.php similarity index 60% rename from core/tests/Drupal/Tests/Phpunit5FCTrait.php rename to core/tests/Drupal/Tests/PhpunitCompatibilityTrait.php index 7ace0bf198..3d381a53ab 100644 --- a/core/tests/Drupal/Tests/Phpunit5FCTrait.php +++ b/core/tests/Drupal/Tests/PhpunitCompatibilityTrait.php @@ -3,17 +3,16 @@ namespace Drupal\Tests; /** - * This trait makes tests forward compatible with PHPUnit 5 and above. + * Makes Drupal's test API forward compatible with multiple versions of PHPUnit. */ -trait Phpunit5FCTrait { +trait PhpunitCompatibilityTrait { /** * Returns a mock object for the specified class using the available method. * - * The getMock method is deprecated in PHPUnit 5 but the createMock method is - * not available in PHPUnit 4. To provide backward compatibility this trait - * provides the getMock method and uses createMock if this method is - * available on the parent class. + * The getMock method is does not exist in PHPUnit 6. To provide backward + * compatibility this trait provides the getMock method and uses createMock if + * this method is available on the parent class. * * @param string $originalClassName * Name of the class to mock. @@ -33,8 +32,11 @@ * Can be used to disable __autoload() during the generation of the test * double class. * @param bool $cloneArguments + * Enables the cloning of arguments passed to mocked methods. * @param bool $callOriginalMethods + * Enables the invocation of the original methods. * @param object $proxyTarget + * Sets the proxy target. * * @see \PHPUnit_Framework_TestCase::getMock * @see https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-5.4.0 @@ -42,49 +44,12 @@ * @return \PHPUnit_Framework_MockObject_MockObject * * @deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. - * Use \Drupal\Tests\Phpunit5FCTrait::createMock() instead. + * Use \Drupal\Tests\PhpunitCompatibilityTrait::createMock() instead. * * @see https://www.drupal.org/node/2907725 */ public function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = FALSE, $callOriginalMethods = FALSE, $proxyTarget = NULL) { - return $this->createMock($originalClassName, $methods, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods, $proxyTarget); - } - - /** - * Returns a mock object for the specified class using the available method. - * - * The getMock method is deprecated in PHPUnit 5 but the createMock method is - * not available in PHPUnit 4. To provide forward compatibility this trait - * provides the createMock method and uses createMock if this method is - * available on the parent class or falls back to getMock if it isn't. - * - * @param string $originalClassName - * Name of the class to mock. - * @param array|null $methods - * When provided, only methods whose names are in the array are replaced - * with a configurable test double. The behavior of the other methods is not - * changed. Providing null means that no methods will be replaced. - * @param array $arguments - * Parameters to pass to the original class' constructor. - * @param string $mockClassName - * Class name for the generated test double class. - * @param bool $callOriginalConstructor - * Can be used to disable the call to the original class' constructor. - * @param bool $callOriginalClone - * Can be used to disable the call to the original class' clone constructor. - * @param bool $callAutoload - * Can be used to disable __autoload() during the generation of the test - * double class. - * @param bool $cloneArguments - * @param bool $callOriginalMethods - * @param object $proxyTarget - * - * @see \PHPUnit_Framework_TestCase::getMock - * - * @return \PHPUnit_Framework_MockObject_MockObject - */ - public function createMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = FALSE, $callOriginalMethods = FALSE, $proxyTarget = NULL) { - if ($this->isPhpunit5()) { + if (!$this->supports('getMock')) { $mock = $this->getMockBuilder($originalClassName) ->setMethods($methods) ->setConstructorArgs($arguments) @@ -122,26 +87,56 @@ public function createMock($originalClassName, $methods = array(), array $argume } return $mock->getMock(); } - return parent::getMock($originalClassName, $methods, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods, $proxyTarget); + else { + return parent::getMock($originalClassName, $methods, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods, $proxyTarget); + } } /** - * Checks if the trait is used in a class extending the PHPUnit 5 TestCase. + * Returns a mock object for the specified class using the available method. + * + * The createMock method does not exist in PHPUnit 4. To provide forward + * compatibility this trait provides the createMock method and uses createMock + * if this method is available on the parent class or falls back to getMock if + * it isn't. + * + * @param string $originalClassName + * Name of the class to mock. + * + * @see \PHPUnit_Framework_TestCase::getMock + * + * @return \PHPUnit_Framework_MockObject_MockObject + */ + public function createMock($originalClassName) { + if ($this->supports('createMock')) { + return parent::createMock($originalClassName); + } + else { + return $this->getMock($originalClassName, [], [], '', FALSE, FALSE); + } + } + + /** + * Checks if the trait is used in a class that has a method. + * + * @param string $method + * Method to check. * * @return bool + * TRUE if the method is supported, FALSE if not. */ - private function isPhpunit5() { + private function supports($method) { // Get the parent class of the currently running test class. $parent = get_parent_class($this); - // Ensure that the method_exists() check on PHPUnit 5's createMock method is - // carried out on the first parent of $this that does not have access to - // this trait's methods. This is because the trait also has a method called + // Ensure that the method_exists() check on the createMock method is carried + // out on the first parent of $this that does not have access to this + // trait's methods. This is because the trait also has a method called // createMock(). Most often the check will be made on // \PHPUnit\Framework\TestCase. - while (method_exists($parent, 'isPhpunit5')) { + while (method_exists($parent, 'supports')) { $parent = get_parent_class($parent); } - return method_exists($parent, 'createMock'); + return method_exists($parent, $method); } /** diff --git a/core/tests/Drupal/Tests/Phpunit5FCTraitTest.php b/core/tests/Drupal/Tests/PhpunitCompatibilityTraitTest.php similarity index 77% rename from core/tests/Drupal/Tests/Phpunit5FCTraitTest.php rename to core/tests/Drupal/Tests/PhpunitCompatibilityTraitTest.php index 7871d69c10..f512b9d060 100644 --- a/core/tests/Drupal/Tests/Phpunit5FCTraitTest.php +++ b/core/tests/Drupal/Tests/PhpunitCompatibilityTraitTest.php @@ -3,13 +3,13 @@ namespace Drupal\Tests; /** - * Test the PHPUnit 5 forward compatibility trait. + * Test the PHPUnit forward compatibility trait. * - * @coversDefaultClass \Drupal\Tests\Phpunit5FCTrait + * @coversDefaultClass \Drupal\Tests\PhpunitCompatibilityTrait * @group simpletest * @group Tests */ -class Phpunit5FCTraitTest extends UnitTestCase { +class PhpunitCompatibilityTraitTest extends UnitTestCase { /** * Test that getMock is available and calls the correct parent method. @@ -42,8 +42,8 @@ public function providerMockVersions() { return [ [UnitTestCasePhpunit4TestClass::class, 'PHPUnit 4'], [UnitTestCasePhpunit4TestClassExtends::class, 'PHPUnit 4'], - [UnitTestCasePhpunit5TestClass::class, 'PHPUnit 5'], - [UnitTestCasePhpunit5TestClassExtends::class, 'PHPUnit 5'], + [UnitTestCasePhpunit6TestClass::class, 'PHPUnit 6'], + [UnitTestCasePhpunit6TestClassExtends::class, 'PHPUnit 6'], ]; } @@ -62,9 +62,9 @@ public function getMock($originalClassName) { /** * Test class for \PHPUnit\Framework\TestCase in PHPUnit 5. */ -class Phpunit5TestClass { +class Phpunit6TestClass { public function createMock($originalClassName) { - throw new \Exception('This method should never be called'); + return 'PHPUnit 6'; } public function getMockbuilder() { @@ -79,7 +79,7 @@ public function __call($name, $arguments) { } public function getMock() { - return 'PHPUnit 5'; + return 'PHPUnit 6'; } } @@ -88,7 +88,7 @@ public function getMock() { * Test class for \Drupal\Tests\UnitTestCase with PHPUnit 4. */ class UnitTestCasePhpunit4TestClass extends Phpunit4TestClass { - use Phpunit5FCTrait; + use PhpunitCompatibilityTrait; } @@ -101,13 +101,13 @@ class UnitTestCasePhpunit4TestClassExtends extends UnitTestCasePhpunit4TestClass /** * Test class for \Drupal\Tests\UnitTestCase with PHPUnit 5. */ -class UnitTestCasePhpunit5TestClass extends Phpunit5TestClass { - use Phpunit5FCTrait; +class UnitTestCasePhpunit6TestClass extends Phpunit6TestClass { + use PhpunitCompatibilityTrait; } /** * Test class for \Drupal\Tests\UnitTestCase with PHPUnit 5. */ -class UnitTestCasePhpunit5TestClassExtends extends UnitTestCasePhpunit5TestClass { +class UnitTestCasePhpunit6TestClassExtends extends UnitTestCasePhpunit6TestClass { } diff --git a/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php b/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php index 4c289e4d78..41a98419ee 100644 --- a/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php +++ b/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php @@ -34,6 +34,13 @@ protected function getFilesystem() { ], 'Tests' => [ 'CoreUnitTest.php' => ' [ + 'Listener.php' => ' [ + 'Listener.php' => 'invokeArgs($stub, [vfsStream::url('root'), $suite_namespace]); // Determine if we loaded the expected test files. - $this->assertNotEmpty($stub->testFiles); - $this->assertEmpty(array_diff_assoc($expected_tests, $stub->testFiles)); + $this->assertEquals($expected_tests, $stub->testFiles); } /** diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php index b4ac0c3805..58173e540f 100644 --- a/core/tests/Drupal/Tests/UnitTestCase.php +++ b/core/tests/Drupal/Tests/UnitTestCase.php @@ -17,7 +17,7 @@ */ abstract class UnitTestCase extends TestCase { - use Phpunit5FCTrait; + use PhpunitCompatibilityTrait; /** * The random generator. diff --git a/core/tests/TestSuites/TestSuiteBase.php b/core/tests/TestSuites/TestSuiteBase.php index 3f4dc32933..e5925debb9 100644 --- a/core/tests/TestSuites/TestSuiteBase.php +++ b/core/tests/TestSuites/TestSuiteBase.php @@ -44,7 +44,7 @@ protected function addTestsBySuiteNamespace($root, $suite_namespace) { $tests = TestDiscovery::scanDirectory("Drupal\\Tests\\", "$root/core/tests/Drupal/Tests"); $tests = array_filter($tests, function ($test) use ($root) { // The Listeners directory does not contain tests. - return !preg_match("@^$root/core/tests/Drupal/Tests/Listeners/@", dirname($test)); + return !preg_match("@^$root/core/tests/Drupal/Tests/Listeners(/|$)@", dirname($test)); }); $this->addTestFiles($tests); } diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php index f2edbd2d97..731110aba0 100644 --- a/core/tests/bootstrap.php +++ b/core/tests/bootstrap.php @@ -180,6 +180,9 @@ class_alias('\PHPUnit\Framework\Error\Warning', '\PHPUnit_Framework_Error_Warnin if (!class_exists('\PHPUnit_Framework_Error') && class_exists('\PHPUnit\Framework\Error\Error')) { class_alias('\PHPUnit\Framework\Error\Error', '\PHPUnit_Framework_Error'); } +if (!class_exists('\PHPUnit_Framework_TestCase') && class_exists('\PHPUnit\Framework\TestCase')) { + class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase'); +} if (!class_exists('\PHPUnit_Util_Test') && class_exists('\PHPUnit\Util\Test')) { class_alias('\PHPUnit\Util\Test', '\PHPUnit_Util_Test'); }