Skip to content

Commit 82fdff8

Browse files
committed
Add additional ComposedOneOf test cases
1 parent f36b9e0 commit 82fdff8

File tree

4 files changed

+193
-43
lines changed

4 files changed

+193
-43
lines changed

tests/AbstractPHPModelGeneratorTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use PHPUnit\Framework\TestCase;
1212
use RecursiveDirectoryIterator;
1313
use RecursiveIteratorIterator;
14+
use ReflectionClass;
1415

1516
/**
1617
* Class AbstractPHPModelGeneratorTest
@@ -209,6 +210,45 @@ public function generateClass(string $jsonSchema, GeneratorConfiguration $genera
209210
return $className;
210211
}
211212

213+
/**
214+
* Combine two data providers
215+
*
216+
* @param array $dataProvider1
217+
* @param array $dataProvider2
218+
*
219+
* @return array
220+
*/
221+
protected function combineDataProvider(array $dataProvider1, array $dataProvider2): array
222+
{
223+
$result = [];
224+
foreach ($dataProvider1 as $dp1Key => $dp1Value) {
225+
foreach ($dataProvider2 as $dp2Key => $dp2Value) {
226+
$result["$dp1Key - $dp2Key"] = array_merge($dp1Value, $dp2Value);
227+
}
228+
}
229+
230+
return $result;
231+
}
232+
233+
/**
234+
* Get the type for an object property
235+
*
236+
* @param object $object
237+
* @param string $property
238+
*
239+
* @return string
240+
*/
241+
protected function getPropertyType(object $object, string $property): string
242+
{
243+
$matches = [];
244+
preg_match(
245+
'/@var\s+([^\s]+)\s/',
246+
(new ReflectionClass($object))->getProperty($property)->getDocComment(),
247+
$matches
248+
);
249+
250+
return $matches[1];
251+
}
212252
/**
213253
* Generate a unique name for a class
214254
*

tests/ComposedValue/ComposedOneOfTest.php

Lines changed: 106 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ public function testNotProvidedPropertyLevelOneOfIsValid(string $schema): void
2929
public function propertyLevelOneOfSchemaFileDataProvider(): array
3030
{
3131
return [
32-
'OneOfType.json' => ['OneOfType.json'],
33-
'ExtendedPropertyDefinition.json' => ['ExtendedPropertyDefinition.json'],
34-
'ReferencedObjectSchema.json' => ['ReferencedObjectSchema.json'],
32+
'Scalar types' => ['OneOfType.json'],
33+
'Property level composition' => ['ExtendedPropertyDefinition.json'],
34+
'Object with scalar type' => ['ReferencedObjectSchema.json'],
35+
'Multiple objects' => ['ReferencedObjectSchema2.json'],
3536
];
3637
}
3738

@@ -72,6 +73,29 @@ public function testValidProvidedOneOfTypePropertyIsValid($propertyValue): void
7273
$this->assertSame($propertyValue, $object->getProperty());
7374
}
7475

76+
/**
77+
* @dataProvider annotationDataProvider
78+
*
79+
* @param string $schema
80+
* @param string $annotationPattern
81+
*/
82+
public function testOneOfTypePropertyHasTypeAnnotation(string $schema, string $annotationPattern): void
83+
{
84+
$className = $this->generateClassFromFile($schema);
85+
86+
$object = new $className([]);
87+
$this->assertRegExp($annotationPattern, $this->getPropertyType($object, 'property'));
88+
}
89+
90+
public function annotationDataProvider(): array
91+
{
92+
return [
93+
'Multiple scalar types' => ['OneOfType.json', '/string\|int\|bool/'],
94+
'Object with scalar type' => ['ReferencedObjectSchema.json', '/ComposedOneOfTest[\w]*\|string/'],
95+
'Multiple objects' => ['ReferencedObjectSchema2.json', '/ComposedOneOfTest[\w]*\|ComposedOneOfTest[\w]*/']
96+
];
97+
}
98+
7599
/**
76100
* @dataProvider invalidPropertyTypeDataProvider
77101
*
@@ -224,11 +248,13 @@ public function composedPropertyWithReferencedSchemaDataProvider(): array
224248
}
225249

226250
/**
227-
* @param $propertyValue
251+
* @dataProvider referencedPersonDataProvider
252+
*
253+
* @param string $schema
228254
*/
229-
public function testMatchingObjectPropertyWithReferencedSchemaIsValid(): void
255+
public function testMatchingObjectPropertyWithReferencedPersonSchemaIsValid(string $schema): void
230256
{
231-
$className = $this->generateClassFromFile('ReferencedObjectSchema.json');
257+
$className = $this->generateClassFromFile($schema);
232258

233259
$object = new $className(['property' => ['name' => 'Ha', 'age' => 42]]);
234260

@@ -237,36 +263,93 @@ public function testMatchingObjectPropertyWithReferencedSchemaIsValid(): void
237263
$this->assertSame(42, $object->getProperty()->getAge());
238264
}
239265

