~canonical-sysadmins/wordpress/openstack-objectstorage-k8s

« back to all changes in this revision

Viewing changes to vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/File.php

  • Committer: Jacek Nykis
  • Date: 2015-02-11 15:35:31 UTC
  • Revision ID: jacek.nykis@canonical.com-20150211153531-hmy6zi0ov2qfkl0b
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/*
 
3
 * This file is part of the PHP_CodeCoverage package.
 
4
 *
 
5
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 
6
 *
 
7
 * For the full copyright and license information, please view the LICENSE
 
8
 * file that was distributed with this source code.
 
9
 */
 
10
 
 
11
/**
 
12
 * Represents a file in the code coverage information tree.
 
13
 *
 
14
 * @category   PHP
 
15
 * @package    CodeCoverage
 
16
 * @author     Sebastian Bergmann <sebastian@phpunit.de>
 
17
 * @copyright  Sebastian Bergmann <sebastian@phpunit.de>
 
18
 * @license    http://www.opensource.org/licenses/BSD-3-Clause  The BSD 3-Clause License
 
19
 * @link       http://github.com/sebastianbergmann/php-code-coverage
 
20
 * @since      Class available since Release 1.1.0
 
21
 */
 
22
class PHP_CodeCoverage_Report_Node_File extends PHP_CodeCoverage_Report_Node
 
23
{
 
24
    /**
 
25
     * @var array
 
26
     */
 
27
    protected $coverageData;
 
28
 
 
29
    /**
 
30
     * @var array
 
31
     */
 
32
    protected $testData;
 
33
 
 
34
    /**
 
35
     * @var integer
 
36
     */
 
37
    protected $numExecutableLines = 0;
 
38
 
 
39
    /**
 
40
     * @var integer
 
41
     */
 
42
    protected $numExecutedLines = 0;
 
43
 
 
44
    /**
 
45
     * @var array
 
46
     */
 
47
    protected $classes = array();
 
48
 
 
49
    /**
 
50
     * @var array
 
51
     */
 
52
    protected $traits = array();
 
53
 
 
54
    /**
 
55
     * @var array
 
56
     */
 
57
    protected $functions = array();
 
58
 
 
59
    /**
 
60
     * @var array
 
61
     */
 
62
    protected $linesOfCode = array();
 
63
 
 
64
    /**
 
65
     * @var integer
 
66
     */
 
67
    protected $numTestedTraits = 0;
 
68
 
 
69
    /**
 
70
     * @var integer
 
71
     */
 
72
    protected $numTestedClasses = 0;
 
73
 
 
74
    /**
 
75
     * @var integer
 
76
     */
 
77
    protected $numMethods = null;
 
78
 
 
79
    /**
 
80
     * @var integer
 
81
     */
 
82
    protected $numTestedMethods = null;
 
83
 
 
84
    /**
 
85
     * @var integer
 
86
     */
 
87
    protected $numTestedFunctions = null;
 
88
 
 
89
    /**
 
90
     * @var array
 
91
     */
 
92
    protected $startLines = array();
 
93
 
 
94
    /**
 
95
     * @var array
 
96
     */
 
97
    protected $endLines = array();
 
98
 
 
99
    /**
 
100
     * @var boolean
 
101
     */
 
102
    protected $cacheTokens;
 
103
 
 
104
    /**
 
105
     * Constructor.
 
106
     *
 
107
     * @param  string                       $name
 
108
     * @param  PHP_CodeCoverage_Report_Node $parent
 
109
     * @param  array                        $coverageData
 
110
     * @param  array                        $testData
 
111
     * @param  boolean                      $cacheTokens
 
112
     * @throws PHP_CodeCoverage_Exception
 
113
     */
 
114
    public function __construct($name, PHP_CodeCoverage_Report_Node $parent, array $coverageData, array $testData, $cacheTokens)
 
115
    {
 
116
        if (!is_bool($cacheTokens)) {
 
117
            throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
 
118
                1, 'boolean'
 
119
            );
 
120
        }
 
121
 
 
122
        parent::__construct($name, $parent);
 
123
 
 
124
        $this->coverageData = $coverageData;
 
125
        $this->testData     = $testData;
 
126
        $this->cacheTokens  = $cacheTokens;
 
127
 
 
128
        $this->calculateStatistics();
 
129
    }
 
