Issues (12)

src/CodeCoverage/Report.php (1 issue)

Severity
1
<?php
2
declare(strict_types=1);
3
4
namespace MyTester\CodeCoverage;
5
6
use Nette\Utils\Strings;
7
use ReflectionClass;
8
use ReflectionFunction;
9
10
/**
11
 * Report for code coverage
12
 * Contains all relevant data in a convenient form
13
 * Is a passed to {@see ICodeCoverageFormatter} to generate output
14
 *
15
 * @author Jakub Konečný
16
 */
17
final readonly class Report
18
{
19
    public int $linesTotal;
20
    public int $linesCovered;
21
    public int $coveragePercent;
22
    public string $sourcePath;
23
    /** @var ReportFile[] */
24
    public array $files;
25
26
    /**
27
     * @see ICodeCoverageEngine::collect()
28
     * @param array<string, array<int, int>> $data Raw code coverage data
29
     */
30
    public function __construct(array $data)
31
    {
32 1
        $filenames = array_keys($data);
33 1
        $this->sourcePath = Strings::findPrefix($filenames);
34
35 1
        $allClassNames = array_merge(get_declared_classes(), get_declared_traits());
36
        /** @var ReflectionClass<object>[] $allClasses */
37 1
        $allClasses = [];
38 1
        foreach ($allClassNames as $className) {
39 1
            $rc = new ReflectionClass($className);
40 1
            if (!str_starts_with((string) $rc->getFileName(), $this->sourcePath)) {
41 1
                continue;
42
            }
43 1
            $allClasses[] = $rc;
44
        }
45
46 1
        $allFunctionNames = get_defined_functions()["user"];
47
        /** @var ReflectionFunction[] $allFunctions */
48 1
        $allFunctions = [];
49 1
        foreach ($allFunctionNames as $functionName) {
50 1
            $rf = new ReflectionFunction($functionName);
51 1
            if (!str_starts_with((string) $rf->getFileName(), $this->sourcePath)) {
52 1
                continue;
53
            }
54 1
            $allFunctions[] = $rf;
55
        }
56
57
        /** @var ReportFile[] $files */
58 1
        $files = [];
59 1
        $totalLines = 0;
60 1
        $coveredLines = 0;
61 1
        foreach ($data as $filename => $file) {
62 1
            $classes = array_values(array_filter($allClasses, static function (ReflectionClass $rc) use ($filename) {
63 1
                return ((string) $rc->getFileName() === $filename);
64 1
            }));
65 1
            $functions = array_values(array_filter($allFunctions, static function (ReflectionFunction $rf) use ($filename) {
0 ignored issues
show
Line exceeds 120 characters; contains 124 characters
Loading history...
66 1
                return ((string) $rf->getFileName() === $filename);
67 1
            }));
68 1
            $files[] = new ReportFile(
69 1
                (string) Strings::after($filename, $this->sourcePath),
70
                $classes,
71
                $functions,
72
                $file
73
            );
74 1
            foreach ($file as $line) {
75 1
                $totalLines++;
76 1
                if ($line > 0) {
77 1
                    $coveredLines++;
78
                }
79
            }
80
        }
81 1
        $coveragePercent = ($totalLines === 0) ? 0 : (int) (($coveredLines / $totalLines) * 100);
82
83 1
        $this->coveragePercent = $coveragePercent;
84 1
        $this->linesTotal = $totalLines;
85 1
        $this->linesCovered = $coveredLines;
86 1
        $this->files = $files;
87 1
    }
88
}
89