266+
public function referencedPersonDataProvider(): array
267+
{
268+
return [
269+
'ReferencedObjectSchema.json' => ['ReferencedObjectSchema.json'],
270+
'ReferencedObjectSchema2.json' => ['ReferencedObjectSchema2.json'],
271+
];
272+
}
273+
274+
public function testMatchingObjectPropertyWithReferencedPetSchemaIsValid(): void
275+
{
276+
$className = $this->generateClassFromFile('ReferencedObjectSchema2.json');
277+
278+
$object = new $className(['property' => ['race' => 'Horse']]);
279+
280+
$this->assertTrue(is_object($object->getProperty()));
281+
$this->assertSame('Horse', $object->getProperty()->getRace());
282+
}
283+
284+
/**
285+
* @dataProvider invalidObjectPropertyWithReferencedPersonSchemaDataProvider
286+
*
287+
* @param string $schema
288+
* @param $propertyValue
289+
*/
290+
public function testNotMatchingObjectPropertyWithReferencedPersonSchemaThrowsAnException(
291+
string $schema,
292+
$propertyValue
293+
): void {
294+
$this->expectException(InvalidArgumentException::class);
295+
$this->expectExceptionMessage('Invalid value for property declined by composition constraint');
296+
297+
$className = $this->generateClassFromFile($schema);
298+
299+
new $className(['property' => $propertyValue]);
300+
}
301+
302+
public function invalidObjectPropertyWithReferencedPersonSchemaDataProvider(): array
303+
{
304+
return $this->combineDataProvider(
305+
$this->referencedPersonDataProvider(),
306+
[
307+
'int' => [0],
308+
'float' => [0.92],
309+
'bool' => [true],
310+
'object' => [new stdClass()],
311+
'empty string' => [''],
312+
'Too short string' => ['Hann'],
313+
'empty array' => [[]],
314+
'Missing property' => [['name' => 'Hannes']],
315+
'Too many properties' => [['name' => 'Hannes', 'age' => 42, 'alive' => true]],
316+
'Matching object with invalid type' => [['name' => 'Hannes', 'age' => '42']],
317+
'Matching object with invalid data' => [['name' => 'H', 'age' => 42]],
318+
]
319+
);
320+
}
321+
240322
/**
241-
* @dataProvider invalidObjectPropertyWithReferencedSchemaDataProvider
323+
* @dataProvider invalidObjectPropertyWithReferencedPetSchemaDataProvider
242324
*
243325
* @param $propertyValue
244326
*/
245-
public function testNotMatchingObjectPropertyWithReferencedSchemaThrowsAnException($propertyValue): void
327+
public function testNotMatchingObjectPropertyWithReferencedPetSchemaThrowsAnException($propertyValue): void
246328
{
247329
$this->expectException(InvalidArgumentException::class);
248330
$this->expectExceptionMessage('Invalid value for property declined by composition constraint');
249331

250-
$className = $this->generateClassFromFile('ReferencedObjectSchema.json');
332+
$className = $this->generateClassFromFile('ReferencedObjectSchema2.json');
251333

252334
new $className(['property' => $propertyValue]);
253335
}
254336

255-
public function invalidObjectPropertyWithReferencedSchemaDataProvider(): array
337+
public function invalidObjectPropertyWithReferencedPetSchemaDataProvider(): array
256338
{
257-
return [
258-
'int' => [0],
259-
'float' => [0.92],
260-
'bool' => [true],
261-
'object' => [new stdClass()],
262-
'empty string' => [''],
263-
'Too short string' => ['Hann'],
264-
'empty array' => [[]],
265-
'Missing property' => [['name' => 'Hannes']],
266-
'Too many properties' => [['name' => 'Hannes', 'age' => 42, 'alive' => true]],
267-
'Matching object with invalid type' => [['name' => 'Hannes', 'age' => '42']],
268-
'Matching object with invalid data' => [['name' => 'H', 'age' => 42]],
269-
];
339+
return $this->combineDataProvider(
340+
$this->referencedPersonDataProvider(),
341+
[
342+
'int' => [0],
343+
'float' => [0.92],
344+
'bool' => [true],
345+
'object' => [new stdClass()],
346+
'string' => ['Horse'],
347+
'empty array' => [[]],
348+
'Too many properties' => [['race' => 'Horse', 'alive' => true]],
349+
'Matching object with invalid type' => [['race' => 123]],
350+
'Matching object with invalid data' => [['race' => 'H']],
351+
]
352+
);
270353
}
271354

272355
/**

tests/Objects/ReferencePropertyTest.php

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -435,24 +435,4 @@ public function nestedReferenceProvider(): array
435435
'Network reference' => ['https://raw.githubusercontent.com/wol-soft/php-json-schema-model-generator/master/tests/Schema/ReferencePropertyTest_external/library.json'],
436436
];
437437
}
438-
439-
/**
440-
* Combine two data providers
441-
*
442-
* @param array $dataProvider1
443-
* @param array $dataProvider2
444-
*
445-
* @return array
446-
*/
447-
protected function combineDataProvider(array $dataProvider1, array $dataProvider2): array
448-
{
449-
$result = [];
450-
foreach ($dataProvider1 as $dp1Key => $dp1Value) {
451-
foreach ($dataProvider2 as $dp2Key => $dp2Value) {
452-
$result["$dp1Key - $dp2Key"] = array_merge($dp1Value, $dp2Value);
453-
}
454-
}
455-
456-
return $result;
457-
}
458438
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"definitions": {
3+
"person": {
4+
"type": "object",
5+
"properties": {
6+
"name": {
7+
"type": "string",
8+
"minLength": 2
9+
},
10+
"age": {
11+
"type": "integer"
12+
}
13+
},
14+
"required": [
15+
"name",
16+
"age"
17+
],
18+
"additionalProperties": false
19+
},
20+
"pet": {
21+
"type": "object",
22+
"properties": {
23+
"race": {
24+
"type": "string",
25+
"minLength": 2
26+
}
27+
},
28+
"required": [
29+
"race"
30+
],
31+
"additionalProperties": false
32+
}
33+
},
34+
"type": "object",
35+
"properties": {
36+
"property": {
37+
"oneOf": [
38+
{
39+
"$ref": "#/definitions/person"
40+
},
41+
{
42+
"$ref": "#/definitions/pet"
43+
}
44+
]
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)