Skip to content

Commit 2cdd9a1

Browse files
committed
Add test cases for OneOf composition
Unset model values transferred from failing compositions
1 parent ece7534 commit 2cdd9a1

17 files changed

+511
-84
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace PHPModelGenerator\Model\Property;
6+
7+
use PHPModelGenerator\Model\ResolvedDefinitionsCollection;
8+
9+
/**
10+
* Class CompositionPropertyDecorator
11+
*
12+
* @package PHPModelGenerator\Model\Property
13+
*/
14+
class CompositionPropertyDecorator extends PropertyProxy
15+
{
16+
private const PROPERTY_KEY = 'composition';
17+
18+
/**
19+
* Store all properties from nested schemas of the composed property validator. If the composition validator fails
20+
* all affected properties must be set to null to adopt only valid values in the base model.
21+
*
22+
* @var PropertyInterface[]
23+
*/
24+
protected $affectedObjectProperties = [];
25+
26+
/**
27+
* CompositionPropertyDecorator constructor.
28+
*
29+
* @param PropertyInterface $property
30+
*/
31+
public function __construct(PropertyInterface $property)
32+
{
33+
parent::__construct(new ResolvedDefinitionsCollection([self::PROPERTY_KEY => $property]), self::PROPERTY_KEY);
34+
}
35+
36+
/**
37+
* Append an object property which is affected by the composition validator
38+
*
39+
* @param PropertyInterface $property
40+
*/
41+
public function appendAffectedObjectProperty(PropertyInterface $property)
42+
{
43+
$this->affectedObjectProperties[] = $property;
44+
}
45+
46+
/**
47+
* @return PropertyInterface[]
48+
*/
49+
public function getAffectedObjectProperties(): array
50+
{
51+
return $this->affectedObjectProperties;
52+
}
53+
}

src/Model/ResolvedDefinitionsCollection.php

Lines changed: 4 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -4,68 +4,8 @@
44

55
namespace PHPModelGenerator\Model;
66

7-
class ResolvedDefinitionsCollection
8-
{
9-
protected $t;
10-
/**
11-
* Whether a offset exists
12-
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
13-
* @param mixed $offset <p>
14-
* An offset to check for.
15-
* </p>
16-
* @return boolean true on success or false on failure.
17-
* </p>
18-
* <p>
19-
* The return value will be casted to boolean if non-boolean was returned.
20-
* @since 5.0.0
21-
*/
22-
public function offsetExists($offset)
23-
{
24-
return isset($this->t[$offset]);
25-
}
26-
27-
/**
28-
* Offset to retrieve
29-
* @link http://php.net/manual/en/arrayaccess.offsetget.php
30-
* @param mixed $offset <p>
31-
* The offset to retrieve.
32-
* </p>
33-
* @return mixed Can return all value types.
34-
* @since 5.0.0
35-
*/
36-
public function offsetGet($offset)
37-
{
38-
return $this->t[$offset];
39-
}
7+
use ArrayObject;
408

41-
/**
42-
* Offset to set
43-
* @link http://php.net/manual/en/arrayaccess.offsetset.php
44-
* @param mixed $offset <p>
45-
* The offset to assign the value to.
46-
* </p>
47-
* @param mixed $value <p>
48-
* The value to set.
49-
* </p>
50-
* @return void
51-
* @since 5.0.0
52-
*/
53-
public function offsetSet($offset, $value)
54-
{
55-
$this->t[$offset] = $value;
56-
}
57-
58-
/**
59-
* Offset to unset
60-
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
61-
* @param mixed $offset <p>
62-
* The offset to unset.
63-
* </p>
64-
* @return void
65-
* @since 5.0.0
66-
*/
67-
public function offsetUnset($offset)
68-
{
69-
unset($this->t[$offset]);
70-
}
71-
}
9+
class ResolvedDefinitionsCollection extends ArrayObject
10+
{
11+
}

src/Model/Validator/ComposedPropertyValidator.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace PHPModelGenerator\Model\Validator;
66

77
use PHPModelGenerator\Exception\InvalidArgumentException;
8+
use PHPModelGenerator\Model\Property\CompositionPropertyDecorator;
89
use PHPModelGenerator\Model\Property\PropertyInterface;
910

1011
/**
@@ -16,16 +17,16 @@ class ComposedPropertyValidator extends PropertyTemplateValidator
1617
{
1718
/** @var string */
1819
protected $composedProcessor;
19-
/** @var PropertyInterface[] */
20+
/** @var CompositionPropertyDecorator[] */
2021
protected $composedProperties;
2122

