From 2d6a2f1b16f06b247dce09a1981afa595fe8bf72 Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Mon, 9 Mar 2015 15:38:41 +1100 Subject: [PATCH 1/5] testSetAProtectedPropertyWhenCreatingTheMock --- src/Concise/Mock/MockBuilder.php | 2 +- src/Concise/TestCase.php | 11 ++++++++--- tests/Concise/Mock/BuilderPropertyTest.php | 13 +++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/Concise/Mock/MockBuilder.php b/src/Concise/Mock/MockBuilder.php index 1ef2b156..39958e09 100644 --- a/src/Concise/Mock/MockBuilder.php +++ b/src/Concise/Mock/MockBuilder.php @@ -195,7 +195,7 @@ public function get() $this->restoreState($mockInstance); foreach ($this->properties as $name => $value) { - $mockInstance->$name = $value; + $this->testCase->setProperty($mockInstance, $name, $value); } return $mockInstance; diff --git a/src/Concise/TestCase.php b/src/Concise/TestCase.php index 9087589e..01a7eecb 100644 --- a/src/Concise/TestCase.php +++ b/src/Concise/TestCase.php @@ -12,6 +12,7 @@ use PHPUnit_Framework_TestCase; use ReflectionClass; use Concise\Mock\MockInterface; +use ReflectionException; // Load the keyword cache before the test suite begins. Keywords::load(); @@ -268,10 +269,14 @@ public function getProperty($object, $property) return $property->getValue($object); } - public function setProperty($object, $property, $value) + public function setProperty($object, $name, $value) { - $property = $this->getReflectionProperty($object, $property); - $property->setValue($object, $value); + try { + $property = $this->getReflectionProperty($object, $name); + $property->setValue($object, $value); + } catch (ReflectionException $e) { + $object->$name = $value; + } } /** diff --git a/tests/Concise/Mock/BuilderPropertyTest.php b/tests/Concise/Mock/BuilderPropertyTest.php index a7cc3c62..18b80736 100644 --- a/tests/Concise/Mock/BuilderPropertyTest.php +++ b/tests/Concise/Mock/BuilderPropertyTest.php @@ -138,4 +138,17 @@ public function testAPropertyNameMustBeAString(MockBuilder $builder, $type) { $builder->setProperty(123, 456); } + + /** + * @dataProvider allBuilders + */ + public function testSetAProtectedPropertyWhenCreatingTheMock(MockBuilder $builder, $type) + { + if (self::MOCK_INTERFACE === $type) { + $this->expectFailure("You cannot set a property on an interface"); + } + $mock = $builder->setProperty('hidden', 'bar') + ->get(); + $this->assert($this->getProperty($mock, 'hidden'), equals, 'bar'); + } } From 195f611a34a1a5605146ce2b994845c91474e84d Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Mon, 9 Mar 2015 15:45:47 +1100 Subject: [PATCH 2/5] testSetAPropertyThatDoesNotExistIsPermitted --- src/Concise/TestCase.php | 12 ++++++++++-- tests/Concise/Mock/BuilderPropertyTest.php | 13 +++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Concise/TestCase.php b/src/Concise/TestCase.php index 01a7eecb..377c8b2e 100644 --- a/src/Concise/TestCase.php +++ b/src/Concise/TestCase.php @@ -265,8 +265,16 @@ protected function getReflectionProperty($object, $property) public function getProperty($object, $property) { - $property = $this->getReflectionProperty($object, $property); - return $property->getValue($object); + try { + $property = $this->getReflectionProperty($object, $property); + return $property->getValue($object); + } catch (ReflectionException $e) { + if (isset($object->$property)) { + return $object->$property; + } + + throw $e; + } } public function setProperty($object, $name, $value) diff --git a/tests/Concise/Mock/BuilderPropertyTest.php b/tests/Concise/Mock/BuilderPropertyTest.php index 18b80736..2de94d87 100644 --- a/tests/Concise/Mock/BuilderPropertyTest.php +++ b/tests/Concise/Mock/BuilderPropertyTest.php @@ -151,4 +151,17 @@ public function testSetAProtectedPropertyWhenCreatingTheMock(MockBuilder $builde ->get(); $this->assert($this->getProperty($mock, 'hidden'), equals, 'bar'); } + + /** + * @dataProvider allBuilders + */ + public function testSetAPropertyThatDoesNotExistIsPermitted(MockBuilder $builder, $type) + { + if (self::MOCK_INTERFACE === $type) { + $this->expectFailure("You cannot set a property on an interface"); + } + $mock = $builder->setProperty('does_not_exist', 'bar') + ->get(); + $this->assert($this->getProperty($mock, 'does_not_exist'), equals, 'bar'); + } } From b746d7ee150411ecfa733ca4479eee13f323fe58 Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Mon, 9 Mar 2015 15:47:34 +1100 Subject: [PATCH 3/5] testNullPropertiesAreStillFound --- src/Concise/TestCase.php | 2 +- tests/Concise/Mock/BuilderPropertyTest.php | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Concise/TestCase.php b/src/Concise/TestCase.php index 377c8b2e..61d827e7 100644 --- a/src/Concise/TestCase.php +++ b/src/Concise/TestCase.php @@ -269,7 +269,7 @@ public function getProperty($object, $property) $property = $this->getReflectionProperty($object, $property); return $property->getValue($object); } catch (ReflectionException $e) { - if (isset($object->$property)) { + if (property_exists($object, $property)) { return $object->$property; } diff --git a/tests/Concise/Mock/BuilderPropertyTest.php b/tests/Concise/Mock/BuilderPropertyTest.php index 2de94d87..18f9b881 100644 --- a/tests/Concise/Mock/BuilderPropertyTest.php +++ b/tests/Concise/Mock/BuilderPropertyTest.php @@ -164,4 +164,17 @@ public function testSetAPropertyThatDoesNotExistIsPermitted(MockBuilder $builder ->get(); $this->assert($this->getProperty($mock, 'does_not_exist'), equals, 'bar'); } + + /** + * @dataProvider allBuilders + */ + public function testNullPropertiesAreStillFound(MockBuilder $builder, $type) + { + if (self::MOCK_INTERFACE === $type) { + $this->expectFailure("You cannot set a property on an interface"); + } + $mock = $builder->setProperty('does_not_exist', null) + ->get(); + $this->assert($this->getProperty($mock, 'does_not_exist'), is_null); + } } From 2fe0c00e32333aa0b61db0f46b8e0fb7bf827aac Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Mon, 9 Mar 2015 15:51:48 +1100 Subject: [PATCH 4/5] testPropertiesAreAlwaysFoundIfClassHasMagicGet --- src/Concise/TestCase.php | 8 +++++++- tests/Concise/Mock/BuilderPropertyTest.php | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Concise/TestCase.php b/src/Concise/TestCase.php index 61d827e7..b5190ed4 100644 --- a/src/Concise/TestCase.php +++ b/src/Concise/TestCase.php @@ -263,13 +263,19 @@ protected function getReflectionProperty($object, $property) return $property; } + protected function shouldAccessProperty($object, $property) + { + return property_exists($object, $property) + || method_exists($object, '__get'); + } + public function getProperty($object, $property) { try { $property = $this->getReflectionProperty($object, $property); return $property->getValue($object); } catch (ReflectionException $e) { - if (property_exists($object, $property)) { + if ($this->shouldAccessProperty($object, $property)) { return $object->$property; } diff --git a/tests/Concise/Mock/BuilderPropertyTest.php b/tests/Concise/Mock/BuilderPropertyTest.php index 18f9b881..e520eefc 100644 --- a/tests/Concise/Mock/BuilderPropertyTest.php +++ b/tests/Concise/Mock/BuilderPropertyTest.php @@ -2,6 +2,14 @@ namespace Concise\Mock; +class MagicGetter +{ + public function __get($name) + { + return 'foo'; + } +} + /** * @group mocking */ @@ -177,4 +185,9 @@ public function testNullPropertiesAreStillFound(MockBuilder $builder, $type) ->get(); $this->assert($this->getProperty($mock, 'does_not_exist'), is_null); } + + public function testPropertiesAreAlwaysFoundIfClassHasMagicGet() + { + $this->assert($this->getProperty(new MagicGetter(), 'does_not_exist'), equals, 'foo'); + } } From efd38d7f3523e11d97159f6f6aadc4d6eb1041cb Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Mon, 9 Mar 2015 15:56:22 +1100 Subject: [PATCH 5/5] testPropertiesAreAlwaysSetIfClassHasMagicSet --- tests/Concise/Mock/BuilderPropertyTest.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/Concise/Mock/BuilderPropertyTest.php b/tests/Concise/Mock/BuilderPropertyTest.php index e520eefc..9a482867 100644 --- a/tests/Concise/Mock/BuilderPropertyTest.php +++ b/tests/Concise/Mock/BuilderPropertyTest.php @@ -2,11 +2,19 @@ namespace Concise\Mock; -class MagicGetter +class MagicProperty { public function __get($name) { - return 'foo'; + if (!property_exists($this, $name)) { + return 'not_found'; + } + return $this->$name; + } + + public function __set($name, $value) + { + $this->$name = $value; } } @@ -188,6 +196,13 @@ public function testNullPropertiesAreStillFound(MockBuilder $builder, $type) public function testPropertiesAreAlwaysFoundIfClassHasMagicGet() { - $this->assert($this->getProperty(new MagicGetter(), 'does_not_exist'), equals, 'foo'); + $this->assert($this->getProperty(new MagicProperty(), 'does_not_exist'), equals, 'not_found'); + } + + public function testPropertiesAreAlwaysSetIfClassHasMagicSet() + { + $object = new MagicProperty(); + $this->setProperty($object, 'foo', 'bar'); + $this->assert($this->getProperty($object, 'foo'), equals, 'bar'); } }