diff --git a/src/Model/SchemaDefinition/JsonSchema.php b/src/Model/SchemaDefinition/JsonSchema.php index facbcccb..df0cf223 100644 --- a/src/Model/SchemaDefinition/JsonSchema.php +++ b/src/Model/SchemaDefinition/JsonSchema.php @@ -46,6 +46,22 @@ class JsonSchema */ public function __construct(string $file, array $json) { + // wrap in an allOf to pass the processing to multiple handlers - ugly hack to be removed after rework + if (isset($json['$ref']) && count(array_diff(array_intersect(array_keys($json), self::SCHEMA_SIGNATURE_RELEVANT_FIELDS), ['$ref', 'type']))) { + $json = array_merge( + array_diff_key($json, array_fill_keys(self::SCHEMA_SIGNATURE_RELEVANT_FIELDS, null)), + [ + 'allOf' => [ + ['$ref' => $json['$ref']], + array_intersect_key( + $json, + array_fill_keys(array_diff(self::SCHEMA_SIGNATURE_RELEVANT_FIELDS, ['$ref']), null), + ), + ], + ], + ); + } + $this->json = $json; $this->file = $file; } diff --git a/tests/Issues/Issue/Issue79Test.php b/tests/Issues/Issue/Issue79Test.php new file mode 100644 index 00000000..37173416 --- /dev/null +++ b/tests/Issues/Issue/Issue79Test.php @@ -0,0 +1,50 @@ +generateClassFromFile('person.json'); + + $object = new $className(['name' => 'Hans', 'street' => 'A28']); + + $this->assertSame('Hans', $object->getName()); + $this->assertSame('A28', $object->getStreet()); + $this->assertNull($object->getAge()); + $this->assertNull($object->getZip()); + } + + /** + * @dataProvider invalidInputDataProvider + */ + public function testCombinedReferenceAndObjectDefinitionWithInvalidDataThrowsAnException(array $data): void + { + $className = $this->generateClassFromFile( + 'person.json', + (new GeneratorConfiguration())->setCollectErrors(true), + ); + + $this->expectException(ErrorRegistryException::class); + + new $className(['name' => 23, 'age' => 'A28']); + } + + public static function invalidInputDataProvider(): array + { + return [ + 'empty input' => [[]], + 'empty reference' => [['name' => 'Hans']], + 'empty object' => [['street' => 'A28']], + 'invalid reference' => [['name' => 'Hans', 'street' => 'A28', 'zip' => 'ABC']], + 'invalid object' => [['name' => 'Hans', 'street' => 'A28', 'age' => 'ABC']], + ]; + } +} diff --git a/tests/Schema/Issues/79/person.json b/tests/Schema/Issues/79/person.json new file mode 100644 index 00000000..f01eb4cc --- /dev/null +++ b/tests/Schema/Issues/79/person.json @@ -0,0 +1,32 @@ +{ + "definitions": { + "location": { + "type": "object", + "properties": { + "street": { + "type": "string" + }, + "zip": { + "type": "integer" + } + }, + "required": [ + "street" + ] + } + }, + "$id": "Person", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "age": { + "type": "integer" + } + }, + "$ref": "#/definitions/location", + "required": [ + "name" + ] +} \ No newline at end of file