130
 
 
131
    /**
 
132
     * Returns the number of files in/under this node.
 
133
     *
 
134
     * @return integer
 
135
     */
 
136
    public function count()
 
137
    {
 
138
        return 1;
 
139
    }
 
140
 
 
141
    /**
 
142
     * Returns the code coverage data of this node.
 
143
     *
 
144
     * @return array
 
145
     */
 
146
    public function getCoverageData()
 
147
    {
 
148
        return $this->coverageData;
 
149
    }
 
150
 
 
151
    /**
 
152
     * Returns the test data of this node.
 
153
     *
 
154
     * @return array
 
155
     */
 
156
    public function getTestData()
 
157
    {
 
158
        return $this->testData;
 
159
    }
 
160
 
 
161
    /**
 
162
     * Returns the classes of this node.
 
163
     *
 
164
     * @return array
 
165
     */
 
166
    public function getClasses()
 
167
    {
 
168
        return $this->classes;
 
169
    }
 
170
 
 
171
    /**
 
172
     * Returns the traits of this node.
 
173
     *
 
174
     * @return array
 
175
     */
 
176
    public function getTraits()
 
177
    {
 
178
        return $this->traits;
 
179
    }
 
180
 
 
181
    /**
 
182
     * Returns the functions of this node.
 
183
     *
 
184
     * @return array
 
185
     */
 
186
    public function getFunctions()
 
187
    {
 
188
        return $this->functions;
 
189
    }
 
190
 
 
191
    /**
 
192
     * Returns the LOC/CLOC/NCLOC of this node.
 
193
     *
 
194
     * @return array
 
195
     */
 
196
    public function getLinesOfCode()
 
197
    {
 
198
        return $this->linesOfCode;
 
199
    }
 
200
 
 
201
    /**
 
202
     * Returns the number of executable lines.
 
203
     *
 
204
     * @return integer
 
205
     */
 
206
    public function getNumExecutableLines()
 
207
    {
 
208
        return $this->numExecutableLines;
 
209
    }
 
210
 
 
211
    /**
 
212
     * Returns the number of executed lines.
 
213
     *
 
214
     * @return integer
 
215
     */
 
216
    public function getNumExecutedLines()
 
217
    {
 
218
        return $this->numExecutedLines;
 
219
    }
 
220
 
 
221
    /**
 
222
     * Returns the number of classes.
 
223
     *
 
224
     * @return integer
 
225
     */
 
226
    public function getNumClasses()
 
227
    {
 
228
        return count($this->classes);
 
229
    }
 
230
 
 
231
    /**
 
232
     * Returns the number of tested classes.
 
233
     *
 
234
     * @return integer
 
235
     */
 
236
    public function getNumTestedClasses()
 
237
    {
 
238
        return $this->numTestedClasses;
 
239
    }
 
240
 
 
241
    /**
 
242
     * Returns the number of traits.
 
243
     *
 
244
     * @return integer
 
245
     */
 
246
    public function getNumTraits()
 
247
    {
 
248
        return count($this->traits);
 
249
    }
 
250
 
 
251
    /**
 
252
     * Returns the number of tested traits.
 
253
     *
 
254
     * @return integer
 
255
     */
 
256
    public function getNumTestedTraits()
 
257
    {
 
258
        return $this->numTestedTraits;
 
259
    }
 
260
 
 
261
    /**
 
262
     * Returns the number of methods.
 
263
     *
 
264
     * @return integer
 
265
     */
 
