Skip to content

Commit ea95590

Browse files
committed
Encapsulate processed coverage data
1 parent 06bfa0c commit ea95590

9 files changed

+294
-139
lines changed

src/CodeCoverage.php

+10-95
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ final class CodeCoverage
8989
/**
9090
* Code coverage data.
9191
*
92-
* @var array
92+
* @var ProcessedCodeCoverageData
9393
*/
94-
private $data = [];
94+
private $data;
9595

9696
/**
9797
* @var array
@@ -151,6 +151,7 @@ public function __construct(Driver $driver = null, Filter $filter = null)
151151
$this->filter = $filter;
152152

153153
$this->wizard = new Wizard;
154+
$this->data = new ProcessedCodeCoverageData();
154155
}
155156

156157
/**
@@ -172,7 +173,7 @@ public function clear(): void
172173
{
173174
$this->isInitialized = false;
174175
$this->currentId = null;
175-
$this->data = [];
176+
$this->data = new ProcessedCodeCoverageData();
176177
$this->tests = [];
177178
$this->report = null;
178179
}
@@ -188,7 +189,7 @@ public function filter(): Filter
188189
/**
189190
* Returns the collected code coverage data.
190191
*/
191-
public function getData(bool $raw = false): array
192+
public function getData(bool $raw = false): ProcessedCodeCoverageData
192193
{
193194
if (!$raw && $this->addUncoveredFilesFromWhitelist) {
194195
$this->addUncoveredFilesFromWhitelist();
@@ -200,7 +201,7 @@ public function getData(bool $raw = false): array
200201
/**
201202
* Sets the coverage data.
202203
*/
203-
public function setData(array $data): void
204+
public function setData(ProcessedCodeCoverageData $data): void
204205
{
205206
$this->data = $data;
206207
$this->report = null;
@@ -297,7 +298,7 @@ public function append(RawCodeCoverageData $rawData, $id = null, bool $append =
297298

298299
$this->applyWhitelistFilter($rawData);
299300
$this->applyIgnoredLinesFilter($rawData);
300-
$this->initializeFilesThatAreSeenTheFirstTime($rawData);
301+
$this->data->initializeFilesThatAreSeenTheFirstTime($rawData);
301302

302303
if (!$append) {
303304
return;
@@ -339,19 +340,7 @@ public function append(RawCodeCoverageData $rawData, $id = null, bool $append =
339340

340341
$this->tests[$id] = ['size' => $size, 'status' => $status];
341342

342-
foreach ($rawData->getLineCoverage() as $file => $lines) {
343-
if (!$this->filter->isFile($file)) {
344-
continue;
345-
}
346-
347-
foreach ($lines as $k => $v) {
348-
if ($v === Driver::LINE_EXECUTED) {
349-
if (empty($this->data[$file][$k]) || !\in_array($id, $this->data[$file][$k])) {
350-
$this->data[$file][$k][] = $id;
351-
}
352-
}
353-
}
354-
}
343+
$this->data->markCodeAsExecutedByTestCase($id, $rawData);
355344

356345
$this->report = null;
357346
}
@@ -367,36 +356,7 @@ public function merge(self $that): void
367356
\array_merge($this->filter->getWhitelistedFiles(), $that->filter()->getWhitelistedFiles())
368357
);
369358

370-
foreach ($that->data as $file => $lines) {
371-
if (!isset($this->data[$file])) {
372-
if (!$this->filter->isFiltered($file)) {
373-
$this->data[$file] = $lines;
374-
}
375-
376-
continue;
377-
}
378-
379-
// we should compare the lines if any of two contains data
380-
$compareLineNumbers = \array_unique(
381-
\array_merge(
382-
\array_keys($this->data[$file]),
383-
\array_keys($that->data[$file])
384-
)
385-
);
386-
387-
foreach ($compareLineNumbers as $line) {
388-
$thatPriority = $this->getLinePriority($that->data[$file], $line);
389-
$thisPriority = $this->getLinePriority($this->data[$file], $line);
390-
391-
if ($thatPriority > $thisPriority) {
392-
$this->data[$file][$line] = $that->data[$file][$line];
393-
} elseif ($thatPriority === $thisPriority && \is_array($this->data[$file][$line])) {
394-
$this->data[$file][$line] = \array_unique(
395-
\array_merge($this->data[$file][$line], $that->data[$file][$line])
396-
);
397-
}
398-
}
399-
}
359+
$this->data->merge($that->data);
400360

401361
$this->tests = \array_merge($this->tests, $that->getTests());
402362
$this->report = null;
@@ -457,38 +417,6 @@ public function setUnintentionallyCoveredSubclassesWhitelist(array $whitelist):
457417
$this->unintentionallyCoveredSubclassesWhitelist = $whitelist;
458418
}
459419

460-
/**
461-
* Determine the priority for a line
462-
*
463-
* 1 = the line is not set
464-
* 2 = the line has not been tested
465-
* 3 = the line is dead code
466-
* 4 = the line has been tested
467-
*
468-
* During a merge, a higher number is better.
469-
*
470-
* @param array $data
471-
* @param int $line
472-
*
473-
* @return int
474-
*/
475-
private function getLinePriority($data, $line)
476-
{
477-
if (!\array_key_exists($line, $data)) {
478-
return 1;
479-
}
480-
481-
if (\is_array($data[$line]) && \count($data[$line]) === 0) {
482-
return 2;
483-
}
484-
485-
if ($data[$line] === null) {
486-
return 3;
487-
}
488-
489-
return 4;
490-
}
491-
492420
/**
493421
* Applies the @covers annotation filtering.
494422
*
@@ -559,19 +487,6 @@ private function applyIgnoredLinesFilter(RawCodeCoverageData $data): void
559487
}
560488
}
561489

562-
private function initializeFilesThatAreSeenTheFirstTime(RawCodeCoverageData $data): void
563-
{
564-
foreach ($data->getLineCoverage() as $file => $lines) {
565-
if (!isset($this->data[$file]) && $this->filter->isFile($file)) {
566-
$this->data[$file] = [];
567-
568-
foreach ($lines as $k => $v) {
569-
$this->data[$file][$k] = $v === -2 ? null : [];
570-
}
571-
}
572-
}
573-
}
574-
575490
/**
576491
* @throws CoveredCodeNotExecutedException
577492
* @throws InvalidArgumentException
@@ -585,7 +500,7 @@ private function addUncoveredFilesFromWhitelist(): void
585500
$data = [];
586501
$uncoveredFiles = \array_diff(
587502
$this->filter->getWhitelist(),
588-
\array_keys($this->data)
503+
\array_keys($this->data->getLineCoverage())
589504
);
590505

591506
foreach ($uncoveredFiles as $uncoveredFile) {

src/Node/Builder.php

+13-16
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,22 @@
1010
namespace SebastianBergmann\CodeCoverage\Node;
1111

1212
use SebastianBergmann\CodeCoverage\CodeCoverage;
13+
use SebastianBergmann\CodeCoverage\ProcessedCodeCoverageData;
1314

1415
final class Builder
1516
{
1617
public function build(CodeCoverage $coverage): Directory
1718
{
18-
$files = $coverage->getData();
19-
$commonPath = $this->reducePaths($files);
19+
$data = clone $coverage->getData(); // clone because path munging is destructive to the original data
20+
$commonPath = $this->reducePaths($data);
2021
$root = new Directory(
2122
$commonPath,
2223
null
2324
);
2425

2526
$this->addItems(
2627
$root,
27-
$this->buildDirectoryStructure($files),
28+
$this->buildDirectoryStructure($data),
2829
$coverage->getTests(),
2930
$coverage->getCacheTokens()
3031
);
@@ -90,8 +91,9 @@ private function addItems(Directory $root, array $items, array $tests, bool $cac
9091
* )
9192
* </code>
9293
*/
93-
private function buildDirectoryStructure(array $files): array
94+
private function buildDirectoryStructure(ProcessedCodeCoverageData $data): array
9495
{
96+
$files = $data->getLineCoverage();
9597
$result = [];
9698

9799
foreach ($files as $path => $file) {
@@ -152,20 +154,18 @@ private function buildDirectoryStructure(array $files): array
152154
* )
153155
* </code>
154156
*/
155-
private function reducePaths(array &$files): string
157+
private function reducePaths(ProcessedCodeCoverageData $coverage): string
156158
{
157-
if (empty($files)) {
159+
if (empty($coverage->getCoveredFiles())) {
158160
return '.';
159161
}
160162

161163
$commonPath = '';
162-
$paths = \array_keys($files);
164+
$paths = $coverage->getCoveredFiles();
163165

164-
if (\count($files) === 1) {
166+
if (\count($paths) === 1) {
165167
$commonPath = \dirname($paths[0]) . \DIRECTORY_SEPARATOR;
166-
$files[\basename($paths[0])] = $files[$paths[0]];
167-
168-
unset($files[$paths[0]]);
168+
$coverage->renameFile($paths[0], \basename($paths[0]));
169169

170170
return $commonPath;
171171
}
@@ -212,16 +212,13 @@ private function reducePaths(array &$files): string
212212
}
213213
}
214214

215-
$original = \array_keys($files);
215+
$original = $coverage->getCoveredFiles();
216216
$max = \count($original);
217217

218218
for ($i = 0; $i < $max; $i++) {
219-
$files[\implode(\DIRECTORY_SEPARATOR, $paths[$i])] = $files[$original[$i]];
220-
unset($files[$original[$i]]);
219+
$coverage->renameFile($original[$i], \implode(\DIRECTORY_SEPARATOR, $paths[$i]));
221220
}
222221

223-
\ksort($files);
224-
225222
return \substr($commonPath, 0, -1);
226223
}
227224
}

0 commit comments

Comments
 (0)