Skip to content

Commit 154be05

Browse files
author
Enno Woortmann
committed
Fix incomplete tuple validation
1 parent 019aac5 commit 154be05

File tree

4 files changed

+50
-32
lines changed

4 files changed

+50
-32
lines changed

docs/source/complexTypes/array.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,6 @@ Items
146146
}
147147
}
148148
149-
Possible exceptions:
150-
151-
* Missing tuple item in array example. Requires 2 items, got 1
152-
153149
If invalid tuples are provided a detailed exception will be thrown containing all violations:
154150

155151
.. code-block:: none
@@ -160,6 +156,10 @@ If invalid tuples are provided a detailed exception will be thrown containing al
160156
- invalid tuple #1
161157
* Invalid type for name. Requires string, got boolean
162158
159+
.. hint::
160+
161+
Incomplete tuples are valid. Consequently an empty array provided for the schema shown above would pass the validation. Keep this in mind when designing tuple constraints. To force the given data to provide all tuples use tuple items combined with the `minItems` array size validation.
162+
163163
Additional items
164164
^^^^^^^^^^^^^^^^
165165

src/PropertyProcessor/Property/ArrayProcessor.php

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -154,27 +154,14 @@ private function addTupleValidator(PropertyInterface $property, array $propertyD
154154
$this->addAdditionalItemsValidator($property, $propertyData);
155155
}
156156

157-
$tupleCount = count($propertyData[self::JSON_FIELD_ITEMS]);
158-
159-
$property
160-
->addValidator(
161-
new PropertyValidator(
162-
'is_array($value) && ($amount = count($value)) < ' . $tupleCount,
163-
sprintf(
164-
'Missing tuple item in array %s. Requires %s items, got $amount',
165-
$property->getName(),
166-
$tupleCount
167-
)
168-
)
157+
$property->addValidator(
158+
new ArrayTupleValidator(
159+
$this->schemaProcessor,
160+
$this->schema,
161+
$propertyData[self::JSON_FIELD_ITEMS],
162+
$property->getName()
169163
)
170-
->addValidator(
171-
new ArrayTupleValidator(
172-
$this->schemaProcessor,
173-
$this->schema,
174-
$propertyData[self::JSON_FIELD_ITEMS],
175-
$property->getName()
176-
)
177-
);
164+
);
178165
}
179166

180167
/**

src/Templates/Validator/ArrayTuple.phptpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ is_array($value) && (function (&$items) use (&$invalidTuples) {
77
{% foreach tupleProperties as tuple %}
88
// ---------------- validate a single tuple of the array ------------------
99
try {
10+
if ($index === count($items)) {
11+
return !empty($invalidTuples);
12+
}
13+
1014
{% if generatorConfiguration.collectErrors() %}
1115
$this->errorRegistry = new {{ viewHelper.getSimpleClassName(generatorConfiguration.getErrorRegistryClass()) }}();
1216
{% endif %}

tests/Objects/TupleArrayPropertyTest.php

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
class TupleArrayPropertyTest extends AbstractPHPModelGeneratorTest
1818
{
1919
/**
20+
* @dataProvider validIncompleteTupleArrayDataProvider
2021
* @dataProvider validTupleArrayDataProvider
2122
* @dataProvider validTupleArrayWithAdditionalPropertiesDataProvider
2223
*
@@ -29,11 +30,33 @@ public function testValidValuesForTupleArray(GeneratorConfiguration $configurati
2930

3031
$object = new $className(['property' => $propertyValue]);
3132

32-
$this->assertSame($propertyValue[0], $object->getProperty()[0]);
33-
$this->assertSame($propertyValue[1], $object->getProperty()[1]);
34-
$this->assertSame($propertyValue[2]['name'], $object->getProperty()[2]->getName());
35-
$this->assertSame($propertyValue[2]['age'] ?? null, $object->getProperty()[2]->getAge());
36-
$this->assertSame($propertyValue[2], $object->getProperty()[2]->getRawModelDataInput());
33+
if (count($propertyValue) > 0) {
34+
$this->assertSame($propertyValue[0], $object->getProperty()[0]);
35+
} else {
36+
$this->assertSame([], $object->getProperty());
37+
}
38+
39+
if (count($propertyValue) > 1) {
40+
$this->assertSame($propertyValue[1], $object->getProperty()[1]);
41+
}
42+
43+
if (count($propertyValue) > 2) {
44+
$this->assertSame($propertyValue[2]['name'], $object->getProperty()[2]->getName());
45+
$this->assertSame($propertyValue[2]['age'] ?? null, $object->getProperty()[2]->getAge());
46+
$this->assertSame($propertyValue[2], $object->getProperty()[2]->getRawModelDataInput());
47+
}
48+
}
49+
50+
public function validIncompleteTupleArrayDataProvider(): array
51+
{
52+
return $this->combineDataProvider(
53+
$this->validationMethodDataProvider(),
54+
[
55+
'empty array' => [[]],
56+
'only one value' => [[4]],
57+
'multiple values' => [[100, 'Avenue']],
58+
]
59+
);
3760
}
3861

3962
public function validTupleArrayDataProvider(): array
@@ -104,9 +127,13 @@ public function invalidTupleArrayDataProvider(): array
104127
return $this->combineDataProvider(
105128
$this->validationMethodDataProvider(),
106129
[
107-
'empty array' => [
108-
[],
109-
'Missing tuple item in array property. Requires 3 items, got 0'
130+
'not all elements invalid type' => [
131+
[400, ''],
132+
<<<ERROR
133+
Invalid tuple item in array property:
134+
- invalid tuple #2
135+
* Invalid value for tuple item #1 of array property declined by enum constraint
136+
ERROR
110137
],
111138
'invalid type' => [
112139
['400', 'Avenue', ['name' => 'Hans', 'age' => 42]],

0 commit comments

Comments
 (0)