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