2223
/**
2324
* ComposedPropertyValidator constructor.
2425
*
25-
* @param PropertyInterface $property
26-
* @param PropertyInterface[] $composedProperties
27-
* @param string $composedProcessor
28-
* @param array $validatorVariables
26+
* @param PropertyInterface $property
27+
* @param CompositionPropertyDecorator[] $composedProperties
28+
* @param string $composedProcessor
29+
* @param array $validatorVariables
2930
*/
3031
public function __construct(
3132
PropertyInterface $property,
@@ -53,7 +54,7 @@ public function getComposedProcessor(): string
5354
}
5455

5556
/**
56-
* @return PropertyInterface[]
57+
* @return CompositionPropertyDecorator[]
5758
*/
5859
public function getComposedProperties(): array
5960
{

src/PropertyProcessor/ComposedValue/AbstractComposedValueProcessor.php

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
<?php
22

3+
declare(strict_types = 1);
4+
35
namespace PHPModelGenerator\PropertyProcessor\ComposedValue;
46

7+
use PHPModelGenerator\Model\Property\CompositionPropertyDecorator;
58
use PHPModelGenerator\Model\Property\PropertyInterface;
69
use PHPModelGenerator\Model\Validator;
710
use PHPModelGenerator\Model\Validator\ComposedPropertyValidator;
@@ -29,14 +32,16 @@ protected function generateValidators(PropertyInterface $property, array $proper
2932
$properties = [];
3033

3134
foreach ($propertyData['composition'] as $compositionElement) {
32-
$compositionProperty = $propertyFactory
33-
->create(
34-
new PropertyCollectionProcessor([$property->getName() => $property->isRequired()]),
35-
$this->schemaProcessor,
36-
$this->schema,
37-
$property->getName(),
38-
$compositionElement
39-
);
35+
$compositionProperty = new CompositionPropertyDecorator(
36+
$propertyFactory
37+
->create(
38+
new PropertyCollectionProcessor([$property->getName() => $property->isRequired()]),
39+
$this->schemaProcessor,
40+
$this->schema,
41+
$property->getName(),
42+
$compositionElement
43+
)
44+
);
4045

4146
$compositionProperty->filterValidators(function (Validator $validator) {
4247
return !is_a($validator->getValidator(), RequiredPropertyValidator::class) &&

src/PropertyProcessor/ComposedValue/AllOfProcessor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace PHPModelGenerator\PropertyProcessor\ComposedValue;
44

55
/**
6-
* Class AllofProcessor
6+
* Class AllOfProcessor
77
*
88
* @package PHPModelGenerator\PropertyProcessor\ComposedValue
99
*/

src/PropertyProcessor/ComposedValue/AnyOfProcessor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace PHPModelGenerator\PropertyProcessor\ComposedValue;
44

55
/**
6-
* Class AnyofProcessor
6+
* Class AnyOfProcessor
77
*
88
* @package PHPModelGenerator\PropertyProcessor\ComposedValue
99
*/

src/PropertyProcessor/ComposedValue/OneOfProcessor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace PHPModelGenerator\PropertyProcessor\ComposedValue;
44

55
/**
6-
* Class OneofProcessor
6+
* Class OneOfProcessor
77
*
88
* @package PHPModelGenerator\PropertyProcessor\ComposedValue
99
*/

src/PropertyProcessor/Property/AbstractPropertyProcessor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ protected function addComposedValueValidator(PropertyInterface $property, array
114114
$property->getName(),
115115
[
116116
'type' => $composedValueKeyword,
117-
'composition' => $propertyData[$composedValueKeyword]
117+
'composition' => $propertyData[$composedValueKeyword],
118118
]
119119
);
120120

src/PropertyProcessor/Property/BaseProcessor.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ protected function transferComposedPropertiesToSchema(PropertyInterface $propert
197197
!is_a($validator->getValidator(), TypeCheckValidator::class);
198198
})
199199
);
200+
201+
$composedProperty->appendAffectedObjectProperty($property);
200202
}
201203
}
202204
}

src/SchemaProcessor/SchemaProcessor.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ public function processSchema(
9999
if ((!isset($jsonSchema['type']) || $jsonSchema['type'] !== 'object') &&
100100
!array_intersect(array_keys($jsonSchema), ['anyOf', 'allOf', 'oneOf'])
101101
) {
102-
throw new SchemaException("JSON-Schema doesn't provide an object " . $jsonSchema['id'] ?? '');
102+
throw new SchemaException(
103+
"JSON-Schema doesn't provide an object or a composition " . $jsonSchema['id'] ?? ''
104+
);
103105
}
104106

105107
return $this->generateModel($classPath, $className, $jsonSchema, $parentDefinitions);

0 commit comments

Comments
 (0)