diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 04249bb..02e455f 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -8,7 +8,7 @@ jobs: strategy: fail-fast: true matrix: - php: [ 7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2 ] + php: [ 8.2 ] dependency-version: [ prefer-lowest, prefer-stable ] name: P${{ matrix.php }} - ${{ matrix.dependency-version }} @@ -33,5 +33,8 @@ jobs: - name: Install dependencies run: composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-suggest + - name: Run PHPStan + run: php vendor/bin/phpstan analyse --no-progress --no-interaction --no-ansi --memory-limit=-1 + - name: Execute tests run: php vendor/bin/phpunit diff --git a/Makefile b/Makefile index 3cdc54a..f580e23 100644 --- a/Makefile +++ b/Makefile @@ -1,24 +1,25 @@ -help: - @echo "Please use \`make ' where is one of" - @echo " install to setup the dev environment." - @echo " test to perform tests." - @echo " coverage to perform tests with code coverage." - @echo " phpstan to run phpstan" - @echo " infection to run infection" +.DEFAULT_GOAL := help -install: +.PHONY: help +help: ## Show help message + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[$$()% 0-9a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +.PHONY: install +install: ## to setup the dev environment. composer install -test: +.PHONY: test +test: ## to perform unit tests. php vendor/bin/phpunit -coverage: +.PHONY: coverage +coverage: ## to perform unit tests with code coverage. php -d xdebug.mode=coverage vendor/bin/phpunit --coverage-text -phpstan: +.PHONY: phpstan +phpstan: ## to run PHPStan php vendor/bin/phpstan analyse -INFECTION_THREADS = $(shell sysctl -n hw.ncpu) - -infection: - php vendor/bin/infection --threads=$(INFECTION_THREADS) +.PHONY: infection +infection: ## to run Infection + php vendor/bin/infection --threads=max diff --git a/composer.json b/composer.json index b4bd29b..f8933a7 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ } ], "require": { - "php": ">=7.1.0" + "php": "8.2.*" }, "autoload": { "psr-4": { @@ -31,7 +31,7 @@ } }, "require-dev": { - "phpunit/phpunit": "^7.5 || ^8.5.23 || ^9.0 || ^10.0", + "phpunit/phpunit": "^10.0", "phpstan/phpstan": "1.10.27" } } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 4a91d60..3e57e58 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,3 +3,4 @@ parameters: checkMissingIterableValueType: false paths: - src + - tests diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c297eed..1aba5e3 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,13 +1,14 @@ - - - - src/ - - + + tests + + + src/ + + diff --git a/src/Exception/InvalidFormatException.php b/src/Exception/InvalidFormatException.php index c93cb04..8e0813e 100644 --- a/src/Exception/InvalidFormatException.php +++ b/src/Exception/InvalidFormatException.php @@ -11,7 +11,7 @@ */ final class InvalidFormatException extends InvalidArgumentException implements MagicConstantException { - public function __construct(MagicConstant $magicConstant, string $format) + public function __construct(MagicConstant $magicConstant, string|int $format) { parent::__construct(sprintf('The format `%s` does not exist in `%s`', $format, get_class($magicConstant))); } diff --git a/src/Exception/InvalidValueException.php b/src/Exception/InvalidValueException.php index f4b4af9..e7373f6 100644 --- a/src/Exception/InvalidValueException.php +++ b/src/Exception/InvalidValueException.php @@ -5,9 +5,6 @@ use InvalidArgumentException; -/** - * @codeCoverageIgnore - */ final class InvalidValueException extends InvalidArgumentException implements MagicConstantException { /** diff --git a/src/MagicConstant.php b/src/MagicConstant.php index 9f4a869..f00192c 100644 --- a/src/MagicConstant.php +++ b/src/MagicConstant.php @@ -13,16 +13,12 @@ abstract class MagicConstant { - /** @var mixed */ - protected $value; + protected mixed $value; - /** @var array */ - protected static $cache = []; + /** @var array, array> */ + protected static array $cache = []; - /** - * @param mixed $value - */ - final public function __construct($value) + final public function __construct(mixed $value) { if ($value instanceof self) { $value = $value->getValue(); @@ -31,17 +27,13 @@ final public function __construct($value) $this->setValue($value); } - /** - * @param string|null $format - * @return mixed - */ - public function getValue(string $format = null) + public function getValue(string|int $format = null): mixed { if (empty($format)) { return $this->value; } - $values = static::toArray(); + $values = self::toArray(); if (!isset($values[$this->getKey()][$format])) { throw new InvalidFormatException($this, $format); @@ -55,7 +47,7 @@ public function getValue(string $format = null) */ public function getAllFormats(): array { - $values = static::toArray(); + $values = self::toArray(); $instances = array_map( function ($value) { return new static($value); @@ -71,24 +63,22 @@ function ($value) { */ public function getAllValues(): array { - $values = static::toArray(); + $values = self::toArray(); return array_values($values[$this->getKey()]); } public function getKey(): string { - return (string)static::search($this->value); + return (string)self::search($this->value); } /** * Returns the current instance format. - * - * @return int|string|null */ - public function getFormat() + public function getFormat(): int|string|null { - $values = static::toArray(); + $values = self::toArray(); foreach ($values[$this->getKey()] as $format => $value) { if ($value === $this->value) { @@ -99,20 +89,14 @@ public function getFormat() return null; } - /** - * @return string - */ - public function __toString() + public function __toString(): string { return (string)$this->value; } - /** - * @return MagicConstant - */ public function normalize(): MagicConstant { - $array = static::toArray(); + $array = self::toArray(); $key = $this->getKey(); $values = array_values($array[$key]); @@ -120,10 +104,7 @@ public function normalize(): MagicConstant return new static($values[0]); } - /** - * @param mixed $value - */ - protected function setValue($value): void + protected function setValue(mixed $value): void { if (!static::isValidValue($value)) { throw new InvalidValueException(static::class, $value); @@ -143,14 +124,13 @@ final public function equals(?MagicConstant $other): bool } $ownKey = $this->getKey(); - $otherKey = static::search($other->getValue()); + $otherKey = self::search($other->getValue()); return $ownKey === $otherKey; } /** * @param mixed[] $values - * @return bool */ public function in(array $values): bool { @@ -167,11 +147,7 @@ public function in(array $values): bool return false; } - /** - * @param string $format - * @return static - */ - public function toFormat(string $format): self + public function toFormat(string $format): static { return new static($this->getValue($format)); } @@ -181,18 +157,17 @@ public function toFormat(string $format): self */ public static function keys(): array { - return array_keys(static::toArray()); + return array_keys(self::toArray()); } /** - * @param string|null $pattern * @return static[] */ public static function values(string $pattern = null): array { $out = []; - foreach (static::toArray() as $key => $values) { + foreach (self::toArray() as $key => $values) { if (null === $pattern || preg_match($pattern, $key)) { $out[$key] = new static(reset($values)); } @@ -229,37 +204,25 @@ private static function toArray(): array return static::$cache[static::class]; } - /** - * @param mixed $value - * @return bool - */ - public static function isValidValue($value): bool + public static function isValidValue(mixed $value): bool { - return false !== static::search($value); + return false !== self::search($value); } - /** - * @param mixed $key - * @return bool - */ - public static function isValidKey($key): bool + public static function isValidKey(mixed $key): bool { - $array = static::toArray(); + $array = self::toArray(); return isset($array[$key]); } - /** - * @param mixed $value - * @return false|string - */ - private static function search($value) + private static function search(mixed $value): string|false { /** * @var string $constant * @var array $values */ - foreach (static::toArray() as $constant => $values) { + foreach (self::toArray() as $constant => $values) { if (in_array($value, $values, true)) { return $constant; } @@ -268,11 +231,7 @@ private static function search($value) return false; } - /** - * @param mixed $value - * @return static|null - */ - public static function tryFrom($value): ?self + public static function tryFrom(mixed $value): ?self { try { return new static($value); @@ -282,14 +241,12 @@ public static function tryFrom($value): ?self } /** - * @param string $name * @param array $arguments - * @return static * @throws InvalidKeyException */ - public static function __callStatic(string $name, array $arguments = []) + public static function __callStatic(string $name, array $arguments = []): static { - $array = static::toArray(); + $array = self::toArray(); if (!isset($array[$name])) { throw new InvalidKeyException(static::class, $name); diff --git a/tests/Fixture/AnyValueMagicConstant.php b/tests/Fixture/AnyValueMagicConstant.php index 2709087..b7ca509 100644 --- a/tests/Fixture/AnyValueMagicConstant.php +++ b/tests/Fixture/AnyValueMagicConstant.php @@ -8,7 +8,7 @@ final class AnyValueMagicConstant extends MagicConstant { - protected function setValue($value): void + protected function setValue(mixed $value): void { $this->value = $value; } diff --git a/tests/Fixture/CustomSetValueMagicConstant.php b/tests/Fixture/CustomSetValueMagicConstant.php index 32a427d..24f33fb 100644 --- a/tests/Fixture/CustomSetValueMagicConstant.php +++ b/tests/Fixture/CustomSetValueMagicConstant.php @@ -9,7 +9,7 @@ final class CustomSetValueMagicConstant extends MagicConstant { protected const A = 'foo'; - protected function setValue($value): void + protected function setValue(mixed $value): void { parent::setValue(strtolower($value)); } diff --git a/tests/MagicConstantTest.php b/tests/MagicConstantTest.php index 85231ed..b364b63 100644 --- a/tests/MagicConstantTest.php +++ b/tests/MagicConstantTest.php @@ -10,11 +10,13 @@ use CuyZ\MagicConstant\Tests\Fixture\AnyValueMagicConstant; use CuyZ\MagicConstant\Tests\Fixture\FakeMagicConstant; use CuyZ\MagicConstant\Tests\Fixture\OtherMagicConstant; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use stdClass; class MagicConstantTest extends TestCase { - /** @test */ + #[Test] public function the_constructor_throws_for_an_invalid_value(): void { /* *** Assertion *** */ @@ -27,7 +29,7 @@ public function the_constructor_throws_for_an_invalid_value(): void new FakeMagicConstant($wrongValue); } - /** @test */ + #[Test] public function the_constructor_throws_for_other_magic_constant_instance(): void { /* *** Assertion *** */ @@ -40,7 +42,7 @@ public function the_constructor_throws_for_other_magic_constant_instance(): void new FakeMagicConstant($wrongValue); } - /** @test */ + #[Test] public function throws_for_wrong_key(): void { /* *** Assertion *** */ @@ -48,10 +50,10 @@ public function throws_for_wrong_key(): void /* *** Process *** */ /** @noinspection PhpUndefinedMethodInspection */ - FakeMagicConstant::WRONG_KEY(); + FakeMagicConstant::WRONG_KEY(); // @phpstan-ignore-line } - /** @test */ + #[Test] public function values_are_case_sensitive(): void { /* *** Initialisation *** */ @@ -64,7 +66,7 @@ public function values_are_case_sensitive(): void new FakeMagicConstant($wrongValue); } - /** @test */ + #[Test] public function getValue_throws_for_an_invalid_format(): void { /* *** Assertion *** */ @@ -77,7 +79,7 @@ public function getValue_throws_for_an_invalid_format(): void $magicConstant->getValue('wrong format'); } - /** @test */ + #[Test] public function create_all_possible_values_from_the_constructor(): void { /* *** Process *** */ @@ -92,7 +94,7 @@ public function create_all_possible_values_from_the_constructor(): void self::assertSame('value C', (new FakeMagicConstant('value C'))->getValue()); } - /** @test */ + #[Test] public function create_all_possible_values_from_the_static_method(): void { /* *** Process *** */ @@ -103,7 +105,7 @@ public function create_all_possible_values_from_the_static_method(): void self::assertSame('value A', FakeMagicConstant::TYPE_ARRAY_FORMATS()->getValue()); } - /** @test */ + #[Test] public function create_instance_from_another_instance(): void { /* *** Initialisation *** */ @@ -118,11 +120,8 @@ public function create_instance_from_another_instance(): void } } - /** - * @test - * @dataProvider fakeMagicConstantDataProvider - * @param FakeMagicConstant $magicConstant - */ + #[Test] + #[DataProvider('fakeMagicConstantDataProvider')] public function getValue_returns_the_correct_value(FakeMagicConstant $magicConstant): void { /* *** Process *** */ @@ -132,16 +131,14 @@ public function getValue_returns_the_correct_value(FakeMagicConstant $magicConst self::assertSame($magicConstant->getValue(), $actualMagicConstant->getValue()); } - /** - * @test - * @dataProvider fakeMagicConstantDataProvider - * @param FakeMagicConstant $magicConstant - * @param string|int $key - * @param mixed $expectedValue - * @param string|int $format - */ - public function getValue_returns_the_correct_value_depending_on_the_format(FakeMagicConstant $magicConstant, $key, $expectedValue, $format): void - { + #[Test] + #[DataProvider('fakeMagicConstantDataProvider')] + public function getValue_returns_the_correct_value_depending_on_the_format( + FakeMagicConstant $magicConstant, + int|string $key, + mixed $expectedValue, + int|string $format + ): void { /* *** Process *** */ $actualMagicConstant = new FakeMagicConstant($magicConstant->getValue()); $actualValue = $actualMagicConstant->getValue($format); @@ -150,12 +147,8 @@ public function getValue_returns_the_correct_value_depending_on_the_format(FakeM self::assertSame($expectedValue, $actualValue); } - /** - * @test - * @dataProvider fakeMagicConstantDataProvider - * @param FakeMagicConstant $magicConstant - * @param string $expectedKey - */ + #[Test] + #[DataProvider('fakeMagicConstantDataProvider')] public function getKey_returns_the_correct_value(FakeMagicConstant $magicConstant, string $expectedKey): void { /* *** Process *** */ @@ -165,22 +158,21 @@ public function getKey_returns_the_correct_value(FakeMagicConstant $magicConstan self::assertSame($expectedKey, $actualMagicConstant->getKey()); } - public function test_getKey_returns_empty_string_for_dynamic_value(): void + #[Test] + public function getKey_returns_empty_string_for_dynamic_value(): void { $constant = new AnyValueMagicConstant('foo'); self::assertSame('', $constant->getKey()); } - /** - * @test - * @dataProvider fakeMagicConstantDataProvider - * @param FakeMagicConstant $magicConstant - * @param string|int $key - * @param mixed $expectedValue - */ - public function toString_returns_the_correct_value(FakeMagicConstant $magicConstant, $key, $expectedValue): void - { + #[Test] + #[DataProvider('fakeMagicConstantDataProvider')] + public function toString_returns_the_correct_value( + FakeMagicConstant $magicConstant, + int|string $key, + mixed $expectedValue + ): void { /* *** Process *** */ $actualValue = (string)$magicConstant; @@ -188,7 +180,7 @@ public function toString_returns_the_correct_value(FakeMagicConstant $magicConst self::assertSame((string)$expectedValue, $actualValue); } - /** @test */ + #[Test] public function keys_returns_the_list_of_possible_keys(): void { /* *** Initialisation *** */ @@ -207,7 +199,7 @@ public function keys_returns_the_list_of_possible_keys(): void self::assertSame($expectedConstants, $actualConstants); } - /** @test */ + #[Test] public function values_returns_an_array_of_possible_values(): void { /* *** Initialisation *** */ @@ -226,13 +218,10 @@ public function values_returns_an_array_of_possible_values(): void self::assertEquals($extectedValues, $actualValues); } - /** - * @test - * @dataProvider isValidValueDataProvider - * @param mixed $value - * @param $isValid - */ - public function isValidValue_checks_if_a_value_is_valid($value, bool $isValid): void + #[Test] + #[DataProvider('isValidValueDataProvider')] + + public function isValidValue_checks_if_a_value_is_valid(mixed $value, bool $isValid): void { /* *** Process *** */ $actualIsValid = FakeMagicConstant::isValidValue($value); @@ -241,10 +230,7 @@ public function isValidValue_checks_if_a_value_is_valid($value, bool $isValid): self::assertSame($isValid, $actualIsValid); } - /** - * @return array - */ - public function isValidValueDataProvider(): array + public static function isValidValueDataProvider(): array { return [ // Valid values @@ -260,13 +246,9 @@ public function isValidValueDataProvider(): array ]; } - /** - * @test - * @dataProvider isValidKeyDataProvider - * @param mixed $key - * @param $isValid - */ - public function isValidKey_checks_if_a_key_is_valid($key, bool $isValid): void + #[Test] + #[DataProvider('isValidKeyDataProvider')] + public function isValidKey_checks_if_a_key_is_valid(mixed $key, bool $isValid): void { /* *** Process *** */ $actualIsValid = FakeMagicConstant::isValidKey($key); @@ -275,10 +257,7 @@ public function isValidKey_checks_if_a_key_is_valid($key, bool $isValid): void self::assertSame($isValid, $actualIsValid); } - /** - * @return array - */ - public function isValidKeyDataProvider(): array + public static function isValidKeyDataProvider(): array { return [ // Valid keys @@ -292,14 +271,9 @@ public function isValidKeyDataProvider(): array ]; } - /** - * @test - * @dataProvider equalsDataProvider - * @param MagicConstant $magicConstantA - * @param mixed $magicConstantB - * @param bool $expectedResult - */ - public function equals_compares_values(MagicConstant $magicConstantA, $magicConstantB, bool $expectedResult): void + #[Test] + #[DataProvider('equalsDataProvider')] + public function equals_compares_values(MagicConstant $magicConstantA, mixed $magicConstantB, bool $expectedResult): void { /* *** Process *** */ $actualResult = $magicConstantA->equals($magicConstantB); @@ -308,7 +282,7 @@ public function equals_compares_values(MagicConstant $magicConstantA, $magicCons self::assertSame($expectedResult, $actualResult); } - public function equalsDataProvider(): array + public static function equalsDataProvider(): array { return [ [new FakeMagicConstant('foo'), new FakeMagicConstant('foo'), true], @@ -334,20 +308,15 @@ public function equalsDataProvider(): array ]; } - /** - * @test - * @dataProvider inDataProvider - * @param MagicConstant $magicConstant - * @param array $values - * @param bool $expectedResult - */ + #[Test] + #[DataProvider('inDataProvider')] public function in_returns_true_if_at_least_one_value_is_correct(MagicConstant $magicConstant, array $values, bool $expectedResult): void { self::assertSame($expectedResult, $magicConstant->in($values)); self::assertSame($expectedResult, $magicConstant->in(array_reverse($values))); } - public function inDataProvider(): array + public static function inDataProvider(): array { return [ [new FakeMagicConstant('foo'), [new FakeMagicConstant('foo')], true], @@ -377,17 +346,13 @@ public function inDataProvider(): array ]; } - public function fakeMagicConstantDataProvider(): array + public static function fakeMagicConstantDataProvider(): array { - return $this->magicConstantDataProvider(FakeMagicConstant::class); + return self::magicConstantDataProvider(FakeMagicConstant::class); } - /** - * @test - * @dataProvider allFormatsDataProvider - * @param MagicConstant $magicConstant - * @param array $expectedValues - */ + #[Test] + #[DataProvider('allFormatsDataProvider')] public function getAllFormats_returns_instances_in_all_possible_formats(MagicConstant $magicConstant, array $expectedValues): void { /* *** Process *** */ @@ -397,10 +362,7 @@ public function getAllFormats_returns_instances_in_all_possible_formats(MagicCon self::assertEquals($expectedValues, $actualValues); } - /** - * @return array - */ - public function allFormatsDataProvider(): array + public static function allFormatsDataProvider(): array { return [ [ @@ -426,7 +388,7 @@ public function allFormatsDataProvider(): array ]; } - /** @test */ + #[Test] public function get_new_instance_in_specific_format(): void { /* *** Initialisation *** */ @@ -443,7 +405,8 @@ public function get_new_instance_in_specific_format(): void self::assertSame('value C', $instanceFormatC->getValue()); } - public function test_normalize_resets_an_instance_to_the_first_format(): void + #[Test] + public function normalize_resets_an_instance_to_the_first_format(): void { /* *** Initialisation *** */ $withoutFormats = new FakeMagicConstant('B'); @@ -461,7 +424,7 @@ public function test_normalize_resets_an_instance_to_the_first_format(): void self::assertNotSame($withFormats, $withFormatsNormalized); } - public function allValuesDataProvider(): array + public static function allValuesDataProvider(): array { return [ [ @@ -487,12 +450,9 @@ public function allValuesDataProvider(): array ]; } - /** - * @dataProvider allValuesDataProvider - * @param MagicConstant $magicConstant - * @param array $expectedValues - */ - public function test_return_values_in_all_formats(MagicConstant $magicConstant, array $expectedValues): void + #[Test] + #[DataProvider('allValuesDataProvider')] + public function return_values_in_all_formats(MagicConstant $magicConstant, array $expectedValues): void { /* *** Process *** */ $actualValues = $magicConstant->getAllValues(); @@ -501,7 +461,8 @@ public function test_return_values_in_all_formats(MagicConstant $magicConstant, self::assertSame($expectedValues, $actualValues); } - public function test_has_custom_value_setter(): void + #[Test] + public function has_custom_value_setter(): void { $magicConstant1 = new CustomSetValueMagicConstant('FOO'); $magicConstant2 = new CustomSetValueMagicConstant('foo'); @@ -510,7 +471,8 @@ public function test_has_custom_value_setter(): void self::assertSame('foo', $magicConstant2->getValue()); } - public function test_getFormat_returns_the_instance_format(): void + #[Test] + public function getFormat_returns_the_instance_format(): void { self::assertEquals(0, (new FakeMagicConstant('foo'))->getFormat()); self::assertEquals(0, (new FakeMagicConstant(123))->getFormat()); @@ -525,7 +487,8 @@ public function test_getFormat_returns_the_instance_format(): void self::assertEquals('format C', (new FakeMagicConstant('value C'))->getFormat()); } - public function test_tryFrom(): void + #[Test] + public function tryFrom(): void { self::assertNull(FakeMagicConstant::tryFrom(null)); self::assertNull(FakeMagicConstant::tryFrom(1234)); diff --git a/tests/TestCase.php b/tests/TestCase.php index 85419d3..126b1c8 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -8,10 +8,10 @@ class TestCase extends \PHPUnit\Framework\TestCase { /** - * @param string|MagicConstant $magicConstantClass + * @param class-string $magicConstantClass * @return array */ - protected function magicConstantDataProvider(string $magicConstantClass): array + protected static function magicConstantDataProvider(string $magicConstantClass): array { $data = [];