From 0a6efe93098864540bfaf35fe79c7c04b3ab764e Mon Sep 17 00:00:00 2001 From: Sebastian Bergmann Date: Wed, 22 Apr 2026 14:31:27 +0200 Subject: [PATCH 1/6] Initial work on filtering code coverage by test size --- src/Data/ProcessedClassType.php | 5 + src/Data/ProcessedFunctionType.php | 5 + src/Data/ProcessedMethodType.php | 5 + src/Data/ProcessedTraitType.php | 5 + src/Node/AbstractNode.php | 140 ++++++ src/Node/Directory.php | 395 ++++++++++++++- src/Node/File.php | 454 +++++++++++++++++- src/Report/Html/Facade.php | 1 + src/Report/Html/Renderer.php | 13 + src/Report/Html/Renderer/Directory.php | 23 + src/Report/Html/Renderer/File.php | 23 + .../Renderer/Template/directory.html.dist | 11 + .../Template/directory_branch.html.dist | 11 + .../Template/directory_item.html.dist | 2 +- .../Template/directory_item_branch.html.dist | 2 +- .../Html/Renderer/Template/file.html.dist | 9 + .../Renderer/Template/file_branch.html.dist | 9 + .../Renderer/Template/file_item.html.dist | 2 +- .../Template/file_item_branch.html.dist | 2 +- .../Renderer/Template/js/test-size-filter.js | 155 ++++++ .../Renderer/Template/method_item.html.dist | 2 +- .../Template/method_item_branch.html.dist | 2 +- .../BankAccount.php.html | 21 +- .../CoverageForBankAccount/dashboard.html | 4 +- .../HTML/CoverageForBankAccount/index.html | 17 +- .../dashboard.html | 4 +- .../index.html | 17 +- ...with_class_and_anonymous_function.php.html | 15 +- .../dashboard.html | 4 +- .../index.html | 17 +- .../source_with_ignore.php.html | 21 +- .../BankAccount.php.html | 275 +---------- .../BankAccount.php_branch.html | 275 +---------- .../BankAccount.php_path.html | 275 +---------- .../PathCoverageForBankAccount/dashboard.html | 4 +- .../PathCoverageForBankAccount/index.html | 17 +- .../dashboard.html | 4 +- .../index.html | 17 +- .../source_without_namespace.php.html | 15 +- .../source_without_namespace.php_branch.html | 17 +- .../source_without_namespace.php_path.html | 17 +- 41 files changed, 1475 insertions(+), 837 deletions(-) create mode 100644 src/Report/Html/Renderer/Template/js/test-size-filter.js diff --git a/src/Data/ProcessedClassType.php b/src/Data/ProcessedClassType.php index 22d6c99df..716722c62 100644 --- a/src/Data/ProcessedClassType.php +++ b/src/Data/ProcessedClassType.php @@ -26,6 +26,11 @@ final class ProcessedClassType public readonly int $startLine; public int $executableLines; public int $executedLines; + public int $executedLinesBySmallTests = 0; + public int $executedLinesByMediumTests = 0; + public int $executedLinesByLargeTests = 0; + public int $executedLinesBySmallOrMediumTests = 0; + public int $executedLinesBySmallOrMediumOrLargeTests = 0; public int $executableBranches; public int $executedBranches; public int $executablePaths; diff --git a/src/Data/ProcessedFunctionType.php b/src/Data/ProcessedFunctionType.php index c97069b8f..72716880f 100644 --- a/src/Data/ProcessedFunctionType.php +++ b/src/Data/ProcessedFunctionType.php @@ -23,6 +23,11 @@ final class ProcessedFunctionType public readonly int $endLine; public int $executableLines; public int $executedLines; + public int $executedLinesBySmallTests = 0; + public int $executedLinesByMediumTests = 0; + public int $executedLinesByLargeTests = 0; + public int $executedLinesBySmallOrMediumTests = 0; + public int $executedLinesBySmallOrMediumOrLargeTests = 0; public int $executableBranches; public int $executedBranches; public int $executablePaths; diff --git a/src/Data/ProcessedMethodType.php b/src/Data/ProcessedMethodType.php index 861b005d8..cc4b6ce90 100644 --- a/src/Data/ProcessedMethodType.php +++ b/src/Data/ProcessedMethodType.php @@ -23,6 +23,11 @@ final class ProcessedMethodType public readonly int $endLine; public int $executableLines; public int $executedLines; + public int $executedLinesBySmallTests = 0; + public int $executedLinesByMediumTests = 0; + public int $executedLinesByLargeTests = 0; + public int $executedLinesBySmallOrMediumTests = 0; + public int $executedLinesBySmallOrMediumOrLargeTests = 0; public int $executableBranches; public int $executedBranches; public int $executablePaths; diff --git a/src/Data/ProcessedTraitType.php b/src/Data/ProcessedTraitType.php index e71ee5d10..d8aba39af 100644 --- a/src/Data/ProcessedTraitType.php +++ b/src/Data/ProcessedTraitType.php @@ -26,6 +26,11 @@ final class ProcessedTraitType public readonly int $startLine; public int $executableLines; public int $executedLines; + public int $executedLinesBySmallTests = 0; + public int $executedLinesByMediumTests = 0; + public int $executedLinesByLargeTests = 0; + public int $executedLinesBySmallOrMediumTests = 0; + public int $executedLinesBySmallOrMediumOrLargeTests = 0; public int $executableBranches; public int $executedBranches; public int $executablePaths; diff --git a/src/Node/AbstractNode.php b/src/Node/AbstractNode.php index c9d6ba42d..aa1e34b29 100644 --- a/src/Node/AbstractNode.php +++ b/src/Node/AbstractNode.php @@ -135,6 +135,46 @@ public function percentageOfExecutedLines(): Percentage ); } + public function percentageOfExecutedLinesBySmallTests(): Percentage + { + return Percentage::fromFractionAndTotal( + $this->numberOfExecutedLinesBySmallTests(), + $this->numberOfExecutableLines(), + ); + } + + public function percentageOfExecutedLinesByMediumTests(): Percentage + { + return Percentage::fromFractionAndTotal( + $this->numberOfExecutedLinesByMediumTests(), + $this->numberOfExecutableLines(), + ); + } + + public function percentageOfExecutedLinesByLargeTests(): Percentage + { + return Percentage::fromFractionAndTotal( + $this->numberOfExecutedLinesByLargeTests(), + $this->numberOfExecutableLines(), + ); + } + + public function percentageOfExecutedLinesBySmallOrMediumTests(): Percentage + { + return Percentage::fromFractionAndTotal( + $this->numberOfExecutedLinesBySmallOrMediumTests(), + $this->numberOfExecutableLines(), + ); + } + + public function percentageOfExecutedLinesBySmallOrMediumOrLargeTests(): Percentage + { + return Percentage::fromFractionAndTotal( + $this->numberOfExecutedLinesBySmallOrMediumOrLargeTests(), + $this->numberOfExecutableLines(), + ); + } + public function percentageOfExecutedBranches(): Percentage { return Percentage::fromFractionAndTotal( @@ -161,6 +201,31 @@ public function numberOfTestedClassesAndTraits(): int return $this->numberOfTestedClasses() + $this->numberOfTestedTraits(); } + public function numberOfTestedClassesAndTraitsBySmallTests(): int + { + return $this->numberOfTestedClassesBySmallTests() + $this->numberOfTestedTraitsBySmallTests(); + } + + public function numberOfTestedClassesAndTraitsByMediumTests(): int + { + return $this->numberOfTestedClassesByMediumTests() + $this->numberOfTestedTraitsByMediumTests(); + } + + public function numberOfTestedClassesAndTraitsByLargeTests(): int + { + return $this->numberOfTestedClassesByLargeTests() + $this->numberOfTestedTraitsByLargeTests(); + } + + public function numberOfTestedClassesAndTraitsBySmallOrMediumTests(): int + { + return $this->numberOfTestedClassesBySmallOrMediumTests() + $this->numberOfTestedTraitsBySmallOrMediumTests(); + } + + public function numberOfTestedClassesAndTraitsBySmallOrMediumOrLargeTests(): int + { + return $this->numberOfTestedClassesBySmallOrMediumOrLargeTests() + $this->numberOfTestedTraitsBySmallOrMediumOrLargeTests(); + } + /** * @return array */ @@ -179,6 +244,31 @@ public function numberOfTestedFunctionsAndMethods(): int return $this->numberOfTestedFunctions() + $this->numberOfTestedMethods(); } + public function numberOfTestedFunctionsAndMethodsBySmallTests(): int + { + return $this->numberOfTestedFunctionsBySmallTests() + $this->numberOfTestedMethodsBySmallTests(); + } + + public function numberOfTestedFunctionsAndMethodsByMediumTests(): int + { + return $this->numberOfTestedFunctionsByMediumTests() + $this->numberOfTestedMethodsByMediumTests(); + } + + public function numberOfTestedFunctionsAndMethodsByLargeTests(): int + { + return $this->numberOfTestedFunctionsByLargeTests() + $this->numberOfTestedMethodsByLargeTests(); + } + + public function numberOfTestedFunctionsAndMethodsBySmallOrMediumTests(): int + { + return $this->numberOfTestedFunctionsBySmallOrMediumTests() + $this->numberOfTestedMethodsBySmallOrMediumTests(); + } + + public function numberOfTestedFunctionsAndMethodsBySmallOrMediumOrLargeTests(): int + { + return $this->numberOfTestedFunctionsBySmallOrMediumOrLargeTests() + $this->numberOfTestedMethodsBySmallOrMediumOrLargeTests(); + } + /** * @return non-negative-int */ @@ -218,6 +308,16 @@ abstract public function numberOfExecutableLines(): int; abstract public function numberOfExecutedLines(): int; + abstract public function numberOfExecutedLinesBySmallTests(): int; + + abstract public function numberOfExecutedLinesByMediumTests(): int; + + abstract public function numberOfExecutedLinesByLargeTests(): int; + + abstract public function numberOfExecutedLinesBySmallOrMediumTests(): int; + + abstract public function numberOfExecutedLinesBySmallOrMediumOrLargeTests(): int; + abstract public function numberOfExecutableBranches(): int; abstract public function numberOfExecutedBranches(): int; @@ -232,18 +332,58 @@ abstract public function numberOfClasses(): int; abstract public function numberOfTestedClasses(): int; + abstract public function numberOfTestedClassesBySmallTests(): int; + + abstract public function numberOfTestedClassesByMediumTests(): int; + + abstract public function numberOfTestedClassesByLargeTests(): int; + + abstract public function numberOfTestedClassesBySmallOrMediumTests(): int; + + abstract public function numberOfTestedClassesBySmallOrMediumOrLargeTests(): int; + abstract public function numberOfTraits(): int; abstract public function numberOfTestedTraits(): int; + abstract public function numberOfTestedTraitsBySmallTests(): int; + + abstract public function numberOfTestedTraitsByMediumTests(): int; + + abstract public function numberOfTestedTraitsByLargeTests(): int; + + abstract public function numberOfTestedTraitsBySmallOrMediumTests(): int; + + abstract public function numberOfTestedTraitsBySmallOrMediumOrLargeTests(): int; + abstract public function numberOfMethods(): int; abstract public function numberOfTestedMethods(): int; + abstract public function numberOfTestedMethodsBySmallTests(): int; + + abstract public function numberOfTestedMethodsByMediumTests(): int; + + abstract public function numberOfTestedMethodsByLargeTests(): int; + + abstract public function numberOfTestedMethodsBySmallOrMediumTests(): int; + + abstract public function numberOfTestedMethodsBySmallOrMediumOrLargeTests(): int; + abstract public function numberOfFunctions(): int; abstract public function numberOfTestedFunctions(): int; + abstract public function numberOfTestedFunctionsBySmallTests(): int; + + abstract public function numberOfTestedFunctionsByMediumTests(): int; + + abstract public function numberOfTestedFunctionsByLargeTests(): int; + + abstract public function numberOfTestedFunctionsBySmallOrMediumTests(): int; + + abstract public function numberOfTestedFunctionsBySmallOrMediumOrLargeTests(): int; + private function processId(): void { if ($this->parent === null) { diff --git a/src/Node/Directory.php b/src/Node/Directory.php index 053bf76b6..be7add75c 100644 --- a/src/Node/Directory.php +++ b/src/Node/Directory.php @@ -56,24 +56,49 @@ final class Directory extends AbstractNode implements IteratorAggregate /** * @var ?array */ - private ?array $functions = null; - private ?LinesOfCode $linesOfCode = null; - private int $numFiles = -1; - private int $numExecutableLines = -1; - private int $numExecutedLines = -1; - private int $numExecutableBranches = -1; - private int $numExecutedBranches = -1; - private int $numExecutablePaths = -1; - private int $numExecutedPaths = -1; - private int $numFilesWithoutBranchCoverageData = -1; - private int $numClasses = -1; - private int $numTestedClasses = -1; - private int $numTraits = -1; - private int $numTestedTraits = -1; - private int $numMethods = -1; - private int $numTestedMethods = -1; - private int $numFunctions = -1; - private int $numTestedFunctions = -1; + private ?array $functions = null; + private ?LinesOfCode $linesOfCode = null; + private int $numFiles = -1; + private int $numExecutableLines = -1; + private int $numExecutedLines = -1; + private int $numExecutedLinesBySmallTests = -1; + private int $numExecutedLinesByMediumTests = -1; + private int $numExecutedLinesByLargeTests = -1; + private int $numExecutedLinesBySmallOrMediumTests = -1; + private int $numExecutedLinesBySmallOrMediumOrLargeTests = -1; + private int $numExecutableBranches = -1; + private int $numExecutedBranches = -1; + private int $numExecutablePaths = -1; + private int $numExecutedPaths = -1; + private int $numFilesWithoutBranchCoverageData = -1; + private int $numClasses = -1; + private int $numTestedClasses = -1; + private int $numTestedClassesBySmallTests = -1; + private int $numTestedClassesByMediumTests = -1; + private int $numTestedClassesByLargeTests = -1; + private int $numTestedClassesBySmallOrMediumTests = -1; + private int $numTestedClassesBySmallOrMediumOrLargeTests = -1; + private int $numTraits = -1; + private int $numTestedTraits = -1; + private int $numTestedTraitsBySmallTests = -1; + private int $numTestedTraitsByMediumTests = -1; + private int $numTestedTraitsByLargeTests = -1; + private int $numTestedTraitsBySmallOrMediumTests = -1; + private int $numTestedTraitsBySmallOrMediumOrLargeTests = -1; + private int $numMethods = -1; + private int $numTestedMethods = -1; + private int $numTestedMethodsBySmallTests = -1; + private int $numTestedMethodsByMediumTests = -1; + private int $numTestedMethodsByLargeTests = -1; + private int $numTestedMethodsBySmallOrMediumTests = -1; + private int $numTestedMethodsBySmallOrMediumOrLargeTests = -1; + private int $numFunctions = -1; + private int $numTestedFunctions = -1; + private int $numTestedFunctionsBySmallTests = -1; + private int $numTestedFunctionsByMediumTests = -1; + private int $numTestedFunctionsByLargeTests = -1; + private int $numTestedFunctionsBySmallOrMediumTests = -1; + private int $numTestedFunctionsBySmallOrMediumOrLargeTests = -1; public function count(): int { @@ -116,8 +141,13 @@ public function addFile(File $file): void $this->children[] = $file; $this->files[] = &$this->children[count($this->children) - 1]; - $this->numExecutableLines = -1; - $this->numExecutedLines = -1; + $this->numExecutableLines = -1; + $this->numExecutedLines = -1; + $this->numExecutedLinesBySmallTests = -1; + $this->numExecutedLinesByMediumTests = -1; + $this->numExecutedLinesByLargeTests = -1; + $this->numExecutedLinesBySmallOrMediumTests = -1; + $this->numExecutedLinesBySmallOrMediumOrLargeTests = -1; } /** @@ -248,6 +278,71 @@ public function numberOfExecutedLines(): int return $this->numExecutedLines; } + public function numberOfExecutedLinesBySmallTests(): int + { + if ($this->numExecutedLinesBySmallTests === -1) { + $this->numExecutedLinesBySmallTests = 0; + + foreach ($this->children as $child) { + $this->numExecutedLinesBySmallTests += $child->numberOfExecutedLinesBySmallTests(); + } + } + + return $this->numExecutedLinesBySmallTests; + } + + public function numberOfExecutedLinesByMediumTests(): int + { + if ($this->numExecutedLinesByMediumTests === -1) { + $this->numExecutedLinesByMediumTests = 0; + + foreach ($this->children as $child) { + $this->numExecutedLinesByMediumTests += $child->numberOfExecutedLinesByMediumTests(); + } + } + + return $this->numExecutedLinesByMediumTests; + } + + public function numberOfExecutedLinesByLargeTests(): int + { + if ($this->numExecutedLinesByLargeTests === -1) { + $this->numExecutedLinesByLargeTests = 0; + + foreach ($this->children as $child) { + $this->numExecutedLinesByLargeTests += $child->numberOfExecutedLinesByLargeTests(); + } + } + + return $this->numExecutedLinesByLargeTests; + } + + public function numberOfExecutedLinesBySmallOrMediumTests(): int + { + if ($this->numExecutedLinesBySmallOrMediumTests === -1) { + $this->numExecutedLinesBySmallOrMediumTests = 0; + + foreach ($this->children as $child) { + $this->numExecutedLinesBySmallOrMediumTests += $child->numberOfExecutedLinesBySmallOrMediumTests(); + } + } + + return $this->numExecutedLinesBySmallOrMediumTests; + } + + public function numberOfExecutedLinesBySmallOrMediumOrLargeTests(): int + { + if ($this->numExecutedLinesBySmallOrMediumOrLargeTests === -1) { + $this->numExecutedLinesBySmallOrMediumOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numExecutedLinesBySmallOrMediumOrLargeTests += $child->numberOfExecutedLinesBySmallOrMediumOrLargeTests(); + } + } + + return $this->numExecutedLinesBySmallOrMediumOrLargeTests; + } + public function numberOfExecutableBranches(): int { if ($this->numExecutableBranches === -1) { @@ -339,6 +434,71 @@ public function numberOfTestedClasses(): int return $this->numTestedClasses; } + public function numberOfTestedClassesBySmallTests(): int + { + if ($this->numTestedClassesBySmallTests === -1) { + $this->numTestedClassesBySmallTests = 0; + + foreach ($this->children as $child) { + $this->numTestedClassesBySmallTests += $child->numberOfTestedClassesBySmallTests(); + } + } + + return $this->numTestedClassesBySmallTests; + } + + public function numberOfTestedClassesByMediumTests(): int + { + if ($this->numTestedClassesByMediumTests === -1) { + $this->numTestedClassesByMediumTests = 0; + + foreach ($this->children as $child) { + $this->numTestedClassesByMediumTests += $child->numberOfTestedClassesByMediumTests(); + } + } + + return $this->numTestedClassesByMediumTests; + } + + public function numberOfTestedClassesByLargeTests(): int + { + if ($this->numTestedClassesByLargeTests === -1) { + $this->numTestedClassesByLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedClassesByLargeTests += $child->numberOfTestedClassesByLargeTests(); + } + } + + return $this->numTestedClassesByLargeTests; + } + + public function numberOfTestedClassesBySmallOrMediumTests(): int + { + if ($this->numTestedClassesBySmallOrMediumTests === -1) { + $this->numTestedClassesBySmallOrMediumTests = 0; + + foreach ($this->children as $child) { + $this->numTestedClassesBySmallOrMediumTests += $child->numberOfTestedClassesBySmallOrMediumTests(); + } + } + + return $this->numTestedClassesBySmallOrMediumTests; + } + + public function numberOfTestedClassesBySmallOrMediumOrLargeTests(): int + { + if ($this->numTestedClassesBySmallOrMediumOrLargeTests === -1) { + $this->numTestedClassesBySmallOrMediumOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedClassesBySmallOrMediumOrLargeTests += $child->numberOfTestedClassesBySmallOrMediumOrLargeTests(); + } + } + + return $this->numTestedClassesBySmallOrMediumOrLargeTests; + } + public function numberOfTraits(): int { if ($this->numTraits === -1) { @@ -365,6 +525,71 @@ public function numberOfTestedTraits(): int return $this->numTestedTraits; } + public function numberOfTestedTraitsBySmallTests(): int + { + if ($this->numTestedTraitsBySmallTests === -1) { + $this->numTestedTraitsBySmallTests = 0; + + foreach ($this->children as $child) { + $this->numTestedTraitsBySmallTests += $child->numberOfTestedTraitsBySmallTests(); + } + } + + return $this->numTestedTraitsBySmallTests; + } + + public function numberOfTestedTraitsByMediumTests(): int + { + if ($this->numTestedTraitsByMediumTests === -1) { + $this->numTestedTraitsByMediumTests = 0; + + foreach ($this->children as $child) { + $this->numTestedTraitsByMediumTests += $child->numberOfTestedTraitsByMediumTests(); + } + } + + return $this->numTestedTraitsByMediumTests; + } + + public function numberOfTestedTraitsByLargeTests(): int + { + if ($this->numTestedTraitsByLargeTests === -1) { + $this->numTestedTraitsByLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedTraitsByLargeTests += $child->numberOfTestedTraitsByLargeTests(); + } + } + + return $this->numTestedTraitsByLargeTests; + } + + public function numberOfTestedTraitsBySmallOrMediumTests(): int + { + if ($this->numTestedTraitsBySmallOrMediumTests === -1) { + $this->numTestedTraitsBySmallOrMediumTests = 0; + + foreach ($this->children as $child) { + $this->numTestedTraitsBySmallOrMediumTests += $child->numberOfTestedTraitsBySmallOrMediumTests(); + } + } + + return $this->numTestedTraitsBySmallOrMediumTests; + } + + public function numberOfTestedTraitsBySmallOrMediumOrLargeTests(): int + { + if ($this->numTestedTraitsBySmallOrMediumOrLargeTests === -1) { + $this->numTestedTraitsBySmallOrMediumOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedTraitsBySmallOrMediumOrLargeTests += $child->numberOfTestedTraitsBySmallOrMediumOrLargeTests(); + } + } + + return $this->numTestedTraitsBySmallOrMediumOrLargeTests; + } + public function numberOfMethods(): int { if ($this->numMethods === -1) { @@ -391,6 +616,71 @@ public function numberOfTestedMethods(): int return $this->numTestedMethods; } + public function numberOfTestedMethodsBySmallTests(): int + { + if ($this->numTestedMethodsBySmallTests === -1) { + $this->numTestedMethodsBySmallTests = 0; + + foreach ($this->children as $child) { + $this->numTestedMethodsBySmallTests += $child->numberOfTestedMethodsBySmallTests(); + } + } + + return $this->numTestedMethodsBySmallTests; + } + + public function numberOfTestedMethodsByMediumTests(): int + { + if ($this->numTestedMethodsByMediumTests === -1) { + $this->numTestedMethodsByMediumTests = 0; + + foreach ($this->children as $child) { + $this->numTestedMethodsByMediumTests += $child->numberOfTestedMethodsByMediumTests(); + } + } + + return $this->numTestedMethodsByMediumTests; + } + + public function numberOfTestedMethodsByLargeTests(): int + { + if ($this->numTestedMethodsByLargeTests === -1) { + $this->numTestedMethodsByLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedMethodsByLargeTests += $child->numberOfTestedMethodsByLargeTests(); + } + } + + return $this->numTestedMethodsByLargeTests; + } + + public function numberOfTestedMethodsBySmallOrMediumTests(): int + { + if ($this->numTestedMethodsBySmallOrMediumTests === -1) { + $this->numTestedMethodsBySmallOrMediumTests = 0; + + foreach ($this->children as $child) { + $this->numTestedMethodsBySmallOrMediumTests += $child->numberOfTestedMethodsBySmallOrMediumTests(); + } + } + + return $this->numTestedMethodsBySmallOrMediumTests; + } + + public function numberOfTestedMethodsBySmallOrMediumOrLargeTests(): int + { + if ($this->numTestedMethodsBySmallOrMediumOrLargeTests === -1) { + $this->numTestedMethodsBySmallOrMediumOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedMethodsBySmallOrMediumOrLargeTests += $child->numberOfTestedMethodsBySmallOrMediumOrLargeTests(); + } + } + + return $this->numTestedMethodsBySmallOrMediumOrLargeTests; + } + public function numberOfFunctions(): int { if ($this->numFunctions === -1) { @@ -416,4 +706,69 @@ public function numberOfTestedFunctions(): int return $this->numTestedFunctions; } + + public function numberOfTestedFunctionsBySmallTests(): int + { + if ($this->numTestedFunctionsBySmallTests === -1) { + $this->numTestedFunctionsBySmallTests = 0; + + foreach ($this->children as $child) { + $this->numTestedFunctionsBySmallTests += $child->numberOfTestedFunctionsBySmallTests(); + } + } + + return $this->numTestedFunctionsBySmallTests; + } + + public function numberOfTestedFunctionsByMediumTests(): int + { + if ($this->numTestedFunctionsByMediumTests === -1) { + $this->numTestedFunctionsByMediumTests = 0; + + foreach ($this->children as $child) { + $this->numTestedFunctionsByMediumTests += $child->numberOfTestedFunctionsByMediumTests(); + } + } + + return $this->numTestedFunctionsByMediumTests; + } + + public function numberOfTestedFunctionsByLargeTests(): int + { + if ($this->numTestedFunctionsByLargeTests === -1) { + $this->numTestedFunctionsByLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedFunctionsByLargeTests += $child->numberOfTestedFunctionsByLargeTests(); + } + } + + return $this->numTestedFunctionsByLargeTests; + } + + public function numberOfTestedFunctionsBySmallOrMediumTests(): int + { + if ($this->numTestedFunctionsBySmallOrMediumTests === -1) { + $this->numTestedFunctionsBySmallOrMediumTests = 0; + + foreach ($this->children as $child) { + $this->numTestedFunctionsBySmallOrMediumTests += $child->numberOfTestedFunctionsBySmallOrMediumTests(); + } + } + + return $this->numTestedFunctionsBySmallOrMediumTests; + } + + public function numberOfTestedFunctionsBySmallOrMediumOrLargeTests(): int + { + if ($this->numTestedFunctionsBySmallOrMediumOrLargeTests === -1) { + $this->numTestedFunctionsBySmallOrMediumOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedFunctionsBySmallOrMediumOrLargeTests += $child->numberOfTestedFunctionsBySmallOrMediumOrLargeTests(); + } + } + + return $this->numTestedFunctionsBySmallOrMediumOrLargeTests; + } } diff --git a/src/Node/File.php b/src/Node/File.php index 7ae9c8288..8801e9264 100644 --- a/src/Node/File.php +++ b/src/Node/File.php @@ -56,12 +56,17 @@ final class File extends AbstractNode * @var array */ private readonly array $testData; - private int $numExecutableLines = 0; - private int $numExecutedLines = 0; - private int $numExecutableBranches = 0; - private int $numExecutedBranches = 0; - private int $numExecutablePaths = 0; - private int $numExecutedPaths = 0; + private int $numExecutableLines = 0; + private int $numExecutedLines = 0; + private int $numExecutedLinesBySmallTests = 0; + private int $numExecutedLinesByMediumTests = 0; + private int $numExecutedLinesByLargeTests = 0; + private int $numExecutedLinesBySmallOrMediumTests = 0; + private int $numExecutedLinesBySmallOrMediumOrLargeTests = 0; + private int $numExecutableBranches = 0; + private int $numExecutedBranches = 0; + private int $numExecutablePaths = 0; + private int $numExecutedPaths = 0; /** * @var array @@ -79,13 +84,33 @@ final class File extends AbstractNode private array $functions = []; private readonly LinesOfCode $linesOfCode; private readonly bool $hasBranchCoverageData; - private ?int $numClasses = null; - private int $numTestedClasses = 0; - private ?int $numTraits = null; - private int $numTestedTraits = 0; - private ?int $numMethods = null; - private ?int $numTestedMethods = null; - private ?int $numTestedFunctions = null; + private ?int $numClasses = null; + private int $numTestedClasses = 0; + private int $numTestedClassesBySmallTests = 0; + private int $numTestedClassesByMediumTests = 0; + private int $numTestedClassesByLargeTests = 0; + private int $numTestedClassesBySmallOrMediumTests = 0; + private int $numTestedClassesBySmallOrMediumOrLargeTests = 0; + private ?int $numTraits = null; + private int $numTestedTraits = 0; + private int $numTestedTraitsBySmallTests = 0; + private int $numTestedTraitsByMediumTests = 0; + private int $numTestedTraitsByLargeTests = 0; + private int $numTestedTraitsBySmallOrMediumTests = 0; + private int $numTestedTraitsBySmallOrMediumOrLargeTests = 0; + private ?int $numMethods = null; + private ?int $numTestedMethods = null; + private ?int $numTestedMethodsBySmallTests = null; + private ?int $numTestedMethodsByMediumTests = null; + private ?int $numTestedMethodsByLargeTests = null; + private ?int $numTestedMethodsBySmallOrMediumTests = null; + private ?int $numTestedMethodsBySmallOrMediumOrLargeTests = null; + private ?int $numTestedFunctions = null; + private ?int $numTestedFunctionsBySmallTests = null; + private ?int $numTestedFunctionsByMediumTests = null; + private ?int $numTestedFunctionsByLargeTests = null; + private ?int $numTestedFunctionsBySmallOrMediumTests = null; + private ?int $numTestedFunctionsBySmallOrMediumOrLargeTests = null; /** * @var array> @@ -191,6 +216,31 @@ public function numberOfExecutedLines(): int return $this->numExecutedLines; } + public function numberOfExecutedLinesBySmallTests(): int + { + return $this->numExecutedLinesBySmallTests; + } + + public function numberOfExecutedLinesByMediumTests(): int + { + return $this->numExecutedLinesByMediumTests; + } + + public function numberOfExecutedLinesByLargeTests(): int + { + return $this->numExecutedLinesByLargeTests; + } + + public function numberOfExecutedLinesBySmallOrMediumTests(): int + { + return $this->numExecutedLinesBySmallOrMediumTests; + } + + public function numberOfExecutedLinesBySmallOrMediumOrLargeTests(): int + { + return $this->numExecutedLinesBySmallOrMediumOrLargeTests; + } + public function numberOfExecutableBranches(): int { return $this->numExecutableBranches; @@ -245,6 +295,31 @@ public function numberOfTestedClasses(): int return $this->numTestedClasses; } + public function numberOfTestedClassesBySmallTests(): int + { + return $this->numTestedClassesBySmallTests; + } + + public function numberOfTestedClassesByMediumTests(): int + { + return $this->numTestedClassesByMediumTests; + } + + public function numberOfTestedClassesByLargeTests(): int + { + return $this->numTestedClassesByLargeTests; + } + + public function numberOfTestedClassesBySmallOrMediumTests(): int + { + return $this->numTestedClassesBySmallOrMediumTests; + } + + public function numberOfTestedClassesBySmallOrMediumOrLargeTests(): int + { + return $this->numTestedClassesBySmallOrMediumOrLargeTests; + } + public function numberOfTraits(): int { if ($this->numTraits === null) { @@ -269,6 +344,31 @@ public function numberOfTestedTraits(): int return $this->numTestedTraits; } + public function numberOfTestedTraitsBySmallTests(): int + { + return $this->numTestedTraitsBySmallTests; + } + + public function numberOfTestedTraitsByMediumTests(): int + { + return $this->numTestedTraitsByMediumTests; + } + + public function numberOfTestedTraitsByLargeTests(): int + { + return $this->numTestedTraitsByLargeTests; + } + + public function numberOfTestedTraitsBySmallOrMediumTests(): int + { + return $this->numTestedTraitsBySmallOrMediumTests; + } + + public function numberOfTestedTraitsBySmallOrMediumOrLargeTests(): int + { + return $this->numTestedTraitsBySmallOrMediumOrLargeTests; + } + public function numberOfMethods(): int { if ($this->numMethods === null) { @@ -321,6 +421,131 @@ public function numberOfTestedMethods(): int return $this->numTestedMethods; } + public function numberOfTestedMethodsBySmallTests(): int + { + if ($this->numTestedMethodsBySmallTests === null) { + $this->numTestedMethodsBySmallTests = 0; + + foreach ($this->classes as $class) { + foreach ($class->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesBySmallTests === $method->executableLines) { + $this->numTestedMethodsBySmallTests++; + } + } + } + + foreach ($this->traits as $trait) { + foreach ($trait->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesBySmallTests === $method->executableLines) { + $this->numTestedMethodsBySmallTests++; + } + } + } + } + + return $this->numTestedMethodsBySmallTests; + } + + public function numberOfTestedMethodsByMediumTests(): int + { + if ($this->numTestedMethodsByMediumTests === null) { + $this->numTestedMethodsByMediumTests = 0; + + foreach ($this->classes as $class) { + foreach ($class->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesByMediumTests === $method->executableLines) { + $this->numTestedMethodsByMediumTests++; + } + } + } + + foreach ($this->traits as $trait) { + foreach ($trait->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesByMediumTests === $method->executableLines) { + $this->numTestedMethodsByMediumTests++; + } + } + } + } + + return $this->numTestedMethodsByMediumTests; + } + + public function numberOfTestedMethodsByLargeTests(): int + { + if ($this->numTestedMethodsByLargeTests === null) { + $this->numTestedMethodsByLargeTests = 0; + + foreach ($this->classes as $class) { + foreach ($class->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesByLargeTests === $method->executableLines) { + $this->numTestedMethodsByLargeTests++; + } + } + } + + foreach ($this->traits as $trait) { + foreach ($trait->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesByLargeTests === $method->executableLines) { + $this->numTestedMethodsByLargeTests++; + } + } + } + } + + return $this->numTestedMethodsByLargeTests; + } + + public function numberOfTestedMethodsBySmallOrMediumTests(): int + { + if ($this->numTestedMethodsBySmallOrMediumTests === null) { + $this->numTestedMethodsBySmallOrMediumTests = 0; + + foreach ($this->classes as $class) { + foreach ($class->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesBySmallOrMediumTests === $method->executableLines) { + $this->numTestedMethodsBySmallOrMediumTests++; + } + } + } + + foreach ($this->traits as $trait) { + foreach ($trait->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesBySmallOrMediumTests === $method->executableLines) { + $this->numTestedMethodsBySmallOrMediumTests++; + } + } + } + } + + return $this->numTestedMethodsBySmallOrMediumTests; + } + + public function numberOfTestedMethodsBySmallOrMediumOrLargeTests(): int + { + if ($this->numTestedMethodsBySmallOrMediumOrLargeTests === null) { + $this->numTestedMethodsBySmallOrMediumOrLargeTests = 0; + + foreach ($this->classes as $class) { + foreach ($class->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesBySmallOrMediumOrLargeTests === $method->executableLines) { + $this->numTestedMethodsBySmallOrMediumOrLargeTests++; + } + } + } + + foreach ($this->traits as $trait) { + foreach ($trait->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesBySmallOrMediumOrLargeTests === $method->executableLines) { + $this->numTestedMethodsBySmallOrMediumOrLargeTests++; + } + } + } + } + + return $this->numTestedMethodsBySmallOrMediumOrLargeTests; + } + public function numberOfFunctions(): int { return count($this->functions); @@ -342,6 +567,81 @@ public function numberOfTestedFunctions(): int return $this->numTestedFunctions; } + public function numberOfTestedFunctionsBySmallTests(): int + { + if ($this->numTestedFunctionsBySmallTests === null) { + $this->numTestedFunctionsBySmallTests = 0; + + foreach ($this->functions as $function) { + if ($function->executableLines > 0 && $function->executedLinesBySmallTests === $function->executableLines) { + $this->numTestedFunctionsBySmallTests++; + } + } + } + + return $this->numTestedFunctionsBySmallTests; + } + + public function numberOfTestedFunctionsByMediumTests(): int + { + if ($this->numTestedFunctionsByMediumTests === null) { + $this->numTestedFunctionsByMediumTests = 0; + + foreach ($this->functions as $function) { + if ($function->executableLines > 0 && $function->executedLinesByMediumTests === $function->executableLines) { + $this->numTestedFunctionsByMediumTests++; + } + } + } + + return $this->numTestedFunctionsByMediumTests; + } + + public function numberOfTestedFunctionsByLargeTests(): int + { + if ($this->numTestedFunctionsByLargeTests === null) { + $this->numTestedFunctionsByLargeTests = 0; + + foreach ($this->functions as $function) { + if ($function->executableLines > 0 && $function->executedLinesByLargeTests === $function->executableLines) { + $this->numTestedFunctionsByLargeTests++; + } + } + } + + return $this->numTestedFunctionsByLargeTests; + } + + public function numberOfTestedFunctionsBySmallOrMediumTests(): int + { + if ($this->numTestedFunctionsBySmallOrMediumTests === null) { + $this->numTestedFunctionsBySmallOrMediumTests = 0; + + foreach ($this->functions as $function) { + if ($function->executableLines > 0 && $function->executedLinesBySmallOrMediumTests === $function->executableLines) { + $this->numTestedFunctionsBySmallOrMediumTests++; + } + } + } + + return $this->numTestedFunctionsBySmallOrMediumTests; + } + + public function numberOfTestedFunctionsBySmallOrMediumOrLargeTests(): int + { + if ($this->numTestedFunctionsBySmallOrMediumOrLargeTests === null) { + $this->numTestedFunctionsBySmallOrMediumOrLargeTests = 0; + + foreach ($this->functions as $function) { + if ($function->executableLines > 0 && $function->executedLinesBySmallOrMediumOrLargeTests === $function->executableLines) { + $this->numTestedFunctionsBySmallOrMediumOrLargeTests++; + } + } + } + + return $this->numTestedFunctionsBySmallOrMediumOrLargeTests; + } + /** * @param array $classes * @param array $traits @@ -375,6 +675,74 @@ private function calculateStatistics(array $classes, array $traits, array $funct unset($codeUnit); $this->numExecutedLines++; + + $coveredBySmall = false; + $coveredByMedium = false; + $coveredByLarge = false; + + foreach ($this->lineCoverageData[$lineNumber] as $testId) { + if (isset($this->testData[$testId])) { + $size = $this->testData[$testId]['size']; + + if ($size === 'small') { + $coveredBySmall = true; + } elseif ($size === 'medium') { + $coveredByMedium = true; + } elseif ($size === 'large') { + $coveredByLarge = true; + } + } + } + + if ($coveredBySmall) { + $this->numExecutedLinesBySmallTests++; + + foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) { + $codeUnit->executedLinesBySmallTests++; + } + + unset($codeUnit); + } + + if ($coveredByMedium) { + $this->numExecutedLinesByMediumTests++; + + foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) { + $codeUnit->executedLinesByMediumTests++; + } + + unset($codeUnit); + } + + if ($coveredByLarge) { + $this->numExecutedLinesByLargeTests++; + + foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) { + $codeUnit->executedLinesByLargeTests++; + } + + unset($codeUnit); + } + + if ($coveredBySmall || $coveredByMedium) { + $this->numExecutedLinesBySmallOrMediumTests++; + + foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) { + $codeUnit->executedLinesBySmallOrMediumTests++; + } + + unset($codeUnit); + } + + if ($coveredBySmall || $coveredByMedium || $coveredByLarge) { + $this->numExecutedLinesBySmallOrMediumOrLargeTests++; + + foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) { + $codeUnit->executedLinesBySmallOrMediumOrLargeTests++; + } + + unset($codeUnit); + } } } } @@ -403,6 +771,26 @@ private function calculateStatistics(array $classes, array $traits, array $funct if ($trait->executableLines > 0 && $trait->coverage === 100) { $this->numTestedTraits++; } + + if ($trait->executableLines > 0 && $trait->executedLinesBySmallTests === $trait->executableLines) { + $this->numTestedTraitsBySmallTests++; + } + + if ($trait->executableLines > 0 && $trait->executedLinesByMediumTests === $trait->executableLines) { + $this->numTestedTraitsByMediumTests++; + } + + if ($trait->executableLines > 0 && $trait->executedLinesByLargeTests === $trait->executableLines) { + $this->numTestedTraitsByLargeTests++; + } + + if ($trait->executableLines > 0 && $trait->executedLinesBySmallOrMediumTests === $trait->executableLines) { + $this->numTestedTraitsBySmallOrMediumTests++; + } + + if ($trait->executableLines > 0 && $trait->executedLinesBySmallOrMediumOrLargeTests === $trait->executableLines) { + $this->numTestedTraitsBySmallOrMediumOrLargeTests++; + } } unset($trait); @@ -431,6 +819,26 @@ private function calculateStatistics(array $classes, array $traits, array $funct if ($class->executableLines > 0 && $class->coverage === 100) { $this->numTestedClasses++; } + + if ($class->executableLines > 0 && $class->executedLinesBySmallTests === $class->executableLines) { + $this->numTestedClassesBySmallTests++; + } + + if ($class->executableLines > 0 && $class->executedLinesByMediumTests === $class->executableLines) { + $this->numTestedClassesByMediumTests++; + } + + if ($class->executableLines > 0 && $class->executedLinesByLargeTests === $class->executableLines) { + $this->numTestedClassesByLargeTests++; + } + + if ($class->executableLines > 0 && $class->executedLinesBySmallOrMediumTests === $class->executableLines) { + $this->numTestedClassesBySmallOrMediumTests++; + } + + if ($class->executableLines > 0 && $class->executedLinesBySmallOrMediumOrLargeTests === $class->executableLines) { + $this->numTestedClassesBySmallOrMediumOrLargeTests++; + } } unset($class); @@ -446,6 +854,26 @@ private function calculateStatistics(array $classes, array $traits, array $funct if ($function->coverage === 100) { $this->numTestedFunctions++; } + + if ($function->executableLines > 0 && $function->executedLinesBySmallTests === $function->executableLines) { + $this->numTestedFunctionsBySmallTests++; + } + + if ($function->executableLines > 0 && $function->executedLinesByMediumTests === $function->executableLines) { + $this->numTestedFunctionsByMediumTests++; + } + + if ($function->executableLines > 0 && $function->executedLinesByLargeTests === $function->executableLines) { + $this->numTestedFunctionsByLargeTests++; + } + + if ($function->executableLines > 0 && $function->executedLinesBySmallOrMediumTests === $function->executableLines) { + $this->numTestedFunctionsBySmallOrMediumTests++; + } + + if ($function->executableLines > 0 && $function->executedLinesBySmallOrMediumOrLargeTests === $function->executableLines) { + $this->numTestedFunctionsBySmallOrMediumOrLargeTests++; + } } } diff --git a/src/Report/Html/Facade.php b/src/Report/Html/Facade.php index c062f60e5..dad3b2d4f 100644 --- a/src/Report/Html/Facade.php +++ b/src/Report/Html/Facade.php @@ -117,6 +117,7 @@ private function copyFiles(string $target): void copy($this->templatePath . 'js/bootstrap.bundle.min.js', $dir . 'bootstrap.bundle.min.js'); copy($this->templatePath . 'js/jquery.min.js', $dir . 'jquery.min.js'); copy($this->templatePath . 'js/file.js', $dir . 'file.js'); + copy($this->templatePath . 'js/test-size-filter.js', $dir . 'test-size-filter.js'); } private function renderCss(string $target): void diff --git a/src/Report/Html/Renderer.php b/src/Report/Html/Renderer.php index b949f99ac..efc237bd8 100644 --- a/src/Report/Html/Renderer.php +++ b/src/Report/Html/Renderer.php @@ -9,8 +9,12 @@ */ namespace SebastianBergmann\CodeCoverage\Report\Html; +use const ENT_COMPAT; +use const JSON_THROW_ON_ERROR; use function array_pop; use function count; +use function htmlspecialchars; +use function json_encode; use function sprintf; use function str_repeat; use function substr_count; @@ -163,6 +167,7 @@ protected function renderItemTemplate(Template $template, array $data): string 'icon' => $data['icon'] ?? '', 'crap' => $data['crap'] ?? '', 'name' => $data['name'], + 'coverage_data' => htmlspecialchars($data['coverageDataJson'] ?? '{}', ENT_COMPAT), 'lines_bar' => $linesBar, 'lines_executed_percent' => $data['linesExecutedPercentAsString'], 'lines_level' => $linesLevel, @@ -301,6 +306,14 @@ protected function colorLevel(float $percent): string return 'success'; } + /** + * @param array $data + */ + protected function buildCoverageDataJson(array $data): string + { + return json_encode($data, JSON_THROW_ON_ERROR); + } + private function runtimeString(): string { $runtime = new Runtime; diff --git a/src/Report/Html/Renderer/Directory.php b/src/Report/Html/Renderer/Directory.php index 514e8a5a7..203aa14b4 100644 --- a/src/Report/Html/Renderer/Directory.php +++ b/src/Report/Html/Renderer/Directory.php @@ -99,6 +99,29 @@ private function renderItem(Node $node, bool $total = false): string 'testedClassesPercent' => $node->percentageOfTestedClassesAndTraits()->asFloat(), 'testedClassesPercentAsString' => $node->percentageOfTestedClassesAndTraits()->asString(), 'numFilesWithoutBranchCoverageData' => $node->numberOfFilesWithoutBranchCoverageData(), + 'coverageDataJson' => $this->buildCoverageDataJson([ + 'linesTotal' => $node->numberOfExecutableLines(), + 'linesAll' => $node->numberOfExecutedLines(), + 'linesSmall' => $node->numberOfExecutedLinesBySmallTests(), + 'linesMedium' => $node->numberOfExecutedLinesByMediumTests(), + 'linesLarge' => $node->numberOfExecutedLinesByLargeTests(), + 'linesSM' => $node->numberOfExecutedLinesBySmallOrMediumTests(), + 'linesSML' => $node->numberOfExecutedLinesBySmallOrMediumOrLargeTests(), + 'methodsTotal' => $node->numberOfFunctionsAndMethods(), + 'methodsAll' => $node->numberOfTestedFunctionsAndMethods(), + 'methodsSmall' => $node->numberOfTestedFunctionsAndMethodsBySmallTests(), + 'methodsMedium' => $node->numberOfTestedFunctionsAndMethodsByMediumTests(), + 'methodsLarge' => $node->numberOfTestedFunctionsAndMethodsByLargeTests(), + 'methodsSM' => $node->numberOfTestedFunctionsAndMethodsBySmallOrMediumTests(), + 'methodsSML' => $node->numberOfTestedFunctionsAndMethodsBySmallOrMediumOrLargeTests(), + 'classesTotal' => $node->numberOfClassesAndTraits(), + 'classesAll' => $node->numberOfTestedClassesAndTraits(), + 'classesSmall' => $node->numberOfTestedClassesAndTraitsBySmallTests(), + 'classesMedium' => $node->numberOfTestedClassesAndTraitsByMediumTests(), + 'classesLarge' => $node->numberOfTestedClassesAndTraitsByLargeTests(), + 'classesSM' => $node->numberOfTestedClassesAndTraitsBySmallOrMediumTests(), + 'classesSML' => $node->numberOfTestedClassesAndTraitsBySmallOrMediumOrLargeTests(), + ]), ]; if ($total) { diff --git a/src/Report/Html/Renderer/File.php b/src/Report/Html/Renderer/File.php index 99abac5b6..6269e5819 100644 --- a/src/Report/Html/Renderer/File.php +++ b/src/Report/Html/Renderer/File.php @@ -159,6 +159,29 @@ private function renderItems(FileNode $node): string 'testedClassesPercent' => $node->percentageOfTestedClassesAndTraits()->asFloat(), 'testedClassesPercentAsString' => $node->percentageOfTestedClassesAndTraits()->asString(), 'crap' => 'CRAP', + 'coverageDataJson' => $this->buildCoverageDataJson([ + 'linesTotal' => $node->numberOfExecutableLines(), + 'linesAll' => $node->numberOfExecutedLines(), + 'linesSmall' => $node->numberOfExecutedLinesBySmallTests(), + 'linesMedium' => $node->numberOfExecutedLinesByMediumTests(), + 'linesLarge' => $node->numberOfExecutedLinesByLargeTests(), + 'linesSM' => $node->numberOfExecutedLinesBySmallOrMediumTests(), + 'linesSML' => $node->numberOfExecutedLinesBySmallOrMediumOrLargeTests(), + 'methodsTotal' => $node->numberOfFunctionsAndMethods(), + 'methodsAll' => $node->numberOfTestedFunctionsAndMethods(), + 'methodsSmall' => $node->numberOfTestedFunctionsAndMethodsBySmallTests(), + 'methodsMedium' => $node->numberOfTestedFunctionsAndMethodsByMediumTests(), + 'methodsLarge' => $node->numberOfTestedFunctionsAndMethodsByLargeTests(), + 'methodsSM' => $node->numberOfTestedFunctionsAndMethodsBySmallOrMediumTests(), + 'methodsSML' => $node->numberOfTestedFunctionsAndMethodsBySmallOrMediumOrLargeTests(), + 'classesTotal' => $node->numberOfClassesAndTraits(), + 'classesAll' => $node->numberOfTestedClassesAndTraits(), + 'classesSmall' => $node->numberOfTestedClassesAndTraitsBySmallTests(), + 'classesMedium' => $node->numberOfTestedClassesAndTraitsByMediumTests(), + 'classesLarge' => $node->numberOfTestedClassesAndTraitsByLargeTests(), + 'classesSM' => $node->numberOfTestedClassesAndTraitsBySmallOrMediumTests(), + 'classesSML' => $node->numberOfTestedClassesAndTraitsBySmallOrMediumOrLargeTests(), + ]), ], ); diff --git a/src/Report/Html/Renderer/Template/directory.html.dist b/src/Report/Html/Renderer/Template/directory.html.dist index f769d2cae..8c2a6725a 100644 --- a/src/Report/Html/Renderer/Template/directory.html.dist +++ b/src/Report/Html/Renderer/Template/directory.html.dist @@ -24,6 +24,14 @@
+
+ + + + + + +
@@ -56,5 +64,8 @@

