CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.6 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.6
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
      • Validator
    • Network
      • Email
      • Http
    • Routing
      • Filter
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper

Classes

  • BaseCoverageReport
  • HtmlCoverageReport
  • TextCoverageReport
  1: <?php
  2: /**
  3:  * PHP5
  4:  *
  5:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  6:  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  7:  *
  8:  * Licensed under The MIT License
  9:  * For full copyright and license information, please see the LICENSE.txt
 10:  * Redistributions of files must retain the above copyright notice.
 11:  *
 12:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 13:  * @link          http://cakephp.org CakePHP(tm) Project
 14:  * @package       Cake.TestSuite.Coverage
 15:  * @since         CakePHP(tm) v 2.0
 16:  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 17:  */
 18: 
 19: App::uses('BaseCoverageReport', 'TestSuite/Coverage');
 20: 
 21: /**
 22:  * Generates code coverage reports in HTML from data obtained from PHPUnit
 23:  *
 24:  * @package       Cake.TestSuite.Coverage
 25:  */
 26: class HtmlCoverageReport extends BaseCoverageReport {
 27: 
 28: /**
 29:  * Holds the total number of processed rows.
 30:  *
 31:  * @var int
 32:  */
 33:     protected $_total = 0;
 34: 
 35: /**
 36:  * Holds the total number of covered rows.
 37:  *
 38:  * @var int
 39:  */
 40:     protected $_covered = 0;
 41: 
 42: /**
 43:  * Generates report HTML to display.
 44:  *
 45:  * @return string Compiled HTML report.
 46:  */
 47:     public function report() {
 48:         $pathFilter = $this->getPathFilter();
 49:         $coverageData = $this->filterCoverageDataByPath($pathFilter);
 50:         if (empty($coverageData)) {
 51:             return '<h3>No files to generate coverage for</h3>';
 52:         }
 53:         $output = $this->coverageScript();
 54:         $output .= <<<HTML
 55:         <h3>Code coverage results
 56:         <a href="#" onclick="coverage_toggle_all()" class="coverage-toggle">Toggle all files</a>
 57:         </h3>
 58: HTML;
 59:         foreach ($coverageData as $file => $coverageData) {
 60:             $fileData = file($file);
 61:             $output .= $this->generateDiff($file, $fileData, $coverageData);
 62:         }
 63: 
 64:         $percentCovered = 100;
 65:         if ($this->_total > 0) {
 66:             $percentCovered = round(100 * $this->_covered / $this->_total, 2);
 67:         }
 68:         $output .= '<div class="total">Overall coverage: <span class="coverage">' . $percentCovered . '%</span></div>';
 69:         return $output;
 70:     }
 71: 
 72: /**
 73:  * Generates an HTML diff for $file based on $coverageData.
 74:  *
 75:  * Handles both PHPUnit3.5 and 3.6 formats.
 76:  *
 77:  * 3.5 uses -1 for uncovered, and -2 for dead.
 78:  * 3.6 uses array() for uncovered and null for dead.
 79:  *
 80:  * @param string $filename Name of the file having coverage generated
 81:  * @param array $fileLines File data as an array. See file() for how to get one of these.
 82:  * @param array $coverageData Array of coverage data to use to generate HTML diffs with
 83:  * @return string HTML diff.
 84:  */
 85:     public function generateDiff($filename, $fileLines, $coverageData) {
 86:         $output = '';
 87:         $diff = array();
 88: 
 89:         list($covered, $total) = $this->_calculateCoveredLines($fileLines, $coverageData);
 90:         $this->_covered += $covered;
 91:         $this->_total += $total;
 92: 
 93:         //shift line numbers forward one;
 94:         array_unshift($fileLines, ' ');
 95:         unset($fileLines[0]);
 96: 
 97:         foreach ($fileLines as $lineno => $line) {
 98:             $class = 'ignored';
 99:             $coveringTests = array();
100:             if (!empty($coverageData[$lineno]) && is_array($coverageData[$lineno])) {
101:                 $coveringTests = array();
102:                 foreach ($coverageData[$lineno] as $test) {
103:                     $class = (is_array($test) && isset($test['id'])) ? $test['id'] : $test;
104:                     $testReflection = new ReflectionClass(current(explode('::', $class)));
105:                     $this->_testNames[] = $this->_guessSubjectName($testReflection);
106:                     $coveringTests[] = $class;
107:                 }
108:                 $class = 'covered';
109:             } elseif (isset($coverageData[$lineno]) && ($coverageData[$lineno] === -1 || $coverageData[$lineno] === array())) {
110:                 $class = 'uncovered';
111:             } elseif (array_key_exists($lineno, $coverageData) && ($coverageData[$lineno] === -2 || $coverageData[$lineno] === null)) {
112:                 $class .= ' dead';
113:             }
114:             $diff[] = $this->_paintLine($line, $lineno, $class, $coveringTests);
115:         }
116: 
117:         $percentCovered = 100;
118:         if ($total > 0) {
119:             $percentCovered = round(100 * $covered / $total, 2);
120:         }
121:         $output .= $this->coverageHeader($filename, $percentCovered);
122:         $output .= implode("", $diff);
123:         $output .= $this->coverageFooter();
124:         return $output;
125:     }
126: 
127: /**
128:  * Guess the class name the test was for based on the test case filename.
129:  *
130:  * @param ReflectionClass $testReflection The class to reflect
131:  * @return string Possible test subject name.
132:  */
133:     protected function _guessSubjectName($testReflection) {
134:         $basename = basename($testReflection->getFilename());
135:         if (strpos($basename, '.test') !== false) {
136:             list($subject, ) = explode('.', $basename, 2);
137:             return $subject;
138:         }
139:         $subject = str_replace('Test.php', '', $basename);
140:         return $subject;
141:     }
142: 
143: /**
144:  * Renders the HTML for a single line in the HTML diff.
145:  *
146:  * @param string $line The line content.
147:  * @param int $linenumber The line number
148:  * @param string $class The classname to use.
149:  * @param array $coveringTests The tests covering the line.
150:  * @return string
151:  */
152:     protected function _paintLine($line, $linenumber, $class, $coveringTests) {
153:         $coveredBy = '';
154:         if (!empty($coveringTests)) {
155:             $coveredBy = "Covered by:\n";
156:             foreach ($coveringTests as $test) {
157:                 $coveredBy .= $test . "\n";
158:             }
159:         }
160: 
161:         return sprintf(
162:             '<div class="code-line %s" title="%s"><span class="line-num">%s</span><span class="content">%s</span></div>',
163:             $class,
164:             $coveredBy,
165:             $linenumber,
166:             htmlspecialchars($line)
167:         );
168:     }
169: 
170: /**
171:  * generate some javascript for the coverage report.
172:  *
173:  * @return string
174:  */
175:     public function coverageScript() {
176:         return <<<HTML
177:         <script type="text/javascript">
178:         function coverage_show_hide(selector) {
179:             var element = document.getElementById(selector);
180:             element.style.display = (element.style.display === 'none') ? '' : 'none';
181:         }
182:         function coverage_toggle_all() {
183:             var divs = document.querySelectorAll('div.coverage-container');
184:             var i = divs.length;
185:             while (i--) {
186:                 if (divs[i] && divs[i].className.indexOf('primary') == -1) {
187:                     divs[i].style.display = (divs[i].style.display === 'none') ? '' : 'none';
188:                 }
189:             }
190:         }
191:         </script>
192: HTML;
193:     }
194: 
195: /**
196:  * Generate an HTML snippet for coverage headers
197:  *
198:  * @param string $filename The file name being covered
199:  * @param string $percent The percentage covered
200:  * @return string
201:  */
202:     public function coverageHeader($filename, $percent) {
203:         $hash = md5($filename);
204:         $filename = basename($filename);
205:         list($file) = explode('.', $filename);
206:         $display = in_array($file, $this->_testNames) ? 'block' : 'none';
207:         $primary = $display === 'block' ? 'primary' : '';
208:         return <<<HTML
209:     <div class="coverage-container $primary" style="display:$display;">
210:     <h4>
211:         <a href="#coverage-$filename-$hash" onclick="coverage_show_hide('coverage-$filename-$hash');">
212:             $filename Code coverage: $percent%
213:         </a>
214:     </h4>
215:     <div class="code-coverage-results" id="coverage-$filename-$hash" style="display:none;">
216:     <pre>
217: HTML;
218:     }
219: 
220: /**
221:  * Generate an HTML snippet for coverage footers
222:  *
223:  * @return void
224:  */
225:     public function coverageFooter() {
226:         return "</pre></div></div>";
227:     }
228: 
229: }
230: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs