PageRenderTime 38ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Factory.php

https://gitlab.com/ealexis.t/trends
PHP | 242 lines | 107 code | 28 blank | 107 comment | 23 complexity | b2eb20c097f79379029a13483df03208 MD5 | raw file
  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. * Factory for PHP_CodeCoverage_Report_Node_* object graphs.
  12. *
  13. * @since Class available since Release 1.1.0
  14. */
  15. class PHP_CodeCoverage_Report_Factory
  16. {
  17. /**
  18. * @param PHP_CodeCoverage $coverage
  19. * @return PHP_CodeCoverage_Report_Node_Directory
  20. */
  21. public function create(PHP_CodeCoverage $coverage)
  22. {
  23. $files = $coverage->getData();
  24. $commonPath = $this->reducePaths($files);
  25. $root = new PHP_CodeCoverage_Report_Node_Directory(
  26. $commonPath,
  27. null
  28. );
  29. $this->addItems(
  30. $root,
  31. $this->buildDirectoryStructure($files),
  32. $coverage->getTests(),
  33. $coverage->getCacheTokens()
  34. );
  35. return $root;
  36. }
  37. /**
  38. * @param PHP_CodeCoverage_Report_Node_Directory $root
  39. * @param array $items
  40. * @param array $tests
  41. * @param bool $cacheTokens
  42. */
  43. private function addItems(PHP_CodeCoverage_Report_Node_Directory $root, array $items, array $tests, $cacheTokens)
  44. {
  45. foreach ($items as $key => $value) {
  46. if (substr($key, -2) == '/f') {
  47. $key = substr($key, 0, -2);
  48. if (file_exists($root->getPath() . DIRECTORY_SEPARATOR . $key)) {
  49. $root->addFile($key, $value, $tests, $cacheTokens);
  50. }
  51. } else {
  52. $child = $root->addDirectory($key);
  53. $this->addItems($child, $value, $tests, $cacheTokens);
  54. }
  55. }
  56. }
  57. /**
  58. * Builds an array representation of the directory structure.
  59. *
  60. * For instance,
  61. *
  62. * <code>
  63. * Array
  64. * (
  65. * [Money.php] => Array
  66. * (
  67. * ...
  68. * )
  69. *
  70. * [MoneyBag.php] => Array
  71. * (
  72. * ...
  73. * )
  74. * )
  75. * </code>
  76. *
  77. * is transformed into
  78. *
  79. * <code>
  80. * Array
  81. * (
  82. * [.] => Array
  83. * (
  84. * [Money.php] => Array
  85. * (
  86. * ...
  87. * )
  88. *
  89. * [MoneyBag.php] => Array
  90. * (
  91. * ...
  92. * )
  93. * )
  94. * )
  95. * </code>
  96. *
  97. * @param array $files
  98. * @return array
  99. */
  100. private function buildDirectoryStructure($files)
  101. {
  102. $result = array();
  103. foreach ($files as $path => $file) {
  104. $path = explode('/', $path);
  105. $pointer = &$result;
  106. $max = count($path);
  107. for ($i = 0; $i < $max; $i++) {
  108. if ($i == ($max - 1)) {
  109. $type = '/f';
  110. } else {
  111. $type = '';
  112. }
  113. $pointer = &$pointer[$path[$i] . $type];
  114. }
  115. $pointer = $file;
  116. }
  117. return $result;
  118. }
  119. /**
  120. * Reduces the paths by cutting the longest common start path.
  121. *
  122. * For instance,
  123. *
  124. * <code>
  125. * Array
  126. * (
  127. * [/home/sb/Money/Money.php] => Array
  128. * (
  129. * ...
  130. * )
  131. *
  132. * [/home/sb/Money/MoneyBag.php] => Array
  133. * (
  134. * ...
  135. * )
  136. * )
  137. * </code>
  138. *
  139. * is reduced to
  140. *
  141. * <code>
  142. * Array
  143. * (
  144. * [Money.php] => Array
  145. * (
  146. * ...
  147. * )
  148. *
  149. * [MoneyBag.php] => Array
  150. * (
  151. * ...
  152. * )
  153. * )
  154. * </code>
  155. *
  156. * @param array $files
  157. * @return string
  158. */
  159. private function reducePaths(&$files)
  160. {
  161. if (empty($files)) {
  162. return '.';
  163. }
  164. $commonPath = '';
  165. $paths = array_keys($files);
  166. if (count($files) == 1) {
  167. $commonPath = dirname($paths[0]) . '/';
  168. $files[basename($paths[0])] = $files[$paths[0]];
  169. unset($files[$paths[0]]);
  170. return $commonPath;
  171. }
  172. $max = count($paths);
  173. for ($i = 0; $i < $max; $i++) {
  174. // strip phar:// prefixes
  175. if (strpos($paths[$i], 'phar://') === 0) {
  176. $paths[$i] = substr($paths[$i], 7);
  177. $paths[$i] = strtr($paths[$i], '/', DIRECTORY_SEPARATOR);
  178. }
  179. $paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]);
  180. if (empty($paths[$i][0])) {
  181. $paths[$i][0] = DIRECTORY_SEPARATOR;
  182. }
  183. }
  184. $done = false;
  185. $max = count($paths);
  186. while (!$done) {
  187. for ($i = 0; $i < $max - 1; $i++) {
  188. if (!isset($paths[$i][0]) ||
  189. !isset($paths[$i+1][0]) ||
  190. $paths[$i][0] != $paths[$i+1][0]) {
  191. $done = true;
  192. break;
  193. }
  194. }
  195. if (!$done) {
  196. $commonPath .= $paths[0][0];
  197. if ($paths[0][0] != DIRECTORY_SEPARATOR) {
  198. $commonPath .= DIRECTORY_SEPARATOR;
  199. }
  200. for ($i = 0; $i < $max; $i++) {
  201. array_shift($paths[$i]);
  202. }
  203. }
  204. }
  205. $original = array_keys($files);
  206. $max = count($original);
  207. for ($i = 0; $i < $max; $i++) {
  208. $files[implode('/', $paths[$i])] = $files[$original[$i]];
  209. unset($files[$original[$i]]);
  210. }
  211. ksort($files);
  212. return substr($commonPath, 0, -1);
  213. }
  214. }