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
22App::uses('Inflector', 'Utility');
23App::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 */
31abstract 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