266
    public function getNumMethods()
 
267
    {
 
268
        if ($this->numMethods === null) {
 
269
            $this->numMethods = 0;
 
270
 
 
271
            foreach ($this->classes as $class) {
 
272
                foreach ($class['methods'] as $method) {
 
273
                    if ($method['executableLines'] > 0) {
 
274
                        $this->numMethods++;
 
275
                    }
 
276
                }
 
277
            }
 
278
 
 
279
            foreach ($this->traits as $trait) {
 
280
                foreach ($trait['methods'] as $method) {
 
281
                    if ($method['executableLines'] > 0) {
 
282
                        $this->numMethods++;
 
283
                    }
 
284
                }
 
285
            }
 
286
        }
 
287
 
 
288
        return $this->numMethods;
 
289
    }
 
290
 
 
291
    /**
 
292
     * Returns the number of tested methods.
 
293
     *
 
294
     * @return integer
 
295
     */
 
296
    public function getNumTestedMethods()
 
297
    {
 
298
        if ($this->numTestedMethods === null) {
 
299
            $this->numTestedMethods = 0;
 
300
 
 
301
            foreach ($this->classes as $class) {
 
302
                foreach ($class['methods'] as $method) {
 
303
                    if ($method['executableLines'] > 0 &&
 
304
                        $method['coverage'] == 100) {
 
305
                        $this->numTestedMethods++;
 
306
                    }
 
307
                }
 
308
            }
 
309
 
 
310
            foreach ($this->traits as $trait) {
 
311
                foreach ($trait['methods'] as $method) {
 
312
                    if ($method['executableLines'] > 0 &&
 
313
                        $method['coverage'] == 100) {
 
314
                        $this->numTestedMethods++;
 
315
                    }
 
316
                }
 
317
            }
 
318
        }
 
319
 
 
320
        return $this->numTestedMethods;
 
321
    }
 
322
 
 
323
    /**
 
324
     * Returns the number of functions.
 
325
     *
 
326
     * @return integer
 
327
     */
 
328
    public function getNumFunctions()
 
329
    {
 
330
        return count($this->functions);
 
331
    }
 
332
 
 
333
    /**
 
334
     * Returns the number of tested functions.
 
335
     *
 
336
     * @return integer
 
337
     */
 
338
    public function getNumTestedFunctions()
 
339
    {
 
340
        if ($this->numTestedFunctions === null) {
 
341
            $this->numTestedFunctions = 0;
 
342
 
 
343
            foreach ($this->functions as $function) {
 
344
                if ($function['executableLines'] > 0 &&
 
345
                    $function['coverage'] == 100) {
 
346
                    $this->numTestedFunctions++;
 
347
                }
 
348
            }
 
349
        }
 
350
 
 
351
        return $this->numTestedFunctions;
 
352
    }
 
353
 
 
354
    /**
 
355
     * Calculates coverage statistics for the file.
 
356
     */
 
357
    protected function calculateStatistics()
 
