Skip to content

Commit 1b7cc72

Browse files
committed
Additional test cases
1 parent 7864db7 commit 1b7cc72

File tree

7 files changed

+137
-39
lines changed

7 files changed

+137
-39
lines changed

src/SchemaProcessor/PostProcessor/BuilderClassPostProcessor.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,7 @@ private function getBuilderClassImports(array $properties, array $originalClassI
122122
}
123123
}
124124

125-
// required for compatibility with the EnumPostProcessor
126-
if (enum_exists($type)) {
127-
array_push($imports, $type, UnitEnum::class);
128-
}
129-
130-
if (class_exists($type)) {
125+
if (class_exists($type) || enum_exists($type)) {
131126
$imports[] = $type;
132127

133128
// for nested objects, allow additionally to pass an instance of the nested model also just plain
@@ -138,6 +133,8 @@ private function getBuilderClassImports(array $properties, array $originalClassI
138133
));
139134

140135
$property->setType();
136+
137+
$imports[] = $type . 'Builder';
141138
}
142139
}
143140
}

tests/AbstractPHPModelGeneratorTestCase.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,12 @@ public function getClassName(
274274
*/
275275
protected function generateDirectory(string $directory, GeneratorConfiguration $configuration): array
276276
{
277-
$generatedClasses = (new ModelGenerator($configuration))->generateModels(
277+
$generator = new ModelGenerator($configuration);
278+
if (is_callable($this->modifyModelGenerator)) {
279+
($this->modifyModelGenerator)($generator);
280+
}
281+
282+
$generatedClasses = $generator->generateModels(
278283
new RecursiveDirectoryProvider(__DIR__ . '/Schema/' . $this->getStaticClassName() . '/' . $directory),
279284
MODEL_TEMP_PATH,
280285
);

tests/PostProcessor/BuilderClassPostProcessorTest.php

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@
44

55
namespace PHPModelGenerator\Tests\PostProcessor;
66

7+
use FilesystemIterator;
78
use PHPModelGenerator\Model\GeneratorConfiguration;
89
use PHPModelGenerator\ModelGenerator;
910
use PHPModelGenerator\SchemaProcessor\PostProcessor\BuilderClassPostProcessor;
11+
use PHPModelGenerator\SchemaProcessor\PostProcessor\EnumPostProcessor;
1012
use PHPModelGenerator\Tests\AbstractPHPModelGeneratorTestCase;
13+
use RecursiveDirectoryIterator;
14+
use RecursiveIteratorIterator;
15+
use SplFileInfo;
1116

1217
class BuilderClassPostProcessorTest extends AbstractPHPModelGeneratorTestCase
1318
{
@@ -103,26 +108,21 @@ public function testImplicitNull(): void
103108

104109
public function testNestedObject(): void
105110
{
106-
$className = $this->generateClassFromFile('NestedObject.json');
111+
$files = $this->generateDirectory(
112+
'NestedObject',
113+
(new GeneratorConfiguration())
114+
->setNamespacePrefix('MyApp\\Namespace\\')
115+
->setOutputEnabled(false)
116+
->setImplicitNull(true),
117+
);
107118

119+
$this->assertCount(2, $files);
108120
$this->assertGeneratedBuilders(2);
109121

110-
$builderClassName = $className . 'Builder';
122+
$builderClassName = 'MyApp\Namespace\NestedObjectBuilder';
111123
$builderObject = new $builderClassName();
112124

113-
$nestedObjectClassName = null;
114-
foreach ($this->getGeneratedFiles() as $file) {
115-
if (str_contains($file, 'Address')) {
116-
$nestedObjectClassName = str_replace('.php', '', basename($file));
117-
118-
break;
119-
}
120-
}
121-
122-
$nestedBuilderClassName = $nestedObjectClassName . 'Builder';
123-
124-
$this->assertNotEmpty($nestedObjectClassName);
125-
$expectedTypeHint = "$nestedObjectClassName|$nestedBuilderClassName|array|null";
125+
$expectedTypeHint = "Address|AddressBuilder|array|null";
126126
$this->assertSame($expectedTypeHint, $this->getParameterTypeAnnotation($builderObject, 'setAddress'));
127127
$this->assertSame($expectedTypeHint, $this->getReturnTypeAnnotation($builderObject, 'getAddress'));
128128

@@ -136,6 +136,7 @@ public function testNestedObject(): void
136136
$this->assertSame(10, $object->getAddress()->getNumber());
137137

138138
// test generate nested object from nested builder
139+
$nestedBuilderClassName = 'MyApp\Namespace\Dependencies\AddressBuilder';
139140
$nestedBuilderObject = new $nestedBuilderClassName();
140141
$this->assertSame('string|null', $this->getParameterTypeAnnotation($nestedBuilderObject, 'setStreet'));
141142
$this->assertSame('int|null', $this->getParameterTypeAnnotation($nestedBuilderObject, 'setNumber'));
@@ -151,12 +152,18 @@ public function testNestedObject(): void
151152
$this->assertSame(10, $object->getAddress()->getNumber());
152153

153154
// test add validated object
155+
$nestedObjectClassName = 'MyApp\Namespace\Dependencies\Address';
154156
$nestedObject = new $nestedObjectClassName($addressArray);
155157
$builderObject->setAddress($nestedObject);
156158
$this->assertSame($nestedObject, $builderObject->getAddress());
157159
$object = $builderObject->validate();
158160
$this->assertSame('Test street', $object->getAddress()->getStreet());
159161
$this->assertSame(10, $object->getAddress()->getNumber());
162+
163+
// check if the nested objects from a different namespace are correctly imported
164+
$mainFileContent = file_get_contents(str_replace('.php', 'Builder.php', $files[1]));
165+
$this->assertStringContainsString("use $nestedObjectClassName;", $mainFileContent);
166+
$this->assertStringContainsString("use $nestedBuilderClassName;", $mainFileContent);
160167
}
161168

162169
public function testNestedObjectArray(): void
@@ -201,10 +208,37 @@ public function testNestedObjectArray(): void
201208
}
202209
}
203210

211+
public function testEnum(): void
212+
{
213+
$this->modifyModelGenerator = static function (ModelGenerator $generator): void {
214+
$generator->addPostProcessor(new BuilderClassPostProcessor())->addPostProcessor(new EnumPostProcessor());
215+
};
216+
$className = $this->generateClassFromFile('BasicSchema.json');
217+
218+
$builderClassName = $className . 'Builder';
219+
$builderObject = new $builderClassName();
220+
221+
$this->assertSame('string', $this->getParameterTypeAnnotation($builderObject, 'setName'));
222+
$this->assertSame('int|null', $this->getParameterTypeAnnotation($builderObject, 'setAge'));
223+
$this->assertSame('string|null', $this->getReturnTypeAnnotation($builderObject, 'getName'));
224+
$this->assertSame('int|null', $this->getReturnTypeAnnotation($builderObject, 'getAge'));
225+
}
226+
204227
private function assertGeneratedBuilders(int $expectedGeneratedBuilders): void
205228
{
206229
$dir = sys_get_temp_dir() . '/PHPModelGeneratorTest/Models';
207-
$files = array_filter(scandir($dir), fn (string $file): bool => str_ends_with($file, 'Builder.php'));
230+
231+
$it = new RecursiveIteratorIterator(
232+
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)
233+
);
234+
235+
$files = [];
236+
/** @var SplFileInfo $file */
237+
foreach ($it as $file) {
238+
if ($file->isFile() && str_ends_with($file->getFilename(), 'Builder.php')) {
239+
$files[] = $file->getPathname();
240+
}
241+
}
208242

209243
$this->assertCount($expectedGeneratedBuilders, $files);
210244
}

tests/PostProcessor/EnumPostProcessorTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PHPModelGenerator\Exception\SchemaException;
1313
use PHPModelGenerator\Model\GeneratorConfiguration;
1414
use PHPModelGenerator\ModelGenerator;
15+
use PHPModelGenerator\SchemaProcessor\PostProcessor\BuilderClassPostProcessor;
1516
use PHPModelGenerator\SchemaProcessor\PostProcessor\EnumPostProcessor;
1617
use PHPModelGenerator\Tests\AbstractPHPModelGeneratorTestCase;
1718
use ReflectionEnum;
@@ -585,6 +586,64 @@ public function testNameNormalization(string $name, string $expectedNormalizedNa
585586
);
586587
}
587588