+ + + diff --git a/src/Report/Html/Renderer/Template/directory_branch.html.dist b/src/Report/Html/Renderer/Template/directory_branch.html.dist index 07ef7a33b..1a5d6dc86 100644 --- a/src/Report/Html/Renderer/Template/directory_branch.html.dist +++ b/src/Report/Html/Renderer/Template/directory_branch.html.dist @@ -24,6 +24,14 @@
+
+ + + + + + +
@@ -57,5 +65,8 @@

+ + + diff --git a/src/Report/Html/Renderer/Template/directory_item.html.dist b/src/Report/Html/Renderer/Template/directory_item.html.dist index f6941a437..4eeb61023 100644 --- a/src/Report/Html/Renderer/Template/directory_item.html.dist +++ b/src/Report/Html/Renderer/Template/directory_item.html.dist @@ -1,4 +1,4 @@ - + diff --git a/src/Report/Html/Renderer/Template/directory_item_branch.html.dist b/src/Report/Html/Renderer/Template/directory_item_branch.html.dist index 1d1884ff3..785eb8384 100644 --- a/src/Report/Html/Renderer/Template/directory_item_branch.html.dist +++ b/src/Report/Html/Renderer/Template/directory_item_branch.html.dist @@ -1,4 +1,4 @@ - + diff --git a/src/Report/Html/Renderer/Template/file.html.dist b/src/Report/Html/Renderer/Template/file.html.dist index d29103481..12c1c49e0 100644 --- a/src/Report/Html/Renderer/Template/file.html.dist +++ b/src/Report/Html/Renderer/Template/file.html.dist @@ -24,6 +24,14 @@
+
+ + + + + + +
{{icon}}{{name}} {{lines_bar}}
{{lines_executed_percent}}
{{icon}}{{name}} {{lines_bar}}
{{lines_executed_percent}}
@@ -60,5 +68,6 @@ + diff --git a/src/Report/Html/Renderer/Template/file_branch.html.dist b/src/Report/Html/Renderer/Template/file_branch.html.dist index 46be3117f..b7be206f4 100644 --- a/src/Report/Html/Renderer/Template/file_branch.html.dist +++ b/src/Report/Html/Renderer/Template/file_branch.html.dist @@ -24,6 +24,14 @@
+
+ + + + + + +
@@ -61,5 +69,6 @@ + diff --git a/src/Report/Html/Renderer/Template/file_item.html.dist b/src/Report/Html/Renderer/Template/file_item.html.dist index b1c0fca48..92157eae4 100644 --- a/src/Report/Html/Renderer/Template/file_item.html.dist +++ b/src/Report/Html/Renderer/Template/file_item.html.dist @@ -1,4 +1,4 @@ - + diff --git a/src/Report/Html/Renderer/Template/file_item_branch.html.dist b/src/Report/Html/Renderer/Template/file_item_branch.html.dist index 089407ba5..5c9144ac7 100644 --- a/src/Report/Html/Renderer/Template/file_item_branch.html.dist +++ b/src/Report/Html/Renderer/Template/file_item_branch.html.dist @@ -1,4 +1,4 @@ - + diff --git a/src/Report/Html/Renderer/Template/js/test-size-filter.js b/src/Report/Html/Renderer/Template/js/test-size-filter.js new file mode 100644 index 000000000..5bdfbd793 --- /dev/null +++ b/src/Report/Html/Renderer/Template/js/test-size-filter.js @@ -0,0 +1,155 @@ +$(function () { + var $btnGroup = $('[data-test-size-filter]').first().parent(); + var lowBound = parseFloat($btnGroup.data('low-upper-bound')) || 50; + var highBound = parseFloat($btnGroup.data('high-lower-bound')) || 90; + + function colorLevel(percent) { + if (percent <= lowBound) return 'danger'; + if (percent < highBound) return 'warning'; + return 'success'; + } + + function coverageBar(percent) { + var level = colorLevel(percent); + var p = percent.toFixed(2); + return '
' + + '
' + + '' + p + '% covered (' + level + ')' + + '
'; + } + + function pct(n, total) { + return total > 0 ? (n / total) * 100 : 0; + } + + function applyFilter(filter) { + $('tr[data-coverage]').each(function () { + var $tr = $(this); + var raw = $tr.attr('data-coverage'); + + if (!raw || raw === '{}') return; + + var d; + try { d = JSON.parse(raw); } catch (e) { return; } + + var linesTotal = d.linesTotal || 0; + var methodsTotal = d.methodsTotal || 0; + var classesTotal = d.classesTotal || 0; + + var linesExec, methodsTested, classesTested; + + if (filter === 'small') { + linesExec = d.linesSmall || 0; + methodsTested = d.methodsSmall || 0; + classesTested = d.classesSmall || 0; + } else if (filter === 'medium') { + linesExec = d.linesMedium || 0; + methodsTested = d.methodsMedium || 0; + classesTested = d.classesMedium || 0; + } else if (filter === 'large') { + linesExec = d.linesLarge || 0; + methodsTested = d.methodsLarge || 0; + classesTested = d.classesLarge || 0; + } else if (filter === 'small+medium') { + linesExec = d.linesSM || 0; + methodsTested = d.methodsSM || 0; + classesTested = d.classesSM || 0; + } else if (filter === 'small+medium+large') { + linesExec = d.linesSML || 0; + methodsTested = d.methodsSML || 0; + classesTested = d.classesSML || 0; + } else { + linesExec = d.linesAll || 0; + methodsTested = d.methodsAll || 0; + classesTested = d.classesAll || 0; + } + + var linesPct = pct(linesExec, linesTotal); + var methodsPct = pct(methodsTested, methodsTotal); + var classesPct = pct(classesTested, classesTotal); + + var cells = $tr.children('td'); + var nameCell = cells.eq(0); + var idx = 1; + + // Lines: bar, percent, number (3 cells) + var linesLevel = linesTotal > 0 ? colorLevel(linesPct) : ''; + + cells.eq(idx).attr('class', linesLevel + ' big').html(linesTotal > 0 ? coverageBar(linesPct) : ''); + cells.eq(idx + 1).attr('class', linesLevel + ' small').html( + '
' + (linesTotal > 0 ? linesPct.toFixed(2) + '%' : 'n/a') + '
' + ); + cells.eq(idx + 2).attr('class', linesLevel + ' small').html( + '
' + linesExec + ' / ' + linesTotal + '
' + ); + idx += 3; + + // Branches (if present): bar, percent, number (3 cells) - skip, don't modify + // Paths (if present): bar, percent, number (3 cells) - skip, don't modify + // We need to find where methods start. Methods are identified by having the methods data. + // For branch views: lines(3) + branches(3) + paths(3) + methods(3+crap) + classes(3) + // For non-branch: lines(3) + methods(3+crap?) + classes(3) + + // Detect if this is a branch view by checking total cell count + var totalCells = cells.length; + var methodsIdx, classesIdx, hasClasses; + + if (totalCells >= 16) { + // Branch view: name(1) + lines(3) + branches(3) + paths(3) + methods(3+crap) + classes(3) + methodsIdx = 10; + classesIdx = 14; + hasClasses = totalCells >= 17; + } else if (totalCells >= 11) { + // Non-branch file view: name(1) + lines(3) + methods(3+crap) + classes(3) + methodsIdx = 4; + classesIdx = 8; + hasClasses = true; + } else if (totalCells >= 10) { + // Directory view: name(1) + lines(3) + methods(3) + classes(3) + methodsIdx = 4; + classesIdx = 7; + hasClasses = true; + } else { + return; + } + + // Methods: bar, percent, number + var methodsLevel = methodsTotal > 0 ? colorLevel(methodsPct) : ''; + + cells.eq(methodsIdx).attr('class', methodsLevel + ' big').html(methodsTotal > 0 ? coverageBar(methodsPct) : ''); + cells.eq(methodsIdx + 1).attr('class', methodsLevel + ' small').html( + '
' + (methodsTotal > 0 ? methodsPct.toFixed(2) + '%' : 'n/a') + '
' + ); + cells.eq(methodsIdx + 2).attr('class', methodsLevel + ' small').html( + '
' + methodsTested + ' / ' + methodsTotal + '
' + ); + + // Classes: bar, percent, number + if (hasClasses && cells.eq(classesIdx).length) { + var classesLevel = classesTotal > 0 ? colorLevel(classesPct) : ''; + + cells.eq(classesIdx).attr('class', classesLevel + ' big').html(classesTotal > 0 ? coverageBar(classesPct) : ''); + cells.eq(classesIdx + 1).attr('class', classesLevel + ' small').html( + '
' + (classesTotal > 0 ? classesPct.toFixed(2) + '%' : 'n/a') + '
' + ); + cells.eq(classesIdx + 2).attr('class', classesLevel + ' small').html( + '
' + classesTested + ' / ' + classesTotal + '
' + ); + } + + // Update name cell background + nameCell.attr('class', linesLevel); + }); + } + + $('[data-test-size-filter]').on('click', function () { + var $btn = $(this); + + $btn.siblings().removeClass('active'); + $btn.addClass('active'); + + applyFilter($btn.data('test-size-filter')); + }); +}); diff --git a/src/Report/Html/Renderer/Template/method_item.html.dist b/src/Report/Html/Renderer/Template/method_item.html.dist index 2311d4564..5f410e5fe 100644 --- a/src/Report/Html/Renderer/Template/method_item.html.dist +++ b/src/Report/Html/Renderer/Template/method_item.html.dist @@ -1,4 +1,4 @@ - + diff --git a/src/Report/Html/Renderer/Template/method_item_branch.html.dist b/src/Report/Html/Renderer/Template/method_item_branch.html.dist index 12c218b2c..8d31280b6 100644 --- a/src/Report/Html/Renderer/Template/method_item_branch.html.dist +++ b/src/Report/Html/Renderer/Template/method_item_branch.html.dist @@ -1,4 +1,4 @@ - + diff --git a/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html b/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html index 9c503316d..5adb04ad7 100644 --- a/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html +++ b/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html @@ -26,6 +26,14 @@
+
+ + + + + + +
{{name}} {{lines_bar}}
{{lines_executed_percent}}
{{name}} {{lines_bar}}
{{lines_executed_percent}}
{{name}} {{lines_bar}}
{{lines_executed_percent}}
{{name}} {{lines_bar}}
{{lines_executed_percent}}
@@ -41,7 +49,7 @@ - + - + - + - + - + - +
Total
@@ -70,7 +78,7 @@
0 / 1
BankAccount
@@ -99,7 +107,7 @@
0 / 1
 getBalance
@@ -121,7 +129,7 @@
 setBalance
@@ -143,7 +151,7 @@
 depositMoney
@@ -165,7 +173,7 @@
 withdrawMoney
@@ -247,5 +255,6 @@

Legend

+ diff --git a/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html b/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html index 0afe13665..5a41556bc 100644 --- a/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html +++ b/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html @@ -2,7 +2,7 @@ - Dashboard for %s + Dashboard for /Users/sb/Work/OpenSource/php-code-coverage/tests/_files @@ -160,7 +160,7 @@

 

diff --git a/tests/_files/Report/HTML/CoverageForBankAccount/index.html b/tests/_files/Report/HTML/CoverageForBankAccount/index.html index 1112add13..f76d2fe8f 100644 --- a/tests/_files/Report/HTML/CoverageForBankAccount/index.html +++ b/tests/_files/Report/HTML/CoverageForBankAccount/index.html @@ -16,7 +16,7 @@
+
+ + + + + + +
@@ -41,7 +49,7 @@ - + - +
Total
@@ -69,7 +77,7 @@
0 / 1
BankAccount.php
@@ -114,5 +122,8 @@

Legend

+ + + diff --git a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html index 1ba16a678..5e5518833 100644 --- a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html +++ b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html @@ -2,7 +2,7 @@ - Dashboard for %s + Dashboard for /Users/sb/Work/OpenSource/php-code-coverage/tests/_files @@ -150,7 +150,7 @@

 

diff --git a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html index ff7813e53..8066cc32b 100644 --- a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html +++ b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html @@ -16,7 +16,7 @@
+
+ + + + + + +
@@ -41,7 +49,7 @@ - + - +
Total
@@ -69,7 +77,7 @@
1 / 1
source_with_class_and_anonymous_function.php
@@ -114,5 +122,8 @@

Legend

+ + + diff --git a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html index ff821b35d..afa5cb451 100644 --- a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html +++ b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html @@ -26,6 +26,14 @@
+
+ + + + + + +
@@ -41,7 +49,7 @@ - + - + - +
Total
@@ -70,7 +78,7 @@
1 / 1
CoveredClassWithAnonymousFunctionInStaticMethod
@@ -99,7 +107,7 @@
1 / 1
 runAnonymous
@@ -166,5 +174,6 @@

Legend

+ diff --git a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html index 766b18a82..757a873cf 100644 --- a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html +++ b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html @@ -2,7 +2,7 @@ - Dashboard for %s + Dashboard for /Users/sb/Work/OpenSource/php-code-coverage/tests/_files @@ -84,7 +84,7 @@

 

diff --git a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html index 73c808041..9690fdc50 100644 --- a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html +++ b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html @@ -16,7 +16,7 @@
+
+ + + + + + +
@@ -41,7 +49,7 @@ - + - +
Total
@@ -64,7 +72,7 @@
0 / 0
source_with_ignore.php
@@ -104,5 +112,8 @@

Legend

+ + + diff --git a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html index 5b61e5aed..6abcb72d1 100644 --- a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html +++ b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html @@ -26,6 +26,14 @@
+
+ + + + + + +
@@ -41,7 +49,7 @@ - + - + @@ -77,7 +85,7 @@ - + @@ -91,7 +99,7 @@ - + @@ -103,7 +111,7 @@ - + @@ -117,7 +125,7 @@ - + @@ -197,5 +205,6 @@

Legend

+ diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php.html index 681941ba2..342c898c2 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php.html @@ -2,7 +2,7 @@ - Code Coverage for %sBankAccount.php + Code Coverage for %a @@ -26,6 +26,14 @@
+
+ + + + + + +
Total
@@ -65,7 +73,7 @@
0 / 0
baz
n/a
Foo
n/a
0 / 0
 bar
n/a
Bar
n/a
0 / 0
 foo
n/a
@@ -43,252 +51,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Total
-
- 62.50% covered (warning) -
-
-
62.50%
5 / 8
-
- 42.86% covered (danger) -
-
-
42.86%
3 / 7
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BankAccount
-
- 62.50% covered (warning) -
-
-
62.50%
5 / 8
-
- 42.86% covered (danger) -
-
-
42.86%
3 / 7
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
6.60
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getBalance
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setBalance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 depositMoney
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 withdrawMoney
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
-%a +%a
+
+

Legend

+

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

+

+ Generated by php-code-coverage %s using %s at %s. +

+ + + +
+
+ + + + - \ No newline at end of file + diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_branch.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_branch.html index 681941ba2..033150baf 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_branch.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_branch.html @@ -2,7 +2,7 @@ - Code Coverage for %sBankAccount.php + Code Coverage for %a @@ -26,6 +26,14 @@
+
+ + + + + + +
@@ -43,252 +51,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Total
-
- 62.50% covered (warning) -
-
-
62.50%
5 / 8
-
- 42.86% covered (danger) -
-
-
42.86%
3 / 7
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BankAccount
-
- 62.50% covered (warning) -
-
-
62.50%
5 / 8
-
- 42.86% covered (danger) -
-
-
42.86%
3 / 7
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
6.60
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getBalance
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setBalance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 depositMoney
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 withdrawMoney
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
-%a +%a +
+ + + + - \ No newline at end of file + diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_path.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_path.html index 681941ba2..033150baf 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_path.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_path.html @@ -2,7 +2,7 @@ - Code Coverage for %sBankAccount.php + Code Coverage for %a @@ -26,6 +26,14 @@
+
+ + + + + + +
@@ -43,252 +51,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Total
-
- 62.50% covered (warning) -
-
-
62.50%
5 / 8
-
- 42.86% covered (danger) -
-
-
42.86%
3 / 7
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BankAccount
-
- 62.50% covered (warning) -
-
-
62.50%
5 / 8
-
- 42.86% covered (danger) -
-
-
42.86%
3 / 7
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
6.60
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getBalance
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setBalance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 depositMoney
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 withdrawMoney
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
-%a +%a +
+ + + + - \ No newline at end of file + diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/dashboard.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/dashboard.html index c4e377bf4..6a0602b84 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/dashboard.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/dashboard.html @@ -2,7 +2,7 @@ - Dashboard for %s + Dashboard for /Users/sb/Work/OpenSource/php-code-coverage/tests/_files @@ -160,7 +160,7 @@

 

diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/index.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/index.html index f4467d57c..efef60283 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/index.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/index.html @@ -16,7 +16,7 @@
+
+ + + + + + +
@@ -43,7 +51,7 @@ - + - +
Total
@@ -87,7 +95,7 @@
0 / 1
BankAccount.php [line] [branch] [path]
@@ -148,5 +156,8 @@

Legend

+ + + diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/dashboard.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/dashboard.html index aefef1c8d..3c2349911 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/dashboard.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/dashboard.html @@ -2,7 +2,7 @@ - Dashboard for %s + Dashboard for /Users/sb/Work/OpenSource/php-code-coverage/tests/_files @@ -81,7 +81,7 @@

 

diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/index.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/index.html index 51d43fe05..73a00177d 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/index.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/index.html @@ -16,7 +16,7 @@
+
+ + + + + + +
@@ -43,7 +51,7 @@ - + - +
Total
@@ -82,7 +90,7 @@
0 / 0
source_without_namespace.php [line] [branch] [path]
@@ -138,5 +146,8 @@

Legend

+ + + diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php.html index 1446f796d..f4c173932 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php.html @@ -26,6 +26,14 @@
+
+ + + + + + +
@@ -43,7 +51,7 @@ - + - + - + @@ -185,5 +193,6 @@

Legend

+ diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_branch.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_branch.html index 590d2010b..769b1b27f 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_branch.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_branch.html @@ -26,6 +26,14 @@
+
+ + + + + + +
Total
@@ -83,7 +91,7 @@
0 / 0
foo
@@ -121,7 +129,7 @@
Foo
n/a
@@ -43,7 +51,7 @@ - + - + - + @@ -207,7 +215,7 @@
foo
Total
@@ -83,7 +91,7 @@
0 / 0
foo
@@ -121,7 +129,7 @@
Foo
n/a
-
{closure:%ssource_without_namespace.php:14-14}
+
{closure:/Users/sb/Work/OpenSource/php-code-coverage/tests/_files/source_without_namespace.php:14-14}
@@ -231,5 +239,6 @@

Legend

+ diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html index 640b60b1f..d7e8ab867 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html @@ -26,6 +26,14 @@
+
+ + + + + + +
14    $baz = function () {};
@@ -43,7 +51,7 @@ - + - + - + @@ -208,7 +216,7 @@
foo
Total
@@ -83,7 +91,7 @@
0 / 0
foo
@@ -121,7 +129,7 @@
Foo
n/a
-
{closure:%ssource_without_namespace.php:14-14}
+
{closure:/Users/sb/Work/OpenSource/php-code-coverage/tests/_files/source_without_namespace.php:14-14}
@@ -232,5 +240,6 @@

Legend

+ From 9440e521cf41a3766dda3a8b4959406ec1cdd52d Mon Sep 17 00:00:00 2001 From: Sebastian Bergmann Date: Wed, 22 Apr 2026 18:45:12 +0200 Subject: [PATCH 2/6] Reorder buttons --- src/Report/Html/Renderer/Template/directory.html.dist | 2 +- src/Report/Html/Renderer/Template/directory_branch.html.dist | 2 +- src/Report/Html/Renderer/Template/file.html.dist | 2 +- src/Report/Html/Renderer/Template/file_branch.html.dist | 2 +- .../Report/HTML/CoverageForBankAccount/BankAccount.php.html | 2 +- tests/_files/Report/HTML/CoverageForBankAccount/index.html | 2 +- .../HTML/CoverageForClassWithAnonymousFunction/index.html | 2 +- .../source_with_class_and_anonymous_function.php.html | 2 +- .../Report/HTML/CoverageForFileWithIgnoredLines/index.html | 2 +- .../CoverageForFileWithIgnoredLines/source_with_ignore.php.html | 2 +- .../Report/HTML/PathCoverageForBankAccount/BankAccount.php.html | 2 +- .../HTML/PathCoverageForBankAccount/BankAccount.php_branch.html | 2 +- .../HTML/PathCoverageForBankAccount/BankAccount.php_path.html | 2 +- tests/_files/Report/HTML/PathCoverageForBankAccount/index.html | 2 +- .../HTML/PathCoverageForSourceWithoutNamespace/index.html | 2 +- .../source_without_namespace.php.html | 2 +- .../source_without_namespace.php_branch.html | 2 +- .../source_without_namespace.php_path.html | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Report/Html/Renderer/Template/directory.html.dist b/src/Report/Html/Renderer/Template/directory.html.dist index 8c2a6725a..c5bee801a 100644 --- a/src/Report/Html/Renderer/Template/directory.html.dist +++ b/src/Report/Html/Renderer/Template/directory.html.dist @@ -25,12 +25,12 @@
- +
14    $baz = function () {};
diff --git a/src/Report/Html/Renderer/Template/directory_branch.html.dist b/src/Report/Html/Renderer/Template/directory_branch.html.dist index 1a5d6dc86..cf0ba02f7 100644 --- a/src/Report/Html/Renderer/Template/directory_branch.html.dist +++ b/src/Report/Html/Renderer/Template/directory_branch.html.dist @@ -25,12 +25,12 @@
- +
diff --git a/src/Report/Html/Renderer/Template/file.html.dist b/src/Report/Html/Renderer/Template/file.html.dist index 12c1c49e0..448b54367 100644 --- a/src/Report/Html/Renderer/Template/file.html.dist +++ b/src/Report/Html/Renderer/Template/file.html.dist @@ -25,12 +25,12 @@
- +
diff --git a/src/Report/Html/Renderer/Template/file_branch.html.dist b/src/Report/Html/Renderer/Template/file_branch.html.dist index b7be206f4..6670ac7a8 100644 --- a/src/Report/Html/Renderer/Template/file_branch.html.dist +++ b/src/Report/Html/Renderer/Template/file_branch.html.dist @@ -25,12 +25,12 @@
- +
diff --git a/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html b/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html index 5adb04ad7..4a5cbeea5 100644 --- a/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html +++ b/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/CoverageForBankAccount/index.html b/tests/_files/Report/HTML/CoverageForBankAccount/index.html index f76d2fe8f..7c9bdcbc3 100644 --- a/tests/_files/Report/HTML/CoverageForBankAccount/index.html +++ b/tests/_files/Report/HTML/CoverageForBankAccount/index.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html index 8066cc32b..04695560c 100644 --- a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html +++ b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html index afa5cb451..7996a90dd 100644 --- a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html +++ b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html index 9690fdc50..03e9b8d50 100644 --- a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html +++ b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html index 6abcb72d1..e3378b881 100644 --- a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html +++ b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php.html index 342c898c2..514c50463 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_branch.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_branch.html index 033150baf..4568015f3 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_branch.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_branch.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_path.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_path.html index 033150baf..4568015f3 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_path.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_path.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/index.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/index.html index efef60283..a2519671d 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/index.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/index.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/index.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/index.html index 73a00177d..685cfe9d7 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/index.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/index.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php.html index f4c173932..e49f89381 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_branch.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_branch.html index 769b1b27f..b9ad8c263 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_branch.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_branch.html @@ -27,12 +27,12 @@
- +
diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html index d7e8ab867..3cb1e01e2 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html @@ -27,12 +27,12 @@
- +
From 42930189d9532df44ea4aac19aa4a125e0e49308 Mon Sep 17 00:00:00 2001 From: Sebastian Bergmann Date: Wed, 22 Apr 2026 19:08:32 +0200 Subject: [PATCH 3/6] Fix expectations --- tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html | 2 +- tests/_files/Report/HTML/CoverageForBankAccount/index.html | 2 +- .../HTML/CoverageForClassWithAnonymousFunction/dashboard.html | 2 +- .../HTML/CoverageForClassWithAnonymousFunction/index.html | 2 +- .../Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html | 2 +- .../Report/HTML/CoverageForFileWithIgnoredLines/index.html | 2 +- .../Report/HTML/PathCoverageForBankAccount/dashboard.html | 2 +- tests/_files/Report/HTML/PathCoverageForBankAccount/index.html | 2 +- .../HTML/PathCoverageForSourceWithoutNamespace/dashboard.html | 2 +- .../HTML/PathCoverageForSourceWithoutNamespace/index.html | 2 +- .../source_without_namespace.php_branch.html | 2 +- .../source_without_namespace.php_path.html | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html b/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html index 5a41556bc..0981c2568 100644 --- a/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html +++ b/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html @@ -2,7 +2,7 @@ - Dashboard for /Users/sb/Work/OpenSource/php-code-coverage/tests/_files + Dashboard for %s diff --git a/tests/_files/Report/HTML/CoverageForBankAccount/index.html b/tests/_files/Report/HTML/CoverageForBankAccount/index.html index 7c9bdcbc3..d1d9ed24b 100644 --- a/tests/_files/Report/HTML/CoverageForBankAccount/index.html +++ b/tests/_files/Report/HTML/CoverageForBankAccount/index.html @@ -16,7 +16,7 @@
-
{closure:/Users/sb/Work/OpenSource/php-code-coverage/tests/_files/source_without_namespace.php:14-14}
+
{closure:%s%esource_without_namespace.php:14-14}
diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html index 3cb1e01e2..1f457e541 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html @@ -216,7 +216,7 @@
foo
14    $baz = function () {};
-
{closure:/Users/sb/Work/OpenSource/php-code-coverage/tests/_files/source_without_namespace.php:14-14}
+
{closure:%s%esource_without_namespace.php:14-14}
From c655ffecc4267c55591273a2b979f00ed80f8ee6 Mon Sep 17 00:00:00 2001 From: Sebastian Bergmann Date: Fri, 8 May 2026 07:42:18 +0200 Subject: [PATCH 4/6] Fix after rebase --- .../Template/directory_branch_and_path.html.dist | 11 +++++++++++ .../Template/directory_item_branch_and_path.html.dist | 2 +- .../Renderer/Template/file_branch_and_path.html.dist | 9 +++++++++ .../Template/file_item_branch_and_path.html.dist | 2 +- .../Template/method_item_branch_and_path.html.dist | 2 +- 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/Report/Html/Renderer/Template/directory_branch_and_path.html.dist b/src/Report/Html/Renderer/Template/directory_branch_and_path.html.dist index a40c2e128..cc095b5f3 100644 --- a/src/Report/Html/Renderer/Template/directory_branch_and_path.html.dist +++ b/src/Report/Html/Renderer/Template/directory_branch_and_path.html.dist @@ -24,6 +24,14 @@
+
+ + + + + + +
14    $baz = function () {};
@@ -58,5 +66,8 @@

+ + + diff --git a/src/Report/Html/Renderer/Template/directory_item_branch_and_path.html.dist b/src/Report/Html/Renderer/Template/directory_item_branch_and_path.html.dist index 532a436c2..f5087ceab 100644 --- a/src/Report/Html/Renderer/Template/directory_item_branch_and_path.html.dist +++ b/src/Report/Html/Renderer/Template/directory_item_branch_and_path.html.dist @@ -1,4 +1,4 @@ - + diff --git a/src/Report/Html/Renderer/Template/file_branch_and_path.html.dist b/src/Report/Html/Renderer/Template/file_branch_and_path.html.dist index b8bcf3747..1d92ade6f 100644 --- a/src/Report/Html/Renderer/Template/file_branch_and_path.html.dist +++ b/src/Report/Html/Renderer/Template/file_branch_and_path.html.dist @@ -24,6 +24,14 @@
+
+ + + + + + +
{{icon}}{{name}} {{lines_bar}}
{{lines_executed_percent}}
@@ -62,5 +70,6 @@ + diff --git a/src/Report/Html/Renderer/Template/file_item_branch_and_path.html.dist b/src/Report/Html/Renderer/Template/file_item_branch_and_path.html.dist index 505025179..434189ab5 100644 --- a/src/Report/Html/Renderer/Template/file_item_branch_and_path.html.dist +++ b/src/Report/Html/Renderer/Template/file_item_branch_and_path.html.dist @@ -1,4 +1,4 @@ - + diff --git a/src/Report/Html/Renderer/Template/method_item_branch_and_path.html.dist b/src/Report/Html/Renderer/Template/method_item_branch_and_path.html.dist index 36d6cb741..cd72ebcfb 100644 --- a/src/Report/Html/Renderer/Template/method_item_branch_and_path.html.dist +++ b/src/Report/Html/Renderer/Template/method_item_branch_and_path.html.dist @@ -1,4 +1,4 @@ - + From 4f0ef8914003543cdc19113270c31c967c1a4d6b Mon Sep 17 00:00:00 2001 From: Sebastian Bergmann Date: Fri, 8 May 2026 07:59:39 +0200 Subject: [PATCH 5/6] Implement suggestion by Sebastian Feldmann --- src/Data/ProcessedClassType.php | 2 + src/Data/ProcessedFunctionType.php | 2 + src/Data/ProcessedMethodType.php | 2 + src/Data/ProcessedTraitType.php | 2 + src/Node/AbstractNode.php | 56 ++++++ src/Node/Directory.php | 142 +++++++++++++++ src/Node/File.php | 164 ++++++++++++++++++ src/Report/Html/Renderer/Directory.php | 6 + src/Report/Html/Renderer/File.php | 6 + .../Renderer/Template/directory.html.dist | 13 +- .../Template/directory_branch.html.dist | 13 +- .../directory_branch_and_path.html.dist | 13 +- .../Html/Renderer/Template/file.html.dist | 13 +- .../Renderer/Template/file_branch.html.dist | 13 +- .../Template/file_branch_and_path.html.dist | 13 +- .../Renderer/Template/js/test-size-filter.js | 100 ++++++----- .../BankAccount.php.html | 15 +- .../HTML/CoverageForBankAccount/index.html | 17 +- .../index.html | 17 +- ...with_class_and_anonymous_function.php.html | 15 +- .../index.html | 17 +- .../source_with_ignore.php.html | 15 +- .../BankAccount.php.html | 13 +- .../BankAccount.php_branch.html | 13 +- .../BankAccount.php_path.html | 13 +- .../PathCoverageForBankAccount/index.html | 17 +- .../index.html | 17 +- .../source_without_namespace.php.html | 15 +- .../source_without_namespace.php_branch.html | 15 +- .../source_without_namespace.php_path.html | 15 +- 30 files changed, 591 insertions(+), 183 deletions(-) diff --git a/src/Data/ProcessedClassType.php b/src/Data/ProcessedClassType.php index 716722c62..482fbeefe 100644 --- a/src/Data/ProcessedClassType.php +++ b/src/Data/ProcessedClassType.php @@ -30,6 +30,8 @@ final class ProcessedClassType public int $executedLinesByMediumTests = 0; public int $executedLinesByLargeTests = 0; public int $executedLinesBySmallOrMediumTests = 0; + public int $executedLinesBySmallOrLargeTests = 0; + public int $executedLinesByMediumOrLargeTests = 0; public int $executedLinesBySmallOrMediumOrLargeTests = 0; public int $executableBranches; public int $executedBranches; diff --git a/src/Data/ProcessedFunctionType.php b/src/Data/ProcessedFunctionType.php index 72716880f..d7bed5545 100644 --- a/src/Data/ProcessedFunctionType.php +++ b/src/Data/ProcessedFunctionType.php @@ -27,6 +27,8 @@ final class ProcessedFunctionType public int $executedLinesByMediumTests = 0; public int $executedLinesByLargeTests = 0; public int $executedLinesBySmallOrMediumTests = 0; + public int $executedLinesBySmallOrLargeTests = 0; + public int $executedLinesByMediumOrLargeTests = 0; public int $executedLinesBySmallOrMediumOrLargeTests = 0; public int $executableBranches; public int $executedBranches; diff --git a/src/Data/ProcessedMethodType.php b/src/Data/ProcessedMethodType.php index cc4b6ce90..cfd5da7e1 100644 --- a/src/Data/ProcessedMethodType.php +++ b/src/Data/ProcessedMethodType.php @@ -27,6 +27,8 @@ final class ProcessedMethodType public int $executedLinesByMediumTests = 0; public int $executedLinesByLargeTests = 0; public int $executedLinesBySmallOrMediumTests = 0; + public int $executedLinesBySmallOrLargeTests = 0; + public int $executedLinesByMediumOrLargeTests = 0; public int $executedLinesBySmallOrMediumOrLargeTests = 0; public int $executableBranches; public int $executedBranches; diff --git a/src/Data/ProcessedTraitType.php b/src/Data/ProcessedTraitType.php index d8aba39af..cb978f4f3 100644 --- a/src/Data/ProcessedTraitType.php +++ b/src/Data/ProcessedTraitType.php @@ -30,6 +30,8 @@ final class ProcessedTraitType public int $executedLinesByMediumTests = 0; public int $executedLinesByLargeTests = 0; public int $executedLinesBySmallOrMediumTests = 0; + public int $executedLinesBySmallOrLargeTests = 0; + public int $executedLinesByMediumOrLargeTests = 0; public int $executedLinesBySmallOrMediumOrLargeTests = 0; public int $executableBranches; public int $executedBranches; diff --git a/src/Node/AbstractNode.php b/src/Node/AbstractNode.php index aa1e34b29..225d894b2 100644 --- a/src/Node/AbstractNode.php +++ b/src/Node/AbstractNode.php @@ -167,6 +167,22 @@ public function percentageOfExecutedLinesBySmallOrMediumTests(): Percentage ); } + public function percentageOfExecutedLinesBySmallOrLargeTests(): Percentage + { + return Percentage::fromFractionAndTotal( + $this->numberOfExecutedLinesBySmallOrLargeTests(), + $this->numberOfExecutableLines(), + ); + } + + public function percentageOfExecutedLinesByMediumOrLargeTests(): Percentage + { + return Percentage::fromFractionAndTotal( + $this->numberOfExecutedLinesByMediumOrLargeTests(), + $this->numberOfExecutableLines(), + ); + } + public function percentageOfExecutedLinesBySmallOrMediumOrLargeTests(): Percentage { return Percentage::fromFractionAndTotal( @@ -221,6 +237,16 @@ public function numberOfTestedClassesAndTraitsBySmallOrMediumTests(): int return $this->numberOfTestedClassesBySmallOrMediumTests() + $this->numberOfTestedTraitsBySmallOrMediumTests(); } + public function numberOfTestedClassesAndTraitsBySmallOrLargeTests(): int + { + return $this->numberOfTestedClassesBySmallOrLargeTests() + $this->numberOfTestedTraitsBySmallOrLargeTests(); + } + + public function numberOfTestedClassesAndTraitsByMediumOrLargeTests(): int + { + return $this->numberOfTestedClassesByMediumOrLargeTests() + $this->numberOfTestedTraitsByMediumOrLargeTests(); + } + public function numberOfTestedClassesAndTraitsBySmallOrMediumOrLargeTests(): int { return $this->numberOfTestedClassesBySmallOrMediumOrLargeTests() + $this->numberOfTestedTraitsBySmallOrMediumOrLargeTests(); @@ -264,6 +290,16 @@ public function numberOfTestedFunctionsAndMethodsBySmallOrMediumTests(): int return $this->numberOfTestedFunctionsBySmallOrMediumTests() + $this->numberOfTestedMethodsBySmallOrMediumTests(); } + public function numberOfTestedFunctionsAndMethodsBySmallOrLargeTests(): int + { + return $this->numberOfTestedFunctionsBySmallOrLargeTests() + $this->numberOfTestedMethodsBySmallOrLargeTests(); + } + + public function numberOfTestedFunctionsAndMethodsByMediumOrLargeTests(): int + { + return $this->numberOfTestedFunctionsByMediumOrLargeTests() + $this->numberOfTestedMethodsByMediumOrLargeTests(); + } + public function numberOfTestedFunctionsAndMethodsBySmallOrMediumOrLargeTests(): int { return $this->numberOfTestedFunctionsBySmallOrMediumOrLargeTests() + $this->numberOfTestedMethodsBySmallOrMediumOrLargeTests(); @@ -316,6 +352,10 @@ abstract public function numberOfExecutedLinesByLargeTests(): int; abstract public function numberOfExecutedLinesBySmallOrMediumTests(): int; + abstract public function numberOfExecutedLinesBySmallOrLargeTests(): int; + + abstract public function numberOfExecutedLinesByMediumOrLargeTests(): int; + abstract public function numberOfExecutedLinesBySmallOrMediumOrLargeTests(): int; abstract public function numberOfExecutableBranches(): int; @@ -340,6 +380,10 @@ abstract public function numberOfTestedClassesByLargeTests(): int; abstract public function numberOfTestedClassesBySmallOrMediumTests(): int; + abstract public function numberOfTestedClassesBySmallOrLargeTests(): int; + + abstract public function numberOfTestedClassesByMediumOrLargeTests(): int; + abstract public function numberOfTestedClassesBySmallOrMediumOrLargeTests(): int; abstract public function numberOfTraits(): int; @@ -354,6 +398,10 @@ abstract public function numberOfTestedTraitsByLargeTests(): int; abstract public function numberOfTestedTraitsBySmallOrMediumTests(): int; + abstract public function numberOfTestedTraitsBySmallOrLargeTests(): int; + + abstract public function numberOfTestedTraitsByMediumOrLargeTests(): int; + abstract public function numberOfTestedTraitsBySmallOrMediumOrLargeTests(): int; abstract public function numberOfMethods(): int; @@ -368,6 +416,10 @@ abstract public function numberOfTestedMethodsByLargeTests(): int; abstract public function numberOfTestedMethodsBySmallOrMediumTests(): int; + abstract public function numberOfTestedMethodsBySmallOrLargeTests(): int; + + abstract public function numberOfTestedMethodsByMediumOrLargeTests(): int; + abstract public function numberOfTestedMethodsBySmallOrMediumOrLargeTests(): int; abstract public function numberOfFunctions(): int; @@ -382,6 +434,10 @@ abstract public function numberOfTestedFunctionsByLargeTests(): int; abstract public function numberOfTestedFunctionsBySmallOrMediumTests(): int; + abstract public function numberOfTestedFunctionsBySmallOrLargeTests(): int; + + abstract public function numberOfTestedFunctionsByMediumOrLargeTests(): int; + abstract public function numberOfTestedFunctionsBySmallOrMediumOrLargeTests(): int; private function processId(): void diff --git a/src/Node/Directory.php b/src/Node/Directory.php index be7add75c..8be443fcf 100644 --- a/src/Node/Directory.php +++ b/src/Node/Directory.php @@ -65,6 +65,8 @@ final class Directory extends AbstractNode implements IteratorAggregate private int $numExecutedLinesByMediumTests = -1; private int $numExecutedLinesByLargeTests = -1; private int $numExecutedLinesBySmallOrMediumTests = -1; + private int $numExecutedLinesBySmallOrLargeTests = -1; + private int $numExecutedLinesByMediumOrLargeTests = -1; private int $numExecutedLinesBySmallOrMediumOrLargeTests = -1; private int $numExecutableBranches = -1; private int $numExecutedBranches = -1; @@ -77,6 +79,8 @@ final class Directory extends AbstractNode implements IteratorAggregate private int $numTestedClassesByMediumTests = -1; private int $numTestedClassesByLargeTests = -1; private int $numTestedClassesBySmallOrMediumTests = -1; + private int $numTestedClassesBySmallOrLargeTests = -1; + private int $numTestedClassesByMediumOrLargeTests = -1; private int $numTestedClassesBySmallOrMediumOrLargeTests = -1; private int $numTraits = -1; private int $numTestedTraits = -1; @@ -84,6 +88,8 @@ final class Directory extends AbstractNode implements IteratorAggregate private int $numTestedTraitsByMediumTests = -1; private int $numTestedTraitsByLargeTests = -1; private int $numTestedTraitsBySmallOrMediumTests = -1; + private int $numTestedTraitsBySmallOrLargeTests = -1; + private int $numTestedTraitsByMediumOrLargeTests = -1; private int $numTestedTraitsBySmallOrMediumOrLargeTests = -1; private int $numMethods = -1; private int $numTestedMethods = -1; @@ -91,6 +97,8 @@ final class Directory extends AbstractNode implements IteratorAggregate private int $numTestedMethodsByMediumTests = -1; private int $numTestedMethodsByLargeTests = -1; private int $numTestedMethodsBySmallOrMediumTests = -1; + private int $numTestedMethodsBySmallOrLargeTests = -1; + private int $numTestedMethodsByMediumOrLargeTests = -1; private int $numTestedMethodsBySmallOrMediumOrLargeTests = -1; private int $numFunctions = -1; private int $numTestedFunctions = -1; @@ -98,6 +106,8 @@ final class Directory extends AbstractNode implements IteratorAggregate private int $numTestedFunctionsByMediumTests = -1; private int $numTestedFunctionsByLargeTests = -1; private int $numTestedFunctionsBySmallOrMediumTests = -1; + private int $numTestedFunctionsBySmallOrLargeTests = -1; + private int $numTestedFunctionsByMediumOrLargeTests = -1; private int $numTestedFunctionsBySmallOrMediumOrLargeTests = -1; public function count(): int @@ -147,6 +157,8 @@ public function addFile(File $file): void $this->numExecutedLinesByMediumTests = -1; $this->numExecutedLinesByLargeTests = -1; $this->numExecutedLinesBySmallOrMediumTests = -1; + $this->numExecutedLinesBySmallOrLargeTests = -1; + $this->numExecutedLinesByMediumOrLargeTests = -1; $this->numExecutedLinesBySmallOrMediumOrLargeTests = -1; } @@ -330,6 +342,32 @@ public function numberOfExecutedLinesBySmallOrMediumTests(): int return $this->numExecutedLinesBySmallOrMediumTests; } + public function numberOfExecutedLinesBySmallOrLargeTests(): int + { + if ($this->numExecutedLinesBySmallOrLargeTests === -1) { + $this->numExecutedLinesBySmallOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numExecutedLinesBySmallOrLargeTests += $child->numberOfExecutedLinesBySmallOrLargeTests(); + } + } + + return $this->numExecutedLinesBySmallOrLargeTests; + } + + public function numberOfExecutedLinesByMediumOrLargeTests(): int + { + if ($this->numExecutedLinesByMediumOrLargeTests === -1) { + $this->numExecutedLinesByMediumOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numExecutedLinesByMediumOrLargeTests += $child->numberOfExecutedLinesByMediumOrLargeTests(); + } + } + + return $this->numExecutedLinesByMediumOrLargeTests; + } + public function numberOfExecutedLinesBySmallOrMediumOrLargeTests(): int { if ($this->numExecutedLinesBySmallOrMediumOrLargeTests === -1) { @@ -486,6 +524,32 @@ public function numberOfTestedClassesBySmallOrMediumTests(): int return $this->numTestedClassesBySmallOrMediumTests; } + public function numberOfTestedClassesBySmallOrLargeTests(): int + { + if ($this->numTestedClassesBySmallOrLargeTests === -1) { + $this->numTestedClassesBySmallOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedClassesBySmallOrLargeTests += $child->numberOfTestedClassesBySmallOrLargeTests(); + } + } + + return $this->numTestedClassesBySmallOrLargeTests; + } + + public function numberOfTestedClassesByMediumOrLargeTests(): int + { + if ($this->numTestedClassesByMediumOrLargeTests === -1) { + $this->numTestedClassesByMediumOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedClassesByMediumOrLargeTests += $child->numberOfTestedClassesByMediumOrLargeTests(); + } + } + + return $this->numTestedClassesByMediumOrLargeTests; + } + public function numberOfTestedClassesBySmallOrMediumOrLargeTests(): int { if ($this->numTestedClassesBySmallOrMediumOrLargeTests === -1) { @@ -577,6 +641,32 @@ public function numberOfTestedTraitsBySmallOrMediumTests(): int return $this->numTestedTraitsBySmallOrMediumTests; } + public function numberOfTestedTraitsBySmallOrLargeTests(): int + { + if ($this->numTestedTraitsBySmallOrLargeTests === -1) { + $this->numTestedTraitsBySmallOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedTraitsBySmallOrLargeTests += $child->numberOfTestedTraitsBySmallOrLargeTests(); + } + } + + return $this->numTestedTraitsBySmallOrLargeTests; + } + + public function numberOfTestedTraitsByMediumOrLargeTests(): int + { + if ($this->numTestedTraitsByMediumOrLargeTests === -1) { + $this->numTestedTraitsByMediumOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedTraitsByMediumOrLargeTests += $child->numberOfTestedTraitsByMediumOrLargeTests(); + } + } + + return $this->numTestedTraitsByMediumOrLargeTests; + } + public function numberOfTestedTraitsBySmallOrMediumOrLargeTests(): int { if ($this->numTestedTraitsBySmallOrMediumOrLargeTests === -1) { @@ -668,6 +758,32 @@ public function numberOfTestedMethodsBySmallOrMediumTests(): int return $this->numTestedMethodsBySmallOrMediumTests; } + public function numberOfTestedMethodsBySmallOrLargeTests(): int + { + if ($this->numTestedMethodsBySmallOrLargeTests === -1) { + $this->numTestedMethodsBySmallOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedMethodsBySmallOrLargeTests += $child->numberOfTestedMethodsBySmallOrLargeTests(); + } + } + + return $this->numTestedMethodsBySmallOrLargeTests; + } + + public function numberOfTestedMethodsByMediumOrLargeTests(): int + { + if ($this->numTestedMethodsByMediumOrLargeTests === -1) { + $this->numTestedMethodsByMediumOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedMethodsByMediumOrLargeTests += $child->numberOfTestedMethodsByMediumOrLargeTests(); + } + } + + return $this->numTestedMethodsByMediumOrLargeTests; + } + public function numberOfTestedMethodsBySmallOrMediumOrLargeTests(): int { if ($this->numTestedMethodsBySmallOrMediumOrLargeTests === -1) { @@ -759,6 +875,32 @@ public function numberOfTestedFunctionsBySmallOrMediumTests(): int return $this->numTestedFunctionsBySmallOrMediumTests; } + public function numberOfTestedFunctionsBySmallOrLargeTests(): int + { + if ($this->numTestedFunctionsBySmallOrLargeTests === -1) { + $this->numTestedFunctionsBySmallOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedFunctionsBySmallOrLargeTests += $child->numberOfTestedFunctionsBySmallOrLargeTests(); + } + } + + return $this->numTestedFunctionsBySmallOrLargeTests; + } + + public function numberOfTestedFunctionsByMediumOrLargeTests(): int + { + if ($this->numTestedFunctionsByMediumOrLargeTests === -1) { + $this->numTestedFunctionsByMediumOrLargeTests = 0; + + foreach ($this->children as $child) { + $this->numTestedFunctionsByMediumOrLargeTests += $child->numberOfTestedFunctionsByMediumOrLargeTests(); + } + } + + return $this->numTestedFunctionsByMediumOrLargeTests; + } + public function numberOfTestedFunctionsBySmallOrMediumOrLargeTests(): int { if ($this->numTestedFunctionsBySmallOrMediumOrLargeTests === -1) { diff --git a/src/Node/File.php b/src/Node/File.php index 8801e9264..ee15fa5a5 100644 --- a/src/Node/File.php +++ b/src/Node/File.php @@ -62,6 +62,8 @@ final class File extends AbstractNode private int $numExecutedLinesByMediumTests = 0; private int $numExecutedLinesByLargeTests = 0; private int $numExecutedLinesBySmallOrMediumTests = 0; + private int $numExecutedLinesBySmallOrLargeTests = 0; + private int $numExecutedLinesByMediumOrLargeTests = 0; private int $numExecutedLinesBySmallOrMediumOrLargeTests = 0; private int $numExecutableBranches = 0; private int $numExecutedBranches = 0; @@ -90,6 +92,8 @@ final class File extends AbstractNode private int $numTestedClassesByMediumTests = 0; private int $numTestedClassesByLargeTests = 0; private int $numTestedClassesBySmallOrMediumTests = 0; + private int $numTestedClassesBySmallOrLargeTests = 0; + private int $numTestedClassesByMediumOrLargeTests = 0; private int $numTestedClassesBySmallOrMediumOrLargeTests = 0; private ?int $numTraits = null; private int $numTestedTraits = 0; @@ -97,6 +101,8 @@ final class File extends AbstractNode private int $numTestedTraitsByMediumTests = 0; private int $numTestedTraitsByLargeTests = 0; private int $numTestedTraitsBySmallOrMediumTests = 0; + private int $numTestedTraitsBySmallOrLargeTests = 0; + private int $numTestedTraitsByMediumOrLargeTests = 0; private int $numTestedTraitsBySmallOrMediumOrLargeTests = 0; private ?int $numMethods = null; private ?int $numTestedMethods = null; @@ -104,12 +110,16 @@ final class File extends AbstractNode private ?int $numTestedMethodsByMediumTests = null; private ?int $numTestedMethodsByLargeTests = null; private ?int $numTestedMethodsBySmallOrMediumTests = null; + private ?int $numTestedMethodsBySmallOrLargeTests = null; + private ?int $numTestedMethodsByMediumOrLargeTests = null; private ?int $numTestedMethodsBySmallOrMediumOrLargeTests = null; private ?int $numTestedFunctions = null; private ?int $numTestedFunctionsBySmallTests = null; private ?int $numTestedFunctionsByMediumTests = null; private ?int $numTestedFunctionsByLargeTests = null; private ?int $numTestedFunctionsBySmallOrMediumTests = null; + private ?int $numTestedFunctionsBySmallOrLargeTests = null; + private ?int $numTestedFunctionsByMediumOrLargeTests = null; private ?int $numTestedFunctionsBySmallOrMediumOrLargeTests = null; /** @@ -236,6 +246,16 @@ public function numberOfExecutedLinesBySmallOrMediumTests(): int return $this->numExecutedLinesBySmallOrMediumTests; } + public function numberOfExecutedLinesBySmallOrLargeTests(): int + { + return $this->numExecutedLinesBySmallOrLargeTests; + } + + public function numberOfExecutedLinesByMediumOrLargeTests(): int + { + return $this->numExecutedLinesByMediumOrLargeTests; + } + public function numberOfExecutedLinesBySmallOrMediumOrLargeTests(): int { return $this->numExecutedLinesBySmallOrMediumOrLargeTests; @@ -315,6 +335,16 @@ public function numberOfTestedClassesBySmallOrMediumTests(): int return $this->numTestedClassesBySmallOrMediumTests; } + public function numberOfTestedClassesBySmallOrLargeTests(): int + { + return $this->numTestedClassesBySmallOrLargeTests; + } + + public function numberOfTestedClassesByMediumOrLargeTests(): int + { + return $this->numTestedClassesByMediumOrLargeTests; + } + public function numberOfTestedClassesBySmallOrMediumOrLargeTests(): int { return $this->numTestedClassesBySmallOrMediumOrLargeTests; @@ -364,6 +394,16 @@ public function numberOfTestedTraitsBySmallOrMediumTests(): int return $this->numTestedTraitsBySmallOrMediumTests; } + public function numberOfTestedTraitsBySmallOrLargeTests(): int + { + return $this->numTestedTraitsBySmallOrLargeTests; + } + + public function numberOfTestedTraitsByMediumOrLargeTests(): int + { + return $this->numTestedTraitsByMediumOrLargeTests; + } + public function numberOfTestedTraitsBySmallOrMediumOrLargeTests(): int { return $this->numTestedTraitsBySmallOrMediumOrLargeTests; @@ -521,6 +561,56 @@ public function numberOfTestedMethodsBySmallOrMediumTests(): int return $this->numTestedMethodsBySmallOrMediumTests; } + public function numberOfTestedMethodsBySmallOrLargeTests(): int + { + if ($this->numTestedMethodsBySmallOrLargeTests === null) { + $this->numTestedMethodsBySmallOrLargeTests = 0; + + foreach ($this->classes as $class) { + foreach ($class->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesBySmallOrLargeTests === $method->executableLines) { + $this->numTestedMethodsBySmallOrLargeTests++; + } + } + } + + foreach ($this->traits as $trait) { + foreach ($trait->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesBySmallOrLargeTests === $method->executableLines) { + $this->numTestedMethodsBySmallOrLargeTests++; + } + } + } + } + + return $this->numTestedMethodsBySmallOrLargeTests; + } + + public function numberOfTestedMethodsByMediumOrLargeTests(): int + { + if ($this->numTestedMethodsByMediumOrLargeTests === null) { + $this->numTestedMethodsByMediumOrLargeTests = 0; + + foreach ($this->classes as $class) { + foreach ($class->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesByMediumOrLargeTests === $method->executableLines) { + $this->numTestedMethodsByMediumOrLargeTests++; + } + } + } + + foreach ($this->traits as $trait) { + foreach ($trait->methods as $method) { + if ($method->executableLines > 0 && $method->executedLinesByMediumOrLargeTests === $method->executableLines) { + $this->numTestedMethodsByMediumOrLargeTests++; + } + } + } + } + + return $this->numTestedMethodsByMediumOrLargeTests; + } + public function numberOfTestedMethodsBySmallOrMediumOrLargeTests(): int { if ($this->numTestedMethodsBySmallOrMediumOrLargeTests === null) { @@ -627,6 +717,36 @@ public function numberOfTestedFunctionsBySmallOrMediumTests(): int return $this->numTestedFunctionsBySmallOrMediumTests; } + public function numberOfTestedFunctionsBySmallOrLargeTests(): int + { + if ($this->numTestedFunctionsBySmallOrLargeTests === null) { + $this->numTestedFunctionsBySmallOrLargeTests = 0; + + foreach ($this->functions as $function) { + if ($function->executableLines > 0 && $function->executedLinesBySmallOrLargeTests === $function->executableLines) { + $this->numTestedFunctionsBySmallOrLargeTests++; + } + } + } + + return $this->numTestedFunctionsBySmallOrLargeTests; + } + + public function numberOfTestedFunctionsByMediumOrLargeTests(): int + { + if ($this->numTestedFunctionsByMediumOrLargeTests === null) { + $this->numTestedFunctionsByMediumOrLargeTests = 0; + + foreach ($this->functions as $function) { + if ($function->executableLines > 0 && $function->executedLinesByMediumOrLargeTests === $function->executableLines) { + $this->numTestedFunctionsByMediumOrLargeTests++; + } + } + } + + return $this->numTestedFunctionsByMediumOrLargeTests; + } + public function numberOfTestedFunctionsBySmallOrMediumOrLargeTests(): int { if ($this->numTestedFunctionsBySmallOrMediumOrLargeTests === null) { @@ -734,6 +854,26 @@ private function calculateStatistics(array $classes, array $traits, array $funct unset($codeUnit); } + if ($coveredBySmall || $coveredByLarge) { + $this->numExecutedLinesBySmallOrLargeTests++; + + foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) { + $codeUnit->executedLinesBySmallOrLargeTests++; + } + + unset($codeUnit); + } + + if ($coveredByMedium || $coveredByLarge) { + $this->numExecutedLinesByMediumOrLargeTests++; + + foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) { + $codeUnit->executedLinesByMediumOrLargeTests++; + } + + unset($codeUnit); + } + if ($coveredBySmall || $coveredByMedium || $coveredByLarge) { $this->numExecutedLinesBySmallOrMediumOrLargeTests++; @@ -788,6 +928,14 @@ private function calculateStatistics(array $classes, array $traits, array $funct $this->numTestedTraitsBySmallOrMediumTests++; } + if ($trait->executableLines > 0 && $trait->executedLinesBySmallOrLargeTests === $trait->executableLines) { + $this->numTestedTraitsBySmallOrLargeTests++; + } + + if ($trait->executableLines > 0 && $trait->executedLinesByMediumOrLargeTests === $trait->executableLines) { + $this->numTestedTraitsByMediumOrLargeTests++; + } + if ($trait->executableLines > 0 && $trait->executedLinesBySmallOrMediumOrLargeTests === $trait->executableLines) { $this->numTestedTraitsBySmallOrMediumOrLargeTests++; } @@ -836,6 +984,14 @@ private function calculateStatistics(array $classes, array $traits, array $funct $this->numTestedClassesBySmallOrMediumTests++; } + if ($class->executableLines > 0 && $class->executedLinesBySmallOrLargeTests === $class->executableLines) { + $this->numTestedClassesBySmallOrLargeTests++; + } + + if ($class->executableLines > 0 && $class->executedLinesByMediumOrLargeTests === $class->executableLines) { + $this->numTestedClassesByMediumOrLargeTests++; + } + if ($class->executableLines > 0 && $class->executedLinesBySmallOrMediumOrLargeTests === $class->executableLines) { $this->numTestedClassesBySmallOrMediumOrLargeTests++; } @@ -871,6 +1027,14 @@ private function calculateStatistics(array $classes, array $traits, array $funct $this->numTestedFunctionsBySmallOrMediumTests++; } + if ($function->executableLines > 0 && $function->executedLinesBySmallOrLargeTests === $function->executableLines) { + $this->numTestedFunctionsBySmallOrLargeTests++; + } + + if ($function->executableLines > 0 && $function->executedLinesByMediumOrLargeTests === $function->executableLines) { + $this->numTestedFunctionsByMediumOrLargeTests++; + } + if ($function->executableLines > 0 && $function->executedLinesBySmallOrMediumOrLargeTests === $function->executableLines) { $this->numTestedFunctionsBySmallOrMediumOrLargeTests++; } diff --git a/src/Report/Html/Renderer/Directory.php b/src/Report/Html/Renderer/Directory.php index 203aa14b4..45f025e94 100644 --- a/src/Report/Html/Renderer/Directory.php +++ b/src/Report/Html/Renderer/Directory.php @@ -106,6 +106,8 @@ private function renderItem(Node $node, bool $total = false): string 'linesMedium' => $node->numberOfExecutedLinesByMediumTests(), 'linesLarge' => $node->numberOfExecutedLinesByLargeTests(), 'linesSM' => $node->numberOfExecutedLinesBySmallOrMediumTests(), + 'linesSL' => $node->numberOfExecutedLinesBySmallOrLargeTests(), + 'linesML' => $node->numberOfExecutedLinesByMediumOrLargeTests(), 'linesSML' => $node->numberOfExecutedLinesBySmallOrMediumOrLargeTests(), 'methodsTotal' => $node->numberOfFunctionsAndMethods(), 'methodsAll' => $node->numberOfTestedFunctionsAndMethods(), @@ -113,6 +115,8 @@ private function renderItem(Node $node, bool $total = false): string 'methodsMedium' => $node->numberOfTestedFunctionsAndMethodsByMediumTests(), 'methodsLarge' => $node->numberOfTestedFunctionsAndMethodsByLargeTests(), 'methodsSM' => $node->numberOfTestedFunctionsAndMethodsBySmallOrMediumTests(), + 'methodsSL' => $node->numberOfTestedFunctionsAndMethodsBySmallOrLargeTests(), + 'methodsML' => $node->numberOfTestedFunctionsAndMethodsByMediumOrLargeTests(), 'methodsSML' => $node->numberOfTestedFunctionsAndMethodsBySmallOrMediumOrLargeTests(), 'classesTotal' => $node->numberOfClassesAndTraits(), 'classesAll' => $node->numberOfTestedClassesAndTraits(), @@ -120,6 +124,8 @@ private function renderItem(Node $node, bool $total = false): string 'classesMedium' => $node->numberOfTestedClassesAndTraitsByMediumTests(), 'classesLarge' => $node->numberOfTestedClassesAndTraitsByLargeTests(), 'classesSM' => $node->numberOfTestedClassesAndTraitsBySmallOrMediumTests(), + 'classesSL' => $node->numberOfTestedClassesAndTraitsBySmallOrLargeTests(), + 'classesML' => $node->numberOfTestedClassesAndTraitsByMediumOrLargeTests(), 'classesSML' => $node->numberOfTestedClassesAndTraitsBySmallOrMediumOrLargeTests(), ]), ]; diff --git a/src/Report/Html/Renderer/File.php b/src/Report/Html/Renderer/File.php index 6269e5819..e6f334fa0 100644 --- a/src/Report/Html/Renderer/File.php +++ b/src/Report/Html/Renderer/File.php @@ -166,6 +166,8 @@ private function renderItems(FileNode $node): string 'linesMedium' => $node->numberOfExecutedLinesByMediumTests(), 'linesLarge' => $node->numberOfExecutedLinesByLargeTests(), 'linesSM' => $node->numberOfExecutedLinesBySmallOrMediumTests(), + 'linesSL' => $node->numberOfExecutedLinesBySmallOrLargeTests(), + 'linesML' => $node->numberOfExecutedLinesByMediumOrLargeTests(), 'linesSML' => $node->numberOfExecutedLinesBySmallOrMediumOrLargeTests(), 'methodsTotal' => $node->numberOfFunctionsAndMethods(), 'methodsAll' => $node->numberOfTestedFunctionsAndMethods(), @@ -173,6 +175,8 @@ private function renderItems(FileNode $node): string 'methodsMedium' => $node->numberOfTestedFunctionsAndMethodsByMediumTests(), 'methodsLarge' => $node->numberOfTestedFunctionsAndMethodsByLargeTests(), 'methodsSM' => $node->numberOfTestedFunctionsAndMethodsBySmallOrMediumTests(), + 'methodsSL' => $node->numberOfTestedFunctionsAndMethodsBySmallOrLargeTests(), + 'methodsML' => $node->numberOfTestedFunctionsAndMethodsByMediumOrLargeTests(), 'methodsSML' => $node->numberOfTestedFunctionsAndMethodsBySmallOrMediumOrLargeTests(), 'classesTotal' => $node->numberOfClassesAndTraits(), 'classesAll' => $node->numberOfTestedClassesAndTraits(), @@ -180,6 +184,8 @@ private function renderItems(FileNode $node): string 'classesMedium' => $node->numberOfTestedClassesAndTraitsByMediumTests(), 'classesLarge' => $node->numberOfTestedClassesAndTraitsByLargeTests(), 'classesSM' => $node->numberOfTestedClassesAndTraitsBySmallOrMediumTests(), + 'classesSL' => $node->numberOfTestedClassesAndTraitsBySmallOrLargeTests(), + 'classesML' => $node->numberOfTestedClassesAndTraitsByMediumOrLargeTests(), 'classesSML' => $node->numberOfTestedClassesAndTraitsBySmallOrMediumOrLargeTests(), ]), ], diff --git a/src/Report/Html/Renderer/Template/directory.html.dist b/src/Report/Html/Renderer/Template/directory.html.dist index c5bee801a..99399ef07 100644 --- a/src/Report/Html/Renderer/Template/directory.html.dist +++ b/src/Report/Html/Renderer/Template/directory.html.dist @@ -25,12 +25,13 @@
- - - - - - + + + + + + +
{{name}} {{lines_bar}}
{{lines_executed_percent}}
{{name}} {{lines_bar}}
{{lines_executed_percent}}
diff --git a/src/Report/Html/Renderer/Template/directory_branch.html.dist b/src/Report/Html/Renderer/Template/directory_branch.html.dist index cf0ba02f7..a91c754c3 100644 --- a/src/Report/Html/Renderer/Template/directory_branch.html.dist +++ b/src/Report/Html/Renderer/Template/directory_branch.html.dist @@ -25,12 +25,13 @@
- - - - - - + + + + + + +
diff --git a/src/Report/Html/Renderer/Template/directory_branch_and_path.html.dist b/src/Report/Html/Renderer/Template/directory_branch_and_path.html.dist index cc095b5f3..6382d3e2a 100644 --- a/src/Report/Html/Renderer/Template/directory_branch_and_path.html.dist +++ b/src/Report/Html/Renderer/Template/directory_branch_and_path.html.dist @@ -25,12 +25,13 @@
- - - - - - + + + + + + +
diff --git a/src/Report/Html/Renderer/Template/file.html.dist b/src/Report/Html/Renderer/Template/file.html.dist index 448b54367..48ba16958 100644 --- a/src/Report/Html/Renderer/Template/file.html.dist +++ b/src/Report/Html/Renderer/Template/file.html.dist @@ -25,12 +25,13 @@
- - - - - - + + + + + + +
diff --git a/src/Report/Html/Renderer/Template/file_branch.html.dist b/src/Report/Html/Renderer/Template/file_branch.html.dist index 6670ac7a8..261ff0253 100644 --- a/src/Report/Html/Renderer/Template/file_branch.html.dist +++ b/src/Report/Html/Renderer/Template/file_branch.html.dist @@ -25,12 +25,13 @@
- - - - - - + + + + + + +
diff --git a/src/Report/Html/Renderer/Template/file_branch_and_path.html.dist b/src/Report/Html/Renderer/Template/file_branch_and_path.html.dist index 1d92ade6f..01f328558 100644 --- a/src/Report/Html/Renderer/Template/file_branch_and_path.html.dist +++ b/src/Report/Html/Renderer/Template/file_branch_and_path.html.dist @@ -25,12 +25,13 @@
- - - - - - + + + + + + +
diff --git a/src/Report/Html/Renderer/Template/js/test-size-filter.js b/src/Report/Html/Renderer/Template/js/test-size-filter.js index 5bdfbd793..38f0b3b87 100644 --- a/src/Report/Html/Renderer/Template/js/test-size-filter.js +++ b/src/Report/Html/Renderer/Template/js/test-size-filter.js @@ -1,5 +1,5 @@ $(function () { - var $btnGroup = $('[data-test-size-filter]').first().parent(); + var $btnGroup = $('[data-test-size-filter], [data-test-size-filter-all]').first().parent(); var lowBound = parseFloat($btnGroup.data('low-upper-bound')) || 50; var highBound = parseFloat($btnGroup.data('high-lower-bound')) || 90; @@ -24,7 +24,34 @@ $(function () { return total > 0 ? (n / total) * 100 : 0; } + function filterKey(sizes) { + if (sizes.length === 0) return 'all'; + if (sizes.length === 1) return sizes[0]; + if (sizes.length === 3) return 'small+medium+large'; + var has = {small: false, medium: false, large: false}; + sizes.forEach(function (s) { has[s] = true; }); + if (has.small && has.medium) return 'small+medium'; + if (has.small && has.large) return 'small+large'; + if (has.medium && has.large) return 'medium+large'; + return 'all'; + } + + function dataKeys(filter) { + switch (filter) { + case 'small': return {lines: 'linesSmall', methods: 'methodsSmall', classes: 'classesSmall'}; + case 'medium': return {lines: 'linesMedium', methods: 'methodsMedium', classes: 'classesMedium'}; + case 'large': return {lines: 'linesLarge', methods: 'methodsLarge', classes: 'classesLarge'}; + case 'small+medium': return {lines: 'linesSM', methods: 'methodsSM', classes: 'classesSM'}; + case 'small+large': return {lines: 'linesSL', methods: 'methodsSL', classes: 'classesSL'}; + case 'medium+large': return {lines: 'linesML', methods: 'methodsML', classes: 'classesML'}; + case 'small+medium+large': return {lines: 'linesSML', methods: 'methodsSML', classes: 'classesSML'}; + default: return {lines: 'linesAll', methods: 'methodsAll', classes: 'classesAll'}; + } + } + function applyFilter(filter) { + var keys = dataKeys(filter); + $('tr[data-coverage]').each(function () { var $tr = $(this); var raw = $tr.attr('data-coverage'); @@ -38,33 +65,9 @@ $(function () { var methodsTotal = d.methodsTotal || 0; var classesTotal = d.classesTotal || 0; - var linesExec, methodsTested, classesTested; - - if (filter === 'small') { - linesExec = d.linesSmall || 0; - methodsTested = d.methodsSmall || 0; - classesTested = d.classesSmall || 0; - } else if (filter === 'medium') { - linesExec = d.linesMedium || 0; - methodsTested = d.methodsMedium || 0; - classesTested = d.classesMedium || 0; - } else if (filter === 'large') { - linesExec = d.linesLarge || 0; - methodsTested = d.methodsLarge || 0; - classesTested = d.classesLarge || 0; - } else if (filter === 'small+medium') { - linesExec = d.linesSM || 0; - methodsTested = d.methodsSM || 0; - classesTested = d.classesSM || 0; - } else if (filter === 'small+medium+large') { - linesExec = d.linesSML || 0; - methodsTested = d.methodsSML || 0; - classesTested = d.classesSML || 0; - } else { - linesExec = d.linesAll || 0; - methodsTested = d.methodsAll || 0; - classesTested = d.classesAll || 0; - } + var linesExec = d[keys.lines] || 0; + var methodsTested = d[keys.methods] || 0; + var classesTested = d[keys.classes] || 0; var linesPct = pct(linesExec, linesTotal); var methodsPct = pct(methodsTested, methodsTotal); @@ -74,7 +77,6 @@ $(function () { var nameCell = cells.eq(0); var idx = 1; - // Lines: bar, percent, number (3 cells) var linesLevel = linesTotal > 0 ? colorLevel(linesPct) : ''; cells.eq(idx).attr('class', linesLevel + ' big').html(linesTotal > 0 ? coverageBar(linesPct) : ''); @@ -86,28 +88,18 @@ $(function () { ); idx += 3; - // Branches (if present): bar, percent, number (3 cells) - skip, don't modify - // Paths (if present): bar, percent, number (3 cells) - skip, don't modify - // We need to find where methods start. Methods are identified by having the methods data. - // For branch views: lines(3) + branches(3) + paths(3) + methods(3+crap) + classes(3) - // For non-branch: lines(3) + methods(3+crap?) + classes(3) - - // Detect if this is a branch view by checking total cell count var totalCells = cells.length; var methodsIdx, classesIdx, hasClasses; if (totalCells >= 16) { - // Branch view: name(1) + lines(3) + branches(3) + paths(3) + methods(3+crap) + classes(3) methodsIdx = 10; classesIdx = 14; hasClasses = totalCells >= 17; } else if (totalCells >= 11) { - // Non-branch file view: name(1) + lines(3) + methods(3+crap) + classes(3) methodsIdx = 4; classesIdx = 8; hasClasses = true; } else if (totalCells >= 10) { - // Directory view: name(1) + lines(3) + methods(3) + classes(3) methodsIdx = 4; classesIdx = 7; hasClasses = true; @@ -115,7 +107,6 @@ $(function () { return; } - // Methods: bar, percent, number var methodsLevel = methodsTotal > 0 ? colorLevel(methodsPct) : ''; cells.eq(methodsIdx).attr('class', methodsLevel + ' big').html(methodsTotal > 0 ? coverageBar(methodsPct) : ''); @@ -126,7 +117,6 @@ $(function () { '
' + methodsTested + ' / ' + methodsTotal + '
' ); - // Classes: bar, percent, number if (hasClasses && cells.eq(classesIdx).length) { var classesLevel = classesTotal > 0 ? colorLevel(classesPct) : ''; @@ -139,17 +129,33 @@ $(function () { ); } - // Update name cell background nameCell.attr('class', linesLevel); }); } - $('[data-test-size-filter]').on('click', function () { - var $btn = $(this); + function currentSizes() { + return $btnGroup.find('input[type=checkbox][data-test-size-filter]:checked').map(function () { + return $(this).data('test-size-filter'); + }).get(); + } + + function refresh() { + var sizes = currentSizes(); + var $allBtn = $btnGroup.find('[data-test-size-filter-all]'); + + if (sizes.length === 0) { + $allBtn.addClass('active'); + } else { + $allBtn.removeClass('active'); + } + + applyFilter(filterKey(sizes)); + } - $btn.siblings().removeClass('active'); - $btn.addClass('active'); + $btnGroup.on('change', 'input[type=checkbox][data-test-size-filter]', refresh); - applyFilter($btn.data('test-size-filter')); + $btnGroup.on('click', '[data-test-size-filter-all]', function () { + $btnGroup.find('input[type=checkbox][data-test-size-filter]:checked').prop('checked', false); + refresh(); }); }); diff --git a/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html b/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html index 4a5cbeea5..6e1e5653b 100644 --- a/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html +++ b/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
@@ -49,7 +50,7 @@ - +
Total
diff --git a/tests/_files/Report/HTML/CoverageForBankAccount/index.html b/tests/_files/Report/HTML/CoverageForBankAccount/index.html index d1d9ed24b..989d0f8d3 100644 --- a/tests/_files/Report/HTML/CoverageForBankAccount/index.html +++ b/tests/_files/Report/HTML/CoverageForBankAccount/index.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
@@ -49,7 +50,7 @@ - + - +
Total
@@ -77,7 +78,7 @@
0 / 1
BankAccount.php
diff --git a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html index 3d96a44d6..36dc83628 100644 --- a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html +++ b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
@@ -49,7 +50,7 @@ - + - +
Total
@@ -77,7 +78,7 @@
1 / 1
source_with_class_and_anonymous_function.php
diff --git a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html index 7996a90dd..3f5f0e31b 100644 --- a/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html +++ b/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
@@ -49,7 +50,7 @@ - +
Total
diff --git a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html index 5f2cab63e..0f64d47ff 100644 --- a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html +++ b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
@@ -49,7 +50,7 @@ - + - +
Total
@@ -72,7 +73,7 @@
0 / 0
source_with_ignore.php
diff --git a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html index e3378b881..a0b6b0e5c 100644 --- a/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html +++ b/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
@@ -49,7 +50,7 @@ - +
Total
diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php.html index 514c50463..70fd53482 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_branch.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_branch.html index 4568015f3..4b894f986 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_branch.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_branch.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_path.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_path.html index 4568015f3..4b894f986 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_path.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/BankAccount.php_path.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
diff --git a/tests/_files/Report/HTML/PathCoverageForBankAccount/index.html b/tests/_files/Report/HTML/PathCoverageForBankAccount/index.html index e77950610..615ad8379 100644 --- a/tests/_files/Report/HTML/PathCoverageForBankAccount/index.html +++ b/tests/_files/Report/HTML/PathCoverageForBankAccount/index.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
@@ -51,7 +52,7 @@ - + - +
Total
@@ -95,7 +96,7 @@
0 / 1
BankAccount.php [line] [branch] [path]
diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/index.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/index.html index f0f6b1c17..0953dac49 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/index.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/index.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
@@ -51,7 +52,7 @@ - + - +
Total
@@ -90,7 +91,7 @@
0 / 0
source_without_namespace.php [line] [branch] [path]
diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php.html index e49f89381..f4b74f673 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
@@ -51,7 +52,7 @@ - +
Total
diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_branch.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_branch.html index d85acb034..66db064e4 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_branch.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_branch.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
@@ -51,7 +52,7 @@ - +
Total
diff --git a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html index 1f457e541..f3aa71f0f 100644 --- a/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html +++ b/tests/_files/Report/HTML/PathCoverageForSourceWithoutNamespace/source_without_namespace.php_path.html @@ -27,12 +27,13 @@
- - - - - - + + + + + + +
@@ -51,7 +52,7 @@ - +
Total
From 84db31f01e0751215e5732a7ea6e2609c3335cab Mon Sep 17 00:00:00 2001 From: Sebastian Bergmann Date: Fri, 8 May 2026 08:13:54 +0200 Subject: [PATCH 6/6] Add tests --- tests/tests/Node/AbstractNodeTest.php | 81 +++++++++++++ tests/tests/Node/DirectoryTest.php | 156 ++++++++++++++++++++++++++ tests/tests/Node/FileTest.php | 152 +++++++++++++++++++++++++ 3 files changed, 389 insertions(+) diff --git a/tests/tests/Node/AbstractNodeTest.php b/tests/tests/Node/AbstractNodeTest.php index b13013d24..3bb5ec226 100644 --- a/tests/tests/Node/AbstractNodeTest.php +++ b/tests/tests/Node/AbstractNodeTest.php @@ -138,6 +138,45 @@ public function testCyclomaticComplexityWithFunctions(): void $this->assertGreaterThan(0, $file->cyclomaticComplexity()); } + public function testPercentageOfExecutedLinesByTestSize(): void + { + $file = $this->createFileWithMixedTestSizeCoverage(); + + $this->assertSame(50.0, $file->percentageOfExecutedLinesBySmallTests()->asFloat()); + $this->assertSame(25.0, $file->percentageOfExecutedLinesByMediumTests()->asFloat()); + $this->assertSame(25.0, $file->percentageOfExecutedLinesByLargeTests()->asFloat()); + $this->assertSame(75.0, $file->percentageOfExecutedLinesBySmallOrMediumTests()->asFloat()); + $this->assertSame(75.0, $file->percentageOfExecutedLinesBySmallOrLargeTests()->asFloat()); + $this->assertSame(50.0, $file->percentageOfExecutedLinesByMediumOrLargeTests()->asFloat()); + $this->assertSame(100.0, $file->percentageOfExecutedLinesBySmallOrMediumOrLargeTests()->asFloat()); + } + + public function testNumberOfTestedClassesAndTraitsByTestSize(): void + { + $file = $this->createFileWithMixedTestSizeCoverage(); + + $this->assertSame(1, $file->numberOfTestedClassesAndTraitsBySmallTests()); + $this->assertSame(1, $file->numberOfTestedClassesAndTraitsByMediumTests()); + $this->assertSame(0, $file->numberOfTestedClassesAndTraitsByLargeTests()); + $this->assertSame(2, $file->numberOfTestedClassesAndTraitsBySmallOrMediumTests()); + $this->assertSame(1, $file->numberOfTestedClassesAndTraitsBySmallOrLargeTests()); + $this->assertSame(1, $file->numberOfTestedClassesAndTraitsByMediumOrLargeTests()); + $this->assertSame(2, $file->numberOfTestedClassesAndTraitsBySmallOrMediumOrLargeTests()); + } + + public function testNumberOfTestedFunctionsAndMethodsByTestSize(): void + { + $file = $this->createFileWithMixedTestSizeCoverage(); + + $this->assertSame(1, $file->numberOfTestedFunctionsAndMethodsBySmallTests()); + $this->assertSame(1, $file->numberOfTestedFunctionsAndMethodsByMediumTests()); + $this->assertSame(1, $file->numberOfTestedFunctionsAndMethodsByLargeTests()); + $this->assertSame(2, $file->numberOfTestedFunctionsAndMethodsBySmallOrMediumTests()); + $this->assertSame(2, $file->numberOfTestedFunctionsAndMethodsBySmallOrLargeTests()); + $this->assertSame(2, $file->numberOfTestedFunctionsAndMethodsByMediumOrLargeTests()); + $this->assertSame(3, $file->numberOfTestedFunctionsAndMethodsBySmallOrMediumOrLargeTests()); + } + public function testNameStripsTrailingDirectorySeparator(): void { $root = new Directory('root' . DIRECTORY_SEPARATOR); @@ -154,6 +193,48 @@ public function testIdForGrandchild(): void $this->assertSame('child/grandchild', $grandchild->id()); } + private function createFileWithMixedTestSizeCoverage(): File + { + $root = new Directory('root'); + + $smallMethod = new Method('m1', 1, 4, 'public function m1(): void', Visibility::Public, 1); + $mediumMethod = new Method('m2', 5, 6, 'public function m2(): void', Visibility::Public, 1); + + $smallClass = new Class_('SmallClass', 'SmallClass', '', 'test.php', 1, 4, null, [], [], ['m1' => $smallMethod]); + $mediumTrait = new Trait_('MediumTrait', 'MediumTrait', '', 'test.php', 5, 6, [], ['m2' => $mediumMethod]); + $largeFunc = new Function_('largeFunc', 'largeFunc', '', 7, 8, 'function largeFunc(): void', 1); + + $lineCoverageData = [ + 1 => ['tSmall'], + 2 => ['tSmall'], + 3 => ['tSmall'], + 4 => ['tSmall'], + 5 => ['tMedium'], + 6 => ['tMedium'], + 7 => ['tLarge'], + 8 => ['tLarge'], + ]; + + $testData = [ + 'tSmall' => ['size' => 'small', 'status' => 'passed', 'time' => 0.0], + 'tMedium' => ['size' => 'medium', 'status' => 'passed', 'time' => 0.0], + 'tLarge' => ['size' => 'large', 'status' => 'passed', 'time' => 0.0], + ]; + + return new File( + 'test.php', + $root, + 'abc123', + $lineCoverageData, + [], + $testData, + ['SmallClass' => $smallClass], + ['MediumTrait' => $mediumTrait], + ['largeFunc' => $largeFunc], + new LinesOfCode(8, 0, 8), + ); + } + private function createFileWithTestedClass(): File { $root = new Directory('root'); diff --git a/tests/tests/Node/DirectoryTest.php b/tests/tests/Node/DirectoryTest.php index 7dc0893b7..ef5530c74 100644 --- a/tests/tests/Node/DirectoryTest.php +++ b/tests/tests/Node/DirectoryTest.php @@ -12,8 +12,11 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Small; use PHPUnit\Framework\TestCase; +use SebastianBergmann\CodeCoverage\StaticAnalysis\Class_; use SebastianBergmann\CodeCoverage\StaticAnalysis\Function_; use SebastianBergmann\CodeCoverage\StaticAnalysis\LinesOfCode; +use SebastianBergmann\CodeCoverage\StaticAnalysis\Method; +use SebastianBergmann\CodeCoverage\StaticAnalysis\Visibility; #[CoversClass(Directory::class)] #[Small] @@ -137,6 +140,159 @@ public function testNumberOfFilesWithoutBranchCoverageDataAggregatesFromNestedDi $this->assertSame(1, $root->numberOfFilesWithoutBranchCoverageData()); } + public function testNumberOfExecutedLinesByTestSizeAggregatesFromChildren(): void + { + $root = new Directory('root'); + $root->addFile($this->createFileCoveredBySmallTest($root, 'small.php')); + $root->addFile($this->createFileCoveredByMediumTest($root, 'medium.php')); + $root->addFile($this->createFileCoveredByLargeTest($root, 'large.php')); + + $this->assertSame(6, $root->numberOfExecutableLines()); + $this->assertSame(6, $root->numberOfExecutedLines()); + $this->assertSame(2, $root->numberOfExecutedLinesBySmallTests()); + $this->assertSame(2, $root->numberOfExecutedLinesByMediumTests()); + $this->assertSame(2, $root->numberOfExecutedLinesByLargeTests()); + $this->assertSame(4, $root->numberOfExecutedLinesBySmallOrMediumTests()); + $this->assertSame(4, $root->numberOfExecutedLinesBySmallOrLargeTests()); + $this->assertSame(4, $root->numberOfExecutedLinesByMediumOrLargeTests()); + $this->assertSame(6, $root->numberOfExecutedLinesBySmallOrMediumOrLargeTests()); + } + + public function testNumberOfTestedClassesByTestSizeAggregatesFromChildren(): void + { + $root = new Directory('root'); + $root->addFile($this->createFileCoveredBySmallTest($root, 'small.php')); + $root->addFile($this->createFileCoveredByMediumTest($root, 'medium.php')); + $root->addFile($this->createFileCoveredByLargeTest($root, 'large.php')); + + $this->assertSame(1, $root->numberOfTestedClassesBySmallTests()); + $this->assertSame(1, $root->numberOfTestedClassesByMediumTests()); + $this->assertSame(1, $root->numberOfTestedClassesByLargeTests()); + $this->assertSame(2, $root->numberOfTestedClassesBySmallOrMediumTests()); + $this->assertSame(2, $root->numberOfTestedClassesBySmallOrLargeTests()); + $this->assertSame(2, $root->numberOfTestedClassesByMediumOrLargeTests()); + $this->assertSame(3, $root->numberOfTestedClassesBySmallOrMediumOrLargeTests()); + } + + public function testNumberOfTestedMethodsByTestSizeAggregatesFromChildren(): void + { + $root = new Directory('root'); + $root->addFile($this->createFileCoveredBySmallTest($root, 'small.php')); + $root->addFile($this->createFileCoveredByMediumTest($root, 'medium.php')); + + $this->assertSame(1, $root->numberOfTestedMethodsBySmallTests()); + $this->assertSame(1, $root->numberOfTestedMethodsByMediumTests()); + $this->assertSame(0, $root->numberOfTestedMethodsByLargeTests()); + $this->assertSame(2, $root->numberOfTestedMethodsBySmallOrMediumTests()); + $this->assertSame(1, $root->numberOfTestedMethodsBySmallOrLargeTests()); + $this->assertSame(1, $root->numberOfTestedMethodsByMediumOrLargeTests()); + $this->assertSame(2, $root->numberOfTestedMethodsBySmallOrMediumOrLargeTests()); + } + + public function testNumberOfTestedFunctionsByTestSizeAggregatesFromChildren(): void + { + $root = new Directory('root'); + $root->addFile($this->createFileWithFunctionCoveredBySmallTest($root, 'small.php')); + $root->addFile($this->createFileWithFunctionCoveredByMediumTest($root, 'medium.php')); + + $this->assertSame(1, $root->numberOfTestedFunctionsBySmallTests()); + $this->assertSame(1, $root->numberOfTestedFunctionsByMediumTests()); + $this->assertSame(0, $root->numberOfTestedFunctionsByLargeTests()); + $this->assertSame(2, $root->numberOfTestedFunctionsBySmallOrMediumTests()); + $this->assertSame(1, $root->numberOfTestedFunctionsBySmallOrLargeTests()); + $this->assertSame(1, $root->numberOfTestedFunctionsByMediumOrLargeTests()); + $this->assertSame(2, $root->numberOfTestedFunctionsBySmallOrMediumOrLargeTests()); + } + + public function testNumberOfTestedTraitsByTestSizeReturnsZeroWhenNoTraitsExist(): void + { + $root = new Directory('root'); + $root->addFile($this->createFileCoveredBySmallTest($root, 'small.php')); + + $this->assertSame(0, $root->numberOfTestedTraitsBySmallTests()); + $this->assertSame(0, $root->numberOfTestedTraitsByMediumTests()); + $this->assertSame(0, $root->numberOfTestedTraitsByLargeTests()); + $this->assertSame(0, $root->numberOfTestedTraitsBySmallOrMediumTests()); + $this->assertSame(0, $root->numberOfTestedTraitsBySmallOrLargeTests()); + $this->assertSame(0, $root->numberOfTestedTraitsByMediumOrLargeTests()); + $this->assertSame(0, $root->numberOfTestedTraitsBySmallOrMediumOrLargeTests()); + } + + public function testTestSizeAggregationCachesResultsAcrossNestedDirectories(): void + { + $root = new Directory('root'); + $sub = $root->addDirectory('sub'); + $sub->addFile($this->createFileCoveredBySmallTest($sub, 'small.php')); + $sub->addFile($this->createFileCoveredByLargeTest($sub, 'large.php')); + + $this->assertSame(2, $root->numberOfExecutedLinesBySmallTests()); + $this->assertSame(2, $root->numberOfExecutedLinesByLargeTests()); + $this->assertSame(4, $root->numberOfExecutedLinesBySmallOrLargeTests()); + $this->assertSame(2, $root->numberOfExecutedLinesBySmallTests()); + } + + private function createFileCoveredBySmallTest(Directory $parent, string $name): File + { + return $this->createFileCoveredBySingleTestSize($parent, $name, 'small'); + } + + private function createFileCoveredByMediumTest(Directory $parent, string $name): File + { + return $this->createFileCoveredBySingleTestSize($parent, $name, 'medium'); + } + + private function createFileCoveredByLargeTest(Directory $parent, string $name): File + { + return $this->createFileCoveredBySingleTestSize($parent, $name, 'large'); + } + + private function createFileCoveredBySingleTestSize(Directory $parent, string $name, string $size): File + { + $method = new Method('m', 1, 2, 'public function m(): void', Visibility::Public, 1); + $class = new Class_('C', 'C', '', $name, 1, 2, null, [], [], ['m' => $method]); + + return new File( + $name, + $parent, + 'sha1hash', + [1 => ['t'], 2 => ['t']], + [], + ['t' => ['size' => $size, 'status' => 'passed', 'time' => 0.0]], + ['C' => $class], + [], + [], + new LinesOfCode(2, 0, 2), + ); + } + + private function createFileWithFunctionCoveredBySmallTest(Directory $parent, string $name): File + { + return $this->createFileWithFunctionCoveredBySingleTestSize($parent, $name, 'small'); + } + + private function createFileWithFunctionCoveredByMediumTest(Directory $parent, string $name): File + { + return $this->createFileWithFunctionCoveredBySingleTestSize($parent, $name, 'medium'); + } + + private function createFileWithFunctionCoveredBySingleTestSize(Directory $parent, string $name, string $size): File + { + $function = new Function_('f', 'f', '', 1, 2, 'function f(): void', 1); + + return new File( + $name, + $parent, + 'sha1hash', + [1 => ['t'], 2 => ['t']], + [], + ['t' => ['size' => $size, 'status' => 'passed', 'time' => 0.0]], + [], + [], + ['f' => $function], + new LinesOfCode(2, 0, 2), + ); + } + private function createFileWithBranchCoverageData(Directory $parent, string $name): File { return new File( diff --git a/tests/tests/Node/FileTest.php b/tests/tests/Node/FileTest.php index 39e1edd73..586721e79 100644 --- a/tests/tests/Node/FileTest.php +++ b/tests/tests/Node/FileTest.php @@ -12,6 +12,7 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Small; use PHPUnit\Framework\TestCase; +use SebastianBergmann\CodeCoverage\StaticAnalysis\Class_; use SebastianBergmann\CodeCoverage\StaticAnalysis\Function_; use SebastianBergmann\CodeCoverage\StaticAnalysis\LinesOfCode; use SebastianBergmann\CodeCoverage\StaticAnalysis\Method; @@ -250,6 +251,98 @@ public function testTestedTraitsCount(): void $this->assertSame(1, $file->numberOfTestedTraits()); } + public function testNumberOfExecutedLinesByTestSize(): void + { + $file = $this->createFileNodeWithMixedTestSizes(); + + $this->assertSame(12, $file->numberOfExecutableLines()); + $this->assertSame(10, $file->numberOfExecutedLines()); + $this->assertSame(6, $file->numberOfExecutedLinesBySmallTests()); + $this->assertSame(4, $file->numberOfExecutedLinesByMediumTests()); + $this->assertSame(2, $file->numberOfExecutedLinesByLargeTests()); + $this->assertSame(8, $file->numberOfExecutedLinesBySmallOrMediumTests()); + $this->assertSame(8, $file->numberOfExecutedLinesBySmallOrLargeTests()); + $this->assertSame(6, $file->numberOfExecutedLinesByMediumOrLargeTests()); + $this->assertSame(10, $file->numberOfExecutedLinesBySmallOrMediumOrLargeTests()); + } + + public function testNumberOfTestedClassesByTestSize(): void + { + $file = $this->createFileNodeWithMixedTestSizes(); + + $this->assertSame(3, $file->numberOfClasses()); + $this->assertSame(3, $file->numberOfTestedClasses()); + $this->assertSame(1, $file->numberOfTestedClassesBySmallTests()); + $this->assertSame(1, $file->numberOfTestedClassesByMediumTests()); + $this->assertSame(1, $file->numberOfTestedClassesByLargeTests()); + $this->assertSame(2, $file->numberOfTestedClassesBySmallOrMediumTests()); + $this->assertSame(2, $file->numberOfTestedClassesBySmallOrLargeTests()); + $this->assertSame(2, $file->numberOfTestedClassesByMediumOrLargeTests()); + $this->assertSame(3, $file->numberOfTestedClassesBySmallOrMediumOrLargeTests()); + } + + public function testNumberOfTestedTraitsByTestSize(): void + { + $file = $this->createFileNodeWithMixedTestSizes(); + + $this->assertSame(1, $file->numberOfTraits()); + $this->assertSame(1, $file->numberOfTestedTraits()); + $this->assertSame(1, $file->numberOfTestedTraitsBySmallTests()); + $this->assertSame(1, $file->numberOfTestedTraitsByMediumTests()); + $this->assertSame(0, $file->numberOfTestedTraitsByLargeTests()); + $this->assertSame(1, $file->numberOfTestedTraitsBySmallOrMediumTests()); + $this->assertSame(1, $file->numberOfTestedTraitsBySmallOrLargeTests()); + $this->assertSame(1, $file->numberOfTestedTraitsByMediumOrLargeTests()); + $this->assertSame(1, $file->numberOfTestedTraitsBySmallOrMediumOrLargeTests()); + } + + public function testNumberOfTestedMethodsByTestSize(): void + { + $file = $this->createFileNodeWithMixedTestSizes(); + + $this->assertSame(4, $file->numberOfMethods()); + $this->assertSame(4, $file->numberOfTestedMethods()); + $this->assertSame(2, $file->numberOfTestedMethodsBySmallTests()); + $this->assertSame(2, $file->numberOfTestedMethodsByMediumTests()); + $this->assertSame(1, $file->numberOfTestedMethodsByLargeTests()); + $this->assertSame(3, $file->numberOfTestedMethodsBySmallOrMediumTests()); + $this->assertSame(3, $file->numberOfTestedMethodsBySmallOrLargeTests()); + $this->assertSame(3, $file->numberOfTestedMethodsByMediumOrLargeTests()); + $this->assertSame(4, $file->numberOfTestedMethodsBySmallOrMediumOrLargeTests()); + } + + public function testNumberOfTestedFunctionsByTestSize(): void + { + $file = $this->createFileNodeWithMixedTestSizes(); + + $this->assertSame(2, $file->numberOfFunctions()); + $this->assertSame(1, $file->numberOfTestedFunctions()); + $this->assertSame(1, $file->numberOfTestedFunctionsBySmallTests()); + $this->assertSame(0, $file->numberOfTestedFunctionsByMediumTests()); + $this->assertSame(0, $file->numberOfTestedFunctionsByLargeTests()); + $this->assertSame(1, $file->numberOfTestedFunctionsBySmallOrMediumTests()); + $this->assertSame(1, $file->numberOfTestedFunctionsBySmallOrLargeTests()); + $this->assertSame(0, $file->numberOfTestedFunctionsByMediumOrLargeTests()); + $this->assertSame(1, $file->numberOfTestedFunctionsBySmallOrMediumOrLargeTests()); + } + + public function testTestSizeCountersAreZeroWhenNoTestDataIsAvailable(): void + { + $file = $this->createFileNode(); + + $this->assertSame(0, $file->numberOfExecutedLinesBySmallTests()); + $this->assertSame(0, $file->numberOfExecutedLinesByMediumTests()); + $this->assertSame(0, $file->numberOfExecutedLinesByLargeTests()); + $this->assertSame(0, $file->numberOfExecutedLinesBySmallOrMediumTests()); + $this->assertSame(0, $file->numberOfExecutedLinesBySmallOrLargeTests()); + $this->assertSame(0, $file->numberOfExecutedLinesByMediumOrLargeTests()); + $this->assertSame(0, $file->numberOfExecutedLinesBySmallOrMediumOrLargeTests()); + $this->assertSame(0, $file->numberOfTestedClassesBySmallTests()); + $this->assertSame(0, $file->numberOfTestedTraitsBySmallTests()); + $this->assertSame(0, $file->numberOfTestedMethodsBySmallTests()); + $this->assertSame(0, $file->numberOfTestedFunctionsBySmallTests()); + } + public function testHasBranchCoverageDataDefaultsToFalse(): void { $file = $this->createFileNode(); @@ -336,6 +429,65 @@ private function createFileNodeWithTrait(): File ); } + private function createFileNodeWithMixedTestSizes(): File + { + $root = new Directory('root'); + + $smallMethod = new Method('smallMethod', 1, 2, 'public function smallMethod(): void', Visibility::Public, 1); + $mediumMethod = new Method('mediumMethod', 3, 4, 'public function mediumMethod(): void', Visibility::Public, 1); + $largeMethod = new Method('largeMethod', 5, 6, 'public function largeMethod(): void', Visibility::Public, 1); + $mixedMethod = new Method('mixedMethod', 7, 8, 'public function mixedMethod(): void', Visibility::Public, 1); + + $smallClass = new Class_('SmallClass', 'SmallClass', '', 'test.php', 1, 2, null, [], [], ['smallMethod' => $smallMethod]); + $mediumClass = new Class_('MediumClass', 'MediumClass', '', 'test.php', 3, 4, null, [], [], ['mediumMethod' => $mediumMethod]); + $largeClass = new Class_('LargeClass', 'LargeClass', '', 'test.php', 5, 6, null, [], [], ['largeMethod' => $largeMethod]); + $mixedTrait = new Trait_('MixedTrait', 'MixedTrait', '', 'test.php', 7, 8, [], ['mixedMethod' => $mixedMethod]); + + $smallFunc = new Function_('smallFunc', 'smallFunc', '', 9, 10, 'function smallFunc(): void', 1); + $untestedFunc = new Function_('untestedFunc', 'untestedFunc', '', 11, 12, 'function untestedFunc(): void', 1); + + $lineCoverageData = [ + 1 => ['tSmall'], + 2 => ['tSmall'], + 3 => ['tMedium'], + 4 => ['tMedium'], + 5 => ['tLarge'], + 6 => ['tLarge'], + 7 => ['tSmall', 'tMedium'], + 8 => ['tSmall', 'tMedium'], + 9 => ['tSmall'], + 10 => ['tSmall'], + 11 => [], + 12 => [], + ]; + + $testData = [ + 'tSmall' => ['size' => 'small', 'status' => 'passed', 'time' => 0.0], + 'tMedium' => ['size' => 'medium', 'status' => 'passed', 'time' => 0.0], + 'tLarge' => ['size' => 'large', 'status' => 'passed', 'time' => 0.0], + ]; + + return new File( + 'test.php', + $root, + 'abc123', + $lineCoverageData, + [], + $testData, + [ + 'SmallClass' => $smallClass, + 'MediumClass' => $mediumClass, + 'LargeClass' => $largeClass, + ], + ['MixedTrait' => $mixedTrait], + [ + 'smallFunc' => $smallFunc, + 'untestedFunc' => $untestedFunc, + ], + new LinesOfCode(12, 0, 12), + ); + } + private function createFileNodeWithFunction(): File { $root = new Directory('root');