diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml
index 8c29a01..36d272c 100644
--- a/.github/workflows/audit.yml
+++ b/.github/workflows/audit.yml
@@ -7,22 +7,12 @@ jobs:
name: Audit
strategy:
matrix:
- php-version: [ '8.2', '8.3' ]
+ php-version: [ '8.2', '8.3', '8.4' ]
fail-fast: false
runs-on: ubuntu-latest
steps:
- - name: Checkout (Push)
+ - name: Checkout
uses: actions/checkout@v4
- if: github.event_name == 'push'
- with:
- fetch-depth: 0
-
- - name: Checkout (PR)
- uses: actions/checkout@v4
- if: github.event_name == 'pull_request'
- with:
- ref: ${{ github.event.pull_request.head.ref }}
- fetch-depth: 0
- name: Setup PHP
uses: shivammathur/setup-php@v2
@@ -54,13 +44,13 @@ jobs:
echo "::endgroup::"
- name: Auditor
- uses: docker://nbgrp/auditor:0.23.1
+ uses: docker://nbgrp/auditor:0.29.0
- name: Tests
run: vendor/bin/simple-phpunit
- name: Codecov
- uses: codecov/codecov-action@v3
+ uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./clover.xml
diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php
index 92c604a..a8baffc 100644
--- a/.php-cs-fixer.php
+++ b/.php-cs-fixer.php
@@ -31,6 +31,9 @@
],
'comment_to_phpdoc' => [
'ignored_tags' => [
+ 'codeCoverageIgnoreStart',
+ 'codeCoverageIgnoreEnd',
+ 'codeCoverageIgnore',
'phan-suppress-current-line',
'phan-suppress-next-line',
'see',
diff --git a/composer.json b/composer.json
index 398a9b4..577755c 100644
--- a/composer.json
+++ b/composer.json
@@ -24,6 +24,7 @@
"symfony/http-kernel": "^7"
},
"require-dev": {
+ "phpunit/phpunit": "^11.5",
"roave/security-advisories": "dev-latest",
"symfony/phpunit-bridge": "^7"
},
diff --git a/grumphp.yml b/grumphp.yml
index 2de630e..5e9f706 100644
--- a/grumphp.yml
+++ b/grumphp.yml
@@ -7,6 +7,9 @@ grumphp:
enabled: false
tasks:
+ composer:
+ strict: true
+
composer_normalize:
indent_size: 4
indent_style: 'space'
@@ -32,4 +35,4 @@ grumphp:
no_cache: true
show_info: true
- securitychecker_local: ~
+ securitychecker_composeraudit: ~
diff --git a/phpcs.xml b/phpcs.xml
index 5b845ab..f67f2f4 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -61,6 +61,7 @@
+ */tests/*
@@ -185,14 +186,17 @@
-
+
-
+
+
+
+
@@ -204,9 +208,9 @@
-
+
-
+
diff --git a/phpstan.neon b/phpstan.neon
index 057b23c..e896512 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -3,12 +3,12 @@ parameters:
paths:
- src
- tests
- bootstrapFiles:
- - vendor/bin/.phpunit/phpunit/vendor/autoload.php
-
- checkMissingIterableValueType: false
ignoreErrors:
-
message: '/Cannot cast mixed to (int|float|string)/'
path: 'src/ArrayCastEnvVarProcessor.php'
+ -
+ identifier: missingType.iterableValue
+ -
+ identifier: phpDoc.parseError
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index f16d75a..bcf7869 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,33 +1,40 @@
-
+ cacheDirectory=".phpunit.cache"
+ requireCoverageMetadata="true"
+ beStrictAboutCoverageMetadata="true"
+ beStrictAboutOutputDuringTests="true"
+ displayDetailsOnPhpunitDeprecations="true"
+ failOnPhpunitDeprecation="true"
+ failOnRisky="true"
+ failOnWarning="true"
+>
-
-
+
+
- ./tests/
+ tests
-
- src
+ src
-
- src/CsvEnvVarProcessor.php
- src/NbgroupEnvBundle.php
-
+
+
+
diff --git a/psalm.xml b/psalm.xml
index 5abf3e3..85f7654 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -17,24 +17,12 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ArrayCastEnvVarProcessor.php b/src/ArrayCastEnvVarProcessor.php
index 2208a26..da851df 100644
--- a/src/ArrayCastEnvVarProcessor.php
+++ b/src/ArrayCastEnvVarProcessor.php
@@ -10,6 +10,7 @@
final class ArrayCastEnvVarProcessor implements EnvVarProcessorInterface
{
+ #[\Override]
public static function getProvidedTypes(): array
{
return [
@@ -27,6 +28,7 @@ public static function getProvidedTypes(): array
*
* @psalm-suppress MixedReturnTypeCoercion
*/
+ #[\Override]
public function getEnv(string $prefix, string $name, \Closure $getEnv): array
{
$env = (array) $getEnv($name);
@@ -46,6 +48,7 @@ public function getEnv(string $prefix, string $name, \Closure $getEnv): array
*/
private static function getBooleanMapper(): callable
{
+ /** @psalm-suppress RiskyTruthyFalsyComparison */
return static fn (mixed $value): bool => (bool) (filter_var($value, \FILTER_VALIDATE_BOOLEAN, ['flags' => \FILTER_NULL_ON_FAILURE]) ?? filter_var($value, \FILTER_VALIDATE_INT) ?: filter_var($value, \FILTER_VALIDATE_FLOAT));
}
@@ -55,6 +58,7 @@ private static function getBooleanMapper(): callable
private static function getIntegerMapper(string $name): callable
{
return static function (mixed $value) use ($name): int {
+ /** @psalm-suppress RiskyTruthyFalsyComparison */
if ((filter_var($value, \FILTER_VALIDATE_INT) ?: filter_var($value, \FILTER_VALIDATE_FLOAT)) === false) {
throw new RuntimeException('Non-numeric member of environment variable "'.$name.'" cannot be cast to int.');
}
diff --git a/src/CsvEnvVarProcessor.php b/src/CsvEnvVarProcessor.php
index 742a466..70dc6ff 100644
--- a/src/CsvEnvVarProcessor.php
+++ b/src/CsvEnvVarProcessor.php
@@ -9,9 +9,11 @@
use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
+// @codeCoverageIgnoreStart
if (class_exists(CsvEnvVarProcessor::class, false)) {
return;
}
+// @codeCoverageIgnoreEnd
final class CsvEnvVarProcessor implements EnvVarProcessorInterface
{
@@ -26,6 +28,7 @@ public function __construct(array $delimiterMap)
$this->delimiterMap = $delimiterMap;
}
+ #[\Override]
public static function getProvidedTypes(): array
{
// NB
@@ -36,6 +39,7 @@ public static function getProvidedTypes(): array
/**
* @return non-empty-list
*/
+ #[\Override]
public function getEnv(string $prefix, string $name, \Closure $getEnv): array
{
if (\array_key_exists($prefix, $this->delimiterMap) === false) {
@@ -49,6 +53,7 @@ public function getEnv(string $prefix, string $name, \Closure $getEnv): array
throw new RuntimeException('Environment variable "'.$name.'" should be a string.');
}
+ // @phpstan-ignore greaterOrEqual.alwaysTrue
return str_getcsv($env, $delimiter, '"', \PHP_VERSION_ID >= 70400 ? '' : '\\');
}
}
diff --git a/src/DependencyInjection/NbgroupEnvExtension.php b/src/DependencyInjection/NbgroupEnvExtension.php
index 3960711..9461fd2 100644
--- a/src/DependencyInjection/NbgroupEnvExtension.php
+++ b/src/DependencyInjection/NbgroupEnvExtension.php
@@ -20,11 +20,14 @@ class NbgroupEnvExtension extends Extension
{
private const NB_REPLACEMENT_MARK = '// NB';
+ #[\Override]
public function getConfiguration(array $config, ContainerBuilder $container): Configuration
{
return new Configuration();
}
+ /** @psalm-suppress MixedArrayAccess, MixedArgument */
+ #[\Override]
public function load(array $configs, ContainerBuilder $container): void
{
$configuration = new Configuration();
diff --git a/tests/ArrayCastEnvVarProcessorTest.php b/tests/ArrayCastEnvVarProcessorTest.php
index 71b834d..58fc1cb 100644
--- a/tests/ArrayCastEnvVarProcessorTest.php
+++ b/tests/ArrayCastEnvVarProcessorTest.php
@@ -6,19 +6,18 @@
namespace Nbgrp\Tests\EnvBundle;
use Nbgrp\EnvBundle\ArrayCastEnvVarProcessor;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
/**
- * @covers \Nbgrp\EnvBundle\ArrayCastEnvVarProcessor
- *
* @internal
*/
+#[CoversClass(ArrayCastEnvVarProcessor::class)]
final class ArrayCastEnvVarProcessorTest extends TestCase
{
- /**
- * @dataProvider provideSuccessCases
- */
+ #[DataProvider('provideSuccessCases')]
public function testSuccess(string $prefix, array $envValue, array $expected): void
{
$processor = new ArrayCastEnvVarProcessor();
@@ -29,7 +28,7 @@ public function testSuccess(string $prefix, array $envValue, array $expected): v
/**
* @return \Generator
*/
- public function provideSuccessCases(): iterable
+ public static function provideSuccessCases(): iterable
{
yield 'bool-array' => [
'bool-array',
@@ -74,15 +73,13 @@ public function provideSuccessCases(): iterable
];
}
- /**
- * @dataProvider provideInvalidNumericCases
- */
+ #[DataProvider('provideInvalidNumericCases')]
public function testInvalidNumeric(string $prefix, array $envValue, string $expectedMessageFormat): void
{
$processor = new ArrayCastEnvVarProcessor();
$this->expectException(RuntimeException::class);
- $this->expectExceptionMessage(sprintf($expectedMessageFormat, 'DM'));
+ $this->expectExceptionMessage(\sprintf($expectedMessageFormat, 'DM'));
$processor->getEnv($prefix, 'DM', static fn (): array => $envValue);
}
@@ -90,7 +87,7 @@ public function testInvalidNumeric(string $prefix, array $envValue, string $expe
/**
* @return \Generator
*/
- public function provideInvalidNumericCases(): iterable
+ public static function provideInvalidNumericCases(): iterable
{
yield [
'int-array',
@@ -105,15 +102,13 @@ public function provideInvalidNumericCases(): iterable
];
}
- /**
- * @dataProvider provideInvalidBase64Cases
- */
+ #[DataProvider('provideInvalidBase64Cases')]
public function testInvalidBase64(string $prefix, array $envValue, string $expectedMessageFormat): void
{
$processor = new ArrayCastEnvVarProcessor();
$this->expectException(RuntimeException::class);
- $this->expectExceptionMessage(sprintf($expectedMessageFormat, 'DM'));
+ $this->expectExceptionMessage(\sprintf($expectedMessageFormat, 'DM'));
$processor->getEnv($prefix, 'DM', static fn (): array => $envValue);
}
@@ -121,7 +116,7 @@ public function testInvalidBase64(string $prefix, array $envValue, string $expec
/**
* @return \Generator
*/
- public function provideInvalidBase64Cases(): iterable
+ public static function provideInvalidBase64Cases(): iterable
{
yield [
'base64-array',
diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php
index 61ed40f..71001b1 100644
--- a/tests/DependencyInjection/ConfigurationTest.php
+++ b/tests/DependencyInjection/ConfigurationTest.php
@@ -6,23 +6,28 @@
namespace Nbgrp\Tests\EnvBundle\DependencyInjection;
use Nbgrp\EnvBundle\DependencyInjection\Configuration;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Processor;
/**
- * @covers \Nbgrp\EnvBundle\DependencyInjection\Configuration
- *
* @internal
*/
+#[CoversClass(Configuration::class)]
final class ConfigurationTest extends TestCase
{
/** @var Processor */
private $processor;
- /**
- * @dataProvider provideValidConfigCases
- */
+ #[\Override]
+ protected function setUp(): void
+ {
+ $this->processor = new Processor();
+ }
+
+ #[DataProvider('provideValidConfigCases')]
public function testValidConfig(array $config, array $expected, string $description): void
{
self::assertSame($expected, $this->processor->processConfiguration(new Configuration(), [$config]), $description);
@@ -31,7 +36,7 @@ public function testValidConfig(array $config, array $expected, string $descript
/**
* @return \Generator
*/
- public function provideValidConfigCases(): iterable
+ public static function provideValidConfigCases(): iterable
{
yield [
[],
@@ -104,9 +109,7 @@ public function provideValidConfigCases(): iterable
];
}
- /**
- * @dataProvider provideInvalidConfigCases
- */
+ #[DataProvider('provideInvalidConfigCases')]
public function testInvalidConfig(array $config, string $expectedMessage): void
{
$this->expectException(InvalidConfigurationException::class);
@@ -117,7 +120,7 @@ public function testInvalidConfig(array $config, string $expectedMessage): void
/**
* @return \Generator
*/
- public function provideInvalidConfigCases(): iterable
+ public static function provideInvalidConfigCases(): iterable
{
yield [
[
@@ -135,9 +138,4 @@ public function provideInvalidConfigCases(): iterable
'Delimiter should be one character only.',
];
}
-
- protected function setUp(): void
- {
- $this->processor = new Processor();
- }
}
diff --git a/tests/DependencyInjection/NbgroupEnvExtensionTest.php b/tests/DependencyInjection/NbgroupEnvExtensionTest.php
index 9a49694..b1c0697 100644
--- a/tests/DependencyInjection/NbgroupEnvExtensionTest.php
+++ b/tests/DependencyInjection/NbgroupEnvExtensionTest.php
@@ -5,15 +5,19 @@
namespace Nbgrp\Tests\EnvBundle\DependencyInjection;
+use Nbgrp\EnvBundle\ArrayCastEnvVarProcessor;
+use Nbgrp\EnvBundle\DependencyInjection\Configuration;
use Nbgrp\EnvBundle\DependencyInjection\NbgroupEnvExtension;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
- * @covers \Nbgrp\EnvBundle\DependencyInjection\NbgroupEnvExtension
- *
* @internal
*/
+#[CoversClass(NbgroupEnvExtension::class)]
+#[CoversClass(ArrayCastEnvVarProcessor::class)]
+#[CoversClass(Configuration::class)]
final class NbgroupEnvExtensionTest extends TestCase
{
public function testComplexUsage(): void
diff --git a/tests/ExplodeEnvVarProcessorTest.php b/tests/ExplodeEnvVarProcessorTest.php
index 2196e3b..41e57b9 100644
--- a/tests/ExplodeEnvVarProcessorTest.php
+++ b/tests/ExplodeEnvVarProcessorTest.php
@@ -6,18 +6,20 @@
namespace Nbgrp\Tests\EnvBundle;
use Nbgrp\EnvBundle\CsvEnvVarProcessor;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
/**
- * @covers \Nbgrp\EnvBundle\CsvEnvVarProcessor
- *
* @internal
*/
+#[CoversClass(CsvEnvVarProcessor::class)]
final class ExplodeEnvVarProcessorTest extends TestCase
{
/**
- * @dataProvider provideSuccessCases
+ * @param array $delimiterMap
*/
+ #[DataProvider('provideSuccessCases')]
public function testSuccess(array $delimiterMap, string $prefix, string $envValue, array $expected): void
{
$processor = new CsvEnvVarProcessor($delimiterMap);
@@ -28,7 +30,7 @@ public function testSuccess(array $delimiterMap, string $prefix, string $envValu
/**
* @return \Generator}>
*/
- public function provideSuccessCases(): iterable
+ public static function provideSuccessCases(): iterable
{
$delimiterMap = [
'csv-dot' => '.',
@@ -69,9 +71,10 @@ public function provideSuccessCases(): iterable
$delimiterMap,
'csv-dot',
'"\".".\.."\""".\.',
+ // @phpstan-ignore greaterOrEqual.alwaysTrue
\PHP_VERSION_ID >= 70400
- ? ['\\', '.\\..\\"""', '\\', '']
- : ['\\".', '\\', '', '\"".\\.'],
+ ? ['\\', '.\..\"""', '\\', '']
+ : ['\".', '\\', '', '\"".\.'],
];
}
}