comparison vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Factory.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2 /*
3 * This file is part of the PHP_CodeCoverage package.
4 *
5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11 /**
12 * Factory for PHP_CodeCoverage_Report_Node_* object graphs.
13 *
14 * @since Class available since Release 1.1.0
15 */
16 class PHP_CodeCoverage_Report_Factory
17 {
18 /**
19 * @param PHP_CodeCoverage $coverage
20 * @return PHP_CodeCoverage_Report_Node_Directory
21 */
22 public function create(PHP_CodeCoverage $coverage)
23 {
24 $files = $coverage->getData();
25 $commonPath = $this->reducePaths($files);
26 $root = new PHP_CodeCoverage_Report_Node_Directory(
27 $commonPath,
28 null
29 );
30
31 $this->addItems(
32 $root,
33 $this->buildDirectoryStructure($files),
34 $coverage->getTests(),
35 $coverage->getCacheTokens()
36 );
37
38 return $root;
39 }
40
41 /**
42 * @param PHP_CodeCoverage_Report_Node_Directory $root
43 * @param array $items
44 * @param array $tests
45 * @param bool $cacheTokens
46 */
47 private function addItems(PHP_CodeCoverage_Report_Node_Directory $root, array $items, array $tests, $cacheTokens)
48 {
49 foreach ($items as $key => $value) {
50 if (substr($key, -2) == '/f') {
51 $key = substr($key, 0, -2);
52
53 if (file_exists($root->getPath() . DIRECTORY_SEPARATOR . $key)) {
54 $root->addFile($key, $value, $tests, $cacheTokens);
55 }
56 } else {
57 $child = $root->addDirectory($key);
58 $this->addItems($child, $value, $tests, $cacheTokens);
59 }
60 }
61 }
62
63 /**
64 * Builds an array representation of the directory structure.
65 *
66 * For instance,
67 *
68 * <code>
69 * Array
70 * (
71 * [Money.php] => Array
72 * (
73 * ...
74 * )
75 *
76 * [MoneyBag.php] => Array
77 * (
78 * ...
79 * )
80 * )
81 * </code>
82 *
83 * is transformed into
84 *
85 * <code>
86 * Array
87 * (
88 * [.] => Array
89 * (
90 * [Money.php] => Array
91 * (
92 * ...
93 * )
94 *
95 * [MoneyBag.php] => Array
96 * (
97 * ...
98 * )
99 * )
100 * )
101 * </code>
102 *
103 * @param array $files
104 * @return array
105 */
106 private function buildDirectoryStructure($files)
107 {
108 $result = array();
109
110 foreach ($files as $path => $file) {
111 $path = explode('/', $path);
112 $pointer = &$result;
113 $max = count($path);
114
115 for ($i = 0; $i < $max; $i++) {
116 if ($i == ($max - 1)) {
117 $type = '/f';
118 } else {
119 $type = '';
120 }
121
122 $pointer = &$pointer[$path[$i] . $type];
123 }
124
125 $pointer = $file;
126 }
127
128 return $result;
129 }
130
131 /**
132 * Reduces the paths by cutting the longest common start path.
133 *
134 * For instance,
135 *
136 * <code>
137 * Array
138 * (
139 * [/home/sb/Money/Money.php] => Array
140 * (
141 * ...
142 * )
143 *
144 * [/home/sb/Money/MoneyBag.php] => Array
145 * (
146 * ...
147 * )
148 * )
149 * </code>
150 *
151 * is reduced to
152 *
153 * <code>
154 * Array
155 * (
156 * [Money.php] => Array
157 * (
158 * ...
159 * )
160 *
161 * [MoneyBag.php] => Array
162 * (
163 * ...
164 * )
165 * )
166 * </code>
167 *
168 * @param array $files
169 * @return string
170 */
171 private function reducePaths(&$files)
172 {
173 if (empty($files)) {
174 return '.';
175 }
176
177 $commonPath = '';
178 $paths = array_keys($files);
179
180 if (count($files) == 1) {
181 $commonPath = dirname($paths[0]) . '/';
182 $files[basename($paths[0])] = $files[$paths[0]];
183
184 unset($files[$paths[0]]);
185
186 return $commonPath;
187 }
188
189 $max = count($paths);
190
191 for ($i = 0; $i < $max; $i++) {
192 // strip phar:// prefixes
193 if (strpos($paths[$i], 'phar://') === 0) {
194 $paths[$i] = substr($paths[$i], 7);
195 $paths[$i] = strtr($paths[$i], '/', DIRECTORY_SEPARATOR);
196 }
197 $paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]);
198
199 if (empty($paths[$i][0])) {
200 $paths[$i][0] = DIRECTORY_SEPARATOR;
201 }
202 }
203
204 $done = false;
205 $max = count($paths);
206
207 while (!$done) {
208 for ($i = 0; $i < $max - 1; $i++) {
209 if (!isset($paths[$i][0]) ||
210 !isset($paths[$i+1][0]) ||
211 $paths[$i][0] != $paths[$i+1][0]) {
212 $done = true;
213 break;
214 }
215 }
216
217 if (!$done) {
218 $commonPath .= $paths[0][0];
219
220 if ($paths[0][0] != DIRECTORY_SEPARATOR) {
221 $commonPath .= DIRECTORY_SEPARATOR;
222 }
223
224 for ($i = 0; $i < $max; $i++) {
225 array_shift($paths[$i]);
226 }
227 }
228 }
229
230 $original = array_keys($files);
231 $max = count($original);
232
233 for ($i = 0; $i < $max; $i++) {
234 $files[implode('/', $paths[$i])] = $files[$original[$i]];
235 unset($files[$original[$i]]);
236 }
237
238 ksort($files);
239
240 return substr($commonPath, 0, -1);
241 }
242 }