589+
/**
590+
* @requires PHP >= 8.1
591+
*/
592+
public function testEnumForBuilderClass(): void
593+
{
594+
$this->modifyModelGenerator = static function (ModelGenerator $generator): void {
595+
$generator
596+
->addPostProcessor(new BuilderClassPostProcessor())
597+
->addPostProcessor(
598+
new EnumPostProcessor(
599+
join(DIRECTORY_SEPARATOR, [sys_get_temp_dir(), 'PHPModelGeneratorTest', 'Enum']),
600+
'Enum',
601+
)
602+
);
603+
};
604+
605+
$className = $this->generateClassFromFileTemplate('EnumProperty.json', ['["hans", "dieter"]'], escape: false);
606+
$builderClassName = $className . 'Builder';
607+
608+
$this->assertGeneratedEnums(1);
609+
610+
$builder = new $builderClassName();
611+
$builder->setProperty('dieter');
612+
613+
$object = $builder->validate();
614+
$this->assertInstanceOf($className, $object);
615+
$this->assertSame('dieter', $object->getProperty()->value);
616+
617+
$returnType = $this->getReturnType($object, 'getProperty');
618+
$enum = $returnType->getName();
619+
$this->assertTrue(enum_exists($enum));
620+
621+
$reflectionEnum = new ReflectionEnum($enum);
622+
$enumName = $reflectionEnum->getShortName();
623+
624+
$this->assertNull($this->getReturnType($builder, 'getProperty'));
625+
$this->assertEqualsCanonicalizing(
626+
[$enumName, 'string', 'null'],
627+
explode('|', $this->getReturnTypeAnnotation($builder, 'getProperty')),
628+
);
629+
630+
$this->assertNull($this->getParameterType($builder, 'setProperty'));
631+
$this->assertEqualsCanonicalizing(
632+
[$enumName, 'string', 'null'],
633+
explode('|', $this->getParameterTypeAnnotation($builder, 'setProperty')),
634+
);
635+
636+
$builder->setProperty($enum::Hans);
637+
$object = $builder->validate();
638+
$this->assertInstanceOf($className, $object);
639+
$this->assertSame('hans', $object->getProperty()->value);
640+
641+
$builder->setProperty('Meier');
642+
$this->expectException(EnumException::class);
643+
$this->expectExceptionMessage('Invalid value for property declined by enum constraint');
644+
$builder->validate();
645+
}
646+
588647
public function normalizedNamesDataProvider(): array
589648
{
590649
return [

tests/Schema/BuilderClassPostProcessorTest/NestedObject.json

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"street": {
5+
"type": "string"
6+
},
7+
"number": {
8+
"type": "integer"
9+
}
10+
}
11+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"address": {
5+
"$ref": "./Dependencies/Address.json"
6+
}
7+
}
8+
}

0 commit comments

Comments
 (0)