Skip to content

Commit c8bfed8

Browse files
committed
Fix object as part of a multi type property (fixes #51)
1 parent 898887e commit c8bfed8

File tree

5 files changed

+97
-5
lines changed

5 files changed

+97
-5
lines changed

src/PropertyProcessor/Property/MultiTypeProcessor.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public function __construct(
5353
parent::__construct($propertyMetaDataCollection, $schemaProcessor, $schema);
5454

5555
foreach ($types as $type) {
56-
$this->propertyProcessors[] = $propertyProcessorFactory->getProcessor(
56+
$this->propertyProcessors[$type] = $propertyProcessorFactory->getProcessor(
5757
$type,
5858
$propertyMetaDataCollection,
5959
$schemaProcessor,
@@ -161,7 +161,9 @@ protected function processSubProperties(
161161
unset($json['default']);
162162
}
163163

164-
foreach ($this->propertyProcessors as $propertyProcessor) {
164+
foreach ($this->propertyProcessors as $type => $propertyProcessor) {
165+
$json['type'] = $type;
166+
165167
$subProperty = $propertyProcessor->process($propertyName, $propertySchema->withJson($json));
166168
$this->transferValidators($subProperty, $property);
167169

src/SchemaProvider/RecursiveDirectoryProvider.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use PHPModelGenerator\Model\SchemaDefinition\JsonSchema;
1010
use RecursiveDirectoryIterator;
1111
use RecursiveIteratorIterator;
12-
use RecursiveRegexIterator;
1312
use RegexIterator;
1413

1514
/**

src/Templates/Validator/ComposedItem.phptpl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,16 @@
8080
{% endif %}
8181

8282
{% if not generatorConfiguration.collectErrors() %}
83-
isset($validatorIndex) ? $this->_propertyValidationState[$validatorIndex][$validatorComponentIndex] = true : null;
83+
if (isset($validatorIndex)) {
84+
$this->_propertyValidationState[$validatorIndex][$validatorComponentIndex] = true;
85+
}
8486
{% endif %}
8587
}
8688
} catch (\Exception $e) {
8789
{% if not generatorConfiguration.collectErrors() %}
88-
isset($validatorIndex) ? $this->_propertyValidationState[$validatorIndex][$validatorComponentIndex] = false : null;
90+
if (isset($validatorIndex)) {
91+
$this->_propertyValidationState[$validatorIndex][$validatorComponentIndex] = false;
92+
}
8993
{% endif %}
9094

9195
{% foreach compositionProperty.getAffectedObjectProperties() as affectedObjectProperty %}

tests/Objects/MultiTypePropertyTest.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,76 @@ public function invalidValueDataProvider()
140140
]
141141
];
142142
}
143+
144+
/**
145+
* @dataProvider nestedObjectDataProvider
146+
*/
147+
public function testValidNestedObjectInMultiTypePropertyIsValidWithNestedObjectProvided(
148+
?array $propertyValue,
149+
?string $expected
150+
): void {
151+
$className = $this->generateClassFromFile('MultiTypeObjectProperty.json');
152+
153+
$object = new $className(['property' => $propertyValue]);
154+
155+
if ($propertyValue === null) {
156+
$this->assertNull($object->getProperty());
157+
} else {
158+
$this->assertIsObject($object->getProperty());
159+
$this->assertSame($expected, $object->getProperty()->getName());
160+
}
161+
}
162+
163+
public function nestedObjectDataProvider(): array
164+
{
165+
return [
166+
'not provided' => [null, null],
167+
'empty nested object' => [[], null],
168+
'empty string' => [['name' => ''], ''],
169+
'name provided' => [['name' => 'Hans'], 'Hans'],
170+
];
171+
}
172+
173+
public function testStringForMultiTypePropertyWithNestedObjectIsValid(): void
174+
{
175+
$className = $this->generateClassFromFile('MultiTypeObjectProperty.json');
176+
177+
$object = new $className(['property' => 'Hello']);
178+
$this->assertSame('Hello', $object->getProperty());
179+
}
180+
181+
/**
182+
* @dataProvider invalidNestedObjectDataProvider
183+
*/
184+
public function testInvalidNestedObjectInMultiTypePropertyThrowsAnException(
185+
array $propertyValue,
186+
string $exceptionMessage
187+
): void {
188+
$this->expectException(ValidationException::class);
189+
$this->expectExceptionMessageMatches("/$exceptionMessage/");
190+
191+
$className = $this->generateClassFromFile('MultiTypeObjectProperty.json');
192+
193+
new $className(['property' => $propertyValue]);
194+
}
195+
196+
public function invalidNestedObjectDataProvider(): array
197+
{
198+
return [
199+
'invalid type' => [
200+
['name' => 42],
201+
<<<ERROR
202+
Invalid nested object for property property:
203+
- Invalid type for name. Requires string, got integer
204+
ERROR,
205+
],
206+
'invalid additional property' => [
207+
['name' => 'Hans', 'age' => 42],
208+
<<<ERROR
209+
Invalid nested object for property property:
210+
- Provided JSON for MultiTypePropertyTest_\w+ contains not allowed additional properties \[age\]
211+
ERROR,
212+
],
213+
];
214+
}
143215
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"property": {
5+
"type": ["string", "object"],
6+
"minLength": 4,
7+
"properties": {
8+
"name": {
9+
"type": "string"
10+
}
11+
},
12+
"additionalProperties": false
13+
}
14+
}
15+
}

0 commit comments

Comments
 (0)