diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1366148 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +/.github export-ignore +/tests export-ignore +/phpunit.xml.dist export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.php-cs-fixer.dist.php export-ignore +/psalm.xml export-ignore + +*.php diff=php \ No newline at end of file diff --git a/.github/workflows/.editorconfig b/.github/workflows/.editorconfig new file mode 100644 index 0000000..473df25 --- /dev/null +++ b/.github/workflows/.editorconfig @@ -0,0 +1,2 @@ +[{*.yaml,*.yml}] +indent_size = 2 \ No newline at end of file diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..e54001a --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,58 @@ +name: Plugin CI +on: + push: + branches: [ 'master' ] + pull_request: + +env: + PHP_CS_FIXER_IGNORE_ENV: 1 + XDEBUG_MODE: coverage + +jobs: + tests: + name: "Tests ${{ matrix.php-version }} deps ${{ matrix.dependency-versions }}" + runs-on: ubuntu-22.04 + + strategy: + fail-fast: false + matrix: + # normal, highest, non-dev installs + php-version: [ '8.2' ] + dependency-versions: [ 'highest' ] + include: + # testing lowest PHP version with the lowest dependencies + # - php-version: '8.2' + # dependency-versions: 'lowest' + + # testing dev versions with the highest PHP + - php-version: '8.2' + dependency-versions: 'highest' + + steps: + - name: "Checkout code" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + + - name: "Composer install" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "${{ matrix.dependency-versions }}" + composer-options: "--prefer-dist --no-progress" + + - name: Run tests + run: composer run test + + - name: Coverage report + run: XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-clover coverage.xml + + - name: Upload coverage reports to Codecov + run: | + # Replace `linux` below with the appropriate OS + curl -Os https://uploader.codecov.io/latest/linux/codecov + chmod +x codecov + ./codecov -t ${CODECOV_TOKEN} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 57872d0..c40cd9d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,9 @@ -/vendor/ +.idea +vendor +composer.lock +.phpunit.result.cache +.php-cs-fixer.cache +test-coverage-report +phpunit.xml +.php-cs-fixer.php +phpstan.neon \ No newline at end of file diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..5147b69 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,31 @@ +in(__DIR__.'/src') + ->in(__DIR__.'/tests') +; + +return (new PhpCsFixer\Config()) + ->setRules(array( + '@Symfony' => true, + '@Symfony:risky' => true, + 'protected_to_private' => false, + 'semicolon_after_instruction' => false, + 'phpdoc_to_comment' => ['ignored_tags' => ['psalm-suppress']], + 'header_comment' => [ + 'header' => << + + For the full copyright and license information, please view the LICENSE + file that was distributed with this source code. +EOF + ] + )) + ->setRiskyAllowed(true) + ->setFinder($finder); \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..e6c0e69 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Komar Stanislau + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..cba81fa --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Micro Framework - The minimum kernel for application initialization. + +Documentation is available [here](https://micro-php.net/docs). If not, we will be grateful if you can become its author :) \ No newline at end of file diff --git a/composer.json b/composer.json index 44d3736..cd94a57 100644 --- a/composer.json +++ b/composer.json @@ -1,24 +1,59 @@ { "name": "micro/kernel-boot-configuration", "description": "Micro Framework: Kernel Boot loader - component to provide plugin configuration", - "type": "library", - "version": "1.3", + "type": "micro-plugin", + "license": "MIT", + "authors": [ + { + "name": "Stanislau Komar", + "email": "stanislau_komar@epam.com" + } + ], "require": { - "micro/kernel": "^1" + "micro/kernel": "^1.6" }, "require-dev": { - "phpunit/phpunit": "^9" + "ergebnis/composer-normalize": "^2.29", + "friendsofphp/php-cs-fixer": "^3.13", + "phpstan/phpstan": "^1.9", + "phpunit/php-code-coverage": "^9.2", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^5.2" }, - "license": "MIT", "autoload": { "psr-4": { "Micro\\Framework\\Kernel\\": "src/" } }, - "authors": [ - { - "name": "Stanislau Komar", - "email": "stanislau_komar@epam.com" + "autoload-dev": { + "psr-4": { + "Micro\\Framework\\Kernel\\Test\\Unit\\": "tests/Unit" } - ] + }, + "config": { + "allow-plugins": { + "ergebnis/composer-normalize": true + }, + "sort-packages": true + }, + "scripts": { + "coverage": "XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-text", + "coverage-html": "XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-html ./test-coverage-report", + "php-cs-fix": "PHP_CS_FIXER_IGNORE_ENV=1 ./vendor/bin/php-cs-fixer fix --verbose --using-cache=no", + "php-cs-try": "PHP_CS_FIXER_IGNORE_ENV=1 ./vendor/bin/php-cs-fixer fix --verbose --dry-run --using-cache=no", + "phpstan": "./vendor/bin/phpstan analyze --no-progress", + "phpunit": "./vendor/bin/phpunit", + "psalm": "./vendor/bin/psalm --no-progress --show-info=true --no-cache", + "statics": [ + "@phpstan", + "@psalm", + "@php-cs-try" + ], + "test": [ + "@statics", + "composer validate --strict", + "composer normalize", + "@coverage" + ] + } } diff --git a/phpcs.xml b/phpcs.xml new file mode 100755 index 0000000..a92f5e2 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,64 @@ + + + src/ + + + + + Micro Framework - сode formatting rules. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..18d77f7 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,4 @@ +parameters: + level: 7 + paths: + - src \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..88daaff --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,41 @@ + + + + + + + + + tests/Unit + + + + + src/ + + src/Exception + src/HttpCorePlugin.php + + + + + + src + + + + + + + + + + + \ No newline at end of file diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..99ad2c8 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Boot/ConfigurationProviderBootLoader.php b/src/Boot/ConfigurationProviderBootLoader.php index 0b139e2..6d7c2ce 100644 --- a/src/Boot/ConfigurationProviderBootLoader.php +++ b/src/Boot/ConfigurationProviderBootLoader.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Boot; use Micro\Framework\Kernel\Configuration\ApplicationConfigurationFactoryInterface; @@ -14,22 +23,25 @@ class ConfigurationProviderBootLoader implements PluginBootLoaderInterface private readonly ApplicationConfigurationInterface $applicationConfiguration; /** - * @param array|ApplicationConfigurationInterface|ApplicationConfigurationFactoryInterface $config + * @param array|ApplicationConfigurationInterface|ApplicationConfigurationFactoryInterface $config */ public function __construct( array|ApplicationConfigurationInterface|ApplicationConfigurationFactoryInterface $config - ) - { + ) { $applicationConfig = $config; - if(is_array($config)) { - $applicationConfig = (new DefaultApplicationConfigurationFactory($config)); + if (\is_array($config)) { + $applicationConfig = new DefaultApplicationConfigurationFactory($config); } - if(($applicationConfig instanceof ApplicationConfigurationFactoryInterface)) { + if ($applicationConfig instanceof ApplicationConfigurationFactoryInterface) { $applicationConfig = $applicationConfig->create(); } - + /** + * @psalm-suppress PossiblyInvalidPropertyAssignmentValue + * + * @phpstan-ignore-next-line + */ $this->applicationConfiguration = $applicationConfig; } @@ -38,14 +50,14 @@ public function __construct( */ public function boot(object $applicationPlugin): void { - if(!($applicationPlugin instanceof ConfigurableInterface)) { + if (!($applicationPlugin instanceof ConfigurableInterface)) { return; - } + } - $applicationPlugin->setConfiguration( - $this->createPluginConfigurationClassResolver() - ->resolve(get_class($applicationPlugin)) - ); + $applicationPlugin->setConfiguration( + $this->createPluginConfigurationClassResolver() + ->resolve(\get_class($applicationPlugin)) + ); } /** @@ -55,4 +67,4 @@ protected function createPluginConfigurationClassResolver(): PluginConfiguration { return new PluginConfigurationClassResolver($this->applicationConfiguration); } -} \ No newline at end of file +} diff --git a/src/Configuration/ApplicationConfigurationFactoryInterface.php b/src/Configuration/ApplicationConfigurationFactoryInterface.php index 05d81f4..473aa09 100755 --- a/src/Configuration/ApplicationConfigurationFactoryInterface.php +++ b/src/Configuration/ApplicationConfigurationFactoryInterface.php @@ -1,11 +1,17 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Configuration; interface ApplicationConfigurationFactoryInterface { - /** - * @return ApplicationConfigurationInterface - */ public function create(): ApplicationConfigurationInterface; } diff --git a/src/Configuration/ApplicationConfigurationInterface.php b/src/Configuration/ApplicationConfigurationInterface.php index 3005c1c..d4b7b96 100755 --- a/src/Configuration/ApplicationConfigurationInterface.php +++ b/src/Configuration/ApplicationConfigurationInterface.php @@ -1,15 +1,17 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Configuration; interface ApplicationConfigurationInterface { - /** - * @param string $key - * @param mixed|null $default - * @param bool $nullable - * - * @return mixed - */ public function get(string $key, mixed $default = null, bool $nullable = true): mixed; } diff --git a/src/Configuration/DefaultApplicationConfiguration.php b/src/Configuration/DefaultApplicationConfiguration.php index 9ff30bd..c46c27a 100755 --- a/src/Configuration/DefaultApplicationConfiguration.php +++ b/src/Configuration/DefaultApplicationConfiguration.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Configuration; use Micro\Framework\Kernel\Configuration\Exception\InvalidConfigurationException; @@ -7,7 +16,11 @@ class DefaultApplicationConfiguration implements ApplicationConfigurationInterface { private const BOOLEAN_TRUE = [ - 'true', 'on', '1', 'yes' + 'true', 'on', '1', 'yes', + ]; + + private const BOOLEAN_FALSE = [ + 'false', 'off', '0', 'no', ]; /** @@ -20,43 +33,49 @@ public function __construct(private readonly array $configuration) /** * {@inheritDoc} */ - public function get(string $key, $default = null, bool $nullable = true): mixed + public function get(string $key, mixed $default = null, bool $nullable = true): mixed { - if(is_bool($default)) { - return $this->getBooleanValue($key, $default); + if (\is_bool($default)) { + try { + return $this->getBooleanValue($key, $default); + } catch (\InvalidArgumentException $exception) { + throw new InvalidConfigurationException(sprintf('Configuration key "%s" can not be converted to boolean', $key), 0, $exception); + } } $value = $this->getValue($key, $default); - if($nullable === false && !$value && !is_numeric($value)) { + if (false === $nullable && !$value && !is_numeric($value)) { throw new InvalidConfigurationException(sprintf('Configuration key "%s" can not be NULL', $key)); } return $value; } - /** - * @param string $key - * @param bool $default - * - * @return bool - */ protected function getBooleanValue(string $key, bool $default): bool { $value = $this->getValue($key, $default); - if($value === null) { + if (\is_bool($value)) { + return $value; + } + + if (null === $value) { return $default; } - return in_array(mb_strtolower($value), self::BOOLEAN_TRUE, true); + $value = mb_strtolower($value); + + if (\in_array($value, self::BOOLEAN_TRUE, true)) { + return true; + } + + if (\in_array($value, self::BOOLEAN_FALSE, true)) { + return false; + } + + throw new \InvalidArgumentException('Value can not be converted to boolean.'); } - /** - * @param string $key - * @param mixed $default - * - * @return mixed - */ protected function getValue(string $key, mixed $default): mixed { return $this->configuration[$key] ?? $default; diff --git a/src/Configuration/DefaultApplicationConfigurationFactory.php b/src/Configuration/DefaultApplicationConfigurationFactory.php index d7547e8..a7670ef 100755 --- a/src/Configuration/DefaultApplicationConfigurationFactory.php +++ b/src/Configuration/DefaultApplicationConfigurationFactory.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Configuration; class DefaultApplicationConfigurationFactory implements ApplicationConfigurationFactoryInterface @@ -11,9 +20,6 @@ public function __construct(private readonly array $configuration) { } - /** - * @return ApplicationConfigurationInterface - */ public function create(): ApplicationConfigurationInterface { return new DefaultApplicationConfiguration($this->configuration); diff --git a/src/Configuration/Exception/InvalidConfigurationException.php b/src/Configuration/Exception/InvalidConfigurationException.php index dde0884..595dcf3 100755 --- a/src/Configuration/Exception/InvalidConfigurationException.php +++ b/src/Configuration/Exception/InvalidConfigurationException.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Configuration\Exception; class InvalidConfigurationException extends \RuntimeException diff --git a/src/Configuration/PluginConfiguration.php b/src/Configuration/PluginConfiguration.php index 289be42..eb51e1a 100755 --- a/src/Configuration/PluginConfiguration.php +++ b/src/Configuration/PluginConfiguration.php @@ -1,30 +1,35 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Configuration; class PluginConfiguration implements PluginConfigurationInterface { - /** - * @param ApplicationConfigurationInterface $configuration - */ public function __construct( protected readonly ApplicationConfigurationInterface $configuration - ) - { + ) { } /** - * @param string|array $list - * @param string $separator + * @param string|string[] $list + * * @return string[] */ protected function explodeStringToArray(string|array $list, string $separator = ','): array { - if(is_array($list)) { + if (\is_array($list)) { return $list; } - if($separator === '') { + if ('' === $separator) { return [$list]; } diff --git a/src/Configuration/PluginConfigurationInterface.php b/src/Configuration/PluginConfigurationInterface.php index 3a004fe..d5764a0 100755 --- a/src/Configuration/PluginConfigurationInterface.php +++ b/src/Configuration/PluginConfigurationInterface.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Configuration; interface PluginConfigurationInterface diff --git a/src/Configuration/PluginRoutingKeyConfiguration.php b/src/Configuration/PluginRoutingKeyConfiguration.php index bd12a1f..bc06c77 100755 --- a/src/Configuration/PluginRoutingKeyConfiguration.php +++ b/src/Configuration/PluginRoutingKeyConfiguration.php @@ -1,35 +1,32 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Configuration; class PluginRoutingKeyConfiguration extends PluginConfiguration { - /** - * @param ApplicationConfigurationInterface $configuration - * @param string $configRoutingKey - */ public function __construct( ApplicationConfigurationInterface $configuration, protected readonly string $configRoutingKey - ) - { + ) { parent::__construct($configuration); } - /** - * @param string $key - * @return string - */ protected function cfg(string $key): string { return sprintf($key, mb_strtoupper($this->configRoutingKey)); } /** - * @param string $key - * @param mixed $default - * @param bool $nullable - * @return mixed + * @param mixed $default */ protected function get(string $key, mixed $default = null, bool $nullable = true): mixed { diff --git a/src/Configuration/Resolver/PluginConfigurationClassResolver.php b/src/Configuration/Resolver/PluginConfigurationClassResolver.php index 4321b52..c3c15c9 100755 --- a/src/Configuration/Resolver/PluginConfigurationClassResolver.php +++ b/src/Configuration/Resolver/PluginConfigurationClassResolver.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Configuration\Resolver; use Micro\Framework\Kernel\Configuration\ApplicationConfigurationInterface; @@ -8,41 +17,26 @@ class PluginConfigurationClassResolver { - /** - * @param ApplicationConfigurationInterface $applicationConfiguration - */ public function __construct( private readonly ApplicationConfigurationInterface $applicationConfiguration - ) - { + ) { } - /** - * @param string $pluginClass - * - * @return PluginConfigurationInterface - */ public function resolve(string $pluginClass): PluginConfigurationInterface { $configClassDefault = PluginConfiguration::class; - $configClasses = []; + $configClasses = []; foreach ($this->getPluginClassResolvers() as $resolver) { $configClass = $resolver->resolve($pluginClass); - if(!class_exists($configClass)) { + if (!class_exists($configClass)) { continue; } $configClasses[] = $configClass; } - if(count($configClasses) > 1) { - throw new \RuntimeException( - sprintf( - 'Too many configuration classes for Application plugin "%s". [%s]', - $pluginClass, - implode(", ", $configClasses) - ) - ); + if (\count($configClasses) > 1) { + throw new \RuntimeException(sprintf('Too many configuration classes for Application plugin "%s". [%s]', $pluginClass, implode(', ', $configClasses))); } /** @var class-string $configClass */ diff --git a/src/Configuration/Resolver/PluginConfigurationClassResolverInterface.php b/src/Configuration/Resolver/PluginConfigurationClassResolverInterface.php index 44e9449..545a86d 100755 --- a/src/Configuration/Resolver/PluginConfigurationClassResolverInterface.php +++ b/src/Configuration/Resolver/PluginConfigurationClassResolverInterface.php @@ -1,13 +1,17 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Configuration\Resolver; interface PluginConfigurationClassResolverInterface { - /** - * @param string $pluginClass - * - * @return string - */ public function resolve(string $pluginClass): string; } diff --git a/src/Configuration/Resolver/PluginNameResolver.php b/src/Configuration/Resolver/PluginNameResolver.php index 77ed6e2..bbbc630 100755 --- a/src/Configuration/Resolver/PluginNameResolver.php +++ b/src/Configuration/Resolver/PluginNameResolver.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Configuration\Resolver; class PluginNameResolver implements PluginConfigurationClassResolverInterface @@ -9,6 +18,6 @@ class PluginNameResolver implements PluginConfigurationClassResolverInterface */ public function resolve(string $pluginClass): string { - return $pluginClass . 'Configuration'; + return $pluginClass.'Configuration'; } } diff --git a/src/Configuration/Resolver/PluginNameShortResolver.php b/src/Configuration/Resolver/PluginNameShortResolver.php index 3874db4..8a94497 100755 --- a/src/Configuration/Resolver/PluginNameShortResolver.php +++ b/src/Configuration/Resolver/PluginNameShortResolver.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Configuration\Resolver; class PluginNameShortResolver implements PluginConfigurationClassResolverInterface @@ -9,6 +18,6 @@ class PluginNameShortResolver implements PluginConfigurationClassResolverInterfa */ public function resolve(string $pluginClass): string { - return $pluginClass . 'Config'; + return $pluginClass.'Config'; } } diff --git a/src/Plugin/ConfigurableInterface.php b/src/Plugin/ConfigurableInterface.php index 3e42046..602b0c9 100644 --- a/src/Plugin/ConfigurableInterface.php +++ b/src/Plugin/ConfigurableInterface.php @@ -1,20 +1,21 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Plugin; use Micro\Framework\Kernel\Configuration\PluginConfigurationInterface; interface ConfigurableInterface { - /** - * @return PluginConfigurationInterface - */ public function configuration(): PluginConfigurationInterface; - /** - * @param PluginConfigurationInterface $pluginConfiguration - * - * @return void - */ public function setConfiguration(PluginConfigurationInterface $pluginConfiguration): void; -} \ No newline at end of file +} diff --git a/src/Plugin/PluginConfigurationTrait.php b/src/Plugin/PluginConfigurationTrait.php index bef2492..9d272bb 100644 --- a/src/Plugin/PluginConfigurationTrait.php +++ b/src/Plugin/PluginConfigurationTrait.php @@ -1,14 +1,20 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Micro\Framework\Kernel\Plugin; use Micro\Framework\Kernel\Configuration\PluginConfigurationInterface; trait PluginConfigurationTrait { - /** - * @var PluginConfigurationInterface - */ private PluginConfigurationInterface $configuration; /** @@ -26,4 +32,4 @@ public function configuration(): PluginConfigurationInterface { return $this->configuration; } -} \ No newline at end of file +} diff --git a/tests/Unit/Boot/ConfigurationProviderBootLoaderTest.php b/tests/Unit/Boot/ConfigurationProviderBootLoaderTest.php new file mode 100644 index 0000000..01c8c29 --- /dev/null +++ b/tests/Unit/Boot/ConfigurationProviderBootLoaderTest.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Micro\Framework\Kernel\Test\Unit\Boot; + +use Micro\Framework\Kernel\Boot\ConfigurationProviderBootLoader; +use Micro\Framework\Kernel\Configuration\DefaultApplicationConfiguration; +use Micro\Framework\Kernel\Configuration\DefaultApplicationConfigurationFactory; +use Micro\Framework\Kernel\Test\Unit\ConfigurableTestPlugin; +use PHPUnit\Framework\TestCase; + +class ConfigurationProviderBootLoaderTest extends TestCase +{ + /** + * @dataProvider dataProvider + */ + public function testBoot(mixed $configuration) + { + $plugin = new ConfigurableTestPlugin(); + $bootLoader = new ConfigurationProviderBootLoader($configuration); + $bootLoader->boot($plugin); + + $this->assertEquals('test', $plugin->getEnv()); + $this->assertEquals(['a', 'b', 'c', 'd'], $plugin->getList()); + $this->assertEquals(['a', 'b', 'c', 'd'], $plugin->getAlreadyList()); + $this->assertEquals(['a,b,c,d'], $plugin->getListWithoutSeparator()); + $this->assertEquals('OK', $plugin->getConfigRoutingKeyValue()); + } + + public function dataProvider(): array + { + $cfgArr = [ + 'APP_ENV' => 'test', + 'ENV_LIST' => 'a,b,c,d', + 'CONFIG_TEST_VALUE' => 'OK', + ]; + + return [ + [$cfgArr], + [new DefaultApplicationConfiguration($cfgArr)], + [new DefaultApplicationConfigurationFactory($cfgArr)], + ]; + } +} diff --git a/tests/Unit/ConfigurableTestPlugin.php b/tests/Unit/ConfigurableTestPlugin.php new file mode 100644 index 0000000..6ab3d76 --- /dev/null +++ b/tests/Unit/ConfigurableTestPlugin.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Micro\Framework\Kernel\Test\Unit; + +use Micro\Framework\Kernel\Plugin\ConfigurableInterface; +use Micro\Framework\Kernel\Plugin\PluginConfigurationTrait; + +/** + * @author Stanislau Komar + * + * @method ConfigurableTestPluginConfiguration configuration() + */ +class ConfigurableTestPlugin implements ConfigurableInterface +{ + use PluginConfigurationTrait; + + public function getEnv(): string + { + return $this->configuration()->getEnv(); + } + + /** + * @return string[] + */ + public function getList(): array + { + return $this->configuration()->getList(); + } + + public function getAlreadyList(): array + { + return $this->configuration()->getAlreadyList(); + } + + public function getListWithoutSeparator(): array + { + return $this->configuration()->getListWithoutSeparator(); + } + + public function getConfigRoutingKeyValue(): string + { + return $this->configuration()->getRoutingKeyConfig()->testTestValueString(); + } +} diff --git a/tests/Unit/ConfigurableTestPluginConfiguration.php b/tests/Unit/ConfigurableTestPluginConfiguration.php new file mode 100644 index 0000000..aa3829f --- /dev/null +++ b/tests/Unit/ConfigurableTestPluginConfiguration.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Micro\Framework\Kernel\Test\Unit; + +use Micro\Framework\Kernel\Configuration\PluginConfiguration; + +/** + * @author Stanislau Komar + */ +class ConfigurableTestPluginConfiguration extends PluginConfiguration +{ + public function getEnv(): string + { + return $this->configuration->get('APP_ENV', null, false); + } + + public function getList(): array + { + $list = $this->configuration->get('ENV_LIST', null, false); + + return $this->explodeStringToArray($list); + } + + public function getAlreadyList(): array + { + return $this->explodeStringToArray($this->getList()); + } + + public function getListWithoutSeparator(): array + { + return $this->explodeStringToArray($this->configuration->get('ENV_LIST', null, false), ''); + } + + public function getRoutingKeyConfig(): ConfigurableTestPluginRoutingConfiguration + { + return new ConfigurableTestPluginRoutingConfiguration($this->configuration, 'TEST'); + } +} diff --git a/tests/Unit/ConfigurableTestPluginRoutingConfiguration.php b/tests/Unit/ConfigurableTestPluginRoutingConfiguration.php new file mode 100644 index 0000000..94ece99 --- /dev/null +++ b/tests/Unit/ConfigurableTestPluginRoutingConfiguration.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Micro\Framework\Kernel\Test\Unit; + +use Micro\Framework\Kernel\Configuration\PluginRoutingKeyConfiguration; + +/** + * @author Stanislau Komar + */ +class ConfigurableTestPluginRoutingConfiguration extends PluginRoutingKeyConfiguration +{ + public function testTestValueString(): string + { + return $this->get('CONFIG_%s_VALUE'); + } +} diff --git a/tests/Unit/Configuration/DefaultApplicationConfigurationTest.php b/tests/Unit/Configuration/DefaultApplicationConfigurationTest.php new file mode 100644 index 0000000..fc33e8a --- /dev/null +++ b/tests/Unit/Configuration/DefaultApplicationConfigurationTest.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Micro\Framework\Kernel\Test\Unit\Configuration; + +use Micro\Framework\Kernel\Configuration\ApplicationConfigurationInterface; +use Micro\Framework\Kernel\Configuration\DefaultApplicationConfiguration; +use Micro\Framework\Kernel\Configuration\Exception\InvalidConfigurationException; +use PHPUnit\Framework\TestCase; + +class DefaultApplicationConfigurationTest extends TestCase +{ + private ApplicationConfigurationInterface $configuration; + + public const BOOLEAN_VALUES_TRUE = [ + 'BOOLEAN_TRUE_STRING' => 'true', + 'BOOLEAN_TRUE_STRING_ON' => 'on', + 'BOOLEAN_TRUE_INT' => 1, + 'BOOLEAN_TRUE_REAL' => true, + ]; + + public const BOOLEAN_VALUES_FALSE = [ + 'BOOLEAN_FALSE_STRING' => 'false', + 'BOOLEAN_FALSE_STRING_OFF' => 'off', + 'BOOLEAN_FALSE_INT' => 0, + 'BOOLEAN_FALSE_REAL' => false, + ]; + + public const BOOLEAN_VALUES_DEFAULT_TEST = [ + 'BOOLEAN_NULL' => null, + ]; + + public const BOOLEAN_VALUES_INVALID = [ + 'BOOLEAN_INVALID' => 'it is invalid value.', + 'VALUE_SHOULD_BE_NON_EMPTY' => null, + ]; + + protected function setUp(): void + { + $config = array_merge( + self::BOOLEAN_VALUES_TRUE, + self::BOOLEAN_VALUES_FALSE, + self::BOOLEAN_VALUES_INVALID, + self::BOOLEAN_VALUES_DEFAULT_TEST, + ); + + $this->configuration = new DefaultApplicationConfiguration($config); + } + + public function testGetTrue() + { + $trueKeys = array_keys(self::BOOLEAN_VALUES_TRUE); + foreach ($trueKeys as $key) { + $this->assertTrue($this->configuration->get($key, false, false)); + } + } + + public function testGetFalse() + { + $trueKeys = array_keys(self::BOOLEAN_VALUES_FALSE); + foreach ($trueKeys as $key) { + $this->assertFalse($this->configuration->get($key, true, false)); + } + } + + public function testGetDefaultTrue() + { + $keys = array_keys(self::BOOLEAN_VALUES_DEFAULT_TEST); + + foreach ($keys as $key) { + $this->assertTrue($this->configuration->get($key, true, false)); + $this->assertFalse($this->configuration->get($key, false, false)); + } + } + + /** + * @dataProvider dataProviderExceptionalKeys + */ + public function testExceptional(string $key, mixed $default) + { + $this->expectException(InvalidConfigurationException::class); + + var_dump($this->configuration->get($key, $default, false)); + } + + public function dataProviderExceptionalKeys() + { + return [ + ['BOOLEAN_INVALID', false], + ['NO_CONFIGURED', null], + ['VALUE_SHOULD_BE_NON_EMPTY', null], + ]; + } +}