gluon-web-remote

Web remote Administration for big size of gluon routers
git clone git://archive.git.mtrnord.blog/MTRNord/gluon-web-remote.git
Log | Files | Refs | README

CodeCoverage.php (22826B)


      1 <?php
      2 /**
      3  * PHP_CodeCoverage
      4  *
      5  * Copyright (c) 2009-2014, Sebastian Bergmann <sebastian@phpunit.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 <sebastian@phpunit.de>
     40  * @copyright  2009-2014 Sebastian Bergmann <sebastian@phpunit.de>
     41  * @license    http://www.opensource.org/licenses/BSD-3-Clause  The BSD 3-Clause License
     42  * @link       http://github.com/sebastianbergmann/php-code-coverage
     43  * @since      File available since Release 1.0.0
     44  */
     45 
     46 // @codeCoverageIgnoreStart
     47 // @codingStandardsIgnoreStart
     48 /**
     49  * @SuppressWarnings(PHPMD)
     50  */
     51 if (!function_exists('trait_exists')) {
     52     function trait_exists($name)
     53     {
     54         return FALSE;
     55     }
     56 }
     57 // @codingStandardsIgnoreEnd
     58 // @codeCoverageIgnoreEnd
     59 
     60 /**
     61  * Provides collection functionality for PHP code coverage information.
     62  *
     63  * @category   PHP
     64  * @package    CodeCoverage
     65  * @author     Sebastian Bergmann <sebastian@phpunit.de>
     66  * @copyright  2009-2014 Sebastian Bergmann <sebastian@phpunit.de>
     67  * @license    http://www.opensource.org/licenses/BSD-3-Clause  The BSD 3-Clause License
     68  * @link       http://github.com/sebastianbergmann/php-code-coverage
     69  * @since      Class available since Release 1.0.0
     70  */
     71 class PHP_CodeCoverage
     72 {
     73     /**
     74      * @var PHP_CodeCoverage_Driver
     75      */
     76     protected $driver;
     77 
     78     /**
     79      * @var PHP_CodeCoverage_Filter
     80      */
     81     protected $filter;
     82 
     83     /**
     84      * @var boolean
     85      */
     86     protected $cacheTokens = FALSE;
     87 
     88     /**
     89      * @var boolean
     90      */
     91     protected $forceCoversAnnotation = FALSE;
     92 
     93     /**
     94      * @var boolean
     95      */
     96     protected $mapTestClassNameToCoveredClassName = FALSE;
     97 
     98     /**
     99      * @var boolean
    100      */
    101     protected $addUncoveredFilesFromWhitelist = TRUE;
    102 
    103     /**
    104      * @var boolean
    105      */
    106     protected $processUncoveredFilesFromWhitelist = FALSE;
    107 
    108     /**
    109      * @var mixed
    110      */
    111     protected $currentId;
    112 
    113     /**
    114      * Code coverage data.
    115      *
    116      * @var array
    117      */
    118     protected $data = array();
    119 
    120     /**
    121      * Test data.
    122      *
    123      * @var array
    124      */
    125     protected $tests = array();
    126 
    127     /**
    128      * Constructor.
    129      *
    130      * @param PHP_CodeCoverage_Driver $driver
    131      * @param PHP_CodeCoverage_Filter $filter
    132      */
    133     public function __construct(PHP_CodeCoverage_Driver $driver = NULL, PHP_CodeCoverage_Filter $filter = NULL)
    134     {
    135         if ($driver === NULL) {
    136             $driver = new PHP_CodeCoverage_Driver_Xdebug;
    137         }
    138 
    139         if ($filter === NULL) {
    140             $filter = new PHP_CodeCoverage_Filter;
    141         }
    142 
    143         $this->driver = $driver;
    144         $this->filter = $filter;
    145     }
    146 
    147     /**
    148      * Returns the PHP_CodeCoverage_Report_Node_* object graph
    149      * for this PHP_CodeCoverage object.
    150      *
    151      * @return PHP_CodeCoverage_Report_Node_Directory
    152      * @since  Method available since Release 1.1.0
    153      */
    154     public function getReport()
    155     {
    156         $factory = new PHP_CodeCoverage_Report_Factory;
    157 
    158         return $factory->create($this);
    159     }
    160 
    161     /**
    162      * Clears collected code coverage data.
    163      */
    164     public function clear()
    165     {
    166         $this->currentId = NULL;
    167         $this->data      = array();
    168         $this->tests     = array();
    169     }
    170 
    171     /**
    172      * Returns the PHP_CodeCoverage_Filter used.
    173      *
    174      * @return PHP_CodeCoverage_Filter
    175      */
    176     public function filter()
    177     {
    178         return $this->filter;
    179     }
    180 
    181     /**
    182      * Returns the collected code coverage data.
    183      *
    184      * @return array
    185      * @since  Method available since Release 1.1.0
    186      */
    187     public function getData()
    188     {
    189         if ($this->addUncoveredFilesFromWhitelist) {
    190             $this->addUncoveredFilesFromWhitelist();
    191         }
    192 
    193         // We need to apply the blacklist filter a second time
    194         // when no whitelist is used.
    195         if (!$this->filter->hasWhitelist()) {
    196             $this->applyListsFilter($this->data);
    197         }
    198 
    199         return $this->data;
    200     }
    201 
    202     /**
    203      * Returns the test data.
    204      *
    205      * @return array
    206      * @since  Method available since Release 1.1.0
    207      */
    208     public function getTests()
    209     {
    210         return $this->tests;
    211     }
    212 
    213     /**
    214      * Start collection of code coverage information.
    215      *
    216      * @param  mixed   $id
    217      * @param  boolean $clear
    218      * @throws PHP_CodeCoverage_Exception
    219      */
    220     public function start($id, $clear = FALSE)
    221     {
    222         if (!is_bool($clear)) {
    223             throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
    224               1, 'boolean'
    225             );
    226         }
    227 
    228         if ($clear) {
    229             $this->clear();
    230         }
    231 
    232         $this->currentId = $id;
    233 
    234         $this->driver->start();
    235     }
    236 
    237     /**
    238      * Stop collection of code coverage information.
    239      *
    240      * @param  boolean $append
    241      * @return array
    242      * @throws PHP_CodeCoverage_Exception
    243      */
    244     public function stop($append = TRUE)
    245     {
    246         if (!is_bool($append)) {
    247             throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
    248               1, 'boolean'
    249             );
    250         }
    251 
    252         $data = $this->driver->stop();
    253         $this->append($data, NULL, $append);
    254 
    255         $this->currentId = NULL;
    256 
    257         return $data;
    258     }
    259 
    260     /**
    261      * Appends code coverage data.
    262      *
    263      * @param array   $data
    264      * @param mixed   $id
    265      * @param boolean $append
    266      */
    267     public function append(array $data, $id = NULL, $append = TRUE)
    268     {
    269         if ($id === NULL) {
    270             $id = $this->currentId;
    271         }
    272 
    273         if ($id === NULL) {
    274             throw new PHP_CodeCoverage_Exception;
    275         }
    276 
    277         $this->applyListsFilter($data);
    278         $this->initializeFilesThatAreSeenTheFirstTime($data);
    279 
    280         if (!$append) {
    281             return;
    282         }
    283 
    284         if ($id != 'UNCOVERED_FILES_FROM_WHITELIST') {
    285             $this->applyCoversAnnotationFilter($data, $id);
    286         }
    287 
    288         if (empty($data)) {
    289             return;
    290         }
    291 
    292         $status = NULL;
    293 
    294         if ($id instanceof PHPUnit_Framework_TestCase) {
    295             $status = $id->getStatus();
    296             $id     = get_class($id) . '::' . $id->getName();
    297         }
    298 
    299         else if ($id instanceof PHPUnit_Extensions_PhptTestCase) {
    300             $id = $id->getName();
    301         }
    302 
    303         $this->tests[$id] = $status;
    304 
    305         foreach ($data as $file => $lines) {
    306             if (!$this->filter->isFile($file)) {
    307                 continue;
    308             }
    309 
    310             foreach ($lines as $k => $v) {
    311                 if ($v == 1) {
    312                     $this->data[$file][$k][] = $id;
    313                 }
    314             }
    315         }
    316     }
    317 
    318     /**
    319      * Merges the data from another instance of PHP_CodeCoverage.
    320      *
    321      * @param PHP_CodeCoverage $that
    322      */
    323     public function merge(PHP_CodeCoverage $that)
    324     {
    325         foreach ($that->data as $file => $lines) {
    326             if (!isset($this->data[$file])) {
    327                 if (!$this->filter->isFiltered($file)) {
    328                     $this->data[$file] = $lines;
    329                 }
    330 
    331                 continue;
    332             }
    333 
    334             foreach ($lines as $line => $data) {
    335                 if ($data !== NULL) {
    336                     if (!isset($this->data[$file][$line])) {
    337                         $this->data[$file][$line] = $data;
    338                     } else {
    339                         $this->data[$file][$line] = array_unique(
    340                           array_merge($this->data[$file][$line], $data)
    341                         );
    342                     }
    343                 }
    344             }
    345         }
    346 
    347         $this->tests = array_merge($this->tests, $that->getTests());
    348     }
    349 
    350     /**
    351      * @param  boolean $flag
    352      * @throws PHP_CodeCoverage_Exception
    353      * @since  Method available since Release 1.1.0
    354      */
    355     public function setCacheTokens($flag)
    356     {
    357         if (!is_bool($flag)) {
    358             throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
    359               1, 'boolean'
    360             );
    361         }
    362 
    363         $this->cacheTokens = $flag;
    364     }
    365 
    366     /**
    367      * @param boolean $flag
    368      * @since Method available since Release 1.1.0
    369      */
    370     public function getCacheTokens()
    371     {
    372         return $this->cacheTokens;
    373     }
    374 
    375     /**
    376      * @param  boolean $flag
    377      * @throws PHP_CodeCoverage_Exception
    378      */
    379     public function setForceCoversAnnotation($flag)
    380     {
    381         if (!is_bool($flag)) {
    382             throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
    383               1, 'boolean'
    384             );
    385         }
    386 
    387         $this->forceCoversAnnotation = $flag;
    388     }
    389 
    390     /**
    391      * @param  boolean $flag
    392      * @throws PHP_CodeCoverage_Exception
    393      */
    394     public function setMapTestClassNameToCoveredClassName($flag)
    395     {
    396         if (!is_bool($flag)) {
    397             throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
    398               1, 'boolean'
    399             );
    400         }
    401 
    402         $this->mapTestClassNameToCoveredClassName = $flag;
    403     }
    404 
    405     /**
    406      * @param  boolean $flag
    407      * @throws PHP_CodeCoverage_Exception
    408      */
    409     public function setAddUncoveredFilesFromWhitelist($flag)
    410     {
    411         if (!is_bool($flag)) {
    412             throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
    413               1, 'boolean'
    414             );
    415         }
    416 
    417         $this->addUncoveredFilesFromWhitelist = $flag;
    418     }
    419 
    420     /**
    421      * @param  boolean $flag
    422      * @throws PHP_CodeCoverage_Exception
    423      */
    424     public function setProcessUncoveredFilesFromWhitelist($flag)
    425     {
    426         if (!is_bool($flag)) {
    427             throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
    428               1, 'boolean'
    429             );
    430         }
    431 
    432         $this->processUncoveredFilesFromWhitelist = $flag;
    433     }
    434 
    435     /**
    436      * Applies the @covers annotation filtering.
    437      *
    438      * @param array $data
    439      * @param mixed $id
    440      */
    441     protected function applyCoversAnnotationFilter(&$data, $id)
    442     {
    443         if ($id instanceof PHPUnit_Framework_TestCase) {
    444             $testClassName    = get_class($id);
    445             $linesToBeCovered = $this->getLinesToBeCovered(
    446               $testClassName, $id->getName()
    447             );
    448 
    449             if ($linesToBeCovered === FALSE) {
    450                 $data = array();
    451                 return;
    452             }
    453 
    454             if ($this->mapTestClassNameToCoveredClassName &&
    455                 empty($linesToBeCovered)) {
    456                 $testedClass = substr($testClassName, 0, -4);
    457 
    458                 if (class_exists($testedClass)) {
    459                     $class = new ReflectionClass($testedClass);
    460 
    461                     $linesToBeCovered = array(
    462                       $class->getFileName() => range(
    463                         $class->getStartLine(), $class->getEndLine()
    464                       )
    465                     );
    466                 }
    467             }
    468         } else {
    469             $linesToBeCovered = array();
    470         }
    471 
    472         if (!empty($linesToBeCovered)) {
    473             $data = array_intersect_key($data, $linesToBeCovered);
    474 
    475             foreach (array_keys($data) as $filename) {
    476                 $data[$filename] = array_intersect_key(
    477                   $data[$filename], array_flip($linesToBeCovered[$filename])
    478                 );
    479             }
    480         }
    481 
    482         else if ($this->forceCoversAnnotation) {
    483             $data = array();
    484         }
    485     }
    486 
    487     /**
    488      * Applies the blacklist/whitelist filtering.
    489      *
    490      * @param array $data
    491      */
    492     protected function applyListsFilter(&$data)
    493     {
    494         foreach (array_keys($data) as $filename) {
    495             if ($this->filter->isFiltered($filename)) {
    496                 unset($data[$filename]);
    497             }
    498         }
    499     }
    500 
    501     /**
    502      * @since Method available since Release 1.1.0
    503      */
    504     protected function initializeFilesThatAreSeenTheFirstTime($data)
    505     {
    506         foreach ($data as $file => $lines) {
    507             if ($this->filter->isFile($file) && !isset($this->data[$file])) {
    508                 $this->data[$file] = array();
    509 
    510                 foreach ($lines as $k => $v) {
    511                     $this->data[$file][$k] = $v == -2 ? NULL : array();
    512                 }
    513             }
    514         }
    515     }
    516 
    517     /**
    518      * Processes whitelisted files that are not covered.
    519      */
    520     protected function addUncoveredFilesFromWhitelist()
    521     {
    522         $data           = array();
    523         $uncoveredFiles = array_diff(
    524           $this->filter->getWhitelist(), array_keys($this->data)
    525         );
    526 
    527         foreach ($uncoveredFiles as $uncoveredFile) {
    528             if (!file_exists($uncoveredFile)) {
    529                 continue;
    530             }
    531 
    532             if ($this->processUncoveredFilesFromWhitelist) {
    533                 $this->processUncoveredFileFromWhitelist(
    534                   $uncoveredFile, $data, $uncoveredFiles
    535                 );
    536             } else {
    537                 $data[$uncoveredFile] = array();
    538 
    539                 $lines = count(file($uncoveredFile));
    540 
    541                 for ($i = 1; $i <= $lines; $i++) {
    542                     $data[$uncoveredFile][$i] = -1;
    543                 }
    544             }
    545         }
    546 
    547         $this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST');
    548     }
    549 
    550     /**
    551      * @param string $uncoveredFile
    552      * @param array  $data
    553      * @param array  $uncoveredFiles
    554      */
    555     protected function processUncoveredFileFromWhitelist($uncoveredFile, array &$data, array $uncoveredFiles)
    556     {
    557         $this->driver->start();
    558         include_once $uncoveredFile;
    559         $coverage = $this->driver->stop();
    560 
    561         foreach ($coverage as $file => $fileCoverage) {
    562             if (!isset($data[$file]) &&
    563                 in_array($file, $uncoveredFiles)) {
    564                 foreach (array_keys($fileCoverage) as $key) {
    565                     if ($fileCoverage[$key] == 1) {
    566                         $fileCoverage[$key] = -1;
    567                     }
    568                 }
    569 
    570                 $data[$file] = $fileCoverage;
    571             }
    572         }
    573     }
    574 
    575     /**
    576      * Returns the files and lines a test method wants to cover.
    577      *
    578      * @param  string $className
    579      * @param  string $methodName
    580      * @return array
    581      * @since  Method available since Release 1.2.0
    582      */
    583     protected function getLinesToBeCovered($className, $methodName)
    584     {
    585         $codeToCoverList = array();
    586         $result          = array();
    587 
    588         // @codeCoverageIgnoreStart
    589         if (($pos = strpos($methodName, ' ')) !== FALSE) {
    590             $methodName = substr($methodName, 0, $pos);
    591         }
    592         // @codeCoverageIgnoreEnd
    593 
    594         $class = new ReflectionClass($className);
    595 
    596         try {
    597             $method = new ReflectionMethod($className, $methodName);
    598         }
    599 
    600         catch (ReflectionException $e) {
    601             return array();
    602         }
    603 
    604         $docComment = substr($class->getDocComment(), 3, -2) . PHP_EOL . substr($method->getDocComment(), 3, -2);
    605 
    606         $templateMethods = array(
    607           'setUp', 'assertPreConditions', 'assertPostConditions', 'tearDown'
    608         );
    609 
    610         foreach ($templateMethods as $templateMethod) {
    611             if ($class->hasMethod($templateMethod)) {
    612                 $reflector   = $class->getMethod($templateMethod);
    613                 $docComment .= PHP_EOL . substr($reflector->getDocComment(), 3, -2);
    614                 unset($reflector);
    615             }
    616         }
    617 
    618         if (strpos($docComment, '@coversNothing') !== FALSE) {
    619             return FALSE;
    620         }
    621 
    622         $classShortcut = preg_match_all(
    623           '(@coversDefaultClass\s+(?P<coveredClass>[^\s]++)\s*$)m',
    624           $class->getDocComment(),
    625           $matches
    626         );
    627 
    628         if ($classShortcut) {
    629             if ($classShortcut > 1) {
    630                 throw new PHP_CodeCoverage_Exception(
    631                   sprintf(
    632                     'More than one @coversClass annotation in class or interface "%s".',
    633                     $className
    634                   )
    635                 );
    636             }
    637 
    638             $classShortcut = $matches['coveredClass'][0];
    639         }
    640 
    641         $match = preg_match_all(
    642           '(@covers\s+(?P<coveredElement>[^\s()]++)[\s()]*$)m',
    643           $docComment,
    644           $matches
    645         );
    646 
    647         if ($match) {
    648             foreach ($matches['coveredElement'] as $coveredElement) {
    649                 if ($classShortcut && strncmp($coveredElement, '::', 2) === 0) {
    650                     $coveredElement = $classShortcut . $coveredElement;
    651                 }
    652 
    653                 $codeToCoverList = array_merge(
    654                   $codeToCoverList,
    655                   $this->resolveCoversToReflectionObjects($coveredElement)
    656                 );
    657             }
    658 
    659             foreach ($codeToCoverList as $codeToCover) {
    660                 $fileName = $codeToCover->getFileName();
    661 
    662                 if (!isset($result[$fileName])) {
    663                     $result[$fileName] = array();
    664                 }
    665 
    666                 $result[$fileName] = array_unique(
    667                   array_merge(
    668                     $result[$fileName],
    669                     range(
    670                       $codeToCover->getStartLine(), $codeToCover->getEndLine()
    671                     )
    672                   )
    673                 );
    674             }
    675         }
    676 
    677         return $result;
    678     }
    679 
    680     /**
    681      * @param  string $coveredElement
    682      * @return array
    683      * @since  Method available since Release 1.2.0
    684      */
    685     protected function resolveCoversToReflectionObjects($coveredElement)
    686     {
    687         $codeToCoverList = array();
    688 
    689         if (strpos($coveredElement, '::') !== FALSE) {
    690             list($className, $methodName) = explode('::', $coveredElement);
    691 
    692             if (isset($methodName[0]) && $methodName[0] == '<') {
    693                 $classes = array($className);
    694 
    695                 foreach ($classes as $className) {
    696                     if (!class_exists($className) &&
    697                         !interface_exists($className)) {
    698                         throw new PHP_CodeCoverage_Exception(
    699                           sprintf(
    700                             'Trying to @cover not existing class or ' .
    701                             'interface "%s".',
    702                             $className
    703                           )
    704                         );
    705                     }
    706 
    707                     $class   = new ReflectionClass($className);
    708                     $methods = $class->getMethods();
    709                     $inverse = isset($methodName[1]) && $methodName[1] == '!';
    710 
    711                     if (strpos($methodName, 'protected')) {
    712                         $visibility = 'isProtected';
    713                     }
    714 
    715                     else if (strpos($methodName, 'private')) {
    716                         $visibility = 'isPrivate';
    717                     }
    718 
    719                     else if (strpos($methodName, 'public')) {
    720                         $visibility = 'isPublic';
    721                     }
    722 
    723                     foreach ($methods as $method) {
    724                         if ($inverse && !$method->$visibility()) {
    725                             $codeToCoverList[] = $method;
    726                         }
    727 
    728                         else if (!$inverse && $method->$visibility()) {
    729                             $codeToCoverList[] = $method;
    730                         }
    731                     }
    732                 }
    733             } else {
    734                 $classes = array($className);
    735 
    736                 foreach ($classes as $className) {
    737                     if ($className == '' && function_exists($methodName)) {
    738                         $codeToCoverList[] = new ReflectionFunction(
    739                           $methodName
    740                         );
    741                     } else {
    742                         if (!((class_exists($className) ||
    743                                interface_exists($className) ||
    744                                trait_exists($className)) &&
    745                               method_exists($className, $methodName))) {
    746                             throw new PHP_CodeCoverage_Exception(
    747                               sprintf(
    748                                 'Trying to @cover not existing method "%s::%s".',
    749                                 $className,
    750                                 $methodName
    751                               )
    752                             );
    753                         }
    754 
    755                         $codeToCoverList[] = new ReflectionMethod(
    756                           $className, $methodName
    757                         );
    758                     }
    759                 }
    760             }
    761         } else {
    762             $extended = FALSE;
    763 
    764             if (strpos($coveredElement, '<extended>') !== FALSE) {
    765                 $coveredElement = str_replace(
    766                   '<extended>', '', $coveredElement
    767                 );
    768 
    769                 $extended = TRUE;
    770             }
    771 
    772             $classes = array($coveredElement);
    773 
    774             if ($extended) {
    775                 $classes = array_merge(
    776                   $classes,
    777                   class_implements($coveredElement),
    778                   class_parents($coveredElement)
    779                 );
    780             }
    781 
    782             foreach ($classes as $className) {
    783                 if (!class_exists($className) &&
    784                     !interface_exists($className) &&
    785                     !trait_exists($className)) {
    786                     throw new PHP_CodeCoverage_Exception(
    787                       sprintf(
    788                         'Trying to @cover not existing class or ' .
    789                         'interface "%s".',
    790                         $className
    791                       )
    792                     );
    793                 }
    794 
    795                 $codeToCoverList[] = new ReflectionClass($className);
    796             }
    797         }
    798 
    799         return $codeToCoverList;
    800     }
    801 }