-
-
Notifications
You must be signed in to change notification settings - Fork 71
/
AbstractGenerator.php
131 lines (100 loc) 路 2.87 KB
/
AbstractGenerator.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<?php
/**
* This file is part of the Nette Tester.
* Copyright (c) 2009 David Grudl (https://davidgrudl.com)
*/
declare(strict_types=1);
namespace Tester\CodeCoverage\Generators;
use Tester\Helpers;
/**
* Code coverage report generator.
*/
abstract class AbstractGenerator
{
protected const
CODE_DEAD = -2,
CODE_UNTESTED = -1,
CODE_TESTED = 1;
/** @var array */
public $acceptFiles = ['php', 'phpt', 'phtml'];
/** @var array */
protected $data;
/** @var array */
protected $sources;
/** @var int */
protected $totalSum = 0;
/** @var int */
protected $coveredSum = 0;
/**
* @param string $file path to coverage.dat file
* @param array $sources paths to covered source files or directories
*/
public function __construct(string $file, array $sources = [])
{
if (!is_file($file)) {
throw new \Exception("File '$file' is missing.");
}
$this->data = @unserialize(file_get_contents($file)); // @ is escalated to exception
if (!is_array($this->data)) {
throw new \Exception("Content of file '$file' is invalid.");
}
$this->data = array_filter($this->data, function (string $path): bool {
return @is_file($path); // @ some files or wrappers may not exist, i.e. mock://
}, ARRAY_FILTER_USE_KEY);
if (!$sources) {
$sources = [Helpers::findCommonDirectory(array_keys($this->data))];
} else {
foreach ($sources as $source) {
if (!file_exists($source)) {
throw new \Exception("File or directory '$source' is missing.");
}
}
}
$this->sources = array_map('realpath', $sources);
}
public function render(string $file = null): void
{
$handle = $file ? @fopen($file, 'w') : STDOUT; // @ is escalated to exception
if (!$handle) {
throw new \Exception("Unable to write to file '$file'.");
}
ob_start(function (string $buffer) use ($handle) { fwrite($handle, $buffer); }, 4096);
try {
$this->renderSelf();
} catch (\Exception $e) {
}
ob_end_flush();
fclose($handle);
if (isset($e)) {
if ($file) {
unlink($file);
}
throw $e;
}
}
public function getCoveredPercent(): float
{
return $this->totalSum ? $this->coveredSum * 100 / $this->totalSum : 0;
}
protected function getSourceIterator(): \Iterator
{
$iterator = new \AppendIterator;
foreach ($this->sources as $source) {
$iterator->append(
is_dir($source)
? new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source))
: new \ArrayIterator([new \SplFileInfo($source)])
);
}
return new \CallbackFilterIterator($iterator, function (\SplFileInfo $file): bool {
return $file->getBasename()[0] !== '.' // . or .. or .gitignore
&& in_array($file->getExtension(), $this->acceptFiles, true);
});
}
/** @deprecated */
protected static function getCommonFilesPath(array $files): string
{
return Helpers::findCommonDirectory($files);
}
abstract protected function renderSelf(): void;
}