Skip to content

Commit 34e171d

Browse files
committed
Optimize composed error exceptions for schema dependencies
Add test cases for composition inside a schema dependency Add test cases for references inside a schema dependency
1 parent d5587a1 commit 34e171d

File tree

4 files changed

+234
-2
lines changed

4 files changed

+234
-2
lines changed

src/Model/Validator/SchemaDependencyValidator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function __construct(SchemaProcessor $schemaProcessor, PropertyInterface
2929
{
3030
parent::__construct(
3131
"Invalid schema which is dependant on {$property->getName()}:\\n - " .
32-
'" . implode("\n - ", explode("\n", $dependencyException->getMessage())) . "',
32+
'" . preg_replace("/\n([^\s])/m", "\n - $1", preg_replace("/\n\s/m", "\n ", $dependencyException->getMessage())) . "',
3333
DIRECTORY_SEPARATOR . 'Validator' . DIRECTORY_SEPARATOR . 'SchemaDependency.phptpl',
3434
[
3535
'viewHelper' => new RenderHelper($schemaProcessor->getGeneratorConfiguration()),

tests/Basic/SchemaDependencyTest.php

Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPModelGenerator\Tests\Basic;
44

5+
use PHPModelGenerator\Exception\ErrorRegistryException;
56
use PHPModelGenerator\Model\GeneratorConfiguration;
67
use PHPModelGenerator\Tests\AbstractPHPModelGeneratorTest;
78

@@ -58,7 +59,6 @@ public function testInvalidSchemaDependency(
5859
new $className($propertyValue);
5960
}
6061

61-
6262
public function invalidSchemaDependencyDataProvider(): array
6363
{
6464
return $this->combineDataProvider(
@@ -88,4 +88,170 @@ public function invalidSchemaDependencyDataProvider(): array
8888
]
8989
);
9090
}
91+
92+
/**
93+
* @dataProvider validSchemaDependencyReferenceDataProvider
94+
*
95+
* @param array $propertyValue
96+
*/
97+
public function testSchemaDependencyReference(array $propertyValue): void
98+
{
99+
$className = $this->generateClassFromFile('ReferenceSchemaDependency.json');
100+
101+
$object = new $className($propertyValue);
102+
$this->assertSame($propertyValue['credit_card'] ?? null, $object->getCreditCard());
103+
$this->assertSame($propertyValue['name'] ?? null, $object->getName());
104+
$this->assertSame($propertyValue['age'] ?? null, $object->getAge());
105+
}
106+
107+
public function validSchemaDependencyReferenceDataProvider(): array
108+
{
109+
return [
110+
'No properties provided' => [[]],
111+
'Only dependant property provided 1' => [['name' => 'Hannes']],
112+
'Only dependant property provided 2' => [['age' => 42]],
113+
'Only dependant property provided 3' => [['name' => 'Hannes', 'age' => 42]],
114+
'All properties provided' => [['credit_card' => 12345, 'name' => 'Hannes', 'age' => 42]],
115+
'Only required properties provided' => [['credit_card' => 12345, 'name' => 'Hannes']],
116+
];
117+
}
118+
119+
/**
120+
* @dataProvider invalidSchemaDependencyReferenceDataProvider
121+
*
122+
* @param GeneratorConfiguration $configuration
123+
* @param array $propertyValue
124+
* @param string $message
125+
*/
126+
public function testInvalidSchemaDependencyReference(
127+
GeneratorConfiguration $configuration,
128+
array $propertyValue,
129+
string $message
130+
): void {
131+
$this->expectValidationError($configuration, $message);
132+
133+
$className = $this->generateClassFromFile('ReferenceSchemaDependency.json', $configuration);
134+
135+
new $className($propertyValue);
136+
}
137+
138+
public function invalidSchemaDependencyReferenceDataProvider(): array
139+
{
140+
return $this->combineDataProvider(
141+
$this->validationMethodDataProvider(),
142+
[
143+
'required attribute not provided 1' => [
144+
['credit_card' => 12345],
145+
<<<ERROR
146+
Invalid schema which is dependant on credit_card:
147+
- Missing required value for name
148+
ERROR
149+
],
150+
'required attribute not provided 2' => [
151+
['credit_card' => 12345, 'age' => 42],
152+
<<<ERROR
153+
Invalid schema which is dependant on credit_card:
154+
- Missing required value for name
155+
ERROR
156+
],
157+
'invalid data type' => [
158+
['credit_card' => 12345, 'name' => false],
159+
<<<ERROR
160+
Invalid schema which is dependant on credit_card:
161+
- Invalid type for name. Requires string, got boolean
162+
ERROR
163+
],
164+
]
165+
);
166+
}
167+
168+
/**
169+
* @dataProvider validSchemaDependencyCompositionDataProvider
170+
*
171+
* @param array $propertyValue
172+
*/
173+
public function testSchemaDependencyComposition(array $propertyValue): void
174+
{
175+
$className = $this->generateClassFromFile('CompositionSchemaDependency.json');
176+
177+
$object = new $className($propertyValue);
178+
$this->assertSame($propertyValue['credit_card'] ?? null, $object->getCreditCard());
179+
$this->assertSame($propertyValue['name'] ?? null, $object->getName());
180+
$this->assertSame($propertyValue['age'] ?? null, $object->getAge());
181+
}
182+
183+
public function validSchemaDependencyCompositionDataProvider(): array
184+
{
185+
return [
186+
'No properties provided' => [[]],
187+
'Only dependant property provided 1' => [['name' => 'Hannes']],
188+
'Only dependant property provided 2' => [['age' => 42]],
189+
'Only dependant property provided 3' => [['name' => 'Hannes', 'age' => 42]],
190+
'All properties provided' => [['credit_card' => 12345, 'name' => 'Hannes', 'age' => 42]],
191+
];
192+
}
193+
194+
/**
195+
* @dataProvider invalidSchemaDependencyCompositionDataProvider
196+
*
197+
* @param array $propertyValue
198+
* @param string $message
199+
*/
200+
public function testInvalidSchemaDependencyComposition(
201+
array $propertyValue,
202+
string $message
203+
): void {
204+
$this->expectException(ErrorRegistryException::class);
205+
$this->expectExceptionMessageMatches("/$message/m");
206+
207+
$className = $this->generateClassFromFile(
208+
'CompositionSchemaDependency.json',
209+
(new GeneratorConfiguration())->setCollectErrors(true)
210+
);
211+
212+
new $className($propertyValue);
213+
}
214+
215+
public function invalidSchemaDependencyCompositionDataProvider(): array
216+
{
217+
return [
218+
'required attribute not provided 1' => [
219+
['credit_card' => 12345],
220+
<<<ERROR
221+
Invalid schema which is dependant on credit_card:
222+
- Invalid value for Credit_card_Dependency_(.*) declined by composition constraint.
223+
Requires to match 2 composition elements but matched 0 elements.
224+
- Composition element #1: Failed
225+
\* Missing required value for name
226+
\* Invalid type for name. Requires string, got NULL
227+
- Composition element #2: Failed
228+
\* Missing required value for age
229+
\* Invalid type for age. Requires int, got NULL
230+
ERROR
231+
],
232+
'required attribute not provided 2' => [
233+
['credit_card' => 12345, 'age' => 42],
234+
<<<ERROR
235+
Invalid schema which is dependant on credit_card:
236+
- Invalid value for Credit_card_Dependency_(.*) declined by composition constraint.
237+
Requires to match 2 composition elements but matched 1 elements.
238+
- Composition element #1: Failed
239+
\* Missing required value for name
240+
\* Invalid type for name. Requires string, got NULL
241+
- Composition element #2: Valid
242+
ERROR
243+
],
244+
'invalid data type' => [
245+
['credit_card' => 12345, 'name' => false, 'age' => 42],
246+
<<<ERROR
247+
Invalid schema which is dependant on credit_card:
248+
- Invalid value for Credit_card_Dependency_(.*) declined by composition constraint.
249+
Requires to match 2 composition elements but matched 1 elements.
250+
- Composition element #1: Failed
251+
\* Invalid type for name. Requires string, got boolean
252+
- Composition element #2: Valid
253+
ERROR
254+
]
255+
];
256+
}
91257
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"credit_card": {
5+
"type": "integer"
6+
}
7+
},
8+
"dependencies": {
9+
"credit_card": {
10+
"allOf": [
11+
{
12+
"type": "object",
13+
"properties": {
14+
"name": {
15+
"type": "string"
16+
}
17+
},
18+
"required": [
19+
"name"
20+
]
21+
},
22+
{
23+
"type": "object",
24+
"properties": {
25+
"age": {
26+
"type": "integer"
27+
}
28+
},
29+
"required": [
30+
"age"
31+
]
32+
}
33+
]
34+
}
35+
}
36+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"definitions": {
3+
"owner": {
4+
"$id": "#owner",
5+
"type": "object",
6+
"properties": {
7+
"name": {
8+
"type": "string"
9+
},
10+
"age": {
11+
"type": "integer"
12+
}
13+
},
14+
"required": [
15+
"name"
16+
]
17+
}
18+
},
19+
"type": "object",
20+
"properties": {
21+
"credit_card": {
22+
"type": "integer"
23+
}
24+
},
25+
"dependencies": {
26+
"credit_card": {
27+
"$ref": "#owner"
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)