PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/reports/asynchronous/clover.php

http://github.com/mageekguy/atoum
PHP | 313 lines | 263 code | 50 blank | 0 comment | 8 complexity | 9adfa5e9dd3f5354fa2cb33c1208a476 MD5 | raw file
  1. <?php
  2. namespace mageekguy\atoum\reports\asynchronous;
  3. use
  4. mageekguy\atoum,
  5. mageekguy\atoum\exceptions,
  6. mageekguy\atoum\score
  7. ;
  8. class clover extends atoum\reports\asynchronous
  9. {
  10. const defaultTitle = 'atoum code coverage';
  11. const defaultPackage = 'atoumCodeCoverage';
  12. const lineTypeMethod = 'method';
  13. const lineTypeStatement = 'stmt';
  14. const lineTypeConditional = 'cond';
  15. protected $score = null;
  16. protected $loc = 0;
  17. protected $coveredLoc = 0;
  18. protected $methods = 0;
  19. protected $coveredMethods = 0;
  20. protected $classes = 0;
  21. protected $package = '';
  22. public function __construct(atoum\adapter $adapter = null)
  23. {
  24. parent::__construct();
  25. $this->setAdapter($adapter);
  26. if ($this->adapter->extension_loaded('libxml') === false)
  27. {
  28. throw new exceptions\runtime('libxml PHP extension is mandatory for clover report');
  29. }
  30. }
  31. public function getTitle()
  32. {
  33. return ($this->title ?: self::defaultTitle);
  34. }
  35. public function getPackage()
  36. {
  37. return ($this->package ?: self::defaultPackage);
  38. }
  39. public function setPackage($package)
  40. {
  41. $this->package = (string) $package;
  42. return $this;
  43. }
  44. public function handleEvent($event, atoum\observable $observable)
  45. {
  46. $this->score = ($event !== atoum\runner::runStop ? null : $observable->getScore());
  47. return parent::handleEvent($event, $observable);
  48. }
  49. public function build($event)
  50. {
  51. if ($event === atoum\runner::runStop)
  52. {
  53. $document = new \DOMDocument('1.0', 'UTF-8');
  54. $document->formatOutput = true;
  55. $document->appendChild($this->makeRootElement($document, $this->score->getCoverage()));
  56. $this->string = $document->saveXML();
  57. }
  58. return $this;
  59. }
  60. protected function makeRootElement(\DOMDocument $document, score\coverage $coverage)
  61. {
  62. $root = $document->createElement('coverage');
  63. $root->setAttribute('generated', $this->getAdapter()->time());
  64. $root->setAttribute('clover', $this->getAdapter()->uniqid());
  65. $root->appendChild($this->makeProjectElement($document, $coverage));
  66. return $root;
  67. }
  68. protected function makeProjectElement(\DOMDocument $document, score\coverage $coverage)
  69. {
  70. $project = $document->createElement('project');
  71. $project->setAttribute('timestamp', $this->getAdapter()->time());
  72. $project->setAttribute('name', $this->getTitle());
  73. $project->appendChild($this->makePackageElement($document, $coverage));
  74. $project->appendChild($this->makeProjectMetricsElement($document, sizeof($coverage->getClasses())));
  75. return $project;
  76. }
  77. protected function makeProjectMetricsElement(\DOMDocument $document, $files)
  78. {
  79. $metrics = $this->makePackageMetricsElement($document, $files);
  80. $metrics->setAttribute('packages', 1);
  81. return $metrics;
  82. }
  83. protected function makePackageElement(\DOMDocument $document, score\coverage $coverage)
  84. {
  85. $package = $document->createElement('package');
  86. $package->setAttribute('name', $this->getPackage());
  87. foreach ($coverage->getClasses() as $class => $file)
  88. {
  89. $package->appendChild($this->makeFileElement($document, $file, $class, $coverage->getCoverageForClass($class)));
  90. }
  91. $package->appendChild($this->makePackageMetricsElement($document, sizeof($coverage->getClasses())));
  92. return $package;
  93. }
  94. protected function makePackageMetricsElement(\DOMDocument $document, $files)
  95. {
  96. $metrics = $this->makeFileMetricsElement($document, $this->loc, $this->coveredLoc, $this->methods, $this->coveredMethods, $files);
  97. $metrics->setAttribute('files', $files);
  98. return $metrics;
  99. }
  100. protected function makeFileElement(\DOMDocument $document, $filename, $class, array $coverage)
  101. {
  102. $file = $document->createElement('file');
  103. $file->setAttribute('name', basename($filename));
  104. $file->setAttribute('path', $filename);
  105. $methods = count($coverage);
  106. $coveredMethods = 0;
  107. $totalLines = 0;
  108. $coveredLines = 0;
  109. foreach ($coverage as $lines)
  110. {
  111. if (sizeof($lines) > 0)
  112. {
  113. foreach ($lines as $lineNumber => $cover)
  114. {
  115. if ($cover >= -1)
  116. {
  117. $totalLines++;
  118. }
  119. if ($cover === 1)
  120. {
  121. $coveredLines++;
  122. $file->appendChild($this->makeLineElement($document, $lineNumber));
  123. } else {
  124. if ($cover !== -2)
  125. {
  126. $file->appendChild($this->makeLineElement($document, $lineNumber, 0));
  127. }
  128. }
  129. }
  130. if ($coveredLines === $totalLines)
  131. {
  132. ++$coveredMethods;
  133. }
  134. }
  135. }
  136. $this
  137. ->addLoc($totalLines)
  138. ->addCoveredLoc($coveredLines)
  139. ->addMethod($methods)
  140. ->addCoveredMethod($coveredMethods)
  141. ->addClasses(1)
  142. ;
  143. $file->appendChild($this->makeClassElement($document, $class, $coverage));
  144. $file->appendChild($this->makeFileMetricsElement($document, $totalLines, $coveredLines, $methods, $coveredMethods, 1));
  145. return $file;
  146. }
  147. protected function makeFileMetricsElement(\DOMDocument $document, $loc, $cloc, $methods, $coveredMethods, $classes)
  148. {
  149. $metrics = $this->makeClassMetricsElement($document, $loc, $cloc, $methods, $coveredMethods);
  150. $metrics->setAttribute('classes', $classes);
  151. $metrics->setAttribute('loc', $loc);
  152. $metrics->setAttribute('ncloc', $loc);
  153. return $metrics;
  154. }
  155. protected function makeClassElement(\DOMDocument $document, $classname, array $coverage)
  156. {
  157. $class = $document->createElement('class');
  158. $class->setAttribute('name', basename(str_replace('\\', DIRECTORY_SEPARATOR, $classname)));
  159. $methods = count($coverage);
  160. $coveredMethods = 0;
  161. $totalLines = 0;
  162. $coveredLines = 0;
  163. foreach ($coverage as $lines)
  164. {
  165. if (sizeof($lines) > 0)
  166. {
  167. ++$coveredMethods;
  168. }
  169. foreach ($lines as $cover)
  170. {
  171. if ($cover >= -1)
  172. {
  173. $totalLines++;
  174. }
  175. if ($cover === 1)
  176. {
  177. $coveredLines++;
  178. }
  179. }
  180. }
  181. $class->appendChild($this->makeClassMetricsElement($document, $totalLines, $coveredLines, $methods, $coveredMethods));
  182. return $class;
  183. }
  184. protected function makeClassMetricsElement(\DOMDocument $document, $loc, $cloc, $methods, $cmethods)
  185. {
  186. $metrics = $document->createElement('metrics');
  187. $metrics->setAttribute('complexity', 0);
  188. $metrics->setAttribute('elements', $loc);
  189. $metrics->setAttribute('coveredelements', $cloc);
  190. $metrics->setAttribute('conditionals', 0);
  191. $metrics->setAttribute('coveredconditionals', 0);
  192. $metrics->setAttribute('statements', $loc);
  193. $metrics->setAttribute('coveredstatements', $cloc);
  194. $metrics->setAttribute('methods', $methods);
  195. $metrics->setAttribute('coveredmethods', $cmethods);
  196. $metrics->setAttribute('testduration', 0);
  197. $metrics->setAttribute('testfailures', 0);
  198. $metrics->setAttribute('testpasses', 0);
  199. $metrics->setAttribute('testruns', 0);
  200. return $metrics;
  201. }
  202. protected function makeLineElement(\DOMDocument $document, $linenum, $count = 1)
  203. {
  204. $line = $document->createElement('line');
  205. $line->setAttribute('num', $linenum);
  206. $line->setAttribute('type', self::lineTypeStatement);
  207. $line->setAttribute('complexity', 0);
  208. $line->setAttribute('count', $count);
  209. $line->setAttribute('falsecount', 0);
  210. $line->setAttribute('truecount', 0);
  211. $line->setAttribute('signature', '');
  212. $line->setAttribute('testduration', 0);
  213. $line->setAttribute('testsuccess', 0);
  214. return $line;
  215. }
  216. protected function addLoc($count)
  217. {
  218. $this->loc += $count;
  219. return $this;
  220. }
  221. protected function addCoveredLoc($count)
  222. {
  223. $this->coveredLoc += $count;
  224. return $this;
  225. }
  226. protected function addMethod($count)
  227. {
  228. $this->methods += $count;
  229. return $this;
  230. }
  231. protected function addCoveredMethod($count)
  232. {
  233. $this->coveredMethods += $count;
  234. return $this;
  235. }
  236. protected function addClasses($count)
  237. {
  238. $this->classes += $count;
  239. return $this;
  240. }
  241. }