Skip to content

Commit 23d47b1

Browse files
committed
Fix error collection for composition properties
1 parent e6500d8 commit 23d47b1

16 files changed

+662
-318
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ As an optional parameter you can set up a *GeneratorConfiguration* object to con
3737
```php
3838
$generator = new Generator(
3939
(new GeneratorConfiguration())
40-
->setNamespacePrefix('\\MyApp\\Model')
40+
->setNamespacePrefix('\MyApp\Model')
4141
->setImmutable(true)
4242
);
4343

src/Exception/ErrorRegistryException.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ class ErrorRegistryException extends Exception implements ErrorRegistryException
1818
public function addError(string $message): ErrorRegistryExceptionInterface
1919
{
2020
$this->errors[] = $message;
21+
22+
$this->message = join("\n", $this->errors);
23+
2124
return $this;
2225
}
2326

src/Model/RenderJob.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ protected function renderClass(GeneratorConfiguration $generatorConfiguration):
113113
$class = $render->renderTemplate(
114114
'Model.phptpl',
115115
[
116-
'namespace' => empty($namespace) ? '' : "namespace $namespace;",
116+
'namespace' => $namespace,
117117
'use' => empty($use) ? '' : 'use ' . join(";\nuse ", array_unique($use)) . ';',
118118
'class' => $this->className,
119119
'baseValidators' => $this->schema->getBaseValidators(),

src/PropertyProcessor/ComposedValue/AbstractComposedValueProcessor.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ protected function generateValidators(PropertyInterface $property, array $proper
7373
static::class,
7474
[
7575
'properties' => $properties,
76+
'generatorConfiguration' => $this->schemaProcessor->getGeneratorConfiguration(),
7677
'viewHelper' => new RenderHelper($this->schemaProcessor->getGeneratorConfiguration()),
7778
'availableAmount' => $availableAmount,
7879
'composedValueValidation' => $this->getComposedValueValidation($availableAmount),

src/PropertyProcessor/ComposedValue/IfProcessor.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ protected function generateValidators(PropertyInterface $property, array $proper
7070
'ifProperty' => $properties['if'],
7171
'thenProperty' => $properties['then'],
7272
'elseProperty' => $properties['else'],
73+
'generatorConfiguration' => $this->schemaProcessor->getGeneratorConfiguration(),
7374
'viewHelper' => new RenderHelper($this->schemaProcessor->getGeneratorConfiguration()),
7475
'onlyForDefinedValues' => $propertyData['onlyForDefinedValues'],
7576
]

src/Templates/Model.phptpl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
declare(strict_types = 1);
44

5-
{{ namespace }}
5+
{% if namespace %}
6+
namespace {{ namespace }};
7+
{% endif %}
68

79
{{ use }}
810

@@ -12,7 +14,7 @@ declare(strict_types = 1);
1214
* are re-generated.
1315
*
1416
* Class {{ class }}
15-
* @package {{ namespace }}
17+
{% if namespace %} * @package {{ namespace }} {% endif %}
1618
*/
1719
class {{ class }}
1820
{
@@ -38,7 +40,7 @@ class {{ class }}
3840
* @param array $modelData
3941
{% if generatorConfiguration.collectErrors() %}* @param {{ viewHelper.getSimpleClassName(generatorConfiguration.getErrorRegistryClass()) }} $errorRegistry{% endif %}
4042
*
41-
* @throws Throwable
43+
* @throws {% if generatorConfiguration.collectErrors() %}{{ viewHelper.getSimpleClassName(generatorConfiguration.getErrorRegistryClass()) }}{% else %}{{ viewHelper.getSimpleClassName(generatorConfiguration.getExceptionClass()) }}{% endif %}
4244
*/
4345
public function __construct(
4446
array $modelData
@@ -48,6 +50,8 @@ class {{ class }}
4850
if (!$errorRegistry) {
4951
$this->isInitialClass = true;
5052
$this->errorRegistry = new {{ viewHelper.getSimpleClassName(generatorConfiguration.getErrorRegistryClass()) }}();
53+
} else {
54+
$this->errorRegistry = $errorRegistry;
5155
}
5256
{% endif%}
5357

src/Templates/Validator/ComposedItem.phptpl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,17 @@
55
$succeededCompositionElements = {{ availableAmount }};
66
$originalModelData = $value;
77
$proposedValue = null;
8+
{% if generatorConfiguration.collectErrors() %}
9+
$originalErrorRegistry = $this->errorRegistry;
10+
$this->errorRegistry = new {{ viewHelper.getSimpleClassName(generatorConfiguration.getErrorRegistryClass()) }}();
11+
{% endif %}
812

913
{% foreach properties as property %}
1014
try {
15+
{% if generatorConfiguration.collectErrors() %}
16+
$currentErrors = count($this->errorRegistry->getErrors());
17+
{% endif %}
18+
1119
{% if not postPropose %}
1220
$proposedValue = $proposedValue ?? $value;
1321
{% endif %}
@@ -20,6 +28,14 @@
2028
}
2129
{% endforeach %}
2230

31+
{% if generatorConfiguration.collectErrors() %}
32+
// an error inside the composed validation occurred. Throw an exception to count the validity of the
33+
// composition item
34+
if ($currentErrors < count($this->errorRegistry->getErrors())) {
35+
throw new \Exception();
36+
}
37+
{% endif %}
38+
2339
{% if postPropose %}
2440
$proposedValue = $proposedValue ?? $value;
2541
{% endif %}
@@ -43,5 +59,9 @@
4359
$value = $proposedValue;
4460
{% endif %}
4561

62+
{% if generatorConfiguration.collectErrors() %}
63+
$this->errorRegistry = $originalErrorRegistry;
64+
{% endif %}
65+
4666
return !({{ composedValueValidation }});
4767
})($value)

src/Templates/Validator/ConditionalComposedItem.phptpl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,40 @@
44
(function (&$value) use (&$modelData) {
55
$originalModelData = $value;
66
$ifValid = true;
7+
{% if generatorConfiguration.collectErrors() %}
8+
$originalErrorRegistry = $this->errorRegistry;
9+
$this->errorRegistry = new {{ viewHelper.getSimpleClassName(generatorConfiguration.getErrorRegistryClass()) }}();
10+
{% endif %}
711

812
try {
13+
{% if generatorConfiguration.collectErrors() %}
14+
$currentErrors = count($this->errorRegistry->getErrors());
15+
{% endif %}
16+
917
{{ viewHelper.resolvePropertyDecorator(ifProperty) }}
1018

1119
{% foreach ifProperty.getOrderedValidators() as validator %}
1220
if ({{ validator.getCheck() }}) {
1321
{{ viewHelper.validationError(validator.getExceptionMessage()) }}
1422
}
1523
{% endforeach %}
24+
25+
{% if generatorConfiguration.collectErrors() %}
26+
// an error inside the composed validation occurred. Throw an exception to count the validity of the
27+
// composition item
28+
if ($currentErrors < count($this->errorRegistry->getErrors())) {
29+
throw new \Exception();
30+
}
31+
{% endif %}
1632
} catch (\Exception $e) {
1733
$ifValid = false;
1834
}
1935
$value = $originalModelData;
2036

37+
{% if generatorConfiguration.collectErrors() %}
38+
$this->errorRegistry = $originalErrorRegistry;
39+
{% endif %}
40+
2141
if ($ifValid) {
2242
{% if thenProperty %}
2343
{{ viewHelper.resolvePropertyDecorator(thenProperty) }}

tests/AbstractPHPModelGeneratorTest.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
namespace PHPModelGenerator\Tests;
44

55
use FilesystemIterator;
6+
use PHPModelGenerator\Exception\ErrorRegistryException;
67
use PHPModelGenerator\Exception\FileSystemException;
78
use PHPModelGenerator\Exception\RenderException;
89
use PHPModelGenerator\Exception\SchemaException;
10+
use PHPModelGenerator\Exception\ValidationException;
911
use PHPModelGenerator\ModelGenerator;
1012
use PHPModelGenerator\Model\GeneratorConfiguration;
1113
use PHPUnit\Framework\TestCase;
@@ -230,6 +232,61 @@ protected function combineDataProvider(array $dataProvider1, array $dataProvider
230232
return $result;
231233
}
232234

235+
protected function expectValidationError(GeneratorConfiguration $configuration, $messages): void
236+
{
237+
if (!is_array($messages)) {
238+
$messages = [$messages];
239+
}
240+
241+
if ($configuration->collectErrors()) {
242+
$this->expectExceptionObject($this->getErrorRegistryException($messages));
243+
} else {
244+
$this->expectException(ValidationException::class);
245+
$this->expectExceptionMessage($messages[0]);
246+
}
247+
}
248+
249+
protected function expectValidationErrorRegExp(GeneratorConfiguration $configuration, $messages)
250+
{
251+
if (!is_array($messages)) {
252+
$messages = [$messages];
253+
}
254+
255+
if ($configuration->collectErrors()) {
256+
$exception = $this->getErrorRegistryException($messages);
257+
$this->expectException(get_class($exception));
258+
$this->expectExceptionMessageRegExp($exception->getMessage());
259+
} else {
260+
$this->expectException(ValidationException::class);
261+
$this->expectExceptionMessageRegExp($messages[0]);
262+
}
263+
}
264+
265+
/**
266+
* Set up an ErrorRegistryException containing the given messages
267+
*
268+
* @param array $messages
269+
*
270+
* @return ErrorRegistryException
271+
*/
272+
protected function getErrorRegistryException(array $messages): ErrorRegistryException
273+
{
274+
$errorRegistry = new ErrorRegistryException();
275+
276+
foreach ($messages as $message) {
277+
$errorRegistry->addError($message);
278+
}
279+
280+
return $errorRegistry;
281+
}
282+
283+
public function validationMethodDataProvider(): array {
284+
return [
285+
'Error Collection' => [new GeneratorConfiguration()],
286+
'Direct Exception' => [(new GeneratorConfiguration())->setCollectErrors(false)],
287+
];
288+
}
289+
233290
/**
234291
* Get the annotated type for an object property
235292
*

tests/Basic/ErrorCollectionTest.php

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace PHPModelGenerator\Tests\Basic;
66

7-
use PHPModelGenerator\Exception\ErrorRegistryException;
87
use PHPModelGenerator\Model\GeneratorConfiguration;
98
use PHPModelGenerator\Tests\AbstractPHPModelGeneratorTest;
109
use stdClass;
@@ -85,22 +84,4 @@ public function invalidValuesForSinglePropertyDataProvider(): array
8584
'object' => [new stdClass(), ['invalid type for property']],
8685
];
8786
}
88-
89-
/**
90-
* Set up an ErrorRegistryException containing the given messages
91-
*
92-
* @param array $messages
93-
*
94-
* @return ErrorRegistryException
95-
*/
96-
protected function getErrorRegistryException(array $messages): ErrorRegistryException
97-
{
98-
$errorRegistry = new ErrorRegistryException();
99-
100-
foreach ($messages as $message) {
101-
$errorRegistry->addError($message);
102-
}
103-
104-
return $errorRegistry;
105-
}
10687
}

0 commit comments

Comments
 (0)