]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - tests/PHPUnit/PHP/CodeCoverage/Report/Text.php
Merge branch 'master' of github.com:sugarcrm/sugarcrm_dev
[Github/sugarcrm.git] / tests / PHPUnit / PHP / CodeCoverage / Report / Text.php
1 <?php
2 /**
3  * PHP_CodeCoverage
4  *
5  * Copyright (c) 2009-2011, Sebastian Bergmann <sb@sebastian-bergmann.de>.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  *   * Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *
15  *   * Redistributions in binary form must reproduce the above copyright
16  *     notice, this list of conditions and the following disclaimer in
17  *     the documentation and/or other materials provided with the
18  *     distribution.
19  *
20  *   * Neither the name of Sebastian Bergmann nor the names of his
21  *     contributors may be used to endorse or promote products derived
22  *     from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * @category   PHP
38  * @package    CodeCoverage
39  * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
40  * @copyright  2009-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
41  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
42  * @link       http://github.com/sebastianbergmann/php-code-coverage
43  * @since      File available since Release 1.1.0
44  */
45
46 /**
47  * Generates human readable output from an PHP_CodeCoverage object.
48  *
49  * The output gets put into a text file our written to the CLI.
50  *
51  * @category   PHP
52  * @package    CodeCoverage
53  * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
54  * @copyright  2009-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
55  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
56  * @version    Release: 1.1.1
57  * @link       http://github.com/sebastianbergmann/php-code-coverage
58  * @since      Class available since Release 1.1.0
59  */
60 class PHP_CodeCoverage_Report_Text
61 {
62     protected $outputStream;
63     protected $title;
64     protected $lowUpperBound;
65     protected $highLowerBound;
66     protected $showUncoveredFiles;
67
68     protected $colors = array(
69       'green'  => "\x1b[30;42m",
70       'yellow' => "\x1b[30;43m",
71       'red'    => "\x1b[37;41m",
72       'header' => "\x1b[47;40m",
73       'reset'  => "\x1b[0m",
74       'eol'    => "\x1b[2K",
75     );
76
77     public function __construct(PHPUnit_Util_Printer $outputStream, $title, $lowUpperBound, $highLowerBound, $showUncoveredFiles)
78     {
79         $this->outputStream       = $outputStream;
80         $this->title              = $title;
81         $this->lowUpperBound      = $lowUpperBound;
82         $this->highLowerBound     = $highLowerBound;
83         $this->showUncoveredFiles = $showUncoveredFiles;
84     }
85
86     /**
87      * @param  PHP_CodeCoverage $coverage
88      * @param  string           $target
89      * @param  string           $name
90      * @return string
91      */
92     public function process(PHP_CodeCoverage $coverage, $showColors = FALSE)
93     {
94         $output   = '';
95         $packages = array();
96         $report   = $coverage->getReport();
97         unset($coverage);
98
99         $colors = array(
100           'header'  => '',
101           'classes' => '',
102           'methods' => '',
103           'lines'   => '',
104           'reset'   => '',
105           'eol'     => ''
106         );
107
108         if ($showColors) {
109             $colors['classes'] = $this->getCoverageColor(
110                                    $report->getNumTestedClasses(),
111                                    $report->getNumClasses()
112                                  );
113             $colors['methods'] = $this->getCoverageColor(
114                                    $report->getNumTestedMethods(),
115                                    $report->getNumMethods()
116                                  );
117             $colors['lines']   = $this->getCoverageColor(
118                                    $report->getNumExecutedLines(),
119                                    $report->getNumExecutableLines()
120                                  );
121             $colors['reset']   = $this->colors['reset'];
122             $colors['header']  = $this->colors['header'];
123             $colors['eol']     = $this->colors['eol'];
124         }
125
126         $output .= PHP_EOL . PHP_EOL .
127                    $colors['header'] . 'Code Coverage Report ';
128
129         if ($this->title) {
130             $output .= 'for "' . $this->title . '"';
131         }
132
133         $output .= PHP_EOL .
134                    date('  Y-m-d H:i:s', $_SERVER['REQUEST_TIME']) .
135                    PHP_EOL;
136
137         $output .= PHP_EOL . ' Summary: ' . PHP_EOL . $colors['reset']
138           . $colors['classes'] . $colors['eol'] . '  Classes: ' . PHP_CodeCoverage_Util::percent($report->getNumTestedClasses(), $report->getNumClasses(), TRUE)
139           . ' (' . $report->getNumTestedClasses() . '/' . $report->getNumClasses() . ')' . PHP_EOL . $colors ['eol']
140           . $colors['methods'] . $colors['eol'] . '  Methods: ' . PHP_CodeCoverage_Util::percent($report->getNumTestedMethods(), $report->getNumMethods(), TRUE)
141           . ' (' . $report->getNumTestedMethods() . '/' . $report->getNumMethods() . ')' . PHP_EOL . $colors ['eol']
142           . $colors['lines'] . $colors['eol'] . '  Lines:   ' . PHP_CodeCoverage_Util::percent($report->getNumExecutedLines(), $report->getNumExecutableLines(), TRUE)
143           . ' (' . $report->getNumExecutedLines() . '/' . $report->getNumExecutableLines() . ')' . PHP_EOL . $colors['reset'] . $colors ['eol'];
144
145         $classCoverage = array();
146
147         foreach ($report as $item) {
148             if (!$item instanceof PHP_CodeCoverage_Report_Node_File) {
149                 continue;
150             }
151
152             $classes      = array_merge($item->getClasses(), $item->getTraits());
153             $coverage     = $item->getCoverageData();
154             $lines        = array();
155             $ignoredLines = $item->getIgnoredLines();
156
157             foreach ($classes as $className => $class) {
158                 $classStatements        = 0;
159                 $coveredClassStatements = 0;
160                 $coveredMethods         = 0;
161
162                 foreach ($class['methods'] as $methodName => $method) {
163                     $methodCount        = 0;
164                     $methodLines        = 0;
165                     $methodLinesCovered = 0;
166
167                     for ($i  = $method['startLine'];
168                          $i <= $method['endLine'];
169                          $i++) {
170                         if (isset($ignoredLines[$i])) {
171                             continue;
172                         }
173
174                         $add   = TRUE;
175                         $count = 0;
176
177                         if (isset($coverage[$i])) {
178                             if ($coverage[$i] !== NULL) {
179                                 $classStatements++;
180                                 $methodLines++;
181                             } else {
182                                 $add = FALSE;
183                             }
184
185                             $count = count($coverage[$i]);
186
187                             if ($count > 0) {
188                                 $coveredClassStatements++;
189                                 $methodLinesCovered++;
190                             }
191                         } else {
192                             $add = FALSE;
193                         }
194
195                         $methodCount = max($methodCount, $count);
196
197                         if ($add) {
198                             $lines[$i] = array(
199                               'count' => $count, 'type'  => 'stmt'
200                             );
201                         }
202                     }
203
204                     if ($methodCount > 0) {
205                         $coveredMethods++;
206                     }
207
208                 }
209
210                 if (!empty($class['package']['namespace'])) {
211                     $namespace = '\\' . $class['package']['namespace'] . '::';
212                 }
213
214                 else if (!empty($class['package']['fullPackage'])) {
215                     $namespace = '@' . $class['package']['fullPackage'] . '::';
216                 }
217
218                 else {
219                     $namespace = '';
220                 }
221
222                 $classCoverage[$namespace . $className] = array(
223                     'namespace'         => $namespace,
224                     'className '        => $className,
225                     'methodsCovered'    => $coveredMethods,
226                     'methodCount'       => count($class['methods']),
227                     'statementsCovered' => $coveredClassStatements,
228                     'statementCount'    => $classStatements,
229                 );
230             }
231         }
232
233         ksort($classCoverage);
234
235         $methodColor = '';
236         $linesColor  = '';
237         $resetColor  = '';
238
239         foreach ($classCoverage as $fullQualifiedPath => $classInfo) {
240             if ($classInfo['statementsCovered'] != 0 ||
241                 $this->showUncoveredFiles) {
242
243                 if ($showColors) {
244                     $methodColor = $this->getCoverageColor($classInfo['methodsCovered'], $classInfo['methodCount']);
245                     $linesColor  = $this->getCoverageColor($classInfo['statementsCovered'], $classInfo['statementCount']);
246                     $resetColor  = $colors['reset'];
247                 }
248
249                 $output .= PHP_EOL . $fullQualifiedPath . PHP_EOL
250                   . '  ' . $methodColor . 'Methods: ' . $this->printCoverageCounts($classInfo['methodsCovered'], $classInfo['methodCount'], 2) . $resetColor . ' '
251                   . '  ' . $linesColor  . 'Lines: ' . $this->printCoverageCounts($classInfo['statementsCovered'], $classInfo['statementCount'], 3) . $resetColor
252                 ;
253             }
254         }
255
256         $this->outputStream->write($output);
257     }
258
259     protected function getCoverageColor($numberOfCoveredElements, $totalNumberOfElements)
260     {
261         $coverage = PHP_CodeCoverage_Util::percent(
262           $numberOfCoveredElements, $totalNumberOfElements
263         );
264
265         if ($coverage > $this->highLowerBound) {
266             return $this->colors['green'];
267         }
268
269         else if ($coverage > $this->lowUpperBound) {
270             return $this->colors['yellow'];
271         }
272
273         return $this->colors['red'];
274     }
275
276     protected function printCoverageCounts($numberOfCoveredElements, $totalNumberOfElements, $presicion)
277     {
278         $format = '%' . $presicion . 's';
279
280         return PHP_CodeCoverage_Util::percent(
281           $numberOfCoveredElements, $totalNumberOfElements, TRUE, TRUE
282         ) .
283         ' (' . sprintf($format, $numberOfCoveredElements) . '/' .
284         sprintf($format, $totalNumberOfElements) . ')';
285     }
286 }