diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index eaffcc8..71cc227 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3']
+ php-versions: ['8.1', '8.2', '8.3', '8.4']
composer-flags: ['', '--prefer-lowest']
steps:
- uses: actions/checkout@v4
diff --git a/.gitignore b/.gitignore
index 6f79ab1..f55bea3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,4 @@
/vendor
/composer.lock
/phpunit.xml
-/.phpunit.result.cache
+/.phpunit.cache
diff --git a/README.md b/README.md
index 2bb443b..32281a6 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[](https://php.net/)
+[](https://php.net/)

# PHP_Codesniffer baseline
diff --git a/composer.json b/composer.json
index 046b101..b258807 100644
--- a/composer.json
+++ b/composer.json
@@ -13,22 +13,26 @@
"lock": false
},
"require": {
- "php": ">=7.4",
- "composer-plugin-api": "^1.0 || ^2.0",
+ "php": ">=8.1",
+ "composer-plugin-api": "^2.0",
"squizlabs/php_codesniffer": "^3.6"
},
"require-dev": {
"composer/composer": "^2.0",
"mikey179/vfsstream": "1.6.12",
"phpmd/phpmd": "^2.15",
- "phpstan/phpstan": "^1.4",
- "phpstan/phpstan-phpunit": "^1.0",
- "phpstan/phpstan-strict-rules": "^1.1",
- "phpstan/extension-installer": "^1.1",
- "phpunit/phpunit": "^9.5",
+ "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0",
+ "phpstan/phpstan-strict-rules": "^2.0",
+ "phpstan/extension-installer": "^1.4",
+ "phpunit/phpunit": "^10.5 || ^11.5",
"roave/security-advisories": "dev-latest"
},
"scripts": {
+ "baseline": ["@baseline:phpcs", "@baseline:phpmd", "@baseline:phpstan", "@baseline:phpcqc"],
+ "baseline:phpcs": "phpcs --report=\\\\DR\\\\CodeSnifferBaseline\\\\Reports\\\\Baseline --report-file=phpcs.baseline.xml --basepath=.",
+ "baseline:phpmd": "@check:phpmd --generate-baseline",
+ "baseline:phpstan": "phpstan --generate-baseline",
"run:plugin": "DR\\CodeSnifferBaseline\\Plugin\\Plugin::run",
"check": ["@check:phpstan", "@check:phpmd", "@check:phpcs"],
"check:phpstan": "phpstan analyse",
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 7854d22..e91356e 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,24 +1,28 @@
tests/Unit
-
+
- src
+ src
-
+
diff --git a/src/Baseline/BaselineSetFactory.php b/src/Baseline/BaselineSetFactory.php
index 8275463..cb03bbe 100644
--- a/src/Baseline/BaselineSetFactory.php
+++ b/src/Baseline/BaselineSetFactory.php
@@ -10,7 +10,6 @@ class BaselineSetFactory
/**
* Read the baseline violations from the given filename path.
* @throws RuntimeException
- * @SuppressWarnings(PHPMD.ErrorControlOperator) - handled by the RuntimeException
*/
public static function fromFile(string $fileName): ?BaselineSet
{
diff --git a/src/Plugin/Plugin.php b/src/Plugin/Plugin.php
index 7e4e2f3..8803d6b 100644
--- a/src/Plugin/Plugin.php
+++ b/src/Plugin/Plugin.php
@@ -15,7 +15,7 @@
class Plugin implements PluginInterface, EventSubscriberInterface
{
private ?IOInterface $stream = null;
- private string $codeSnifferFilePath;
+ private string $codeSnifferFilePath;
public function __construct(?string $codeSnifferFilePath = null)
{
@@ -48,9 +48,6 @@ public function uninstall(Composer $composer, IOInterface $stream): void
// not necessary
}
- /**
- * @SuppressWarnings(PHPMD.ErrorControlOperator) - handled by the === false check
- */
public function onPostInstall(): void
{
if ($this->stream === null) {
diff --git a/tests/Unit/Baseline/BaselineSetFactoryTest.php b/tests/Unit/Baseline/BaselineSetFactoryTest.php
index d0ac100..e847cff 100644
--- a/tests/Unit/Baseline/BaselineSetFactoryTest.php
+++ b/tests/Unit/Baseline/BaselineSetFactoryTest.php
@@ -4,17 +4,13 @@
namespace DR\CodeSnifferBaseline\Tests\Unit\Baseline;
use DR\CodeSnifferBaseline\Baseline\BaselineSetFactory;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use RuntimeException;
-/**
- * @coversDefaultClass \DR\CodeSnifferBaseline\Baseline\BaselineSetFactory
- */
+#[CoversClass(BaselineSetFactory::class)]
class BaselineSetFactoryTest extends TestCase
{
- /**
- * @covers ::fromFile
- */
public function testFromFileShouldSucceed(): void
{
$filename = __DIR__ . '/TestFiles/baseline.xml';
@@ -23,9 +19,6 @@ public function testFromFileShouldSucceed(): void
static::assertTrue($set->contains('Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterOpen', '/test/src/foo/bar', 'foobar'));
}
- /**
- * @covers ::fromFile
- */
public function testFromFileShouldSucceedWithBackAndForwardSlashes(): void
{
$filename = __DIR__ . '/TestFiles/baseline.xml';
@@ -35,17 +28,11 @@ public function testFromFileShouldSucceedWithBackAndForwardSlashes(): void
static::assertTrue($set->contains('Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterOpen', '/test\\src\\foo/bar', 'foobar'));
}
- /**
- * @covers ::fromFile
- */
public function testFromFileShouldReturnNullIfAbsent(): void
{
static::assertNull(BaselineSetFactory::fromFile('foobar.xml'));
}
- /**
- * @covers ::fromFile
- */
public function testFromFileShouldThrowExceptionForOnInvalidXML(): void
{
$this->expectException(RuntimeException::class);
@@ -53,9 +40,6 @@ public function testFromFileShouldThrowExceptionForOnInvalidXML(): void
BaselineSetFactory::fromFile(__DIR__ . '/TestFiles/invalid-baseline.xml');
}
- /**
- * @covers ::fromFile
- */
public function testFromFileViolationMissingSniffShouldThrowException(): void
{
$this->expectException(RuntimeException::class);
@@ -63,9 +47,6 @@ public function testFromFileViolationMissingSniffShouldThrowException(): void
BaselineSetFactory::fromFile(__DIR__ . '/TestFiles/missing-sniff-baseline.xml');
}
- /**
- * @covers ::fromFile
- */
public function testFromFileViolationMissingSignatureShouldThrowException(): void
{
$this->expectException(RuntimeException::class);
@@ -73,9 +54,6 @@ public function testFromFileViolationMissingSignatureShouldThrowException(): voi
BaselineSetFactory::fromFile(__DIR__ . '/TestFiles/missing-signature-baseline.xml');
}
- /**
- * @covers ::fromFile
- */
public function testFromFileViolationMissingFileShouldThrowException(): void
{
$this->expectException(RuntimeException::class);
diff --git a/tests/Unit/Baseline/BaselineSetTest.php b/tests/Unit/Baseline/BaselineSetTest.php
index 2b7ca40..fc773df 100644
--- a/tests/Unit/Baseline/BaselineSetTest.php
+++ b/tests/Unit/Baseline/BaselineSetTest.php
@@ -3,21 +3,17 @@
namespace DR\CodeSnifferBaseline\Tests\Unit\Baseline;
+use PHPUnit\Framework\Attributes\CoversClass;
use DR\CodeSnifferBaseline\Baseline\BaselineSet;
use DR\CodeSnifferBaseline\Baseline\ViolationBaseline;
use PHPUnit\Framework\TestCase;
/**
* Test the logic of the baseline set
- * @coversDefaultClass \DR\CodeSnifferBaseline\Baseline\BaselineSet
*/
+#[CoversClass(BaselineSet::class)]
class BaselineSetTest extends TestCase
{
- /**
- * @covers ::addEntry
- * @covers ::contains
- *
- */
public function testSetContainsEntry(): void
{
$set = new BaselineSet();
@@ -26,10 +22,6 @@ public function testSetContainsEntry(): void
static::assertTrue($set->contains('sniff', 'foobar', 'signature'));
}
- /**
- * @covers ::addEntry
- * @covers ::contains
- */
public function testShouldFindEntryForIdenticalRules(): void
{
$set = new BaselineSet();
@@ -42,10 +34,6 @@ public function testShouldFindEntryForIdenticalRules(): void
static::assertFalse($set->contains('sniff', 'foo', 'signB'));
}
- /**
- * @covers ::addEntry
- * @covers ::contains
- */
public function testShouldNotFindEntryForNonExistingRule(): void
{
$set = new BaselineSet();
diff --git a/tests/Unit/Baseline/ViolationBaselineTest.php b/tests/Unit/Baseline/ViolationBaselineTest.php
index edf95b5..ef4bee0 100644
--- a/tests/Unit/Baseline/ViolationBaselineTest.php
+++ b/tests/Unit/Baseline/ViolationBaselineTest.php
@@ -3,19 +3,13 @@
namespace DR\CodeSnifferBaseline\Tests\Unit\Baseline;
+use PHPUnit\Framework\Attributes\CoversClass;
use DR\CodeSnifferBaseline\Baseline\ViolationBaseline;
use PHPUnit\Framework\TestCase;
-/**
- * @coversDefaultClass \DR\CodeSnifferBaseline\Baseline\ViolationBaseline
- */
+#[CoversClass(ViolationBaseline::class)]
class ViolationBaselineTest extends TestCase
{
- /**
- * @covers ::__construct
- * @covers ::getSniffName
- * @covers ::getSignature
- */
public function testAccessors(): void
{
$violation = new ViolationBaseline('sniff', 'foobar', 'signature');
@@ -25,8 +19,6 @@ public function testAccessors(): void
/**
* Test the give file matches the baseline correctly
- * @covers ::__construct
- * @covers ::matches
*/
public function testMatches(): void
{
diff --git a/tests/Unit/Plugin/BaselineHandlerTest.php b/tests/Unit/Plugin/BaselineHandlerTest.php
index d3a4bf3..db49240 100644
--- a/tests/Unit/Plugin/BaselineHandlerTest.php
+++ b/tests/Unit/Plugin/BaselineHandlerTest.php
@@ -3,28 +3,20 @@
namespace DR\CodeSnifferBaseline\Tests\Unit\Plugin;
+use PHPUnit\Framework\Attributes\CoversClass;
use DR\CodeSnifferBaseline\Baseline\BaselineSet;
use DR\CodeSnifferBaseline\Plugin\BaselineHandler;
use PHPUnit\Framework\TestCase;
-/**
- * @coversDefaultClass \DR\CodeSnifferBaseline\Plugin\BaselineHandler
- * @covers ::__construct
- */
+#[CoversClass(BaselineHandler::class)]
class BaselineHandlerTest extends TestCase
{
- /**
- * @covers ::isSuppressed
- */
public function testIsSuppressedNoBaselineShouldBeFalse(): void
{
$handler = new BaselineHandler(null);
static::assertFalse($handler->isSuppressed([], 1, 'foobar', '/path/'));
}
- /**
- * @covers ::isSuppressed
- */
public function testIsSuppressedWithBaseline(): void
{
$baseline = $this->createMock(BaselineSet::class);
diff --git a/tests/Unit/Plugin/PluginTest.php b/tests/Unit/Plugin/PluginTest.php
index ef291e0..bc4ff5a 100644
--- a/tests/Unit/Plugin/PluginTest.php
+++ b/tests/Unit/Plugin/PluginTest.php
@@ -11,20 +11,16 @@
use DR\CodeSnifferBaseline\Plugin\Plugin;
use Exception;
use org\bovigo\vfs\vfsStream;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use RuntimeException;
-/**
- * @coversDefaultClass \DR\CodeSnifferBaseline\Plugin\Plugin
- * @covers ::__construct
- */
+#[CoversClass(Plugin::class)]
class PluginTest extends TestCase
{
- /** @var Composer|MockObject */
- private Composer $composer;
- /** @var IOInterface|MockObject */
- private IOInterface $stream;
+ private Composer&MockObject $composer;
+ private IOInterface&MockObject $stream;
protected function setUp(): void
{
@@ -32,9 +28,6 @@ protected function setUp(): void
$this->stream = $this->createMock(IOInterface::class);
}
- /**
- * @covers ::getSubscribedEvents
- */
public function testGetSubscribedEvents(): void
{
$expected = [
@@ -45,10 +38,6 @@ public function testGetSubscribedEvents(): void
static::assertSame($expected, Plugin::getSubscribedEvents());
}
- /**
- * @covers ::activate
- * @covers ::onPostInstall
- */
public function testOnPostInstallWithoutExistingFile(): void
{
$this->stream->expects(static::once())->method('error')->with(static::stringContains('failed to find'));
@@ -58,15 +47,20 @@ public function testOnPostInstallWithoutExistingFile(): void
$plugin->onPostInstall();
}
- /**
- * @covers ::activate
- * @covers ::onPostInstall
- */
public function testOnPostInstallAlreadyContainsInjection(): void
{
- $this->stream->expects(static::exactly(2))
+ $matcher = static::exactly(2);
+ $this->stream->expects($matcher)
->method('info')
- ->withConsecutive([static::stringContains('read')], [static::stringContains('is already modified')]);
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ static::assertIsString($parameters[0]);
+ if ($matcher->numberOfInvocations() === 1) {
+ static::assertStringContainsString('read', $parameters[0]);
+ }
+ if ($matcher->numberOfInvocations() === 2) {
+ static::assertStringContainsString('is already modified', $parameters[0]);
+ }
+ });
$file = vfsStream::setup()->url() . '/File.php';
file_put_contents($file, 'foobar \\' . BaselineHandler::class . 'foobar');
@@ -77,15 +71,17 @@ public function testOnPostInstallAlreadyContainsInjection(): void
$plugin->onPostInstall();
}
- /**
- * @covers ::activate
- * @covers ::onPostInstall
- */
public function testOnPostInstallShouldErrorWhenMessageCountCantBeFound(): void
{
- $this->stream->expects(static::once())
+ $matcher = static::once();
+ $this->stream->expects($matcher)
->method('error')
- ->withConsecutive([static::stringContains('unable to find `$messageCount++;`')]);
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ static::assertIsString($parameters[0]);
+ if ($matcher->numberOfInvocations() === 1) {
+ static::assertStringContainsString('unable to find `$messageCount++;`', $parameters[0]);
+ }
+ });
$file = vfsStream::setup()->url() . '/File.php';
file_put_contents($file, 'foobar ');
@@ -95,15 +91,20 @@ public function testOnPostInstallShouldErrorWhenMessageCountCantBeFound(): void
$plugin->onPostInstall();
}
- /**
- * @covers ::activate
- * @covers ::onPostInstall
- */
public function testOnPostInstallShouldInjectCode(): void
{
- $this->stream->expects(static::exactly(2))
+ $matcher = static::exactly(2);
+ $this->stream->expects($matcher)
->method('info')
- ->withConsecutive([static::stringContains('read')], [static::stringContains('saved to:')]);
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ static::assertIsString($parameters[0]);
+ if ($matcher->numberOfInvocations() === 1) {
+ static::assertStringContainsString('read', $parameters[0]);
+ }
+ if ($matcher->numberOfInvocations() === 2) {
+ static::assertStringContainsString('saved to:', $parameters[0]);
+ }
+ });
$file = vfsStream::setup()->url() . '/File.php';
file_put_contents($file, 'foobar $messageCount++; foobar');
@@ -116,7 +117,6 @@ public function testOnPostInstallShouldInjectCode(): void
}
/**
- * @covers ::run
* @throws Exception
*/
public function testRun(): void
diff --git a/tests/Unit/Reports/BaselineTest.php b/tests/Unit/Reports/BaselineTest.php
index d3a70d4..05b30e9 100644
--- a/tests/Unit/Reports/BaselineTest.php
+++ b/tests/Unit/Reports/BaselineTest.php
@@ -7,34 +7,26 @@
use DR\CodeSnifferBaseline\Util\CodeSignature;
use PHP_CodeSniffer\Config;
use PHP_CodeSniffer\Files\File;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
-/**
- * @coversDefaultClass \DR\CodeSnifferBaseline\Reports\Baseline
- */
+#[CoversClass(Baseline::class)]
class BaselineTest extends TestCase
{
- /** @var File|MockObject */
- private File $file;
+ private File&MockObject $file;
protected function setUp(): void
{
$this->file = $this->createMock(File::class);
}
- /**
- * @covers ::generateFileReport
- */
public function testGenerateFileReportEmptyShouldReturnFalse(): void
{
$report = new Baseline();
static::assertFalse($report->generateFileReport(['errors' => 0, 'warnings' => 0, 'filename' => 'foo', 'messages' => []], $this->file));
}
- /**
- * @covers ::generateFileReport
- */
public function testGenerateFileReportShouldPrintReport(): void
{
$reportData = [
@@ -60,9 +52,6 @@ public function testGenerateFileReportShouldPrintReport(): void
static::assertSame('' . PHP_EOL, $result);
}
- /**
- * @covers ::generate
- */
public function testGenerate(): void
{
$expected = "" . PHP_EOL;
diff --git a/tests/Unit/Util/CodeSignatureTest.php b/tests/Unit/Util/CodeSignatureTest.php
index 737f626..91269dd 100644
--- a/tests/Unit/Util/CodeSignatureTest.php
+++ b/tests/Unit/Util/CodeSignatureTest.php
@@ -3,18 +3,15 @@
namespace DR\CodeSnifferBaseline\Tests\Unit\Util;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use DR\CodeSnifferBaseline\Util\CodeSignature;
use PHPUnit\Framework\TestCase;
-/**
- * @coversDefaultClass \DR\CodeSnifferBaseline\Util\CodeSignature
- */
+#[CoversClass(CodeSignature::class)]
class CodeSignatureTest extends TestCase
{
- /**
- * @covers ::createSignature
- * @dataProvider dataProvider
- */
+ #[DataProvider('dataProvider')]
public function testCreateSignature(int $lineNr, string $expected): void
{
$tokens = [
@@ -51,7 +48,7 @@ public function testCreateSignature(int $lineNr, string $expected): void
/**
* @return array>
*/
- public function dataProvider(): array
+ public static function dataProvider(): array
{
return [
'first line of file' => [
diff --git a/tests/Unit/Util/DirectoryUtilTest.php b/tests/Unit/Util/DirectoryUtilTest.php
index 965de7a..3f52fbb 100644
--- a/tests/Unit/Util/DirectoryUtilTest.php
+++ b/tests/Unit/Util/DirectoryUtilTest.php
@@ -3,17 +3,13 @@
namespace DR\CodeSnifferBaseline\Tests\Unit\Util;
+use PHPUnit\Framework\Attributes\CoversClass;
use DR\CodeSnifferBaseline\Util\DirectoryUtil;
use PHPUnit\Framework\TestCase;
-/**
- * @coversDefaultClass \DR\CodeSnifferBaseline\Util\DirectoryUtil
- */
+#[CoversClass(DirectoryUtil::class)]
class DirectoryUtilTest extends TestCase
{
- /**
- * @covers ::getVendorDir
- */
public function testGetVendorDir(): void
{
$directory = DirectoryUtil::getVendorDir();
@@ -21,9 +17,6 @@ public function testGetVendorDir(): void
static::assertSame(dirname(__DIR__, 3) . '/vendor/', $directory);
}
- /**
- * @covers ::getProjectRoot
- */
public function testGetProjectRoot(): void
{
$directory = DirectoryUtil::getProjectRoot();