diff --git a/src/TUnit/framework/ConsoleTestRunner.php b/src/TUnit/framework/ConsoleTestRunner.php index 2df232e..b7c7822 100644 --- a/src/TUnit/framework/ConsoleTestRunner.php +++ b/src/TUnit/framework/ConsoleTestRunner.php @@ -19,6 +19,43 @@ */ class ConsoleTestRunner extends TestRunner { + /** + * @see setFiles() + * @var array + */ + protected $files; + + /** + * Constructor + * + * @author Tommy Montgomery + * @version 1.0 + * @since 1.0 + * + * @param array $tests + * @param array $listeners + * @param array $options + */ + public function __construct(array $tests = array(), array $listeners = array(), array $options = array()) { + parent::__construct($tests, $listeners, $options); + $this->files = array(); + } + + /** + * Sets the files to parse for tests + * + * @author Tommy Montgomery + * @version 1.0 + * @since 1.0 + * + * @param array $files Array of files and/or directories to parse for tests + * @return ConsoleTestRunner + */ + public final function setFiles(array $files) { + $this->files = $files; + return $this; + } + /** * {@inheritdoc} * @@ -36,6 +73,14 @@ if ($bootstrap !== null) { require_once $bootstrap; } + + + //accumulate tests from files + if (!empty($this->files)) { + foreach (TestAccumulator::getTests($this->files, $this->getOption('recursive')) as $test) { + $this->addTest($test); + } + } } /** diff --git a/src/TUnit/framework/reporting/CoverageReporter.php b/src/TUnit/framework/reporting/CoverageReporter.php index 6e81885..b230cda 100644 --- a/src/TUnit/framework/reporting/CoverageReporter.php +++ b/src/TUnit/framework/reporting/CoverageReporter.php @@ -9,6 +9,70 @@ private function __construct() {} + private static function parseCoverageData(array $coverageData) { + $newData = array(); + foreach ($coverageData as $file => $data) { + $classes = Util::getClassNamesFromFile($file); + //print_r($classes); + $refClasses = array(); + + foreach ($classes as $class) { + $refClasses[] = new ReflectionClass($class); + } + + $newData[$file] = array(); + foreach ($data as $line => $unitsCovered) { + $loc = 1; + $dloc = ($unitsCovered === self::DEAD) ? 1 : 0; + $cloc = ($unitsCovered > 0) ? 1 : 0; + + //find the class this line resides in, if any + $class = null; + foreach ($refClasses as $refClass) { + if ($line >= $refClass->getStartLine() && $line <= $refClass->getEndLine()) { + $class = $refClass; + //find the method this line resides in + foreach ($class->getMethods() as $refMethod) { + if ($line >= $refMethod->getStartLine() && $line <= $refMethod->getEndLine()) { + + if (isset($newData[$file]['classes'][$class->getName()][$refMethod->getName()])) { + $newData[$file]['classes'][$class->getName()][$refMethod->getName()]['loc'] += $loc; + $newData[$file]['classes'][$class->getName()][$refMethod->getName()]['dloc'] += $dloc; + $newData[$file]['classes'][$class->getName()][$refMethod->getName()]['cloc'] += $cloc; + } else { + $newData[$file]['classes'][$class->getName()][$refMethod->getName()] = array( + 'loc' => $loc, + 'dloc' => $dloc, + 'cloc' => $cloc + ); + } + break; + } + } + break; + } + } + + //procedural code + if ($class === null) { + if (isset($newData[$file]['procedural'])) { + $newData[$file]['procedural']['loc'] += $loc; + $newData[$file]['procedural']['dloc'] += $dloc; + $newData[$file]['procedural']['cloc'] += $cloc; + } else { + $newData[$file]['procedural'] = array( + 'loc' => $loc, + 'dloc' => $dloc, + 'cloc' => $cloc + ); + } + } + } + } + + return $newData; + } + public static function createConsoleReport(array $coverageData) { $coverageData = CoverageFilter::filter($coverageData); fwrite(STDOUT, "\nCode coverage information:\n\n"); @@ -47,11 +111,7 @@ fwrite(STDOUT, " Executable: $totloc (" . round($totcloc / $totloc * 100, 2) . "%)\n"); } - public static function createHtmlReport($dir, array $coverageData) { - if (!is_dir($dir)) { - throw new TUnitException($dir . ' is not a directory'); - } - + public static function createHtmlReport($coverageDir, array $coverageData) { $coverageData = CoverageFilter::filter($coverageData); $baseDir = array(); @@ -72,45 +132,72 @@ $baseDir = implode(DIRECTORY_SEPARATOR, $baseDir) . DIRECTORY_SEPARATOR; - $totalData = array(); + $dirData = array(); foreach ($coverageData as $file => $data) { - $totalData[$file] = array( - 'loc' => 0, - 'dloc' => 0, - 'cloc' => 0 - ); - - foreach ($data as $line => $unitsCovered) { - $totalData[$file]['loc']++; - if ($unitsCovered > 0) { - $totalData[$file]['cloc']++; - } else if ($unitsCovered === self::DEAD) { - $totalData[$file]['dloc']++; - } - } - - self::writeHtmlFile($file, $baseDir, $dir, $data); + self::writeHtmlFile($file, $baseDir, $coverageDir, self::parseCoverageData(array($file => $data)), $data); } //copy css over $template = dirname(__FILE__) . DIRECTORY_SEPARATOR . self::TEMPLATE_DIR . DIRECTORY_SEPARATOR; - copy($template . 'style.css', $dir . DIRECTORY_SEPARATOR . 'style.css'); + copy($template . 'style.css', $coverageDir . DIRECTORY_SEPARATOR . 'style.css'); } - private static function writeHtmlFile($sourceFile, $baseDir, $coverageDir, array $data) { - $lines = file($sourceFile, FILE_IGNORE_NEW_LINES); - $code = ''; + private static function writeHtmlFile($sourceFile, $baseDir, $coverageDir, array $classData, array $coverageData) { + //summary view + $fileCoverage = ''; + $classCoverage = ''; + + $tloc = 0; + $tdloc = 0; + $tcloc = 0; + foreach ($classData[$sourceFile]['classes'] as $class => $methods) { + $classCoverage = ''; + $classLoc = 0; + $classDloc = 0; + $classCloc = 0; + $methodCoverage = ''; + $refClass = new ReflectionClass($class); + foreach ($methods as $method => $methodData) { + $tloc += $methodData['loc']; + $tdloc += $methodData['dloc']; + $tcloc += $methodData['cloc']; + + $methodStartLine = $refClass->getMethod($method)->getStartLine(); + $methodCoverage .= "
Coverage | +
---|