Skip to content

Commit 365eaa6

Browse files
AbstractCallHandler: Check data type when setting a property in an object.
1 parent 2645657 commit 365eaa6

5 files changed

Lines changed: 57 additions & 5 deletions

File tree

src/Magic/AbstractCallHandler.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212

1313
namespace ScaleUpStack\EasyObject\Magic;
1414

15+
use ScaleUpStack\Metadata\FeatureAnalyzers\TypedProperties;
16+
use ScaleUpStack\Metadata\FeatureAnalyzers\TypedPropertyMetadata;
1517
use ScaleUpStack\Metadata\FeatureAnalyzers\VirtualMethods;
1618
use ScaleUpStack\Metadata\FeatureAnalyzers\VirtualMethodMetadata;
1719
use ScaleUpStack\Metadata\Metadata\ClassMetadata;
18-
use ScaleUpStack\Metadata\Metadata\PropertyMetadata;
1920
use ScaleUpStack\Reflection\Reflection;
2021

2122
abstract class AbstractCallHandler implements CallHandler
@@ -94,8 +95,24 @@ protected function propertyName(
9495
return null;
9596
}
9697

97-
protected function setProperty(object $object, string $propertyName, $value, PropertyMetadata $propertyMetadata)
98+
protected function setProperty(object $object, string $propertyName, $value, ClassMetadata $classMetadata)
9899
{
100+
/** @var TypedPropertyMetadata $typedPropertyMetadata */
101+
$typedPropertyMetadata = $classMetadata->features[TypedProperties::class][$propertyName];
102+
$isValid = $typedPropertyMetadata->docBlockDataTypeMetadata()->validateVariable($value, $object);
103+
104+
if (! $isValid) {
105+
throw new \TypeError(
106+
sprintf(
107+
"Value for property %s::\$%s must be of the type %s, %s given",
108+
get_class($object),
109+
$propertyName,
110+
$typedPropertyMetadata->docBlockDataTypeMetadata()->declaration(),
111+
gettype($value)
112+
)
113+
);
114+
}
115+
99116
Reflection::setPropertyValue($object, $propertyName, $value);
100117
}
101118
}

src/Magic/FixtureBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ private function executeBuild(object $object, ClassMetadata $toBeBuildClassMetad
111111
$value = eval($phpString);
112112
}
113113

114-
$this->setProperty($newObject, $propertyName, $value, $propertyMetadata);
114+
$this->setProperty($newObject, $propertyName, $value, $toBeBuildClassMetadata);
115115
}
116116

117117
return $newObject;

src/Magic/NamedConstructor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public function execute($objectOrClassName, string $methodName, array $arguments
9797
$newObject,
9898
$propertyMetadata->name,
9999
$arguments[$counter],
100-
$propertyMetadata
100+
$classMetadata
101101
);
102102

103103
$counter++;

tests/PhpUnit/Magic/AbstractCallHandlerTest.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public function it_sets_the_value_of_an_object_when_type_matches()
141141
$object,
142142
$propertyName,
143143
$newValue,
144-
$this->classMetadata->propertyMetadata[$propertyName]
144+
$this->classMetadata
145145
);
146146

147147
// then the property of the object is set
@@ -150,4 +150,37 @@ public function it_sets_the_value_of_an_object_when_type_matches()
150150
Reflection::getPropertyValue($object, 'someProperty')
151151
);
152152
}
153+
154+
/**
155+
* @test
156+
* @covers ::setProperty()
157+
*/
158+
public function it_throws_an_exception_when_setting_the_property_of_an_object_with_an_invalid_type()
159+
{
160+
// given a mocked AbstractCallHandler, and ClassMetadata of some object as provided in setUp(),
161+
// and some object, a property name, and an invalid value
162+
$object = new ClassForAbstractCallHandlerTesting();
163+
$propertyName = 'someProperty';
164+
$invalidValue = 42;
165+
166+
// when requesting the property name
167+
// then an Exception is thrown
168+
$this->expectException(\TypeError::class);
169+
$this->expectExceptionMessage(
170+
sprintf(
171+
"Value for property %s::\$%s must be of the type string, integer given",
172+
ClassForAbstractCallHandlerTesting::class,
173+
$propertyName
174+
)
175+
);
176+
177+
Reflection::methodOfClass(AbstractCallHandler::class, 'setProperty')
178+
->invoke(
179+
$this->callHandler,
180+
$object,
181+
$propertyName,
182+
$invalidValue,
183+
$this->classMetadata
184+
);
185+
}
153186
}

tests/bootstrap.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
*/
1414

1515
use ScaleUpStack\Metadata\Configuration;
16+
use ScaleUpStack\Metadata\FeatureAnalyzers\TypedProperties;
1617
use ScaleUpStack\Metadata\FeatureAnalyzers\VirtualMethods;
1718

1819
require_once __DIR__ . '/../vendor/autoload.php';
1920

2021
// register FeatureAnalyzers in ScaleUpStack\Metadata\Configuration
2122
Configuration::registerFeatureAnalyzer(new VirtualMethods());
23+
Configuration::registerFeatureAnalyzer(new TypedProperties());

0 commit comments

Comments
 (0)