diff --git a/docs/BundleConfiguration.md b/docs/BundleConfiguration.md index fef0896..a727c33 100644 --- a/docs/BundleConfiguration.md +++ b/docs/BundleConfiguration.md @@ -7,6 +7,7 @@ The bundle provides following defaults: ```yaml twig_doc: doc_identifier: TWIG_DOC + use_fake_parameter: false directories: - '%twig.default_path%/components' categories: @@ -51,6 +52,12 @@ MY_DOC_IDENTIFIER#}
``` +### Fake Parameters + +By default, the creation of fake parameters is disabled! + +When enabled, the bundle fakes parameters based on parameter-config of the component + ### Categories The bundle groups components into categories and optionally into sub-categories. diff --git a/docs/ComponentConfiguration.md b/docs/ComponentConfiguration.md index db6a4dc..16c077a 100644 --- a/docs/ComponentConfiguration.md +++ b/docs/ComponentConfiguration.md @@ -85,8 +85,46 @@ components: ### Parameter Provision -You must provide the types of your template parameters in the configuration. +You must provide the types of your template parameters in the configuration. As twig templates are not aware of types, there is no other possibility at the moment. + +Unless you enable use_fake_parameter in the bundle configuration, parameter-values for the components +must be configured in each variation for this component! + +`use_fake_parameter: false` + +When a parameter is not provided in a variation, it will be set to NULL. + +Objects will not be provided as objects, only as arrays based on the variation configuration. + +e.g: +```yaml +... +parameters: + car: App\Entity\Car + owner: String +variation: + blue: + car: + color: blue + manufacturer: + name: Mitsubishi +``` +will result that car is provided as an array when the component is rendered: +```php +[ + 'color' => 'blue', + 'manufacturer' => [ + 'name' => 'Mitsubishi' + ], + 'owner' => null +] +``` + +When you do not call fancy object-methods in your component-templates, this should suffice for most cases. + +`use_fake_paramter: true` + As this bundle makes use of [Nelmio/Alice](https://github.com/nelmio/alice) and [FakerPhp](https://fakerphp.github.io), all you need to do is define the types of your parameters in the component configuration. The bundle will take care of creating a set of parameters for every component. diff --git a/phpunit.xml.dist b/phpunit.xml.dist index b435231..1b767b1 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,11 +1,9 @@ $this->faker->getFakeData($parameters), + 'default' => $this->createVariationParameters($parameters, []), ]; } @@ -125,11 +126,34 @@ private function createVariationParameters(array $parameters, array $variation): { $params = []; + if ($this->useFakeParams) { + return $this->createFakeParamValues($parameters, $variation); + } + + foreach ($parameters as $name => $type) { + if (\is_array($type)) { + $params[$name] = $this->createVariationParameters($type, $variation[$name] ?? []); + } else { + $params[$name] = $variation[$name] ?? null; + } + } + + return $params; + } + + private function createFakeParamValues(array $parameters, array $variation): array + { + $params = []; + foreach ($parameters as $name => $type) { if (\is_array($type)) { $paramValue[$name] = $this->createVariationParameters($type, $variation[$name] ?? []); } else { - $paramValue = $this->faker->getFakeData([$name => $type], $variation[$name] ?? null); + if (\array_key_exists($name, $variation) && null === $variation[$name]) { + $paramValue = [$name => null]; + } else { + $paramValue = $this->faker->getFakeData([$name => $type], $variation[$name] ?? null); + } } $params += $paramValue; } diff --git a/src/Component/Data/Generator/NullGenerator.php b/src/Component/Data/Generator/NullGenerator.php index 8c9687f..00ef79e 100644 --- a/src/Component/Data/Generator/NullGenerator.php +++ b/src/Component/Data/Generator/NullGenerator.php @@ -10,7 +10,7 @@ class NullGenerator implements GeneratorInterface { public function supports(string $type, mixed $context = null): bool { - return null === $context || '' === $context; + return true; } public function generate(string $type, mixed $context = null): null diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index a21aeb8..4027fce 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -21,6 +21,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->thenInvalid('The twig_doc documentation identifier must match \w (regex)') ->end() ->end() + ->booleanNode('use_fake_parameter')->defaultFalse()->end() ->arrayNode('breakpoints') ->defaultValue([ 'small' => 240, diff --git a/src/DependencyInjection/TwigDocExtension.php b/src/DependencyInjection/TwigDocExtension.php index aac2a9b..294a41b 100644 --- a/src/DependencyInjection/TwigDocExtension.php +++ b/src/DependencyInjection/TwigDocExtension.php @@ -36,5 +36,8 @@ public function load(array $configs, ContainerBuilder $container): void $definition = $container->getDefinition('twig_doc.service.faker'); $definition->setArgument('$generators', tagged_iterator('twig_doc.data_generator')); + + $definition = $container->getDefinition('twig_doc.service.component_factory'); + $definition->setArgument('$useFakeParams', $config['use_fake_parameter']); } } diff --git a/templates/component/_invalid_component.html.twig b/templates/component/_invalid_component.html.twig index b95d11a..5ecf291 100644 --- a/templates/component/_invalid_component.html.twig +++ b/templates/component/_invalid_component.html.twig @@ -35,7 +35,7 @@ {% if loop.first %} {% endif %} diff --git a/tests/Functional/Service/ComponentItemFactoryTest.php b/tests/Functional/Service/ComponentItemFactoryTest.php index 5fd9834..915705d 100644 --- a/tests/Functional/Service/ComponentItemFactoryTest.php +++ b/tests/Functional/Service/ComponentItemFactoryTest.php @@ -18,6 +18,7 @@ use Qossmic\TwigDocBundle\Exception\InvalidComponentConfigurationException; use Qossmic\TwigDocBundle\Service\CategoryService; use Qossmic\TwigDocBundle\Tests\TestApp\Entity\Car; +use Qossmic\TwigDocBundle\Tests\TestApp\Test\ConfigurableContainerTrait; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; #[CoversClass(ComponentItemFactory::class)] @@ -29,6 +30,8 @@ #[UsesClass(NullGenerator::class)] class ComponentItemFactoryTest extends KernelTestCase { + use ConfigurableContainerTrait; + #[DataProvider('getValidComponents')] public function testValidComponent(array $componentData): void { @@ -115,8 +118,10 @@ public function testFactoryCreatesDefaultVariationWithParameterTypes(): void ], ]; + $container = $this->createContainer(['twig_doc' => ['use_fake_parameter' => true]]); + /** @var ComponentItemFactory $factory */ - $factory = self::getContainer()->get('twig_doc.service.component_factory'); + $factory = $container->get('twig_doc.service.component_factory'); $component = $factory->create($data); @@ -135,6 +140,40 @@ public function testFactoryCreatesDefaultVariationWithParameterTypes(): void self::assertIsFloat($component->getVariations()['default']['complex']['amount']); } + public function testCreateObjectParameter(): void + { + $data = [ + 'name' => 'component', + 'title' => 'title', + 'description' => 'description', + 'category' => 'MainCategory', + 'path' => 'path', + 'renderPath' => 'renderPath', + 'parameters' => [ + 'car' => Car::class, + ], + 'variations' => [ + 'variation1' => [ + 'car' => [ + 'color' => 'blue', + ], + ], + 'variation2' => [ + 'car' => null, + ], + ], + ]; + + $container = $this->createContainer(['twig_doc' => ['use_fake_parameter' => true]]); + + /** @var ComponentItemFactory $factory */ + $factory = $container->get('twig_doc.service.component_factory'); + + $component = $factory->create($data); + + self::assertInstanceOf(ComponentItem::class, $component); + } + public function testCreateKeepsParamValueFromVariation(): void { $data = [ @@ -200,11 +239,14 @@ public function testCreateForObjectParameter(): void static::assertIsArray($variations['fuchsia']); static::assertArrayHasKey('car', $variations['fuchsia']); - $car = $variations['fuchsia']['car']; + $carData = $variations['fuchsia']['car']; - static::assertInstanceOf(Car::class, $car); - static::assertEquals('fuchsia', $car->getColor()); - static::assertEquals('Mitsubishi', $car->getManufacturer()->getName()); + static::assertEquals([ + 'color' => 'fuchsia', + 'manufacturer' => [ + 'name' => 'Mitsubishi', + ], + ], $carData); } public function testCreateForParamWithOptionalVariationValue(): void @@ -224,7 +266,7 @@ public function testCreateForParamWithOptionalVariationValue(): void 'variations' => [ 'variation1' => [ 'stringParam' => 'Some cool hipster text', - 'optionalEmpty' => '', + 'optionalEmpty' => null, ], ], ]; @@ -238,7 +280,7 @@ public function testCreateForParamWithOptionalVariationValue(): void self::assertIsArray($variations); self::assertArrayHasKey('variation1', $variations); self::assertArrayHasKey('secondParam', $variations['variation1']); - self::assertIsString($variations['variation1']['secondParam']); + self::assertNull($variations['variation1']['secondParam']); self::assertNull($variations['variation1']['optionalEmpty']); } diff --git a/tests/TestApp/Kernel.php b/tests/TestApp/Kernel.php index 381fc17..33c9a2e 100644 --- a/tests/TestApp/Kernel.php +++ b/tests/TestApp/Kernel.php @@ -17,9 +17,9 @@ class Kernel extends SymfonyKernel { use MicroKernelTrait; - public function __construct() + public function __construct(string $environment = 'test', bool $debug = false, private readonly array $extraConfigs = []) { - parent::__construct('test', false); + parent::__construct($environment, $debug); } public function registerBundles(): iterable @@ -42,6 +42,10 @@ protected function configureContainer(ContainerBuilder $container, LoaderInterfa $loader->load(__DIR__.'/config/services.php'); $loader->load(__DIR__.'/config/packages/*.php', 'glob'); $loader->load(__DIR__.'/config/packages/*.yaml', 'glob'); + + foreach ($this->extraConfigs as $name => $config) { + $container->prependExtensionConfig($name, $config); + } } public function getCacheDir(): string diff --git a/tests/TestApp/Test/ConfigurableContainerTrait.php b/tests/TestApp/Test/ConfigurableContainerTrait.php new file mode 100644 index 0000000..6be4320 --- /dev/null +++ b/tests/TestApp/Test/ConfigurableContainerTrait.php @@ -0,0 +1,22 @@ +remove($kernel->getCacheDir()); + $kernel->boot(); + + return $kernel->getContainer(); + } +} diff --git a/tests/Unit/Component/ComponentItemFactoryTest.php b/tests/Unit/Component/ComponentItemFactoryTest.php index 44fd8c8..3dbafcd 100644 --- a/tests/Unit/Component/ComponentItemFactoryTest.php +++ b/tests/Unit/Component/ComponentItemFactoryTest.php @@ -38,7 +38,8 @@ public function testValidComponent(array $componentData): void $componentItemFactory = new ComponentItemFactory( $validatorMock, $categoryServiceMock, - $this->createMock(Faker::class) + $this->createMock(Faker::class), + false ); $item = $componentItemFactory->create($componentData); @@ -57,7 +58,12 @@ public function testInvalidCategory(): void ->willReturn(null); $validatorMock = $this->createMock(ValidatorInterface::class); - $componentItemFactory = new ComponentItemFactory($validatorMock, $categoryServiceMock, $this->createMock(Faker::class)); + $componentItemFactory = new ComponentItemFactory( + $validatorMock, + $categoryServiceMock, + $this->createMock(Faker::class), + false + ); $componentItemFactory->create(['category' => 'Category']); } @@ -73,7 +79,8 @@ public function testGetParamsFromVariables(): void $componentItemFactory = new ComponentItemFactory( $this->createMock(ValidatorInterface::class), $this->createMock(CategoryService::class), - $this->createMock(Faker::class) + $this->createMock(Faker::class), + false ); $result = $componentItemFactory->getParamsFromVariables($variables); diff --git a/tests/Unit/Component/Data/Generator/NullGeneratorTest.php b/tests/Unit/Component/Data/Generator/NullGeneratorTest.php index cff0a80..22bc907 100644 --- a/tests/Unit/Component/Data/Generator/NullGeneratorTest.php +++ b/tests/Unit/Component/Data/Generator/NullGeneratorTest.php @@ -15,8 +15,8 @@ public function testSupports(): void { $generator = new NullGenerator(); - static::assertTrue($generator->supports('any', null)); - static::assertFalse($generator->supports('any', 'notEmpty')); + static::assertTrue($generator->supports('any')); + static::assertTrue($generator->supports('any', 'notEmpty')); } public function testGenerate(): void @@ -24,5 +24,6 @@ public function testGenerate(): void $generator = new NullGenerator(); static::assertNull($generator->generate('any')); + static::assertNull($generator->generate('any', 'anyContext')); } } diff --git a/tests/Unit/Component/Data/Generator/ScalarGeneratorTest.php b/tests/Unit/Component/Data/Generator/ScalarGeneratorTest.php index 805db30..87f296b 100644 --- a/tests/Unit/Component/Data/Generator/ScalarGeneratorTest.php +++ b/tests/Unit/Component/Data/Generator/ScalarGeneratorTest.php @@ -15,11 +15,11 @@ class ScalarGeneratorTest extends TestCase { #[DataProvider('getSupportsTestCases')] - public function testSupports(string $type, mixed $context, bool $expected): void + public function testSupports(string $type, mixed $context, bool $expectedReturn): void { $generator = new ScalarGenerator(); - self::assertEquals($expected, $generator->supports($type, $context)); + self::assertEquals($expectedReturn, $generator->supports($type, $context)); } #[DataProvider('getGenerateTestCases')] @@ -57,42 +57,42 @@ public static function getGenerateTestCases(): iterable { yield 'bool' => [ 'type' => Type::BUILTIN_TYPE_BOOL, - 'method' => 'assertIsBool', + 'assertionMethod' => 'assertIsBool', ]; yield 'boolean' => [ 'type' => 'boolean', - 'method' => 'assertIsBool', + 'assertionMethod' => 'assertIsBool', ]; yield 'float' => [ 'type' => Type::BUILTIN_TYPE_FLOAT, - 'method' => 'assertIsFloat', + 'assertionMethod' => 'assertIsFloat', ]; yield 'double' => [ 'type' => 'double', - 'method' => 'assertIsFloat', + 'assertionMethod' => 'assertIsFloat', ]; yield 'integer' => [ 'type' => 'integer', - 'method' => 'assertIsInt', + 'assertionMethod' => 'assertIsInt', ]; yield 'int' => [ 'type' => Type::BUILTIN_TYPE_INT, - 'method' => 'assertIsInt', + 'assertionMethod' => 'assertIsInt', ]; yield 'null' => [ 'type' => Type::BUILTIN_TYPE_NULL, - 'method' => 'assertNull', + 'assertionMethod' => 'assertNull', ]; yield 'string' => [ 'type' => Type::BUILTIN_TYPE_STRING, - 'method' => 'assertIsString', + 'assertionMethod' => 'assertIsString', ]; } } diff --git a/tests/Unit/DependencyInjection/Compiler/TwigDocCollectDocsPassTest.php b/tests/Unit/DependencyInjection/Compiler/TwigDocCollectDocsPassTest.php index 7572243..a11137e 100644 --- a/tests/Unit/DependencyInjection/Compiler/TwigDocCollectDocsPassTest.php +++ b/tests/Unit/DependencyInjection/Compiler/TwigDocCollectDocsPassTest.php @@ -54,8 +54,8 @@ public function testProcessNotEnrichingPathsForMissingTemplate(): void $definition = $container->getDefinition('twig_doc.service.component'); - static::assertEmpty($definition->getArgument('$componentsConfig')[0]['path']); - static::assertEmpty($definition->getArgument('$componentsConfig')[0]['renderPath']); + static::assertArrayNotHasKey('path', $definition->getArgument('$componentsConfig')[0]); + static::assertArrayNotHasKey('renderPath', $definition->getArgument('$componentsConfig')[0]); } public function testProcessNotEnrichingPathsForAmbiguousTemplate(): void @@ -76,10 +76,10 @@ public function testProcessNotEnrichingPathsForAmbiguousTemplate(): void $definition = $container->getDefinition('twig_doc.service.component'); - static::assertEmpty($definition->getArgument('$componentsConfig')[0]['path']); - static::assertEmpty($definition->getArgument('$componentsConfig')[0]['renderPath']); - static::assertEmpty($definition->getArgument('$componentsConfig')[1]['path']); - static::assertEmpty($definition->getArgument('$componentsConfig')[1]['renderPath']); + static::assertArrayNotHasKey('path', $definition->getArgument('$componentsConfig')[0]); + static::assertArrayNotHasKey('renderPath', $definition->getArgument('$componentsConfig')[0]); + static::assertArrayNotHasKey('path', $definition->getArgument('$componentsConfig')[1]); + static::assertArrayNotHasKey('renderPath', $definition->getArgument('$componentsConfig')[1]); } public function testProcessThrowsExceptionForInvalidConfiguration(): void diff --git a/tests/Unit/DependencyInjection/ConfigurationTest.php b/tests/Unit/DependencyInjection/ConfigurationTest.php index fff3fd9..37c0f82 100644 --- a/tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/tests/Unit/DependencyInjection/ConfigurationTest.php @@ -43,6 +43,7 @@ public static function getTestConfiguration(): iterable ], [ 'doc_identifier' => 'TWIG_DOC', + 'use_fake_parameter' => false, 'breakpoints' => [ 'small' => 240, 'medium' => 640, @@ -107,6 +108,7 @@ public static function getTestConfiguration(): iterable ], [ 'doc_identifier' => 'TWIG_DOC', + 'use_fake_parameter' => false, 'breakpoints' => [ 'small' => 240, 'medium' => 640, @@ -167,6 +169,7 @@ public static function getTestConfiguration(): iterable 'generic' => 896, ], 'doc_identifier' => 'TWIG_DOC', + 'use_fake_parameter' => false, 'directories' => [ '%twig.default_path%/components', ], diff --git a/tests/bootstrap.php b/tests/bootstrap.php deleted file mode 100644 index c923d81..0000000 --- a/tests/bootstrap.php +++ /dev/null @@ -1,16 +0,0 @@ -remove($kernel->getCacheDir()); -$kernel->boot(); -$kernel->shutdown();