358
    {
 
359
        if ($this->cacheTokens) {
 
360
            $tokens = PHP_Token_Stream_CachingFactory::get($this->getPath());
 
361
        } else {
 
362
            $tokens = new PHP_Token_Stream($this->getPath());
 
363
        }
 
364
 
 
365
        $this->processClasses($tokens);
 
366
        $this->processTraits($tokens);
 
367
        $this->processFunctions($tokens);
 
368
        $this->linesOfCode = $tokens->getLinesOfCode();
 
369
        unset($tokens);
 
370
 
 
371
        for ($lineNumber = 1; $lineNumber <= $this->linesOfCode['loc']; $lineNumber++) {
 
372
            if (isset($this->startLines[$lineNumber])) {
 
373
                // Start line of a class.
 
374
                if (isset($this->startLines[$lineNumber]['className'])) {
 
375
                    $currentClass = &$this->startLines[$lineNumber];
 
376
                }
 
377
 
 
378
                // Start line of a trait.
 
379
                elseif (isset($this->startLines[$lineNumber]['traitName'])) {
 
380
                    $currentTrait = &$this->startLines[$lineNumber];
 
381
                }
 
382
 
 
383
                // Start line of a method.
 
384
                elseif (isset($this->startLines[$lineNumber]['methodName'])) {
 
385
                    $currentMethod = &$this->startLines[$lineNumber];
 
386
                }
 
387
 
 
388
                // Start line of a function.
 
389
                elseif (isset($this->startLines[$lineNumber]['functionName'])) {
 
390
                    $currentFunction = &$this->startLines[$lineNumber];
 
391
                }
 
392
            }
 
393
 
 
394
            if (isset($this->coverageData[$lineNumber]) &&
 
395
                $this->coverageData[$lineNumber] !== null) {
 
396
                if (isset($currentClass)) {
 
397
                    $currentClass['executableLines']++;
 
398
                }
 
399
 
 
400
                if (isset($currentTrait)) {
 
401
                    $currentTrait['executableLines']++;
 
402
                }
 
403
 
 
404
                if (isset($currentMethod)) {
 
405
                    $currentMethod['executableLines']++;
 
406
                }
 
407
 
 
408
                if (isset($currentFunction)) {
 
409
                    $currentFunction['executableLines']++;
 
410
                }
 
411
 
 
412
                $this->numExecutableLines++;
 
413
 
 
414
                if (count($this->coverageData[$lineNumber]) > 0) {
 
415
                    if (isset($currentClass)) {
 
416
                        $currentClass['executedLines']++;
 
417
                    }
 
418
 
 
419
                    if (isset($currentTrait)) {
 
420
                        $currentTrait['executedLines']++;
 
421
                    }
 
422
 
 
423
                    if (isset($currentMethod)) {
 
424
                        $currentMethod['executedLines']++;
 
425
                    }
 
426
 
 
427
                    if (isset($currentFunction)) {
 
428
                        $currentFunction['executedLines']++;
 
429
                    }
 
430
 
 
431
                    $this->numExecutedLines++;
 
432
                }
 
433
            }
 
434
 
 
435
            if (isset($this->endLines[$lineNumber])) {
 
436
                // End line of a class.
 
437
                if (isset($this->endLines[$lineNumber]['className'])) {
 
438
                    unset($currentClass);
 
439
                }
 
440
 
 
441
                // End line of a trait.
 
442
                elseif (isset($this->endLines[$lineNumber]['traitName'])) {
 
443
                    unset($currentTrait);
 
444
                }
 
445
 
 
446
                // End line of a method.
 
447
                elseif (isset($this->endLines[$lineNumber]['methodName'])) {
 
448
                    unset($currentMethod);
 
449
                }
 
450
 
 
451
                // End line of a function.
 
452
                elseif (isset($this->endLines[$lineNumber]['functionName'])) {
 
453
                    unset($currentFunction);
 
454
                }
 
455
            }
 
456
        }
 
457
 
 
458
        foreach ($this->traits as &$trait) {
 
459
            foreach ($trait['methods'] as &$method) {
 
460
                if ($method['executableLines'] > 0) {
 
461
                    $method['coverage'] = ($method['executedLines'] /
 
462
                            $method['executableLines']) * 100;
 
463
                } else {
 
464
                    $method['coverage'] = 100;
 
465
                }
 
466
 
 
467
                $method['crap'] = $this->crap(
 
468
                    $method['ccn'], $method['coverage']
 
469
                );
 
470
 
 
471
                $trait['ccn'] += $method['ccn'];
 
472
            }
 
473
 
 
474
            if ($trait['executableLines'] > 0) {
 
475
                $trait['coverage'] = ($trait['executedLines'] /
 
476
                        $trait['executableLines']) * 100;
 
477
            } else {
 
478
                $trait['coverage'] = 100;
 
479
            }
 
480
 
 
481
            if ($trait['coverage'] == 100) {
 
482
                $this->numTestedClasses++;
 
483
            }
 
484
 
 
485
            $trait['crap'] = $this->crap(
 
486
                $trait['ccn'], $trait['coverage']
 
487
            );
 
488
        }
 
489
 
 
490
        foreach ($this->classes as &$class) {
 
491
            foreach ($class['methods'] as &$method) {
 
492
                if ($method['executableLines'] > 0) {
 
493
                    $method['coverage'] = ($method['executedLines'] /
 
494
                            $method['executableLines']) * 100;
 
495
                } else {
 
496
                    $method['coverage'] = 100;
 
497
                }
 
498
 
 
499
                $method['crap'] = $this->crap(
 
500
                    $method['ccn'], $method['coverage']
 
501
                );
 
502
 
 
503
                $class['ccn'] += $method['ccn'];
 
504
            }
 
505
 
 
506
            if ($class['executableLines'] > 0) {
 
507
                $class['coverage'] = ($class['executedLines'] /
 
508
                        $class['executableLines']) * 100;
 
509
            } else {
 
510
                $class['coverage'] = 100;
 
511
            }
 
512
 
 
513
            if ($class['coverage'] == 100) {
 
514
                $this->numTestedClasses++;
 
515
            }
 
516
 
 
517
            $class['crap'] = $this->crap(
 
518
                $class['ccn'], $class['coverage']
 
519
            );
 
520
        }
 
521
    }
 
