diff --git a/src/Model/Schema/Discriminator.php b/src/Model/Schema/Discriminator.php index 0778e5e..9182c8f 100644 --- a/src/Model/Schema/Discriminator.php +++ b/src/Model/Schema/Discriminator.php @@ -6,9 +6,13 @@ final readonly class Discriminator { - /** @param array $mapping */ + /** + * @param array $mapping + * @param array $extensions + */ public function __construct( public string $propertyName, public array $mapping = [], + public array $extensions = [], ) {} } diff --git a/src/Parser/Schema/Reader.php b/src/Parser/Schema/Reader.php index c10014f..70ba9bc 100644 --- a/src/Parser/Schema/Reader.php +++ b/src/Parser/Schema/Reader.php @@ -263,6 +263,10 @@ private function discriminator(array $data): ?Discriminator $mapping[(string) $name] = $reference; } - return new Discriminator(Value::requiredString($value, 'propertyName', 'schema/discriminator'), $mapping); + return new Discriminator( + Value::requiredString($value, 'propertyName', 'schema/discriminator'), + $mapping, + Value::extensions($value), + ); } } diff --git a/tests/Schema/ReaderTest.php b/tests/Schema/ReaderTest.php index 5d206ef..228edda 100644 --- a/tests/Schema/ReaderTest.php +++ b/tests/Schema/ReaderTest.php @@ -115,6 +115,52 @@ public function test_discriminator_is_read_from_both_the_string_and_object_forms self::assertSame(['cat' => '#/components/schemas/Cat'], $fromObject->discriminator?->mapping); } + public function test_discriminator_captures_extensions(): void + { + $reader = $this->reader(Version::V3_0); + + $schema = $reader->read([ + 'oneOf' => [], + 'discriminator' => [ + 'propertyName' => 'type', + 'mapping' => ['string' => '#/components/schemas/Text'], + 'x-mapping' => [ + '#/components/schemas/Email' => ['type' => 'string', 'format' => 'email'], + '#/components/schemas/Text' => ['type' => 'string'], + ], + 'x-propertyNames' => ['type', 'format'], + ], + ], '#/x'); + + self::assertInstanceOf(CompositeSchema::class, $schema); + self::assertSame([ + 'x-mapping' => [ + '#/components/schemas/Email' => ['type' => 'string', 'format' => 'email'], + '#/components/schemas/Text' => ['type' => 'string'], + ], + 'x-propertyNames' => ['type', 'format'], + ], $schema->discriminator?->extensions); + + self::assertSame('type', $schema->discriminator?->propertyName); + self::assertSame(['string' => '#/components/schemas/Text'], $schema->discriminator?->mapping); + } + + public function test_discriminator_extensions_default_to_empty(): void + { + $reader = $this->reader(Version::V3_0); + + $fromString = $reader->read(['oneOf' => [], 'discriminator' => 'kind'], '#/x'); + self::assertInstanceOf(CompositeSchema::class, $fromString); + self::assertSame([], $fromString->discriminator?->extensions); + + $fromObject = $reader->read([ + 'oneOf' => [], + 'discriminator' => ['propertyName' => 'kind'], + ], '#/x'); + self::assertInstanceOf(CompositeSchema::class, $fromObject); + self::assertSame([], $fromObject->discriminator?->extensions); + } + public function test_object_and_array_types_are_implied_from_their_keywords(): void { $reader = $this->reader(Version::V3_0);