From 6829c6f7961dbedcc348d522b219f48581fd4601 Mon Sep 17 00:00:00 2001 From: reinfi Date: Mon, 27 Oct 2025 20:57:33 +0100 Subject: [PATCH 1/4] adjust test to check for namespaces files as well --- test/Acceptance/AcceptanceTest.php | 12 +++- .../Test/Test23InlineObjectArrayNamespace.php | 66 +++++++++++++++++++ .../Test23InlineObjectArrayNamespaceItems.php | 13 ++++ .../Schema/Test23InlineObjectArray.php | 66 +++++++++++++++++++ .../Schema/Test23InlineObjectArrayItems.php | 13 ++++ test/spec/acceptance.yml | 23 ++++++- 6 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectArrayNamespace.php create mode 100644 test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectArrayNamespaceItems.php create mode 100644 test/Acceptance/ExpectedClasses/Schema/Test23InlineObjectArray.php create mode 100644 test/Acceptance/ExpectedClasses/Schema/Test23InlineObjectArrayItems.php diff --git a/test/Acceptance/AcceptanceTest.php b/test/Acceptance/AcceptanceTest.php index 6753deb..590a670 100644 --- a/test/Acceptance/AcceptanceTest.php +++ b/test/Acceptance/AcceptanceTest.php @@ -5,6 +5,9 @@ namespace Reinfi\OpenApiModels\Test\Acceptance; use PHPUnit\Framework\TestCase; +use RecursiveDirectoryIterator; +use RecursiveIteratorIterator; +use SplFileInfo; class AcceptanceTest extends TestCase { @@ -19,8 +22,13 @@ public function testApplicationRuns(): void self::assertNotNull($output); self::assertNotFalse($output); - $expectedFiles = glob(__DIR__ . '/ExpectedClasses/**/*.php'); - self::assertNotFalse($expectedFiles); + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__ . '/ExpectedClasses')); + $expectedFiles = []; + foreach ($iterator as $file) { + if ($file instanceof SplFileInfo && $file->isFile() && $file->getExtension() === 'php') { + $expectedFiles[] = $file->getPathname(); + } + } foreach ($expectedFiles as $file) { $fileName = basename($file); diff --git a/test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectArrayNamespace.php b/test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectArrayNamespace.php new file mode 100644 index 0000000..9140443 --- /dev/null +++ b/test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectArrayNamespace.php @@ -0,0 +1,66 @@ + + * @implements \IteratorAggregate + */ +readonly class Test23InlineObjectArrayNamespace implements IteratorAggregate, Countable, ArrayAccess, JsonSerializable +{ + /** @var array $items */ + private array $items; + + public function __construct(Test23InlineObjectArrayNamespaceItems ...$items) + { + $this->items = $items; + } + + public function getIterator(): Traversable + { + return new ArrayIterator($this->items); + } + + public function count(): int + { + return count($this->items); + } + + public function offsetExists(mixed $offset): bool + { + return isset($this->items[$offset]); + } + + public function offsetGet(mixed $offset): ?Test23InlineObjectArrayNamespaceItems + { + return $this->items[$offset] ?? null; + } + + public function offsetSet(mixed $offset, mixed $value): void + { + throw new BadMethodCallException('Object is readOnly'); + } + + public function offsetUnset(mixed $offset): void + { + throw new BadMethodCallException('Object is readOnly'); + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + return $this->items; + } +} diff --git a/test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectArrayNamespaceItems.php b/test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectArrayNamespaceItems.php new file mode 100644 index 0000000..4ba61b6 --- /dev/null +++ b/test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectArrayNamespaceItems.php @@ -0,0 +1,13 @@ + + * @implements \IteratorAggregate + */ +readonly class Test23InlineObjectArray implements IteratorAggregate, Countable, ArrayAccess, JsonSerializable +{ + /** @var array $items */ + private array $items; + + public function __construct(Test23InlineObjectArrayItems ...$items) + { + $this->items = $items; + } + + public function getIterator(): Traversable + { + return new ArrayIterator($this->items); + } + + public function count(): int + { + return count($this->items); + } + + public function offsetExists(mixed $offset): bool + { + return isset($this->items[$offset]); + } + + public function offsetGet(mixed $offset): ?Test23InlineObjectArrayItems + { + return $this->items[$offset] ?? null; + } + + public function offsetSet(mixed $offset, mixed $value): void + { + throw new BadMethodCallException('Object is readOnly'); + } + + public function offsetUnset(mixed $offset): void + { + throw new BadMethodCallException('Object is readOnly'); + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + return $this->items; + } +} diff --git a/test/Acceptance/ExpectedClasses/Schema/Test23InlineObjectArrayItems.php b/test/Acceptance/ExpectedClasses/Schema/Test23InlineObjectArrayItems.php new file mode 100644 index 0000000..addeca5 --- /dev/null +++ b/test/Acceptance/ExpectedClasses/Schema/Test23InlineObjectArrayItems.php @@ -0,0 +1,13 @@ + Date: Mon, 27 Oct 2025 21:13:18 +0100 Subject: [PATCH 2/4] fix namespace selection in inline objects --- src/Generator/ClassTransformer.php | 8 ++++++++ test/Acceptance/AcceptanceTest.php | 8 +++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Generator/ClassTransformer.php b/src/Generator/ClassTransformer.php index a5da35e..886c853 100644 --- a/src/Generator/ClassTransformer.php +++ b/src/Generator/ClassTransformer.php @@ -511,6 +511,14 @@ private function resolveArrayType( } if ($arrayType === Types::Object) { + // @phpstan-ignore-next-line + $xPhpNamespace = $schema->{'x-php-namespace'} ?? null; + + if (is_string($xPhpNamespace)) { + // @phpstan-ignore-next-line + $itemsSchema->{'x-php-namespace'} = $xPhpNamespace; + } + $inlineObject = $this->transformInlineObject( $configuration, $openApi, diff --git a/test/Acceptance/AcceptanceTest.php b/test/Acceptance/AcceptanceTest.php index 590a670..cb3534e 100644 --- a/test/Acceptance/AcceptanceTest.php +++ b/test/Acceptance/AcceptanceTest.php @@ -22,7 +22,8 @@ public function testApplicationRuns(): void self::assertNotNull($output); self::assertNotFalse($output); - $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__ . '/ExpectedClasses')); + $baseDirectoryPath = __DIR__ . '/ExpectedClasses'; + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($baseDirectoryPath)); $expectedFiles = []; foreach ($iterator as $file) { if ($file instanceof SplFileInfo && $file->isFile() && $file->getExtension() === 'php') { @@ -31,8 +32,9 @@ public function testApplicationRuns(): void } foreach ($expectedFiles as $file) { - $fileName = basename($file); - $fileDirectory = basename(dirname($file)); + $fileWithoutBaseDirectory = str_replace($baseDirectoryPath, '', $file); + $fileName = basename($fileWithoutBaseDirectory); + $fileDirectory = ltrim(dirname($fileWithoutBaseDirectory)); self::assertFileEquals($file, sprintf(__DIR__ . '/../output/%s/%s', $fileDirectory, $fileName)); } From fcc851dc8613c879f526a911b4167bed8983a669 Mon Sep 17 00:00:00 2001 From: reinfi Date: Mon, 27 Oct 2025 21:22:18 +0100 Subject: [PATCH 3/4] fix inline object for objects --- src/Generator/ClassTransformer.php | 25 +++++++++++++------ .../Test/Test23InlineObjectNamespace.php | 13 ++++++++++ .../Test/Test23InlineObjectNamespaceUser.php | 13 ++++++++++ test/spec/acceptance.yml | 14 +++++++++++ 4 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectNamespace.php create mode 100644 test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectNamespaceUser.php diff --git a/src/Generator/ClassTransformer.php b/src/Generator/ClassTransformer.php index 886c853..dc5d451 100644 --- a/src/Generator/ClassTransformer.php +++ b/src/Generator/ClassTransformer.php @@ -151,6 +151,8 @@ public function transform( } if ($type === Types::Object) { + $property = $this->applyNamespaceToSchema($schema, $property); + $inlineObject = $this->transformInlineObject( $configuration, $openApi, @@ -511,13 +513,7 @@ private function resolveArrayType( } if ($arrayType === Types::Object) { - // @phpstan-ignore-next-line - $xPhpNamespace = $schema->{'x-php-namespace'} ?? null; - - if (is_string($xPhpNamespace)) { - // @phpstan-ignore-next-line - $itemsSchema->{'x-php-namespace'} = $xPhpNamespace; - } + $itemsSchema = $this->applyNamespaceToSchema($schema, $itemsSchema); $inlineObject = $this->transformInlineObject( $configuration, @@ -798,4 +794,19 @@ private function resolveNamespace( return $this->namespaceResolver->resolveNamespace($openApiType, $schema); } + + private function applyNamespaceToSchema( + Schema $baseSchema, + Schema $schema, + ): Schema { + // @phpstan-ignore-next-line + $xPhpNamespace = $baseSchema->{'x-php-namespace'} ?? null; + + if (is_string($xPhpNamespace)) { + // @phpstan-ignore-next-line + $schema->{'x-php-namespace'} = $xPhpNamespace; + } + + return $schema; + } } diff --git a/test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectNamespace.php b/test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectNamespace.php new file mode 100644 index 0000000..58d0c66 --- /dev/null +++ b/test/Acceptance/ExpectedClasses/Schema/Test/Test23InlineObjectNamespace.php @@ -0,0 +1,13 @@ + Date: Mon, 27 Oct 2025 21:24:57 +0100 Subject: [PATCH 4/4] fix codestyle --- src/Generator/ClassTransformer.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Generator/ClassTransformer.php b/src/Generator/ClassTransformer.php index dc5d451..8ab5ecc 100644 --- a/src/Generator/ClassTransformer.php +++ b/src/Generator/ClassTransformer.php @@ -795,10 +795,8 @@ private function resolveNamespace( return $this->namespaceResolver->resolveNamespace($openApiType, $schema); } - private function applyNamespaceToSchema( - Schema $baseSchema, - Schema $schema, - ): Schema { + private function applyNamespaceToSchema(Schema $baseSchema, Schema $schema): Schema + { // @phpstan-ignore-next-line $xPhpNamespace = $baseSchema->{'x-php-namespace'} ?? null;