1: <?php
2: /**
3: * Abstract class for common CoverageReport methods.
4: * Provides several template methods for custom output.
5: *
6: * PHP5
7: *
8: * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
9: * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
10: *
11: * Licensed under The MIT License
12: * Redistributions of files must retain the above copyright notice.
13: *
14: * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
15: * @link http://cakephp.org CakePHP(tm) Project
16: * @package Cake.TestSuite.Coverage
17: * @since CakePHP(tm) v 2.0
18: * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
19: */
20:
21: /**
22: * Abstract class for common CoverageReport methods.
23: * Provides several template methods for custom output.
24: *
25: * @package Cake.TestSuite.Coverage
26: */
27: abstract class BaseCoverageReport {
28:
29: /**
30: * coverage data
31: *
32: * @var string
33: */
34: protected $_rawCoverage;
35:
36: /**
37: * is the test an app test
38: *
39: * @var string
40: */
41: public $appTest = false;
42:
43: /**
44: * is the test a plugin test
45: *
46: * @var string
47: */
48: public $pluginTest = false;
49:
50: /**
51: * Array of test case file names. Used to do basename() matching with
52: * files that have coverage to decide which results to show on page load.
53: *
54: * @var array
55: */
56: protected $_testNames = array();
57:
58: /**
59: * Constructor
60: *
61: * @param array $coverage Array of coverage data from PHPUnit_Test_Result
62: * @param CakeBaseReporter $reporter A reporter to use for the coverage report.
63: * @return void
64: */
65: public function __construct($coverage, CakeBaseReporter $reporter) {
66: $this->_rawCoverage = $coverage;
67: $this->_setParams($reporter);
68: }
69:
70: /**
71: * Pulls params out of the reporter.
72: *
73: * @param CakeBaseReporter $reporter Reporter to suck params out of.
74: * @return void
75: */
76: protected function _setParams(CakeBaseReporter $reporter) {
77: if ($reporter->params['app']) {
78: $this->appTest = true;
79: }
80: if ($reporter->params['plugin']) {
81: $this->pluginTest = Inflector::camelize($reporter->params['plugin']);
82: }
83: }
84:
85: /**
86: * Set the coverage data array
87: *
88: * @param array $coverage Coverage data to use.
89: * @return void
90: */
91: public function setCoverage($coverage) {
92: $this->_rawCoverage = $coverage;
93: }
94:
95: /**
96: * Gets the base path that the files we are interested in live in.
97: *
98: * @return void
99: */
100: public function getPathFilter() {
101: $path = ROOT . DS;
102: if ($this->appTest) {
103: $path .= APP_DIR . DS;
104: } elseif ($this->pluginTest) {
105: $path = App::pluginPath($this->pluginTest);
106: } else {
107: $path = CAKE;
108: }
109: return $path;
110: }
111:
112: /**
113: * Filters the coverage data by path. Files not in the provided path will be removed.
114: *
115: * @param string $path Path to filter files by.
116: * @return array Array of coverage data for files that match the given path.
117: */
118: public function filterCoverageDataByPath($path) {
119: $files = array();
120: foreach ($this->_rawCoverage as $fileName => $fileCoverage) {
121: if (strpos($fileName, $path) !== 0) {
122: continue;
123: }
124: $files[$fileName] = $fileCoverage;
125: }
126: return $files;
127: }
128:
129: /**
130: * Calculates how many lines are covered and what the total number of executable lines is.
131: *
132: * Handles both PHPUnit3.5 and 3.6 formats.
133: *
134: * 3.5 uses -1 for uncovered, and -2 for dead.
135: * 3.6 uses array() for uncovered and null for dead.
136: *
137: * @param array $fileLines
138: * @param array $coverageData
139: * @return array. Array of covered, total lines.
140: */
141: protected function _calculateCoveredLines($fileLines, $coverageData) {
142: $covered = $total = 0;
143:
144: //shift line numbers forward one
145: array_unshift($fileLines, ' ');
146: unset($fileLines[0]);
147:
148: foreach ($fileLines as $lineno => $line) {
149: if (!isset($coverageData[$lineno])) {
150: continue;
151: }
152: if (is_array($coverageData[$lineno]) && !empty($coverageData[$lineno])) {
153: $covered++;
154: $total++;
155: } elseif ($coverageData[$lineno] === -1 || $coverageData[$lineno] === array()) {
156: $total++;
157: }
158: }
159: return array($covered, $total);
160: }
161:
162: /**
163: * Generates report to display.
164: *
165: * @return string compiled html report.
166: */
167: abstract public function report();
168:
169: /**
170: * Generates an coverage 'diff' for $file based on $coverageData.
171: *
172: * @param string $filename Name of the file having coverage generated
173: * @param array $fileLines File data as an array. See file() for how to get one of these.
174: * @param array $coverageData Array of coverage data to use to generate HTML diffs with
175: * @return string prepared report for a single file.
176: */
177: abstract public function generateDiff($filename, $fileLines, $coverageData);
178:
179: }
180: