first commit - working
This commit is contained in:
394
vendor/phpunit/php-code-coverage/ChangeLog.md
vendored
Normal file
394
vendor/phpunit/php-code-coverage/ChangeLog.md
vendored
Normal file
@ -0,0 +1,394 @@
|
||||
# ChangeLog
|
||||
|
||||
All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
|
||||
|
||||
## [9.2.10] - 2021-12-05
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#887](https://github.com/sebastianbergmann/php-code-coverage/issues/887): Document return type of `CodeUnitFindingVisitor::enterNode()` so that Symfony's DebugClassLoader does not trigger a deprecation warning
|
||||
|
||||
## [9.2.9] - 2021-11-19
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#882](https://github.com/sebastianbergmann/php-code-coverage/issues/882): PHPUnit 9.2.8 has wrong version number
|
||||
|
||||
## [9.2.8] - 2021-10-30
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#866](https://github.com/sebastianbergmann/php-code-coverage/issues/866): `CodeUnitFindingVisitor` does not handle `enum` type introduced in PHP 8.1
|
||||
* [#868](https://github.com/sebastianbergmann/php-code-coverage/pull/868): Uncovered files should be ignored unless requested
|
||||
* [#876](https://github.com/sebastianbergmann/php-code-coverage/issues/876): PCOV driver causes 2x slowdown after upgrade to PHPUnit 9.5
|
||||
|
||||
## [9.2.7] - 2021-09-17
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#860](https://github.com/sebastianbergmann/php-code-coverage/pull/860): Empty value for `XDEBUG_MODE` environment variable is not handled correctly
|
||||
|
||||
## [9.2.6] - 2021-03-28
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#846](https://github.com/sebastianbergmann/php-code-coverage/issues/846): Method name should not appear in the method signature attribute of Cobertura XML
|
||||
|
||||
## [9.2.5] - 2020-11-28
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#831](https://github.com/sebastianbergmann/php-code-coverage/issues/831): Files that do not contain a newline are not handled correctly
|
||||
|
||||
## [9.2.4] - 2020-11-27
|
||||
|
||||
### Added
|
||||
|
||||
* [#834](https://github.com/sebastianbergmann/php-code-coverage/issues/834): Support `XDEBUG_MODE` environment variable
|
||||
|
||||
## [9.2.3] - 2020-10-30
|
||||
|
||||
### Changed
|
||||
|
||||
* Bumped required version of `nikic/php-parser`
|
||||
|
||||
## [9.2.2] - 2020-10-28
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#820](https://github.com/sebastianbergmann/php-code-coverage/issues/820): Hidden dependency on PHPUnit
|
||||
|
||||
## [9.2.1] - 2020-10-26
|
||||
|
||||
### Fixed
|
||||
|
||||
* `SebastianBergmann\CodeCoverage\Exception` now correctly extends `\Throwable`
|
||||
|
||||
## [9.2.0] - 2020-10-02
|
||||
|
||||
### Added
|
||||
|
||||
* [#812](https://github.com/sebastianbergmann/php-code-coverage/pull/812): Support for Cobertura XML report format
|
||||
|
||||
### Changed
|
||||
|
||||
* Reduced the number of I/O operations performed by the static analysis cache
|
||||
|
||||
## [9.1.11] - 2020-09-19
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#811](https://github.com/sebastianbergmann/php-code-coverage/issues/811): `T_FN` constant is used on PHP 7.3 where it is not available
|
||||
|
||||
## [9.1.10] - 2020-09-18
|
||||
|
||||
### Added
|
||||
|
||||
* `SebastianBergmann\CodeCoverage\Driver\Selector::forLineCoverage()` and `SebastianBergmann\CodeCoverage\Driver\Selector::forLineAndPathCoverage()` have been added
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#810](https://github.com/sebastianbergmann/php-code-coverage/issues/810): `SebastianBergmann\CodeCoverage\Driver\Driver::forLineCoverage()` and `SebastianBergmann\CodeCoverage\Driver\Driver::forLineAndPathCoverage()` are marked as internal
|
||||
|
||||
### Removed
|
||||
|
||||
* `SebastianBergmann\CodeCoverage\Driver\Driver::forLineCoverage()` and `SebastianBergmann\CodeCoverage\Driver\Driver::forLineAndPathCoverage()` are now deprecated
|
||||
|
||||
## [9.1.9] - 2020-09-15
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#808](https://github.com/sebastianbergmann/php-code-coverage/issues/808): `PHP Warning: Use of undefined constant T_MATCH`
|
||||
|
||||
## [9.1.8] - 2020-09-07
|
||||
|
||||
### Changed
|
||||
|
||||
* [#800](https://github.com/sebastianbergmann/php-code-coverage/pull/800): All files on the inclusion list are no longer loaded when `SebastianBergmann\CodeCoverage::start()` is called for the first time and `processUncoveredFiles` is set to `true`
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#799](https://github.com/sebastianbergmann/php-code-coverage/issues/799): Uncovered new line at end of file
|
||||
|
||||
## [9.1.7] - 2020-09-03
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed regressions introduced in versions 9.1.5 and 9.1.6
|
||||
|
||||
## [9.1.6] - 2020-08-31
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#799](https://github.com/sebastianbergmann/php-code-coverage/issues/799): Uncovered new line at end of file
|
||||
* [#803](https://github.com/sebastianbergmann/php-code-coverage/issues/803): HTML report does not sort directories and files anymore
|
||||
|
||||
## [9.1.5] - 2020-08-27
|
||||
|
||||
### Changed
|
||||
|
||||
* [#800](https://github.com/sebastianbergmann/php-code-coverage/pull/800): All files on the inclusion list are no longer loaded when `SebastianBergmann\CodeCoverage::start()` is called for the first time and `processUncoveredFiles` is set to `true`
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#797](https://github.com/sebastianbergmann/php-code-coverage/pull/797): Class name is wrongly removed from namespace name
|
||||
|
||||
## [9.1.4] - 2020-08-13
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#793](https://github.com/sebastianbergmann/php-code-coverage/issues/793): Lines with `::class` constant are not covered
|
||||
|
||||
## [9.1.3] - 2020-08-10
|
||||
|
||||
### Changed
|
||||
|
||||
* Changed PHP-Parser usage to parse sourcecode according to the PHP version we are currently running on instead of using emulative lexing
|
||||
|
||||
## [9.1.2] - 2020-08-10
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#791](https://github.com/sebastianbergmann/php-code-coverage/pull/791): Cache Warmer does not warm all caches
|
||||
|
||||
## [9.1.1] - 2020-08-10
|
||||
|
||||
### Added
|
||||
|
||||
* Added `SebastianBergmann\CodeCoverage::cacheDirectory()` method for querying where the cache writes its files
|
||||
|
||||
## [9.1.0] - 2020-08-10
|
||||
|
||||
### Added
|
||||
|
||||
* Implemented a persistent cache for information gathered using PHP-Parser based static analysis (hereinafter referred to as "cache")
|
||||
* Added `SebastianBergmann\CodeCoverage::cacheStaticAnalysis(string $cacheDirectory)` method for enabling the cache; it will write its files to `$directory`
|
||||
* Added `SebastianBergmann\CodeCoverage::doNotCacheStaticAnalysis` method for disabling the cache
|
||||
* Added `SebastianBergmann\CodeCoverage::cachesStaticAnalysis()` method for querying whether the cache is enabled
|
||||
* Added `SebastianBergmann\CodeCoverage\StaticAnalysis\CacheWarmer::warmCache()` method for warming the cache
|
||||
|
||||
## [9.0.0] - 2020-08-07
|
||||
|
||||
### Added
|
||||
|
||||
* [#761](https://github.com/sebastianbergmann/php-code-coverage/pull/761): Support for Branch Coverage and Path Coverage
|
||||
* Added `SebastianBergmann\CodeCoverage\Driver\Driver::forLineCoverage()` for selecting the best available driver for line coverage
|
||||
* Added `SebastianBergmann\CodeCoverage\Driver\Driver::forLineAndPathCoverage()` for selecting the best available driver for path coverage
|
||||
* This component is now supported on PHP 8
|
||||
* This component now supports Xdebug 3
|
||||
|
||||
### Changed
|
||||
|
||||
* [#746](https://github.com/sebastianbergmann/php-code-coverage/pull/746): Remove some ancient workarounds for very old Xdebug versions
|
||||
* [#747](https://github.com/sebastianbergmann/php-code-coverage/pull/747): Use native filtering in PCOV and Xdebug drivers
|
||||
* [#748](https://github.com/sebastianbergmann/php-code-coverage/pull/748): Store raw code coverage in value objects instead of arrays
|
||||
* [#749](https://github.com/sebastianbergmann/php-code-coverage/pull/749): Store processed code coverage in value objects instead of arrays
|
||||
* [#752](https://github.com/sebastianbergmann/php-code-coverage/pull/752): Rework how code coverage settings are propagated to the driver
|
||||
* [#754](https://github.com/sebastianbergmann/php-code-coverage/pull/754): Implement collection of raw branch and path coverage
|
||||
* [#755](https://github.com/sebastianbergmann/php-code-coverage/pull/755): Implement processing of raw branch and path coverage
|
||||
* [#756](https://github.com/sebastianbergmann/php-code-coverage/pull/756): Improve handling of uncovered files
|
||||
* `SebastianBergmann\CodeCoverage\Filter::addDirectoryToWhitelist()` has been renamed to `SebastianBergmann\CodeCoverage\Filter::includeDirectory()`
|
||||
* `SebastianBergmann\CodeCoverage\Filter::addFilesToWhitelist()` has been renamed to `SebastianBergmann\CodeCoverage\Filter::includeFiles()`
|
||||
* `SebastianBergmann\CodeCoverage\Filter::addFileToWhitelist()` has been renamed to `SebastianBergmann\CodeCoverage\Filter::includeFile()`
|
||||
* `SebastianBergmann\CodeCoverage\Filter::removeDirectoryFromWhitelist()` has been renamed to `SebastianBergmann\CodeCoverage\Filter::excludeDirectory()`
|
||||
* `SebastianBergmann\CodeCoverage\Filter::removeFileFromWhitelist()` has been renamed to `SebastianBergmann\CodeCoverage\Filter::excludeFile()`
|
||||
* `SebastianBergmann\CodeCoverage\Filter::isFiltered()` has been renamed to `SebastianBergmann\CodeCoverage\Filter::isExcluded()`
|
||||
* `SebastianBergmann\CodeCoverage\Filter::getWhitelist()` has been renamed to `SebastianBergmann\CodeCoverage\Filter::files()`
|
||||
* The arguments for `CodeCoverage::__construct()` are no longer optional
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#700](https://github.com/sebastianbergmann/php-code-coverage/pull/700): Throw an exception if code coverage fails to write to disk
|
||||
|
||||
### Removed
|
||||
|
||||
* `SebastianBergmann\CodeCoverage\CodeCoverage::setCacheTokens()` and `SebastianBergmann\CodeCoverage\CodeCoverage::getCacheTokens()` have been removed
|
||||
* `SebastianBergmann\CodeCoverage\CodeCoverage::setCheckForUnintentionallyCoveredCode()` has been removed, please use `SebastianBergmann\CodeCoverage\CodeCoverage::enableCheckForUnintentionallyCoveredCode()` or `SebastianBergmann\CodeCoverage\CodeCoverage::disableCheckForUnintentionallyCoveredCode()` instead
|
||||
* `SebastianBergmann\CodeCoverage\CodeCoverage::setSubclassesExcludedFromUnintentionallyCoveredCodeCheck()` has been removed, please use `SebastianBergmann\CodeCoverage\CodeCoverage::excludeSubclassesOfThisClassFromUnintentionallyCoveredCodeCheck()` instead
|
||||
* `SebastianBergmann\CodeCoverage\CodeCoverage::setAddUncoveredFilesFromWhitelist()` has been removed, please use `SebastianBergmann\CodeCoverage\CodeCoverage::includeUncoveredFiles()` or `SebastianBergmann\CodeCoverage\CodeCoverage::excludeUncoveredFiles()` instead
|
||||
* `SebastianBergmann\CodeCoverage\CodeCoverage::setProcessUncoveredFiles()` has been removed, please use `SebastianBergmann\CodeCoverage\CodeCoverage::processUncoveredFiles()` or `SebastianBergmann\CodeCoverage\CodeCoverage::doNotProcessUncoveredFiles()` instead
|
||||
* `SebastianBergmann\CodeCoverage\CodeCoverage::setIgnoreDeprecatedCode()` has been removed, please use `SebastianBergmann\CodeCoverage\CodeCoverage::ignoreDeprecatedCode()` or `SebastianBergmann\CodeCoverage\CodeCoverage::doNotIgnoreDeprecatedCode()` instead
|
||||
* `SebastianBergmann\CodeCoverage\CodeCoverage::setDisableIgnoredLines()` has been removed, please use `SebastianBergmann\CodeCoverage\CodeCoverage::enableAnnotationsForIgnoringCode()` or `SebastianBergmann\CodeCoverage\CodeCoverage::disableAnnotationsForIgnoringCode()` instead
|
||||
* `SebastianBergmann\CodeCoverage\CodeCoverage::setCheckForMissingCoversAnnotation()` has been removed
|
||||
* `SebastianBergmann\CodeCoverage\CodeCoverage::setCheckForUnexecutedCoveredCode()` has been removed
|
||||
* `SebastianBergmann\CodeCoverage\CodeCoverage::setForceCoversAnnotation()` has been removed
|
||||
* `SebastianBergmann\CodeCoverage\Filter::hasWhitelist()` has been removed, please use `SebastianBergmann\CodeCoverage\Filter::isEmpty()` instead
|
||||
* `SebastianBergmann\CodeCoverage\Filter::getWhitelistedFiles()` has been removed
|
||||
* `SebastianBergmann\CodeCoverage\Filter::setWhitelistedFiles()` has been removed
|
||||
|
||||
## [8.0.2] - 2020-05-23
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#750](https://github.com/sebastianbergmann/php-code-coverage/pull/750): Inconsistent handling of namespaces
|
||||
* [#751](https://github.com/sebastianbergmann/php-code-coverage/pull/751): Dead code is not highlighted correctly
|
||||
* [#753](https://github.com/sebastianbergmann/php-code-coverage/issues/753): Do not use `$_SERVER['REQUEST_TIME']` because the test(ed) code might unset it
|
||||
|
||||
## [8.0.1] - 2020-02-19
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#731](https://github.com/sebastianbergmann/php-code-coverage/pull/731): Confusing footer in the HTML report
|
||||
|
||||
## [8.0.0] - 2020-02-07
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#721](https://github.com/sebastianbergmann/php-code-coverage/pull/721): Workaround for PHP bug [#79191](https://bugs.php.net/bug.php?id=79191)
|
||||
|
||||
### Removed
|
||||
|
||||
* This component is no longer supported on PHP 7.2
|
||||
|
||||
## [7.0.15] - 2021-07-26
|
||||
|
||||
### Changed
|
||||
|
||||
* Bumped required version of php-token-stream
|
||||
|
||||
## [7.0.14] - 2020-12-02
|
||||
|
||||
### Changed
|
||||
|
||||
* [#837](https://github.com/sebastianbergmann/php-code-coverage/issues/837): Allow version 4 of php-token-stream
|
||||
|
||||
## [7.0.13] - 2020-11-30
|
||||
|
||||
### Changed
|
||||
|
||||
* Changed PHP version constraint in `composer.json` from `^7.2` to `>=7.2` to allow installation of this version of this library on PHP 8. However, this version of this library does not work on PHP 8. PHPUnit 8.5, which uses this version of this library, does not call into this library and instead shows a message that code coverage functionality is not available for PHPUnit 8.5 on PHP 8.
|
||||
|
||||
## [7.0.12] - 2020-11-27
|
||||
|
||||
### Added
|
||||
|
||||
* [#834](https://github.com/sebastianbergmann/php-code-coverage/issues/834): Support `XDEBUG_MODE` environment variable
|
||||
|
||||
## [7.0.11] - 2020-11-27
|
||||
|
||||
### Added
|
||||
|
||||
* Support for Xdebug 3
|
||||
|
||||
## [7.0.10] - 2019-11-20
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#710](https://github.com/sebastianbergmann/php-code-coverage/pull/710): Code Coverage does not work in PhpStorm
|
||||
|
||||
## [7.0.9] - 2019-11-20
|
||||
|
||||
### Changed
|
||||
|
||||
* [#709](https://github.com/sebastianbergmann/php-code-coverage/pull/709): Prioritize PCOV over Xdebug
|
||||
|
||||
## [7.0.8] - 2019-09-17
|
||||
|
||||
### Changed
|
||||
|
||||
* Update HTML report Bootstrap 4.3.1, jQuery 3.4.1, and popper.js 1.15.0
|
||||
|
||||
## [7.0.7] - 2019-07-25
|
||||
|
||||
### Changed
|
||||
|
||||
* Bumped required version of php-token-stream
|
||||
|
||||
## [7.0.6] - 2019-07-08
|
||||
|
||||
### Changed
|
||||
|
||||
* Bumped required version of php-token-stream
|
||||
|
||||
## [7.0.5] - 2019-06-06
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#681](https://github.com/sebastianbergmann/php-code-coverage/pull/681): `use function` statements are not ignored
|
||||
|
||||
## [7.0.4] - 2019-05-29
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#682](https://github.com/sebastianbergmann/php-code-coverage/pull/682): Code that is not executed is reported as being executed when using PCOV
|
||||
|
||||
## [7.0.3] - 2019-02-26
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#671](https://github.com/sebastianbergmann/php-code-coverage/issues/671): `TypeError` when directory name is a number
|
||||
|
||||
## [7.0.2] - 2019-02-15
|
||||
|
||||
### Changed
|
||||
|
||||
* Updated HTML report to Bootstrap 4.3.0
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#667](https://github.com/sebastianbergmann/php-code-coverage/pull/667): `TypeError` in PHP reporter
|
||||
|
||||
## [7.0.1] - 2019-02-01
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#664](https://github.com/sebastianbergmann/php-code-coverage/issues/664): `TypeError` when whitelisted file does not exist
|
||||
|
||||
## [7.0.0] - 2019-02-01
|
||||
|
||||
### Added
|
||||
|
||||
* [#663](https://github.com/sebastianbergmann/php-code-coverage/pull/663): Support for PCOV
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#654](https://github.com/sebastianbergmann/php-code-coverage/issues/654): HTML report fails to load assets
|
||||
* [#655](https://github.com/sebastianbergmann/php-code-coverage/issues/655): Popin pops in outside of screen
|
||||
|
||||
### Removed
|
||||
|
||||
* This component is no longer supported on PHP 7.1
|
||||
|
||||
[9.2.10]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.9...9.2.10
|
||||
[9.2.9]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.8...9.2.9
|
||||
[9.2.8]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.7...9.2.8
|
||||
[9.2.7]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.6...9.2.7
|
||||
[9.2.6]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.5...9.2.6
|
||||
[9.2.5]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.4...9.2.5
|
||||
[9.2.4]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.3...9.2.4
|
||||
[9.2.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.2...9.2.3
|
||||
[9.2.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.1...9.2.2
|
||||
[9.2.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.0...9.2.1
|
||||
[9.2.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.1.11...9.2.0
|
||||
[9.1.11]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.1.10...9.1.11
|
||||
[9.1.10]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.1.9...9.1.10
|
||||
[9.1.9]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.1.8...9.1.9
|
||||
[9.1.8]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.1.7...9.1.8
|
||||
[9.1.7]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.1.6...9.1.7
|
||||
[9.1.6]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.1.5...9.1.6
|
||||
[9.1.5]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.1.4...9.1.5
|
||||
[9.1.4]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.1.3...9.1.4
|
||||
[9.1.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.1.2...9.1.3
|
||||
[9.1.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.1.1...9.1.2
|
||||
[9.1.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.1.0...9.1.1
|
||||
[9.1.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.0.0...9.1.0
|
||||
[9.0.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/8.0...9.0.0
|
||||
[8.0.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/8.0.1...8.0.2
|
||||
[8.0.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/8.0.0...8.0.1
|
||||
[8.0.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.10...8.0.0
|
||||
[7.0.15]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.14...7.0.15
|
||||
[7.0.14]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.13...7.0.14
|
||||
[7.0.13]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.12...7.0.13
|
||||
[7.0.12]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.11...7.0.12
|
||||
[7.0.11]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.10...7.0.11
|
||||
[7.0.10]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.9...7.0.10
|
||||
[7.0.9]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.8...7.0.9
|
||||
[7.0.8]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.7...7.0.8
|
||||
[7.0.7]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.6...7.0.7
|
||||
[7.0.6]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.5...7.0.6
|
||||
[7.0.5]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.4...7.0.5
|
||||
[7.0.4]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.3...7.0.4
|
||||
[7.0.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.2...7.0.3
|
||||
[7.0.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.1...7.0.2
|
||||
[7.0.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.0...7.0.1
|
||||
[7.0.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/6.1.4...7.0.0
|
33
vendor/phpunit/php-code-coverage/LICENSE
vendored
Normal file
33
vendor/phpunit/php-code-coverage/LICENSE
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
php-code-coverage
|
||||
|
||||
Copyright (c) 2009-2021, Sebastian Bergmann <sebastian@phpunit.de>.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of Sebastian Bergmann nor the names of his
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
48
vendor/phpunit/php-code-coverage/README.md
vendored
Normal file
48
vendor/phpunit/php-code-coverage/README.md
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
# phpunit/php-code-coverage
|
||||
|
||||
[](https://packagist.org/packages/phpunit/php-code-coverage)
|
||||
[](https://github.com/sebastianbergmann/php-code-coverage/actions)
|
||||
[](https://shepherd.dev/github/sebastianbergmann/php-code-coverage)
|
||||
|
||||
Provides collection, processing, and rendering functionality for PHP code coverage information.
|
||||
|
||||
## Installation
|
||||
|
||||
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
|
||||
|
||||
```
|
||||
composer require phpunit/php-code-coverage
|
||||
```
|
||||
|
||||
If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
|
||||
|
||||
```
|
||||
composer require --dev phpunit/php-code-coverage
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```php
|
||||
<?php declare(strict_types=1);
|
||||
use SebastianBergmann\CodeCoverage\Filter;
|
||||
use SebastianBergmann\CodeCoverage\Driver\Selector;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Report\Html\Facade as HtmlReport;
|
||||
|
||||
$filter = new Filter;
|
||||
$filter->includeDirectory('/path/to/directory');
|
||||
|
||||
$coverage = new CodeCoverage(
|
||||
(new Selector)->forLineCoverage($filter),
|
||||
$filter
|
||||
);
|
||||
|
||||
$coverage->start('<name of test>');
|
||||
|
||||
// ...
|
||||
|
||||
$coverage->stop();
|
||||
|
||||
|
||||
(new HtmlReport)->process($coverage, '/tmp/code-coverage-report');
|
||||
```
|
68
vendor/phpunit/php-code-coverage/composer.json
vendored
Normal file
68
vendor/phpunit/php-code-coverage/composer.json
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"coverage",
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"homepage": "https://github.com/sebastianbergmann/php-code-coverage",
|
||||
"license": "BSD-3-Clause",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues"
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.3.0"
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true
|
||||
},
|
||||
"prefer-stable": true,
|
||||
"require": {
|
||||
"php": ">=7.3",
|
||||
"ext-dom": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"nikic/php-parser": "^4.13.0",
|
||||
"phpunit/php-file-iterator": "^3.0.3",
|
||||
"phpunit/php-text-template": "^2.0.2",
|
||||
"sebastian/code-unit-reverse-lookup": "^2.0.2",
|
||||
"sebastian/complexity": "^2.0",
|
||||
"sebastian/environment": "^5.1.2",
|
||||
"sebastian/lines-of-code": "^1.0.3",
|
||||
"sebastian/version": "^3.0.1",
|
||||
"theseer/tokenizer": "^1.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.3"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-pcov": "*",
|
||||
"ext-xdebug": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"files": [
|
||||
"tests/TestCase.php",
|
||||
"tests/_files/BankAccountTest.php"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "9.2-dev"
|
||||
}
|
||||
}
|
||||
}
|
687
vendor/phpunit/php-code-coverage/src/CodeCoverage.php
vendored
Normal file
687
vendor/phpunit/php-code-coverage/src/CodeCoverage.php
vendored
Normal file
@ -0,0 +1,687 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use function array_diff;
|
||||
use function array_diff_key;
|
||||
use function array_flip;
|
||||
use function array_keys;
|
||||
use function array_merge;
|
||||
use function array_unique;
|
||||
use function array_values;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function get_class;
|
||||
use function is_array;
|
||||
use function is_file;
|
||||
use function sort;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Runner\PhptTestCase;
|
||||
use PHPUnit\Util\Test;
|
||||
use ReflectionClass;
|
||||
use SebastianBergmann\CodeCoverage\Driver\Driver;
|
||||
use SebastianBergmann\CodeCoverage\Node\Builder;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\CachingCoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\CachingUncoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\CoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\ParsingCoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\ParsingUncoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\UncoveredFileAnalyser;
|
||||
use SebastianBergmann\CodeUnitReverseLookup\Wizard;
|
||||
|
||||
/**
|
||||
* Provides collection functionality for PHP code coverage information.
|
||||
*/
|
||||
final class CodeCoverage
|
||||
{
|
||||
private const UNCOVERED_FILES = 'UNCOVERED_FILES';
|
||||
|
||||
/**
|
||||
* @var Driver
|
||||
*/
|
||||
private $driver;
|
||||
|
||||
/**
|
||||
* @var Filter
|
||||
*/
|
||||
private $filter;
|
||||
|
||||
/**
|
||||
* @var Wizard
|
||||
*/
|
||||
private $wizard;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $checkForUnintentionallyCoveredCode = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $includeUncoveredFiles = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $processUncoveredFiles = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $ignoreDeprecatedCode = false;
|
||||
|
||||
/**
|
||||
* @var PhptTestCase|string|TestCase
|
||||
*/
|
||||
private $currentId;
|
||||
|
||||
/**
|
||||
* Code coverage data.
|
||||
*
|
||||
* @var ProcessedCodeCoverageData
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $useAnnotationsForIgnoringCode = true;
|
||||
|
||||
/**
|
||||
* Test data.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $tests = [];
|
||||
|
||||
/**
|
||||
* @psalm-var list<class-string>
|
||||
*/
|
||||
private $parentClassesExcludedFromUnintentionallyCoveredCodeCheck = [];
|
||||
|
||||
/**
|
||||
* @var ?CoveredFileAnalyser
|
||||
*/
|
||||
private $coveredFileAnalyser;
|
||||
|
||||
/**
|
||||
* @var ?UncoveredFileAnalyser
|
||||
*/
|
||||
private $uncoveredFileAnalyser;
|
||||
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
private $cacheDirectory;
|
||||
|
||||
public function __construct(Driver $driver, Filter $filter)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
$this->filter = $filter;
|
||||
$this->data = new ProcessedCodeCoverageData;
|
||||
$this->wizard = new Wizard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code coverage information as a graph of node objects.
|
||||
*/
|
||||
public function getReport(): Directory
|
||||
{
|
||||
return (new Builder($this->coveredFileAnalyser()))->build($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears collected code coverage data.
|
||||
*/
|
||||
public function clear(): void
|
||||
{
|
||||
$this->currentId = null;
|
||||
$this->data = new ProcessedCodeCoverageData;
|
||||
$this->tests = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filter object used.
|
||||
*/
|
||||
public function filter(): Filter
|
||||
{
|
||||
return $this->filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the collected code coverage data.
|
||||
*/
|
||||
public function getData(bool $raw = false): ProcessedCodeCoverageData
|
||||
{
|
||||
if (!$raw) {
|
||||
if ($this->processUncoveredFiles) {
|
||||
$this->processUncoveredFilesFromFilter();
|
||||
} elseif ($this->includeUncoveredFiles) {
|
||||
$this->addUncoveredFilesFromFilter();
|
||||
} else {
|
||||
$this->data->removeFilesWithNoCoverage();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the coverage data.
|
||||
*/
|
||||
public function setData(ProcessedCodeCoverageData $data): void
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the test data.
|
||||
*/
|
||||
public function getTests(): array
|
||||
{
|
||||
return $this->tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test data.
|
||||
*/
|
||||
public function setTests(array $tests): void
|
||||
{
|
||||
$this->tests = $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start collection of code coverage information.
|
||||
*
|
||||
* @param PhptTestCase|string|TestCase $id
|
||||
*/
|
||||
public function start($id, bool $clear = false): void
|
||||
{
|
||||
if ($clear) {
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
$this->currentId = $id;
|
||||
|
||||
$this->driver->start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop collection of code coverage information.
|
||||
*
|
||||
* @param array|false $linesToBeCovered
|
||||
*/
|
||||
public function stop(bool $append = true, $linesToBeCovered = [], array $linesToBeUsed = []): RawCodeCoverageData
|
||||
{
|
||||
if (!is_array($linesToBeCovered) && $linesToBeCovered !== false) {
|
||||
throw new InvalidArgumentException(
|
||||
'$linesToBeCovered must be an array or false'
|
||||
);
|
||||
}
|
||||
|
||||
$data = $this->driver->stop();
|
||||
$this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed);
|
||||
|
||||
$this->currentId = null;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends code coverage data.
|
||||
*
|
||||
* @param PhptTestCase|string|TestCase $id
|
||||
* @param array|false $linesToBeCovered
|
||||
*
|
||||
* @throws ReflectionException
|
||||
* @throws TestIdMissingException
|
||||
* @throws UnintentionallyCoveredCodeException
|
||||
*/
|
||||
public function append(RawCodeCoverageData $rawData, $id = null, bool $append = true, $linesToBeCovered = [], array $linesToBeUsed = []): void
|
||||
{
|
||||
if ($id === null) {
|
||||
$id = $this->currentId;
|
||||
}
|
||||
|
||||
if ($id === null) {
|
||||
throw new TestIdMissingException;
|
||||
}
|
||||
|
||||
$this->applyFilter($rawData);
|
||||
|
||||
if ($this->useAnnotationsForIgnoringCode) {
|
||||
$this->applyIgnoredLinesFilter($rawData);
|
||||
}
|
||||
|
||||
$this->data->initializeUnseenData($rawData);
|
||||
|
||||
if (!$append) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($id !== self::UNCOVERED_FILES) {
|
||||
$this->applyCoversAnnotationFilter(
|
||||
$rawData,
|
||||
$linesToBeCovered,
|
||||
$linesToBeUsed
|
||||
);
|
||||
|
||||
if (empty($rawData->lineCoverage())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$size = 'unknown';
|
||||
$status = -1;
|
||||
$fromTestcase = false;
|
||||
|
||||
if ($id instanceof TestCase) {
|
||||
$fromTestcase = true;
|
||||
$_size = $id->getSize();
|
||||
|
||||
if ($_size === Test::SMALL) {
|
||||
$size = 'small';
|
||||
} elseif ($_size === Test::MEDIUM) {
|
||||
$size = 'medium';
|
||||
} elseif ($_size === Test::LARGE) {
|
||||
$size = 'large';
|
||||
}
|
||||
|
||||
$status = $id->getStatus();
|
||||
$id = get_class($id) . '::' . $id->getName();
|
||||
} elseif ($id instanceof PhptTestCase) {
|
||||
$fromTestcase = true;
|
||||
$size = 'large';
|
||||
$id = $id->getName();
|
||||
}
|
||||
|
||||
$this->tests[$id] = ['size' => $size, 'status' => $status, 'fromTestcase' => $fromTestcase];
|
||||
|
||||
$this->data->markCodeAsExecutedByTestCase($id, $rawData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the data from another instance.
|
||||
*/
|
||||
public function merge(self $that): void
|
||||
{
|
||||
$this->filter->includeFiles(
|
||||
$that->filter()->files()
|
||||
);
|
||||
|
||||
$this->data->merge($that->data);
|
||||
|
||||
$this->tests = array_merge($this->tests, $that->getTests());
|
||||
}
|
||||
|
||||
public function enableCheckForUnintentionallyCoveredCode(): void
|
||||
{
|
||||
$this->checkForUnintentionallyCoveredCode = true;
|
||||
}
|
||||
|
||||
public function disableCheckForUnintentionallyCoveredCode(): void
|
||||
{
|
||||
$this->checkForUnintentionallyCoveredCode = false;
|
||||
}
|
||||
|
||||
public function includeUncoveredFiles(): void
|
||||
{
|
||||
$this->includeUncoveredFiles = true;
|
||||
}
|
||||
|
||||
public function excludeUncoveredFiles(): void
|
||||
{
|
||||
$this->includeUncoveredFiles = false;
|
||||
}
|
||||
|
||||
public function processUncoveredFiles(): void
|
||||
{
|
||||
$this->processUncoveredFiles = true;
|
||||
}
|
||||
|
||||
public function doNotProcessUncoveredFiles(): void
|
||||
{
|
||||
$this->processUncoveredFiles = false;
|
||||
}
|
||||
|
||||
public function enableAnnotationsForIgnoringCode(): void
|
||||
{
|
||||
$this->useAnnotationsForIgnoringCode = true;
|
||||
}
|
||||
|
||||
public function disableAnnotationsForIgnoringCode(): void
|
||||
{
|
||||
$this->useAnnotationsForIgnoringCode = false;
|
||||
}
|
||||
|
||||
public function ignoreDeprecatedCode(): void
|
||||
{
|
||||
$this->ignoreDeprecatedCode = true;
|
||||
}
|
||||
|
||||
public function doNotIgnoreDeprecatedCode(): void
|
||||
{
|
||||
$this->ignoreDeprecatedCode = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-assert-if-true !null $this->cacheDirectory
|
||||
*/
|
||||
public function cachesStaticAnalysis(): bool
|
||||
{
|
||||
return $this->cacheDirectory !== null;
|
||||
}
|
||||
|
||||
public function cacheStaticAnalysis(string $directory): void
|
||||
{
|
||||
$this->cacheDirectory = $directory;
|
||||
}
|
||||
|
||||
public function doNotCacheStaticAnalysis(): void
|
||||
{
|
||||
$this->cacheDirectory = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws StaticAnalysisCacheNotConfiguredException
|
||||
*/
|
||||
public function cacheDirectory(): string
|
||||
{
|
||||
if (!$this->cachesStaticAnalysis()) {
|
||||
throw new StaticAnalysisCacheNotConfiguredException(
|
||||
'The static analysis cache is not configured'
|
||||
);
|
||||
}
|
||||
|
||||
return $this->cacheDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-param class-string $className
|
||||
*/
|
||||
public function excludeSubclassesOfThisClassFromUnintentionallyCoveredCodeCheck(string $className): void
|
||||
{
|
||||
$this->parentClassesExcludedFromUnintentionallyCoveredCodeCheck[] = $className;
|
||||
}
|
||||
|
||||
public function enableBranchAndPathCoverage(): void
|
||||
{
|
||||
$this->driver->enableBranchAndPathCoverage();
|
||||
}
|
||||
|
||||
public function disableBranchAndPathCoverage(): void
|
||||
{
|
||||
$this->driver->disableBranchAndPathCoverage();
|
||||
}
|
||||
|
||||
public function collectsBranchAndPathCoverage(): bool
|
||||
{
|
||||
return $this->driver->collectsBranchAndPathCoverage();
|
||||
}
|
||||
|
||||
public function detectsDeadCode(): bool
|
||||
{
|
||||
return $this->driver->detectsDeadCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the @covers annotation filtering.
|
||||
*
|
||||
* @param array|false $linesToBeCovered
|
||||
*
|
||||
* @throws ReflectionException
|
||||
* @throws UnintentionallyCoveredCodeException
|
||||
*/
|
||||
private function applyCoversAnnotationFilter(RawCodeCoverageData $rawData, $linesToBeCovered, array $linesToBeUsed): void
|
||||
{
|
||||
if ($linesToBeCovered === false) {
|
||||
$rawData->clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($linesToBeCovered)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->checkForUnintentionallyCoveredCode &&
|
||||
(!$this->currentId instanceof TestCase ||
|
||||
(!$this->currentId->isMedium() && !$this->currentId->isLarge()))) {
|
||||
$this->performUnintentionallyCoveredCodeCheck($rawData, $linesToBeCovered, $linesToBeUsed);
|
||||
}
|
||||
|
||||
$rawLineData = $rawData->lineCoverage();
|
||||
$filesWithNoCoverage = array_diff_key($rawLineData, $linesToBeCovered);
|
||||
|
||||
foreach (array_keys($filesWithNoCoverage) as $fileWithNoCoverage) {
|
||||
$rawData->removeCoverageDataForFile($fileWithNoCoverage);
|
||||
}
|
||||
|
||||
if (is_array($linesToBeCovered)) {
|
||||
foreach ($linesToBeCovered as $fileToBeCovered => $includedLines) {
|
||||
$rawData->keepCoverageDataOnlyForLines($fileToBeCovered, $includedLines);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function applyFilter(RawCodeCoverageData $data): void
|
||||
{
|
||||
if ($this->filter->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (array_keys($data->lineCoverage()) as $filename) {
|
||||
if ($this->filter->isExcluded($filename)) {
|
||||
$data->removeCoverageDataForFile($filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function applyIgnoredLinesFilter(RawCodeCoverageData $data): void
|
||||
{
|
||||
foreach (array_keys($data->lineCoverage()) as $filename) {
|
||||
if (!$this->filter->isFile($filename)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data->removeCoverageDataForLines(
|
||||
$filename,
|
||||
$this->coveredFileAnalyser()->ignoredLinesFor($filename)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws UnintentionallyCoveredCodeException
|
||||
*/
|
||||
private function addUncoveredFilesFromFilter(): void
|
||||
{
|
||||
$uncoveredFiles = array_diff(
|
||||
$this->filter->files(),
|
||||
$this->data->coveredFiles()
|
||||
);
|
||||
|
||||
foreach ($uncoveredFiles as $uncoveredFile) {
|
||||
if (is_file($uncoveredFile)) {
|
||||
$this->append(
|
||||
RawCodeCoverageData::fromUncoveredFile(
|
||||
$uncoveredFile,
|
||||
$this->uncoveredFileAnalyser()
|
||||
),
|
||||
self::UNCOVERED_FILES
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws UnintentionallyCoveredCodeException
|
||||
*/
|
||||
private function processUncoveredFilesFromFilter(): void
|
||||
{
|
||||
$uncoveredFiles = array_diff(
|
||||
$this->filter->files(),
|
||||
$this->data->coveredFiles()
|
||||
);
|
||||
|
||||
$this->driver->start();
|
||||
|
||||
foreach ($uncoveredFiles as $uncoveredFile) {
|
||||
if (is_file($uncoveredFile)) {
|
||||
include_once $uncoveredFile;
|
||||
}
|
||||
}
|
||||
|
||||
$this->append($this->driver->stop(), self::UNCOVERED_FILES);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ReflectionException
|
||||
* @throws UnintentionallyCoveredCodeException
|
||||
*/
|
||||
private function performUnintentionallyCoveredCodeCheck(RawCodeCoverageData $data, array $linesToBeCovered, array $linesToBeUsed): void
|
||||
{
|
||||
$allowedLines = $this->getAllowedLines(
|
||||
$linesToBeCovered,
|
||||
$linesToBeUsed
|
||||
);
|
||||
|
||||
$unintentionallyCoveredUnits = [];
|
||||
|
||||
foreach ($data->lineCoverage() as $file => $_data) {
|
||||
foreach ($_data as $line => $flag) {
|
||||
if ($flag === 1 && !isset($allowedLines[$file][$line])) {
|
||||
$unintentionallyCoveredUnits[] = $this->wizard->lookup($file, $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$unintentionallyCoveredUnits = $this->processUnintentionallyCoveredUnits($unintentionallyCoveredUnits);
|
||||
|
||||
if (!empty($unintentionallyCoveredUnits)) {
|
||||
throw new UnintentionallyCoveredCodeException(
|
||||
$unintentionallyCoveredUnits
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed): array
|
||||
{
|
||||
$allowedLines = [];
|
||||
|
||||
foreach (array_keys($linesToBeCovered) as $file) {
|
||||
if (!isset($allowedLines[$file])) {
|
||||
$allowedLines[$file] = [];
|
||||
}
|
||||
|
||||
$allowedLines[$file] = array_merge(
|
||||
$allowedLines[$file],
|
||||
$linesToBeCovered[$file]
|
||||
);
|
||||
}
|
||||
|
||||
foreach (array_keys($linesToBeUsed) as $file) {
|
||||
if (!isset($allowedLines[$file])) {
|
||||
$allowedLines[$file] = [];
|
||||
}
|
||||
|
||||
$allowedLines[$file] = array_merge(
|
||||
$allowedLines[$file],
|
||||
$linesToBeUsed[$file]
|
||||
);
|
||||
}
|
||||
|
||||
foreach (array_keys($allowedLines) as $file) {
|
||||
$allowedLines[$file] = array_flip(
|
||||
array_unique($allowedLines[$file])
|
||||
);
|
||||
}
|
||||
|
||||
return $allowedLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
private function processUnintentionallyCoveredUnits(array $unintentionallyCoveredUnits): array
|
||||
{
|
||||
$unintentionallyCoveredUnits = array_unique($unintentionallyCoveredUnits);
|
||||
sort($unintentionallyCoveredUnits);
|
||||
|
||||
foreach (array_keys($unintentionallyCoveredUnits) as $k => $v) {
|
||||
$unit = explode('::', $unintentionallyCoveredUnits[$k]);
|
||||
|
||||
if (count($unit) !== 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$class = new ReflectionClass($unit[0]);
|
||||
|
||||
foreach ($this->parentClassesExcludedFromUnintentionallyCoveredCodeCheck as $parentClass) {
|
||||
if ($class->isSubclassOf($parentClass)) {
|
||||
unset($unintentionallyCoveredUnits[$k]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (\ReflectionException $e) {
|
||||
throw new ReflectionException(
|
||||
$e->getMessage(),
|
||||
(int) $e->getCode(),
|
||||
$e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($unintentionallyCoveredUnits);
|
||||
}
|
||||
|
||||
private function coveredFileAnalyser(): CoveredFileAnalyser
|
||||
{
|
||||
if ($this->coveredFileAnalyser !== null) {
|
||||
return $this->coveredFileAnalyser;
|
||||
}
|
||||
|
||||
$this->coveredFileAnalyser = new ParsingCoveredFileAnalyser(
|
||||
$this->useAnnotationsForIgnoringCode,
|
||||
$this->ignoreDeprecatedCode
|
||||
);
|
||||
|
||||
if ($this->cachesStaticAnalysis()) {
|
||||
$this->coveredFileAnalyser = new CachingCoveredFileAnalyser(
|
||||
$this->cacheDirectory,
|
||||
$this->coveredFileAnalyser
|
||||
);
|
||||
}
|
||||
|
||||
return $this->coveredFileAnalyser;
|
||||
}
|
||||
|
||||
private function uncoveredFileAnalyser(): UncoveredFileAnalyser
|
||||
{
|
||||
if ($this->uncoveredFileAnalyser !== null) {
|
||||
return $this->uncoveredFileAnalyser;
|
||||
}
|
||||
|
||||
$this->uncoveredFileAnalyser = new ParsingUncoveredFileAnalyser;
|
||||
|
||||
if ($this->cachesStaticAnalysis()) {
|
||||
$this->uncoveredFileAnalyser = new CachingUncoveredFileAnalyser(
|
||||
$this->cacheDirectory,
|
||||
$this->uncoveredFileAnalyser
|
||||
);
|
||||
}
|
||||
|
||||
return $this->uncoveredFileAnalyser;
|
||||
}
|
||||
}
|
55
vendor/phpunit/php-code-coverage/src/CrapIndex.php
vendored
Normal file
55
vendor/phpunit/php-code-coverage/src/CrapIndex.php
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class CrapIndex
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $cyclomaticComplexity;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $codeCoverage;
|
||||
|
||||
public static function fromCyclomaticComplexityAndCoveragePercentage(int $cyclomaticComplexity, float $codeCoverage): self
|
||||
{
|
||||
return new self($cyclomaticComplexity, $codeCoverage);
|
||||
}
|
||||
|
||||
public function __construct(int $cyclomaticComplexity, float $codeCoverage)
|
||||
{
|
||||
$this->cyclomaticComplexity = $cyclomaticComplexity;
|
||||
$this->codeCoverage = $codeCoverage;
|
||||
}
|
||||
|
||||
public function asString(): string
|
||||
{
|
||||
if ($this->codeCoverage === 0.0) {
|
||||
return (string) ($this->cyclomaticComplexity ** 2 + $this->cyclomaticComplexity);
|
||||
}
|
||||
|
||||
if ($this->codeCoverage >= 95) {
|
||||
return (string) $this->cyclomaticComplexity;
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'%01.2F',
|
||||
$this->cyclomaticComplexity ** 2 * (1 - $this->codeCoverage / 100) ** 3 + $this->cyclomaticComplexity
|
||||
);
|
||||
}
|
||||
}
|
37
vendor/phpunit/php-code-coverage/src/Directory.php
vendored
Normal file
37
vendor/phpunit/php-code-coverage/src/Directory.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use function is_dir;
|
||||
use function mkdir;
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Directory
|
||||
{
|
||||
/**
|
||||
* @throws DirectoryCouldNotBeCreatedException
|
||||
*/
|
||||
public static function create(string $directory): void
|
||||
{
|
||||
$success = !(!is_dir($directory) && !@mkdir($directory, 0777, true) && !is_dir($directory));
|
||||
|
||||
if (!$success) {
|
||||
throw new DirectoryCouldNotBeCreatedException(
|
||||
sprintf(
|
||||
'Directory "%s" could not be created',
|
||||
$directory
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
167
vendor/phpunit/php-code-coverage/src/Driver/Driver.php
vendored
Normal file
167
vendor/phpunit/php-code-coverage/src/Driver/Driver.php
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use function sprintf;
|
||||
use SebastianBergmann\CodeCoverage\BranchAndPathCoverageNotSupportedException;
|
||||
use SebastianBergmann\CodeCoverage\DeadCodeDetectionNotSupportedException;
|
||||
use SebastianBergmann\CodeCoverage\Filter;
|
||||
use SebastianBergmann\CodeCoverage\NoCodeCoverageDriverAvailableException;
|
||||
use SebastianBergmann\CodeCoverage\NoCodeCoverageDriverWithPathCoverageSupportAvailableException;
|
||||
use SebastianBergmann\CodeCoverage\RawCodeCoverageData;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
abstract class Driver
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @see http://xdebug.org/docs/code_coverage
|
||||
*/
|
||||
public const LINE_NOT_EXECUTABLE = -2;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @see http://xdebug.org/docs/code_coverage
|
||||
*/
|
||||
public const LINE_NOT_EXECUTED = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @see http://xdebug.org/docs/code_coverage
|
||||
*/
|
||||
public const LINE_EXECUTED = 1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @see http://xdebug.org/docs/code_coverage
|
||||
*/
|
||||
public const BRANCH_NOT_HIT = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @see http://xdebug.org/docs/code_coverage
|
||||
*/
|
||||
public const BRANCH_HIT = 1;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $collectBranchAndPathCoverage = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $detectDeadCode = false;
|
||||
|
||||
/**
|
||||
* @throws NoCodeCoverageDriverAvailableException
|
||||
* @throws PcovNotAvailableException
|
||||
* @throws PhpdbgNotAvailableException
|
||||
* @throws Xdebug2NotEnabledException
|
||||
* @throws Xdebug3NotEnabledException
|
||||
* @throws XdebugNotAvailableException
|
||||
*
|
||||
* @deprecated Use DriverSelector::forLineCoverage() instead
|
||||
*/
|
||||
public static function forLineCoverage(Filter $filter): self
|
||||
{
|
||||
return (new Selector)->forLineCoverage($filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NoCodeCoverageDriverWithPathCoverageSupportAvailableException
|
||||
* @throws Xdebug2NotEnabledException
|
||||
* @throws Xdebug3NotEnabledException
|
||||
* @throws XdebugNotAvailableException
|
||||
*
|
||||
* @deprecated Use DriverSelector::forLineAndPathCoverage() instead
|
||||
*/
|
||||
public static function forLineAndPathCoverage(Filter $filter): self
|
||||
{
|
||||
return (new Selector)->forLineAndPathCoverage($filter);
|
||||
}
|
||||
|
||||
public function canCollectBranchAndPathCoverage(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function collectsBranchAndPathCoverage(): bool
|
||||
{
|
||||
return $this->collectBranchAndPathCoverage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws BranchAndPathCoverageNotSupportedException
|
||||
*/
|
||||
public function enableBranchAndPathCoverage(): void
|
||||
{
|
||||
if (!$this->canCollectBranchAndPathCoverage()) {
|
||||
throw new BranchAndPathCoverageNotSupportedException(
|
||||
sprintf(
|
||||
'%s does not support branch and path coverage',
|
||||
$this->nameAndVersion()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->collectBranchAndPathCoverage = true;
|
||||
}
|
||||
|
||||
public function disableBranchAndPathCoverage(): void
|
||||
{
|
||||
$this->collectBranchAndPathCoverage = false;
|
||||
}
|
||||
|
||||
public function canDetectDeadCode(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function detectsDeadCode(): bool
|
||||
{
|
||||
return $this->detectDeadCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DeadCodeDetectionNotSupportedException
|
||||
*/
|
||||
public function enableDeadCodeDetection(): void
|
||||
{
|
||||
if (!$this->canDetectDeadCode()) {
|
||||
throw new DeadCodeDetectionNotSupportedException(
|
||||
sprintf(
|
||||
'%s does not support dead code detection',
|
||||
$this->nameAndVersion()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->detectDeadCode = true;
|
||||
}
|
||||
|
||||
public function disableDeadCodeDetection(): void
|
||||
{
|
||||
$this->detectDeadCode = false;
|
||||
}
|
||||
|
||||
abstract public function nameAndVersion(): string;
|
||||
|
||||
abstract public function start(): void;
|
||||
|
||||
abstract public function stop(): RawCodeCoverageData;
|
||||
}
|
75
vendor/phpunit/php-code-coverage/src/Driver/PcovDriver.php
vendored
Normal file
75
vendor/phpunit/php-code-coverage/src/Driver/PcovDriver.php
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use const pcov\inclusive;
|
||||
use function array_intersect;
|
||||
use function extension_loaded;
|
||||
use function pcov\clear;
|
||||
use function pcov\collect;
|
||||
use function pcov\start;
|
||||
use function pcov\stop;
|
||||
use function pcov\waiting;
|
||||
use function phpversion;
|
||||
use SebastianBergmann\CodeCoverage\Filter;
|
||||
use SebastianBergmann\CodeCoverage\RawCodeCoverageData;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class PcovDriver extends Driver
|
||||
{
|
||||
/**
|
||||
* @var Filter
|
||||
*/
|
||||
private $filter;
|
||||
|
||||
/**
|
||||
* @throws PcovNotAvailableException
|
||||
*/
|
||||
public function __construct(Filter $filter)
|
||||
{
|
||||
if (!extension_loaded('pcov')) {
|
||||
throw new PcovNotAvailableException;
|
||||
}
|
||||
|
||||
$this->filter = $filter;
|
||||
}
|
||||
|
||||
public function start(): void
|
||||
{
|
||||
start();
|
||||
}
|
||||
|
||||
public function stop(): RawCodeCoverageData
|
||||
{
|
||||
stop();
|
||||
|
||||
$filesToCollectCoverageFor = waiting();
|
||||
$collected = [];
|
||||
|
||||
if ($filesToCollectCoverageFor) {
|
||||
if (!$this->filter->isEmpty()) {
|
||||
$filesToCollectCoverageFor = array_intersect($filesToCollectCoverageFor, $this->filter->files());
|
||||
}
|
||||
|
||||
$collected = collect(inclusive, $filesToCollectCoverageFor);
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
return RawCodeCoverageData::fromXdebugWithoutPathCoverage($collected);
|
||||
}
|
||||
|
||||
public function nameAndVersion(): string
|
||||
{
|
||||
return 'PCOV ' . phpversion('pcov');
|
||||
}
|
||||
}
|
93
vendor/phpunit/php-code-coverage/src/Driver/PhpdbgDriver.php
vendored
Normal file
93
vendor/phpunit/php-code-coverage/src/Driver/PhpdbgDriver.php
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use const PHP_SAPI;
|
||||
use const PHP_VERSION;
|
||||
use function array_diff;
|
||||
use function array_keys;
|
||||
use function array_merge;
|
||||
use function get_included_files;
|
||||
use function phpdbg_end_oplog;
|
||||
use function phpdbg_get_executable;
|
||||
use function phpdbg_start_oplog;
|
||||
use SebastianBergmann\CodeCoverage\RawCodeCoverageData;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class PhpdbgDriver extends Driver
|
||||
{
|
||||
/**
|
||||
* @throws PhpdbgNotAvailableException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (PHP_SAPI !== 'phpdbg') {
|
||||
throw new PhpdbgNotAvailableException;
|
||||
}
|
||||
}
|
||||
|
||||
public function start(): void
|
||||
{
|
||||
phpdbg_start_oplog();
|
||||
}
|
||||
|
||||
public function stop(): RawCodeCoverageData
|
||||
{
|
||||
static $fetchedLines = [];
|
||||
|
||||
$dbgData = phpdbg_end_oplog();
|
||||
|
||||
if ($fetchedLines === []) {
|
||||
$sourceLines = phpdbg_get_executable();
|
||||
} else {
|
||||
$newFiles = array_diff(get_included_files(), array_keys($fetchedLines));
|
||||
|
||||
$sourceLines = [];
|
||||
|
||||
if ($newFiles) {
|
||||
$sourceLines = phpdbg_get_executable(['files' => $newFiles]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($sourceLines as $file => $lines) {
|
||||
foreach ($lines as $lineNo => $numExecuted) {
|
||||
$sourceLines[$file][$lineNo] = self::LINE_NOT_EXECUTED;
|
||||
}
|
||||
}
|
||||
|
||||
$fetchedLines = array_merge($fetchedLines, $sourceLines);
|
||||
|
||||
return RawCodeCoverageData::fromXdebugWithoutPathCoverage(
|
||||
$this->detectExecutedLines($fetchedLines, $dbgData)
|
||||
);
|
||||
}
|
||||
|
||||
public function nameAndVersion(): string
|
||||
{
|
||||
return 'PHPDBG ' . PHP_VERSION;
|
||||
}
|
||||
|
||||
private function detectExecutedLines(array $sourceLines, array $dbgData): array
|
||||
{
|
||||
foreach ($dbgData as $file => $coveredLines) {
|
||||
foreach ($coveredLines as $lineNo => $numExecuted) {
|
||||
// phpdbg also reports $lineNo=0 when e.g. exceptions get thrown.
|
||||
// make sure we only mark lines executed which are actually executable.
|
||||
if (isset($sourceLines[$file][$lineNo])) {
|
||||
$sourceLines[$file][$lineNo] = self::LINE_EXECUTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sourceLines;
|
||||
}
|
||||
}
|
79
vendor/phpunit/php-code-coverage/src/Driver/Selector.php
vendored
Normal file
79
vendor/phpunit/php-code-coverage/src/Driver/Selector.php
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use function phpversion;
|
||||
use function version_compare;
|
||||
use SebastianBergmann\CodeCoverage\Filter;
|
||||
use SebastianBergmann\CodeCoverage\NoCodeCoverageDriverAvailableException;
|
||||
use SebastianBergmann\CodeCoverage\NoCodeCoverageDriverWithPathCoverageSupportAvailableException;
|
||||
use SebastianBergmann\Environment\Runtime;
|
||||
|
||||
final class Selector
|
||||
{
|
||||
/**
|
||||
* @throws NoCodeCoverageDriverAvailableException
|
||||
* @throws PcovNotAvailableException
|
||||
* @throws PhpdbgNotAvailableException
|
||||
* @throws Xdebug2NotEnabledException
|
||||
* @throws Xdebug3NotEnabledException
|
||||
* @throws XdebugNotAvailableException
|
||||
*/
|
||||
public function forLineCoverage(Filter $filter): Driver
|
||||
{
|
||||
$runtime = new Runtime;
|
||||
|
||||
if ($runtime->hasPHPDBGCodeCoverage()) {
|
||||
return new PhpdbgDriver;
|
||||
}
|
||||
|
||||
if ($runtime->hasPCOV()) {
|
||||
return new PcovDriver($filter);
|
||||
}
|
||||
|
||||
if ($runtime->hasXdebug()) {
|
||||
if (version_compare(phpversion('xdebug'), '3', '>=')) {
|
||||
$driver = new Xdebug3Driver($filter);
|
||||
} else {
|
||||
$driver = new Xdebug2Driver($filter);
|
||||
}
|
||||
|
||||
$driver->enableDeadCodeDetection();
|
||||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
throw new NoCodeCoverageDriverAvailableException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NoCodeCoverageDriverWithPathCoverageSupportAvailableException
|
||||
* @throws Xdebug2NotEnabledException
|
||||
* @throws Xdebug3NotEnabledException
|
||||
* @throws XdebugNotAvailableException
|
||||
*/
|
||||
public function forLineAndPathCoverage(Filter $filter): Driver
|
||||
{
|
||||
if ((new Runtime)->hasXdebug()) {
|
||||
if (version_compare(phpversion('xdebug'), '3', '>=')) {
|
||||
$driver = new Xdebug3Driver($filter);
|
||||
} else {
|
||||
$driver = new Xdebug2Driver($filter);
|
||||
}
|
||||
|
||||
$driver->enableDeadCodeDetection();
|
||||
$driver->enableBranchAndPathCoverage();
|
||||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
throw new NoCodeCoverageDriverWithPathCoverageSupportAvailableException;
|
||||
}
|
||||
}
|
128
vendor/phpunit/php-code-coverage/src/Driver/Xdebug2Driver.php
vendored
Normal file
128
vendor/phpunit/php-code-coverage/src/Driver/Xdebug2Driver.php
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use const XDEBUG_CC_BRANCH_CHECK;
|
||||
use const XDEBUG_CC_DEAD_CODE;
|
||||
use const XDEBUG_CC_UNUSED;
|
||||
use const XDEBUG_FILTER_CODE_COVERAGE;
|
||||
use const XDEBUG_PATH_INCLUDE;
|
||||
use const XDEBUG_PATH_WHITELIST;
|
||||
use function defined;
|
||||
use function extension_loaded;
|
||||
use function ini_get;
|
||||
use function phpversion;
|
||||
use function sprintf;
|
||||
use function version_compare;
|
||||
use function xdebug_get_code_coverage;
|
||||
use function xdebug_set_filter;
|
||||
use function xdebug_start_code_coverage;
|
||||
use function xdebug_stop_code_coverage;
|
||||
use SebastianBergmann\CodeCoverage\Filter;
|
||||
use SebastianBergmann\CodeCoverage\RawCodeCoverageData;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Xdebug2Driver extends Driver
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $pathCoverageIsMixedCoverage;
|
||||
|
||||
/**
|
||||
* @throws WrongXdebugVersionException
|
||||
* @throws Xdebug2NotEnabledException
|
||||
* @throws XdebugNotAvailableException
|
||||
*/
|
||||
public function __construct(Filter $filter)
|
||||
{
|
||||
if (!extension_loaded('xdebug')) {
|
||||
throw new XdebugNotAvailableException;
|
||||
}
|
||||
|
||||
if (version_compare(phpversion('xdebug'), '3', '>=')) {
|
||||
throw new WrongXdebugVersionException(
|
||||
sprintf(
|
||||
'This driver requires Xdebug 2 but version %s is loaded',
|
||||
phpversion('xdebug')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!ini_get('xdebug.coverage_enable')) {
|
||||
throw new Xdebug2NotEnabledException;
|
||||
}
|
||||
|
||||
if (!$filter->isEmpty()) {
|
||||
if (defined('XDEBUG_PATH_WHITELIST')) {
|
||||
$listType = XDEBUG_PATH_WHITELIST;
|
||||
} else {
|
||||
$listType = XDEBUG_PATH_INCLUDE;
|
||||
}
|
||||
|
||||
xdebug_set_filter(
|
||||
XDEBUG_FILTER_CODE_COVERAGE,
|
||||
$listType,
|
||||
$filter->files()
|
||||
);
|
||||
}
|
||||
|
||||
$this->pathCoverageIsMixedCoverage = version_compare(phpversion('xdebug'), '2.9.6', '<');
|
||||
}
|
||||
|
||||
public function canCollectBranchAndPathCoverage(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canDetectDeadCode(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function start(): void
|
||||
{
|
||||
$flags = XDEBUG_CC_UNUSED;
|
||||
|
||||
if ($this->detectsDeadCode() || $this->collectsBranchAndPathCoverage()) {
|
||||
$flags |= XDEBUG_CC_DEAD_CODE;
|
||||
}
|
||||
|
||||
if ($this->collectsBranchAndPathCoverage()) {
|
||||
$flags |= XDEBUG_CC_BRANCH_CHECK;
|
||||
}
|
||||
|
||||
xdebug_start_code_coverage($flags);
|
||||
}
|
||||
|
||||
public function stop(): RawCodeCoverageData
|
||||
{
|
||||
$data = xdebug_get_code_coverage();
|
||||
|
||||
xdebug_stop_code_coverage();
|
||||
|
||||
if ($this->collectsBranchAndPathCoverage()) {
|
||||
if ($this->pathCoverageIsMixedCoverage) {
|
||||
return RawCodeCoverageData::fromXdebugWithMixedCoverage($data);
|
||||
}
|
||||
|
||||
return RawCodeCoverageData::fromXdebugWithPathCoverage($data);
|
||||
}
|
||||
|
||||
return RawCodeCoverageData::fromXdebugWithoutPathCoverage($data);
|
||||
}
|
||||
|
||||
public function nameAndVersion(): string
|
||||
{
|
||||
return 'Xdebug ' . phpversion('xdebug');
|
||||
}
|
||||
}
|
119
vendor/phpunit/php-code-coverage/src/Driver/Xdebug3Driver.php
vendored
Normal file
119
vendor/phpunit/php-code-coverage/src/Driver/Xdebug3Driver.php
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use const XDEBUG_CC_BRANCH_CHECK;
|
||||
use const XDEBUG_CC_DEAD_CODE;
|
||||
use const XDEBUG_CC_UNUSED;
|
||||
use const XDEBUG_FILTER_CODE_COVERAGE;
|
||||
use const XDEBUG_PATH_INCLUDE;
|
||||
use function explode;
|
||||
use function extension_loaded;
|
||||
use function getenv;
|
||||
use function in_array;
|
||||
use function ini_get;
|
||||
use function phpversion;
|
||||
use function sprintf;
|
||||
use function version_compare;
|
||||
use function xdebug_get_code_coverage;
|
||||
use function xdebug_set_filter;
|
||||
use function xdebug_start_code_coverage;
|
||||
use function xdebug_stop_code_coverage;
|
||||
use SebastianBergmann\CodeCoverage\Filter;
|
||||
use SebastianBergmann\CodeCoverage\RawCodeCoverageData;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Xdebug3Driver extends Driver
|
||||
{
|
||||
/**
|
||||
* @throws WrongXdebugVersionException
|
||||
* @throws Xdebug3NotEnabledException
|
||||
* @throws XdebugNotAvailableException
|
||||
*/
|
||||
public function __construct(Filter $filter)
|
||||
{
|
||||
if (!extension_loaded('xdebug')) {
|
||||
throw new XdebugNotAvailableException;
|
||||
}
|
||||
|
||||
if (version_compare(phpversion('xdebug'), '3', '<')) {
|
||||
throw new WrongXdebugVersionException(
|
||||
sprintf(
|
||||
'This driver requires Xdebug 3 but version %s is loaded',
|
||||
phpversion('xdebug')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$mode = getenv('XDEBUG_MODE');
|
||||
|
||||
if ($mode === false || $mode === '') {
|
||||
$mode = ini_get('xdebug.mode');
|
||||
}
|
||||
|
||||
if ($mode === false ||
|
||||
!in_array('coverage', explode(',', $mode), true)) {
|
||||
throw new Xdebug3NotEnabledException;
|
||||
}
|
||||
|
||||
if (!$filter->isEmpty()) {
|
||||
xdebug_set_filter(
|
||||
XDEBUG_FILTER_CODE_COVERAGE,
|
||||
XDEBUG_PATH_INCLUDE,
|
||||
$filter->files()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function canCollectBranchAndPathCoverage(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canDetectDeadCode(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function start(): void
|
||||
{
|
||||
$flags = XDEBUG_CC_UNUSED;
|
||||
|
||||
if ($this->detectsDeadCode() || $this->collectsBranchAndPathCoverage()) {
|
||||
$flags |= XDEBUG_CC_DEAD_CODE;
|
||||
}
|
||||
|
||||
if ($this->collectsBranchAndPathCoverage()) {
|
||||
$flags |= XDEBUG_CC_BRANCH_CHECK;
|
||||
}
|
||||
|
||||
xdebug_start_code_coverage($flags);
|
||||
}
|
||||
|
||||
public function stop(): RawCodeCoverageData
|
||||
{
|
||||
$data = xdebug_get_code_coverage();
|
||||
|
||||
xdebug_stop_code_coverage();
|
||||
|
||||
if ($this->collectsBranchAndPathCoverage()) {
|
||||
return RawCodeCoverageData::fromXdebugWithPathCoverage($data);
|
||||
}
|
||||
|
||||
return RawCodeCoverageData::fromXdebugWithoutPathCoverage($data);
|
||||
}
|
||||
|
||||
public function nameAndVersion(): string
|
||||
{
|
||||
return 'Xdebug ' . phpversion('xdebug');
|
||||
}
|
||||
}
|
16
vendor/phpunit/php-code-coverage/src/Exception/BranchAndPathCoverageNotSupportedException.php
vendored
Normal file
16
vendor/phpunit/php-code-coverage/src/Exception/BranchAndPathCoverageNotSupportedException.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class BranchAndPathCoverageNotSupportedException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
16
vendor/phpunit/php-code-coverage/src/Exception/DeadCodeDetectionNotSupportedException.php
vendored
Normal file
16
vendor/phpunit/php-code-coverage/src/Exception/DeadCodeDetectionNotSupportedException.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class DeadCodeDetectionNotSupportedException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
16
vendor/phpunit/php-code-coverage/src/Exception/DirectoryCouldNotBeCreatedException.php
vendored
Normal file
16
vendor/phpunit/php-code-coverage/src/Exception/DirectoryCouldNotBeCreatedException.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class DirectoryCouldNotBeCreatedException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
16
vendor/phpunit/php-code-coverage/src/Exception/Exception.php
vendored
Normal file
16
vendor/phpunit/php-code-coverage/src/Exception/Exception.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use Throwable;
|
||||
|
||||
interface Exception extends Throwable
|
||||
{
|
||||
}
|
14
vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php
vendored
Normal file
14
vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
final class InvalidArgumentException extends \InvalidArgumentException implements Exception
|
||||
{
|
||||
}
|
20
vendor/phpunit/php-code-coverage/src/Exception/NoCodeCoverageDriverAvailableException.php
vendored
Normal file
20
vendor/phpunit/php-code-coverage/src/Exception/NoCodeCoverageDriverAvailableException.php
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class NoCodeCoverageDriverAvailableException extends RuntimeException implements Exception
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('No code coverage driver available');
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class NoCodeCoverageDriverWithPathCoverageSupportAvailableException extends RuntimeException implements Exception
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('No code coverage driver with path coverage support available');
|
||||
}
|
||||
}
|
16
vendor/phpunit/php-code-coverage/src/Exception/ParserException.php
vendored
Normal file
16
vendor/phpunit/php-code-coverage/src/Exception/ParserException.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class ParserException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
22
vendor/phpunit/php-code-coverage/src/Exception/PathExistsButIsNotDirectoryException.php
vendored
Normal file
22
vendor/phpunit/php-code-coverage/src/Exception/PathExistsButIsNotDirectoryException.php
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use function sprintf;
|
||||
use RuntimeException;
|
||||
use SebastianBergmann\CodeCoverage\Exception;
|
||||
|
||||
final class PathExistsButIsNotDirectoryException extends RuntimeException implements Exception
|
||||
{
|
||||
public function __construct(string $path)
|
||||
{
|
||||
parent::__construct(sprintf('"%s" exists but is not a directory', $path));
|
||||
}
|
||||
}
|
21
vendor/phpunit/php-code-coverage/src/Exception/PcovNotAvailableException.php
vendored
Normal file
21
vendor/phpunit/php-code-coverage/src/Exception/PcovNotAvailableException.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use RuntimeException;
|
||||
use SebastianBergmann\CodeCoverage\Exception;
|
||||
|
||||
final class PcovNotAvailableException extends RuntimeException implements Exception
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('The PCOV extension is not available');
|
||||
}
|
||||
}
|
21
vendor/phpunit/php-code-coverage/src/Exception/PhpdbgNotAvailableException.php
vendored
Normal file
21
vendor/phpunit/php-code-coverage/src/Exception/PhpdbgNotAvailableException.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use RuntimeException;
|
||||
use SebastianBergmann\CodeCoverage\Exception;
|
||||
|
||||
final class PhpdbgNotAvailableException extends RuntimeException implements Exception
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('The PHPDBG SAPI is not available');
|
||||
}
|
||||
}
|
16
vendor/phpunit/php-code-coverage/src/Exception/ReflectionException.php
vendored
Normal file
16
vendor/phpunit/php-code-coverage/src/Exception/ReflectionException.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class ReflectionException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
20
vendor/phpunit/php-code-coverage/src/Exception/ReportAlreadyFinalizedException.php
vendored
Normal file
20
vendor/phpunit/php-code-coverage/src/Exception/ReportAlreadyFinalizedException.php
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class ReportAlreadyFinalizedException extends RuntimeException implements Exception
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('The code coverage report has already been finalized');
|
||||
}
|
||||
}
|
16
vendor/phpunit/php-code-coverage/src/Exception/StaticAnalysisCacheNotConfiguredException.php
vendored
Normal file
16
vendor/phpunit/php-code-coverage/src/Exception/StaticAnalysisCacheNotConfiguredException.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class StaticAnalysisCacheNotConfiguredException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
20
vendor/phpunit/php-code-coverage/src/Exception/TestIdMissingException.php
vendored
Normal file
20
vendor/phpunit/php-code-coverage/src/Exception/TestIdMissingException.php
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class TestIdMissingException extends RuntimeException implements Exception
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('Test ID is missing');
|
||||
}
|
||||
}
|
43
vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php
vendored
Normal file
43
vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class UnintentionallyCoveredCodeException extends RuntimeException implements Exception
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $unintentionallyCoveredUnits;
|
||||
|
||||
public function __construct(array $unintentionallyCoveredUnits)
|
||||
{
|
||||
$this->unintentionallyCoveredUnits = $unintentionallyCoveredUnits;
|
||||
|
||||
parent::__construct($this->toString());
|
||||
}
|
||||
|
||||
public function getUnintentionallyCoveredUnits(): array
|
||||
{
|
||||
return $this->unintentionallyCoveredUnits;
|
||||
}
|
||||
|
||||
private function toString(): string
|
||||
{
|
||||
$message = '';
|
||||
|
||||
foreach ($this->unintentionallyCoveredUnits as $unit) {
|
||||
$message .= '- ' . $unit . "\n";
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
22
vendor/phpunit/php-code-coverage/src/Exception/WriteOperationFailedException.php
vendored
Normal file
22
vendor/phpunit/php-code-coverage/src/Exception/WriteOperationFailedException.php
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use function sprintf;
|
||||
use RuntimeException;
|
||||
use SebastianBergmann\CodeCoverage\Exception;
|
||||
|
||||
final class WriteOperationFailedException extends RuntimeException implements Exception
|
||||
{
|
||||
public function __construct(string $path)
|
||||
{
|
||||
parent::__construct(sprintf('Cannot write to "%s"', $path));
|
||||
}
|
||||
}
|
17
vendor/phpunit/php-code-coverage/src/Exception/WrongXdebugVersionException.php
vendored
Normal file
17
vendor/phpunit/php-code-coverage/src/Exception/WrongXdebugVersionException.php
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use RuntimeException;
|
||||
use SebastianBergmann\CodeCoverage\Exception;
|
||||
|
||||
final class WrongXdebugVersionException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
21
vendor/phpunit/php-code-coverage/src/Exception/Xdebug2NotEnabledException.php
vendored
Normal file
21
vendor/phpunit/php-code-coverage/src/Exception/Xdebug2NotEnabledException.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use RuntimeException;
|
||||
use SebastianBergmann\CodeCoverage\Exception;
|
||||
|
||||
final class Xdebug2NotEnabledException extends RuntimeException implements Exception
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('xdebug.coverage_enable=On has to be set');
|
||||
}
|
||||
}
|
21
vendor/phpunit/php-code-coverage/src/Exception/Xdebug3NotEnabledException.php
vendored
Normal file
21
vendor/phpunit/php-code-coverage/src/Exception/Xdebug3NotEnabledException.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use RuntimeException;
|
||||
use SebastianBergmann\CodeCoverage\Exception;
|
||||
|
||||
final class Xdebug3NotEnabledException extends RuntimeException implements Exception
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('XDEBUG_MODE=coverage or xdebug.mode=coverage has to be set');
|
||||
}
|
||||
}
|
21
vendor/phpunit/php-code-coverage/src/Exception/XdebugNotAvailableException.php
vendored
Normal file
21
vendor/phpunit/php-code-coverage/src/Exception/XdebugNotAvailableException.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Driver;
|
||||
|
||||
use RuntimeException;
|
||||
use SebastianBergmann\CodeCoverage\Exception;
|
||||
|
||||
final class XdebugNotAvailableException extends RuntimeException implements Exception
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('The Xdebug extension is not available');
|
||||
}
|
||||
}
|
16
vendor/phpunit/php-code-coverage/src/Exception/XmlException.php
vendored
Normal file
16
vendor/phpunit/php-code-coverage/src/Exception/XmlException.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class XmlException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
122
vendor/phpunit/php-code-coverage/src/Filter.php
vendored
Normal file
122
vendor/phpunit/php-code-coverage/src/Filter.php
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use function array_keys;
|
||||
use function is_file;
|
||||
use function realpath;
|
||||
use function strpos;
|
||||
use SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
|
||||
|
||||
final class Filter
|
||||
{
|
||||
/**
|
||||
* @psalm-var array<string,true>
|
||||
*/
|
||||
private $files = [];
|
||||
|
||||
/**
|
||||
* @psalm-var array<string,bool>
|
||||
*/
|
||||
private $isFileCache = [];
|
||||
|
||||
public function includeDirectory(string $directory, string $suffix = '.php', string $prefix = ''): void
|
||||
{
|
||||
foreach ((new FileIteratorFacade)->getFilesAsArray($directory, $suffix, $prefix) as $file) {
|
||||
$this->includeFile($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-param list<string> $files
|
||||
*/
|
||||
public function includeFiles(array $filenames): void
|
||||
{
|
||||
foreach ($filenames as $filename) {
|
||||
$this->includeFile($filename);
|
||||
}
|
||||
}
|
||||
|
||||
public function includeFile(string $filename): void
|
||||
{
|
||||
$filename = realpath($filename);
|
||||
|
||||
if (!$filename) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->files[$filename] = true;
|
||||
}
|
||||
|
||||
public function excludeDirectory(string $directory, string $suffix = '.php', string $prefix = ''): void
|
||||
{
|
||||
foreach ((new FileIteratorFacade)->getFilesAsArray($directory, $suffix, $prefix) as $file) {
|
||||
$this->excludeFile($file);
|
||||
}
|
||||
}
|
||||
|
||||
public function excludeFile(string $filename): void
|
||||
{
|
||||
$filename = realpath($filename);
|
||||
|
||||
if (!$filename || !isset($this->files[$filename])) {
|
||||
return;
|
||||
}
|
||||
|
||||
unset($this->files[$filename]);
|
||||
}
|
||||
|
||||
public function isFile(string $filename): bool
|
||||
{
|
||||
if (isset($this->isFileCache[$filename])) {
|
||||
return $this->isFileCache[$filename];
|
||||
}
|
||||
|
||||
if ($filename === '-' ||
|
||||
strpos($filename, 'vfs://') === 0 ||
|
||||
strpos($filename, 'xdebug://debug-eval') !== false ||
|
||||
strpos($filename, 'eval()\'d code') !== false ||
|
||||
strpos($filename, 'runtime-created function') !== false ||
|
||||
strpos($filename, 'runkit created function') !== false ||
|
||||
strpos($filename, 'assert code') !== false ||
|
||||
strpos($filename, 'regexp code') !== false ||
|
||||
strpos($filename, 'Standard input code') !== false) {
|
||||
$isFile = false;
|
||||
} else {
|
||||
$isFile = is_file($filename);
|
||||
}
|
||||
|
||||
$this->isFileCache[$filename] = $isFile;
|
||||
|
||||
return $isFile;
|
||||
}
|
||||
|
||||
public function isExcluded(string $filename): bool
|
||||
{
|
||||
if (!$this->isFile($filename)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !isset($this->files[$filename]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public function files(): array
|
||||
{
|
||||
return array_keys($this->files);
|
||||
}
|
||||
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->files);
|
||||
}
|
||||
}
|
251
vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php
vendored
Normal file
251
vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Node;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use function array_merge;
|
||||
use function str_replace;
|
||||
use function substr;
|
||||
use Countable;
|
||||
use SebastianBergmann\CodeCoverage\Percentage;
|
||||
use SebastianBergmann\LinesOfCode\LinesOfCode;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
abstract class AbstractNode implements Countable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $pathAsString;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $pathAsArray;
|
||||
|
||||
/**
|
||||
* @var AbstractNode
|
||||
*/
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $id;
|
||||
|
||||
public function __construct(string $name, self $parent = null)
|
||||
{
|
||||
if (substr($name, -1) === DIRECTORY_SEPARATOR) {
|
||||
$name = substr($name, 0, -1);
|
||||
}
|
||||
|
||||
$this->name = $name;
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
public function name(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function id(): string
|
||||
{
|
||||
if ($this->id === null) {
|
||||
$parent = $this->parent();
|
||||
|
||||
if ($parent === null) {
|
||||
$this->id = 'index';
|
||||
} else {
|
||||
$parentId = $parent->id();
|
||||
|
||||
if ($parentId === 'index') {
|
||||
$this->id = str_replace(':', '_', $this->name);
|
||||
} else {
|
||||
$this->id = $parentId . '/' . $this->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function pathAsString(): string
|
||||
{
|
||||
if ($this->pathAsString === null) {
|
||||
if ($this->parent === null) {
|
||||
$this->pathAsString = $this->name;
|
||||
} else {
|
||||
$this->pathAsString = $this->parent->pathAsString() . DIRECTORY_SEPARATOR . $this->name;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->pathAsString;
|
||||
}
|
||||
|
||||
public function pathAsArray(): array
|
||||
{
|
||||
if ($this->pathAsArray === null) {
|
||||
if ($this->parent === null) {
|
||||
$this->pathAsArray = [];
|
||||
} else {
|
||||
$this->pathAsArray = $this->parent->pathAsArray();
|
||||
}
|
||||
|
||||
$this->pathAsArray[] = $this;
|
||||
}
|
||||
|
||||
return $this->pathAsArray;
|
||||
}
|
||||
|
||||
public function parent(): ?self
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
public function percentageOfTestedClasses(): Percentage
|
||||
{
|
||||
return Percentage::fromFractionAndTotal(
|
||||
$this->numberOfTestedClasses(),
|
||||
$this->numberOfClasses(),
|
||||
);
|
||||
}
|
||||
|
||||
public function percentageOfTestedTraits(): Percentage
|
||||
{
|
||||
return Percentage::fromFractionAndTotal(
|
||||
$this->numberOfTestedTraits(),
|
||||
$this->numberOfTraits(),
|
||||
);
|
||||
}
|
||||
|
||||
public function percentageOfTestedClassesAndTraits(): Percentage
|
||||
{
|
||||
return Percentage::fromFractionAndTotal(
|
||||
$this->numberOfTestedClassesAndTraits(),
|
||||
$this->numberOfClassesAndTraits(),
|
||||
);
|
||||
}
|
||||
|
||||
public function percentageOfTestedFunctions(): Percentage
|
||||
{
|
||||
return Percentage::fromFractionAndTotal(
|
||||
$this->numberOfTestedFunctions(),
|
||||
$this->numberOfFunctions(),
|
||||
);
|
||||
}
|
||||
|
||||
public function percentageOfTestedMethods(): Percentage
|
||||
{
|
||||
return Percentage::fromFractionAndTotal(
|
||||
$this->numberOfTestedMethods(),
|
||||
$this->numberOfMethods(),
|
||||
);
|
||||
}
|
||||
|
||||
public function percentageOfTestedFunctionsAndMethods(): Percentage
|
||||
{
|
||||
return Percentage::fromFractionAndTotal(
|
||||
$this->numberOfTestedFunctionsAndMethods(),
|
||||
$this->numberOfFunctionsAndMethods(),
|
||||
);
|
||||
}
|
||||
|
||||
public function percentageOfExecutedLines(): Percentage
|
||||
{
|
||||
return Percentage::fromFractionAndTotal(
|
||||
$this->numberOfExecutedLines(),
|
||||
$this->numberOfExecutableLines(),
|
||||
);
|
||||
}
|
||||
|
||||
public function percentageOfExecutedBranches(): Percentage
|
||||
{
|
||||
return Percentage::fromFractionAndTotal(
|
||||
$this->numberOfExecutedBranches(),
|
||||
$this->numberOfExecutableBranches()
|
||||
);
|
||||
}
|
||||
|
||||
public function percentageOfExecutedPaths(): Percentage
|
||||
{
|
||||
return Percentage::fromFractionAndTotal(
|
||||
$this->numberOfExecutedPaths(),
|
||||
$this->numberOfExecutablePaths()
|
||||
);
|
||||
}
|
||||
|
||||
public function numberOfClassesAndTraits(): int
|
||||
{
|
||||
return $this->numberOfClasses() + $this->numberOfTraits();
|
||||
}
|
||||
|
||||
public function numberOfTestedClassesAndTraits(): int
|
||||
{
|
||||
return $this->numberOfTestedClasses() + $this->numberOfTestedTraits();
|
||||
}
|
||||
|
||||
public function classesAndTraits(): array
|
||||
{
|
||||
return array_merge($this->classes(), $this->traits());
|
||||
}
|
||||
|
||||
public function numberOfFunctionsAndMethods(): int
|
||||
{
|
||||
return $this->numberOfFunctions() + $this->numberOfMethods();
|
||||
}
|
||||
|
||||
public function numberOfTestedFunctionsAndMethods(): int
|
||||
{
|
||||
return $this->numberOfTestedFunctions() + $this->numberOfTestedMethods();
|
||||
}
|
||||
|
||||
abstract public function classes(): array;
|
||||
|
||||
abstract public function traits(): array;
|
||||
|
||||
abstract public function functions(): array;
|
||||
|
||||
abstract public function linesOfCode(): LinesOfCode;
|
||||
|
||||
abstract public function numberOfExecutableLines(): int;
|
||||
|
||||
abstract public function numberOfExecutedLines(): int;
|
||||
|
||||
abstract public function numberOfExecutableBranches(): int;
|
||||
|
||||
abstract public function numberOfExecutedBranches(): int;
|
||||
|
||||
abstract public function numberOfExecutablePaths(): int;
|
||||
|
||||
abstract public function numberOfExecutedPaths(): int;
|
||||
|
||||
abstract public function numberOfClasses(): int;
|
||||
|
||||
abstract public function numberOfTestedClasses(): int;
|
||||
|
||||
abstract public function numberOfTraits(): int;
|
||||
|
||||
abstract public function numberOfTestedTraits(): int;
|
||||
|
||||
abstract public function numberOfMethods(): int;
|
||||
|
||||
abstract public function numberOfTestedMethods(): int;
|
||||
|
||||
abstract public function numberOfFunctions(): int;
|
||||
|
||||
abstract public function numberOfTestedFunctions(): int;
|
||||
}
|
264
vendor/phpunit/php-code-coverage/src/Node/Builder.php
vendored
Normal file
264
vendor/phpunit/php-code-coverage/src/Node/Builder.php
vendored
Normal file
@ -0,0 +1,264 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Node;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use function array_shift;
|
||||
use function basename;
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function explode;
|
||||
use function implode;
|
||||
use function is_file;
|
||||
use function str_replace;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\ProcessedCodeCoverageData;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\CoveredFileAnalyser;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Builder
|
||||
{
|
||||
/**
|
||||
* @var CoveredFileAnalyser
|
||||
*/
|
||||
private $coveredFileAnalyser;
|
||||
|
||||
public function __construct(CoveredFileAnalyser $coveredFileAnalyser)
|
||||
{
|
||||
$this->coveredFileAnalyser = $coveredFileAnalyser;
|
||||
}
|
||||
|
||||
public function build(CodeCoverage $coverage): Directory
|
||||
{
|
||||
$data = clone $coverage->getData(); // clone because path munging is destructive to the original data
|
||||
$commonPath = $this->reducePaths($data);
|
||||
$root = new Directory(
|
||||
$commonPath,
|
||||
null
|
||||
);
|
||||
|
||||
$this->addItems(
|
||||
$root,
|
||||
$this->buildDirectoryStructure($data),
|
||||
$coverage->getTests()
|
||||
);
|
||||
|
||||
return $root;
|
||||
}
|
||||
|
||||
private function addItems(Directory $root, array $items, array $tests): void
|
||||
{
|
||||
foreach ($items as $key => $value) {
|
||||
$key = (string) $key;
|
||||
|
||||
if (substr($key, -2) === '/f') {
|
||||
$key = substr($key, 0, -2);
|
||||
$filename = $root->pathAsString() . DIRECTORY_SEPARATOR . $key;
|
||||
|
||||
if (is_file($filename)) {
|
||||
$root->addFile(
|
||||
new File(
|
||||
$key,
|
||||
$root,
|
||||
$value['lineCoverage'],
|
||||
$value['functionCoverage'],
|
||||
$tests,
|
||||
$this->coveredFileAnalyser->classesIn($filename),
|
||||
$this->coveredFileAnalyser->traitsIn($filename),
|
||||
$this->coveredFileAnalyser->functionsIn($filename),
|
||||
$this->coveredFileAnalyser->linesOfCodeFor($filename)
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$child = $root->addDirectory($key);
|
||||
|
||||
$this->addItems($child, $value, $tests);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an array representation of the directory structure.
|
||||
*
|
||||
* For instance,
|
||||
*
|
||||
* <code>
|
||||
* Array
|
||||
* (
|
||||
* [Money.php] => Array
|
||||
* (
|
||||
* ...
|
||||
* )
|
||||
*
|
||||
* [MoneyBag.php] => Array
|
||||
* (
|
||||
* ...
|
||||
* )
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* is transformed into
|
||||
*
|
||||
* <code>
|
||||
* Array
|
||||
* (
|
||||
* [.] => Array
|
||||
* (
|
||||
* [Money.php] => Array
|
||||
* (
|
||||
* ...
|
||||
* )
|
||||
*
|
||||
* [MoneyBag.php] => Array
|
||||
* (
|
||||
* ...
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* </code>
|
||||
*/
|
||||
private function buildDirectoryStructure(ProcessedCodeCoverageData $data): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($data->coveredFiles() as $originalPath) {
|
||||
$path = explode(DIRECTORY_SEPARATOR, $originalPath);
|
||||
$pointer = &$result;
|
||||
$max = count($path);
|
||||
|
||||
for ($i = 0; $i < $max; $i++) {
|
||||
$type = '';
|
||||
|
||||
if ($i === ($max - 1)) {
|
||||
$type = '/f';
|
||||
}
|
||||
|
||||
$pointer = &$pointer[$path[$i] . $type];
|
||||
}
|
||||
|
||||
$pointer = [
|
||||
'lineCoverage' => $data->lineCoverage()[$originalPath] ?? [],
|
||||
'functionCoverage' => $data->functionCoverage()[$originalPath] ?? [],
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces the paths by cutting the longest common start path.
|
||||
*
|
||||
* For instance,
|
||||
*
|
||||
* <code>
|
||||
* Array
|
||||
* (
|
||||
* [/home/sb/Money/Money.php] => Array
|
||||
* (
|
||||
* ...
|
||||
* )
|
||||
*
|
||||
* [/home/sb/Money/MoneyBag.php] => Array
|
||||
* (
|
||||
* ...
|
||||
* )
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* is reduced to
|
||||
*
|
||||
* <code>
|
||||
* Array
|
||||
* (
|
||||
* [Money.php] => Array
|
||||
* (
|
||||
* ...
|
||||
* )
|
||||
*
|
||||
* [MoneyBag.php] => Array
|
||||
* (
|
||||
* ...
|
||||
* )
|
||||
* )
|
||||
* </code>
|
||||
*/
|
||||
private function reducePaths(ProcessedCodeCoverageData $coverage): string
|
||||
{
|
||||
if (empty($coverage->coveredFiles())) {
|
||||
return '.';
|
||||
}
|
||||
|
||||
$commonPath = '';
|
||||
$paths = $coverage->coveredFiles();
|
||||
|
||||
if (count($paths) === 1) {
|
||||
$commonPath = dirname($paths[0]) . DIRECTORY_SEPARATOR;
|
||||
$coverage->renameFile($paths[0], basename($paths[0]));
|
||||
|
||||
return $commonPath;
|
||||
}
|
||||
|
||||
$max = count($paths);
|
||||
|
||||
for ($i = 0; $i < $max; $i++) {
|
||||
// strip phar:// prefixes
|
||||
if (strpos($paths[$i], 'phar://') === 0) {
|
||||
$paths[$i] = substr($paths[$i], 7);
|
||||
$paths[$i] = str_replace('/', DIRECTORY_SEPARATOR, $paths[$i]);
|
||||
}
|
||||
$paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]);
|
||||
|
||||
if (empty($paths[$i][0])) {
|
||||
$paths[$i][0] = DIRECTORY_SEPARATOR;
|
||||
}
|
||||
}
|
||||
|
||||
$done = false;
|
||||
$max = count($paths);
|
||||
|
||||
while (!$done) {
|
||||
for ($i = 0; $i < $max - 1; $i++) {
|
||||
if (!isset($paths[$i][0]) ||
|
||||
!isset($paths[$i + 1][0]) ||
|
||||
$paths[$i][0] !== $paths[$i + 1][0]) {
|
||||
$done = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$done) {
|
||||
$commonPath .= $paths[0][0];
|
||||
|
||||
if ($paths[0][0] !== DIRECTORY_SEPARATOR) {
|
||||
$commonPath .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $max; $i++) {
|
||||
array_shift($paths[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$original = $coverage->coveredFiles();
|
||||
$max = count($original);
|
||||
|
||||
for ($i = 0; $i < $max; $i++) {
|
||||
$coverage->renameFile($original[$i], implode(DIRECTORY_SEPARATOR, $paths[$i]));
|
||||
}
|
||||
|
||||
return substr($commonPath, 0, -1);
|
||||
}
|
||||
}
|
430
vendor/phpunit/php-code-coverage/src/Node/Directory.php
vendored
Normal file
430
vendor/phpunit/php-code-coverage/src/Node/Directory.php
vendored
Normal file
@ -0,0 +1,430 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Node;
|
||||
|
||||
use function array_merge;
|
||||
use function count;
|
||||
use IteratorAggregate;
|
||||
use RecursiveIteratorIterator;
|
||||
use SebastianBergmann\LinesOfCode\LinesOfCode;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Directory extends AbstractNode implements IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var AbstractNode[]
|
||||
*/
|
||||
private $children = [];
|
||||
|
||||
/**
|
||||
* @var Directory[]
|
||||
*/
|
||||
private $directories = [];
|
||||
|
||||
/**
|
||||
* @var File[]
|
||||
*/
|
||||
private $files = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $classes;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $traits;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $functions;
|
||||
|
||||
/**
|
||||
* @var LinesOfCode
|
||||
*/
|
||||
private $linesOfCode;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numFiles = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numExecutableLines = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numExecutedLines = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numExecutableBranches = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numExecutedBranches = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numExecutablePaths = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numExecutedPaths = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numClasses = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTestedClasses = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTraits = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTestedTraits = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numMethods = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTestedMethods = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numFunctions = -1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTestedFunctions = -1;
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
if ($this->numFiles === -1) {
|
||||
$this->numFiles = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numFiles += count($child);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numFiles;
|
||||
}
|
||||
|
||||
public function getIterator(): RecursiveIteratorIterator
|
||||
{
|
||||
return new RecursiveIteratorIterator(
|
||||
new Iterator($this),
|
||||
RecursiveIteratorIterator::SELF_FIRST
|
||||
);
|
||||
}
|
||||
|
||||
public function addDirectory(string $name): self
|
||||
{
|
||||
$directory = new self($name, $this);
|
||||
|
||||
$this->children[] = $directory;
|
||||
$this->directories[] = &$this->children[count($this->children) - 1];
|
||||
|
||||
return $directory;
|
||||
}
|
||||
|
||||
public function addFile(File $file): void
|
||||
{
|
||||
$this->children[] = $file;
|
||||
$this->files[] = &$this->children[count($this->children) - 1];
|
||||
|
||||
$this->numExecutableLines = -1;
|
||||
$this->numExecutedLines = -1;
|
||||
}
|
||||
|
||||
public function directories(): array
|
||||
{
|
||||
return $this->directories;
|
||||
}
|
||||
|
||||
public function files(): array
|
||||
{
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
public function children(): array
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
public function classes(): array
|
||||
{
|
||||
if ($this->classes === null) {
|
||||
$this->classes = [];
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->classes = array_merge(
|
||||
$this->classes,
|
||||
$child->classes()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->classes;
|
||||
}
|
||||
|
||||
public function traits(): array
|
||||
{
|
||||
if ($this->traits === null) {
|
||||
$this->traits = [];
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->traits = array_merge(
|
||||
$this->traits,
|
||||
$child->traits()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->traits;
|
||||
}
|
||||
|
||||
public function functions(): array
|
||||
{
|
||||
if ($this->functions === null) {
|
||||
$this->functions = [];
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->functions = array_merge(
|
||||
$this->functions,
|
||||
$child->functions()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->functions;
|
||||
}
|
||||
|
||||
public function linesOfCode(): LinesOfCode
|
||||
{
|
||||
if ($this->linesOfCode === null) {
|
||||
$this->linesOfCode = new LinesOfCode(0, 0, 0, 0);
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->linesOfCode = $this->linesOfCode->plus($child->linesOfCode());
|
||||
}
|
||||
}
|
||||
|
||||
return $this->linesOfCode;
|
||||
}
|
||||
|
||||
public function numberOfExecutableLines(): int
|
||||
{
|
||||
if ($this->numExecutableLines === -1) {
|
||||
$this->numExecutableLines = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numExecutableLines += $child->numberOfExecutableLines();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numExecutableLines;
|
||||
}
|
||||
|
||||
public function numberOfExecutedLines(): int
|
||||
{
|
||||
if ($this->numExecutedLines === -1) {
|
||||
$this->numExecutedLines = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numExecutedLines += $child->numberOfExecutedLines();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numExecutedLines;
|
||||
}
|
||||
|
||||
public function numberOfExecutableBranches(): int
|
||||
{
|
||||
if ($this->numExecutableBranches === -1) {
|
||||
$this->numExecutableBranches = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numExecutableBranches += $child->numberOfExecutableBranches();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numExecutableBranches;
|
||||
}
|
||||
|
||||
public function numberOfExecutedBranches(): int
|
||||
{
|
||||
if ($this->numExecutedBranches === -1) {
|
||||
$this->numExecutedBranches = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numExecutedBranches += $child->numberOfExecutedBranches();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numExecutedBranches;
|
||||
}
|
||||
|
||||
public function numberOfExecutablePaths(): int
|
||||
{
|
||||
if ($this->numExecutablePaths === -1) {
|
||||
$this->numExecutablePaths = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numExecutablePaths += $child->numberOfExecutablePaths();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numExecutablePaths;
|
||||
}
|
||||
|
||||
public function numberOfExecutedPaths(): int
|
||||
{
|
||||
if ($this->numExecutedPaths === -1) {
|
||||
$this->numExecutedPaths = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numExecutedPaths += $child->numberOfExecutedPaths();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numExecutedPaths;
|
||||
}
|
||||
|
||||
public function numberOfClasses(): int
|
||||
{
|
||||
if ($this->numClasses === -1) {
|
||||
$this->numClasses = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numClasses += $child->numberOfClasses();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numClasses;
|
||||
}
|
||||
|
||||
public function numberOfTestedClasses(): int
|
||||
{
|
||||
if ($this->numTestedClasses === -1) {
|
||||
$this->numTestedClasses = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numTestedClasses += $child->numberOfTestedClasses();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numTestedClasses;
|
||||
}
|
||||
|
||||
public function numberOfTraits(): int
|
||||
{
|
||||
if ($this->numTraits === -1) {
|
||||
$this->numTraits = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numTraits += $child->numberOfTraits();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numTraits;
|
||||
}
|
||||
|
||||
public function numberOfTestedTraits(): int
|
||||
{
|
||||
if ($this->numTestedTraits === -1) {
|
||||
$this->numTestedTraits = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numTestedTraits += $child->numberOfTestedTraits();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numTestedTraits;
|
||||
}
|
||||
|
||||
public function numberOfMethods(): int
|
||||
{
|
||||
if ($this->numMethods === -1) {
|
||||
$this->numMethods = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numMethods += $child->numberOfMethods();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numMethods;
|
||||
}
|
||||
|
||||
public function numberOfTestedMethods(): int
|
||||
{
|
||||
if ($this->numTestedMethods === -1) {
|
||||
$this->numTestedMethods = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numTestedMethods += $child->numberOfTestedMethods();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numTestedMethods;
|
||||
}
|
||||
|
||||
public function numberOfFunctions(): int
|
||||
{
|
||||
if ($this->numFunctions === -1) {
|
||||
$this->numFunctions = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numFunctions += $child->numberOfFunctions();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numFunctions;
|
||||
}
|
||||
|
||||
public function numberOfTestedFunctions(): int
|
||||
{
|
||||
if ($this->numTestedFunctions === -1) {
|
||||
$this->numTestedFunctions = 0;
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$this->numTestedFunctions += $child->numberOfTestedFunctions();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numTestedFunctions;
|
||||
}
|
||||
}
|
643
vendor/phpunit/php-code-coverage/src/Node/File.php
vendored
Normal file
643
vendor/phpunit/php-code-coverage/src/Node/File.php
vendored
Normal file
@ -0,0 +1,643 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Node;
|
||||
|
||||
use function array_filter;
|
||||
use function count;
|
||||
use function range;
|
||||
use SebastianBergmann\CodeCoverage\CrapIndex;
|
||||
use SebastianBergmann\LinesOfCode\LinesOfCode;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class File extends AbstractNode
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $lineCoverageData;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $functionCoverageData;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $testData;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numExecutableLines = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numExecutedLines = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numExecutableBranches = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numExecutedBranches = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numExecutablePaths = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numExecutedPaths = 0;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $classes = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $traits = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $functions = [];
|
||||
|
||||
/**
|
||||
* @var LinesOfCode
|
||||
*/
|
||||
private $linesOfCode;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numClasses;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTestedClasses = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTraits;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTestedTraits = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numMethods;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTestedMethods;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $numTestedFunctions;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $codeUnitsByLine = [];
|
||||
|
||||
public function __construct(string $name, AbstractNode $parent, array $lineCoverageData, array $functionCoverageData, array $testData, array $classes, array $traits, array $functions, LinesOfCode $linesOfCode)
|
||||
{
|
||||
parent::__construct($name, $parent);
|
||||
|
||||
$this->lineCoverageData = $lineCoverageData;
|
||||
$this->functionCoverageData = $functionCoverageData;
|
||||
$this->testData = $testData;
|
||||
$this->linesOfCode = $linesOfCode;
|
||||
|
||||
$this->calculateStatistics($classes, $traits, $functions);
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function lineCoverageData(): array
|
||||
{
|
||||
return $this->lineCoverageData;
|
||||
}
|
||||
|
||||
public function functionCoverageData(): array
|
||||
{
|
||||
return $this->functionCoverageData;
|
||||
}
|
||||
|
||||
public function testData(): array
|
||||
{
|
||||
return $this->testData;
|
||||
}
|
||||
|
||||
public function classes(): array
|
||||
{
|
||||
return $this->classes;
|
||||
}
|
||||
|
||||
public function traits(): array
|
||||
{
|
||||
return $this->traits;
|
||||
}
|
||||
|
||||
public function functions(): array
|
||||
{
|
||||
return $this->functions;
|
||||
}
|
||||
|
||||
public function linesOfCode(): LinesOfCode
|
||||
{
|
||||
return $this->linesOfCode;
|
||||
}
|
||||
|
||||
public function numberOfExecutableLines(): int
|
||||
{
|
||||
return $this->numExecutableLines;
|
||||
}
|
||||
|
||||
public function numberOfExecutedLines(): int
|
||||
{
|
||||
return $this->numExecutedLines;
|
||||
}
|
||||
|
||||
public function numberOfExecutableBranches(): int
|
||||
{
|
||||
return $this->numExecutableBranches;
|
||||
}
|
||||
|
||||
public function numberOfExecutedBranches(): int
|
||||
{
|
||||
return $this->numExecutedBranches;
|
||||
}
|
||||
|
||||
public function numberOfExecutablePaths(): int
|
||||
{
|
||||
return $this->numExecutablePaths;
|
||||
}
|
||||
|
||||
public function numberOfExecutedPaths(): int
|
||||
{
|
||||
return $this->numExecutedPaths;
|
||||
}
|
||||
|
||||
public function numberOfClasses(): int
|
||||
{
|
||||
if ($this->numClasses === null) {
|
||||
$this->numClasses = 0;
|
||||
|
||||
foreach ($this->classes as $class) {
|
||||
foreach ($class['methods'] as $method) {
|
||||
if ($method['executableLines'] > 0) {
|
||||
$this->numClasses++;
|
||||
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numClasses;
|
||||
}
|
||||
|
||||
public function numberOfTestedClasses(): int
|
||||
{
|
||||
return $this->numTestedClasses;
|
||||
}
|
||||
|
||||
public function numberOfTraits(): int
|
||||
{
|
||||
if ($this->numTraits === null) {
|
||||
$this->numTraits = 0;
|
||||
|
||||
foreach ($this->traits as $trait) {
|
||||
foreach ($trait['methods'] as $method) {
|
||||
if ($method['executableLines'] > 0) {
|
||||
$this->numTraits++;
|
||||
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numTraits;
|
||||
}
|
||||
|
||||
public function numberOfTestedTraits(): int
|
||||
{
|
||||
return $this->numTestedTraits;
|
||||
}
|
||||
|
||||
public function numberOfMethods(): int
|
||||
{
|
||||
if ($this->numMethods === null) {
|
||||
$this->numMethods = 0;
|
||||
|
||||
foreach ($this->classes as $class) {
|
||||
foreach ($class['methods'] as $method) {
|
||||
if ($method['executableLines'] > 0) {
|
||||
$this->numMethods++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->traits as $trait) {
|
||||
foreach ($trait['methods'] as $method) {
|
||||
if ($method['executableLines'] > 0) {
|
||||
$this->numMethods++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numMethods;
|
||||
}
|
||||
|
||||
public function numberOfTestedMethods(): int
|
||||
{
|
||||
if ($this->numTestedMethods === null) {
|
||||
$this->numTestedMethods = 0;
|
||||
|
||||
foreach ($this->classes as $class) {
|
||||
foreach ($class['methods'] as $method) {
|
||||
if ($method['executableLines'] > 0 &&
|
||||
$method['coverage'] === 100) {
|
||||
$this->numTestedMethods++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->traits as $trait) {
|
||||
foreach ($trait['methods'] as $method) {
|
||||
if ($method['executableLines'] > 0 &&
|
||||
$method['coverage'] === 100) {
|
||||
$this->numTestedMethods++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numTestedMethods;
|
||||
}
|
||||
|
||||
public function numberOfFunctions(): int
|
||||
{
|
||||
return count($this->functions);
|
||||
}
|
||||
|
||||
public function numberOfTestedFunctions(): int
|
||||
{
|
||||
if ($this->numTestedFunctions === null) {
|
||||
$this->numTestedFunctions = 0;
|
||||
|
||||
foreach ($this->functions as $function) {
|
||||
if ($function['executableLines'] > 0 &&
|
||||
$function['coverage'] === 100) {
|
||||
$this->numTestedFunctions++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->numTestedFunctions;
|
||||
}
|
||||
|
||||
private function calculateStatistics(array $classes, array $traits, array $functions): void
|
||||
{
|
||||
foreach (range(1, $this->linesOfCode->linesOfCode()) as $lineNumber) {
|
||||
$this->codeUnitsByLine[$lineNumber] = [];
|
||||
}
|
||||
|
||||
$this->processClasses($classes);
|
||||
$this->processTraits($traits);
|
||||
$this->processFunctions($functions);
|
||||
|
||||
foreach (range(1, $this->linesOfCode->linesOfCode()) as $lineNumber) {
|
||||
if (isset($this->lineCoverageData[$lineNumber])) {
|
||||
foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) {
|
||||
$codeUnit['executableLines']++;
|
||||
}
|
||||
|
||||
unset($codeUnit);
|
||||
|
||||
$this->numExecutableLines++;
|
||||
|
||||
if (count($this->lineCoverageData[$lineNumber]) > 0) {
|
||||
foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) {
|
||||
$codeUnit['executedLines']++;
|
||||
}
|
||||
|
||||
unset($codeUnit);
|
||||
|
||||
$this->numExecutedLines++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->traits as &$trait) {
|
||||
foreach ($trait['methods'] as &$method) {
|
||||
$methodLineCoverage = $method['executableLines'] ? ($method['executedLines'] / $method['executableLines']) * 100 : 100;
|
||||
$methodBranchCoverage = $method['executableBranches'] ? ($method['executedBranches'] / $method['executableBranches']) * 100 : 0;
|
||||
$methodPathCoverage = $method['executablePaths'] ? ($method['executedPaths'] / $method['executablePaths']) * 100 : 0;
|
||||
|
||||
$method['coverage'] = $methodBranchCoverage ?: $methodLineCoverage;
|
||||
$method['crap'] = (new CrapIndex($method['ccn'], $methodPathCoverage ?: $methodLineCoverage))->asString();
|
||||
|
||||
$trait['ccn'] += $method['ccn'];
|
||||
}
|
||||
|
||||
unset($method);
|
||||
|
||||
$traitLineCoverage = $trait['executableLines'] ? ($trait['executedLines'] / $trait['executableLines']) * 100 : 100;
|
||||
$traitBranchCoverage = $trait['executableBranches'] ? ($trait['executedBranches'] / $trait['executableBranches']) * 100 : 0;
|
||||
$traitPathCoverage = $trait['executablePaths'] ? ($trait['executedPaths'] / $trait['executablePaths']) * 100 : 0;
|
||||
|
||||
$trait['coverage'] = $traitBranchCoverage ?: $traitLineCoverage;
|
||||
$trait['crap'] = (new CrapIndex($trait['ccn'], $traitPathCoverage ?: $traitLineCoverage))->asString();
|
||||
|
||||
if ($trait['executableLines'] > 0 && $trait['coverage'] === 100) {
|
||||
$this->numTestedClasses++;
|
||||
}
|
||||
}
|
||||
|
||||
unset($trait);
|
||||
|
||||
foreach ($this->classes as &$class) {
|
||||
foreach ($class['methods'] as &$method) {
|
||||
$methodLineCoverage = $method['executableLines'] ? ($method['executedLines'] / $method['executableLines']) * 100 : 100;
|
||||
$methodBranchCoverage = $method['executableBranches'] ? ($method['executedBranches'] / $method['executableBranches']) * 100 : 0;
|
||||
$methodPathCoverage = $method['executablePaths'] ? ($method['executedPaths'] / $method['executablePaths']) * 100 : 0;
|
||||
|
||||
$method['coverage'] = $methodBranchCoverage ?: $methodLineCoverage;
|
||||
$method['crap'] = (new CrapIndex($method['ccn'], $methodPathCoverage ?: $methodLineCoverage))->asString();
|
||||
|
||||
$class['ccn'] += $method['ccn'];
|
||||
}
|
||||
|
||||
unset($method);
|
||||
|
||||
$classLineCoverage = $class['executableLines'] ? ($class['executedLines'] / $class['executableLines']) * 100 : 100;
|
||||
$classBranchCoverage = $class['executableBranches'] ? ($class['executedBranches'] / $class['executableBranches']) * 100 : 0;
|
||||
$classPathCoverage = $class['executablePaths'] ? ($class['executedPaths'] / $class['executablePaths']) * 100 : 0;
|
||||
|
||||
$class['coverage'] = $classBranchCoverage ?: $classLineCoverage;
|
||||
$class['crap'] = (new CrapIndex($class['ccn'], $classPathCoverage ?: $classLineCoverage))->asString();
|
||||
|
||||
if ($class['executableLines'] > 0 && $class['coverage'] === 100) {
|
||||
$this->numTestedClasses++;
|
||||
}
|
||||
}
|
||||
|
||||
unset($class);
|
||||
|
||||
foreach ($this->functions as &$function) {
|
||||
$functionLineCoverage = $function['executableLines'] ? ($function['executedLines'] / $function['executableLines']) * 100 : 100;
|
||||
$functionBranchCoverage = $function['executableBranches'] ? ($function['executedBranches'] / $function['executableBranches']) * 100 : 0;
|
||||
$functionPathCoverage = $function['executablePaths'] ? ($function['executedPaths'] / $function['executablePaths']) * 100 : 0;
|
||||
|
||||
$function['coverage'] = $functionBranchCoverage ?: $functionLineCoverage;
|
||||
$function['crap'] = (new CrapIndex($function['ccn'], $functionPathCoverage ?: $functionLineCoverage))->asString();
|
||||
|
||||
if ($function['coverage'] === 100) {
|
||||
$this->numTestedFunctions++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function processClasses(array $classes): void
|
||||
{
|
||||
$link = $this->id() . '.html#';
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
$this->classes[$className] = [
|
||||
'className' => $className,
|
||||
'namespace' => $class['namespace'],
|
||||
'methods' => [],
|
||||
'startLine' => $class['startLine'],
|
||||
'executableLines' => 0,
|
||||
'executedLines' => 0,
|
||||
'executableBranches' => 0,
|
||||
'executedBranches' => 0,
|
||||
'executablePaths' => 0,
|
||||
'executedPaths' => 0,
|
||||
'ccn' => 0,
|
||||
'coverage' => 0,
|
||||
'crap' => 0,
|
||||
'link' => $link . $class['startLine'],
|
||||
];
|
||||
|
||||
foreach ($class['methods'] as $methodName => $method) {
|
||||
$methodData = $this->newMethod($className, $methodName, $method, $link);
|
||||
$this->classes[$className]['methods'][$methodName] = $methodData;
|
||||
|
||||
$this->classes[$className]['executableBranches'] += $methodData['executableBranches'];
|
||||
$this->classes[$className]['executedBranches'] += $methodData['executedBranches'];
|
||||
$this->classes[$className]['executablePaths'] += $methodData['executablePaths'];
|
||||
$this->classes[$className]['executedPaths'] += $methodData['executedPaths'];
|
||||
|
||||
$this->numExecutableBranches += $methodData['executableBranches'];
|
||||
$this->numExecutedBranches += $methodData['executedBranches'];
|
||||
$this->numExecutablePaths += $methodData['executablePaths'];
|
||||
$this->numExecutedPaths += $methodData['executedPaths'];
|
||||
|
||||
foreach (range($method['startLine'], $method['endLine']) as $lineNumber) {
|
||||
$this->codeUnitsByLine[$lineNumber] = [
|
||||
&$this->classes[$className],
|
||||
&$this->classes[$className]['methods'][$methodName],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function processTraits(array $traits): void
|
||||
{
|
||||
$link = $this->id() . '.html#';
|
||||
|
||||
foreach ($traits as $traitName => $trait) {
|
||||
$this->traits[$traitName] = [
|
||||
'traitName' => $traitName,
|
||||
'namespace' => $trait['namespace'],
|
||||
'methods' => [],
|
||||
'startLine' => $trait['startLine'],
|
||||
'executableLines' => 0,
|
||||
'executedLines' => 0,
|
||||
'executableBranches' => 0,
|
||||
'executedBranches' => 0,
|
||||
'executablePaths' => 0,
|
||||
'executedPaths' => 0,
|
||||
'ccn' => 0,
|
||||
'coverage' => 0,
|
||||
'crap' => 0,
|
||||
'link' => $link . $trait['startLine'],
|
||||
];
|
||||
|
||||
foreach ($trait['methods'] as $methodName => $method) {
|
||||
$methodData = $this->newMethod($traitName, $methodName, $method, $link);
|
||||
$this->traits[$traitName]['methods'][$methodName] = $methodData;
|
||||
|
||||
$this->traits[$traitName]['executableBranches'] += $methodData['executableBranches'];
|
||||
$this->traits[$traitName]['executedBranches'] += $methodData['executedBranches'];
|
||||
$this->traits[$traitName]['executablePaths'] += $methodData['executablePaths'];
|
||||
$this->traits[$traitName]['executedPaths'] += $methodData['executedPaths'];
|
||||
|
||||
$this->numExecutableBranches += $methodData['executableBranches'];
|
||||
$this->numExecutedBranches += $methodData['executedBranches'];
|
||||
$this->numExecutablePaths += $methodData['executablePaths'];
|
||||
$this->numExecutedPaths += $methodData['executedPaths'];
|
||||
|
||||
foreach (range($method['startLine'], $method['endLine']) as $lineNumber) {
|
||||
$this->codeUnitsByLine[$lineNumber] = [
|
||||
&$this->traits[$traitName],
|
||||
&$this->traits[$traitName]['methods'][$methodName],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function processFunctions(array $functions): void
|
||||
{
|
||||
$link = $this->id() . '.html#';
|
||||
|
||||
foreach ($functions as $functionName => $function) {
|
||||
$this->functions[$functionName] = [
|
||||
'functionName' => $functionName,
|
||||
'namespace' => $function['namespace'],
|
||||
'signature' => $function['signature'],
|
||||
'startLine' => $function['startLine'],
|
||||
'endLine' => $function['endLine'],
|
||||
'executableLines' => 0,
|
||||
'executedLines' => 0,
|
||||
'executableBranches' => 0,
|
||||
'executedBranches' => 0,
|
||||
'executablePaths' => 0,
|
||||
'executedPaths' => 0,
|
||||
'ccn' => $function['ccn'],
|
||||
'coverage' => 0,
|
||||
'crap' => 0,
|
||||
'link' => $link . $function['startLine'],
|
||||
];
|
||||
|
||||
foreach (range($function['startLine'], $function['endLine']) as $lineNumber) {
|
||||
$this->codeUnitsByLine[$lineNumber] = [&$this->functions[$functionName]];
|
||||
}
|
||||
|
||||
if (isset($this->functionCoverageData[$functionName]['branches'])) {
|
||||
$this->functions[$functionName]['executableBranches'] = count(
|
||||
$this->functionCoverageData[$functionName]['branches']
|
||||
);
|
||||
|
||||
$this->functions[$functionName]['executedBranches'] = count(
|
||||
array_filter(
|
||||
$this->functionCoverageData[$functionName]['branches'],
|
||||
static function (array $branch) {
|
||||
return (bool) $branch['hit'];
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($this->functionCoverageData[$functionName]['paths'])) {
|
||||
$this->functions[$functionName]['executablePaths'] = count(
|
||||
$this->functionCoverageData[$functionName]['paths']
|
||||
);
|
||||
|
||||
$this->functions[$functionName]['executedPaths'] = count(
|
||||
array_filter(
|
||||
$this->functionCoverageData[$functionName]['paths'],
|
||||
static function (array $path) {
|
||||
return (bool) $path['hit'];
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->numExecutableBranches += $this->functions[$functionName]['executableBranches'];
|
||||
$this->numExecutedBranches += $this->functions[$functionName]['executedBranches'];
|
||||
$this->numExecutablePaths += $this->functions[$functionName]['executablePaths'];
|
||||
$this->numExecutedPaths += $this->functions[$functionName]['executedPaths'];
|
||||
}
|
||||
}
|
||||
|
||||
private function newMethod(string $className, string $methodName, array $method, string $link): array
|
||||
{
|
||||
$methodData = [
|
||||
'methodName' => $methodName,
|
||||
'visibility' => $method['visibility'],
|
||||
'signature' => $method['signature'],
|
||||
'startLine' => $method['startLine'],
|
||||
'endLine' => $method['endLine'],
|
||||
'executableLines' => 0,
|
||||
'executedLines' => 0,
|
||||
'executableBranches' => 0,
|
||||
'executedBranches' => 0,
|
||||
'executablePaths' => 0,
|
||||
'executedPaths' => 0,
|
||||
'ccn' => $method['ccn'],
|
||||
'coverage' => 0,
|
||||
'crap' => 0,
|
||||
'link' => $link . $method['startLine'],
|
||||
];
|
||||
|
||||
$key = $className . '->' . $methodName;
|
||||
|
||||
if (isset($this->functionCoverageData[$key]['branches'])) {
|
||||
$methodData['executableBranches'] = count(
|
||||
$this->functionCoverageData[$key]['branches']
|
||||
);
|
||||
|
||||
$methodData['executedBranches'] = count(
|
||||
array_filter(
|
||||
$this->functionCoverageData[$key]['branches'],
|
||||
static function (array $branch) {
|
||||
return (bool) $branch['hit'];
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($this->functionCoverageData[$key]['paths'])) {
|
||||
$methodData['executablePaths'] = count(
|
||||
$this->functionCoverageData[$key]['paths']
|
||||
);
|
||||
|
||||
$methodData['executedPaths'] = count(
|
||||
array_filter(
|
||||
$this->functionCoverageData[$key]['paths'],
|
||||
static function (array $path) {
|
||||
return (bool) $path['hit'];
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $methodData;
|
||||
}
|
||||
}
|
92
vendor/phpunit/php-code-coverage/src/Node/Iterator.php
vendored
Normal file
92
vendor/phpunit/php-code-coverage/src/Node/Iterator.php
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Node;
|
||||
|
||||
use function count;
|
||||
use RecursiveIterator;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Iterator implements RecursiveIterator
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $position;
|
||||
|
||||
/**
|
||||
* @var AbstractNode[]
|
||||
*/
|
||||
private $nodes;
|
||||
|
||||
public function __construct(Directory $node)
|
||||
{
|
||||
$this->nodes = $node->children();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewinds the Iterator to the first element.
|
||||
*/
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a current element after calls to rewind() or next().
|
||||
*/
|
||||
public function valid(): bool
|
||||
{
|
||||
return $this->position < count($this->nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key of the current element.
|
||||
*/
|
||||
public function key(): int
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current element.
|
||||
*/
|
||||
public function current(): ?AbstractNode
|
||||
{
|
||||
return $this->valid() ? $this->nodes[$this->position] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves forward to next element.
|
||||
*/
|
||||
public function next(): void
|
||||
{
|
||||
$this->position++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sub iterator for the current element.
|
||||
*
|
||||
* @return Iterator
|
||||
*/
|
||||
public function getChildren(): self
|
||||
{
|
||||
return new self($this->nodes[$this->position]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the current element has children.
|
||||
*/
|
||||
public function hasChildren(): bool
|
||||
{
|
||||
return $this->nodes[$this->position] instanceof Directory;
|
||||
}
|
||||
}
|
66
vendor/phpunit/php-code-coverage/src/Percentage.php
vendored
Normal file
66
vendor/phpunit/php-code-coverage/src/Percentage.php
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Percentage
|
||||
{
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $fraction;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $total;
|
||||
|
||||
public static function fromFractionAndTotal(float $fraction, float $total): self
|
||||
{
|
||||
return new self($fraction, $total);
|
||||
}
|
||||
|
||||
private function __construct(float $fraction, float $total)
|
||||
{
|
||||
$this->fraction = $fraction;
|
||||
$this->total = $total;
|
||||
}
|
||||
|
||||
public function asFloat(): float
|
||||
{
|
||||
if ($this->total > 0) {
|
||||
return ($this->fraction / $this->total) * 100;
|
||||
}
|
||||
|
||||
return 100.0;
|
||||
}
|
||||
|
||||
public function asString(): string
|
||||
{
|
||||
if ($this->total > 0) {
|
||||
return sprintf('%01.2F%%', $this->asFloat());
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public function asFixedWidthString(): string
|
||||
{
|
||||
if ($this->total > 0) {
|
||||
return sprintf('%6.2F%%', $this->asFloat());
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
267
vendor/phpunit/php-code-coverage/src/ProcessedCodeCoverageData.php
vendored
Normal file
267
vendor/phpunit/php-code-coverage/src/ProcessedCodeCoverageData.php
vendored
Normal file
@ -0,0 +1,267 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use function array_key_exists;
|
||||
use function array_keys;
|
||||
use function array_merge;
|
||||
use function array_unique;
|
||||
use function count;
|
||||
use function is_array;
|
||||
use function ksort;
|
||||
use SebastianBergmann\CodeCoverage\Driver\Driver;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class ProcessedCodeCoverageData
|
||||
{
|
||||
/**
|
||||
* Line coverage data.
|
||||
* An array of filenames, each having an array of linenumbers, each executable line having an array of testcase ids.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $lineCoverage = [];
|
||||
|
||||
/**
|
||||
* Function coverage data.
|
||||
* Maintains base format of raw data (@see https://xdebug.org/docs/code_coverage), but each 'hit' entry is an array
|
||||
* of testcase ids.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $functionCoverage = [];
|
||||
|
||||
public function initializeUnseenData(RawCodeCoverageData $rawData): void
|
||||
{
|
||||
foreach ($rawData->lineCoverage() as $file => $lines) {
|
||||
if (!isset($this->lineCoverage[$file])) {
|
||||
$this->lineCoverage[$file] = [];
|
||||
|
||||
foreach ($lines as $k => $v) {
|
||||
$this->lineCoverage[$file][$k] = $v === Driver::LINE_NOT_EXECUTABLE ? null : [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($rawData->functionCoverage() as $file => $functions) {
|
||||
foreach ($functions as $functionName => $functionData) {
|
||||
if (isset($this->functionCoverage[$file][$functionName])) {
|
||||
$this->initPreviouslySeenFunction($file, $functionName, $functionData);
|
||||
} else {
|
||||
$this->initPreviouslyUnseenFunction($file, $functionName, $functionData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function markCodeAsExecutedByTestCase(string $testCaseId, RawCodeCoverageData $executedCode): void
|
||||
{
|
||||
foreach ($executedCode->lineCoverage() as $file => $lines) {
|
||||
foreach ($lines as $k => $v) {
|
||||
if ($v === Driver::LINE_EXECUTED) {
|
||||
$this->lineCoverage[$file][$k][] = $testCaseId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($executedCode->functionCoverage() as $file => $functions) {
|
||||
foreach ($functions as $functionName => $functionData) {
|
||||
foreach ($functionData['branches'] as $branchId => $branchData) {
|
||||
if ($branchData['hit'] === Driver::BRANCH_HIT) {
|
||||
$this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'][] = $testCaseId;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($functionData['paths'] as $pathId => $pathData) {
|
||||
if ($pathData['hit'] === Driver::BRANCH_HIT) {
|
||||
$this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'][] = $testCaseId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setLineCoverage(array $lineCoverage): void
|
||||
{
|
||||
$this->lineCoverage = $lineCoverage;
|
||||
}
|
||||
|
||||
public function lineCoverage(): array
|
||||
{
|
||||
ksort($this->lineCoverage);
|
||||
|
||||
return $this->lineCoverage;
|
||||
}
|
||||
|
||||
public function setFunctionCoverage(array $functionCoverage): void
|
||||
{
|
||||
$this->functionCoverage = $functionCoverage;
|
||||
}
|
||||
|
||||
public function functionCoverage(): array
|
||||
{
|
||||
ksort($this->functionCoverage);
|
||||
|
||||
return $this->functionCoverage;
|
||||
}
|
||||
|
||||
public function coveredFiles(): array
|
||||
{
|
||||
ksort($this->lineCoverage);
|
||||
|
||||
return array_keys($this->lineCoverage);
|
||||
}
|
||||
|
||||
public function renameFile(string $oldFile, string $newFile): void
|
||||
{
|
||||
$this->lineCoverage[$newFile] = $this->lineCoverage[$oldFile];
|
||||
|
||||
if (isset($this->functionCoverage[$oldFile])) {
|
||||
$this->functionCoverage[$newFile] = $this->functionCoverage[$oldFile];
|
||||
}
|
||||
|
||||
unset($this->lineCoverage[$oldFile], $this->functionCoverage[$oldFile]);
|
||||
}
|
||||
|
||||
public function removeFilesWithNoCoverage(): void
|
||||
{
|
||||
foreach ($this->lineCoverage as $file => $lines) {
|
||||
foreach ($lines as $line) {
|
||||
if (is_array($line) && !empty($line)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
unset($file);
|
||||
}
|
||||
}
|
||||
|
||||
public function merge(self $newData): void
|
||||
{
|
||||
foreach ($newData->lineCoverage as $file => $lines) {
|
||||
if (!isset($this->lineCoverage[$file])) {
|
||||
$this->lineCoverage[$file] = $lines;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// we should compare the lines if any of two contains data
|
||||
$compareLineNumbers = array_unique(
|
||||
array_merge(
|
||||
array_keys($this->lineCoverage[$file]),
|
||||
array_keys($newData->lineCoverage[$file])
|
||||
)
|
||||
);
|
||||
|
||||
foreach ($compareLineNumbers as $line) {
|
||||
$thatPriority = $this->priorityForLine($newData->lineCoverage[$file], $line);
|
||||
$thisPriority = $this->priorityForLine($this->lineCoverage[$file], $line);
|
||||
|
||||
if ($thatPriority > $thisPriority) {
|
||||
$this->lineCoverage[$file][$line] = $newData->lineCoverage[$file][$line];
|
||||
} elseif ($thatPriority === $thisPriority && is_array($this->lineCoverage[$file][$line])) {
|
||||
$this->lineCoverage[$file][$line] = array_unique(
|
||||
array_merge($this->lineCoverage[$file][$line], $newData->lineCoverage[$file][$line])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($newData->functionCoverage as $file => $functions) {
|
||||
if (!isset($this->functionCoverage[$file])) {
|
||||
$this->functionCoverage[$file] = $functions;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($functions as $functionName => $functionData) {
|
||||
if (isset($this->functionCoverage[$file][$functionName])) {
|
||||
$this->initPreviouslySeenFunction($file, $functionName, $functionData);
|
||||
} else {
|
||||
$this->initPreviouslyUnseenFunction($file, $functionName, $functionData);
|
||||
}
|
||||
|
||||
foreach ($functionData['branches'] as $branchId => $branchData) {
|
||||
$this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'] = array_unique(array_merge($this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'], $branchData['hit']));
|
||||
}
|
||||
|
||||
foreach ($functionData['paths'] as $pathId => $pathData) {
|
||||
$this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'] = array_unique(array_merge($this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'], $pathData['hit']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the priority for a line.
|
||||
*
|
||||
* 1 = the line is not set
|
||||
* 2 = the line has not been tested
|
||||
* 3 = the line is dead code
|
||||
* 4 = the line has been tested
|
||||
*
|
||||
* During a merge, a higher number is better.
|
||||
*/
|
||||
private function priorityForLine(array $data, int $line): int
|
||||
{
|
||||
if (!array_key_exists($line, $data)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (is_array($data[$line]) && count($data[$line]) === 0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if ($data[$line] === null) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a function we have never seen before, copy all data over and simply init the 'hit' array.
|
||||
*/
|
||||
private function initPreviouslyUnseenFunction(string $file, string $functionName, array $functionData): void
|
||||
{
|
||||
$this->functionCoverage[$file][$functionName] = $functionData;
|
||||
|
||||
foreach (array_keys($functionData['branches']) as $branchId) {
|
||||
$this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'] = [];
|
||||
}
|
||||
|
||||
foreach (array_keys($functionData['paths']) as $pathId) {
|
||||
$this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'] = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For a function we have seen before, only copy over and init the 'hit' array for any unseen branches and paths.
|
||||
* Techniques such as mocking and where the contents of a file are different vary during tests (e.g. compiling
|
||||
* containers) mean that the functions inside a file cannot be relied upon to be static.
|
||||
*/
|
||||
private function initPreviouslySeenFunction(string $file, string $functionName, array $functionData): void
|
||||
{
|
||||
foreach ($functionData['branches'] as $branchId => $branchData) {
|
||||
if (!isset($this->functionCoverage[$file][$functionName]['branches'][$branchId])) {
|
||||
$this->functionCoverage[$file][$functionName]['branches'][$branchId] = $branchData;
|
||||
$this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'] = [];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($functionData['paths'] as $pathId => $pathData) {
|
||||
if (!isset($this->functionCoverage[$file][$functionName]['paths'][$pathId])) {
|
||||
$this->functionCoverage[$file][$functionName]['paths'][$pathId] = $pathData;
|
||||
$this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'] = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
227
vendor/phpunit/php-code-coverage/src/RawCodeCoverageData.php
vendored
Normal file
227
vendor/phpunit/php-code-coverage/src/RawCodeCoverageData.php
vendored
Normal file
@ -0,0 +1,227 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage;
|
||||
|
||||
use function array_diff;
|
||||
use function array_diff_key;
|
||||
use function array_flip;
|
||||
use function array_intersect;
|
||||
use function array_intersect_key;
|
||||
use function count;
|
||||
use function file;
|
||||
use function in_array;
|
||||
use function range;
|
||||
use SebastianBergmann\CodeCoverage\Driver\Driver;
|
||||
use SebastianBergmann\CodeCoverage\StaticAnalysis\UncoveredFileAnalyser;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class RawCodeCoverageData
|
||||
{
|
||||
/**
|
||||
* @var array<string, array<int>>
|
||||
*/
|
||||
private static $emptyLineCache = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @see https://xdebug.org/docs/code_coverage for format
|
||||
*/
|
||||
private $lineCoverage;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @see https://xdebug.org/docs/code_coverage for format
|
||||
*/
|
||||
private $functionCoverage;
|
||||
|
||||
public static function fromXdebugWithoutPathCoverage(array $rawCoverage): self
|
||||
{
|
||||
return new self($rawCoverage, []);
|
||||
}
|
||||
|
||||
public static function fromXdebugWithPathCoverage(array $rawCoverage): self
|
||||
{
|
||||
$lineCoverage = [];
|
||||
$functionCoverage = [];
|
||||
|
||||
foreach ($rawCoverage as $file => $fileCoverageData) {
|
||||
$lineCoverage[$file] = $fileCoverageData['lines'];
|
||||
$functionCoverage[$file] = $fileCoverageData['functions'];
|
||||
}
|
||||
|
||||
return new self($lineCoverage, $functionCoverage);
|
||||
}
|
||||
|
||||
public static function fromXdebugWithMixedCoverage(array $rawCoverage): self
|
||||
{
|
||||
$lineCoverage = [];
|
||||
$functionCoverage = [];
|
||||
|
||||
foreach ($rawCoverage as $file => $fileCoverageData) {
|
||||
if (!isset($fileCoverageData['functions'])) {
|
||||
// Current file does not have functions, so line coverage
|
||||
// is stored in $fileCoverageData, not in $fileCoverageData['lines']
|
||||
$lineCoverage[$file] = $fileCoverageData;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$lineCoverage[$file] = $fileCoverageData['lines'];
|
||||
$functionCoverage[$file] = $fileCoverageData['functions'];
|
||||
}
|
||||
|
||||
return new self($lineCoverage, $functionCoverage);
|
||||
}
|
||||
|
||||
public static function fromUncoveredFile(string $filename, UncoveredFileAnalyser $uncoveredFileAnalyser): self
|
||||
{
|
||||
$lineCoverage = [];
|
||||
|
||||
foreach ($uncoveredFileAnalyser->executableLinesIn($filename) as $line) {
|
||||
$lineCoverage[$line] = Driver::LINE_NOT_EXECUTED;
|
||||
}
|
||||
|
||||
return new self([$filename => $lineCoverage], []);
|
||||
}
|
||||
|
||||
private function __construct(array $lineCoverage, array $functionCoverage)
|
||||
{
|
||||
$this->lineCoverage = $lineCoverage;
|
||||
$this->functionCoverage = $functionCoverage;
|
||||
|
||||
$this->skipEmptyLines();
|
||||
}
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->lineCoverage = $this->functionCoverage = [];
|
||||
}
|
||||
|
||||
public function lineCoverage(): array
|
||||
{
|
||||
return $this->lineCoverage;
|
||||
}
|
||||
|
||||
public function functionCoverage(): array
|
||||
{
|
||||
return $this->functionCoverage;
|
||||
}
|
||||
|
||||
public function removeCoverageDataForFile(string $filename): void
|
||||
{
|
||||
unset($this->lineCoverage[$filename], $this->functionCoverage[$filename]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $lines
|
||||
*/
|
||||
public function keepCoverageDataOnlyForLines(string $filename, array $lines): void
|
||||
{
|
||||
if (!isset($this->lineCoverage[$filename])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->lineCoverage[$filename] = array_intersect_key(
|
||||
$this->lineCoverage[$filename],
|
||||
array_flip($lines)
|
||||
);
|
||||
|
||||
if (isset($this->functionCoverage[$filename])) {
|
||||
foreach ($this->functionCoverage[$filename] as $functionName => $functionData) {
|
||||
foreach ($functionData['branches'] as $branchId => $branch) {
|
||||
if (count(array_diff(range($branch['line_start'], $branch['line_end']), $lines)) > 0) {
|
||||
unset($this->functionCoverage[$filename][$functionName]['branches'][$branchId]);
|
||||
|
||||
foreach ($functionData['paths'] as $pathId => $path) {
|
||||
if (in_array($branchId, $path['path'], true)) {
|
||||
unset($this->functionCoverage[$filename][$functionName]['paths'][$pathId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $lines
|
||||
*/
|
||||
public function removeCoverageDataForLines(string $filename, array $lines): void
|
||||
{
|
||||
if (empty($lines)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($this->lineCoverage[$filename])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->lineCoverage[$filename] = array_diff_key(
|
||||
$this->lineCoverage[$filename],
|
||||
array_flip($lines)
|
||||
);
|
||||
|
||||
if (isset($this->functionCoverage[$filename])) {
|
||||
foreach ($this->functionCoverage[$filename] as $functionName => $functionData) {
|
||||
foreach ($functionData['branches'] as $branchId => $branch) {
|
||||
if (count(array_intersect($lines, range($branch['line_start'], $branch['line_end']))) > 0) {
|
||||
unset($this->functionCoverage[$filename][$functionName]['branches'][$branchId]);
|
||||
|
||||
foreach ($functionData['paths'] as $pathId => $path) {
|
||||
if (in_array($branchId, $path['path'], true)) {
|
||||
unset($this->functionCoverage[$filename][$functionName]['paths'][$pathId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* At the end of a file, the PHP interpreter always sees an implicit return. Where this occurs in a file that has
|
||||
* e.g. a class definition, that line cannot be invoked from a test and results in confusing coverage. This engine
|
||||
* implementation detail therefore needs to be masked which is done here by simply ensuring that all empty lines
|
||||
* are skipped over for coverage purposes.
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/php-code-coverage/issues/799
|
||||
*/
|
||||
private function skipEmptyLines(): void
|
||||
{
|
||||
foreach ($this->lineCoverage as $filename => $coverage) {
|
||||
foreach ($this->getEmptyLinesForFile($filename) as $emptyLine) {
|
||||
unset($this->lineCoverage[$filename][$emptyLine]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getEmptyLinesForFile(string $filename): array
|
||||
{
|
||||
if (!isset(self::$emptyLineCache[$filename])) {
|
||||
self::$emptyLineCache[$filename] = [];
|
||||
|
||||
if (is_file($filename)) {
|
||||
$sourceLines = explode("\n", file_get_contents($filename));
|
||||
|
||||
foreach ($sourceLines as $line => $source) {
|
||||
if (trim($source) === '') {
|
||||
self::$emptyLineCache[$filename][] = ($line + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self::$emptyLineCache[$filename];
|
||||
}
|
||||
}
|
255
vendor/phpunit/php-code-coverage/src/Report/Clover.php
vendored
Normal file
255
vendor/phpunit/php-code-coverage/src/Report/Clover.php
vendored
Normal file
@ -0,0 +1,255 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report;
|
||||
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function file_put_contents;
|
||||
use function is_string;
|
||||
use function ksort;
|
||||
use function max;
|
||||
use function range;
|
||||
use function time;
|
||||
use DOMDocument;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Directory;
|
||||
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
|
||||
use SebastianBergmann\CodeCoverage\Node\File;
|
||||
|
||||
final class Clover
|
||||
{
|
||||
/**
|
||||
* @throws WriteOperationFailedException
|
||||
*/
|
||||
public function process(CodeCoverage $coverage, ?string $target = null, ?string $name = null): string
|
||||
{
|
||||
$time = (string) time();
|
||||
|
||||
$xmlDocument = new DOMDocument('1.0', 'UTF-8');
|
||||
$xmlDocument->formatOutput = true;
|
||||
|
||||
$xmlCoverage = $xmlDocument->createElement('coverage');
|
||||
$xmlCoverage->setAttribute('generated', $time);
|
||||
$xmlDocument->appendChild($xmlCoverage);
|
||||
|
||||
$xmlProject = $xmlDocument->createElement('project');
|
||||
$xmlProject->setAttribute('timestamp', $time);
|
||||
|
||||
if (is_string($name)) {
|
||||
$xmlProject->setAttribute('name', $name);
|
||||
}
|
||||
|
||||
$xmlCoverage->appendChild($xmlProject);
|
||||
|
||||
$packages = [];
|
||||
$report = $coverage->getReport();
|
||||
|
||||
foreach ($report as $item) {
|
||||
if (!$item instanceof File) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* @var File $item */
|
||||
|
||||
$xmlFile = $xmlDocument->createElement('file');
|
||||
$xmlFile->setAttribute('name', $item->pathAsString());
|
||||
|
||||
$classes = $item->classesAndTraits();
|
||||
$coverageData = $item->lineCoverageData();
|
||||
$lines = [];
|
||||
$namespace = 'global';
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
$classStatements = 0;
|
||||
$coveredClassStatements = 0;
|
||||
$coveredMethods = 0;
|
||||
$classMethods = 0;
|
||||
|
||||
foreach ($class['methods'] as $methodName => $method) {
|
||||
if ($method['executableLines'] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$classMethods++;
|
||||
$classStatements += $method['executableLines'];
|
||||
$coveredClassStatements += $method['executedLines'];
|
||||
|
||||
if ($method['coverage'] == 100) {
|
||||
$coveredMethods++;
|
||||
}
|
||||
|
||||
$methodCount = 0;
|
||||
|
||||
foreach (range($method['startLine'], $method['endLine']) as $line) {
|
||||
if (isset($coverageData[$line]) && ($coverageData[$line] !== null)) {
|
||||
$methodCount = max($methodCount, count($coverageData[$line]));
|
||||
}
|
||||
}
|
||||
|
||||
$lines[$method['startLine']] = [
|
||||
'ccn' => $method['ccn'],
|
||||
'count' => $methodCount,
|
||||
'crap' => $method['crap'],
|
||||
'type' => 'method',
|
||||
'visibility' => $method['visibility'],
|
||||
'name' => $methodName,
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($class['package']['namespace'])) {
|
||||
$namespace = $class['package']['namespace'];
|
||||
}
|
||||
|
||||
$xmlClass = $xmlDocument->createElement('class');
|
||||
$xmlClass->setAttribute('name', $className);
|
||||
$xmlClass->setAttribute('namespace', $namespace);
|
||||
|
||||
if (!empty($class['package']['fullPackage'])) {
|
||||
$xmlClass->setAttribute(
|
||||
'fullPackage',
|
||||
$class['package']['fullPackage']
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($class['package']['category'])) {
|
||||
$xmlClass->setAttribute(
|
||||
'category',
|
||||
$class['package']['category']
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($class['package']['package'])) {
|
||||
$xmlClass->setAttribute(
|
||||
'package',
|
||||
$class['package']['package']
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($class['package']['subpackage'])) {
|
||||
$xmlClass->setAttribute(
|
||||
'subpackage',
|
||||
$class['package']['subpackage']
|
||||
);
|
||||
}
|
||||
|
||||
$xmlFile->appendChild($xmlClass);
|
||||
|
||||
$xmlMetrics = $xmlDocument->createElement('metrics');
|
||||
$xmlMetrics->setAttribute('complexity', (string) $class['ccn']);
|
||||
$xmlMetrics->setAttribute('methods', (string) $classMethods);
|
||||
$xmlMetrics->setAttribute('coveredmethods', (string) $coveredMethods);
|
||||
$xmlMetrics->setAttribute('conditionals', (string) $class['executableBranches']);
|
||||
$xmlMetrics->setAttribute('coveredconditionals', (string) $class['executedBranches']);
|
||||
$xmlMetrics->setAttribute('statements', (string) $classStatements);
|
||||
$xmlMetrics->setAttribute('coveredstatements', (string) $coveredClassStatements);
|
||||
$xmlMetrics->setAttribute('elements', (string) ($classMethods + $classStatements + $class['executableBranches']));
|
||||
$xmlMetrics->setAttribute('coveredelements', (string) ($coveredMethods + $coveredClassStatements + $class['executedBranches']));
|
||||
$xmlClass->appendChild($xmlMetrics);
|
||||
}
|
||||
|
||||
foreach ($coverageData as $line => $data) {
|
||||
if ($data === null || isset($lines[$line])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lines[$line] = [
|
||||
'count' => count($data), 'type' => 'stmt',
|
||||
];
|
||||
}
|
||||
|
||||
ksort($lines);
|
||||
|
||||
foreach ($lines as $line => $data) {
|
||||
$xmlLine = $xmlDocument->createElement('line');
|
||||
$xmlLine->setAttribute('num', (string) $line);
|
||||
$xmlLine->setAttribute('type', $data['type']);
|
||||
|
||||
if (isset($data['name'])) {
|
||||
$xmlLine->setAttribute('name', $data['name']);
|
||||
}
|
||||
|
||||
if (isset($data['visibility'])) {
|
||||
$xmlLine->setAttribute('visibility', $data['visibility']);
|
||||
}
|
||||
|
||||
if (isset($data['ccn'])) {
|
||||
$xmlLine->setAttribute('complexity', (string) $data['ccn']);
|
||||
}
|
||||
|
||||
if (isset($data['crap'])) {
|
||||
$xmlLine->setAttribute('crap', (string) $data['crap']);
|
||||
}
|
||||
|
||||
$xmlLine->setAttribute('count', (string) $data['count']);
|
||||
$xmlFile->appendChild($xmlLine);
|
||||
}
|
||||
|
||||
$linesOfCode = $item->linesOfCode();
|
||||
|
||||
$xmlMetrics = $xmlDocument->createElement('metrics');
|
||||
$xmlMetrics->setAttribute('loc', (string) $linesOfCode->linesOfCode());
|
||||
$xmlMetrics->setAttribute('ncloc', (string) $linesOfCode->nonCommentLinesOfCode());
|
||||
$xmlMetrics->setAttribute('classes', (string) $item->numberOfClassesAndTraits());
|
||||
$xmlMetrics->setAttribute('methods', (string) $item->numberOfMethods());
|
||||
$xmlMetrics->setAttribute('coveredmethods', (string) $item->numberOfTestedMethods());
|
||||
$xmlMetrics->setAttribute('conditionals', (string) $item->numberOfExecutableBranches());
|
||||
$xmlMetrics->setAttribute('coveredconditionals', (string) $item->numberOfExecutedBranches());
|
||||
$xmlMetrics->setAttribute('statements', (string) $item->numberOfExecutableLines());
|
||||
$xmlMetrics->setAttribute('coveredstatements', (string) $item->numberOfExecutedLines());
|
||||
$xmlMetrics->setAttribute('elements', (string) ($item->numberOfMethods() + $item->numberOfExecutableLines() + $item->numberOfExecutableBranches()));
|
||||
$xmlMetrics->setAttribute('coveredelements', (string) ($item->numberOfTestedMethods() + $item->numberOfExecutedLines() + $item->numberOfExecutedBranches()));
|
||||
$xmlFile->appendChild($xmlMetrics);
|
||||
|
||||
if ($namespace === 'global') {
|
||||
$xmlProject->appendChild($xmlFile);
|
||||
} else {
|
||||
if (!isset($packages[$namespace])) {
|
||||
$packages[$namespace] = $xmlDocument->createElement(
|
||||
'package'
|
||||
);
|
||||
|
||||
$packages[$namespace]->setAttribute('name', $namespace);
|
||||
$xmlProject->appendChild($packages[$namespace]);
|
||||
}
|
||||
|
||||
$packages[$namespace]->appendChild($xmlFile);
|
||||
}
|
||||
}
|
||||
|
||||
$linesOfCode = $report->linesOfCode();
|
||||
|
||||
$xmlMetrics = $xmlDocument->createElement('metrics');
|
||||
$xmlMetrics->setAttribute('files', (string) count($report));
|
||||
$xmlMetrics->setAttribute('loc', (string) $linesOfCode->linesOfCode());
|
||||
$xmlMetrics->setAttribute('ncloc', (string) $linesOfCode->nonCommentLinesOfCode());
|
||||
$xmlMetrics->setAttribute('classes', (string) $report->numberOfClassesAndTraits());
|
||||
$xmlMetrics->setAttribute('methods', (string) $report->numberOfMethods());
|
||||
$xmlMetrics->setAttribute('coveredmethods', (string) $report->numberOfTestedMethods());
|
||||
$xmlMetrics->setAttribute('conditionals', (string) $report->numberOfExecutableBranches());
|
||||
$xmlMetrics->setAttribute('coveredconditionals', (string) $report->numberOfExecutedBranches());
|
||||
$xmlMetrics->setAttribute('statements', (string) $report->numberOfExecutableLines());
|
||||
$xmlMetrics->setAttribute('coveredstatements', (string) $report->numberOfExecutedLines());
|
||||
$xmlMetrics->setAttribute('elements', (string) ($report->numberOfMethods() + $report->numberOfExecutableLines() + $report->numberOfExecutableBranches()));
|
||||
$xmlMetrics->setAttribute('coveredelements', (string) ($report->numberOfTestedMethods() + $report->numberOfExecutedLines() + $report->numberOfExecutedBranches()));
|
||||
$xmlProject->appendChild($xmlMetrics);
|
||||
|
||||
$buffer = $xmlDocument->saveXML();
|
||||
|
||||
if ($target !== null) {
|
||||
Directory::create(dirname($target));
|
||||
|
||||
if (@file_put_contents($target, $buffer) === false) {
|
||||
throw new WriteOperationFailedException($target);
|
||||
}
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
}
|
304
vendor/phpunit/php-code-coverage/src/Report/Cobertura.php
vendored
Normal file
304
vendor/phpunit/php-code-coverage/src/Report/Cobertura.php
vendored
Normal file
@ -0,0 +1,304 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report;
|
||||
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function file_put_contents;
|
||||
use function range;
|
||||
use function time;
|
||||
use DOMImplementation;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Directory;
|
||||
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
|
||||
use SebastianBergmann\CodeCoverage\Node\File;
|
||||
|
||||
final class Cobertura
|
||||
{
|
||||
/**
|
||||
* @throws WriteOperationFailedException
|
||||
*/
|
||||
public function process(CodeCoverage $coverage, ?string $target = null, ?string $name = null): string
|
||||
{
|
||||
$time = (string) time();
|
||||
|
||||
$report = $coverage->getReport();
|
||||
|
||||
$implementation = new DOMImplementation;
|
||||
|
||||
$documentType = $implementation->createDocumentType(
|
||||
'coverage',
|
||||
'',
|
||||
'http://cobertura.sourceforge.net/xml/coverage-04.dtd'
|
||||
);
|
||||
|
||||
$document = $implementation->createDocument('', '', $documentType);
|
||||
$document->xmlVersion = '1.0';
|
||||
$document->encoding = 'UTF-8';
|
||||
$document->formatOutput = true;
|
||||
|
||||
$coverageElement = $document->createElement('coverage');
|
||||
|
||||
$linesValid = $report->numberOfExecutableLines();
|
||||
$linesCovered = $report->numberOfExecutedLines();
|
||||
$lineRate = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
|
||||
$coverageElement->setAttribute('line-rate', (string) $lineRate);
|
||||
|
||||
$branchesValid = $report->numberOfExecutableBranches();
|
||||
$branchesCovered = $report->numberOfExecutedBranches();
|
||||
$branchRate = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
|
||||
$coverageElement->setAttribute('branch-rate', (string) $branchRate);
|
||||
|
||||
$coverageElement->setAttribute('lines-covered', (string) $report->numberOfExecutedLines());
|
||||
$coverageElement->setAttribute('lines-valid', (string) $report->numberOfExecutableLines());
|
||||
$coverageElement->setAttribute('branches-covered', (string) $report->numberOfExecutedBranches());
|
||||
$coverageElement->setAttribute('branches-valid', (string) $report->numberOfExecutableBranches());
|
||||
$coverageElement->setAttribute('complexity', '');
|
||||
$coverageElement->setAttribute('version', '0.4');
|
||||
$coverageElement->setAttribute('timestamp', $time);
|
||||
|
||||
$document->appendChild($coverageElement);
|
||||
|
||||
$sourcesElement = $document->createElement('sources');
|
||||
$coverageElement->appendChild($sourcesElement);
|
||||
|
||||
$sourceElement = $document->createElement('source', $report->pathAsString());
|
||||
$sourcesElement->appendChild($sourceElement);
|
||||
|
||||
$packagesElement = $document->createElement('packages');
|
||||
$coverageElement->appendChild($packagesElement);
|
||||
|
||||
$complexity = 0;
|
||||
|
||||
foreach ($report as $item) {
|
||||
if (!$item instanceof File) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$packageElement = $document->createElement('package');
|
||||
$packageComplexity = 0;
|
||||
$packageName = $name ?? '';
|
||||
|
||||
$packageElement->setAttribute('name', $packageName);
|
||||
|
||||
$linesValid = $item->numberOfExecutableLines();
|
||||
$linesCovered = $item->numberOfExecutedLines();
|
||||
$lineRate = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
|
||||
|
||||
$packageElement->setAttribute('line-rate', (string) $lineRate);
|
||||
|
||||
$branchesValid = $item->numberOfExecutableBranches();
|
||||
$branchesCovered = $item->numberOfExecutedBranches();
|
||||
$branchRate = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
|
||||
|
||||
$packageElement->setAttribute('branch-rate', (string) $branchRate);
|
||||
|
||||
$packageElement->setAttribute('complexity', '');
|
||||
$packagesElement->appendChild($packageElement);
|
||||
|
||||
$classesElement = $document->createElement('classes');
|
||||
|
||||
$packageElement->appendChild($classesElement);
|
||||
|
||||
$classes = $item->classesAndTraits();
|
||||
$coverageData = $item->lineCoverageData();
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
$complexity += $class['ccn'];
|
||||
$packageComplexity += $class['ccn'];
|
||||
|
||||
if (!empty($class['package']['namespace'])) {
|
||||
$className = $class['package']['namespace'] . '\\' . $className;
|
||||
}
|
||||
|
||||
$linesValid = $class['executableLines'];
|
||||
$linesCovered = $class['executedLines'];
|
||||
$lineRate = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
|
||||
|
||||
$branchesValid = $class['executableBranches'];
|
||||
$branchesCovered = $class['executedBranches'];
|
||||
$branchRate = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
|
||||
|
||||
$classElement = $document->createElement('class');
|
||||
|
||||
$classElement->setAttribute('name', $className);
|
||||
$classElement->setAttribute('filename', str_replace($report->pathAsString() . DIRECTORY_SEPARATOR, '', $item->pathAsString()));
|
||||
$classElement->setAttribute('line-rate', (string) $lineRate);
|
||||
$classElement->setAttribute('branch-rate', (string) $branchRate);
|
||||
$classElement->setAttribute('complexity', (string) $class['ccn']);
|
||||
|
||||
$classesElement->appendChild($classElement);
|
||||
|
||||
$methodsElement = $document->createElement('methods');
|
||||
|
||||
$classElement->appendChild($methodsElement);
|
||||
|
||||
$classLinesElement = $document->createElement('lines');
|
||||
|
||||
$classElement->appendChild($classLinesElement);
|
||||
|
||||
foreach ($class['methods'] as $methodName => $method) {
|
||||
if ($method['executableLines'] === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
preg_match("/\((.*?)\)/", $method['signature'], $signature);
|
||||
|
||||
$linesValid = $method['executableLines'];
|
||||
$linesCovered = $method['executedLines'];
|
||||
$lineRate = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
|
||||
|
||||
$branchesValid = $method['executableBranches'];
|
||||
$branchesCovered = $method['executedBranches'];
|
||||
$branchRate = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
|
||||
|
||||
$methodElement = $document->createElement('method');
|
||||
|
||||
$methodElement->setAttribute('name', $methodName);
|
||||
$methodElement->setAttribute('signature', $signature[1]);
|
||||
$methodElement->setAttribute('line-rate', (string) $lineRate);
|
||||
$methodElement->setAttribute('branch-rate', (string) $branchRate);
|
||||
$methodElement->setAttribute('complexity', (string) $method['ccn']);
|
||||
|
||||
$methodLinesElement = $document->createElement('lines');
|
||||
|
||||
$methodElement->appendChild($methodLinesElement);
|
||||
|
||||
foreach (range($method['startLine'], $method['endLine']) as $line) {
|
||||
if (!isset($coverageData[$line]) || $coverageData[$line] === null) {
|
||||
continue;
|
||||
}
|
||||
$methodLineElement = $document->createElement('line');
|
||||
|
||||
$methodLineElement->setAttribute('number', (string) $line);
|
||||
$methodLineElement->setAttribute('hits', (string) count($coverageData[$line]));
|
||||
|
||||
$methodLinesElement->appendChild($methodLineElement);
|
||||
|
||||
$classLineElement = $methodLineElement->cloneNode();
|
||||
|
||||
$classLinesElement->appendChild($classLineElement);
|
||||
}
|
||||
|
||||
$methodsElement->appendChild($methodElement);
|
||||
}
|
||||
}
|
||||
|
||||
if ($report->numberOfFunctions() === 0) {
|
||||
$packageElement->setAttribute('complexity', (string) $packageComplexity);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$functionsComplexity = 0;
|
||||
$functionsLinesValid = 0;
|
||||
$functionsLinesCovered = 0;
|
||||
$functionsBranchesValid = 0;
|
||||
$functionsBranchesCovered = 0;
|
||||
|
||||
$classElement = $document->createElement('class');
|
||||
$classElement->setAttribute('name', basename($item->pathAsString()));
|
||||
$classElement->setAttribute('filename', str_replace($report->pathAsString() . DIRECTORY_SEPARATOR, '', $item->pathAsString()));
|
||||
|
||||
$methodsElement = $document->createElement('methods');
|
||||
|
||||
$classElement->appendChild($methodsElement);
|
||||
|
||||
$classLinesElement = $document->createElement('lines');
|
||||
|
||||
$classElement->appendChild($classLinesElement);
|
||||
|
||||
$functions = $report->functions();
|
||||
|
||||
foreach ($functions as $functionName => $function) {
|
||||
if ($function['executableLines'] === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$complexity += $function['ccn'];
|
||||
$packageComplexity += $function['ccn'];
|
||||
$functionsComplexity += $function['ccn'];
|
||||
|
||||
$linesValid = $function['executableLines'];
|
||||
$linesCovered = $function['executedLines'];
|
||||
$lineRate = $linesValid === 0 ? 0 : ($linesCovered / $linesValid);
|
||||
|
||||
$functionsLinesValid += $linesValid;
|
||||
$functionsLinesCovered += $linesCovered;
|
||||
|
||||
$branchesValid = $function['executableBranches'];
|
||||
$branchesCovered = $function['executedBranches'];
|
||||
$branchRate = $branchesValid === 0 ? 0 : ($branchesCovered / $branchesValid);
|
||||
|
||||
$functionsBranchesValid += $branchesValid;
|
||||
$functionsBranchesCovered += $branchesValid;
|
||||
|
||||
$methodElement = $document->createElement('method');
|
||||
|
||||
$methodElement->setAttribute('name', $functionName);
|
||||
$methodElement->setAttribute('signature', $function['signature']);
|
||||
$methodElement->setAttribute('line-rate', (string) $lineRate);
|
||||
$methodElement->setAttribute('branch-rate', (string) $branchRate);
|
||||
$methodElement->setAttribute('complexity', (string) $function['ccn']);
|
||||
|
||||
$methodLinesElement = $document->createElement('lines');
|
||||
|
||||
$methodElement->appendChild($methodLinesElement);
|
||||
|
||||
foreach (range($function['startLine'], $function['endLine']) as $line) {
|
||||
if (!isset($coverageData[$line]) || $coverageData[$line] === null) {
|
||||
continue;
|
||||
}
|
||||
$methodLineElement = $document->createElement('line');
|
||||
|
||||
$methodLineElement->setAttribute('number', (string) $line);
|
||||
$methodLineElement->setAttribute('hits', (string) count($coverageData[$line]));
|
||||
|
||||
$methodLinesElement->appendChild($methodLineElement);
|
||||
|
||||
$classLineElement = $methodLineElement->cloneNode();
|
||||
|
||||
$classLinesElement->appendChild($classLineElement);
|
||||
}
|
||||
|
||||
$methodsElement->appendChild($methodElement);
|
||||
}
|
||||
|
||||
$packageElement->setAttribute('complexity', (string) $packageComplexity);
|
||||
|
||||
if ($functionsLinesValid === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lineRate = $functionsLinesCovered / $functionsLinesValid;
|
||||
$branchRate = $functionsBranchesValid === 0 ? 0 : ($functionsBranchesCovered / $functionsBranchesValid);
|
||||
|
||||
$classElement->setAttribute('line-rate', (string) $lineRate);
|
||||
$classElement->setAttribute('branch-rate', (string) $branchRate);
|
||||
$classElement->setAttribute('complexity', (string) $functionsComplexity);
|
||||
|
||||
$classesElement->appendChild($classElement);
|
||||
}
|
||||
|
||||
$coverageElement->setAttribute('complexity', (string) $complexity);
|
||||
|
||||
$buffer = $document->saveXML();
|
||||
|
||||
if ($target !== null) {
|
||||
Directory::create(dirname($target));
|
||||
|
||||
if (@file_put_contents($target, $buffer) === false) {
|
||||
throw new WriteOperationFailedException($target);
|
||||
}
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
}
|
153
vendor/phpunit/php-code-coverage/src/Report/Crap4j.php
vendored
Normal file
153
vendor/phpunit/php-code-coverage/src/Report/Crap4j.php
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report;
|
||||
|
||||
use function date;
|
||||
use function dirname;
|
||||
use function file_put_contents;
|
||||
use function htmlspecialchars;
|
||||
use function is_string;
|
||||
use function round;
|
||||
use DOMDocument;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Directory;
|
||||
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
|
||||
use SebastianBergmann\CodeCoverage\Node\File;
|
||||
|
||||
final class Crap4j
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $threshold;
|
||||
|
||||
public function __construct(int $threshold = 30)
|
||||
{
|
||||
$this->threshold = $threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws WriteOperationFailedException
|
||||
*/
|
||||
public function process(CodeCoverage $coverage, ?string $target = null, ?string $name = null): string
|
||||
{
|
||||
$document = new DOMDocument('1.0', 'UTF-8');
|
||||
$document->formatOutput = true;
|
||||
|
||||
$root = $document->createElement('crap_result');
|
||||
$document->appendChild($root);
|
||||
|
||||
$project = $document->createElement('project', is_string($name) ? $name : '');
|
||||
$root->appendChild($project);
|
||||
$root->appendChild($document->createElement('timestamp', date('Y-m-d H:i:s')));
|
||||
|
||||
$stats = $document->createElement('stats');
|
||||
$methodsNode = $document->createElement('methods');
|
||||
|
||||
$report = $coverage->getReport();
|
||||
unset($coverage);
|
||||
|
||||
$fullMethodCount = 0;
|
||||
$fullCrapMethodCount = 0;
|
||||
$fullCrapLoad = 0;
|
||||
$fullCrap = 0;
|
||||
|
||||
foreach ($report as $item) {
|
||||
$namespace = 'global';
|
||||
|
||||
if (!$item instanceof File) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$file = $document->createElement('file');
|
||||
$file->setAttribute('name', $item->pathAsString());
|
||||
|
||||
$classes = $item->classesAndTraits();
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
foreach ($class['methods'] as $methodName => $method) {
|
||||
$crapLoad = $this->crapLoad((float) $method['crap'], $method['ccn'], $method['coverage']);
|
||||
|
||||
$fullCrap += $method['crap'];
|
||||
$fullCrapLoad += $crapLoad;
|
||||
$fullMethodCount++;
|
||||
|
||||
if ($method['crap'] >= $this->threshold) {
|
||||
$fullCrapMethodCount++;
|
||||
}
|
||||
|
||||
$methodNode = $document->createElement('method');
|
||||
|
||||
if (!empty($class['namespace'])) {
|
||||
$namespace = $class['namespace'];
|
||||
}
|
||||
|
||||
$methodNode->appendChild($document->createElement('package', $namespace));
|
||||
$methodNode->appendChild($document->createElement('className', $className));
|
||||
$methodNode->appendChild($document->createElement('methodName', $methodName));
|
||||
$methodNode->appendChild($document->createElement('methodSignature', htmlspecialchars($method['signature'])));
|
||||
$methodNode->appendChild($document->createElement('fullMethod', htmlspecialchars($method['signature'])));
|
||||
$methodNode->appendChild($document->createElement('crap', (string) $this->roundValue((float) $method['crap'])));
|
||||
$methodNode->appendChild($document->createElement('complexity', (string) $method['ccn']));
|
||||
$methodNode->appendChild($document->createElement('coverage', (string) $this->roundValue($method['coverage'])));
|
||||
$methodNode->appendChild($document->createElement('crapLoad', (string) round($crapLoad)));
|
||||
|
||||
$methodsNode->appendChild($methodNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$stats->appendChild($document->createElement('name', 'Method Crap Stats'));
|
||||
$stats->appendChild($document->createElement('methodCount', (string) $fullMethodCount));
|
||||
$stats->appendChild($document->createElement('crapMethodCount', (string) $fullCrapMethodCount));
|
||||
$stats->appendChild($document->createElement('crapLoad', (string) round($fullCrapLoad)));
|
||||
$stats->appendChild($document->createElement('totalCrap', (string) $fullCrap));
|
||||
|
||||
$crapMethodPercent = 0;
|
||||
|
||||
if ($fullMethodCount > 0) {
|
||||
$crapMethodPercent = $this->roundValue((100 * $fullCrapMethodCount) / $fullMethodCount);
|
||||
}
|
||||
|
||||
$stats->appendChild($document->createElement('crapMethodPercent', (string) $crapMethodPercent));
|
||||
|
||||
$root->appendChild($stats);
|
||||
$root->appendChild($methodsNode);
|
||||
|
||||
$buffer = $document->saveXML();
|
||||
|
||||
if ($target !== null) {
|
||||
Directory::create(dirname($target));
|
||||
|
||||
if (@file_put_contents($target, $buffer) === false) {
|
||||
throw new WriteOperationFailedException($target);
|
||||
}
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
private function crapLoad(float $crapValue, int $cyclomaticComplexity, float $coveragePercent): float
|
||||
{
|
||||
$crapLoad = 0;
|
||||
|
||||
if ($crapValue >= $this->threshold) {
|
||||
$crapLoad += $cyclomaticComplexity * (1.0 - $coveragePercent / 100);
|
||||
$crapLoad += $cyclomaticComplexity / $this->threshold;
|
||||
}
|
||||
|
||||
return $crapLoad;
|
||||
}
|
||||
|
||||
private function roundValue(float $value): float
|
||||
{
|
||||
return round($value, 2);
|
||||
}
|
||||
}
|
140
vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php
vendored
Normal file
140
vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Html;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use function copy;
|
||||
use function date;
|
||||
use function dirname;
|
||||
use function substr;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Directory as DirectoryUtil;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
|
||||
final class Facade
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $templatePath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $generator;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $lowUpperBound;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $highLowerBound;
|
||||
|
||||
public function __construct(int $lowUpperBound = 50, int $highLowerBound = 90, string $generator = '')
|
||||
{
|
||||
$this->generator = $generator;
|
||||
$this->highLowerBound = $highLowerBound;
|
||||
$this->lowUpperBound = $lowUpperBound;
|
||||
$this->templatePath = __DIR__ . '/Renderer/Template/';
|
||||
}
|
||||
|
||||
public function process(CodeCoverage $coverage, string $target): void
|
||||
{
|
||||
$target = $this->directory($target);
|
||||
$report = $coverage->getReport();
|
||||
$date = date('D M j G:i:s T Y');
|
||||
|
||||
$dashboard = new Dashboard(
|
||||
$this->templatePath,
|
||||
$this->generator,
|
||||
$date,
|
||||
$this->lowUpperBound,
|
||||
$this->highLowerBound,
|
||||
$coverage->collectsBranchAndPathCoverage()
|
||||
);
|
||||
|
||||
$directory = new Directory(
|
||||
$this->templatePath,
|
||||
$this->generator,
|
||||
$date,
|
||||
$this->lowUpperBound,
|
||||
$this->highLowerBound,
|
||||
$coverage->collectsBranchAndPathCoverage()
|
||||
);
|
||||
|
||||
$file = new File(
|
||||
$this->templatePath,
|
||||
$this->generator,
|
||||
$date,
|
||||
$this->lowUpperBound,
|
||||
$this->highLowerBound,
|
||||
$coverage->collectsBranchAndPathCoverage()
|
||||
);
|
||||
|
||||
$directory->render($report, $target . 'index.html');
|
||||
$dashboard->render($report, $target . 'dashboard.html');
|
||||
|
||||
foreach ($report as $node) {
|
||||
$id = $node->id();
|
||||
|
||||
if ($node instanceof DirectoryNode) {
|
||||
DirectoryUtil::create($target . $id);
|
||||
|
||||
$directory->render($node, $target . $id . '/index.html');
|
||||
$dashboard->render($node, $target . $id . '/dashboard.html');
|
||||
} else {
|
||||
$dir = dirname($target . $id);
|
||||
|
||||
DirectoryUtil::create($dir);
|
||||
|
||||
$file->render($node, $target . $id);
|
||||
}
|
||||
}
|
||||
|
||||
$this->copyFiles($target);
|
||||
}
|
||||
|
||||
private function copyFiles(string $target): void
|
||||
{
|
||||
$dir = $this->directory($target . '_css');
|
||||
|
||||
copy($this->templatePath . 'css/bootstrap.min.css', $dir . 'bootstrap.min.css');
|
||||
copy($this->templatePath . 'css/nv.d3.min.css', $dir . 'nv.d3.min.css');
|
||||
copy($this->templatePath . 'css/style.css', $dir . 'style.css');
|
||||
copy($this->templatePath . 'css/custom.css', $dir . 'custom.css');
|
||||
copy($this->templatePath . 'css/octicons.css', $dir . 'octicons.css');
|
||||
|
||||
$dir = $this->directory($target . '_icons');
|
||||
copy($this->templatePath . 'icons/file-code.svg', $dir . 'file-code.svg');
|
||||
copy($this->templatePath . 'icons/file-directory.svg', $dir . 'file-directory.svg');
|
||||
|
||||
$dir = $this->directory($target . '_js');
|
||||
copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js');
|
||||
copy($this->templatePath . 'js/popper.min.js', $dir . 'popper.min.js');
|
||||
copy($this->templatePath . 'js/d3.min.js', $dir . 'd3.min.js');
|
||||
copy($this->templatePath . 'js/jquery.min.js', $dir . 'jquery.min.js');
|
||||
copy($this->templatePath . 'js/nv.d3.min.js', $dir . 'nv.d3.min.js');
|
||||
copy($this->templatePath . 'js/file.js', $dir . 'file.js');
|
||||
}
|
||||
|
||||
private function directory(string $directory): string
|
||||
{
|
||||
if (substr($directory, -1, 1) != DIRECTORY_SEPARATOR) {
|
||||
$directory .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
DirectoryUtil::create($directory);
|
||||
|
||||
return $directory;
|
||||
}
|
||||
}
|
314
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php
vendored
Normal file
314
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php
vendored
Normal file
@ -0,0 +1,314 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Html;
|
||||
|
||||
use function array_pop;
|
||||
use function count;
|
||||
use function sprintf;
|
||||
use function str_repeat;
|
||||
use function substr_count;
|
||||
use SebastianBergmann\CodeCoverage\Node\AbstractNode;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
use SebastianBergmann\CodeCoverage\Node\File as FileNode;
|
||||
use SebastianBergmann\CodeCoverage\Version;
|
||||
use SebastianBergmann\Environment\Runtime;
|
||||
use SebastianBergmann\Template\Template;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
abstract class Renderer
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $templatePath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $generator;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $date;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $lowUpperBound;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $highLowerBound;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $hasBranchCoverage;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $version;
|
||||
|
||||
public function __construct(string $templatePath, string $generator, string $date, int $lowUpperBound, int $highLowerBound, bool $hasBranchCoverage)
|
||||
{
|
||||
$this->templatePath = $templatePath;
|
||||
$this->generator = $generator;
|
||||
$this->date = $date;
|
||||
$this->lowUpperBound = $lowUpperBound;
|
||||
$this->highLowerBound = $highLowerBound;
|
||||
$this->version = Version::id();
|
||||
$this->hasBranchCoverage = $hasBranchCoverage;
|
||||
}
|
||||
|
||||
protected function renderItemTemplate(Template $template, array $data): string
|
||||
{
|
||||
$numSeparator = ' / ';
|
||||
|
||||
if (isset($data['numClasses']) && $data['numClasses'] > 0) {
|
||||
$classesLevel = $this->colorLevel($data['testedClassesPercent']);
|
||||
|
||||
$classesNumber = $data['numTestedClasses'] . $numSeparator .
|
||||
$data['numClasses'];
|
||||
|
||||
$classesBar = $this->coverageBar(
|
||||
$data['testedClassesPercent']
|
||||
);
|
||||
} else {
|
||||
$classesLevel = '';
|
||||
$classesNumber = '0' . $numSeparator . '0';
|
||||
$classesBar = '';
|
||||
$data['testedClassesPercentAsString'] = 'n/a';
|
||||
}
|
||||
|
||||
if ($data['numMethods'] > 0) {
|
||||
$methodsLevel = $this->colorLevel($data['testedMethodsPercent']);
|
||||
|
||||
$methodsNumber = $data['numTestedMethods'] . $numSeparator .
|
||||
$data['numMethods'];
|
||||
|
||||
$methodsBar = $this->coverageBar(
|
||||
$data['testedMethodsPercent']
|
||||
);
|
||||
} else {
|
||||
$methodsLevel = '';
|
||||
$methodsNumber = '0' . $numSeparator . '0';
|
||||
$methodsBar = '';
|
||||
$data['testedMethodsPercentAsString'] = 'n/a';
|
||||
}
|
||||
|
||||
if ($data['numExecutableLines'] > 0) {
|
||||
$linesLevel = $this->colorLevel($data['linesExecutedPercent']);
|
||||
|
||||
$linesNumber = $data['numExecutedLines'] . $numSeparator .
|
||||
$data['numExecutableLines'];
|
||||
|
||||
$linesBar = $this->coverageBar(
|
||||
$data['linesExecutedPercent']
|
||||
);
|
||||
} else {
|
||||
$linesLevel = '';
|
||||
$linesNumber = '0' . $numSeparator . '0';
|
||||
$linesBar = '';
|
||||
$data['linesExecutedPercentAsString'] = 'n/a';
|
||||
}
|
||||
|
||||
if ($data['numExecutablePaths'] > 0) {
|
||||
$pathsLevel = $this->colorLevel($data['pathsExecutedPercent']);
|
||||
|
||||
$pathsNumber = $data['numExecutedPaths'] . $numSeparator .
|
||||
$data['numExecutablePaths'];
|
||||
|
||||
$pathsBar = $this->coverageBar(
|
||||
$data['pathsExecutedPercent']
|
||||
);
|
||||
} else {
|
||||
$pathsLevel = '';
|
||||
$pathsNumber = '0' . $numSeparator . '0';
|
||||
$pathsBar = '';
|
||||
$data['pathsExecutedPercentAsString'] = 'n/a';
|
||||
}
|
||||
|
||||
if ($data['numExecutableBranches'] > 0) {
|
||||
$branchesLevel = $this->colorLevel($data['branchesExecutedPercent']);
|
||||
|
||||
$branchesNumber = $data['numExecutedBranches'] . $numSeparator .
|
||||
$data['numExecutableBranches'];
|
||||
|
||||
$branchesBar = $this->coverageBar(
|
||||
$data['branchesExecutedPercent']
|
||||
);
|
||||
} else {
|
||||
$branchesLevel = '';
|
||||
$branchesNumber = '0' . $numSeparator . '0';
|
||||
$branchesBar = '';
|
||||
$data['branchesExecutedPercentAsString'] = 'n/a';
|
||||
}
|
||||
|
||||
$template->setVar(
|
||||
[
|
||||
'icon' => $data['icon'] ?? '',
|
||||
'crap' => $data['crap'] ?? '',
|
||||
'name' => $data['name'],
|
||||
'lines_bar' => $linesBar,
|
||||
'lines_executed_percent' => $data['linesExecutedPercentAsString'],
|
||||
'lines_level' => $linesLevel,
|
||||
'lines_number' => $linesNumber,
|
||||
'paths_bar' => $pathsBar,
|
||||
'paths_executed_percent' => $data['pathsExecutedPercentAsString'],
|
||||
'paths_level' => $pathsLevel,
|
||||
'paths_number' => $pathsNumber,
|
||||
'branches_bar' => $branchesBar,
|
||||
'branches_executed_percent' => $data['branchesExecutedPercentAsString'],
|
||||
'branches_level' => $branchesLevel,
|
||||
'branches_number' => $branchesNumber,
|
||||
'methods_bar' => $methodsBar,
|
||||
'methods_tested_percent' => $data['testedMethodsPercentAsString'],
|
||||
'methods_level' => $methodsLevel,
|
||||
'methods_number' => $methodsNumber,
|
||||
'classes_bar' => $classesBar,
|
||||
'classes_tested_percent' => $data['testedClassesPercentAsString'] ?? '',
|
||||
'classes_level' => $classesLevel,
|
||||
'classes_number' => $classesNumber,
|
||||
]
|
||||
);
|
||||
|
||||
return $template->render();
|
||||
}
|
||||
|
||||
protected function setCommonTemplateVariables(Template $template, AbstractNode $node): void
|
||||
{
|
||||
$template->setVar(
|
||||
[
|
||||
'id' => $node->id(),
|
||||
'full_path' => $node->pathAsString(),
|
||||
'path_to_root' => $this->pathToRoot($node),
|
||||
'breadcrumbs' => $this->breadcrumbs($node),
|
||||
'date' => $this->date,
|
||||
'version' => $this->version,
|
||||
'runtime' => $this->runtimeString(),
|
||||
'generator' => $this->generator,
|
||||
'low_upper_bound' => $this->lowUpperBound,
|
||||
'high_lower_bound' => $this->highLowerBound,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function breadcrumbs(AbstractNode $node): string
|
||||
{
|
||||
$breadcrumbs = '';
|
||||
$path = $node->pathAsArray();
|
||||
$pathToRoot = [];
|
||||
$max = count($path);
|
||||
|
||||
if ($node instanceof FileNode) {
|
||||
$max--;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $max; $i++) {
|
||||
$pathToRoot[] = str_repeat('../', $i);
|
||||
}
|
||||
|
||||
foreach ($path as $step) {
|
||||
if ($step !== $node) {
|
||||
$breadcrumbs .= $this->inactiveBreadcrumb(
|
||||
$step,
|
||||
array_pop($pathToRoot)
|
||||
);
|
||||
} else {
|
||||
$breadcrumbs .= $this->activeBreadcrumb($step);
|
||||
}
|
||||
}
|
||||
|
||||
return $breadcrumbs;
|
||||
}
|
||||
|
||||
protected function activeBreadcrumb(AbstractNode $node): string
|
||||
{
|
||||
$buffer = sprintf(
|
||||
' <li class="breadcrumb-item active">%s</li>' . "\n",
|
||||
$node->name()
|
||||
);
|
||||
|
||||
if ($node instanceof DirectoryNode) {
|
||||
$buffer .= ' <li class="breadcrumb-item">(<a href="dashboard.html">Dashboard</a>)</li>' . "\n";
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
protected function inactiveBreadcrumb(AbstractNode $node, string $pathToRoot): string
|
||||
{
|
||||
return sprintf(
|
||||
' <li class="breadcrumb-item"><a href="%sindex.html">%s</a></li>' . "\n",
|
||||
$pathToRoot,
|
||||
$node->name()
|
||||
);
|
||||
}
|
||||
|
||||
protected function pathToRoot(AbstractNode $node): string
|
||||
{
|
||||
$id = $node->id();
|
||||
$depth = substr_count($id, '/');
|
||||
|
||||
if ($id !== 'index' &&
|
||||
$node instanceof DirectoryNode) {
|
||||
$depth++;
|
||||
}
|
||||
|
||||
return str_repeat('../', $depth);
|
||||
}
|
||||
|
||||
protected function coverageBar(float $percent): string
|
||||
{
|
||||
$level = $this->colorLevel($percent);
|
||||
|
||||
$templateName = $this->templatePath . ($this->hasBranchCoverage ? 'coverage_bar_branch.html' : 'coverage_bar.html');
|
||||
$template = new Template(
|
||||
$templateName,
|
||||
'{{',
|
||||
'}}'
|
||||
);
|
||||
|
||||
$template->setVar(['level' => $level, 'percent' => sprintf('%.2F', $percent)]);
|
||||
|
||||
return $template->render();
|
||||
}
|
||||
|
||||
protected function colorLevel(float $percent): string
|
||||
{
|
||||
if ($percent <= $this->lowUpperBound) {
|
||||
return 'danger';
|
||||
}
|
||||
|
||||
if ($percent > $this->lowUpperBound &&
|
||||
$percent < $this->highLowerBound) {
|
||||
return 'warning';
|
||||
}
|
||||
|
||||
return 'success';
|
||||
}
|
||||
|
||||
private function runtimeString(): string
|
||||
{
|
||||
$runtime = new Runtime;
|
||||
|
||||
return sprintf(
|
||||
'<a href="%s" target="_top">%s %s</a>',
|
||||
$runtime->getVendorUrl(),
|
||||
$runtime->getName(),
|
||||
$runtime->getVersion()
|
||||
);
|
||||
}
|
||||
}
|
288
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php
vendored
Normal file
288
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php
vendored
Normal file
@ -0,0 +1,288 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Html;
|
||||
|
||||
use function array_values;
|
||||
use function arsort;
|
||||
use function asort;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function floor;
|
||||
use function json_encode;
|
||||
use function sprintf;
|
||||
use function str_replace;
|
||||
use SebastianBergmann\CodeCoverage\Node\AbstractNode;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
use SebastianBergmann\Template\Template;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Dashboard extends Renderer
|
||||
{
|
||||
public function render(DirectoryNode $node, string $file): void
|
||||
{
|
||||
$classes = $node->classesAndTraits();
|
||||
$templateName = $this->templatePath . ($this->hasBranchCoverage ? 'dashboard_branch.html' : 'dashboard.html');
|
||||
$template = new Template(
|
||||
$templateName,
|
||||
'{{',
|
||||
'}}'
|
||||
);
|
||||
|
||||
$this->setCommonTemplateVariables($template, $node);
|
||||
|
||||
$baseLink = $node->id() . '/';
|
||||
$complexity = $this->complexity($classes, $baseLink);
|
||||
$coverageDistribution = $this->coverageDistribution($classes);
|
||||
$insufficientCoverage = $this->insufficientCoverage($classes, $baseLink);
|
||||
$projectRisks = $this->projectRisks($classes, $baseLink);
|
||||
|
||||
$template->setVar(
|
||||
[
|
||||
'insufficient_coverage_classes' => $insufficientCoverage['class'],
|
||||
'insufficient_coverage_methods' => $insufficientCoverage['method'],
|
||||
'project_risks_classes' => $projectRisks['class'],
|
||||
'project_risks_methods' => $projectRisks['method'],
|
||||
'complexity_class' => $complexity['class'],
|
||||
'complexity_method' => $complexity['method'],
|
||||
'class_coverage_distribution' => $coverageDistribution['class'],
|
||||
'method_coverage_distribution' => $coverageDistribution['method'],
|
||||
]
|
||||
);
|
||||
|
||||
$template->renderTo($file);
|
||||
}
|
||||
|
||||
protected function activeBreadcrumb(AbstractNode $node): string
|
||||
{
|
||||
return sprintf(
|
||||
' <li class="breadcrumb-item"><a href="index.html">%s</a></li>' . "\n" .
|
||||
' <li class="breadcrumb-item active">(Dashboard)</li>' . "\n",
|
||||
$node->name()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data for the Class/Method Complexity charts.
|
||||
*/
|
||||
private function complexity(array $classes, string $baseLink): array
|
||||
{
|
||||
$result = ['class' => [], 'method' => []];
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
foreach ($class['methods'] as $methodName => $method) {
|
||||
if ($className !== '*') {
|
||||
$methodName = $className . '::' . $methodName;
|
||||
}
|
||||
|
||||
$result['method'][] = [
|
||||
$method['coverage'],
|
||||
$method['ccn'],
|
||||
sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
str_replace($baseLink, '', $method['link']),
|
||||
$methodName
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
$result['class'][] = [
|
||||
$class['coverage'],
|
||||
$class['ccn'],
|
||||
sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
str_replace($baseLink, '', $class['link']),
|
||||
$className
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'class' => json_encode($result['class']),
|
||||
'method' => json_encode($result['method']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data for the Class / Method Coverage Distribution chart.
|
||||
*/
|
||||
private function coverageDistribution(array $classes): array
|
||||
{
|
||||
$result = [
|
||||
'class' => [
|
||||
'0%' => 0,
|
||||
'0-10%' => 0,
|
||||
'10-20%' => 0,
|
||||
'20-30%' => 0,
|
||||
'30-40%' => 0,
|
||||
'40-50%' => 0,
|
||||
'50-60%' => 0,
|
||||
'60-70%' => 0,
|
||||
'70-80%' => 0,
|
||||
'80-90%' => 0,
|
||||
'90-100%' => 0,
|
||||
'100%' => 0,
|
||||
],
|
||||
'method' => [
|
||||
'0%' => 0,
|
||||
'0-10%' => 0,
|
||||
'10-20%' => 0,
|
||||
'20-30%' => 0,
|
||||
'30-40%' => 0,
|
||||
'40-50%' => 0,
|
||||
'50-60%' => 0,
|
||||
'60-70%' => 0,
|
||||
'70-80%' => 0,
|
||||
'80-90%' => 0,
|
||||
'90-100%' => 0,
|
||||
'100%' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($classes as $class) {
|
||||
foreach ($class['methods'] as $methodName => $method) {
|
||||
if ($method['coverage'] === 0) {
|
||||
$result['method']['0%']++;
|
||||
} elseif ($method['coverage'] === 100) {
|
||||
$result['method']['100%']++;
|
||||
} else {
|
||||
$key = floor($method['coverage'] / 10) * 10;
|
||||
$key = $key . '-' . ($key + 10) . '%';
|
||||
$result['method'][$key]++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($class['coverage'] === 0) {
|
||||
$result['class']['0%']++;
|
||||
} elseif ($class['coverage'] === 100) {
|
||||
$result['class']['100%']++;
|
||||
} else {
|
||||
$key = floor($class['coverage'] / 10) * 10;
|
||||
$key = $key . '-' . ($key + 10) . '%';
|
||||
$result['class'][$key]++;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'class' => json_encode(array_values($result['class'])),
|
||||
'method' => json_encode(array_values($result['method'])),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the classes / methods with insufficient coverage.
|
||||
*/
|
||||
private function insufficientCoverage(array $classes, string $baseLink): array
|
||||
{
|
||||
$leastTestedClasses = [];
|
||||
$leastTestedMethods = [];
|
||||
$result = ['class' => '', 'method' => ''];
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
foreach ($class['methods'] as $methodName => $method) {
|
||||
if ($method['coverage'] < $this->highLowerBound) {
|
||||
$key = $methodName;
|
||||
|
||||
if ($className !== '*') {
|
||||
$key = $className . '::' . $methodName;
|
||||
}
|
||||
|
||||
$leastTestedMethods[$key] = $method['coverage'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($class['coverage'] < $this->highLowerBound) {
|
||||
$leastTestedClasses[$className] = $class['coverage'];
|
||||
}
|
||||
}
|
||||
|
||||
asort($leastTestedClasses);
|
||||
asort($leastTestedMethods);
|
||||
|
||||
foreach ($leastTestedClasses as $className => $coverage) {
|
||||
$result['class'] .= sprintf(
|
||||
' <tr><td><a href="%s">%s</a></td><td class="text-right">%d%%</td></tr>' . "\n",
|
||||
str_replace($baseLink, '', $classes[$className]['link']),
|
||||
$className,
|
||||
$coverage
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($leastTestedMethods as $methodName => $coverage) {
|
||||
[$class, $method] = explode('::', $methodName);
|
||||
|
||||
$result['method'] .= sprintf(
|
||||
' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d%%</td></tr>' . "\n",
|
||||
str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']),
|
||||
$methodName,
|
||||
$method,
|
||||
$coverage
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the project risks according to the CRAP index.
|
||||
*/
|
||||
private function projectRisks(array $classes, string $baseLink): array
|
||||
{
|
||||
$classRisks = [];
|
||||
$methodRisks = [];
|
||||
$result = ['class' => '', 'method' => ''];
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
foreach ($class['methods'] as $methodName => $method) {
|
||||
if ($method['coverage'] < $this->highLowerBound && $method['ccn'] > 1) {
|
||||
$key = $methodName;
|
||||
|
||||
if ($className !== '*') {
|
||||
$key = $className . '::' . $methodName;
|
||||
}
|
||||
|
||||
$methodRisks[$key] = $method['crap'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($class['coverage'] < $this->highLowerBound &&
|
||||
$class['ccn'] > count($class['methods'])) {
|
||||
$classRisks[$className] = $class['crap'];
|
||||
}
|
||||
}
|
||||
|
||||
arsort($classRisks);
|
||||
arsort($methodRisks);
|
||||
|
||||
foreach ($classRisks as $className => $crap) {
|
||||
$result['class'] .= sprintf(
|
||||
' <tr><td><a href="%s">%s</a></td><td class="text-right">%d</td></tr>' . "\n",
|
||||
str_replace($baseLink, '', $classes[$className]['link']),
|
||||
$className,
|
||||
$crap
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($methodRisks as $methodName => $crap) {
|
||||
[$class, $method] = explode('::', $methodName);
|
||||
|
||||
$result['method'] .= sprintf(
|
||||
' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d</td></tr>' . "\n",
|
||||
str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']),
|
||||
$methodName,
|
||||
$method,
|
||||
$crap
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
113
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php
vendored
Normal file
113
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Html;
|
||||
|
||||
use function count;
|
||||
use function sprintf;
|
||||
use function str_repeat;
|
||||
use SebastianBergmann\CodeCoverage\Node\AbstractNode as Node;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
use SebastianBergmann\Template\Template;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Directory extends Renderer
|
||||
{
|
||||
public function render(DirectoryNode $node, string $file): void
|
||||
{
|
||||
$templateName = $this->templatePath . ($this->hasBranchCoverage ? 'directory_branch.html' : 'directory.html');
|
||||
$template = new Template($templateName, '{{', '}}');
|
||||
|
||||
$this->setCommonTemplateVariables($template, $node);
|
||||
|
||||
$items = $this->renderItem($node, true);
|
||||
|
||||
foreach ($node->directories() as $item) {
|
||||
$items .= $this->renderItem($item);
|
||||
}
|
||||
|
||||
foreach ($node->files() as $item) {
|
||||
$items .= $this->renderItem($item);
|
||||
}
|
||||
|
||||
$template->setVar(
|
||||
[
|
||||
'id' => $node->id(),
|
||||
'items' => $items,
|
||||
]
|
||||
);
|
||||
|
||||
$template->renderTo($file);
|
||||
}
|
||||
|
||||
private function renderItem(Node $node, bool $total = false): string
|
||||
{
|
||||
$data = [
|
||||
'numClasses' => $node->numberOfClassesAndTraits(),
|
||||
'numTestedClasses' => $node->numberOfTestedClassesAndTraits(),
|
||||
'numMethods' => $node->numberOfFunctionsAndMethods(),
|
||||
'numTestedMethods' => $node->numberOfTestedFunctionsAndMethods(),
|
||||
'linesExecutedPercent' => $node->percentageOfExecutedLines()->asFloat(),
|
||||
'linesExecutedPercentAsString' => $node->percentageOfExecutedLines()->asString(),
|
||||
'numExecutedLines' => $node->numberOfExecutedLines(),
|
||||
'numExecutableLines' => $node->numberOfExecutableLines(),
|
||||
'branchesExecutedPercent' => $node->percentageOfExecutedBranches()->asFloat(),
|
||||
'branchesExecutedPercentAsString' => $node->percentageOfExecutedBranches()->asString(),
|
||||
'numExecutedBranches' => $node->numberOfExecutedBranches(),
|
||||
'numExecutableBranches' => $node->numberOfExecutableBranches(),
|
||||
'pathsExecutedPercent' => $node->percentageOfExecutedPaths()->asFloat(),
|
||||
'pathsExecutedPercentAsString' => $node->percentageOfExecutedPaths()->asString(),
|
||||
'numExecutedPaths' => $node->numberOfExecutedPaths(),
|
||||
'numExecutablePaths' => $node->numberOfExecutablePaths(),
|
||||
'testedMethodsPercent' => $node->percentageOfTestedFunctionsAndMethods()->asFloat(),
|
||||
'testedMethodsPercentAsString' => $node->percentageOfTestedFunctionsAndMethods()->asString(),
|
||||
'testedClassesPercent' => $node->percentageOfTestedClassesAndTraits()->asFloat(),
|
||||
'testedClassesPercentAsString' => $node->percentageOfTestedClassesAndTraits()->asString(),
|
||||
];
|
||||
|
||||
if ($total) {
|
||||
$data['name'] = 'Total';
|
||||
} else {
|
||||
$up = str_repeat('../', count($node->pathAsArray()) - 2);
|
||||
$data['icon'] = sprintf('<img src="%s_icons/file-code.svg" class="octicon" />', $up);
|
||||
|
||||
if ($node instanceof DirectoryNode) {
|
||||
$data['name'] = sprintf(
|
||||
'<a href="%s/index.html">%s</a>',
|
||||
$node->name(),
|
||||
$node->name()
|
||||
);
|
||||
$data['icon'] = sprintf('<img src="%s_icons/file-directory.svg" class="octicon" />', $up);
|
||||
} elseif ($this->hasBranchCoverage) {
|
||||
$data['name'] = sprintf(
|
||||
'%s <a class="small" href="%s.html">[line]</a> <a class="small" href="%s_branch.html">[branch]</a> <a class="small" href="%s_path.html">[path]</a>',
|
||||
$node->name(),
|
||||
$node->name(),
|
||||
$node->name(),
|
||||
$node->name()
|
||||
);
|
||||
} else {
|
||||
$data['name'] = sprintf(
|
||||
'<a href="%s.html">%s</a>',
|
||||
$node->name(),
|
||||
$node->name()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$templateName = $this->templatePath . ($this->hasBranchCoverage ? 'directory_item_branch.html' : 'directory_item.html');
|
||||
|
||||
return $this->renderItemTemplate(
|
||||
new Template($templateName, '{{', '}}'),
|
||||
$data
|
||||
);
|
||||
}
|
||||
}
|
1149
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php
vendored
Normal file
1149
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/branches.html.dist
vendored
Normal file
9
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/branches.html.dist
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<hr/>
|
||||
<h4>Branches</h4>
|
||||
<p>
|
||||
Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not
|
||||
necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once.
|
||||
Please also be aware that some branches may be implicit rather than explicit, e.g. an <code>if</code> statement
|
||||
<i>always</i> has an <code>else</code> as part of its logical flow even if you didn't write one.
|
||||
</p>
|
||||
{{branches}}
|
5
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist
vendored
Normal file
5
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<div class="progress">
|
||||
<div class="progress-bar bg-{{level}}" role="progressbar" aria-valuenow="{{percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{percent}}%">
|
||||
<span class="sr-only">{{percent}}% covered ({{level}})</span>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,5 @@
|
||||
<div class="progress">
|
||||
<div class="progress-bar bg-{{level}}" role="progressbar" aria-valuenow="{{percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{percent}}%">
|
||||
<span class="sr-only">{{percent}}% covered ({{level}})</span>
|
||||
</div>
|
||||
</div>
|
7
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css
vendored
Normal file
7
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
0
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/custom.css
vendored
Normal file
0
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/custom.css
vendored
Normal file
1
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css
vendored
Normal file
1
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
5
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/octicons.css
vendored
Normal file
5
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/octicons.css
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.octicon {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
fill: currentColor;
|
||||
}
|
127
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css
vendored
Normal file
127
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
body {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.popover {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.octicon {
|
||||
margin-right:.25em;
|
||||
}
|
||||
|
||||
.table-bordered>thead>tr>td {
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.table tbody>tr>td, .table thead>tr>td {
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
|
||||
.table-condensed tbody>tr>td {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.table .progress {
|
||||
margin-bottom: inherit;
|
||||
}
|
||||
|
||||
.table-borderless th, .table-borderless td {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.table tbody tr.covered-by-large-tests, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
|
||||
background-color: #dff0d8;
|
||||
}
|
||||
|
||||
.table tbody tr.covered-by-medium-tests, li.covered-by-medium-tests {
|
||||
background-color: #c3e3b5;
|
||||
}
|
||||
|
||||
.table tbody tr.covered-by-small-tests, li.covered-by-small-tests {
|
||||
background-color: #99cb84;
|
||||
}
|
||||
|
||||
.table tbody tr.danger, .table tbody td.danger, li.danger, span.danger {
|
||||
background-color: #f2dede;
|
||||
}
|
||||
|
||||
.table tbody tr.warning, .table tbody td.warning, li.warning, span.warning {
|
||||
background-color: #fcf8e3;
|
||||
}
|
||||
|
||||
.table tbody td.info {
|
||||
background-color: #d9edf7;
|
||||
}
|
||||
|
||||
td.big {
|
||||
width: 117px;
|
||||
}
|
||||
|
||||
td.small {
|
||||
}
|
||||
|
||||
td.codeLine {
|
||||
font-family: "Source Code Pro", "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
td span.comment {
|
||||
color: #888a85;
|
||||
}
|
||||
|
||||
td span.default {
|
||||
color: #2e3436;
|
||||
}
|
||||
|
||||
td span.html {
|
||||
color: #888a85;
|
||||
}
|
||||
|
||||
td span.keyword {
|
||||
color: #2e3436;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
pre span.string {
|
||||
color: #2e3436;
|
||||
}
|
||||
|
||||
span.success, span.warning, span.danger {
|
||||
margin-right: 2px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#classCoverageDistribution, #classComplexity {
|
||||
height: 200px;
|
||||
width: 475px;
|
||||
}
|
||||
|
||||
#toplink {
|
||||
position: fixed;
|
||||
left: 5px;
|
||||
bottom: 5px;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
svg text {
|
||||
font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: 11px;
|
||||
color: #666;
|
||||
fill: #666;
|
||||
}
|
||||
|
||||
.scrollbox {
|
||||
height:245px;
|
||||
overflow-x:hidden;
|
||||
overflow-y:scroll;
|
||||
}
|
||||
|
||||
table + .structure-heading {
|
||||
border-top: 1px solid lightgrey;
|
||||
padding-top: 0.5em;
|
||||
}
|
281
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist
vendored
Normal file
281
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist
vendored
Normal file
@ -0,0 +1,281 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Dashboard for {{full_path}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}_css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/nv.d3.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/style.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
{{breadcrumbs}}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2>Classes</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Coverage Distribution</h3>
|
||||
<div id="classCoverageDistribution" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Complexity</h3>
|
||||
<div id="classComplexity" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Insufficient Coverage</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th class="text-right">Coverage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{insufficient_coverage_classes}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Project Risks</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{project_risks_classes}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2>Methods</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Coverage Distribution</h3>
|
||||
<div id="methodCoverageDistribution" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Complexity</h3>
|
||||
<div id="methodComplexity" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Insufficient Coverage</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method</th>
|
||||
<th class="text-right">Coverage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{insufficient_coverage_methods}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Project Risks</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method</th>
|
||||
<th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{project_risks_methods}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<hr/>
|
||||
<p>
|
||||
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="{{path_to_root}}_js/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/d3.min.js" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/nv.d3.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
nv.addGraph(function() {
|
||||
var chart = nv.models.multiBarChart();
|
||||
chart.tooltips(false)
|
||||
.showControls(false)
|
||||
.showLegend(false)
|
||||
.reduceXTicks(false)
|
||||
.staggerLabels(true)
|
||||
.yAxis.tickFormat(d3.format('d'));
|
||||
|
||||
d3.select('#classCoverageDistribution svg')
|
||||
.datum(getCoverageDistributionData({{class_coverage_distribution}}, "Class Coverage"))
|
||||
.transition().duration(500).call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
|
||||
nv.addGraph(function() {
|
||||
var chart = nv.models.multiBarChart();
|
||||
chart.tooltips(false)
|
||||
.showControls(false)
|
||||
.showLegend(false)
|
||||
.reduceXTicks(false)
|
||||
.staggerLabels(true)
|
||||
.yAxis.tickFormat(d3.format('d'));
|
||||
|
||||
d3.select('#methodCoverageDistribution svg')
|
||||
.datum(getCoverageDistributionData({{method_coverage_distribution}}, "Method Coverage"))
|
||||
.transition().duration(500).call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
|
||||
function getCoverageDistributionData(data, label) {
|
||||
var labels = [
|
||||
'0%',
|
||||
'0-10%',
|
||||
'10-20%',
|
||||
'20-30%',
|
||||
'30-40%',
|
||||
'40-50%',
|
||||
'50-60%',
|
||||
'60-70%',
|
||||
'70-80%',
|
||||
'80-90%',
|
||||
'90-100%',
|
||||
'100%'
|
||||
];
|
||||
var values = [];
|
||||
$.each(labels, function(key) {
|
||||
values.push({x: labels[key], y: data[key]});
|
||||
});
|
||||
|
||||
return [
|
||||
{
|
||||
key: label,
|
||||
values: values,
|
||||
color: "#4572A7"
|
||||
}
|
||||
];
|
||||
}
|
||||
nv.addGraph(function() {
|
||||
var chart = nv.models.scatterChart()
|
||||
.showDistX(true)
|
||||
.showDistY(true)
|
||||
.showLegend(false)
|
||||
.forceX([0, 100]);
|
||||
chart.tooltipContent(function(graph) {
|
||||
return '<p>' + graph.point.class + '</p>';
|
||||
});
|
||||
|
||||
chart.xAxis.axisLabel('Code Coverage (in percent)');
|
||||
chart.yAxis.axisLabel('Cyclomatic Complexity');
|
||||
|
||||
d3.select('#classComplexity svg')
|
||||
.datum(getComplexityData({{complexity_class}}, 'Class Complexity'))
|
||||
.transition()
|
||||
.duration(500)
|
||||
.call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
|
||||
nv.addGraph(function() {
|
||||
var chart = nv.models.scatterChart()
|
||||
.showDistX(true)
|
||||
.showDistY(true)
|
||||
.showLegend(false)
|
||||
.forceX([0, 100]);
|
||||
chart.tooltipContent(function(graph) {
|
||||
return '<p>' + graph.point.class + '</p>';
|
||||
});
|
||||
|
||||
chart.xAxis.axisLabel('Code Coverage (in percent)');
|
||||
chart.yAxis.axisLabel('Method Complexity');
|
||||
|
||||
d3.select('#methodComplexity svg')
|
||||
.datum(getComplexityData({{complexity_method}}, 'Method Complexity'))
|
||||
.transition()
|
||||
.duration(500)
|
||||
.call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
|
||||
function getComplexityData(data, label) {
|
||||
var values = [];
|
||||
$.each(data, function(key) {
|
||||
var value = Math.round(data[key][0]*100) / 100;
|
||||
values.push({
|
||||
x: value,
|
||||
y: data[key][1],
|
||||
class: data[key][2],
|
||||
size: 0.05,
|
||||
shape: 'diamond'
|
||||
});
|
||||
});
|
||||
|
||||
return [
|
||||
{
|
||||
key: label,
|
||||
values: values,
|
||||
color: "#4572A7"
|
||||
}
|
||||
];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
281
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard_branch.html.dist
vendored
Normal file
281
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard_branch.html.dist
vendored
Normal file
@ -0,0 +1,281 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Dashboard for {{full_path}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}_css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/nv.d3.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/style.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
{{breadcrumbs}}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2>Classes</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Coverage Distribution</h3>
|
||||
<div id="classCoverageDistribution" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Complexity</h3>
|
||||
<div id="classComplexity" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Insufficient Coverage</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th class="text-right">Coverage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{insufficient_coverage_classes}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Project Risks</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{project_risks_classes}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2>Methods</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Coverage Distribution</h3>
|
||||
<div id="methodCoverageDistribution" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Complexity</h3>
|
||||
<div id="methodComplexity" style="height: 300px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Insufficient Coverage</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method</th>
|
||||
<th class="text-right">Coverage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{insufficient_coverage_methods}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Project Risks</h3>
|
||||
<div class="scrollbox">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method</th>
|
||||
<th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{project_risks_methods}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<hr/>
|
||||
<p>
|
||||
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="{{path_to_root}}_js/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/d3.min.js" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/nv.d3.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
nv.addGraph(function() {
|
||||
var chart = nv.models.multiBarChart();
|
||||
chart.tooltips(false)
|
||||
.showControls(false)
|
||||
.showLegend(false)
|
||||
.reduceXTicks(false)
|
||||
.staggerLabels(true)
|
||||
.yAxis.tickFormat(d3.format('d'));
|
||||
|
||||
d3.select('#classCoverageDistribution svg')
|
||||
.datum(getCoverageDistributionData({{class_coverage_distribution}}, "Class Coverage"))
|
||||
.transition().duration(500).call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
|
||||
nv.addGraph(function() {
|
||||
var chart = nv.models.multiBarChart();
|
||||
chart.tooltips(false)
|
||||
.showControls(false)
|
||||
.showLegend(false)
|
||||
.reduceXTicks(false)
|
||||
.staggerLabels(true)
|
||||
.yAxis.tickFormat(d3.format('d'));
|
||||
|
||||
d3.select('#methodCoverageDistribution svg')
|
||||
.datum(getCoverageDistributionData({{method_coverage_distribution}}, "Method Coverage"))
|
||||
.transition().duration(500).call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
|
||||
function getCoverageDistributionData(data, label) {
|
||||
var labels = [
|
||||
'0%',
|
||||
'0-10%',
|
||||
'10-20%',
|
||||
'20-30%',
|
||||
'30-40%',
|
||||
'40-50%',
|
||||
'50-60%',
|
||||
'60-70%',
|
||||
'70-80%',
|
||||
'80-90%',
|
||||
'90-100%',
|
||||
'100%'
|
||||
];
|
||||
var values = [];
|
||||
$.each(labels, function(key) {
|
||||
values.push({x: labels[key], y: data[key]});
|
||||
});
|
||||
|
||||
return [
|
||||
{
|
||||
key: label,
|
||||
values: values,
|
||||
color: "#4572A7"
|
||||
}
|
||||
];
|
||||
}
|
||||
nv.addGraph(function() {
|
||||
var chart = nv.models.scatterChart()
|
||||
.showDistX(true)
|
||||
.showDistY(true)
|
||||
.showLegend(false)
|
||||
.forceX([0, 100]);
|
||||
chart.tooltipContent(function(graph) {
|
||||
return '<p>' + graph.point.class + '</p>';
|
||||
});
|
||||
|
||||
chart.xAxis.axisLabel('Code Coverage (in percent)');
|
||||
chart.yAxis.axisLabel('Cyclomatic Complexity');
|
||||
|
||||
d3.select('#classComplexity svg')
|
||||
.datum(getComplexityData({{complexity_class}}, 'Class Complexity'))
|
||||
.transition()
|
||||
.duration(500)
|
||||
.call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
|
||||
nv.addGraph(function() {
|
||||
var chart = nv.models.scatterChart()
|
||||
.showDistX(true)
|
||||
.showDistY(true)
|
||||
.showLegend(false)
|
||||
.forceX([0, 100]);
|
||||
chart.tooltipContent(function(graph) {
|
||||
return '<p>' + graph.point.class + '</p>';
|
||||
});
|
||||
|
||||
chart.xAxis.axisLabel('Code Coverage (in percent)');
|
||||
chart.yAxis.axisLabel('Method Complexity');
|
||||
|
||||
d3.select('#methodComplexity svg')
|
||||
.datum(getComplexityData({{complexity_method}}, 'Method Complexity'))
|
||||
.transition()
|
||||
.duration(500)
|
||||
.call(chart);
|
||||
|
||||
nv.utils.windowResize(chart.update);
|
||||
|
||||
return chart;
|
||||
});
|
||||
|
||||
function getComplexityData(data, label) {
|
||||
var values = [];
|
||||
$.each(data, function(key) {
|
||||
var value = Math.round(data[key][0]*100) / 100;
|
||||
values.push({
|
||||
x: value,
|
||||
y: data[key][1],
|
||||
class: data[key][2],
|
||||
size: 0.05,
|
||||
shape: 'diamond'
|
||||
});
|
||||
});
|
||||
|
||||
return [
|
||||
{
|
||||
key: label,
|
||||
values: values,
|
||||
color: "#4572A7"
|
||||
}
|
||||
];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
60
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist
vendored
Normal file
60
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Code Coverage for {{full_path}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}_css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/octicons.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/style.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
{{breadcrumbs}}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="9"><div align="center"><strong>Code Coverage</strong></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"><div align="center"><strong>Lines</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{items}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<footer>
|
||||
<hr/>
|
||||
<h4>Legend</h4>
|
||||
<p>
|
||||
<span class="danger"><strong>Low</strong>: 0% to {{low_upper_bound}}%</span>
|
||||
<span class="warning"><strong>Medium</strong>: {{low_upper_bound}}% to {{high_lower_bound}}%</span>
|
||||
<span class="success"><strong>High</strong>: {{high_lower_bound}}% to 100%</span>
|
||||
</p>
|
||||
<p>
|
||||
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
62
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_branch.html.dist
vendored
Normal file
62
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_branch.html.dist
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Code Coverage for {{full_path}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}_css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/octicons.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/style.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
{{breadcrumbs}}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="15"><div align="center"><strong>Code Coverage</strong></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"><div align="center"><strong>Lines</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Branches</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Paths</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{items}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<footer>
|
||||
<hr/>
|
||||
<h4>Legend</h4>
|
||||
<p>
|
||||
<span class="danger"><strong>Low</strong>: 0% to {{low_upper_bound}}%</span>
|
||||
<span class="warning"><strong>Medium</strong>: {{low_upper_bound}}% to {{high_lower_bound}}%</span>
|
||||
<span class="success"><strong>High</strong>: {{high_lower_bound}}% to 100%</span>
|
||||
</p>
|
||||
<p>
|
||||
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
13
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist
vendored
Normal file
13
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<tr>
|
||||
<td class="{{lines_level}}">{{icon}}{{name}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{classes_level}} big">{{classes_bar}}</td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
|
||||
</tr>
|
||||
|
@ -0,0 +1,19 @@
|
||||
<tr>
|
||||
<td class="{{lines_level}}">{{icon}}{{name}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
<td class="{{branches_level}} big">{{branches_bar}}</td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
|
||||
<td class="{{paths_level}} big">{{paths_bar}}</td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{classes_level}} big">{{classes_bar}}</td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
|
||||
</tr>
|
||||
|
65
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist
vendored
Normal file
65
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Code Coverage for {{full_path}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}_css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/octicons.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/style.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
{{breadcrumbs}}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="10"><div align="center"><strong>Code Coverage</strong></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
|
||||
<td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Lines</strong></div></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{items}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{lines}}
|
||||
{{structure}}
|
||||
<footer>
|
||||
<hr/>
|
||||
<h4>Legend</h4>
|
||||
{{legend}}
|
||||
<p>
|
||||
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
|
||||
</p>
|
||||
<a title="Back to the top" id="toplink" href="#">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M12 11L6 5l-6 6h12z"/></svg>
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="{{path_to_root}}_js/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/popper.min.js" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/file.js" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
67
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_branch.html.dist
vendored
Normal file
67
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_branch.html.dist
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Code Coverage for {{full_path}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{path_to_root}}_css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/octicons.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/style.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
{{breadcrumbs}}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="16"><div align="center"><strong>Code Coverage</strong></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
|
||||
<td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Paths</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Branches</strong></div></td>
|
||||
<td colspan="3"><div align="center"><strong>Lines</strong></div></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{items}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{lines}}
|
||||
{{structure}}
|
||||
<footer>
|
||||
<hr/>
|
||||
<h4>Legend</h4>
|
||||
{{legend}}
|
||||
<p>
|
||||
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
|
||||
</p>
|
||||
<a title="Back to the top" id="toplink" href="#">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M12 11L6 5l-6 6h12z"/></svg>
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="{{path_to_root}}_js/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/popper.min.js" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script src="{{path_to_root}}_js/file.js" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
14
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist
vendored
Normal file
14
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<tr>
|
||||
<td class="{{classes_level}}">{{name}}</td>
|
||||
<td class="{{classes_level}} big">{{classes_bar}}</td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{methods_level}} small">{{crap}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
</tr>
|
||||
|
20
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item_branch.html.dist
vendored
Normal file
20
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item_branch.html.dist
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<tr>
|
||||
<td class="{{classes_level}}">{{name}}</td>
|
||||
<td class="{{classes_level}} big">{{classes_bar}}</td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
|
||||
<td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{methods_level}} small">{{crap}}</td>
|
||||
<td class="{{paths_level}} big">{{paths_bar}}</td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
|
||||
<td class="{{branches_level}} big">{{branches_bar}}</td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
</tr>
|
||||
|
1
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/icons/file-code.svg
vendored
Normal file
1
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/icons/file-code.svg
vendored
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M8.5 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V4.5L8.5 1zM11 14H1V2h7l3 3v9zM5 6.98L3.5 8.5 5 10l-.5 1L2 8.5 4.5 6l.5.98zM7.5 6L10 8.5 7.5 11l-.5-.98L8.5 8.5 7 7l.5-1z"/></svg>
|
After Width: | Height: | Size: 304 B |
1
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/icons/file-directory.svg
vendored
Normal file
1
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/icons/file-directory.svg
vendored
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z"/></svg>
|
After Width: | Height: | Size: 234 B |
7
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js
vendored
Normal file
7
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/d3.min.js
vendored
Normal file
5
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/d3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
62
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/file.js
vendored
Normal file
62
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/file.js
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
$(function() {
|
||||
var $window = $(window)
|
||||
, $top_link = $('#toplink')
|
||||
, $body = $('body, html')
|
||||
, offset = $('#code').offset().top
|
||||
, hidePopover = function ($target) {
|
||||
$target.data('popover-hover', false);
|
||||
|
||||
setTimeout(function () {
|
||||
if (!$target.data('popover-hover')) {
|
||||
$target.popover('hide');
|
||||
}
|
||||
}, 300);
|
||||
};
|
||||
|
||||
$top_link.hide().click(function(event) {
|
||||
event.preventDefault();
|
||||
$body.animate({scrollTop:0}, 800);
|
||||
});
|
||||
|
||||
$window.scroll(function() {
|
||||
if($window.scrollTop() > offset) {
|
||||
$top_link.fadeIn();
|
||||
} else {
|
||||
$top_link.fadeOut();
|
||||
}
|
||||
}).scroll();
|
||||
|
||||
$('.popin')
|
||||
.popover({trigger: 'manual'})
|
||||
.on({
|
||||
'mouseenter.popover': function () {
|
||||
var $target = $(this);
|
||||
var $container = $target.children().first();
|
||||
|
||||
$target.data('popover-hover', true);
|
||||
|
||||
// popover already displayed
|
||||
if ($target.next('.popover').length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// show the popover
|
||||
$container.popover('show');
|
||||
|
||||
// register mouse events on the popover
|
||||
$target.next('.popover:not(.popover-initialized)')
|
||||
.on({
|
||||
'mouseenter': function () {
|
||||
$target.data('popover-hover', true);
|
||||
},
|
||||
'mouseleave': function () {
|
||||
hidePopover($container);
|
||||
}
|
||||
})
|
||||
.addClass('popover-initialized');
|
||||
},
|
||||
'mouseleave.popover': function () {
|
||||
hidePopover($(this).children().first());
|
||||
}
|
||||
});
|
||||
});
|
2
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js
vendored
Normal file
2
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/nv.d3.min.js
vendored
Normal file
8
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/nv.d3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/popper.min.js
vendored
Normal file
5
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/popper.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/line.html.dist
vendored
Normal file
1
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/line.html.dist
vendored
Normal file
@ -0,0 +1 @@
|
||||
<tr class="{{class}} d-flex"><td {{popover}} class="col-1 text-right"><a id="{{lineNumber}}" href="#{{lineNumber}}">{{lineNumber}}</a></td><td class="col-11 codeLine">{{lineContent}}</td></tr>
|
5
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/lines.html.dist
vendored
Normal file
5
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/lines.html.dist
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<table id="code" class="table table-borderless table-condensed">
|
||||
<tbody>
|
||||
{{lines}}
|
||||
</tbody>
|
||||
</table>
|
11
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item.html.dist
vendored
Normal file
11
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item.html.dist
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<tr>
|
||||
<td class="{{methods_level}}" colspan="4">{{name}}</td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{methods_level}} small">{{crap}}</td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
</tr>
|
||||
|
17
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item_branch.html.dist
vendored
Normal file
17
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item_branch.html.dist
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<tr>
|
||||
<td class="{{methods_level}}" colspan="4">{{name}}</td>
|
||||
<td class="{{methods_level}} big">{{methods_bar}}</td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
|
||||
<td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
|
||||
<td class="{{methods_level}} small">{{crap}}</td>
|
||||
<td class="{{paths_level}} big">{{paths_bar}}</td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
|
||||
<td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
|
||||
<td class="{{branches_level}} big">{{branches_bar}}</td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
|
||||
<td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
|
||||
<td class="{{lines_level}} big">{{lines_bar}}</td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
|
||||
<td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
|
||||
</tr>
|
||||
|
9
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/paths.html.dist
vendored
Normal file
9
vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/paths.html.dist
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<hr/>
|
||||
<h4>Paths</h4>
|
||||
<p>
|
||||
Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not
|
||||
necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once.
|
||||
Please also be aware that some paths may include implicit rather than explicit branches, e.g. an <code>if</code> statement
|
||||
<i>always</i> has an <code>else</code> as part of its logical flow even if you didn't write one.
|
||||
</p>
|
||||
{{paths}}
|
43
vendor/phpunit/php-code-coverage/src/Report/PHP.php
vendored
Normal file
43
vendor/phpunit/php-code-coverage/src/Report/PHP.php
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report;
|
||||
|
||||
use function dirname;
|
||||
use function file_put_contents;
|
||||
use function serialize;
|
||||
use function sprintf;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Directory;
|
||||
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
|
||||
|
||||
final class PHP
|
||||
{
|
||||
public function process(CodeCoverage $coverage, ?string $target = null): string
|
||||
{
|
||||
$buffer = sprintf(
|
||||
"<?php
|
||||
return \unserialize(<<<'END_OF_COVERAGE_SERIALIZATION'%s%s%sEND_OF_COVERAGE_SERIALIZATION%s);",
|
||||
PHP_EOL,
|
||||
serialize($coverage),
|
||||
PHP_EOL,
|
||||
PHP_EOL
|
||||
);
|
||||
|
||||
if ($target !== null) {
|
||||
Directory::create(dirname($target));
|
||||
|
||||
if (@file_put_contents($target, $buffer) === false) {
|
||||
throw new WriteOperationFailedException($target);
|
||||
}
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
}
|
341
vendor/phpunit/php-code-coverage/src/Report/Text.php
vendored
Normal file
341
vendor/phpunit/php-code-coverage/src/Report/Text.php
vendored
Normal file
@ -0,0 +1,341 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report;
|
||||
|
||||
use const PHP_EOL;
|
||||
use function array_map;
|
||||
use function date;
|
||||
use function ksort;
|
||||
use function max;
|
||||
use function sprintf;
|
||||
use function str_pad;
|
||||
use function strlen;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Node\File;
|
||||
use SebastianBergmann\CodeCoverage\Percentage;
|
||||
|
||||
final class Text
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const COLOR_GREEN = "\x1b[30;42m";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const COLOR_YELLOW = "\x1b[30;43m";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const COLOR_RED = "\x1b[37;41m";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const COLOR_HEADER = "\x1b[1;37;40m";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const COLOR_RESET = "\x1b[0m";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const COLOR_EOL = "\x1b[2K";
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $lowUpperBound;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $highLowerBound;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $showUncoveredFiles;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $showOnlySummary;
|
||||
|
||||
public function __construct(int $lowUpperBound = 50, int $highLowerBound = 90, bool $showUncoveredFiles = false, bool $showOnlySummary = false)
|
||||
{
|
||||
$this->lowUpperBound = $lowUpperBound;
|
||||
$this->highLowerBound = $highLowerBound;
|
||||
$this->showUncoveredFiles = $showUncoveredFiles;
|
||||
$this->showOnlySummary = $showOnlySummary;
|
||||
}
|
||||
|
||||
public function process(CodeCoverage $coverage, bool $showColors = false): string
|
||||
{
|
||||
$hasBranchCoverage = !empty($coverage->getData(true)->functionCoverage());
|
||||
|
||||
$output = PHP_EOL . PHP_EOL;
|
||||
$report = $coverage->getReport();
|
||||
|
||||
$colors = [
|
||||
'header' => '',
|
||||
'classes' => '',
|
||||
'methods' => '',
|
||||
'lines' => '',
|
||||
'branches' => '',
|
||||
'paths' => '',
|
||||
'reset' => '',
|
||||
'eol' => '',
|
||||
];
|
||||
|
||||
if ($showColors) {
|
||||
$colors['classes'] = $this->coverageColor(
|
||||
$report->numberOfTestedClassesAndTraits(),
|
||||
$report->numberOfClassesAndTraits()
|
||||
);
|
||||
|
||||
$colors['methods'] = $this->coverageColor(
|
||||
$report->numberOfTestedMethods(),
|
||||
$report->numberOfMethods()
|
||||
);
|
||||
|
||||
$colors['lines'] = $this->coverageColor(
|
||||
$report->numberOfExecutedLines(),
|
||||
$report->numberOfExecutableLines()
|
||||
);
|
||||
|
||||
$colors['branches'] = $this->coverageColor(
|
||||
$report->numberOfExecutedBranches(),
|
||||
$report->numberOfExecutableBranches()
|
||||
);
|
||||
|
||||
$colors['paths'] = $this->coverageColor(
|
||||
$report->numberOfExecutedPaths(),
|
||||
$report->numberOfExecutablePaths()
|
||||
);
|
||||
|
||||
$colors['reset'] = self::COLOR_RESET;
|
||||
$colors['header'] = self::COLOR_HEADER;
|
||||
$colors['eol'] = self::COLOR_EOL;
|
||||
}
|
||||
|
||||
$classes = sprintf(
|
||||
' Classes: %6s (%d/%d)',
|
||||
Percentage::fromFractionAndTotal(
|
||||
$report->numberOfTestedClassesAndTraits(),
|
||||
$report->numberOfClassesAndTraits()
|
||||
)->asString(),
|
||||
$report->numberOfTestedClassesAndTraits(),
|
||||
$report->numberOfClassesAndTraits()
|
||||
);
|
||||
|
||||
$methods = sprintf(
|
||||
' Methods: %6s (%d/%d)',
|
||||
Percentage::fromFractionAndTotal(
|
||||
$report->numberOfTestedMethods(),
|
||||
$report->numberOfMethods(),
|
||||
)->asString(),
|
||||
$report->numberOfTestedMethods(),
|
||||
$report->numberOfMethods()
|
||||
);
|
||||
|
||||
$paths = '';
|
||||
$branches = '';
|
||||
|
||||
if ($hasBranchCoverage) {
|
||||
$paths = sprintf(
|
||||
' Paths: %6s (%d/%d)',
|
||||
Percentage::fromFractionAndTotal(
|
||||
$report->numberOfExecutedPaths(),
|
||||
$report->numberOfExecutablePaths(),
|
||||
)->asString(),
|
||||
$report->numberOfExecutedPaths(),
|
||||
$report->numberOfExecutablePaths()
|
||||
);
|
||||
|
||||
$branches = sprintf(
|
||||
' Branches: %6s (%d/%d)',
|
||||
Percentage::fromFractionAndTotal(
|
||||
$report->numberOfExecutedBranches(),
|
||||
$report->numberOfExecutableBranches(),
|
||||
)->asString(),
|
||||
$report->numberOfExecutedBranches(),
|
||||
$report->numberOfExecutableBranches()
|
||||
);
|
||||
}
|
||||
|
||||
$lines = sprintf(
|
||||
' Lines: %6s (%d/%d)',
|
||||
Percentage::fromFractionAndTotal(
|
||||
$report->numberOfExecutedLines(),
|
||||
$report->numberOfExecutableLines(),
|
||||
)->asString(),
|
||||
$report->numberOfExecutedLines(),
|
||||
$report->numberOfExecutableLines()
|
||||
);
|
||||
|
||||
$padding = max(array_map('strlen', [$classes, $methods, $lines]));
|
||||
|
||||
if ($this->showOnlySummary) {
|
||||
$title = 'Code Coverage Report Summary:';
|
||||
$padding = max($padding, strlen($title));
|
||||
|
||||
$output .= $this->format($colors['header'], $padding, $title);
|
||||
} else {
|
||||
$date = date(' Y-m-d H:i:s');
|
||||
$title = 'Code Coverage Report:';
|
||||
|
||||
$output .= $this->format($colors['header'], $padding, $title);
|
||||
$output .= $this->format($colors['header'], $padding, $date);
|
||||
$output .= $this->format($colors['header'], $padding, '');
|
||||
$output .= $this->format($colors['header'], $padding, ' Summary:');
|
||||
}
|
||||
|
||||
$output .= $this->format($colors['classes'], $padding, $classes);
|
||||
$output .= $this->format($colors['methods'], $padding, $methods);
|
||||
|
||||
if ($hasBranchCoverage) {
|
||||
$output .= $this->format($colors['paths'], $padding, $paths);
|
||||
$output .= $this->format($colors['branches'], $padding, $branches);
|
||||
}
|
||||
$output .= $this->format($colors['lines'], $padding, $lines);
|
||||
|
||||
if ($this->showOnlySummary) {
|
||||
return $output . PHP_EOL;
|
||||
}
|
||||
|
||||
$classCoverage = [];
|
||||
|
||||
foreach ($report as $item) {
|
||||
if (!$item instanceof File) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$classes = $item->classesAndTraits();
|
||||
|
||||
foreach ($classes as $className => $class) {
|
||||
$classExecutableLines = 0;
|
||||
$classExecutedLines = 0;
|
||||
$classExecutableBranches = 0;
|
||||
$classExecutedBranches = 0;
|
||||
$classExecutablePaths = 0;
|
||||
$classExecutedPaths = 0;
|
||||
$coveredMethods = 0;
|
||||
$classMethods = 0;
|
||||
|
||||
foreach ($class['methods'] as $method) {
|
||||
if ($method['executableLines'] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$classMethods++;
|
||||
$classExecutableLines += $method['executableLines'];
|
||||
$classExecutedLines += $method['executedLines'];
|
||||
$classExecutableBranches += $method['executableBranches'];
|
||||
$classExecutedBranches += $method['executedBranches'];
|
||||
$classExecutablePaths += $method['executablePaths'];
|
||||
$classExecutedPaths += $method['executedPaths'];
|
||||
|
||||
if ($method['coverage'] == 100) {
|
||||
$coveredMethods++;
|
||||
}
|
||||
}
|
||||
|
||||
$classCoverage[$className] = [
|
||||
'namespace' => $class['namespace'],
|
||||
'className' => $className,
|
||||
'methodsCovered' => $coveredMethods,
|
||||
'methodCount' => $classMethods,
|
||||
'statementsCovered' => $classExecutedLines,
|
||||
'statementCount' => $classExecutableLines,
|
||||
'branchesCovered' => $classExecutedBranches,
|
||||
'branchesCount' => $classExecutableBranches,
|
||||
'pathsCovered' => $classExecutedPaths,
|
||||
'pathsCount' => $classExecutablePaths,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
ksort($classCoverage);
|
||||
|
||||
$methodColor = '';
|
||||
$pathsColor = '';
|
||||
$branchesColor = '';
|
||||
$linesColor = '';
|
||||
$resetColor = '';
|
||||
|
||||
foreach ($classCoverage as $fullQualifiedPath => $classInfo) {
|
||||
if ($this->showUncoveredFiles || $classInfo['statementsCovered'] != 0) {
|
||||
if ($showColors) {
|
||||
$methodColor = $this->coverageColor($classInfo['methodsCovered'], $classInfo['methodCount']);
|
||||
$pathsColor = $this->coverageColor($classInfo['pathsCovered'], $classInfo['pathsCount']);
|
||||
$branchesColor = $this->coverageColor($classInfo['branchesCovered'], $classInfo['branchesCount']);
|
||||
$linesColor = $this->coverageColor($classInfo['statementsCovered'], $classInfo['statementCount']);
|
||||
$resetColor = $colors['reset'];
|
||||
}
|
||||
|
||||
$output .= PHP_EOL . $fullQualifiedPath . PHP_EOL
|
||||
. ' ' . $methodColor . 'Methods: ' . $this->printCoverageCounts($classInfo['methodsCovered'], $classInfo['methodCount'], 2) . $resetColor . ' ';
|
||||
|
||||
if ($hasBranchCoverage) {
|
||||
$output .= ' ' . $pathsColor . 'Paths: ' . $this->printCoverageCounts($classInfo['pathsCovered'], $classInfo['pathsCount'], 3) . $resetColor . ' '
|
||||
. ' ' . $branchesColor . 'Branches: ' . $this->printCoverageCounts($classInfo['branchesCovered'], $classInfo['branchesCount'], 3) . $resetColor . ' ';
|
||||
}
|
||||
$output .= ' ' . $linesColor . 'Lines: ' . $this->printCoverageCounts($classInfo['statementsCovered'], $classInfo['statementCount'], 3) . $resetColor;
|
||||
}
|
||||
}
|
||||
|
||||
return $output . PHP_EOL;
|
||||
}
|
||||
|
||||
private function coverageColor(int $numberOfCoveredElements, int $totalNumberOfElements): string
|
||||
{
|
||||
$coverage = Percentage::fromFractionAndTotal(
|
||||
$numberOfCoveredElements,
|
||||
$totalNumberOfElements
|
||||
);
|
||||
|
||||
if ($coverage->asFloat() >= $this->highLowerBound) {
|
||||
return self::COLOR_GREEN;
|
||||
}
|
||||
|
||||
if ($coverage->asFloat() > $this->lowUpperBound) {
|
||||
return self::COLOR_YELLOW;
|
||||
}
|
||||
|
||||
return self::COLOR_RED;
|
||||
}
|
||||
|
||||
private function printCoverageCounts(int $numberOfCoveredElements, int $totalNumberOfElements, int $precision): string
|
||||
{
|
||||
$format = '%' . $precision . 's';
|
||||
|
||||
return Percentage::fromFractionAndTotal(
|
||||
$numberOfCoveredElements,
|
||||
$totalNumberOfElements
|
||||
)->asFixedWidthString() .
|
||||
' (' . sprintf($format, $numberOfCoveredElements) . '/' .
|
||||
sprintf($format, $totalNumberOfElements) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param false|string $string
|
||||
*/
|
||||
private function format(string $color, int $padding, $string): string
|
||||
{
|
||||
$reset = $color ? self::COLOR_RESET : '';
|
||||
|
||||
return $color . str_pad((string) $string, $padding) . $reset . PHP_EOL;
|
||||
}
|
||||
}
|
88
vendor/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php
vendored
Normal file
88
vendor/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use function constant;
|
||||
use function phpversion;
|
||||
use DateTimeImmutable;
|
||||
use DOMElement;
|
||||
use SebastianBergmann\Environment\Runtime;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class BuildInformation
|
||||
{
|
||||
/**
|
||||
* @var DOMElement
|
||||
*/
|
||||
private $contextNode;
|
||||
|
||||
public function __construct(DOMElement $contextNode)
|
||||
{
|
||||
$this->contextNode = $contextNode;
|
||||
}
|
||||
|
||||
public function setRuntimeInformation(Runtime $runtime): void
|
||||
{
|
||||
$runtimeNode = $this->nodeByName('runtime');
|
||||
|
||||
$runtimeNode->setAttribute('name', $runtime->getName());
|
||||
$runtimeNode->setAttribute('version', $runtime->getVersion());
|
||||
$runtimeNode->setAttribute('url', $runtime->getVendorUrl());
|
||||
|
||||
$driverNode = $this->nodeByName('driver');
|
||||
|
||||
if ($runtime->hasPHPDBGCodeCoverage()) {
|
||||
$driverNode->setAttribute('name', 'phpdbg');
|
||||
$driverNode->setAttribute('version', constant('PHPDBG_VERSION'));
|
||||
}
|
||||
|
||||
if ($runtime->hasXdebug()) {
|
||||
$driverNode->setAttribute('name', 'xdebug');
|
||||
$driverNode->setAttribute('version', phpversion('xdebug'));
|
||||
}
|
||||
|
||||
if ($runtime->hasPCOV()) {
|
||||
$driverNode->setAttribute('name', 'pcov');
|
||||
$driverNode->setAttribute('version', phpversion('pcov'));
|
||||
}
|
||||
}
|
||||
|
||||
public function setBuildTime(DateTimeImmutable $date): void
|
||||
{
|
||||
$this->contextNode->setAttribute('time', $date->format('D M j G:i:s T Y'));
|
||||
}
|
||||
|
||||
public function setGeneratorVersions(string $phpUnitVersion, string $coverageVersion): void
|
||||
{
|
||||
$this->contextNode->setAttribute('phpunit', $phpUnitVersion);
|
||||
$this->contextNode->setAttribute('coverage', $coverageVersion);
|
||||
}
|
||||
|
||||
private function nodeByName(string $name): DOMElement
|
||||
{
|
||||
$node = $this->contextNode->getElementsByTagNameNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
$name
|
||||
)->item(0);
|
||||
|
||||
if (!$node) {
|
||||
$node = $this->contextNode->appendChild(
|
||||
$this->contextNode->ownerDocument->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
$name
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
74
vendor/phpunit/php-code-coverage/src/Report/Xml/Coverage.php
vendored
Normal file
74
vendor/phpunit/php-code-coverage/src/Report/Xml/Coverage.php
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use DOMElement;
|
||||
use SebastianBergmann\CodeCoverage\ReportAlreadyFinalizedException;
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Coverage
|
||||
{
|
||||
/**
|
||||
* @var XMLWriter
|
||||
*/
|
||||
private $writer;
|
||||
|
||||
/**
|
||||
* @var DOMElement
|
||||
*/
|
||||
private $contextNode;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $finalized = false;
|
||||
|
||||
public function __construct(DOMElement $context, string $line)
|
||||
{
|
||||
$this->contextNode = $context;
|
||||
|
||||
$this->writer = new XMLWriter();
|
||||
$this->writer->openMemory();
|
||||
$this->writer->startElementNS(null, $context->nodeName, 'https://schema.phpunit.de/coverage/1.0');
|
||||
$this->writer->writeAttribute('nr', $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ReportAlreadyFinalizedException
|
||||
*/
|
||||
public function addTest(string $test): void
|
||||
{
|
||||
if ($this->finalized) {
|
||||
throw new ReportAlreadyFinalizedException;
|
||||
}
|
||||
|
||||
$this->writer->startElement('covered');
|
||||
$this->writer->writeAttribute('by', $test);
|
||||
$this->writer->endElement();
|
||||
}
|
||||
|
||||
public function finalize(): void
|
||||
{
|
||||
$this->writer->endElement();
|
||||
|
||||
$fragment = $this->contextNode->ownerDocument->createDocumentFragment();
|
||||
$fragment->appendXML($this->writer->outputMemory());
|
||||
|
||||
$this->contextNode->parentNode->replaceChild(
|
||||
$fragment,
|
||||
$this->contextNode
|
||||
);
|
||||
|
||||
$this->finalized = true;
|
||||
}
|
||||
}
|
17
vendor/phpunit/php-code-coverage/src/Report/Xml/Directory.php
vendored
Normal file
17
vendor/phpunit/php-code-coverage/src/Report/Xml/Directory.php
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Directory extends Node
|
||||
{
|
||||
}
|
315
vendor/phpunit/php-code-coverage/src/Report/Xml/Facade.php
vendored
Normal file
315
vendor/phpunit/php-code-coverage/src/Report/Xml/Facade.php
vendored
Normal file
@ -0,0 +1,315 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use const PHP_EOL;
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function file_get_contents;
|
||||
use function file_put_contents;
|
||||
use function is_array;
|
||||
use function is_dir;
|
||||
use function is_file;
|
||||
use function is_writable;
|
||||
use function libxml_clear_errors;
|
||||
use function libxml_get_errors;
|
||||
use function libxml_use_internal_errors;
|
||||
use function sprintf;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
use DateTimeImmutable;
|
||||
use DOMDocument;
|
||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||
use SebastianBergmann\CodeCoverage\Directory as DirectoryUtil;
|
||||
use SebastianBergmann\CodeCoverage\Driver\PathExistsButIsNotDirectoryException;
|
||||
use SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
|
||||
use SebastianBergmann\CodeCoverage\Node\AbstractNode;
|
||||
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
|
||||
use SebastianBergmann\CodeCoverage\Node\File as FileNode;
|
||||
use SebastianBergmann\CodeCoverage\Version;
|
||||
use SebastianBergmann\CodeCoverage\XmlException;
|
||||
use SebastianBergmann\Environment\Runtime;
|
||||
|
||||
final class Facade
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $target;
|
||||
|
||||
/**
|
||||
* @var Project
|
||||
*/
|
||||
private $project;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $phpUnitVersion;
|
||||
|
||||
public function __construct(string $version)
|
||||
{
|
||||
$this->phpUnitVersion = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws XmlException
|
||||
*/
|
||||
public function process(CodeCoverage $coverage, string $target): void
|
||||
{
|
||||
if (substr($target, -1, 1) !== DIRECTORY_SEPARATOR) {
|
||||
$target .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
$this->target = $target;
|
||||
$this->initTargetDirectory($target);
|
||||
|
||||
$report = $coverage->getReport();
|
||||
|
||||
$this->project = new Project(
|
||||
$coverage->getReport()->name()
|
||||
);
|
||||
|
||||
$this->setBuildInformation();
|
||||
$this->processTests($coverage->getTests());
|
||||
$this->processDirectory($report, $this->project);
|
||||
|
||||
$this->saveDocument($this->project->asDom(), 'index');
|
||||
}
|
||||
|
||||
private function setBuildInformation(): void
|
||||
{
|
||||
$buildNode = $this->project->buildInformation();
|
||||
$buildNode->setRuntimeInformation(new Runtime);
|
||||
$buildNode->setBuildTime(new DateTimeImmutable);
|
||||
$buildNode->setGeneratorVersions($this->phpUnitVersion, Version::id());
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PathExistsButIsNotDirectoryException
|
||||
* @throws WriteOperationFailedException
|
||||
*/
|
||||
private function initTargetDirectory(string $directory): void
|
||||
{
|
||||
if (is_file($directory)) {
|
||||
if (!is_dir($directory)) {
|
||||
throw new PathExistsButIsNotDirectoryException($directory);
|
||||
}
|
||||
|
||||
if (!is_writable($directory)) {
|
||||
throw new WriteOperationFailedException($directory);
|
||||
}
|
||||
}
|
||||
|
||||
DirectoryUtil::create($directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws XmlException
|
||||
*/
|
||||
private function processDirectory(DirectoryNode $directory, Node $context): void
|
||||
{
|
||||
$directoryName = $directory->name();
|
||||
|
||||
if ($this->project->projectSourceDirectory() === $directoryName) {
|
||||
$directoryName = '/';
|
||||
}
|
||||
|
||||
$directoryObject = $context->addDirectory($directoryName);
|
||||
|
||||
$this->setTotals($directory, $directoryObject->totals());
|
||||
|
||||
foreach ($directory->directories() as $node) {
|
||||
$this->processDirectory($node, $directoryObject);
|
||||
}
|
||||
|
||||
foreach ($directory->files() as $node) {
|
||||
$this->processFile($node, $directoryObject);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws XmlException
|
||||
*/
|
||||
private function processFile(FileNode $file, Directory $context): void
|
||||
{
|
||||
$fileObject = $context->addFile(
|
||||
$file->name(),
|
||||
$file->id() . '.xml'
|
||||
);
|
||||
|
||||
$this->setTotals($file, $fileObject->totals());
|
||||
|
||||
$path = substr(
|
||||
$file->pathAsString(),
|
||||
strlen($this->project->projectSourceDirectory())
|
||||
);
|
||||
|
||||
$fileReport = new Report($path);
|
||||
|
||||
$this->setTotals($file, $fileReport->totals());
|
||||
|
||||
foreach ($file->classesAndTraits() as $unit) {
|
||||
$this->processUnit($unit, $fileReport);
|
||||
}
|
||||
|
||||
foreach ($file->functions() as $function) {
|
||||
$this->processFunction($function, $fileReport);
|
||||
}
|
||||
|
||||
foreach ($file->lineCoverageData() as $line => $tests) {
|
||||
if (!is_array($tests) || count($tests) === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$coverage = $fileReport->lineCoverage((string) $line);
|
||||
|
||||
foreach ($tests as $test) {
|
||||
$coverage->addTest($test);
|
||||
}
|
||||
|
||||
$coverage->finalize();
|
||||
}
|
||||
|
||||
$fileReport->source()->setSourceCode(
|
||||
file_get_contents($file->pathAsString())
|
||||
);
|
||||
|
||||
$this->saveDocument($fileReport->asDom(), $file->id());
|
||||
}
|
||||
|
||||
private function processUnit(array $unit, Report $report): void
|
||||
{
|
||||
if (isset($unit['className'])) {
|
||||
$unitObject = $report->classObject($unit['className']);
|
||||
} else {
|
||||
$unitObject = $report->traitObject($unit['traitName']);
|
||||
}
|
||||
|
||||
$unitObject->setLines(
|
||||
$unit['startLine'],
|
||||
$unit['executableLines'],
|
||||
$unit['executedLines']
|
||||
);
|
||||
|
||||
$unitObject->setCrap((float) $unit['crap']);
|
||||
$unitObject->setNamespace($unit['namespace']);
|
||||
|
||||
foreach ($unit['methods'] as $method) {
|
||||
$methodObject = $unitObject->addMethod($method['methodName']);
|
||||
$methodObject->setSignature($method['signature']);
|
||||
$methodObject->setLines((string) $method['startLine'], (string) $method['endLine']);
|
||||
$methodObject->setCrap($method['crap']);
|
||||
$methodObject->setTotals(
|
||||
(string) $method['executableLines'],
|
||||
(string) $method['executedLines'],
|
||||
(string) $method['coverage']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function processFunction(array $function, Report $report): void
|
||||
{
|
||||
$functionObject = $report->functionObject($function['functionName']);
|
||||
|
||||
$functionObject->setSignature($function['signature']);
|
||||
$functionObject->setLines((string) $function['startLine']);
|
||||
$functionObject->setCrap($function['crap']);
|
||||
$functionObject->setTotals((string) $function['executableLines'], (string) $function['executedLines'], (string) $function['coverage']);
|
||||
}
|
||||
|
||||
private function processTests(array $tests): void
|
||||
{
|
||||
$testsObject = $this->project->tests();
|
||||
|
||||
foreach ($tests as $test => $result) {
|
||||
$testsObject->addTest($test, $result);
|
||||
}
|
||||
}
|
||||
|
||||
private function setTotals(AbstractNode $node, Totals $totals): void
|
||||
{
|
||||
$loc = $node->linesOfCode();
|
||||
|
||||
$totals->setNumLines(
|
||||
$loc->linesOfCode(),
|
||||
$loc->commentLinesOfCode(),
|
||||
$loc->nonCommentLinesOfCode(),
|
||||
$node->numberOfExecutableLines(),
|
||||
$node->numberOfExecutedLines()
|
||||
);
|
||||
|
||||
$totals->setNumClasses(
|
||||
$node->numberOfClasses(),
|
||||
$node->numberOfTestedClasses()
|
||||
);
|
||||
|
||||
$totals->setNumTraits(
|
||||
$node->numberOfTraits(),
|
||||
$node->numberOfTestedTraits()
|
||||
);
|
||||
|
||||
$totals->setNumMethods(
|
||||
$node->numberOfMethods(),
|
||||
$node->numberOfTestedMethods()
|
||||
);
|
||||
|
||||
$totals->setNumFunctions(
|
||||
$node->numberOfFunctions(),
|
||||
$node->numberOfTestedFunctions()
|
||||
);
|
||||
}
|
||||
|
||||
private function targetDirectory(): string
|
||||
{
|
||||
return $this->target;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws XmlException
|
||||
*/
|
||||
private function saveDocument(DOMDocument $document, string $name): void
|
||||
{
|
||||
$filename = sprintf('%s/%s.xml', $this->targetDirectory(), $name);
|
||||
|
||||
$document->formatOutput = true;
|
||||
$document->preserveWhiteSpace = false;
|
||||
$this->initTargetDirectory(dirname($filename));
|
||||
|
||||
file_put_contents($filename, $this->documentAsString($document));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws XmlException
|
||||
*
|
||||
* @see https://bugs.php.net/bug.php?id=79191
|
||||
*/
|
||||
private function documentAsString(DOMDocument $document): string
|
||||
{
|
||||
$xmlErrorHandling = libxml_use_internal_errors(true);
|
||||
$xml = $document->saveXML();
|
||||
|
||||
if ($xml === false) {
|
||||
$message = 'Unable to generate the XML';
|
||||
|
||||
foreach (libxml_get_errors() as $error) {
|
||||
$message .= PHP_EOL . $error->message;
|
||||
}
|
||||
|
||||
throw new XmlException($message);
|
||||
}
|
||||
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($xmlErrorHandling);
|
||||
|
||||
return $xml;
|
||||
}
|
||||
}
|
87
vendor/phpunit/php-code-coverage/src/Report/Xml/File.php
vendored
Normal file
87
vendor/phpunit/php-code-coverage/src/Report/Xml/File.php
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMElement;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
class File
|
||||
{
|
||||
/**
|
||||
* @var DOMDocument
|
||||
*/
|
||||
private $dom;
|
||||
|
||||
/**
|
||||
* @var DOMElement
|
||||
*/
|
||||
private $contextNode;
|
||||
|
||||
public function __construct(DOMElement $context)
|
||||
{
|
||||
$this->dom = $context->ownerDocument;
|
||||
$this->contextNode = $context;
|
||||
}
|
||||
|
||||
public function totals(): Totals
|
||||
{
|
||||
$totalsContainer = $this->contextNode->firstChild;
|
||||
|
||||
if (!$totalsContainer) {
|
||||
$totalsContainer = $this->contextNode->appendChild(
|
||||
$this->dom->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'totals'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return new Totals($totalsContainer);
|
||||
}
|
||||
|
||||
public function lineCoverage(string $line): Coverage
|
||||
{
|
||||
$coverage = $this->contextNode->getElementsByTagNameNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'coverage'
|
||||
)->item(0);
|
||||
|
||||
if (!$coverage) {
|
||||
$coverage = $this->contextNode->appendChild(
|
||||
$this->dom->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'coverage'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$lineNode = $coverage->appendChild(
|
||||
$this->dom->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'line'
|
||||
)
|
||||
);
|
||||
|
||||
return new Coverage($lineNode, $line);
|
||||
}
|
||||
|
||||
protected function contextNode(): DOMElement
|
||||
{
|
||||
return $this->contextNode;
|
||||
}
|
||||
|
||||
protected function dom(): DOMDocument
|
||||
{
|
||||
return $this->dom;
|
||||
}
|
||||
}
|
61
vendor/phpunit/php-code-coverage/src/Report/Xml/Method.php
vendored
Normal file
61
vendor/phpunit/php-code-coverage/src/Report/Xml/Method.php
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use DOMElement;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Method
|
||||
{
|
||||
/**
|
||||
* @var DOMElement
|
||||
*/
|
||||
private $contextNode;
|
||||
|
||||
public function __construct(DOMElement $context, string $name)
|
||||
{
|
||||
$this->contextNode = $context;
|
||||
|
||||
$this->setName($name);
|
||||
}
|
||||
|
||||
public function setSignature(string $signature): void
|
||||
{
|
||||
$this->contextNode->setAttribute('signature', $signature);
|
||||
}
|
||||
|
||||
public function setLines(string $start, ?string $end = null): void
|
||||
{
|
||||
$this->contextNode->setAttribute('start', $start);
|
||||
|
||||
if ($end !== null) {
|
||||
$this->contextNode->setAttribute('end', $end);
|
||||
}
|
||||
}
|
||||
|
||||
public function setTotals(string $executable, string $executed, string $coverage): void
|
||||
{
|
||||
$this->contextNode->setAttribute('executable', $executable);
|
||||
$this->contextNode->setAttribute('executed', $executed);
|
||||
$this->contextNode->setAttribute('coverage', $coverage);
|
||||
}
|
||||
|
||||
public function setCrap(string $crap): void
|
||||
{
|
||||
$this->contextNode->setAttribute('crap', $crap);
|
||||
}
|
||||
|
||||
private function setName(string $name): void
|
||||
{
|
||||
$this->contextNode->setAttribute('name', $name);
|
||||
}
|
||||
}
|
93
vendor/phpunit/php-code-coverage/src/Report/Xml/Node.php
vendored
Normal file
93
vendor/phpunit/php-code-coverage/src/Report/Xml/Node.php
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMElement;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
abstract class Node
|
||||
{
|
||||
/**
|
||||
* @var DOMDocument
|
||||
*/
|
||||
private $dom;
|
||||
|
||||
/**
|
||||
* @var DOMElement
|
||||
*/
|
||||
private $contextNode;
|
||||
|
||||
public function __construct(DOMElement $context)
|
||||
{
|
||||
$this->setContextNode($context);
|
||||
}
|
||||
|
||||
public function dom(): DOMDocument
|
||||
{
|
||||
return $this->dom;
|
||||
}
|
||||
|
||||
public function totals(): Totals
|
||||
{
|
||||
$totalsContainer = $this->contextNode()->firstChild;
|
||||
|
||||
if (!$totalsContainer) {
|
||||
$totalsContainer = $this->contextNode()->appendChild(
|
||||
$this->dom->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'totals'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return new Totals($totalsContainer);
|
||||
}
|
||||
|
||||
public function addDirectory(string $name): Directory
|
||||
{
|
||||
$dirNode = $this->dom()->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'directory'
|
||||
);
|
||||
|
||||
$dirNode->setAttribute('name', $name);
|
||||
$this->contextNode()->appendChild($dirNode);
|
||||
|
||||
return new Directory($dirNode);
|
||||
}
|
||||
|
||||
public function addFile(string $name, string $href): File
|
||||
{
|
||||
$fileNode = $this->dom()->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'file'
|
||||
);
|
||||
|
||||
$fileNode->setAttribute('name', $name);
|
||||
$fileNode->setAttribute('href', $href);
|
||||
$this->contextNode()->appendChild($fileNode);
|
||||
|
||||
return new File($fileNode);
|
||||
}
|
||||
|
||||
protected function setContextNode(DOMElement $context): void
|
||||
{
|
||||
$this->dom = $context->ownerDocument;
|
||||
$this->contextNode = $context;
|
||||
}
|
||||
|
||||
protected function contextNode(): DOMElement
|
||||
{
|
||||
return $this->contextNode;
|
||||
}
|
||||
}
|
90
vendor/phpunit/php-code-coverage/src/Report/Xml/Project.php
vendored
Normal file
90
vendor/phpunit/php-code-coverage/src/Report/Xml/Project.php
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use DOMDocument;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Project extends Node
|
||||
{
|
||||
public function __construct(string $directory)
|
||||
{
|
||||
$this->init();
|
||||
$this->setProjectSourceDirectory($directory);
|
||||
}
|
||||
|
||||
public function projectSourceDirectory(): string
|
||||
{
|
||||
return $this->contextNode()->getAttribute('source');
|
||||
}
|
||||
|
||||
public function buildInformation(): BuildInformation
|
||||
{
|
||||
$buildNode = $this->dom()->getElementsByTagNameNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'build'
|
||||
)->item(0);
|
||||
|
||||
if (!$buildNode) {
|
||||
$buildNode = $this->dom()->documentElement->appendChild(
|
||||
$this->dom()->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'build'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return new BuildInformation($buildNode);
|
||||
}
|
||||
|
||||
public function tests(): Tests
|
||||
{
|
||||
$testsNode = $this->contextNode()->getElementsByTagNameNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'tests'
|
||||
)->item(0);
|
||||
|
||||
if (!$testsNode) {
|
||||
$testsNode = $this->contextNode()->appendChild(
|
||||
$this->dom()->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'tests'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return new Tests($testsNode);
|
||||
}
|
||||
|
||||
public function asDom(): DOMDocument
|
||||
{
|
||||
return $this->dom();
|
||||
}
|
||||
|
||||
private function init(): void
|
||||
{
|
||||
$dom = new DOMDocument;
|
||||
$dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="https://schema.phpunit.de/coverage/1.0"><build/><project/></phpunit>');
|
||||
|
||||
$this->setContextNode(
|
||||
$dom->getElementsByTagNameNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'project'
|
||||
)->item(0)
|
||||
);
|
||||
}
|
||||
|
||||
private function setProjectSourceDirectory(string $name): void
|
||||
{
|
||||
$this->contextNode()->setAttribute('source', $name);
|
||||
}
|
||||
}
|
99
vendor/phpunit/php-code-coverage/src/Report/Xml/Report.php
vendored
Normal file
99
vendor/phpunit/php-code-coverage/src/Report/Xml/Report.php
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use function basename;
|
||||
use function dirname;
|
||||
use DOMDocument;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Report extends File
|
||||
{
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$dom = new DOMDocument();
|
||||
$dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="https://schema.phpunit.de/coverage/1.0"><file /></phpunit>');
|
||||
|
||||
$contextNode = $dom->getElementsByTagNameNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'file'
|
||||
)->item(0);
|
||||
|
||||
parent::__construct($contextNode);
|
||||
|
||||
$this->setName($name);
|
||||
}
|
||||
|
||||
public function asDom(): DOMDocument
|
||||
{
|
||||
return $this->dom();
|
||||
}
|
||||
|
||||
public function functionObject($name): Method
|
||||
{
|
||||
$node = $this->contextNode()->appendChild(
|
||||
$this->dom()->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'function'
|
||||
)
|
||||
);
|
||||
|
||||
return new Method($node, $name);
|
||||
}
|
||||
|
||||
public function classObject($name): Unit
|
||||
{
|
||||
return $this->unitObject('class', $name);
|
||||
}
|
||||
|
||||
public function traitObject($name): Unit
|
||||
{
|
||||
return $this->unitObject('trait', $name);
|
||||
}
|
||||
|
||||
public function source(): Source
|
||||
{
|
||||
$source = $this->contextNode()->getElementsByTagNameNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'source'
|
||||
)->item(0);
|
||||
|
||||
if (!$source) {
|
||||
$source = $this->contextNode()->appendChild(
|
||||
$this->dom()->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'source'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return new Source($source);
|
||||
}
|
||||
|
||||
private function setName(string $name): void
|
||||
{
|
||||
$this->contextNode()->setAttribute('name', basename($name));
|
||||
$this->contextNode()->setAttribute('path', dirname($name));
|
||||
}
|
||||
|
||||
private function unitObject(string $tagName, $name): Unit
|
||||
{
|
||||
$node = $this->contextNode()->appendChild(
|
||||
$this->dom()->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
$tagName
|
||||
)
|
||||
);
|
||||
|
||||
return new Unit($node, $name);
|
||||
}
|
||||
}
|
42
vendor/phpunit/php-code-coverage/src/Report/Xml/Source.php
vendored
Normal file
42
vendor/phpunit/php-code-coverage/src/Report/Xml/Source.php
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use DOMElement;
|
||||
use TheSeer\Tokenizer\NamespaceUri;
|
||||
use TheSeer\Tokenizer\Tokenizer;
|
||||
use TheSeer\Tokenizer\XMLSerializer;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Source
|
||||
{
|
||||
/** @var DOMElement */
|
||||
private $context;
|
||||
|
||||
public function __construct(DOMElement $context)
|
||||
{
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
public function setSourceCode(string $source): void
|
||||
{
|
||||
$context = $this->context;
|
||||
|
||||
$tokens = (new Tokenizer())->parse($source);
|
||||
$srcDom = (new XMLSerializer(new NamespaceUri($context->namespaceURI)))->toDom($tokens);
|
||||
|
||||
$context->parentNode->replaceChild(
|
||||
$context->ownerDocument->importNode($srcDom->documentElement, true),
|
||||
$context
|
||||
);
|
||||
}
|
||||
}
|
51
vendor/phpunit/php-code-coverage/src/Report/Xml/Tests.php
vendored
Normal file
51
vendor/phpunit/php-code-coverage/src/Report/Xml/Tests.php
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use DOMElement;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Tests
|
||||
{
|
||||
private $contextNode;
|
||||
|
||||
private $codeMap = [
|
||||
-1 => 'UNKNOWN', // PHPUnit_Runner_BaseTestRunner::STATUS_UNKNOWN
|
||||
0 => 'PASSED', // PHPUnit_Runner_BaseTestRunner::STATUS_PASSED
|
||||
1 => 'SKIPPED', // PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED
|
||||
2 => 'INCOMPLETE', // PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE
|
||||
3 => 'FAILURE', // PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE
|
||||
4 => 'ERROR', // PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
|
||||
5 => 'RISKY', // PHPUnit_Runner_BaseTestRunner::STATUS_RISKY
|
||||
6 => 'WARNING', // PHPUnit_Runner_BaseTestRunner::STATUS_WARNING
|
||||
];
|
||||
|
||||
public function __construct(DOMElement $context)
|
||||
{
|
||||
$this->contextNode = $context;
|
||||
}
|
||||
|
||||
public function addTest(string $test, array $result): void
|
||||
{
|
||||
$node = $this->contextNode->appendChild(
|
||||
$this->contextNode->ownerDocument->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'test'
|
||||
)
|
||||
);
|
||||
|
||||
$node->setAttribute('name', $test);
|
||||
$node->setAttribute('size', $result['size']);
|
||||
$node->setAttribute('result', (string) $result['status']);
|
||||
$node->setAttribute('status', $this->codeMap[(int) $result['status']]);
|
||||
}
|
||||
}
|
146
vendor/phpunit/php-code-coverage/src/Report/Xml/Totals.php
vendored
Normal file
146
vendor/phpunit/php-code-coverage/src/Report/Xml/Totals.php
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use function sprintf;
|
||||
use DOMElement;
|
||||
use DOMNode;
|
||||
use SebastianBergmann\CodeCoverage\Percentage;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Totals
|
||||
{
|
||||
/**
|
||||
* @var DOMNode
|
||||
*/
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* @var DOMElement
|
||||
*/
|
||||
private $linesNode;
|
||||
|
||||
/**
|
||||
* @var DOMElement
|
||||
*/
|
||||
private $methodsNode;
|
||||
|
||||
/**
|
||||
* @var DOMElement
|
||||
*/
|
||||
private $functionsNode;
|
||||
|
||||
/**
|
||||
* @var DOMElement
|
||||
*/
|
||||
private $classesNode;
|
||||
|
||||
/**
|
||||
* @var DOMElement
|
||||
*/
|
||||
private $traitsNode;
|
||||
|
||||
public function __construct(DOMElement $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
$dom = $container->ownerDocument;
|
||||
|
||||
$this->linesNode = $dom->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'lines'
|
||||
);
|
||||
|
||||
$this->methodsNode = $dom->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'methods'
|
||||
);
|
||||
|
||||
$this->functionsNode = $dom->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'functions'
|
||||
);
|
||||
|
||||
$this->classesNode = $dom->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'classes'
|
||||
);
|
||||
|
||||
$this->traitsNode = $dom->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'traits'
|
||||
);
|
||||
|
||||
$container->appendChild($this->linesNode);
|
||||
$container->appendChild($this->methodsNode);
|
||||
$container->appendChild($this->functionsNode);
|
||||
$container->appendChild($this->classesNode);
|
||||
$container->appendChild($this->traitsNode);
|
||||
}
|
||||
|
||||
public function container(): DOMNode
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
public function setNumLines(int $loc, int $cloc, int $ncloc, int $executable, int $executed): void
|
||||
{
|
||||
$this->linesNode->setAttribute('total', (string) $loc);
|
||||
$this->linesNode->setAttribute('comments', (string) $cloc);
|
||||
$this->linesNode->setAttribute('code', (string) $ncloc);
|
||||
$this->linesNode->setAttribute('executable', (string) $executable);
|
||||
$this->linesNode->setAttribute('executed', (string) $executed);
|
||||
$this->linesNode->setAttribute(
|
||||
'percent',
|
||||
$executable === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($executed, $executable)->asFloat())
|
||||
);
|
||||
}
|
||||
|
||||
public function setNumClasses(int $count, int $tested): void
|
||||
{
|
||||
$this->classesNode->setAttribute('count', (string) $count);
|
||||
$this->classesNode->setAttribute('tested', (string) $tested);
|
||||
$this->classesNode->setAttribute(
|
||||
'percent',
|
||||
$count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat())
|
||||
);
|
||||
}
|
||||
|
||||
public function setNumTraits(int $count, int $tested): void
|
||||
{
|
||||
$this->traitsNode->setAttribute('count', (string) $count);
|
||||
$this->traitsNode->setAttribute('tested', (string) $tested);
|
||||
$this->traitsNode->setAttribute(
|
||||
'percent',
|
||||
$count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat())
|
||||
);
|
||||
}
|
||||
|
||||
public function setNumMethods(int $count, int $tested): void
|
||||
{
|
||||
$this->methodsNode->setAttribute('count', (string) $count);
|
||||
$this->methodsNode->setAttribute('tested', (string) $tested);
|
||||
$this->methodsNode->setAttribute(
|
||||
'percent',
|
||||
$count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat())
|
||||
);
|
||||
}
|
||||
|
||||
public function setNumFunctions(int $count, int $tested): void
|
||||
{
|
||||
$this->functionsNode->setAttribute('count', (string) $count);
|
||||
$this->functionsNode->setAttribute('tested', (string) $tested);
|
||||
$this->functionsNode->setAttribute(
|
||||
'percent',
|
||||
$count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat())
|
||||
);
|
||||
}
|
||||
}
|
78
vendor/phpunit/php-code-coverage/src/Report/Xml/Unit.php
vendored
Normal file
78
vendor/phpunit/php-code-coverage/src/Report/Xml/Unit.php
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\Report\Xml;
|
||||
|
||||
use DOMElement;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
final class Unit
|
||||
{
|
||||
/**
|
||||
* @var DOMElement
|
||||
*/
|
||||
private $contextNode;
|
||||
|
||||
public function __construct(DOMElement $context, string $name)
|
||||
{
|
||||
$this->contextNode = $context;
|
||||
|
||||
$this->setName($name);
|
||||
}
|
||||
|
||||
public function setLines(int $start, int $executable, int $executed): void
|
||||
{
|
||||
$this->contextNode->setAttribute('start', (string) $start);
|
||||
$this->contextNode->setAttribute('executable', (string) $executable);
|
||||
$this->contextNode->setAttribute('executed', (string) $executed);
|
||||
}
|
||||
|
||||
public function setCrap(float $crap): void
|
||||
{
|
||||
$this->contextNode->setAttribute('crap', (string) $crap);
|
||||
}
|
||||
|
||||
public function setNamespace(string $namespace): void
|
||||
{
|
||||
$node = $this->contextNode->getElementsByTagNameNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'namespace'
|
||||
)->item(0);
|
||||
|
||||
if (!$node) {
|
||||
$node = $this->contextNode->appendChild(
|
||||
$this->contextNode->ownerDocument->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'namespace'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$node->setAttribute('name', $namespace);
|
||||
}
|
||||
|
||||
public function addMethod(string $name): Method
|
||||
{
|
||||
$node = $this->contextNode->appendChild(
|
||||
$this->contextNode->ownerDocument->createElementNS(
|
||||
'https://schema.phpunit.de/coverage/1.0',
|
||||
'method'
|
||||
)
|
||||
);
|
||||
|
||||
return new Method($node, $name);
|
||||
}
|
||||
|
||||
private function setName(string $name): void
|
||||
{
|
||||
$this->contextNode->setAttribute('name', $name);
|
||||
}
|
||||
}
|
90
vendor/phpunit/php-code-coverage/src/StaticAnalysis/Cache.php
vendored
Normal file
90
vendor/phpunit/php-code-coverage/src/StaticAnalysis/Cache.php
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\StaticAnalysis;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use function file_get_contents;
|
||||
use function file_put_contents;
|
||||
use function filemtime;
|
||||
use function hash;
|
||||
use function is_file;
|
||||
use function serialize;
|
||||
use function unserialize;
|
||||
use SebastianBergmann\CodeCoverage\Directory;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
|
||||
*/
|
||||
abstract class Cache
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $directory;
|
||||
|
||||
public function __construct(string $directory)
|
||||
{
|
||||
Directory::create($directory);
|
||||
|
||||
$this->directory = $directory;
|
||||
}
|
||||
|
||||
protected function has(string $filename, string $key): bool
|
||||
{
|
||||
$cacheFile = $this->cacheFile($filename, $key);
|
||||
|
||||
if (!is_file($cacheFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (filemtime($cacheFile) < filemtime($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-param list<class-string> $allowedClasses
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function read(string $filename, string $key, array $allowedClasses = [])
|
||||
{
|
||||
$options = ['allowed_classes' => false];
|
||||
|
||||
if (!empty($allowedClasses)) {
|
||||
$options = ['allowed_classes' => $allowedClasses];
|
||||
}
|
||||
|
||||
return unserialize(
|
||||
file_get_contents(
|
||||
$this->cacheFile($filename, $key)
|
||||
),
|
||||
$options
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*/
|
||||
protected function write(string $filename, string $key, $data): void
|
||||
{
|
||||
file_put_contents(
|
||||
$this->cacheFile($filename, $key),
|
||||
serialize($data)
|
||||
);
|
||||
}
|
||||
|
||||
private function cacheFile(string $filename, string $key): string
|
||||
{
|
||||
return $this->directory . DIRECTORY_SEPARATOR . hash('sha256', $filename . $key);
|
||||
}
|
||||
}
|
38
vendor/phpunit/php-code-coverage/src/StaticAnalysis/CacheWarmer.php
vendored
Normal file
38
vendor/phpunit/php-code-coverage/src/StaticAnalysis/CacheWarmer.php
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<?php declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of phpunit/php-code-coverage.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace SebastianBergmann\CodeCoverage\StaticAnalysis;
|
||||
|
||||
use SebastianBergmann\CodeCoverage\Filter;
|
||||
|
||||
final class CacheWarmer
|
||||
{
|
||||
public function warmCache(string $cacheDirectory, bool $useAnnotationsForIgnoringCode, bool $ignoreDeprecatedCode, Filter $filter): void
|
||||
{
|
||||
$coveredFileAnalyser = new CachingCoveredFileAnalyser(
|
||||
$cacheDirectory,
|
||||
new ParsingCoveredFileAnalyser(
|
||||
$useAnnotationsForIgnoringCode,
|
||||
$ignoreDeprecatedCode
|
||||
)
|
||||
);
|
||||
|
||||
$uncoveredFileAnalyser = new CachingUncoveredFileAnalyser(
|
||||
$cacheDirectory,
|
||||
new ParsingUncoveredFileAnalyser
|
||||
);
|
||||
|
||||
foreach ($filter->files() as $file) {
|
||||
$coveredFileAnalyser->process($file);
|
||||
|
||||
/* @noinspection UnusedFunctionResultInspection */
|
||||
$uncoveredFileAnalyser->executableLinesIn($file);
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user