Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * PHPUnit
4
 *
5
 * Copyright (c) 2002-2010, 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   Testing
38
 * @package    PHPUnit
39
 * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
40
 * @copyright  2002-2010 Sebastian Bergmann <sb@sebastian-bergmann.de>
41
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
42
 * @link       http://www.phpunit.de/
43
 * @since      File available since Release 3.2.0
44
 */
45
 
46
require_once 'PHPUnit/Framework.php';
47
require_once 'PHPUnit/Util/Filter.php';
48
require_once 'PHPUnit/Util/Filesystem.php';
49
require_once 'PHPUnit/Util/Test.php';
50
 
51
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
52
 
53
/**
54
 * Base class for nodes in the code coverage information tree.
55
 *
56
 * @category   Testing
57
 * @package    PHPUnit
58
 * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
59
 * @copyright  2002-2010 Sebastian Bergmann <sb@sebastian-bergmann.de>
60
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
61
 * @version    Release: 3.4.15
62
 * @link       http://www.phpunit.de/
63
 * @since      Class available since Release 3.2.0
64
 */
65
abstract class PHPUnit_Util_Report_Node
66
{
67
    /**
68
     * @var    array
69
     */
70
    protected $cache = array();
71
 
72
    /**
73
     * @var    string
74
     */
75
    protected $name;
76
 
77
    /**
78
     * @var    PHPUnit_Util_Report_Node
79
     */
80
    protected $parent;
81
 
82
    /**
83
     * Constructor.
84
     *
85
     * @param  string                   $name
86
     * @param  PHPUnit_Util_Report_Node $parent
87
     */
88
    public function __construct($name, PHPUnit_Util_Report_Node $parent = NULL)
89
    {
90
        $this->name   = $name;
91
        $this->parent = $parent;
92
    }
93
 
94
    /**
95
     * Returns the percentage of classes that has been tested.
96
     *
97
     * @return integer
98
     */
99
    public function getTestedClassesPercent()
100
    {
101
        return $this->calculatePercent(
102
          $this->getNumTestedClasses(),
103
          $this->getNumClasses()
104
        );
105
    }
106
 
107
    /**
108
     * Returns the percentage of methods that has been tested.
109
     *
110
     * @return integer
111
     */
112
    public function getTestedMethodsPercent()
113
    {
114
        return $this->calculatePercent(
115
          $this->getNumTestedMethods(),
116
          $this->getNumMethods()
117
        );
118
    }
119
 
120
    /**
121
     * Returns the percentage of executed lines.
122
     *
123
     * @return integer
124
     */
125
    public function getLineExecutedPercent()
126
    {
127
        return $this->calculatePercent(
128
          $this->getNumExecutedLines(),
129
          $this->getNumExecutableLines()
130
        );
131
    }
132
 
133
    /**
134
     * Returns this node's ID.
135
     *
136
     * @return string
137
     */
138
    public function getId()
139
    {
140
        if (!isset($this->cache['id'])) {
141
            if ($this->parent === NULL) {
142
                $this->cache['id'] = 'index';
143
            } else {
144
                $parentId = $this->parent->getId();
145
 
146
                if ($parentId == 'index') {
147
                    $this->cache['id'] = $this->getName();
148
                } else {
149
                    $this->cache['id'] = $parentId . '_' . $this->getName();
150
                }
151
            }
152
        }
153
 
154
        return $this->cache['id'];
155
    }
156
 
157
    /**
158
     * Returns this node's name.
159
     *
160
     * @param  boolean $includeParent
161
     * @return string
162
     */
163
    public function getName($includeParent = FALSE, $includeCommonPath = FALSE)
164
    {
165
        if ($includeParent && $this->parent !== NULL) {
166
            if (!isset($this->cache['nameIncludingParent'])) {
167
                $parent = $this->parent->getName(TRUE);
168
                $this->cache['nameIncludingParent'] = !empty($parent) ? $parent . '/' . $this->name : $this->name;
169
            }
170
 
171
            return $this->cache['nameIncludingParent'];
172
        } else {
173
            if ($this->parent !== NULL) {
174
                return $this->name;
175
            } else {
176
                return $includeCommonPath ? $this->name : '';
177
            }
178
        }
179
    }
180
 
181
    /**
182
     * Returns the link to this node.
183
     *
184
     * @param  boolean $full
185
     * @return string
186
     */
187
    public function getLink($full)
188
    {
189
        if (substr($this->name, -1) == DIRECTORY_SEPARATOR) {
190
            $name = substr($this->name, 0, -1);
191
        } else {
192
            $name = $this->name;
193
        }
194
 
195
        $cleanId = PHPUnit_Util_Filesystem::getSafeFilename($this->getId());
196
 
197
        if ($full) {
198
            if ($this->parent !== NULL) {
199
                $parent = $this->parent->getLink(TRUE) . DIRECTORY_SEPARATOR;
200
            } else {
201
                $parent = '';
202
            }
203
 
204
            return sprintf(
205
              '%s<a href="%s.html">%s</a>',
206
              $parent,
207
              $cleanId,
208
              $name
209
            );
210
        } else {
211
            return sprintf(
212
              '<a href="%s.html">%s</a>',
213
              $cleanId,
214
              $name
215
            );
216
        }
217
    }
218
 
219
    /**
220
     * Returns this node's path.
221
     *
222
     * @return string
223
     */
224
    public function getPath()
225
    {
226
        if (!isset($this->cache['path'])) {
227
            if ($this->parent === NULL) {
228
                $this->cache['path'] = $this->getName(FALSE, TRUE);
229
            } else {
230
                if (substr($this->parent->getPath(), -1) == DIRECTORY_SEPARATOR) {
231
                    $this->cache['path'] = $this->parent->getPath() .
232
                                           $this->getName(FALSE, TRUE);
233
                } else {
234
                    $this->cache['path'] = $this->parent->getPath() .
235
                                           DIRECTORY_SEPARATOR .
236
                                           $this->getName(FALSE, TRUE);
237
 
238
                    if ($this->parent->getPath() === '' &&
239
                        realpath($this->cache['path']) === FALSE &&
240
                        realpath($this->getName(FALSE, TRUE)) !== FALSE) {
241
                        $this->cache['path'] = $this->getName(FALSE, TRUE);
242
                    }
243
                }
244
            }
245
        }
246
 
247
        return $this->cache['path'];
248
    }
249
 
250
    /**
251
     * Calculates a percentage value.
252
     *
253
     * @param  integer $a
254
     * @param  integer $b
255
     * @return float   ($a / $b) * 100
256
     */
257
    protected function calculatePercent($a, $b)
258
    {
259
        if ($b > 0) {
260
            $percent = ($a / $b) * 100;
261
        } else {
262
            $percent = 100;
263
        }
264
 
265
        return sprintf(
266
          '%01.2F',
267
          $percent
268
        );
269
    }
270
 
271
    protected function doRenderItemObject(PHPUnit_Util_Report_Node $item, $lowUpperBound, $highLowerBound, $link = NULL, $itemClass = 'coverItem')
272
    {
273
        return $this->doRenderItem(
274
          array(
275
            'name'                 => $link != NULL ? $link : $item->getLink(FALSE),
276
            'itemClass'            => $itemClass,
277
            'numClasses'           => $item->getNumClasses(),
278
            'numTestedClasses'     => $item->getNumTestedClasses(),
279
            'testedClassesPercent' => $item->getTestedClassesPercent(),
280
            'numMethods'           => $item->getNumMethods(),
281
            'numTestedMethods'     => $item->getNumTestedMethods(),
282
            'testedMethodsPercent' => $item->getTestedMethodsPercent(),
283
            'numExecutableLines'   => $item->getNumExecutableLines(),
284
            'numExecutedLines'     => $item->getNumExecutedLines(),
285
            'executedLinesPercent' => $item->getLineExecutedPercent()
286
          ),
287
          $lowUpperBound,
288
          $highLowerBound
289
        );
290
    }
291
 
292
    protected function doRenderItem(array $data, $lowUpperBound, $highLowerBound, $template = NULL)
293
    {
294
        if ($template === NULL) {
295
            if ($this instanceof PHPUnit_Util_Report_Node_Directory) {
296
                $template = 'directory_item.html';
297
            } else {
298
                $template = 'file_item.html';
299
            }
300
        }
301
 
302
        $itemTemplate = new PHPUnit_Util_Template(
303
          PHPUnit_Util_Report::$templatePath . $template
304
        );
305
 
306
        if ($data['numClasses'] > 0) {
307
            list($classesColor, $classesLevel) = $this->getColorLevel(
308
              $data['testedClassesPercent'], $lowUpperBound, $highLowerBound
309
            );
310
 
311
            $classesNumber = $data['numTestedClasses'] . ' / ' . $data['numClasses'];
312
        } else {
313
            $classesColor  = 'snow';
314
            $classesLevel  = 'None';
315
            $classesNumber = '&nbsp;';
316
        }
317
 
318
        if ($data['numMethods'] > 0) {
319
            list($methodsColor, $methodsLevel) = $this->getColorLevel(
320
              $data['testedMethodsPercent'], $lowUpperBound, $highLowerBound
321
            );
322
 
323
            $methodsNumber = $data['numTestedMethods'] . ' / ' . $data['numMethods'];
324
        } else {
325
            $methodsColor  = 'snow';
326
            $methodsLevel  = 'None';
327
            $methodsNumber = '&nbsp;';
328
        }
329
 
330
        list($linesColor, $linesLevel) = $this->getColorLevel(
331
          $data['executedLinesPercent'], $lowUpperBound, $highLowerBound
332
        );
333
 
334
        if ($data['name'] == '<b><a href="#0">*</a></b>') {
335
            $functions = TRUE;
336
        } else {
337
            $functions = FALSE;
338
        }
339
 
340
        $itemTemplate->setVar(
341
          array(
342
            'name'                     => $functions ? 'Functions' : $data['name'],
343
            'itemClass'                => isset($data['itemClass']) ? $data['itemClass'] : 'coverItem',
344
            'classes_color'            => $classesColor,
345
            'classes_level'            => $functions ? 'None' : $classesLevel,
346
            'classes_tested_width'     => floor($data['testedClassesPercent']),
347
            'classes_tested_percent'   => !$functions && $data['numClasses'] > 0 ? $data['testedClassesPercent'] . '%' : '&nbsp;',
348
            'classes_not_tested_width' => 100 - floor($data['testedClassesPercent']),
349
            'classes_number'           => $functions ? '&nbsp;' : $classesNumber,
350
            'methods_color'            => $methodsColor,
351
            'methods_level'            => $methodsLevel,
352
            'methods_tested_width'     => floor($data['testedMethodsPercent']),
353
            'methods_tested_percent'   => $data['numMethods'] > 0 ? $data['testedMethodsPercent'] . '%' : '&nbsp;',
354
            'methods_not_tested_width' => 100 - floor($data['testedMethodsPercent']),
355
            'methods_number'           => $methodsNumber,
356
            'lines_color'              => $linesColor,
357
            'lines_level'              => $linesLevel,
358
            'lines_executed_width'     => floor($data['executedLinesPercent']),
359
            'lines_executed_percent'   => $data['executedLinesPercent'] . '%',
360
            'lines_not_executed_width' => 100 - floor($data['executedLinesPercent']),
361
            'num_executable_lines'     => $data['numExecutableLines'],
362
            'num_executed_lines'       => $data['numExecutedLines']
363
          )
364
        );
365
 
366
        return $itemTemplate->render();
367
    }
368
 
369
    protected function getColorLevel($percent, $lowUpperBound, $highLowerBound)
370
    {
371
        $floorPercent = floor($percent);
372
 
373
        if ($floorPercent < $lowUpperBound) {
374
            $color = 'scarlet_red';
375
            $level = 'Lo';
376
        }
377
 
378
        else if ($floorPercent >= $lowUpperBound &&
379
                 $floorPercent <  $highLowerBound) {
380
            $color = 'butter';
381
            $level = 'Med';
382
        }
383
 
384
        else {
385
            $color = 'chameleon';
386
            $level = 'Hi';
387
        }
388
 
389
        return array($color, $level);
390
    }
391
 
392
    protected function renderTotalItem($lowUpperBound, $highLowerBound, $directory = TRUE)
393
    {
394
        if ($directory && empty($this->directories) && count($this->files) == 1) {
395
            return '';
396
        }
397
 
398
        return $this->doRenderItemObject($this, $lowUpperBound, $highLowerBound, 'Total') .
399
               "        <tr>\n" .
400
               '          <td class="tableHead" colspan="10">&nbsp;</td>' . "\n" .
401
               "        </tr>\n";
402
    }
403
 
404
    /**
405
     * @param  PHPUnit_Util_Template $template
406
     * @param  string                $title
407
     * @param  string                $charset
408
     */
409
    protected function setTemplateVars(PHPUnit_Util_Template $template, $title, $charset)
410
    {
411
        $template->setVar(
412
          array(
413
            'title'                  => $title,
414
            'charset'                => $charset,
415
            'link'                   => $this->getLink(TRUE),
416
            'num_executable_lines'   => $this->getNumExecutableLines(),
417
            'num_executed_lines'     => $this->getNumExecutedLines(),
418
            'lines_executed_percent' => $this->getLineExecutedPercent(),
419
            'date'                   => $template->getDate(),
420
            'phpunit_version'        => PHPUnit_Runner_Version::id(),
421
            'xdebug_version'         => phpversion('xdebug'),
422
            'php_version'            => PHP_VERSION
423
          )
424
        );
425
    }
426
 
427
    /**
428
     * Returns the classes of this node.
429
     *
430
     * @return array
431
     */
432
    abstract public function getClasses();
433
 
434
    /**
435
     * Returns the number of executable lines.
436
     *
437
     * @return integer
438
     */
439
    abstract public function getNumExecutableLines();
440
 
441
    /**
442
     * Returns the number of executed lines.
443
     *
444
     * @return integer
445
     */
446
    abstract public function getNumExecutedLines();
447
 
448
    /**
449
     * Returns the number of classes.
450
     *
451
     * @return integer
452
     */
453
    abstract public function getNumClasses();
454
 
455
    /**
456
     * Returns the number of tested classes.
457
     *
458
     * @return integer
459
     */
460
    abstract public function getNumTestedClasses();
461
 
462
    /**
463
     * Returns the number of methods.
464
     *
465
     * @return integer
466
     */
467
    abstract public function getNumMethods();
468
 
469
    /**
470
     * Returns the number of tested methods.
471
     *
472
     * @return integer
473
     */
474
    abstract public function getNumTestedMethods();
475
 
476
    /**
477
     * Renders this node.
478
     *
479
     * @param string  $target
480
     * @param string  $title
481
     * @param string  $charset
482
     * @param integer $lowUpperBound
483
     * @param integer $highLowerBound
484
     */
485
    abstract public function render($target, $title, $charset = 'ISO-8859-1', $lowUpperBound = 35, $highLowerBound = 70);
486
}
487
?>