522
 
 
523
    /**
 
524
     * @param PHP_Token_Stream $tokens
 
525
     */
 
526
    protected function processClasses(PHP_Token_Stream $tokens)
 
527
    {
 
528
        $classes = $tokens->getClasses();
 
529
        unset($tokens);
 
530
 
 
531
        $link = $this->getId() . '.html#';
 
532
 
 
533
        foreach ($classes as $className => $class) {
 
534
            $this->classes[$className] = array(
 
535
                'className'       => $className,
 
536
                'methods'         => array(),
 
537
                'startLine'       => $class['startLine'],
 
538
                'executableLines' => 0,
 
539
                'executedLines'   => 0,
 
540
                'ccn'             => 0,
 
541
                'coverage'        => 0,
 
542
                'crap'            => 0,
 
543
                'package'         => $class['package'],
 
544
                'link'            => $link . $class['startLine']
 
545
            );
 
546
 
 
547
            $this->startLines[$class['startLine']] = &$this->classes[$className];
 
548
            $this->endLines[$class['endLine']]     = &$this->classes[$className];
 
549
 
 
550
            foreach ($class['methods'] as $methodName => $method) {
 
551
                $this->classes[$className]['methods'][$methodName] = array(
 
552
                    'methodName'      => $methodName,
 
553
                    'signature'       => $method['signature'],
 
554
                    'startLine'       => $method['startLine'],
 
555
                    'endLine'         => $method['endLine'],
 
556
                    'executableLines' => 0,
 
557
                    'executedLines'   => 0,
 
558
                    'ccn'             => $method['ccn'],
 
559
                    'coverage'        => 0,
 
560
                    'crap'            => 0,
 
561
                    'link'            => $link . $method['startLine']
 
562
                );
 
563
 
 
564
                $this->startLines[$method['startLine']] = &$this->classes[$className]['methods'][$methodName];
 
565
                $this->endLines[$method['endLine']]     = &$this->classes[$className]['methods'][$methodName];
 
566
            }
 
567
        }
 
568
    }
 
569
 
 
570
    /**
 
571
     * @param PHP_Token_Stream $tokens
 
572
     */
 
573
    protected function processTraits(PHP_Token_Stream $tokens)
 
