Skip to content

Commit 037ea1c

Browse files
committed
Test PhpatUsageProvider via DeadCodeRuleTest integration fixture
Replace the standalone PhpatUsageProviderTest with the conventional integration fixture used by every other provider: a real data/providers/phpat.php with a registered and an unregistered phpat architecture test, driven through DeadCodeRuleTest. The container mock now returns an instance of the registered test for the "phpat.test" tag, mirroring phpat's getServicesByTag() lookup, so detection is exercised end-to-end against the dead-code graph. testNoFatalError uses require_once since the fixture classes are autoloaded during analysis. Co-Authored-By: Claude Code Claude-Session: https://claude.ai/code/session_01WqA3SLHn3vQEytN5C1KCJj
1 parent 16d15b7 commit 037ea1c

7 files changed

Lines changed: 58 additions & 120 deletions

File tree

composer-dependency-analyser.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
$config = (new Configuration())
1212
->ignoreErrorsOnPath(__DIR__ . '/src/Provider', [ErrorType::DEV_DEPENDENCY_IN_PROD]) // providers are designed that way
1313
->ignoreErrorsOnExtensionAndPath('ext-simplexml', __DIR__ . '/src/Provider/SymfonyUsageProvider.php', [ErrorType::SHADOW_DEPENDENCY]) // guarded with extension_loaded()
14-
->addPathToExclude(__DIR__ . '/tests/Provider/data')
1514
->addPathToExclude(__DIR__ . '/tests/Rule/data');
1615

1716
return $config;

composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@
6666
"ShipMonk\\PHPStan\\DeadCode\\": "tests/"
6767
},
6868
"classmap": [
69-
"tests/Provider/data",
7069
"tests/Rule/data"
7170
]
7271
},

tests/Excluder/TestsUsageExcluderTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ public function testAutodetectComposerDevPaths(): void
1919

2020
self::assertSame([
2121
realpath(__DIR__ . '/../../tests'),
22-
realpath(__DIR__ . '/../../tests/Provider/data'),
2322
realpath(__DIR__ . '/../../tests/Rule/data'),
2423
], $devPathsPropertyReflection->getValue($excluder));
2524
}

tests/Provider/PhpatUsageProviderTest.php

Lines changed: 0 additions & 79 deletions
This file was deleted.

tests/Provider/data/phpat.php

Lines changed: 0 additions & 36 deletions
This file was deleted.

tests/Rule/DeadCodeRuleTest.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Composer\Semver\VersionParser;
88
use Generator;
99
use LogicException;
10+
use PhpatProvider\RegisteredArchitectureTest;
1011
use PhpParser\Node;
1112
use PHPStan\Analyser\Error;
1213
use PHPStan\Analyser\Scope;
@@ -235,7 +236,7 @@ public function testNoFatalError(): void
235236

236237
try {
237238
ob_start();
238-
require $file;
239+
require_once $file;
239240
ob_end_clean();
240241
} catch (Throwable $e) {
241242
self::fail("Fatal error in {$e->getFile()}:{$e->getLine()}:\n {$e->getMessage()}");
@@ -1015,6 +1016,7 @@ public static function provideFiles(): Traversable
10151016
yield 'provider-behat' => [__DIR__ . '/data/providers/behat.php'];
10161017
yield 'provider-doctrine' => [__DIR__ . '/data/providers/doctrine.php'];
10171018
yield 'provider-phpstan' => [__DIR__ . '/data/providers/phpstan.php'];
1019+
yield 'provider-phpat' => [__DIR__ . '/data/providers/phpat.php', self::requiresPackage('phpat/phpat', '>= 0.12')];
10181020
yield 'provider-eloquent' => [__DIR__ . '/data/providers/eloquent.php'];
10191021
yield 'provider-laravel' => [__DIR__ . '/data/providers/laravel.php'];
10201022
yield 'provider-blade' => [__DIR__ . '/data/providers/blade.php'];
@@ -1374,7 +1376,11 @@ static function (string $type): array {
13741376
},
13751377
);
13761378
$mock->method('getServicesByTag')
1377-
->willReturn([]);
1379+
->willReturnCallback(
1380+
static fn (string $tag): array => $tag === 'phpat.test'
1381+
? [new RegisteredArchitectureTest()]
1382+
: [],
1383+
);
13781384
return $mock;
13791385
}
13801386

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PhpatProvider;
4+
5+
use PHPat\Selector\Selector;
6+
use PHPat\Test\Attributes\TestRule;
7+
use PHPat\Test\Builder\Rule;
8+
use PHPat\Test\PHPat;
9+
10+
// Registered via the "phpat.test" service tag (see DeadCodeRuleTest container mock).
11+
// phpat invokes its public test* / #[TestRule] methods, so they are not dead.
12+
class RegisteredArchitectureTest
13+
{
14+
15+
public function testSrcShouldNotDependOnTests(): Rule
16+
{
17+
return PHPat::rule()
18+
->classes(Selector::AllOf())
19+
->shouldNotDependOn()
20+
->classes(Selector::AllOf());
21+
}
22+
23+
#[TestRule]
24+
public function customNamedRule(): Rule
25+
{
26+
return PHPat::rule()
27+
->classes(Selector::AllOf())
28+
->shouldNotDependOn()
29+
->classes(Selector::AllOf());
30+
}
31+
32+
public function unusedHelper(): void // error: Unused PhpatProvider\RegisteredArchitectureTest::unusedHelper
33+
{
34+
}
35+
36+
}
37+
38+
// Not registered as a phpat test → its test method really is dead.
39+
class UnregisteredArchitectureTest
40+
{
41+
42+
public function testOrphanRule(): Rule // error: Unused PhpatProvider\UnregisteredArchitectureTest::testOrphanRule
43+
{
44+
return PHPat::rule()
45+
->classes(Selector::AllOf())
46+
->shouldNotDependOn()
47+
->classes(Selector::AllOf());
48+
}
49+
50+
}

0 commit comments

Comments
 (0)