/** * Transforms the coverage information * * @param string $filename The filename * @param array $coverageInformation Array with covergae information * * @author Michiel Rook <*****@*****.**> * @author Benjamin Schultz <*****@*****.**> * @return void */ protected function transformCoverageInformation($filename, $coverageInformation) { $classes = PHPUnitUtil::getDefinedClasses($filename, $this->classpath); if (is_array($classes)) { foreach ($classes as $classname) { $reflection = new ReflectionClass($classname); $methods = $reflection->getMethods(); if (method_exists($reflection, 'getShortName')) { $className = $reflection->getShortName(); } else { $className = $reflection->getName(); } $classElement = $this->doc->createElement('class'); $classElement->setAttribute('name', $className); $packageName = PHPUnitUtil::getPackageName($reflection->getName()); $subpackageName = PHPUnitUtil::getSubpackageName($reflection->getName()); if ($subpackageName !== null) { $this->addSubpackageToPackage($packageName, $subpackageName); $this->addClassToSubpackage($className, $classElement); } else { $this->addClassToPackage($packageName, $classElement); } $classStartLine = $reflection->getStartLine(); $methodscovered = 0; $methodcount = 0; // Strange PHP5 reflection bug, classes without parent class or implemented interfaces seem to start one line off if ($reflection->getParentClass() == NULL && count($reflection->getInterfaces()) == 0) { unset($coverageInformation[$classStartLine + 1]); } else { unset($coverageInformation[$classStartLine]); } // Remove out-of-bounds info unset($coverageInformation[0]); reset($coverageInformation); foreach ($methods as $method) { // PHP5 reflection considers methods of a parent class to be part of a subclass, we don't if ($method->getDeclaringClass()->getName() != $reflection->getName()) { continue; } // small fix for XDEBUG_CC_UNUSED if (isset($coverageInformation[$method->getStartLine()])) { unset($coverageInformation[$method->getStartLine()]); } if (isset($coverageInformation[$method->getEndLine()])) { unset($coverageInformation[$method->getEndLine()]); } if ($method->isAbstract()) { continue; } $linenr = key($coverageInformation); while ($linenr !== null && $linenr < $method->getStartLine()) { next($coverageInformation); $linenr = key($coverageInformation); } $methodCoveredCount = 0; $methodTotalCount = 0; $methodHasCoveredLine = false; while ($linenr !== null && $linenr <= $method->getEndLine()) { $methodTotalCount++; $methodHasCoveredLine = true; // set covered when CODE is other than -1 (not executed) if ($coverageInformation[$linenr] > 0 || $coverageInformation[$linenr] == -2) { $methodCoveredCount++; } next($coverageInformation); $linenr = key($coverageInformation); } if ($methodTotalCount == $methodCoveredCount && $methodHasCoveredLine) { $methodscovered++; } $methodcount++; } $statementcount = count(array_filter($coverageInformation, create_function('$var', 'return ($var != -2);'))); $statementscovered = count(array_filter($coverageInformation, create_function('$var', 'return ($var >= 0);'))); $classElement->appendChild($this->transformSourceFile($filename, $coverageInformation, $classStartLine)); $classElement->setAttribute('methodcount', $methodcount); $classElement->setAttribute('methodscovered', $methodscovered); $classElement->setAttribute('statementcount', $statementcount); $classElement->setAttribute('statementscovered', $statementscovered); $classElement->setAttribute('totalcount', $methodcount + $statementcount); $classElement->setAttribute('totalcovered', $methodscovered + $statementscovered); } } }
/** * Adds a class to their subpackage * * @param string $classname The name of the class * @param DOMNode $element The dom node to append to the subpackage element * * @author Benjamin Schultz <*****@*****.**> * @return void */ protected function addClassToSubpackage($classname, $element) { $subpackageName = PHPUnitUtil::getSubpackageName($classname); $subpackage = $this->getSubpackageElement($subpackageName); if ($subpackage === null) { $subpackage = $this->doc->createElement('subpackage'); $subpackage->setAttribute('name', $subpackageName); $this->doc->documentElement->appendChild($subpackage); } $subpackage->appendChild($element); }