574
    {
 
575
        $traits = $tokens->getTraits();
 
576
        unset($tokens);
 
577
 
 
578
        $link = $this->getId() . '.html#';
 
579
 
 
580
        foreach ($traits as $traitName => $trait) {
 
581
            $this->traits[$traitName] = array(
 
582
                'traitName'       => $traitName,
 
583
                'methods'         => array(),
 
584
                'startLine'       => $trait['startLine'],
 
585
                'executableLines' => 0,
 
586
                'executedLines'   => 0,
 
587
                'ccn'             => 0,
 
588
                'coverage'        => 0,
 
589
                'crap'            => 0,
 
590
                'package'         => $trait['package'],
 
591
                'link'            => $link . $trait['startLine']
 
592
            );
 
593
 
 
594
            $this->startLines[$trait['startLine']] = &$this->traits[$traitName];
 
595
            $this->endLines[$trait['endLine']]     = &$this->traits[$traitName];
 
596
 
 
597
            foreach ($trait['methods'] as $methodName => $method) {
 
598
                $this->traits[$traitName]['methods'][$methodName] = array(
 
599
                    'methodName'      => $methodName,
 
600
                    'signature'       => $method['signature'],
 
601
                    'startLine'       => $method['startLine'],
 
602
                    'endLine'         => $method['endLine'],
 
603
                    'executableLines' => 0,
 
604
                    'executedLines'   => 0,
 
605
                    'ccn'             => $method['ccn'],
 
606
                    'coverage'        => 0,
 
607
                    'crap'            => 0,
 
608
                    'link'            => $link . $method['startLine']
 
609
                );
 
610
 
 
611
                $this->startLines[$method['startLine']] = &$this->traits[$traitName]['methods'][$methodName];
 
612
                $this->endLines[$method['endLine']]     = &$this->traits[$traitName]['methods'][$methodName];
 
613
            }
 
614
        }
 
615
    }
 
616
 
 
617
    /**
 
618
     * @param PHP_Token_Stream $tokens
 
619
     */
 
620
    protected function processFunctions(PHP_Token_Stream $tokens)
 
621
    {
 
622
        $functions = $tokens->getFunctions();
 
623
        unset($tokens);
 
624
 
 
625
        $link = $this->getId() . '.html#';
 
626
 
 
627
        foreach ($functions as $functionName => $function) {
 
628
            $this->functions[$functionName] = array(
 
629
                'functionName'    => $functionName,
 
630
                'signature'       => $function['signature'],
 
631
                'startLine'       => $function['startLine'],
 
632
                'executableLines' => 0,
 
633
                'executedLines'   => 0,
 
634
                'ccn'             => $function['ccn'],
 
635
                'coverage'        => 0,
 
636
                'crap'            => 0,
 
637
                'link'            => $link . $function['startLine']
 
638
            );
 
639
 
 
640
            $this->startLines[$function['startLine']] = &$this->functions[$functionName];
 
641
            $this->endLines[$function['endLine']]     = &$this->functions[$functionName];
 
642
        }
 
643
    }
 
644
 
 
645
    /**
 
646
     * Calculates the Change Risk Anti-Patterns (CRAP) index for a unit of code
 
647
     * based on its cyclomatic complexity and percentage of code coverage.
 
648
     *
 
649
     * @param  integer $ccn
 
650
     * @param  float   $coverage
 
651
     * @return string
 
652
     * @since  Method available since Release 1.2.0
 
653
     */
 
654
    protected function crap($ccn, $coverage)
 
655
    {
 
656
        if ($coverage == 0) {
 
657
            return (string) pow($ccn, 2) + $ccn;
 
658
        }
 
659
 
 
660
        if ($coverage >= 95) {
 
661
            return (string) $ccn;
 
662
        }
 
663
 
 
664
        return sprintf(
 
665
            '%01.2F', pow($ccn, 2) * pow(1 - $coverage/100, 3) + $ccn
 
666
        );
 
667
    }
 
668
}