From 904990a9bf74cc938eba90aea13eff60e308fff2 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 20 Jun 2026 02:36:57 +0700 Subject: [PATCH 1/3] [internal] move TestCollector and UsageClassifier to under Analysis --- src/{ => Analysis}/TestCollector.php | 3 ++- src/{ => Analysis}/UsageClassifier.php | 3 ++- src/Event/CollectTestResultSubscriber.php | 4 ++-- src/Event/PrintReportSubscriber.php | 2 +- src/Extension.php | 2 ++ tests/{ => Analysis}/TestCollectorTest.php | 4 ++-- tests/{ => Analysis}/UsageClassifierTest.php | 4 ++-- tests/Config/PyrameterConfigTest.php | 2 +- tests/Event/CollectTestResultSubscriberTest.php | 4 ++-- tests/Event/PrintReportSubscriberTest.php | 2 +- tests/UsageClassificationTest.php | 2 +- 11 files changed, 18 insertions(+), 14 deletions(-) rename src/{ => Analysis}/TestCollector.php (95%) rename src/{ => Analysis}/UsageClassifier.php (98%) rename tests/{ => Analysis}/TestCollectorTest.php (95%) rename tests/{ => Analysis}/UsageClassifierTest.php (98%) diff --git a/src/TestCollector.php b/src/Analysis/TestCollector.php similarity index 95% rename from src/TestCollector.php rename to src/Analysis/TestCollector.php index f48f7a0..eccf943 100644 --- a/src/TestCollector.php +++ b/src/Analysis/TestCollector.php @@ -2,8 +2,9 @@ declare(strict_types=1); -namespace Boundwize\Pyrameter; +namespace Boundwize\Pyrameter\Analysis; +use Boundwize\Pyrameter\TestKind; use Boundwize\Pyrameter\ValueObject\PyramidSummary; use Boundwize\Pyrameter\ValueObject\TestRecord; diff --git a/src/UsageClassifier.php b/src/Analysis/UsageClassifier.php similarity index 98% rename from src/UsageClassifier.php rename to src/Analysis/UsageClassifier.php index 59833e3..a195523 100644 --- a/src/UsageClassifier.php +++ b/src/Analysis/UsageClassifier.php @@ -2,10 +2,11 @@ declare(strict_types=1); -namespace Boundwize\Pyrameter; +namespace Boundwize\Pyrameter\Analysis; use Boundwize\Pyrameter\Rule\UsageRule; use Boundwize\Pyrameter\Rule\UsageType; +use Boundwize\Pyrameter\TestKind; use function array_keys; use function ltrim; diff --git a/src/Event/CollectTestResultSubscriber.php b/src/Event/CollectTestResultSubscriber.php index 697cab1..7a41f76 100644 --- a/src/Event/CollectTestResultSubscriber.php +++ b/src/Event/CollectTestResultSubscriber.php @@ -4,10 +4,10 @@ namespace Boundwize\Pyrameter\Event; +use Boundwize\Pyrameter\Analysis\TestCollector; +use Boundwize\Pyrameter\Analysis\UsageClassifier; use Boundwize\Pyrameter\Detection\TestUsageScanner; -use Boundwize\Pyrameter\TestCollector; use Boundwize\Pyrameter\TestKind; -use Boundwize\Pyrameter\UsageClassifier; use Boundwize\Pyrameter\ValueObject\TestRecord; use PHPUnit\Event\Test\Finished; use PHPUnit\Event\Test\FinishedSubscriber; diff --git a/src/Event/PrintReportSubscriber.php b/src/Event/PrintReportSubscriber.php index 77494f3..7c4e16c 100644 --- a/src/Event/PrintReportSubscriber.php +++ b/src/Event/PrintReportSubscriber.php @@ -4,10 +4,10 @@ namespace Boundwize\Pyrameter\Event; +use Boundwize\Pyrameter\Analysis\TestCollector; use Boundwize\Pyrameter\Report\PyramidReporter; use Boundwize\Pyrameter\Report\SuiteShapeResolver; use Boundwize\Pyrameter\Target\TargetEvaluator; -use Boundwize\Pyrameter\TestCollector; use Closure; use PHPUnit\Event\TestRunner\ExecutionFinished; use PHPUnit\Event\TestRunner\ExecutionFinishedSubscriber; diff --git a/src/Extension.php b/src/Extension.php index 093e442..b85fd36 100644 --- a/src/Extension.php +++ b/src/Extension.php @@ -4,6 +4,8 @@ namespace Boundwize\Pyrameter; +use Boundwize\Pyrameter\Analysis\TestCollector; +use Boundwize\Pyrameter\Analysis\UsageClassifier; use Boundwize\Pyrameter\Config\PyrameterConfigLoader; use Boundwize\Pyrameter\Detection\TestUsageScanner; use Boundwize\Pyrameter\Event\CollectTestResultSubscriber; diff --git a/tests/TestCollectorTest.php b/tests/Analysis/TestCollectorTest.php similarity index 95% rename from tests/TestCollectorTest.php rename to tests/Analysis/TestCollectorTest.php index c739334..7f9910c 100644 --- a/tests/TestCollectorTest.php +++ b/tests/Analysis/TestCollectorTest.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace Boundwize\Pyrameter\Tests; +namespace Boundwize\Pyrameter\Tests\Analysis; -use Boundwize\Pyrameter\TestCollector; +use Boundwize\Pyrameter\Analysis\TestCollector; use Boundwize\Pyrameter\TestKind; use Boundwize\Pyrameter\ValueObject\TestRecord; use PHPUnit\Framework\TestCase; diff --git a/tests/UsageClassifierTest.php b/tests/Analysis/UsageClassifierTest.php similarity index 98% rename from tests/UsageClassifierTest.php rename to tests/Analysis/UsageClassifierTest.php index cbff8a5..6f6a714 100644 --- a/tests/UsageClassifierTest.php +++ b/tests/Analysis/UsageClassifierTest.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace Boundwize\Pyrameter\Tests; +namespace Boundwize\Pyrameter\Tests\Analysis; +use Boundwize\Pyrameter\Analysis\UsageClassifier; use Boundwize\Pyrameter\Rule\UsageRule; use Boundwize\Pyrameter\Rule\UsageType; use Boundwize\Pyrameter\TestKind; -use Boundwize\Pyrameter\UsageClassifier; use PHPUnit\Framework\TestCase; final class UsageClassifierTest extends TestCase diff --git a/tests/Config/PyrameterConfigTest.php b/tests/Config/PyrameterConfigTest.php index 2132059..7d80d47 100644 --- a/tests/Config/PyrameterConfigTest.php +++ b/tests/Config/PyrameterConfigTest.php @@ -4,9 +4,9 @@ namespace Boundwize\Pyrameter\Tests\Config; +use Boundwize\Pyrameter\Analysis\UsageClassifier; use Boundwize\Pyrameter\Config\PyrameterConfig; use Boundwize\Pyrameter\TestKind; -use Boundwize\Pyrameter\UsageClassifier; use InvalidArgumentException; use PDO; use PHPUnit\Framework\TestCase; diff --git a/tests/Event/CollectTestResultSubscriberTest.php b/tests/Event/CollectTestResultSubscriberTest.php index 4fc8b66..e48f822 100644 --- a/tests/Event/CollectTestResultSubscriberTest.php +++ b/tests/Event/CollectTestResultSubscriberTest.php @@ -4,14 +4,14 @@ namespace Boundwize\Pyrameter\Tests\Event; +use Boundwize\Pyrameter\Analysis\TestCollector; +use Boundwize\Pyrameter\Analysis\UsageClassifier; use Boundwize\Pyrameter\Config\PyrameterConfig; use Boundwize\Pyrameter\Detection\TestUsageScanner; use Boundwize\Pyrameter\Event\CollectTestResultSubscriber; -use Boundwize\Pyrameter\TestCollector; use Boundwize\Pyrameter\TestKind; use Boundwize\Pyrameter\Tests\Fixtures\SimpleUnitFixture; use Boundwize\Pyrameter\Tests\Fixtures\TelemetryInfoFactory; -use Boundwize\Pyrameter\UsageClassifier; use PHPUnit\Event\Code\Phpt; use PHPUnit\Event\Code\TestDox; use PHPUnit\Event\Code\TestMethod; diff --git a/tests/Event/PrintReportSubscriberTest.php b/tests/Event/PrintReportSubscriberTest.php index 11a445f..79cf1d2 100644 --- a/tests/Event/PrintReportSubscriberTest.php +++ b/tests/Event/PrintReportSubscriberTest.php @@ -4,10 +4,10 @@ namespace Boundwize\Pyrameter\Tests\Event; +use Boundwize\Pyrameter\Analysis\TestCollector; use Boundwize\Pyrameter\Config\PyrameterConfig; use Boundwize\Pyrameter\Event\PrintReportSubscriber; use Boundwize\Pyrameter\Report\PyramidReporter; -use Boundwize\Pyrameter\TestCollector; use Boundwize\Pyrameter\TestKind; use Boundwize\Pyrameter\Tests\Fixtures\TelemetryInfoFactory; use Boundwize\Pyrameter\ValueObject\TestRecord; diff --git a/tests/UsageClassificationTest.php b/tests/UsageClassificationTest.php index d77cc8b..cfbfe00 100644 --- a/tests/UsageClassificationTest.php +++ b/tests/UsageClassificationTest.php @@ -4,6 +4,7 @@ namespace Boundwize\Pyrameter\Tests; +use Boundwize\Pyrameter\Analysis\UsageClassifier; use Boundwize\Pyrameter\Config\PyrameterConfig; use Boundwize\Pyrameter\Detection\ConsumedUsageExtractor; use Boundwize\Pyrameter\Detection\TestUsageScanner; @@ -23,7 +24,6 @@ use Boundwize\Pyrameter\Tests\Fixtures\SimpleUnitFixture; use Boundwize\Pyrameter\Tests\Fixtures\SymfonyFunctionalFixture; use Boundwize\Pyrameter\Tests\Fixtures\WebDriverE2EFixture; -use Boundwize\Pyrameter\UsageClassifier; use PhpParser\ParserFactory; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; From 7cba4c07324a7a66fbcc47fc5dbe169bbce6b75d Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 20 Jun 2026 02:38:17 +0700 Subject: [PATCH 2/3] move PyramidSummaryTest under ValueObject --- tests/{ => ValueObject}/PyramidSummaryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/{ => ValueObject}/PyramidSummaryTest.php (97%) diff --git a/tests/PyramidSummaryTest.php b/tests/ValueObject/PyramidSummaryTest.php similarity index 97% rename from tests/PyramidSummaryTest.php rename to tests/ValueObject/PyramidSummaryTest.php index 37cfe57..9f02d38 100644 --- a/tests/PyramidSummaryTest.php +++ b/tests/ValueObject/PyramidSummaryTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Boundwize\Pyrameter\Tests; +namespace Boundwize\Pyrameter\Tests\ValueObject; use Boundwize\Pyrameter\TestKind; use Boundwize\Pyrameter\ValueObject\PyramidSummary; From 6b5006e95c1391571c016b3f8d2b7642ffc985e6 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 20 Jun 2026 02:45:53 +0700 Subject: [PATCH 3/3] move along tests --- tests/Analysis/UsageClassifierTest.php | 104 +++++++++++++++ tests/Detection/TestUsageScannerTest.php | 18 +++ .../UsageClassificationTest.php | 121 +----------------- 3 files changed, 123 insertions(+), 120 deletions(-) rename tests/{ => Detection}/UsageClassificationTest.php (55%) diff --git a/tests/Analysis/UsageClassifierTest.php b/tests/Analysis/UsageClassifierTest.php index 6f6a714..87d6217 100644 --- a/tests/Analysis/UsageClassifierTest.php +++ b/tests/Analysis/UsageClassifierTest.php @@ -5,13 +5,117 @@ namespace Boundwize\Pyrameter\Tests\Analysis; use Boundwize\Pyrameter\Analysis\UsageClassifier; +use Boundwize\Pyrameter\Config\PyrameterConfig; use Boundwize\Pyrameter\Rule\UsageRule; use Boundwize\Pyrameter\Rule\UsageType; use Boundwize\Pyrameter\TestKind; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; final class UsageClassifierTest extends TestCase { + /** + * @param non-empty-string $className + */ + #[DataProvider('phpRedisGlobalClassCases')] + public function testDefaultRulesClassifyPhpRedisGlobalClassesAsIntegration(string $className): void + { + $pyrameterConfig = PyrameterConfig::defaults(); + $usageClassifier = new UsageClassifier($pyrameterConfig->usageRules()); + + $this->assertSame(TestKind::Integration, $usageClassifier->classify([$className])); + } + + /** + * @return iterable + */ + public static function phpRedisGlobalClassCases(): iterable + { + yield 'Redis client' => ['Redis']; + yield 'Redis cluster client' => ['RedisCluster']; + yield 'Redis sentinel client' => ['RedisSentinel']; + } + + /** + * @param non-empty-string $functionName + */ + #[DataProvider('fileOperationFunctionCases')] + public function testDefaultRulesClassifyFileOperationFunctionsAsIntegration(string $functionName): void + { + $pyrameterConfig = PyrameterConfig::defaults(); + $usageClassifier = new UsageClassifier($pyrameterConfig->usageRules()); + + $this->assertSame(TestKind::Integration, $usageClassifier->classify(['function:' . $functionName])); + } + + /** + * @return iterable + */ + public static function fileOperationFunctionCases(): iterable + { + yield 'file_get_contents' => ['file_get_contents']; + yield 'file_put_contents' => ['file_put_contents']; + yield 'fopen' => ['fopen']; + yield 'fread' => ['fread']; + yield 'fwrite' => ['fwrite']; + yield 'fgets' => ['fgets']; + yield 'fgetc' => ['fgetc']; + yield 'fclose' => ['fclose']; + yield 'feof' => ['feof']; + yield 'rewind' => ['rewind']; + yield 'fseek' => ['fseek']; + yield 'ftell' => ['ftell']; + yield 'fflush' => ['fflush']; + yield 'ftruncate' => ['ftruncate']; + yield 'file_exists' => ['file_exists']; + yield 'is_file' => ['is_file']; + yield 'is_dir' => ['is_dir']; + yield 'is_readable' => ['is_readable']; + yield 'is_writable' => ['is_writable']; + yield 'is_executable' => ['is_executable']; + yield 'filesize' => ['filesize']; + yield 'filemtime' => ['filemtime']; + yield 'filectime' => ['filectime']; + yield 'fileatime' => ['fileatime']; + yield 'fileperms' => ['fileperms']; + yield 'fileowner' => ['fileowner']; + yield 'filegroup' => ['filegroup']; + yield 'filetype' => ['filetype']; + yield 'stat' => ['stat']; + yield 'lstat' => ['lstat']; + yield 'touch' => ['touch']; + yield 'copy' => ['copy']; + yield 'rename' => ['rename']; + yield 'unlink' => ['unlink']; + yield 'mkdir' => ['mkdir']; + yield 'rmdir' => ['rmdir']; + yield 'opendir' => ['opendir']; + yield 'readdir' => ['readdir']; + yield 'closedir' => ['closedir']; + yield 'rewinddir' => ['rewinddir']; + yield 'scandir' => ['scandir']; + yield 'glob' => ['glob']; + yield 'chdir' => ['chdir']; + yield 'getcwd' => ['getcwd']; + yield 'realpath' => ['realpath']; + yield 'chmod' => ['chmod']; + yield 'chown' => ['chown']; + yield 'chgrp' => ['chgrp']; + yield 'umask' => ['umask']; + yield 'link' => ['link']; + yield 'symlink' => ['symlink']; + yield 'readlink' => ['readlink']; + yield 'is_link' => ['is_link']; + yield 'tmpfile' => ['tmpfile']; + yield 'tempnam' => ['tempnam']; + yield 'flock' => ['flock']; + yield 'is_uploaded_file' => ['is_uploaded_file']; + yield 'move_uploaded_file' => ['move_uploaded_file']; + yield 'fgetcsv' => ['fgetcsv']; + yield 'fputcsv' => ['fputcsv']; + yield 'parse_ini_file' => ['parse_ini_file']; + } + public function testNamespaceRulesMatchOnlyConfiguredPrefixCaseInsensitively(): void { $usageClassifier = new UsageClassifier([ diff --git a/tests/Detection/TestUsageScannerTest.php b/tests/Detection/TestUsageScannerTest.php index 6b9b4fa..5215c95 100644 --- a/tests/Detection/TestUsageScannerTest.php +++ b/tests/Detection/TestUsageScannerTest.php @@ -5,6 +5,7 @@ namespace Boundwize\Pyrameter\Tests\Detection; use Boundwize\Pyrameter\Detection\TestUsageScanner; +use Boundwize\Pyrameter\Tests\Fixtures\MockedHeavyFixture; use PHPUnit\Framework\TestCase; use ReflectionClass; use stdClass; @@ -21,6 +22,23 @@ final class TestUsageScannerTest extends TestCase { + public function testItRemovesMockTargetsFromConsumedUsages(): void + { + $scanResult = (new TestUsageScanner())->scan(MockedHeavyFixture::class); + + $this->assertTrue($scanResult->inspectable); + $this->assertNotContains('class:PDO', $scanResult->consumedUsages); + } + + public function testItReturnsNoConsumedUsagesForAnUninspectableClass(): void + { + $scanResult = (new TestUsageScanner())->scan('Boundwize\Pyrameter\Tests\Fixtures\MissingFixture'); + + $this->assertFalse($scanResult->inspectable); + $this->assertSame([], $scanResult->consumedUsages); + $this->assertNotNull($scanResult->errorMessage); + } + public function testItReportsUninspectableResultForInternalClassesWithoutSourceFiles(): void { $scanResult = (new TestUsageScanner())->scan(stdClass::class); diff --git a/tests/UsageClassificationTest.php b/tests/Detection/UsageClassificationTest.php similarity index 55% rename from tests/UsageClassificationTest.php rename to tests/Detection/UsageClassificationTest.php index cfbfe00..cb8a37a 100644 --- a/tests/UsageClassificationTest.php +++ b/tests/Detection/UsageClassificationTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Boundwize\Pyrameter\Tests; +namespace Boundwize\Pyrameter\Tests\Detection; use Boundwize\Pyrameter\Analysis\UsageClassifier; use Boundwize\Pyrameter\Config\PyrameterConfig; @@ -78,125 +78,6 @@ public static function classificationCases(): iterable yield 'integration plus e2e chooses e2e' => [IntegrationAndE2EFixture::class, TestKind::E2E]; } - public function testMockTargetsAreRemovedFromConsumedClasses(): void - { - $scanResult = (new TestUsageScanner())->scan(MockedHeavyFixture::class); - - $this->assertTrue($scanResult->inspectable); - $this->assertNotContains('class:PDO', $scanResult->consumedUsages); - } - - /** - * @param non-empty-string $className - */ - #[DataProvider('phpRedisGlobalClassCases')] - public function testDefaultRulesClassifyPhpRedisGlobalClassesAsIntegration(string $className): void - { - $pyrameterConfig = PyrameterConfig::defaults(); - $usageClassifier = new UsageClassifier($pyrameterConfig->usageRules()); - - $this->assertSame(TestKind::Integration, $usageClassifier->classify([$className])); - } - - /** - * @return iterable - */ - public static function phpRedisGlobalClassCases(): iterable - { - yield 'Redis client' => ['Redis']; - yield 'Redis cluster client' => ['RedisCluster']; - yield 'Redis sentinel client' => ['RedisSentinel']; - } - - /** - * @param non-empty-string $functionName - */ - #[DataProvider('fileOperationFunctionCases')] - public function testDefaultRulesClassifyFileOperationFunctionsAsIntegration(string $functionName): void - { - $pyrameterConfig = PyrameterConfig::defaults(); - $usageClassifier = new UsageClassifier($pyrameterConfig->usageRules()); - - $this->assertSame(TestKind::Integration, $usageClassifier->classify(['function:' . $functionName])); - } - - /** - * @return iterable - */ - public static function fileOperationFunctionCases(): iterable - { - yield 'file_get_contents' => ['file_get_contents']; - yield 'file_put_contents' => ['file_put_contents']; - yield 'fopen' => ['fopen']; - yield 'fread' => ['fread']; - yield 'fwrite' => ['fwrite']; - yield 'fgets' => ['fgets']; - yield 'fgetc' => ['fgetc']; - yield 'fclose' => ['fclose']; - yield 'feof' => ['feof']; - yield 'rewind' => ['rewind']; - yield 'fseek' => ['fseek']; - yield 'ftell' => ['ftell']; - yield 'fflush' => ['fflush']; - yield 'ftruncate' => ['ftruncate']; - yield 'file_exists' => ['file_exists']; - yield 'is_file' => ['is_file']; - yield 'is_dir' => ['is_dir']; - yield 'is_readable' => ['is_readable']; - yield 'is_writable' => ['is_writable']; - yield 'is_executable' => ['is_executable']; - yield 'filesize' => ['filesize']; - yield 'filemtime' => ['filemtime']; - yield 'filectime' => ['filectime']; - yield 'fileatime' => ['fileatime']; - yield 'fileperms' => ['fileperms']; - yield 'fileowner' => ['fileowner']; - yield 'filegroup' => ['filegroup']; - yield 'filetype' => ['filetype']; - yield 'stat' => ['stat']; - yield 'lstat' => ['lstat']; - yield 'touch' => ['touch']; - yield 'copy' => ['copy']; - yield 'rename' => ['rename']; - yield 'unlink' => ['unlink']; - yield 'mkdir' => ['mkdir']; - yield 'rmdir' => ['rmdir']; - yield 'opendir' => ['opendir']; - yield 'readdir' => ['readdir']; - yield 'closedir' => ['closedir']; - yield 'rewinddir' => ['rewinddir']; - yield 'scandir' => ['scandir']; - yield 'glob' => ['glob']; - yield 'chdir' => ['chdir']; - yield 'getcwd' => ['getcwd']; - yield 'realpath' => ['realpath']; - yield 'chmod' => ['chmod']; - yield 'chown' => ['chown']; - yield 'chgrp' => ['chgrp']; - yield 'umask' => ['umask']; - yield 'link' => ['link']; - yield 'symlink' => ['symlink']; - yield 'readlink' => ['readlink']; - yield 'is_link' => ['is_link']; - yield 'tmpfile' => ['tmpfile']; - yield 'tempnam' => ['tempnam']; - yield 'flock' => ['flock']; - yield 'is_uploaded_file' => ['is_uploaded_file']; - yield 'move_uploaded_file' => ['move_uploaded_file']; - yield 'fgetcsv' => ['fgetcsv']; - yield 'fputcsv' => ['fputcsv']; - yield 'parse_ini_file' => ['parse_ini_file']; - } - - public function testUninspectableTestHasNoConsumedClasses(): void - { - $scanResult = (new TestUsageScanner())->scan('Boundwize\Pyrameter\Tests\Fixtures\MissingFixture'); - - $this->assertFalse($scanResult->inspectable); - $this->assertSame([], $scanResult->consumedUsages); - $this->assertNotNull($scanResult->errorMessage); - } - public function testClassNamedLikeFileOperationFunctionStaysUnit(): void { $parser = (new ParserFactory())->createForNewestSupportedVersion();