diff --git a/composer.json b/composer.json index b21275d..31f2e18 100644 --- a/composer.json +++ b/composer.json @@ -18,10 +18,11 @@ "symfony/process": "^5.4|^6.3" }, "require-dev": { + "matthiasnoback/symfony-config-test": "^5.0", "symfony/filesystem": "^6.3", "symfony/framework-bundle": "^6.3", "symfony/phpunit-bridge": "^6.3", - "phpstan/phpstan": "1.11.x-dev" + "phpstan/phpstan-symfony": "^1.4" }, "minimum-stability": "dev", "autoload": { diff --git a/phpstan.neon.dist b/phpstan.neon.dist index ded42a0..5c3268e 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,10 +1,7 @@ +includes: + - vendor/phpstan/phpstan-symfony/extension.neon + parameters: - level: 4 + level: 5 paths: - src - - ignoreErrors: - - - message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeParentInterface\\:\\:defaultValue\\(\\)\\.$#" - count: 1 - path: src/DependencyInjection/SymfonycastsSassExtension.php diff --git a/src/DependencyInjection/SymfonycastsSassExtension.php b/src/DependencyInjection/SymfonycastsSassExtension.php index 3025038..c07d9a4 100644 --- a/src/DependencyInjection/SymfonycastsSassExtension.php +++ b/src/DependencyInjection/SymfonycastsSassExtension.php @@ -59,6 +59,22 @@ public function getConfigTreeBuilder(): TreeBuilder ->cannotBeEmpty() ->scalarPrototype() ->end() + ->validate() + ->ifTrue(static function (array $paths): bool { + if (1 === \count($paths)) { + return false; + } + + $filenames = []; + foreach ($paths as $path) { + $filename = basename($path, '.scss'); + $filenames[$filename] = $filename; + } + + return \count($filenames) !== \count($paths); + }) + ->thenInvalid('The "root_sass" paths need to end with unique filenames.') + ->end() ->defaultValue(['%kernel.project_dir%/assets/styles/app.scss']) ->end() ->scalarNode('binary') diff --git a/tests/ConfigurationTest.php b/tests/ConfigurationTest.php new file mode 100644 index 0000000..f1b724e --- /dev/null +++ b/tests/ConfigurationTest.php @@ -0,0 +1,62 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfonycasts\SassBundle\Tests; + +use Matthias\SymfonyConfigTest\PhpUnit\ConfigurationTestCaseTrait; +use PHPUnit\Framework\TestCase; +use Symfonycasts\SassBundle\DependencyInjection\SymfonycastsSassExtension; + +final class ConfigurationTest extends TestCase +{ + use ConfigurationTestCaseTrait; + + protected function getConfiguration(): SymfonycastsSassExtension + { + return new SymfonycastsSassExtension(); + } + + public function testSingleSassRootPath(): void + { + $this->assertConfigurationIsValid([ + 'symfonycasts_sass' => [ + 'root_sass' => [ + '%kernel.project_dir%/assets/scss/app.scss', + ], + ], + ]); + } + + public function testMultipleSassRootPaths(): void + { + $this->assertConfigurationIsValid([ + 'symfonycasts_sass' => [ + 'root_sass' => [ + '%kernel.project_dir%/assets/scss/app.scss', + '%kernel.project_dir%/assets/admin/scss/admin.scss', + ], + ], + ]); + } + + public function testMultipleSassRootPathsWithSameFilename(): void + { + $this->assertConfigurationIsInvalid([ + 'symfonycasts_sass' => [ + 'root_sass' => [ + '%kernel.project_dir%/assets/scss/app.scss', + '%kernel.project_dir%/assets/admin/scss/app.scss', + ], + ], + ], + 'Invalid configuration for path "symfonycasts_sass.root_sass": The "root_sass" paths need to end with unique filenames.'); + } +}