diff --git a/.github/workflows/test.Dockerfile b/.github/workflows/test.Dockerfile index 1eb3557..962a3d7 100644 --- a/.github/workflows/test.Dockerfile +++ b/.github/workflows/test.Dockerfile @@ -8,14 +8,3 @@ RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local ENV COMPOSER_ALLOW_SUPERUSER=1 ENV COMPOSER_HTACCESS_PROTECT=0 ENV COMPOSER_CACHE_DIR=/.composer-cache-dir - -# install PHP extension pcov -ARG CODE_COVERAGE -RUN if [[ "${CODE_COVERAGE}" == "true" ]] ; then \ - apk add --no-cache --virtual .build-deps $PHPIZE_DEPS \ - && mkdir -p /usr/src/php/ext/pcov && curl -fsSL https://pecl.php.net/get/pcov | tar xvz -C /usr/src/php/ext/pcov --strip 1 \ - && docker-php-ext-install pcov \ - && docker-php-ext-enable pcov \ - && rm -Rf /usr/src/php/ext/pcov \ - && apk del --no-cache .build-deps \ - ; fi diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 322ce8d..0b2829c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,39 +14,45 @@ jobs: matrix: include: - PHP_VERSION: '7.1' - CODE_COVERAGE: 'false' RUN_PHPSTAN: 'false' RUN_PSALM: 'false' - PHP_VERSION: '7.2' - CODE_COVERAGE: 'true' - RUN_PHPSTAN: 'false' + RUN_PHPSTAN: 'true' RUN_PSALM: 'false' - PHP_VERSION: '7.3' - CODE_COVERAGE: 'true' RUN_PHPSTAN: 'false' RUN_PSALM: 'false' - PHP_VERSION: '7.4' - CODE_COVERAGE: 'true' - RUN_PHPSTAN: 'true' - RUN_PSALM: 'true' + RUN_PHPSTAN: 'false' + RUN_PSALM: 'false' - PHP_VERSION: '8.0' - CODE_COVERAGE: 'true' RUN_PHPSTAN: 'true' RUN_PSALM: 'true' - PHP_VERSION: '8.1' - CODE_COVERAGE: 'true' RUN_PHPSTAN: 'false' RUN_PSALM: 'false' + - PHP_VERSION: '8.2' + RUN_PHPSTAN: 'false' + RUN_PSALM: 'false' + - PHP_VERSION: '8.3' + RUN_PHPSTAN: 'false' + RUN_PSALM: 'false' + - PHP_VERSION: '8.4' + RUN_PHPSTAN: 'false' + RUN_PSALM: 'false' + - PHP_VERSION: '8.5' + RUN_PHPSTAN: 'true' + RUN_PSALM: 'false' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v6 - name: Cache Docker Image id: docker-cache-image - uses: actions/cache@v2 + uses: actions/cache@v5 with: path: /tmp/docker-cache-image.tar - key: docker-cache-image:${{ matrix.PHP_VERSION }}:${{ matrix.CODE_COVERAGE }} + key: docker-cache-image:${{ matrix.PHP_VERSION }} - name: Load Docker Image if: steps.docker-cache-image.outputs.cache-hit == 'true' @@ -54,10 +60,10 @@ jobs: - name: Build Docker Image if: steps.docker-cache-image.outputs.cache-hit != 'true' - run: docker build -f .github/workflows/test.Dockerfile -t 'test:${{ matrix.PHP_VERSION }}' --build-arg 'PHP_VERSION=${{ matrix.PHP_VERSION }}' --build-arg 'CODE_COVERAGE=${{ matrix.CODE_COVERAGE }}' . + run: docker build -f .github/workflows/test.Dockerfile -t 'test:${{ matrix.PHP_VERSION }}' --build-arg 'PHP_VERSION=${{ matrix.PHP_VERSION }}' . - name: Cache Composer Cache Dir - uses: actions/cache@v2 + uses: actions/cache@v5 with: path: /tmp/composer-cache-dir key: composer-cache-dir:${{ matrix.PHP_VERSION }} @@ -76,17 +82,7 @@ jobs: - name: Run Unit Test run: | - if [ "${{ matrix.CODE_COVERAGE }}" == "true" ]; then - docker run --rm -u "$(id -u):$(id -g)" -v "$(pwd):/workdir" 'test:${{ matrix.PHP_VERSION }}' php -d 'zend.assertions=1' -d 'pcov.enabled=1' ./vendor/bin/phpunit --coverage-clover=.clover.xml - else - docker run --rm -u "$(id -u):$(id -g)" -v "$(pwd):/workdir" 'test:${{ matrix.PHP_VERSION }}' php -d 'zend.assertions=1' ./vendor/bin/phpunit - fi - - - name: Upload Codecov Report - uses: codecov/codecov-action@v1 - if: ${{ matrix.CODE_COVERAGE == 'true' }} - with: - file: .clover.xml + docker run --rm -u "$(id -u):$(id -g)" -v "$(pwd):/workdir" 'test:${{ matrix.PHP_VERSION }}' php -d 'zend.assertions=1' ./vendor/bin/phpunit - name: Run PHPStan if: ${{ matrix.RUN_PHPSTAN == 'true' }} diff --git a/composer.json b/composer.json index 8485a5f..f6552a1 100644 --- a/composer.json +++ b/composer.json @@ -21,8 +21,8 @@ "composer-runtime-api": "^2.0" }, "require-dev": { - "phpstan/phpstan": "^1.3.0", - "phpunit/phpunit": "^7.5.20 | ^8.5.52 | ^9.6.33", + "phpstan/phpstan": "^1.4.0", + "phpunit/phpunit": "^7.5.20 | ^8.5.52 | ^9.6.34", "vimeo/psalm": "^4.17.0" }, "autoload": { diff --git a/examples/doctrine/composer.json b/examples/doctrine/composer.json index cb53dc0..566fade 100644 --- a/examples/doctrine/composer.json +++ b/examples/doctrine/composer.json @@ -16,6 +16,7 @@ "license": "BSD-3-Clause", "require": { "php": "^7.1 | ^8.0", + "ext-pdo_sqlite": "*", "marc-mabe/enum-cl": "@dev", "doctrine/orm": "2.9.6" }, diff --git a/src/functions.php b/src/functions.php index 4691664..62d682e 100644 --- a/src/functions.php +++ b/src/functions.php @@ -51,11 +51,7 @@ function get_debug_type($value): string return 'class@anonymous'; default: /** @var resource $value */ - /** @var string|null $type */ $type = @get_resource_type($value); - if (null === $type) { - return 'unknown'; - } if ('Unknown' === $type) { $type = 'closed'; @@ -79,7 +75,6 @@ function get_debug_type($value): string function enum_exists(string $enum, bool $autoload = true) : bool { if (\PHP_VERSION_ID >= 80100) { - /** @phpstan-ignore-next-line */ return \enum_exists($enum, $autoload); } diff --git a/src/psr-4/EmulatedBackedEnumTrait.php b/src/psr-4/EmulatedBackedEnumTrait.php index afdeaf7..1c03f90 100644 --- a/src/psr-4/EmulatedBackedEnumTrait.php +++ b/src/psr-4/EmulatedBackedEnumTrait.php @@ -57,6 +57,7 @@ trait EmulatedBackedEnumTrait /** @param string|int $value */ final private function __construct(string $name, $value) { + /** @phpstan-ignore-next-line */ $this->name = $name; /** @phpstan-ignore-next-line */ diff --git a/tests/BasicIntEnumTest.php b/tests/BasicIntEnumTest.php index ed3ac22..f6cb642 100644 --- a/tests/BasicIntEnumTest.php +++ b/tests/BasicIntEnumTest.php @@ -38,8 +38,14 @@ public function testFromSuccess(): void public function testFromInvalidValue(): void { + if (PHP_VERSION_ID < 80200) { + $enumClass = '"' . BasicIntEnum::class . '"'; + } else { + $enumClass = BasicIntEnum::class; + } + + $this->expectExceptionMessage("10 is not a valid backing value for enum {$enumClass}"); $this->expectException('ValueError'); - $this->expectExceptionMessage('10 is not a valid backing value for enum "BasicIntEnum"'); BasicIntEnum::from(10); } @@ -74,13 +80,20 @@ public function testFromUnexpectedBoolTypeError(): void if (PHP_VERSION_ID >= 80000 && PHP_VERSION_ID < 80100) { $class = EmulatedIntEnum::class; $type = 'string|int'; + $given = 'bool'; } else { $class = BasicIntEnum::class; $type = 'int'; + + if (PHP_VERSION_ID >= 80300) { + $given = 'true'; + } else { + $given = 'bool'; + } } $this->expectException('TypeError'); - $this->expectExceptionMessage("{$class}::from(): Argument #1 (\$value) must be of type {$type}, bool given"); + $this->expectExceptionMessage("{$class}::from(): Argument #1 (\$value) must be of type {$type}, {$given} given"); /** @phpstan-ignore-next-line */ BasicIntEnum::from(true); @@ -169,13 +182,20 @@ public function testTryFromUnexpectedBoolTypeError(): void if (PHP_VERSION_ID >= 80000 && PHP_VERSION_ID < 80100) { $class = EmulatedIntEnum::class; $type = 'string|int'; + $given = 'bool'; } else { $class = BasicIntEnum::class; $type = 'int'; + + if (PHP_VERSION_ID >= 80300) { + $given = 'true'; + } else { + $given = 'bool'; + } } $this->expectException('TypeError'); - $this->expectExceptionMessage("{$class}::tryFrom(): Argument #1 (\$value) must be of type {$type}, bool given"); + $this->expectExceptionMessage("{$class}::tryFrom(): Argument #1 (\$value) must be of type {$type}, {$given} given"); /** @phpstan-ignore-next-line */ BasicIntEnum::tryFrom(true); diff --git a/tests/BasicStringEnumTest.php b/tests/BasicStringEnumTest.php index cce6100..4d0b008 100644 --- a/tests/BasicStringEnumTest.php +++ b/tests/BasicStringEnumTest.php @@ -38,8 +38,14 @@ public function testFromSuccess(): void public function testFromInvalidValue(): void { + if (PHP_VERSION_ID < 80200) { + $enumClass = '"' . BasicStringEnum::class . '"'; + } else { + $enumClass = BasicStringEnum::class; + } + + $this->expectExceptionMessage("\"10\" is not a valid backing value for enum {$enumClass}"); $this->expectException('ValueError'); - $this->expectExceptionMessage('"10" is not a valid backing value for enum "BasicStringEnum"'); BasicStringEnum::from('10'); } @@ -74,13 +80,20 @@ public function testFromUnexpectedBoolTypeError(): void if (PHP_VERSION_ID >= 80000 && PHP_VERSION_ID < 80100) { $class = EmulatedStringEnum::class; $type = 'string|int'; + $given = 'bool'; } else { $class = BasicStringEnum::class; $type = 'string'; + + if (PHP_VERSION_ID >= 80300) { + $given = 'true'; + } else { + $given = 'bool'; + } } $this->expectException('TypeError'); - $this->expectExceptionMessage("{$class}::from(): Argument #1 (\$value) must be of type {$type}, bool given"); + $this->expectExceptionMessage("{$class}::from(): Argument #1 (\$value) must be of type {$type}, {$given} given"); /** @phpstan-ignore-next-line */ BasicStringEnum::from(true); @@ -169,13 +182,20 @@ public function testTryFromUnexpectedBoolTypeError(): void if (PHP_VERSION_ID >= 80000 && PHP_VERSION_ID < 80100) { $class = EmulatedStringEnum::class; $type = 'string|int'; + $given = 'bool'; } else { $class = BasicStringEnum::class; $type = 'string'; + + if (PHP_VERSION_ID >= 80300) { + $given = 'true'; + } else { + $given = 'bool'; + } } $this->expectException('TypeError'); - $this->expectExceptionMessage("{$class}::tryFrom(): Argument #1 (\$value) must be of type {$type}, bool given"); + $this->expectExceptionMessage("{$class}::tryFrom(): Argument #1 (\$value) must be of type {$type}, {$given} given"); /** @phpstan-ignore-next-line */ BasicStringEnum::tryFrom(true);