diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..efb6801 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,19 @@ +name: CI + +on: + - pull_request + - push + +jobs: + php-cs-fixer: + name: CS Fixer + runs-on: ubuntu-latest + container: + image: ghcr.io/elbformat/php-cs-fixer:edge-php8.2 + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: check src + run: php-cs-fixer fix --dry-run src + - name: check tests + run: php-cs-fixer fix --dry-run tests \ No newline at end of file diff --git a/.gitignore b/.gitignore index a040318..210f39a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ /.idea -vendor/ +/build +/vendor +.phpunit.result.cache composer.lock docker-compose.override.yml diff --git a/composer.json b/composer.json index e75fb77..c096f1b 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,8 @@ ], "autoload": { "psr-4": { - "Elbformat\\IconBundle\\": "src/" + "Elbformat\\IconBundle\\": "src/", + "Elbformat\\IconBundle\\Test\\": "tests/" } }, "require": { @@ -27,7 +28,7 @@ "symfony/finder": "^5.4|^6.4" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^9.6" }, "config": { "sort-packages": true, diff --git a/doc/development.md b/doc/development.md index 3f7b1a5..acf842f 100644 --- a/doc/development.md +++ b/doc/development.md @@ -16,6 +16,12 @@ Run tests vendor/bin/phpunit ``` +Fix styles +```bash +docker run -v $(pwd):/code ghcr.io/elbformat/php-cs-fixer:edge-php8.2 fix src +docker run -v $(pwd):/code ghcr.io/elbformat/php-cs-fixer:edge-php8.2 fix tests +``` + ## In-Place development If you want to test out how it integrates into ibexa, it's the easiest way to integrate the bundle into your project directly. By adding it as "vcs" your are able to push the changes you made right from your vendor folder. diff --git a/docker/Dockerfile b/docker/Dockerfile index 2d7f176..74ca6cb 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -2,20 +2,6 @@ FROM php:8.2-fpm-alpine COPY --from=composer:2.5 /usr/bin/composer /usr/local/bin/composer -# ext-intl -RUN apk add --no-cache icu icu-data-full && \ - apk add --no-cache --virtual .build-deps icu-dev && \ - docker-php-ext-install intl && \ - apk del .build-deps && \ - rm -rf /tmp/* - -#ext-xsl -RUN apk add --no-cache libxslt && \ - apk add --no-cache --virtual .build-deps libxslt-dev && \ - docker-php-ext-install xsl && \ - apk del .build-deps && \ - rm -rf /tmp/* - # xdebug RUN apk add --no-cache --virtual .build-deps autoconf g++ make linux-headers && \ pecl install xdebug-3.2.1 && \ @@ -23,13 +9,12 @@ RUN apk add --no-cache --virtual .build-deps autoconf g++ make linux-headers && apk del .build-deps && \ rm -rf /tmp/* -# ext-gd -RUN apk add --no-cache libpng libjpeg-turbo freetype && \ - apk add --no-cache --virtual .build-deps libpng-dev libjpeg-turbo-dev freetype-dev && \ - docker-php-ext-configure gd && \ - docker-php-ext-install gd && \ +# pcov +RUN apk add --no-cache --virtual .build-deps autoconf g++ make && \ + pecl install pcov-1.0.11 && \ apk del .build-deps && \ - rm -rf /tmp/* + rm -rf /tmp/* &&\ + docker-php-ext-enable pcov RUN rmdir /var/www/html WORKDIR /var/www \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..7b44633 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,24 @@ + + + + + src/ + + + + + + + + + tests/ + + + + + + + + + + diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 54a14eb..2a7d1b3 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -1,4 +1,5 @@ prependExtensionConfig('framework', ['translator' => ['paths' => [__DIR__.'/../../translations']]]); } -} \ No newline at end of file +} diff --git a/src/ElbformatIconBundle.php b/src/ElbformatIconBundle.php index 4021ce0..440df4c 100644 --- a/src/ElbformatIconBundle.php +++ b/src/ElbformatIconBundle.php @@ -1,4 +1,5 @@ false, ]); } -} \ No newline at end of file +} diff --git a/src/FieldType/Icon/Value.php b/src/FieldType/Icon/Value.php index d140df8..ee69763 100644 --- a/src/FieldType/Icon/Value.php +++ b/src/FieldType/Icon/Value.php @@ -1,4 +1,5 @@ icon = $icon; } + public function __construct(?string $icon = null) + { + $this->icon = $icon; + } public function __toString(): string { - return $this->icon; + return $this->icon ?? ''; } public function getIcon(): ?string @@ -25,4 +29,4 @@ public function setIcon(?string $icon): void { $this->icon = $icon; } -} \ No newline at end of file +} diff --git a/src/Form/Type/IconSettingsType.php b/src/Form/Type/IconSettingsType.php index 0d6b707..343d950 100644 --- a/src/Form/Type/IconSettingsType.php +++ b/src/Form/Type/IconSettingsType.php @@ -1,4 +1,5 @@ add('iconset', ChoiceType::class,[ + $builder->add('iconset', ChoiceType::class, [ 'choices' => $this->iconSetManager->getSetList() ]); } -} \ No newline at end of file +} diff --git a/src/Form/Type/IconType.php b/src/Form/Type/IconType.php index 007dcee..86ea953 100644 --- a/src/Form/Type/IconType.php +++ b/src/Form/Type/IconType.php @@ -1,4 +1,5 @@ iconSetManager->getSet($iconSet)->getList(); $iconTemplates = []; foreach($iconList as $icon) { - $iconTemplates[$icon] = $this->twig->render('@ElbformatIconFieldtype/icon.html.twig',['icon' => $icon,'iconset' => $iconSet]); + $iconTemplates[$icon] = $this->twig->render('@ElbformatIconFieldtype/icon.html.twig', ['icon' => $icon,'iconset' => $iconSet]); } $builder->add('icon', ChoiceType::class, [ 'choices' => $iconList, @@ -47,4 +47,4 @@ public function configureOptions(OptionsResolver $resolver): void ]); $resolver->addAllowedTypes('icon_set', 'string'); } -} \ No newline at end of file +} diff --git a/src/IconSet/IconSet.php b/src/IconSet/IconSet.php index 7f8b804..a5984c0 100644 --- a/src/IconSet/IconSet.php +++ b/src/IconSet/IconSet.php @@ -1,4 +1,5 @@ */ protected array $items; - /** @param string[] */ + /** @param $items string[] */ public function __construct(array $items) { // Convert to string => string array $this->items = array_flip($items); - array_walk($this->items, fn(&$val, $key) => $val = $key); + array_walk($this->items, fn (&$val, $key) => $val = $key); } /** @return string[] */ @@ -21,4 +22,4 @@ public function getList(): array { return $this->items; } -} \ No newline at end of file +} diff --git a/src/IconSet/IconSetManager.php b/src/IconSet/IconSetManager.php index b408816..e337586 100644 --- a/src/IconSet/IconSetManager.php +++ b/src/IconSet/IconSetManager.php @@ -1,4 +1,5 @@ */ - protected array $sets; + protected array $sets = []; /** array $setConfig) { $items = []; - if (null !== ($setConfig['items']??null)) { + if (null !== ($setConfig['items'] ?? null)) { $items = $setConfig['items']; } - if (null !== ($setConfig['folder']??null)) { - $finder = (new Finder())->files()->in($setConfig['folder'])->depth(0); - if (null !== ($setConfig['pattern']??null)) { + if (null !== ($setConfig['folder'] ?? null)) { + $finder = (new Finder())->files()->in($setConfig['folder'])->depth(0)->sortByName(); + if (null !== ($setConfig['pattern'] ?? null)) { $finder = $finder->name($setConfig['pattern']); } foreach ($finder as $file) { @@ -40,11 +41,11 @@ public function getSet(string $name): IconSet } /** @return array */ - public function getSetList():array + public function getSetList(): array { // Convert to string => string array $sets = array_flip(array_keys($this->sets)); - array_walk($sets, fn(&$val, $key) => $val = $key); + array_walk($sets, fn (&$val, $key) => $val = $key); return $sets; } -} \ No newline at end of file +} diff --git a/tests/FieldType/Icon/ValueTest.php b/tests/FieldType/Icon/ValueTest.php new file mode 100644 index 0000000..74b081a --- /dev/null +++ b/tests/FieldType/Icon/ValueTest.php @@ -0,0 +1,24 @@ +assertSame('icon1', $value->getIcon()); + $this->assertSame('icon1', (string) $value); + $value->setIcon(null); + $this->assertNull($value->getIcon()); + $this->assertSame('', (string) $value); + $value->setIcon('value2'); + $this->assertSame('value2', $value->getIcon()); + $this->assertSame('value2', (string) $value); + } +} diff --git a/tests/IconSet/IconSetManagerTest.php b/tests/IconSet/IconSetManagerTest.php new file mode 100644 index 0000000..b6b0ef5 --- /dev/null +++ b/tests/IconSet/IconSetManagerTest.php @@ -0,0 +1,64 @@ +assertSame($setList, $ism->getSetList()); + if (null !== $setName) { + $this->assertSame($iconList, $ism->getSet($setName)->getList()); + } + } + + public function validConfigsProvider(): \Generator + { + // Simple list + yield [ + ['set1' => ['items' => ['entry1', 'entry2']]], + ['set1' => 'set1'], + 'set1', + ['entry1' => 'entry1', 'entry2' => 'entry2'], + ]; + // Multiple lists + yield [ + ['set1' => ['items' => ['entry1', 'entry2']],'set2' => []], + ['set1' => 'set1', 'set2' => 'set2'], + 'set2', + [], + ]; + // List from files + yield [ + ['set1' => ['folder' => __DIR__.'/../_fixtures/iconlist']], + ['set1' => 'set1'], + 'set1', + ['icon1.svg' => 'icon1.svg', 'icon2.png' => 'icon2.png'], + ]; + // List from files with filter + yield [ + ['set1' => ['folder' => __DIR__.'/../_fixtures/iconlist', 'pattern' => '*.svg']], + ['set1' => 'set1'], + 'set1', + ['icon1.svg' => 'icon1.svg'], + ]; + // No lists + yield [[], []]; + } + + public function testInvalidSet(): void + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('IconSet not found'); + $ism = new IconSetManager([]); + $ism->getSet('nope'); + } +} diff --git a/tests/_fixtures/iconlist/icon1.svg b/tests/_fixtures/iconlist/icon1.svg new file mode 100644 index 0000000..e69de29 diff --git a/tests/_fixtures/iconlist/icon2.png b/tests/_fixtures/iconlist/icon2.png new file mode 100644 index 0000000..e69de29