From fc085b7c3b147bc03b37cceacb3545bac5bc6b20 Mon Sep 17 00:00:00 2001 From: PeeHaa Date: Tue, 1 Sep 2015 03:32:12 +0200 Subject: [PATCH] Fixed blacklisted method names for php 7 --- src/Framework/MockObject/Generator.php | 41 ++++++++++++++++++- tests/GeneratorTest.php | 21 ++++++++++ .../InterfaceWithSemiReservedMethodName.php | 5 +++ 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 tests/_fixture/InterfaceWithSemiReservedMethodName.php diff --git a/src/Framework/MockObject/Generator.php b/src/Framework/MockObject/Generator.php index 56828a66..c03ed80e 100644 --- a/src/Framework/MockObject/Generator.php +++ b/src/Framework/MockObject/Generator.php @@ -34,7 +34,7 @@ class PHPUnit_Framework_MockObject_Generator /** * @var array */ - protected $blacklistedMethodNames = [ + protected $legacyBlacklistedMethodNames = [ '__CLASS__' => true, '__DIR__' => true, '__FILE__' => true, @@ -112,6 +112,22 @@ class PHPUnit_Framework_MockObject_Generator 'xor' => true ]; + /** + * @var array + */ + protected $blacklistedMethodNames = [ + '__CLASS__' => true, + '__DIR__' => true, + '__FILE__' => true, + '__FUNCTION__' => true, + '__LINE__' => true, + '__METHOD__' => true, + '__NAMESPACE__' => true, + '__TRAIT__' => true, + '__clone' => true, + '__halt_compiler' => true, + ]; + /** * Returns a mock object for the specified class. * @@ -998,13 +1014,34 @@ protected function canMockMethod(ReflectionMethod $method) if ($method->isConstructor() || $method->isFinal() || $method->isPrivate() || - isset($this->blacklistedMethodNames[$method->getName()])) { + $this->isMethodNameBlacklisted($method->getName())) { return false; } return true; } + /** + * Returns whether i method name is blacklisted + * + * Since PHP 7 the only names that are still reserved for method names are the ones that start with an underscore + * + * @param string $name + * @return boolean + */ + protected function isMethodNameBlacklisted($name) + { + if (PHP_MAJOR_VERSION < 7 && isset($this->legacyBlacklistedMethodNames[$name])) { + return true; + } + + if (PHP_MAJOR_VERSION >= 7 && isset($this->blacklistedMethodNames[$name])) { + return true; + } + + return false; + } + /** * Returns the parameters of a function or method. * diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index e0aa9ad4..17630fc9 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -39,6 +39,27 @@ public function testGetMockGeneratorFails() $mock = $this->generator->getMock('StdClass', ['foo', 'foo']); } + /** + * @covers PHPUnit_Framework_MockObject_Generator::getMock + * @covers PHPUnit_Framework_MockObject_Generator::isMethodNameBlacklisted + */ + public function testGetMockBlacklistedMethodNamesPhp7() + { + if (PHP_MAJOR_VERSION < 7) { + $this->markTestSkipped('PHP >= 7.0.0 required'); + + return; + } + + // Probably, this should be moved to tests/autoload.php + require_once __DIR__ . '/_fixture/InterfaceWithSemiReservedMethodName.php'; + + $mock = $this->generator->getMock('InterfaceWithSemiReservedMethodName'); + + $this->assertTrue(method_exists($mock, 'unset')); + $this->assertInstanceOf('InterfaceWithSemiReservedMethodName', $mock); + } + /** * @covers PHPUnit_Framework_MockObject_Generator::getMockForAbstractClass */ diff --git a/tests/_fixture/InterfaceWithSemiReservedMethodName.php b/tests/_fixture/InterfaceWithSemiReservedMethodName.php new file mode 100644 index 00000000..bcef2942 --- /dev/null +++ b/tests/_fixture/InterfaceWithSemiReservedMethodName.php @@ -0,0 +1,5 @@ +