diff --git a/src/Event/CollectTestResultSubscriber.php b/src/Event/CollectTestResultSubscriber.php index d40564d..697cab1 100644 --- a/src/Event/CollectTestResultSubscriber.php +++ b/src/Event/CollectTestResultSubscriber.php @@ -7,8 +7,8 @@ use Boundwize\Pyrameter\Detection\TestUsageScanner; use Boundwize\Pyrameter\TestCollector; use Boundwize\Pyrameter\TestKind; -use Boundwize\Pyrameter\TestRecord; 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 792ed94..77494f3 100644 --- a/src/Event/PrintReportSubscriber.php +++ b/src/Event/PrintReportSubscriber.php @@ -4,7 +4,6 @@ namespace Boundwize\Pyrameter\Event; -use Boundwize\Pyrameter\PyramidSummary; use Boundwize\Pyrameter\Report\PyramidReporter; use Boundwize\Pyrameter\Report\SuiteShapeResolver; use Boundwize\Pyrameter\Target\TargetEvaluator; @@ -38,7 +37,7 @@ public function __construct( public function notify(ExecutionFinished $event): void { - $pyramidSummary = PyramidSummary::fromRecords($this->testCollector->all()); + $pyramidSummary = $this->testCollector->summary(); $targetEvaluation = $this->targetEvaluator->evaluate($pyramidSummary); $suiteShape = $this->suiteShapeResolver->resolve($pyramidSummary, $targetEvaluation); diff --git a/src/Report/PyramidReporter.php b/src/Report/PyramidReporter.php index 70c659d..e81825e 100644 --- a/src/Report/PyramidReporter.php +++ b/src/Report/PyramidReporter.php @@ -4,9 +4,9 @@ namespace Boundwize\Pyrameter\Report; -use Boundwize\Pyrameter\PyramidSummary; use Boundwize\Pyrameter\Target\TargetEvaluation; use Boundwize\Pyrameter\TestKind; +use Boundwize\Pyrameter\ValueObject\PyramidSummary; use function array_fill; use function array_reverse; diff --git a/src/Report/SuiteShapeResolver.php b/src/Report/SuiteShapeResolver.php index 65578e7..a62dd2c 100644 --- a/src/Report/SuiteShapeResolver.php +++ b/src/Report/SuiteShapeResolver.php @@ -4,9 +4,9 @@ namespace Boundwize\Pyrameter\Report; -use Boundwize\Pyrameter\PyramidSummary; use Boundwize\Pyrameter\Target\TargetEvaluation; use Boundwize\Pyrameter\TestKind; +use Boundwize\Pyrameter\ValueObject\PyramidSummary; final readonly class SuiteShapeResolver { diff --git a/src/Target/TargetEvaluator.php b/src/Target/TargetEvaluator.php index 1f89cea..f8438a7 100644 --- a/src/Target/TargetEvaluator.php +++ b/src/Target/TargetEvaluator.php @@ -4,8 +4,8 @@ namespace Boundwize\Pyrameter\Target; -use Boundwize\Pyrameter\PyramidSummary; use Boundwize\Pyrameter\TestKind; +use Boundwize\Pyrameter\ValueObject\PyramidSummary; final readonly class TargetEvaluator { diff --git a/src/TestCollector.php b/src/TestCollector.php index 601f4b4..f48f7a0 100644 --- a/src/TestCollector.php +++ b/src/TestCollector.php @@ -4,16 +4,44 @@ namespace Boundwize\Pyrameter; -use function array_values; +use Boundwize\Pyrameter\ValueObject\PyramidSummary; +use Boundwize\Pyrameter\ValueObject\TestRecord; + +use function explode; final class TestCollector { - /** @var array */ - private array $records = []; + /** @var array */ + private array $kindByTestId = []; + + /** @var array */ + private array $counts = [ + 'unit' => 0, + 'functional' => 0, + 'integration' => 0, + 'e2e' => 0, + ]; public function add(TestRecord $testRecord): void { - $this->records[$testRecord->id()] = $testRecord; + $testId = $testRecord->id(); + $existingKind = $this->kindByTestId[$testId] ?? null; + + if ($existingKind === $testRecord->kind) { + return; + } + + if ($existingKind instanceof TestKind) { + --$this->counts[$existingKind->value]; + } + + $this->kindByTestId[$testId] = $testRecord->kind; + ++$this->counts[$testRecord->kind->value]; + } + + public function summary(): PyramidSummary + { + return PyramidSummary::fromCounts($this->counts); } /** @@ -21,6 +49,13 @@ public function add(TestRecord $testRecord): void */ public function all(): array { - return array_values($this->records); + $records = []; + + foreach ($this->kindByTestId as $testId => $testKind) { + [$testClassName, $testMethodName] = explode('::', $testId, 2); + $records[] = new TestRecord($testClassName, $testMethodName, [], $testKind); + } + + return $records; } } diff --git a/src/PyramidSummary.php b/src/ValueObject/PyramidSummary.php similarity index 72% rename from src/PyramidSummary.php rename to src/ValueObject/PyramidSummary.php index 8d702ba..93373a8 100644 --- a/src/PyramidSummary.php +++ b/src/ValueObject/PyramidSummary.php @@ -2,10 +2,12 @@ declare(strict_types=1); -namespace Boundwize\Pyrameter; +namespace Boundwize\Pyrameter\ValueObject; + +use Boundwize\Pyrameter\TestKind; use function array_keys; -use function count; +use function array_sum; use function intdiv; use function usort; @@ -27,18 +29,22 @@ public function __construct( */ public static function fromRecords(array $records): self { - $counts = [ - TestKind::Unit->value => 0, - TestKind::Functional->value => 0, - TestKind::Integration->value => 0, - TestKind::E2E->value => 0, - ]; + $counts = self::emptyCounts(); foreach ($records as $record) { ++$counts[$record->kind->value]; } - $total = count($records); + return self::fromCounts($counts); + } + + /** + * @param array $counts + */ + public static function fromCounts(array $counts): self + { + $counts = self::normalizeCounts($counts); + $total = array_sum($counts); $percentages = self::percentagesFromCounts($counts, $total); return new self($total, $counts, $percentages); @@ -54,6 +60,34 @@ public function percentage(TestKind $testKind): float return $this->percentages[$testKind->value] ?? 0.0; } + /** + * @return array + */ + private static function emptyCounts(): array + { + return [ + TestKind::Unit->value => 0, + TestKind::Functional->value => 0, + TestKind::Integration->value => 0, + TestKind::E2E->value => 0, + ]; + } + + /** + * @param array $counts + * @return array + */ + private static function normalizeCounts(array $counts): array + { + $normalizedCounts = self::emptyCounts(); + + foreach (TestKind::ordered() as $testKind) { + $normalizedCounts[$testKind->value] = $counts[$testKind->value] ?? 0; + } + + return $normalizedCounts; + } + /** * @param array $counts * @return array diff --git a/src/TestRecord.php b/src/ValueObject/TestRecord.php similarity index 85% rename from src/TestRecord.php rename to src/ValueObject/TestRecord.php index 107fa0d..daf9d6d 100644 --- a/src/TestRecord.php +++ b/src/ValueObject/TestRecord.php @@ -2,7 +2,9 @@ declare(strict_types=1); -namespace Boundwize\Pyrameter; +namespace Boundwize\Pyrameter\ValueObject; + +use Boundwize\Pyrameter\TestKind; final readonly class TestRecord { diff --git a/tests/Event/PrintReportSubscriberTest.php b/tests/Event/PrintReportSubscriberTest.php index 0021925..dec58bb 100644 --- a/tests/Event/PrintReportSubscriberTest.php +++ b/tests/Event/PrintReportSubscriberTest.php @@ -9,7 +9,7 @@ use Boundwize\Pyrameter\Report\PyramidReporter; use Boundwize\Pyrameter\TestCollector; use Boundwize\Pyrameter\TestKind; -use Boundwize\Pyrameter\TestRecord; +use Boundwize\Pyrameter\ValueObject\TestRecord; use PHPUnit\Event\Telemetry\Duration; use PHPUnit\Event\Telemetry\GarbageCollectorStatus; use PHPUnit\Event\Telemetry\HRTime; diff --git a/tests/PyramidSummaryTest.php b/tests/PyramidSummaryTest.php index a96235c..37cfe57 100644 --- a/tests/PyramidSummaryTest.php +++ b/tests/PyramidSummaryTest.php @@ -4,9 +4,9 @@ namespace Boundwize\Pyrameter\Tests; -use Boundwize\Pyrameter\PyramidSummary; use Boundwize\Pyrameter\TestKind; -use Boundwize\Pyrameter\TestRecord; +use Boundwize\Pyrameter\ValueObject\PyramidSummary; +use Boundwize\Pyrameter\ValueObject\TestRecord; use PHPUnit\Framework\TestCase; use function array_sum; diff --git a/tests/Report/PyramidReporterTest.php b/tests/Report/PyramidReporterTest.php index 65b0ffa..b53ea6a 100644 --- a/tests/Report/PyramidReporterTest.php +++ b/tests/Report/PyramidReporterTest.php @@ -5,12 +5,12 @@ namespace Boundwize\Pyrameter\Tests\Report; use Boundwize\Pyrameter\Config\PyrameterConfig; -use Boundwize\Pyrameter\PyramidSummary; use Boundwize\Pyrameter\Report\PyramidReporter; use Boundwize\Pyrameter\Report\SuiteShapeResolver; use Boundwize\Pyrameter\Target\TargetEvaluator; use Boundwize\Pyrameter\TestKind; -use Boundwize\Pyrameter\TestRecord; +use Boundwize\Pyrameter\ValueObject\PyramidSummary; +use Boundwize\Pyrameter\ValueObject\TestRecord; use PHPUnit\Framework\TestCase; use function strpos; diff --git a/tests/Report/SuiteShapeResolverTest.php b/tests/Report/SuiteShapeResolverTest.php index 8b8906e..984c8d0 100644 --- a/tests/Report/SuiteShapeResolverTest.php +++ b/tests/Report/SuiteShapeResolverTest.php @@ -5,12 +5,12 @@ namespace Boundwize\Pyrameter\Tests\Report; use Boundwize\Pyrameter\Config\PyrameterConfig; -use Boundwize\Pyrameter\PyramidSummary; use Boundwize\Pyrameter\Report\SuiteShape; use Boundwize\Pyrameter\Report\SuiteShapeResolver; use Boundwize\Pyrameter\Target\TargetEvaluator; use Boundwize\Pyrameter\TestKind; -use Boundwize\Pyrameter\TestRecord; +use Boundwize\Pyrameter\ValueObject\PyramidSummary; +use Boundwize\Pyrameter\ValueObject\TestRecord; use PHPUnit\Framework\TestCase; final class SuiteShapeResolverTest extends TestCase diff --git a/tests/Target/TargetEvaluationTest.php b/tests/Target/TargetEvaluationTest.php index ff33fbb..1e3acb9 100644 --- a/tests/Target/TargetEvaluationTest.php +++ b/tests/Target/TargetEvaluationTest.php @@ -4,11 +4,11 @@ namespace Boundwize\Pyrameter\Tests\Target; -use Boundwize\Pyrameter\PyramidSummary; use Boundwize\Pyrameter\Target\TargetEvaluator; use Boundwize\Pyrameter\Target\TargetStatus; use Boundwize\Pyrameter\TestKind; -use Boundwize\Pyrameter\TestRecord; +use Boundwize\Pyrameter\ValueObject\PyramidSummary; +use Boundwize\Pyrameter\ValueObject\TestRecord; use PHPUnit\Framework\TestCase; final class TargetEvaluationTest extends TestCase diff --git a/tests/TestCollectorTest.php b/tests/TestCollectorTest.php index 2a1a73f..c739334 100644 --- a/tests/TestCollectorTest.php +++ b/tests/TestCollectorTest.php @@ -6,7 +6,7 @@ use Boundwize\Pyrameter\TestCollector; use Boundwize\Pyrameter\TestKind; -use Boundwize\Pyrameter\TestRecord; +use Boundwize\Pyrameter\ValueObject\TestRecord; use PHPUnit\Framework\TestCase; final class TestCollectorTest extends TestCase @@ -19,6 +19,8 @@ public function testItDeduplicatesIdenticalRecords(): void $testCollector->add(new TestRecord('PriceTest', 'testItCalculatesPrice', [], TestKind::Unit)); $this->assertCount(1, $testCollector->all()); + $this->assertSame(1, $testCollector->summary()->total); + $this->assertSame(1, $testCollector->summary()->count(TestKind::Unit)); } public function testItKeepsSeparateDataProviderExecutions(): void @@ -39,5 +41,22 @@ public function testItKeepsSeparateDataProviderExecutions(): void )); $this->assertCount(2, $testCollector->all()); + $this->assertSame(2, $testCollector->summary()->total); + $this->assertSame(2, $testCollector->summary()->count(TestKind::Unit)); + } + + public function testItReplacesCountsWhenTheSameTestIdChangesKind(): void + { + $testCollector = new TestCollector(); + + $testCollector->add(new TestRecord('PriceTest', 'testItCalculatesPrice', [], TestKind::Unit)); + $testCollector->add(new TestRecord('PriceTest', 'testItCalculatesPrice', [], TestKind::Integration)); + + $summary = $testCollector->summary(); + + $this->assertCount(1, $testCollector->all()); + $this->assertSame(1, $summary->total); + $this->assertSame(0, $summary->count(TestKind::Unit)); + $this->assertSame(1, $summary->count(TestKind::Integration)); } }