diff --git a/docs/code-generation/assemblers.md b/docs/code-generation/assemblers.md index 30b536bb..82802f14 100644 --- a/docs/code-generation/assemblers.md +++ b/docs/code-generation/assemblers.md @@ -19,6 +19,7 @@ to generate the code you want to add to the generated SOAP types. - [IteratorAssembler](#iteratorassembler) - [JsonSerializableAssembler](#jsonserializableassembler) - [PropertyAssembler](#propertyassembler) +- [PropertyDefaultsAssembler](#propertydefaultsassembler) - [RequestAssembler](#requestassembler) - [ResultAssembler](#resultassembler) - [ResultProviderAssembler](#resultproviderassembler) @@ -317,6 +318,19 @@ new PropertyAssembler(PropertyGenerator::VISIBILITY_PROTECTED) Please note that the default ruleset has a visibility of private. If you want to override this, you will have to override all rules by calling `Phpro\SoapClient\CodeGenerator\Config\Config::setRuleSet`. +## PropertyDefaultsAssembler + +This `PropertyDefaultsAssembler` can be used together with the default `PropertyAssembler` and can be used to determine basic default values for specific properties. +It adds default values for following scalar types: `string`, `int`, `float`, `bool`, `array`, `mixed`. + +Example output: + +```php + /** + * @var string + */ + private $prop1 = ''; +``` ## RequestAssembler diff --git a/src/Phpro/SoapClient/CodeGenerator/Assembler/PropertyDefaultsAssembler.php b/src/Phpro/SoapClient/CodeGenerator/Assembler/PropertyDefaultsAssembler.php new file mode 100644 index 00000000..f481585e --- /dev/null +++ b/src/Phpro/SoapClient/CodeGenerator/Assembler/PropertyDefaultsAssembler.php @@ -0,0 +1,55 @@ +getClass(); + $property = $context->getProperty(); + $propertyGenerator = $class->getProperty($property->getName()); + if (!$propertyGenerator) { + return; + } + + if ($propertyGenerator->getDefaultValue()) { + return; + } + + $defaultValue = wrap( + fn (): mixed => match ($property->getPhpType()) { + 'mixed' => null, + 'string' => '', + 'int' => 0, + 'bool' => false, + 'float' => 0.0, + 'array' => [], + default => throw new \RuntimeException('Type with unknown default: ' . $property->getPhpType()) + } + ); + + if ($defaultValue->isFailed()) { + return; + } + + $propertyGenerator + ->setDefaultValue($defaultValue->getResult()) + ->omitDefaultValue(false); + } +} diff --git a/test/PhproTest/SoapClient/Unit/CodeGenerator/Assembler/PropertyDefaultsAssemblerTest.php b/test/PhproTest/SoapClient/Unit/CodeGenerator/Assembler/PropertyDefaultsAssemblerTest.php new file mode 100644 index 00000000..f4028b42 --- /dev/null +++ b/test/PhproTest/SoapClient/Unit/CodeGenerator/Assembler/PropertyDefaultsAssemblerTest.php @@ -0,0 +1,118 @@ +assertInstanceOf(AssemblerInterface::class, $assembler); + } + + /** + * @test + * @dataProvider provideAssemblerContexts + */ + function it_can_enhance_assembled_property_with_a_default_value( + PropertyContext $context, + string $expectedCode, + bool $skipPropertyGeneration = false, + ): void { + if (!$skipPropertyGeneration) { + (new PropertyAssembler(PropertyAssemblerOptions::create()->withDocBlocks(false)))->assemble($context); + } + (new PropertyDefaultsAssembler())->assemble($context); + + $code = $context->getClass()->generate(); + $this->assertEquals($expectedCode, $code); + } + + public static function provideAssemblerContexts(): iterable + { + $expectedOutput = << [ + self::createContext(self::configureProperty(XsdType::create('mixed'))), + sprintf($expectedOutput, 'private mixed $prop1 = null;') + ]; + yield 'string' => [ + self::createContext(self::configureProperty(XsdType::create('string'))), + sprintf($expectedOutput, 'private string $prop1 = \'\';') + ]; + yield 'int' => [ + self::createContext(self::configureProperty(XsdType::create('int'))), + sprintf($expectedOutput, 'private int $prop1 = 0;') + ]; + yield 'bool' => [ + self::createContext(self::configureProperty(XsdType::create('bool'))), + sprintf($expectedOutput, 'private bool $prop1 = false;') + ]; + yield 'float' => [ + self::createContext(self::configureProperty(XsdType::create('float'))), + sprintf($expectedOutput, 'private float $prop1 = 0;') + ]; + yield 'nullable-type' => [ + self::createContext(self::configureProperty(XsdType::create('SomeClass')->withMeta( + static fn(TypeMeta $meta): TypeMeta => $meta->withIsNullable(true) + ))), + sprintf($expectedOutput, 'private ?\ns1\SomeClass $prop1 = null;') + ]; + yield 'non-nullable-type' => [ + self::createContext(self::configureProperty(XsdType::create('SomeClass'))), + sprintf($expectedOutput, 'private \ns1\SomeClass $prop1;') + ]; + yield 'without-known-property' => [ + self::createContext(self::configureProperty(XsdType::create('SomeClass'))), + <<