From 7125d6e8c1bead5b4f2df7fd3a6b347778934ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20H=C3=B6lzel?= <56548897+davidhoelzel@users.noreply.github.com> Date: Mon, 18 Mar 2024 13:19:29 +0100 Subject: [PATCH] Create Pipeline (#7) Setup pipeline with tests and cs-fixer --- .github/workflows/tests.yaml | 32 +++++++++++++++++ .gitignore | 1 + .php-cs-fixer.dist.php | 16 +++++++++ composer.json | 3 +- config/documentation.php | 5 +-- src/Component/ComponentCategory.php | 9 +++-- src/Component/ComponentInvalid.php | 1 + src/Component/ComponentItem.php | 30 ++++++++++------ src/Component/ComponentItemFactory.php | 13 +++---- src/Controller/TwigDocController.php | 14 ++++---- src/DependencyInjection/Configuration.php | 8 ++--- src/DependencyInjection/TwigDocExtension.php | 8 ++--- ...InvalidComponentConfigurationException.php | 7 ++-- src/Exception/InvalidConfigException.php | 1 + src/Service/CategoryService.php | 11 +++--- src/Service/ComponentService.php | 15 ++++---- src/Twig/TwigDocExtension.php | 17 +++++---- src/TwigDocBundle.php | 1 + .../Service/ComponentItemFactoryTest.php | 19 +++++----- tests/TestApp/Kernel.php | 3 +- tests/TestApp/config/packages/twig_doc.php | 22 ++++++------ .../Component/ComponentItemFactoryTest.php | 12 +++---- .../DependencyInjection/ConfigurationTest.php | 36 +++++++++---------- tests/Unit/Service/CategoryServiceTest.php | 14 ++++---- 24 files changed, 177 insertions(+), 121 deletions(-) create mode 100644 .github/workflows/tests.yaml create mode 100644 .php-cs-fixer.dist.php diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..60196f3 --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,32 @@ +name: Tests + +on: + pull_request: + push: + branches: + - main + +jobs: + tests: + name: "PHP ${{ matrix.php-version }}" + runs-on: ubuntu-latest + continue-on-error: false + strategy: + matrix: + php-version: ['8.2', '8.3'] + steps: + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + tools: composer:v2 + - name: Checkout code + uses: actions/checkout@v3 + - name: Install Dependencies + run: composer update --no-interaction --prefer-dist --optimize-autoloader --prefer-stable + - name: PHP-CS-Fixer + run: vendor/bin/php-cs-fixer fix --diff --dry-run + - name: Run tests + run: vendor/bin/phpunit + + diff --git a/.gitignore b/.gitignore index 7c6c1fb..a0a9d64 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /vendor/ .phpunit.cache composer.lock +.php-cs-fixer.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..912d733 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,16 @@ +in(__DIR__) + ->exclude('var'); + +$config = new PhpCsFixer\Config(); +return $config + ->setRiskyAllowed(true) + ->setRules([ + '@Symfony' => true, + '@Symfony:risky' => true, + 'array_syntax' => ['syntax' => 'short'], + 'yoda_style' => false, +]) + ->setFinder($finder); diff --git a/composer.json b/composer.json index 44bcfe9..4c08521 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,7 @@ "require-dev": { "phpunit/phpunit": "^10.5", "symfony/browser-kit": "^6.4|^7.0", - "symfony/css-selector": "^6.4|^7.0" + "symfony/css-selector": "^6.4|^7.0", + "friendsofphp/php-cs-fixer": "^3.51" } } diff --git a/config/documentation.php b/config/documentation.php index 55e5754..ccf9d71 100644 --- a/config/documentation.php +++ b/config/documentation.php @@ -1,4 +1,5 @@ services() ->set('twig_doc.controller.documentation', TwigDocController::class) + $container->services()->set('twig_doc.controller.documentation', TwigDocController::class) ->public() ->autoconfigure() ->autowire() @@ -35,5 +36,5 @@ ->autowire() ->tag('twig.extension') ->alias(TwigDocExtension::class, 'twig_doc.twig.extension') - ; + ; }; diff --git a/src/Component/ComponentCategory.php b/src/Component/ComponentCategory.php index f87559f..5e5ad60 100644 --- a/src/Component/ComponentCategory.php +++ b/src/Component/ComponentCategory.php @@ -1,4 +1,5 @@ parent; } - public function setParent(?ComponentCategory $parent): ComponentCategory + public function setParent(?self $parent): self { $this->parent = $parent; + return $this; } @@ -31,9 +33,10 @@ public function getName(): string return $this->name; } - public function setName(string $name): ComponentCategory + public function setName(string $name): self { $this->name = $name; + return $this; } } diff --git a/src/Component/ComponentInvalid.php b/src/Component/ComponentInvalid.php index dd45f22..740e9eb 100644 --- a/src/Component/ComponentInvalid.php +++ b/src/Component/ComponentInvalid.php @@ -1,4 +1,5 @@ name; } - public function setName(string $name): ComponentItem + public function setName(string $name): self { $this->name = $name; + return $this; } @@ -41,9 +43,10 @@ public function getTitle(): string return $this->title; } - public function setTitle(string $title): ComponentItem + public function setTitle(string $title): self { $this->title = $title; + return $this; } @@ -52,9 +55,10 @@ public function getDescription(): string return $this->description; } - public function setDescription(string $description): ComponentItem + public function setDescription(string $description): self { $this->description = $description; + return $this; } @@ -63,9 +67,10 @@ public function getTags(): array return $this->tags; } - public function setTags(array $tags): ComponentItem + public function setTags(array $tags): self { $this->tags = $tags; + return $this; } @@ -74,27 +79,28 @@ public function getParameters(): array return $this->parameters; } - public function setParameters(array $parameters): ComponentItem + public function setParameters(array $parameters): self { $this->parameters = $parameters; return $this; } - public function setVariations(array $variations): ComponentItem + public function setVariations(array $variations): self { $this->variations = $variations; return $this; } - public function addParameter(string $name, mixed $value): ComponentItem + public function addParameter(string $name, mixed $value): self { $this->parameters[$name] = $value; + return $this; } - public function removeParameter(string $name): ComponentItem + public function removeParameter(string $name): self { unset($this->parameters[$name]); @@ -106,13 +112,14 @@ public function getVariations(): array return $this->variations; } - public function addVariation(string $name, array $variation): ComponentItem + public function addVariation(string $name, array $variation): self { $this->variations[$name] = $variation; + return $this; } - public function removeVariation(string $name): ComponentItem + public function removeVariation(string $name): self { unset($this->variations[$name]); @@ -124,9 +131,10 @@ public function getCategory(): ComponentCategory return $this->category; } - public function setCategory(ComponentCategory $category): ComponentItem + public function setCategory(ComponentCategory $category): self { $this->category = $category; + return $this; } diff --git a/src/Component/ComponentItemFactory.php b/src/Component/ComponentItemFactory.php index d2fb560..16c4986 100644 --- a/src/Component/ComponentItemFactory.php +++ b/src/Component/ComponentItemFactory.php @@ -1,12 +1,13 @@ categoryService->getCategories())), @@ -53,7 +54,7 @@ private function createItem(array $data): ComponentItem ->setTags($data['tags'] ?? []) ->setParameters($data['parameters'] ?? []) ->setVariations($data['variations'] ?? [ - 'default' => $this->createVariationParameters($data['parameters'] ?? []) + 'default' => $this->createVariationParameters($data['parameters'] ?? []), ]); return $item; @@ -63,7 +64,7 @@ public function createVariationParameters(array $parameters): array { $params = []; foreach ($parameters as $name => $type) { - if (is_array($type)) { + if (\is_array($type)) { $paramValue = $this->createVariationParameters($type); } else { $paramValue = $this->createParamValue($type); @@ -86,7 +87,7 @@ private function createParamValue(string $type): bool|int|float|string|null return random_int(0, 100000); case 'bool': case 'boolean': - return [true, false][rand(0,1)]; + return [true, false][rand(0, 1)]; case 'float': case 'double': return (float) rand(1, 1000) / 100; diff --git a/src/Controller/TwigDocController.php b/src/Controller/TwigDocController.php index 1f3dc96..273e68d 100644 --- a/src/Controller/TwigDocController.php +++ b/src/Controller/TwigDocController.php @@ -1,15 +1,15 @@ query->get('breakpoint'); // disable profiler to get rid of toolbar in dev - if($this->profiler) { - $this->profiler->disable(); + if ($this->profiler) { + $this->profiler->disable(); } + return new Response( $this->twig->render('@TwigDoc/component.html.twig', [ 'component' => $component, 'componentData' => $request->query->all('data'), - 'quantity' => $request->query->get('quantity') + 'quantity' => $request->query->get('quantity'), ]) ); } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 233019b..5ea5e44 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -7,10 +7,6 @@ class Configuration implements ConfigurationInterface { - - /** - * @inheritDoc - */ public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder('twig_doc'); @@ -40,13 +36,13 @@ public function getConfigTreeBuilder(): TreeBuilder ->end() ->variableNode('parameters') ->validate() - ->ifTrue(fn ($v) => is_string($v) === false && is_array($v) === false) + ->ifTrue(fn ($v) => \is_string($v) === false && \is_array($v) === false) ->thenInvalid('parameters must be either a scalar or an array') ->end() ->end() ->variableNode('variations') ->validate() - ->ifTrue(fn ($v) => is_string($v) === false && is_array($v) === false) + ->ifTrue(fn ($v) => \is_string($v) === false && \is_array($v) === false) ->thenInvalid('variations must be either a scalar or an array') ->end() ->end() diff --git a/src/DependencyInjection/TwigDocExtension.php b/src/DependencyInjection/TwigDocExtension.php index c4ecf84..b7ac68a 100644 --- a/src/DependencyInjection/TwigDocExtension.php +++ b/src/DependencyInjection/TwigDocExtension.php @@ -9,16 +9,12 @@ class TwigDocExtension extends Extension { - - /** - * @inheritDoc - */ - public function load(array $configs, ContainerBuilder $container) + public function load(array $configs, ContainerBuilder $container): void { $configuration = $this->getConfiguration($configs, $container); $config = $this->processConfiguration($configuration, $configs); - $loader = new PhpFileLoader($container, new FileLocator(__DIR__ . '/../../config')); + $loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../../config')); $loader->load('documentation.php'); $definition = $container->getDefinition('twig_doc.service.component'); diff --git a/src/Exception/InvalidComponentConfigurationException.php b/src/Exception/InvalidComponentConfigurationException.php index a080f45..45c33c8 100644 --- a/src/Exception/InvalidComponentConfigurationException.php +++ b/src/Exception/InvalidComponentConfigurationException.php @@ -1,21 +1,22 @@ violationList; } diff --git a/src/Exception/InvalidConfigException.php b/src/Exception/InvalidConfigException.php index 2afa012..1a4a955 100644 --- a/src/Exception/InvalidConfigException.php +++ b/src/Exception/InvalidConfigException.php @@ -1,4 +1,5 @@ subCategories, fn(ComponentCategory $category) => $category->getParent() === $mainCategory); + return array_filter($this->subCategories, fn (ComponentCategory $category) => $category->getParent() === $mainCategory); } return $this->subCategories; } - public function getCategory(string $category, string $subCategoryName = null): ?ComponentCategory + public function getCategory(string $category, ?string $subCategoryName = null): ?ComponentCategory { if ($subCategoryName === null) { return $this->categories[$category] ?? null; @@ -65,9 +66,7 @@ private function parseCategories(): void $cat->setName($category['name']); if (isset($this->categories[$cat->getName()])) { - throw new InvalidConfigException( - sprintf('Category %s has been already configured, be sure to have main-categories only once', $cat->getName()) - ); + throw new InvalidConfigException(sprintf('Category %s has been already configured, be sure to have main-categories only once', $cat->getName())); } $this->categories[$cat->getName()] = $cat; diff --git a/src/Service/ComponentService.php b/src/Service/ComponentService.php index 356ac32..90222cf 100644 --- a/src/Service/ComponentService.php +++ b/src/Service/ComponentService.php @@ -1,4 +1,5 @@ parse(); } @@ -72,7 +72,7 @@ private function parse(): void public function filter(string $filterQuery, string $filterType): array { - $components = array_unique($this->filterComponents($filterQuery, $filterType), SORT_REGULAR); + $components = array_unique($this->filterComponents($filterQuery, $filterType), \SORT_REGULAR); $result = []; @@ -86,23 +86,22 @@ public function filter(string $filterQuery, string $filterType): array private function filterComponents(string $filterQuery, string $filterType): array { $components = []; - switch($filterType) { + switch ($filterType) { case 'category': - $components = array_filter($this->categories, fn (string $category) => strtolower($category) === strtolower($filterQuery), ARRAY_FILTER_USE_KEY); + $components = array_filter($this->categories, fn (string $category) => strtolower($category) === strtolower($filterQuery), \ARRAY_FILTER_USE_KEY); return $components[array_key_first($components)] ?? []; case 'sub_category': $components = array_filter( $this->components, - fn (ComponentItem $item) => - $item->getCategory()->getParent() !== null + fn (ComponentItem $item) => $item->getCategory()->getParent() !== null && strtolower($item->getCategory()->getName()) === strtolower($filterQuery) ); break; case 'tags': $tags = array_map('trim', explode(',', strtolower($filterQuery))); - $components = array_filter($this->components, function(ComponentItem $item) use ($tags) { + $components = array_filter($this->components, function (ComponentItem $item) use ($tags) { return array_intersect($tags, array_map('strtolower', $item->getTags())) !== []; }); diff --git a/src/Twig/TwigDocExtension.php b/src/Twig/TwigDocExtension.php index 09a645f..8adba61 100644 --- a/src/Twig/TwigDocExtension.php +++ b/src/Twig/TwigDocExtension.php @@ -1,13 +1,14 @@ componentService->filter($filterQuery, $type); } @@ -51,8 +50,8 @@ public function renderComponent(ComponentItem $item, array $params): string try { return $this->componentRenderer->createAndRender($item->getName(), $params); - } catch (InvalidArgumentException $e) { - # no ux-component found, so try to render as normal template + } catch (\InvalidArgumentException $e) { + // no ux-component found, so try to render as normal template return $this->renderFallback($item, $params); } } @@ -68,7 +67,7 @@ public function getInvalidComponents(): array /** * @return ComponentCategory[] */ - public function getSubCategories(string $mainCategoryName = null): array + public function getSubCategories(?string $mainCategoryName = null): array { return $this->categoryService->getSubCategories($this->categoryService->getCategory($mainCategoryName)); } diff --git a/src/TwigDocBundle.php b/src/TwigDocBundle.php index 2e6a17f..a6a9500 100644 --- a/src/TwigDocBundle.php +++ b/src/TwigDocBundle.php @@ -1,4 +1,5 @@ [ 'title' => 'String', 'amount' => 'Float', - ] - ] + ], + ], ]; /** @var ComponentItemFactory $factory */ @@ -111,24 +110,24 @@ public static function getInvalidComponentConfigurationTestCases(): iterable yield [ [ 'name' => 'InvalidComponent1', - 'category' => 'MainCategory' - ] + 'category' => 'MainCategory', + ], ]; yield [ [ 'name' => 'InvalidComponentMissingTitleAndDescription', 'category' => 'MainCategory', - 'title' => 'Component title' - ] + 'title' => 'Component title', + ], ]; yield [ [ 'name' => 'InvalidComponentMissingDescription', 'category' => 'MainCategory', - 'title' => 'Component title' - ] + 'title' => 'Component title', + ], ]; yield [ @@ -141,7 +140,7 @@ public static function getInvalidComponentConfigurationTestCases(): iterable 'variations' => 'Should be an array', 'tags' => 'Should be an array', ], - TypeError::class, + \TypeError::class, ]; } } diff --git a/tests/TestApp/Kernel.php b/tests/TestApp/Kernel.php index 34224ef..381fc17 100644 --- a/tests/TestApp/Kernel.php +++ b/tests/TestApp/Kernel.php @@ -1,4 +1,5 @@ load(__DIR__.'/config/services.php'); $loader->load(__DIR__.'/config/packages/*.php', 'glob'); $loader->load(__DIR__.'/config/packages/*.yaml', 'glob'); diff --git a/tests/TestApp/config/packages/twig_doc.php b/tests/TestApp/config/packages/twig_doc.php index 73cc784..c957322 100644 --- a/tests/TestApp/config/packages/twig_doc.php +++ b/tests/TestApp/config/packages/twig_doc.php @@ -7,8 +7,8 @@ 'sub_categories' => [ 'SubCategory1', 'SubCategory2', - ] - ] + ], + ], ], 'components' => [ [ @@ -29,9 +29,9 @@ 'default' => [ 'type' => 'primary', 'msg' => 'Click Me', - 'link' => '#' - ] - ] + 'link' => '#', + ], + ], ], [ 'name' => 'ButtonSubmit', @@ -51,9 +51,9 @@ 'default' => [ 'type' => 'primary', 'msg' => 'Click Me', - 'link' => '#' - ] - ] + 'link' => '#', + ], + ], ], [ 'name' => 'InvalidComponent', @@ -64,10 +64,10 @@ 'tags' => [], 'parameters' => [], 'variations' => [ - 'default' => [] - ] + 'default' => [], + ], ], - ] + ], ]; $container->loadFromExtension('twig_doc', $config); diff --git a/tests/Unit/Component/ComponentItemFactoryTest.php b/tests/Unit/Component/ComponentItemFactoryTest.php index 806ab29..be88006 100644 --- a/tests/Unit/Component/ComponentItemFactoryTest.php +++ b/tests/Unit/Component/ComponentItemFactoryTest.php @@ -5,10 +5,10 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\UsesClass; +use PHPUnit\Framework\TestCase; use Qossmic\TwigDocBundle\Component\ComponentCategory; use Qossmic\TwigDocBundle\Component\ComponentItem; use Qossmic\TwigDocBundle\Component\ComponentItemFactory; -use PHPUnit\Framework\TestCase; use Qossmic\TwigDocBundle\Exception\InvalidComponentConfigurationException; use Qossmic\TwigDocBundle\Service\CategoryService; use Symfony\Component\Validator\ConstraintViolationList; @@ -27,7 +27,7 @@ public function testValidComponent(array $componentData): void ->method('getCategory') ->with($componentData['category']) ->willReturn($componentCategoryMock) - ; + ; $validatorMock = static::createMock(ValidatorInterface::class); $validatorMock->method('validate') ->willReturn(new ConstraintViolationList()); @@ -66,8 +66,8 @@ public static function getValidComponents(): iterable 'category' => 'TestCategory', 'parameters' => [], 'variations' => [ - 'default' => [] - ] + 'default' => [], + ], ], ]; @@ -80,8 +80,8 @@ public static function getValidComponents(): iterable 'sub_category' => 'SubCategory', 'parameters' => [], 'variations' => [ - 'default' => [] - ] + 'default' => [], + ], ], ]; } diff --git a/tests/Unit/DependencyInjection/ConfigurationTest.php b/tests/Unit/DependencyInjection/ConfigurationTest.php index cec01d1..582d0bc 100644 --- a/tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/tests/Unit/DependencyInjection/ConfigurationTest.php @@ -31,8 +31,8 @@ public static function getTestConfiguration(): iterable 'sub_categories' => [ 'SubCategory1', 'SubCategory2', - ] - ] + ], + ], ], ], [ @@ -42,11 +42,11 @@ public static function getTestConfiguration(): iterable 'sub_categories' => [ 'SubCategory1', 'SubCategory2', - ] - ] + ], + ], ], - 'components' => [] - ] + 'components' => [], + ], ]; yield 'Simple Component' => [ @@ -57,8 +57,8 @@ public static function getTestConfiguration(): iterable 'sub_categories' => [ 'SubCategory1', 'SubCategory2', - ] - ] + ], + ], ], 'components' => [ [ @@ -79,11 +79,11 @@ public static function getTestConfiguration(): iterable 'default' => [ 'type' => 'primary', 'msg' => 'Click Me', - 'link' => '#' - ] - ] + 'link' => '#', + ], + ], ], - ] + ], ], [ 'categories' => [ @@ -92,8 +92,8 @@ public static function getTestConfiguration(): iterable 'sub_categories' => [ 'SubCategory1', 'SubCategory2', - ] - ] + ], + ], ], 'components' => [ [ @@ -114,11 +114,11 @@ public static function getTestConfiguration(): iterable 'default' => [ 'type' => 'primary', 'msg' => 'Click Me', - 'link' => '#' - ] - ] + 'link' => '#', + ], + ], ], - ] + ], ], ]; } diff --git a/tests/Unit/Service/CategoryServiceTest.php b/tests/Unit/Service/CategoryServiceTest.php index e14049e..09f3ccb 100644 --- a/tests/Unit/Service/CategoryServiceTest.php +++ b/tests/Unit/Service/CategoryServiceTest.php @@ -20,7 +20,7 @@ public function testValidCategories(array $categoryConfig): void $categoryService = new CategoryService([$categoryConfig]); static::assertInstanceOf(ComponentCategory::class, $categoryService->getCategory($categoryConfig['name'])); - static::assertCount(count($categoryConfig['sub_categories'] ?? []), $categoryService->getSubCategories()); + static::assertCount(\count($categoryConfig['sub_categories'] ?? []), $categoryService->getSubCategories()); foreach ($categoryConfig['sub_categories'] ?? [] as $subCategoryName) { $subCategory = $categoryService->getCategory($categoryConfig['name'], $subCategoryName); @@ -38,7 +38,7 @@ public function testInvalidCategoryConfig() ], [ 'name' => 'Category', - ] + ], ]; static::expectException(InvalidConfigException::class); @@ -72,14 +72,14 @@ public function testGetSubCategoriesForCategory(): void 'sub_categories' => [ 'subCategory1', 'subCategory2', - ] + ], ], [ 'name' => 'Category2', 'sub_categories' => [ 'subCategory1', 'subCategory2', - ] + ], ], ]); @@ -94,7 +94,7 @@ public static function getValidCategories(): iterable yield 'Main Category' => [ [ 'name' => 'MainCategory', - ] + ], ]; yield 'Single sub category' => [ @@ -103,7 +103,7 @@ public static function getValidCategories(): iterable 'sub_categories' => [ 'SubCategory', ], - ] + ], ]; yield 'Multiple sub categories' => [ @@ -113,7 +113,7 @@ public static function getValidCategories(): iterable 'SubCategory1', 'SubCategory2', ], - ] + ], ]; } }