Add pear modules, mail and net_smtp via composer (#93)

Add pear modules, mail and net_smtp via composer, remove php 5.6 build due to phpunit 6
This commit is contained in:
Thilina Hasantha authored and GitHub committed 2018-01-08 23:13:43 +01:00
1 parent 359e3f8382
commit e7792e7d79
2349 files changed
+117263 -83163

No files matched your search

@@ -0,0 +1,18 @@
| Q | A
| --------------------------| ---------------
| php-code-coverage version | x.y.z
| PHP version | x.y.z
| Driver | Xdebug / PHPDBG
| Xdebug version (if used) | x.y.z
| Installation Method | Composer / PHPUnit PHAR
| Usage Method | PHPUnit / other
| PHPUnit version (if used) | x.y.z
<!--
- Please fill in this template according to your issue.
- Please keep the table shown above at the top of your issue.
- Please post code as text (using proper markup). Do not post screenshots of code.
- For support request or how-tos, visit https://phpunit.de/support.html
- Otherwise, replace this comment by the description of your issue.
-->
@@ -1,12 +1,6 @@
build/api
build/code-browser
build/coverage
build/logs
build/pdepend
cache.properties
/tests/_files/tmp
/vendor
/composer.lock
/composer.phar
/.idea
/.php_cs.cache
+84 -66
View File
@@ -1,69 +1,87 @@
<?php
$finder = Symfony\CS\Finder\DefaultFinder::create()
->files()
->in('src')
->in('tests')
->exclude('_files')
->name('*.php');
$header = <<<'EOF'
This file is part of the php-code-coverage package.
return Symfony\CS\Config\Config::create()
->setUsingCache(true)
->level(\Symfony\CS\FixerInterface::NONE_LEVEL)
->fixers(
array(
'align_double_arrow',
'align_equals',
'braces',
'concat_with_spaces',
'duplicate_semicolon',
'elseif',
'empty_return',
'encoding',
'eof_ending',
'extra_empty_lines',
'function_call_space',
'function_declaration',
'indentation',
'join_function',
'line_after_namespace',
'linefeed',
'list_commas',
'lowercase_constants',
'lowercase_keywords',
'method_argument_space',
'multiple_use',
'namespace_no_leading_whitespace',
'no_blank_lines_after_class_opening',
'no_empty_lines_after_phpdocs',
'parenthesis',
'php_closing_tag',
'phpdoc_indent',
'phpdoc_no_access',
'phpdoc_no_empty_return',
'phpdoc_no_package',
'phpdoc_params',
'phpdoc_scalar',
'phpdoc_separation',
'phpdoc_to_comment',
'phpdoc_trim',
'phpdoc_types',
'phpdoc_var_without_name',
'remove_lines_between_uses',
'return',
'self_accessor',
'short_array_syntax',
'short_tag',
'single_line_after_imports',
'single_quote',
'spaces_before_semicolon',
'spaces_cast',
'ternary_spaces',
'trailing_spaces',
'trim_array_spaces',
'unused_use',
'visibility',
'whitespacy_lines'
)
(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.
EOF;
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules(
[
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => [
'align_double_arrow' => true,
'align_equals' => true
],
'blank_line_after_namespace' => true,
'blank_line_before_statement' => [
'statements' => [
'break',
'continue',
'return',
'throw',
'try',
],
],
'braces' => true,
'cast_spaces' => true,
'concat_space' => ['spacing' => 'one'],
'elseif' => true,
'encoding' => true,
'full_opening_tag' => true,
'function_declaration' => true,
'header_comment' => ['header' => $header, 'separate' => 'none'],
'indentation_type' => true,
'line_ending' => true,
'lowercase_constants' => true,
'lowercase_keywords' => true,
'method_argument_space' => true,
'native_function_invocation' => true,
'no_alias_functions' => true,
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_closing_tag' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_extra_consecutive_blank_lines' => true,
'no_leading_namespace_whitespace' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_spaces_after_function_name' => true,
'no_spaces_inside_parenthesis' => true,
'no_trailing_comma_in_list_call' => true,
'no_trailing_whitespace' => true,
'no_unused_imports' => true,
'no_whitespace_in_blank_line' => true,
'ordered_imports' => true,
'phpdoc_align' => true,
'phpdoc_indent' => true,
'phpdoc_no_access' => true,
'phpdoc_no_empty_return' => true,
'phpdoc_no_package' => true,
'phpdoc_scalar' => true,
'phpdoc_separation' => true,
'phpdoc_to_comment' => true,
'phpdoc_trim' => true,
'phpdoc_types' => true,
'phpdoc_var_without_name' => true,
'self_accessor' => true,
'simplified_null_return' => true,
'single_blank_line_at_eof' => true,
'single_import_per_statement' => true,
'single_line_after_imports' => true,
'single_quote' => true,
'ternary_operator_spaces' => true,
'trim_array_spaces' => true,
'visibility_required' => true,
]
)
->finder($finder);
->setFinder(
PhpCsFixer\Finder::create()
->files()
->in(__DIR__ . '/src')
->name('*.php')
);
+26 -8
View File
@@ -1,21 +1,39 @@
language: php
php:
- 5.6
- 7.0
- nightly
sudo: false
php:
- 7.0
- 7.1
- 7.2
- master
matrix:
allow_failures:
- php: master
fast_finish: true
env:
matrix:
- DEPENDENCIES="high"
- DEPENDENCIES="low"
global:
- DEFAULT_COMPOSER_FLAGS="--no-interaction --no-ansi --no-progress --no-suggest"
before_install:
- composer self-update
- composer self-update
- composer clear-cache
install:
- travis_retry composer install --no-interaction --prefer-source
- if [[ "$DEPENDENCIES" = 'high' ]]; then travis_retry composer update $DEFAULT_COMPOSER_FLAGS; fi
- if [[ "$DEPENDENCIES" = 'low' ]]; then travis_retry composer update $DEFAULT_COMPOSER_FLAGS --prefer-lowest; fi
script:
- if [[ "$DRIVER" = 'phpdbg' ]]; then phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml; fi
- if [[ "$DRIVER" = 'xdebug' ]]; then vendor/bin/phpunit --coverage-clover=coverage.xml; fi
- vendor/bin/phpunit --configuration build
after_success:
- bash <(curl -s https://codecov.io/bash)
notifications:
email: false
@@ -2,6 +2,41 @@
All notable changes of the PHP_CodeCoverage 4.0 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [4.0.8] - 2017-04-02
* Fixed [#515](https://github.com/sebastianbergmann/php-code-coverage/pull/515): Wrong use of recursive iterator causing duplicate entries in XML coverage report
## [4.0.7] - 2017-03-01
### Changed
* Cleaned up requirements in `composer.json`
## [4.0.6] - 2017-02-23
### Changed
* Added support for `phpunit/php-token-stream` 2.0
* Updated HTML report assets
## [4.0.5] - 2017-01-20
### Fixed
* Fixed formatting of executed lines percentage for classes in file view
## [4.0.4] - 2016-12-20
### Changed
* Implemented [#432](https://github.com/sebastianbergmann/php-code-coverage/issues/432): Change how files with no executable lines are displayed in the HTML report
## [4.0.3] - 2016-11-28
### Changed
* The check for unintentionally covered code is no longer performed for `@medium` and `@large` tests
## [4.0.2] - 2016-11-01
### Fixed
@@ -20,6 +55,12 @@ All notable changes of the PHP_CodeCoverage 4.0 release series are documented in
* This component now uses namespaces
[4.0.8]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.7...4.0.8
[4.0.7]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.6...4.0.7
[4.0.6]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.5...4.0.6
[4.0.5]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.4...4.0.5
[4.0.4]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.3...4.0.4
[4.0.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.2...4.0.3
[4.0.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.1...4.0.2
[4.0.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.0...4.0.1
[4.0.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.3...4.0.0
@@ -0,0 +1,45 @@
# Changes in PHP_CodeCoverage 5.0
All notable changes of the PHP_CodeCoverage 5.0 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [5.0.4] - 2017-04-02
### Added
* Added `SebastianBergmann\CodeCoverage\Version::id()` method
### Fixed
* Fixed [#515](https://github.com/sebastianbergmann/php-code-coverage/pull/515): Wrong use of recursive iterator causing duplicate entries in XML coverage report
## [5.0.3] - 2017-03-06
### Fixed
* Fixed [#451](https://github.com/sebastianbergmann/php-code-coverage/pull/451): Conflict between HTML report assets and directories named `css`, `fonts`, or `js`
* Fixed [#485](https://github.com/sebastianbergmann/php-code-coverage/issues/485): Large popover contents cannot be viewed
## [5.0.2] - 2017-03-01
### Changed
* Cleaned up requirements in `composer.json`
## [5.0.1] - 2017-02-23
### Added
* Implemented [#508](https://github.com/sebastianbergmann/php-code-coverage/pull/508): Support for HackLang's `ENUM` declaration
## [5.0.0] - 2017-02-03
### Removed
* This component is no longer supported on PHP 5
[5.0.4]: https://github.com/sebastianbergmann/php-code-coverage/compare/5.0.3...5.0.4
[5.0.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/5.0.2...5.0.3
[5.0.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/5.0.1...5.0.2
[5.0.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/5.0.0...5.0.1
[5.0.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0...5.0.0
@@ -0,0 +1,19 @@
# Changes in PHP_CodeCoverage 5.1
All notable changes of the PHP_CodeCoverage 5.1 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [5.1.1] - 2017-04-12
## Fixed
* Fixed [#420](https://github.com/sebastianbergmann/php-code-coverage/issues/420): Check for unexecuted covered or used code is too strict
## [5.1.0] - 2017-04-07
## Changed
* Implemented [#516](https://github.com/sebastianbergmann/php-code-coverage/pull/516): Add more information to XML code coverage report
[5.1.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/5.1.0...5.1.1
[5.1.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/5.0...5.1.0
@@ -0,0 +1,44 @@
# Changes in PHP_CodeCoverage 5.2
All notable changes of the PHP_CodeCoverage 5.2 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [5.2.4] - 2017-11-27
### Fixed
* Fixed [#424](https://github.com/sebastianbergmann/php-code-coverage/issues/424): Rest of a function or method is ignored after an anonymous function
* Fixed [#455](https://github.com/sebastianbergmann/php-code-coverage/issues/455): Dashboard does not handle namespaced classes properly
* Fixed [#468](https://github.com/sebastianbergmann/php-code-coverage/issues/468): Global functions are not properly counted
* Fixed [#560](https://github.com/sebastianbergmann/php-code-coverage/issues/560): Uncovered whitelisted files are missing from the report
## [5.2.3] - 2017-11-03
### Fixed
* Fixed [#540](https://github.com/sebastianbergmann/php-code-coverage/issues/540): Missing attribute `type` in the CSS `<link>` elements
* Fixed [#554](https://github.com/sebastianbergmann/php-code-coverage/pull/554): `Parameter must be an array or an object that implements Countable`
## [5.2.2] - 2017-08-03
## Changed
* Bumped required versions of dependencies
## [5.2.1] - 2017-04-21
## Changed
* Version 3 of `sebastian/environment` is now required
## [5.2.0] - 2017-04-20
## Changed
* Implemented [#518](https://github.com/sebastianbergmann/php-code-coverage/pull/518): Add more information to XML code coverage report
[5.2.4]: https://github.com/sebastianbergmann/php-code-coverage/compare/5.2.3...5.2.4
[5.2.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/5.2.2...5.2.3
[5.2.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/5.2.1...5.2.2
[5.2.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/5.2.0...5.2.1
[5.2.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/5.1...5.2.0
@@ -0,0 +1,16 @@
# Changes in PHP_CodeCoverage 5.3
All notable changes of the PHP_CodeCoverage 5.3 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [5.3.0] - 2017-12-06
### Added
* Added option to ignore the `forceCoversAnnotation="true"` setting for a single test
### Fixed
* Fixed [#564](https://github.com/sebastianbergmann/php-code-coverage/issues/564): `setDisableIgnoredLines(true)` disables more than it should
[5.3.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/5.2...5.3.0
+1 -1
View File
@@ -1,6 +1,6 @@
PHP_CodeCoverage
Copyright (c) 2009-2015, Sebastian Bergmann <sebastian@phpunit.de>.
Copyright (c) 2009-2017, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
+10 -21
View File
@@ -1,25 +1,9 @@
[![Latest Stable Version](https://poser.pugx.org/phpunit/php-code-coverage/v/stable.png)](https://packagist.org/packages/phpunit/php-code-coverage)
[![Build Status](https://travis-ci.org/sebastianbergmann/php-code-coverage.svg?branch=master)](https://travis-ci.org/sebastianbergmann/php-code-coverage)
[![Build Status](https://travis-ci.org/sebastianbergmann/php-code-coverage.svg?branch=5.3)](https://travis-ci.org/sebastianbergmann/php-code-coverage)
# PHP_CodeCoverage
# SebastianBergmann\CodeCoverage
**PHP_CodeCoverage** is a library that provides collection, processing, and rendering functionality for PHP code coverage information.
## Requirements
PHP 5.6 is required but using the latest version of PHP is highly recommended.
### PHP 5
[Xdebug](http://xdebug.org/) is the only source of raw code coverage data supported for PHP 5. Version 2.2.1 of Xdebug is required but using the latest version is highly recommended.
### PHP 7
Version 2.4.0 (or later) of [Xdebug](http://xdebug.org/) as well as [phpdbg](http://phpdbg.com/docs) are supported sources of raw code coverage data for PHP 7.
### HHVM
A version of HHVM that implements the Xdebug API for code coverage (`xdebug_*_code_coverage()`) is required.
**SebastianBergmann\CodeCoverage** is a library that provides collection, processing, and rendering functionality for PHP code coverage information.
## Installation
@@ -31,11 +15,16 @@ If you only need this library during development, for instance to run your proje
composer require --dev phpunit/php-code-coverage
## Using the PHP_CodeCoverage API
## Using the SebastianBergmann\CodeCoverage API
```php
<?php
$coverage = new \SebastianBergmann\CodeCoverage\CodeCoverage;
use SebastianBergmann\CodeCoverage\CodeCoverage;
$coverage = new CodeCoverage;
$coverage->filter()->addDirectoryToWhitelist('/path/to/src');
$coverage->start('<name of test>');
// ...
+15 -37
View File
@@ -1,41 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="PHP_CodeCoverage">
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/vendor"/>
<delete file="${basedir}/composer.lock"/>
<project name="php-code-coverage" default="setup">
<target name="setup" depends="clean,composer"/>
<delete>
<fileset dir="${basedir}/build">
<include name="**/*.phar" />
</fileset>
</delete>
</target>
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/vendor"/>
<delete file="${basedir}/composer.lock"/>
</target>
<target name="composer" depends="clean" description="Install dependencies with Composer">
<tstamp>
<format property="thirty.days.ago" pattern="MM/dd/yyyy hh:mm aa" offset="-30" unit="day"/>
</tstamp>
<delete>
<fileset dir="${basedir}">
<include name="composer.phar" />
<date datetime="${thirty.days.ago}" when="before"/>
</fileset>
</delete>
<get src="https://getcomposer.org/composer.phar" dest="${basedir}/composer.phar" skipexisting="true"/>
<exec executable="php">
<arg value="composer.phar"/>
<arg value="install"/>
</exec>
</target>
<target name="phpcs" description="Find coding standard violations using PHP_CodeSniffer">
<exec executable="phpcs">
<arg value="--standard=PSR2" />
<arg value="--extensions=php" />
<arg path="${basedir}/src" />
<arg path="${basedir}/tests" />
</exec>
</target>
<target name="composer" depends="clean" description="Install dependencies with Composer">
<exec executable="composer" taskname="composer">
<arg value="update"/>
<arg value="--no-interaction"/>
<arg value="--no-progress"/>
<arg value="--no-ansi"/>
<arg value="--no-suggest"/>
</exec>
</target>
</project>
+20 -16
View File
@@ -12,31 +12,35 @@
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"irc": "irc://irc.freenode.net/phpunit"
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues"
},
"config": {
"optimize-autoloader": true,
"sort-packages": true
},
"prefer-stable": true,
"require": {
"php": "^5.6 || ^7.0",
"phpunit/php-file-iterator": "~1.3",
"phpunit/php-token-stream": "^1.4.2",
"phpunit/php-text-template": "~1.2",
"sebastian/code-unit-reverse-lookup": "~1.0",
"sebastian/environment": "^1.3.2 || ^2.0",
"sebastian/version": "~1.0|~2.0"
"php": "^7.0",
"ext-dom": "*",
"ext-xmlwriter": "*",
"phpunit/php-file-iterator": "^1.4.2",
"phpunit/php-token-stream": "^2.0.1",
"phpunit/php-text-template": "^1.2.1",
"sebastian/code-unit-reverse-lookup": "^1.0.1",
"sebastian/environment": "^3.0",
"sebastian/version": "^2.0.1",
"theseer/tokenizer": "^1.1"
},
"require-dev": {
"phpunit/phpunit": "^5.4",
"ext-xdebug": ">=2.1.4"
"phpunit/phpunit": "^6.0"
},
"suggest": {
"ext-dom": "*",
"ext-xdebug": ">=2.4.0",
"ext-xmlwriter": "*"
"ext-xdebug": "^2.5.5"
},
"autoload": {
"classmap": [
@@ -45,7 +49,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "4.0.x-dev"
"dev-master": "5.3.x-dev"
}
}
}
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.0/phpunit.xsd"
bootstrap="tests/bootstrap.php"
backupGlobals="false"
verbose="true">
<testsuite name="default">
<directory suffix="Test.php">tests/tests</directory>
</testsuite>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
<php>
<ini name="serialize_precision" value="14"/>
</php>
</phpunit>
@@ -10,10 +10,12 @@
namespace SebastianBergmann\CodeCoverage;
use PHPUnit\Framework\TestCase;
use PHPUnit\Runner\PhptTestCase;
use SebastianBergmann\CodeCoverage\Driver\Driver;
use SebastianBergmann\CodeCoverage\Driver\Xdebug;
use SebastianBergmann\CodeCoverage\Driver\HHVM;
use SebastianBergmann\CodeCoverage\Driver\PHPDBG;
use SebastianBergmann\CodeCoverage\Driver\Xdebug;
use SebastianBergmann\CodeCoverage\Node\Builder;
use SebastianBergmann\CodeCoverage\Node\Directory;
use SebastianBergmann\CodeUnitReverseLookup\Wizard;
@@ -127,6 +129,11 @@ class CodeCoverage
*/
private $shouldCheckForDeadAndUnused = true;
/**
* @var Directory
*/
private $report;
/**
* Constructor.
*
@@ -158,9 +165,13 @@ class CodeCoverage
*/
public function getReport()
{
$builder = new Builder;
if ($this->report === null) {
$builder = new Builder;
return $builder->build($this);
$this->report = $builder->build($this);
}
return $this->report;
}
/**
@@ -172,6 +183,7 @@ class CodeCoverage
$this->currentId = null;
$this->data = [];
$this->tests = [];
$this->report = null;
}
/**
@@ -208,7 +220,8 @@ class CodeCoverage
*/
public function setData(array $data)
{
$this->data = $data;
$this->data = $data;
$this->report = null;
}
/**
@@ -241,7 +254,7 @@ class CodeCoverage
*/
public function start($id, $clear = false)
{
if (!is_bool($clear)) {
if (!\is_bool($clear)) {
throw InvalidArgumentException::create(
1,
'boolean'
@@ -267,21 +280,23 @@ class CodeCoverage
* @param bool $append
* @param mixed $linesToBeCovered
* @param array $linesToBeUsed
* @param bool $ignoreForceCoversAnnotation
*
* @return array
*
* @throws \SebastianBergmann\CodeCoverage\RuntimeException
* @throws InvalidArgumentException
*/
public function stop($append = true, $linesToBeCovered = [], array $linesToBeUsed = [])
public function stop($append = true, $linesToBeCovered = [], array $linesToBeUsed = [], $ignoreForceCoversAnnotation = false)
{
if (!is_bool($append)) {
if (!\is_bool($append)) {
throw InvalidArgumentException::create(
1,
'boolean'
);
}
if (!is_array($linesToBeCovered) && $linesToBeCovered !== false) {
if (!\is_array($linesToBeCovered) && $linesToBeCovered !== false) {
throw InvalidArgumentException::create(
2,
'array or false'
@@ -289,7 +304,7 @@ class CodeCoverage
}
$data = $this->driver->stop();
$this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed);
$this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed, $ignoreForceCoversAnnotation);
$this->currentId = null;
@@ -304,10 +319,16 @@ class CodeCoverage
* @param bool $append
* @param mixed $linesToBeCovered
* @param array $linesToBeUsed
* @param bool $ignoreForceCoversAnnotation
*
* @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException
* @throws \SebastianBergmann\CodeCoverage\MissingCoversAnnotationException
* @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException
* @throws \ReflectionException
* @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
* @throws RuntimeException
*/
public function append(array $data, $id = null, $append = true, $linesToBeCovered = [], array $linesToBeUsed = [])
public function append(array $data, $id = null, $append = true, $linesToBeCovered = [], array $linesToBeUsed = [], $ignoreForceCoversAnnotation = false)
{
if ($id === null) {
$id = $this->currentId;
@@ -325,11 +346,12 @@ class CodeCoverage
return;
}
if ($id != 'UNCOVERED_FILES_FROM_WHITELIST') {
if ($id !== 'UNCOVERED_FILES_FROM_WHITELIST') {
$this->applyCoversAnnotationFilter(
$data,
$linesToBeCovered,
$linesToBeUsed
$linesToBeUsed,
$ignoreForceCoversAnnotation
);
}
@@ -340,20 +362,20 @@ class CodeCoverage
$size = 'unknown';
$status = null;
if ($id instanceof \PHPUnit_Framework_TestCase) {
if ($id instanceof TestCase) {
$_size = $id->getSize();
if ($_size == \PHPUnit_Util_Test::SMALL) {
if ($_size === \PHPUnit\Util\Test::SMALL) {
$size = 'small';
} elseif ($_size == \PHPUnit_Util_Test::MEDIUM) {
} elseif ($_size === \PHPUnit\Util\Test::MEDIUM) {
$size = 'medium';
} elseif ($_size == \PHPUnit_Util_Test::LARGE) {
} elseif ($_size === \PHPUnit\Util\Test::LARGE) {
$size = 'large';
}
$status = $id->getStatus();
$id = get_class($id) . '::' . $id->getName();
} elseif ($id instanceof \PHPUnit_Extensions_PhptTestCase) {
$id = \get_class($id) . '::' . $id->getName();
} elseif ($id instanceof PhptTestCase) {
$size = 'large';
$id = $id->getName();
}
@@ -366,13 +388,15 @@ class CodeCoverage
}
foreach ($lines as $k => $v) {
if ($v == Driver::LINE_EXECUTED) {
if (empty($this->data[$file][$k]) || !in_array($id, $this->data[$file][$k])) {
if ($v === Driver::LINE_EXECUTED) {
if (empty($this->data[$file][$k]) || !\in_array($id, $this->data[$file][$k])) {
$this->data[$file][$k][] = $id;
}
}
}
}
$this->report = null;
}
/**
@@ -380,10 +404,10 @@ class CodeCoverage
*
* @param CodeCoverage $that
*/
public function merge(CodeCoverage $that)
public function merge(self $that)
{
$this->filter->setWhitelistedFiles(
array_merge($this->filter->getWhitelistedFiles(), $that->filter()->getWhitelistedFiles())
\array_merge($this->filter->getWhitelistedFiles(), $that->filter()->getWhitelistedFiles())
);
foreach ($that->data as $file => $lines) {
@@ -400,15 +424,16 @@ class CodeCoverage
if (!isset($this->data[$file][$line])) {
$this->data[$file][$line] = $data;
} else {
$this->data[$file][$line] = array_unique(
array_merge($this->data[$file][$line], $data)
$this->data[$file][$line] = \array_unique(
\array_merge($this->data[$file][$line], $data)
);
}
}
}
}
$this->tests = array_merge($this->tests, $that->getTests());
$this->tests = \array_merge($this->tests, $that->getTests());
$this->report = null;
}
/**
@@ -418,7 +443,7 @@ class CodeCoverage
*/
public function setCacheTokens($flag)
{
if (!is_bool($flag)) {
if (!\is_bool($flag)) {
throw InvalidArgumentException::create(
1,
'boolean'
@@ -443,7 +468,7 @@ class CodeCoverage
*/
public function setCheckForUnintentionallyCoveredCode($flag)
{
if (!is_bool($flag)) {
if (!\is_bool($flag)) {
throw InvalidArgumentException::create(
1,
'boolean'
@@ -460,7 +485,7 @@ class CodeCoverage
*/
public function setForceCoversAnnotation($flag)
{
if (!is_bool($flag)) {
if (!\is_bool($flag)) {
throw InvalidArgumentException::create(
1,
'boolean'
@@ -477,7 +502,7 @@ class CodeCoverage
*/
public function setCheckForMissingCoversAnnotation($flag)
{
if (!is_bool($flag)) {
if (!\is_bool($flag)) {
throw InvalidArgumentException::create(
1,
'boolean'
@@ -494,7 +519,7 @@ class CodeCoverage
*/
public function setCheckForUnexecutedCoveredCode($flag)
{
if (!is_bool($flag)) {
if (!\is_bool($flag)) {
throw InvalidArgumentException::create(
1,
'boolean'
@@ -522,7 +547,7 @@ class CodeCoverage
*/
public function setAddUncoveredFilesFromWhitelist($flag)
{
if (!is_bool($flag)) {
if (!\is_bool($flag)) {
throw InvalidArgumentException::create(
1,
'boolean'
@@ -539,7 +564,7 @@ class CodeCoverage
*/
public function setProcessUncoveredFilesFromWhitelist($flag)
{
if (!is_bool($flag)) {
if (!\is_bool($flag)) {
throw InvalidArgumentException::create(
1,
'boolean'
@@ -556,7 +581,7 @@ class CodeCoverage
*/
public function setDisableIgnoredLines($flag)
{
if (!is_bool($flag)) {
if (!\is_bool($flag)) {
throw InvalidArgumentException::create(
1,
'boolean'
@@ -573,7 +598,7 @@ class CodeCoverage
*/
public function setIgnoreDeprecatedCode($flag)
{
if (!is_bool($flag)) {
if (!\is_bool($flag)) {
throw InvalidArgumentException::create(
1,
'boolean'
@@ -597,14 +622,17 @@ class CodeCoverage
* @param array $data
* @param mixed $linesToBeCovered
* @param array $linesToBeUsed
* @param bool $ignoreForceCoversAnnotation
*
* @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException
* @throws \ReflectionException
* @throws MissingCoversAnnotationException
* @throws UnintentionallyCoveredCodeException
*/
private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, array $linesToBeUsed)
private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, array $linesToBeUsed, $ignoreForceCoversAnnotation)
{
if ($linesToBeCovered === false ||
($this->forceCoversAnnotation && empty($linesToBeCovered))) {
($this->forceCoversAnnotation && empty($linesToBeCovered) && !$ignoreForceCoversAnnotation)) {
if ($this->checkForMissingCoversAnnotation) {
throw new MissingCoversAnnotationException;
}
@@ -618,27 +646,21 @@ class CodeCoverage
return;
}
if ($this->checkForUnintentionallyCoveredCode) {
$this->performUnintentionallyCoveredCodeCheck(
$data,
$linesToBeCovered,
$linesToBeUsed
);
if ($this->checkForUnintentionallyCoveredCode &&
(!$this->currentId instanceof TestCase ||
(!$this->currentId->isMedium() && !$this->currentId->isLarge()))) {
$this->performUnintentionallyCoveredCodeCheck($data, $linesToBeCovered, $linesToBeUsed);
}
if ($this->checkForUnexecutedCoveredCode) {
$this->performUnexecutedCoveredCodeCheck($data, $linesToBeCovered, $linesToBeUsed);
}
$data = array_intersect_key($data, $linesToBeCovered);
$data = \array_intersect_key($data, $linesToBeCovered);
foreach (array_keys($data) as $filename) {
$_linesToBeCovered = array_flip($linesToBeCovered[$filename]);
$data[$filename] = array_intersect_key(
$data[$filename],
$_linesToBeCovered
);
foreach (\array_keys($data) as $filename) {
$_linesToBeCovered = \array_flip($linesToBeCovered[$filename]);
$data[$filename] = \array_intersect_key($data[$filename], $_linesToBeCovered);
}
}
@@ -649,7 +671,7 @@ class CodeCoverage
*/
private function applyListsFilter(array &$data)
{
foreach (array_keys($data) as $filename) {
foreach (\array_keys($data) as $filename) {
if ($this->filter->isFiltered($filename)) {
unset($data[$filename]);
}
@@ -660,10 +682,12 @@ class CodeCoverage
* Applies the "ignored lines" filtering.
*
* @param array $data
*
* @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
*/
private function applyIgnoredLinesFilter(array &$data)
{
foreach (array_keys($data) as $filename) {
foreach (\array_keys($data) as $filename) {
if (!$this->filter->isFile($filename)) {
continue;
}
@@ -680,11 +704,11 @@ class CodeCoverage
private function initializeFilesThatAreSeenTheFirstTime(array $data)
{
foreach ($data as $file => $lines) {
if ($this->filter->isFile($file) && !isset($this->data[$file])) {
if (!isset($this->data[$file]) && $this->filter->isFile($file)) {
$this->data[$file] = [];
foreach ($lines as $k => $v) {
$this->data[$file][$k] = $v == -2 ? null : [];
$this->data[$file][$k] = $v === -2 ? null : [];
}
}
}
@@ -696,24 +720,22 @@ class CodeCoverage
private function addUncoveredFilesFromWhitelist()
{
$data = [];
$uncoveredFiles = array_diff(
$uncoveredFiles = \array_diff(
$this->filter->getWhitelist(),
array_keys($this->data)
\array_keys($this->data)
);
foreach ($uncoveredFiles as $uncoveredFile) {
if (!file_exists($uncoveredFile)) {
if (!\file_exists($uncoveredFile)) {
continue;
}
if (!$this->processUncoveredFilesFromWhitelist) {
$data[$uncoveredFile] = [];
$data[$uncoveredFile] = [];
$lines = count(file($uncoveredFile));
$lines = \count(\file($uncoveredFile));
for ($i = 1; $i <= $lines; $i++) {
$data[$uncoveredFile][$i] = Driver::LINE_NOT_EXECUTED;
}
for ($i = 1; $i <= $lines; $i++) {
$data[$uncoveredFile][$i] = Driver::LINE_NOT_EXECUTED;
}
}
@@ -731,168 +753,185 @@ class CodeCoverage
*/
private function getLinesToBeIgnored($filename)
{
if (!is_string($filename)) {
if (!\is_string($filename)) {
throw InvalidArgumentException::create(
1,
'string'
);
}
if (!isset($this->ignoredLines[$filename])) {
$this->ignoredLines[$filename] = [];
if (isset($this->ignoredLines[$filename])) {
return $this->ignoredLines[$filename];
}
if ($this->disableIgnoredLines) {
return $this->ignoredLines[$filename];
$this->ignoredLines[$filename] = [];
$lines = \file($filename);
foreach ($lines as $index => $line) {
if (!\trim($line)) {
$this->ignoredLines[$filename][] = $index + 1;
}
}
$ignore = false;
$stop = false;
$lines = file($filename);
$numLines = count($lines);
if ($this->cacheTokens) {
$tokens = \PHP_Token_Stream_CachingFactory::get($filename);
} else {
$tokens = new \PHP_Token_Stream($filename);
}
foreach ($lines as $index => $line) {
if (!trim($line)) {
$this->ignoredLines[$filename][] = $index + 1;
}
foreach ($tokens->getInterfaces() as $interface) {
$interfaceStartLine = $interface['startLine'];
$interfaceEndLine = $interface['endLine'];
foreach (\range($interfaceStartLine, $interfaceEndLine) as $line) {
$this->ignoredLines[$filename][] = $line;
}
}
if ($this->cacheTokens) {
$tokens = \PHP_Token_Stream_CachingFactory::get($filename);
} else {
$tokens = new \PHP_Token_Stream($filename);
}
foreach (\array_merge($tokens->getClasses(), $tokens->getTraits()) as $classOrTrait) {
$classOrTraitStartLine = $classOrTrait['startLine'];
$classOrTraitEndLine = $classOrTrait['endLine'];
$classes = array_merge($tokens->getClasses(), $tokens->getTraits());
$tokens = $tokens->tokens();
foreach ($tokens as $token) {
switch (get_class($token)) {
case 'PHP_Token_COMMENT':
case 'PHP_Token_DOC_COMMENT':
$_token = trim($token);
$_line = trim($lines[$token->getLine() - 1]);
if ($_token == '// @codeCoverageIgnore' ||
$_token == '//@codeCoverageIgnore') {
$ignore = true;
$stop = true;
} elseif ($_token == '// @codeCoverageIgnoreStart' ||
$_token == '//@codeCoverageIgnoreStart') {
$ignore = true;
} elseif ($_token == '// @codeCoverageIgnoreEnd' ||
$_token == '//@codeCoverageIgnoreEnd') {
$stop = true;
}
if (!$ignore) {
$start = $token->getLine();
$end = $start + substr_count($token, "\n");
// Do not ignore the first line when there is a token
// before the comment
if (0 !== strpos($_token, $_line)) {
$start++;
}
for ($i = $start; $i < $end; $i++) {
$this->ignoredLines[$filename][] = $i;
}
// A DOC_COMMENT token or a COMMENT token starting with "/*"
// does not contain the final \n character in its text
if (isset($lines[$i-1]) && 0 === strpos($_token, '/*') && '*/' === substr(trim($lines[$i-1]), -2)) {
$this->ignoredLines[$filename][] = $i;
}
}
break;
case 'PHP_Token_INTERFACE':
case 'PHP_Token_TRAIT':
case 'PHP_Token_CLASS':
case 'PHP_Token_FUNCTION':
/* @var \PHP_Token_Interface $token */
$docblock = $token->getDocblock();
$this->ignoredLines[$filename][] = $token->getLine();
if (strpos($docblock, '@codeCoverageIgnore') || ($this->ignoreDeprecatedCode && strpos($docblock, '@deprecated'))) {
$endLine = $token->getEndLine();
for ($i = $token->getLine(); $i <= $endLine; $i++) {
$this->ignoredLines[$filename][] = $i;
}
} elseif ($token instanceof \PHP_Token_INTERFACE ||
$token instanceof \PHP_Token_TRAIT ||
$token instanceof \PHP_Token_CLASS) {
if (empty($classes[$token->getName()]['methods'])) {
for ($i = $token->getLine();
$i <= $token->getEndLine();
$i++) {
$this->ignoredLines[$filename][] = $i;
}
} else {
$firstMethod = array_shift(
$classes[$token->getName()]['methods']
);
do {
$lastMethod = array_pop(
$classes[$token->getName()]['methods']
);
} while ($lastMethod !== null &&
substr($lastMethod['signature'], 0, 18) == 'anonymous function');
if ($lastMethod === null) {
$lastMethod = $firstMethod;
}
for ($i = $token->getLine();
$i < $firstMethod['startLine'];
$i++) {
$this->ignoredLines[$filename][] = $i;
}
for ($i = $token->getEndLine();
$i > $lastMethod['endLine'];
$i--) {
$this->ignoredLines[$filename][] = $i;
}
}
}
break;
case 'PHP_Token_NAMESPACE':
$this->ignoredLines[$filename][] = $token->getEndLine();
// Intentional fallthrough
case 'PHP_Token_DECLARE':
case 'PHP_Token_OPEN_TAG':
case 'PHP_Token_CLOSE_TAG':
case 'PHP_Token_USE':
$this->ignoredLines[$filename][] = $token->getLine();
break;
if (empty($classOrTrait['methods'])) {
foreach (\range($classOrTraitStartLine, $classOrTraitEndLine) as $line) {
$this->ignoredLines[$filename][] = $line;
}
if ($ignore) {
continue;
}
$firstMethod = \array_shift($classOrTrait['methods']);
$firstMethodStartLine = $firstMethod['startLine'];
$firstMethodEndLine = $firstMethod['endLine'];
$lastMethodEndLine = $firstMethodEndLine;
do {
$lastMethod = \array_pop($classOrTrait['methods']);
} while ($lastMethod !== null && 0 === \strpos($lastMethod['signature'], 'anonymousFunction'));
if ($lastMethod !== null) {
$lastMethodEndLine = $lastMethod['endLine'];
}
foreach (\range($classOrTraitStartLine, $firstMethodStartLine) as $line) {
$this->ignoredLines[$filename][] = $line;
}
foreach (\range($lastMethodEndLine + 1, $classOrTraitEndLine) as $line) {
$this->ignoredLines[$filename][] = $line;
}
}
if ($this->disableIgnoredLines) {
$this->ignoredLines[$filename] = array_unique($this->ignoredLines[$filename]);
\sort($this->ignoredLines[$filename]);
return $this->ignoredLines[$filename];
}
$ignore = false;
$stop = false;
foreach ($tokens->tokens() as $token) {
switch (\get_class($token)) {
case \PHP_Token_COMMENT::class:
case \PHP_Token_DOC_COMMENT::class:
$_token = \trim($token);
$_line = \trim($lines[$token->getLine() - 1]);
if ($_token === '// @codeCoverageIgnore' ||
$_token === '//@codeCoverageIgnore') {
$ignore = true;
$stop = true;
} elseif ($_token === '// @codeCoverageIgnoreStart' ||
$_token === '//@codeCoverageIgnoreStart') {
$ignore = true;
} elseif ($_token === '// @codeCoverageIgnoreEnd' ||
$_token === '//@codeCoverageIgnoreEnd') {
$stop = true;
}
if (!$ignore) {
$start = $token->getLine();
$end = $start + \substr_count($token, "\n");
// Do not ignore the first line when there is a token
// before the comment
if (0 !== \strpos($_token, $_line)) {
$start++;
}
for ($i = $start; $i < $end; $i++) {
$this->ignoredLines[$filename][] = $i;
}
// A DOC_COMMENT token or a COMMENT token starting with "/*"
// does not contain the final \n character in its text
if (isset($lines[$i - 1]) && 0 === \strpos($_token, '/*') && '*/' === \substr(\trim($lines[$i - 1]), -2)) {
$this->ignoredLines[$filename][] = $i;
}
}
break;
case \PHP_Token_INTERFACE::class:
case \PHP_Token_TRAIT::class:
case \PHP_Token_CLASS::class:
case \PHP_Token_FUNCTION::class:
/* @var \PHP_Token_Interface $token */
$docblock = $token->getDocblock();
$this->ignoredLines[$filename][] = $token->getLine();
if ($stop) {
$ignore = false;
$stop = false;
if (\strpos($docblock, '@codeCoverageIgnore') || ($this->ignoreDeprecatedCode && \strpos($docblock, '@deprecated'))) {
$endLine = $token->getEndLine();
for ($i = $token->getLine(); $i <= $endLine; $i++) {
$this->ignoredLines[$filename][] = $i;
}
}
}
break;
case \PHP_Token_ENUM::class:
$this->ignoredLines[$filename][] = $token->getLine();
break;
case \PHP_Token_NAMESPACE::class:
$this->ignoredLines[$filename][] = $token->getEndLine();
// Intentional fallthrough
case \PHP_Token_DECLARE::class:
case \PHP_Token_OPEN_TAG::class:
case \PHP_Token_CLOSE_TAG::class:
case \PHP_Token_USE::class:
$this->ignoredLines[$filename][] = $token->getLine();
break;
}
$this->ignoredLines[$filename][] = $numLines + 1;
if ($ignore) {
$this->ignoredLines[$filename][] = $token->getLine();
$this->ignoredLines[$filename] = array_unique(
$this->ignoredLines[$filename]
);
sort($this->ignoredLines[$filename]);
if ($stop) {
$ignore = false;
$stop = false;
}
}
}
$this->ignoredLines[$filename][] = \count($lines) + 1;
$this->ignoredLines[$filename] = \array_unique(
$this->ignoredLines[$filename]
);
$this->ignoredLines[$filename] = array_unique($this->ignoredLines[$filename]);
\sort($this->ignoredLines[$filename]);
return $this->ignoredLines[$filename];
}
@@ -901,6 +940,7 @@ class CodeCoverage
* @param array $linesToBeCovered
* @param array $linesToBeUsed
*
* @throws \ReflectionException
* @throws UnintentionallyCoveredCodeException
*/
private function performUnintentionallyCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed)
@@ -914,7 +954,7 @@ class CodeCoverage
foreach ($data as $file => $_data) {
foreach ($_data as $line => $flag) {
if ($flag == 1 && !isset($allowedLines[$file][$line])) {
if ($flag === 1 && !isset($allowedLines[$file][$line])) {
$unintentionallyCoveredUnits[] = $this->wizard->lookup($file, $line);
}
}
@@ -938,30 +978,24 @@ class CodeCoverage
*/
private function performUnexecutedCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed)
{
$expectedLines = $this->getAllowedLines(
$linesToBeCovered,
$linesToBeUsed
);
$executedCodeUnits = $this->coverageToCodeUnits($data);
$message = '';
foreach ($data as $file => $_data) {
foreach (array_keys($_data) as $line) {
if (!isset($expectedLines[$file][$line])) {
continue;
}
unset($expectedLines[$file][$line]);
foreach ($this->linesToCodeUnits($linesToBeCovered) as $codeUnit) {
if (!\in_array($codeUnit, $executedCodeUnits)) {
$message .= \sprintf(
'- %s is expected to be executed (@covers) but was not executed' . "\n",
$codeUnit
);
}
}
$message = '';
foreach ($expectedLines as $file => $lines) {
if (empty($lines)) {
continue;
}
foreach (array_keys($lines) as $line) {
$message .= sprintf('- %s:%d' . PHP_EOL, $file, $line);
foreach ($this->linesToCodeUnits($linesToBeUsed) as $codeUnit) {
if (!\in_array($codeUnit, $executedCodeUnits)) {
$message .= \sprintf(
'- %s is expected to be executed (@uses) but was not executed' . "\n",
$codeUnit
);
}
}
@@ -980,31 +1014,31 @@ class CodeCoverage
{
$allowedLines = [];
foreach (array_keys($linesToBeCovered) as $file) {
foreach (\array_keys($linesToBeCovered) as $file) {
if (!isset($allowedLines[$file])) {
$allowedLines[$file] = [];
}
$allowedLines[$file] = array_merge(
$allowedLines[$file] = \array_merge(
$allowedLines[$file],
$linesToBeCovered[$file]
);
}
foreach (array_keys($linesToBeUsed) as $file) {
foreach (\array_keys($linesToBeUsed) as $file) {
if (!isset($allowedLines[$file])) {
$allowedLines[$file] = [];
}
$allowedLines[$file] = array_merge(
$allowedLines[$file] = \array_merge(
$allowedLines[$file],
$linesToBeUsed[$file]
);
}
foreach (array_keys($allowedLines) as $file) {
$allowedLines[$file] = array_flip(
array_unique($allowedLines[$file])
foreach (\array_keys($allowedLines) as $file) {
$allowedLines[$file] = \array_flip(
\array_unique($allowedLines[$file])
);
}
@@ -1026,27 +1060,31 @@ class CodeCoverage
if ($runtime->isHHVM()) {
return new HHVM;
} elseif ($runtime->isPHPDBG()) {
return new PHPDBG;
} else {
return new Xdebug;
}
if ($runtime->isPHPDBG()) {
return new PHPDBG;
}
return new Xdebug;
}
/**
* @param array $unintentionallyCoveredUnits
*
* @return array
*
* @throws \ReflectionException
*/
private function processUnintentionallyCoveredUnits(array $unintentionallyCoveredUnits)
{
$unintentionallyCoveredUnits = array_unique($unintentionallyCoveredUnits);
sort($unintentionallyCoveredUnits);
$unintentionallyCoveredUnits = \array_unique($unintentionallyCoveredUnits);
\sort($unintentionallyCoveredUnits);
foreach (array_keys($unintentionallyCoveredUnits) as $k => $v) {
$unit = explode('::', $unintentionallyCoveredUnits[$k]);
foreach (\array_keys($unintentionallyCoveredUnits) as $k => $v) {
$unit = \explode('::', $unintentionallyCoveredUnits[$k]);
if (count($unit) != 2) {
if (\count($unit) !== 2) {
continue;
}
@@ -1055,17 +1093,20 @@ class CodeCoverage
foreach ($this->unintentionallyCoveredSubclassesWhitelist as $whitelisted) {
if ($class->isSubclassOf($whitelisted)) {
unset($unintentionallyCoveredUnits[$k]);
break;
}
}
}
return array_values($unintentionallyCoveredUnits);
return \array_values($unintentionallyCoveredUnits);
}
/**
* If we are processing uncovered files from whitelist,
* we can initialize the data before we start to speed up the tests
*
* @throws \SebastianBergmann\CodeCoverage\RuntimeException
*/
protected function initializeData()
{
@@ -1090,8 +1131,8 @@ class CodeCoverage
continue;
}
foreach (array_keys($fileCoverage) as $key) {
if ($fileCoverage[$key] == Driver::LINE_EXECUTED) {
foreach (\array_keys($fileCoverage) as $key) {
if ($fileCoverage[$key] === Driver::LINE_EXECUTED) {
$fileCoverage[$key] = Driver::LINE_NOT_EXECUTED;
}
}
@@ -1102,4 +1143,42 @@ class CodeCoverage
$this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST');
}
}
/**
* @param array $data
*
* @return array
*/
private function coverageToCodeUnits(array $data)
{
$codeUnits = [];
foreach ($data as $filename => $lines) {
foreach ($lines as $line => $flag) {
if ($flag === 1) {
$codeUnits[] = $this->wizard->lookup($filename, $line);
}
}
}
return \array_unique($codeUnits);
}
/**
* @param array $data
*
* @return array
*/
private function linesToCodeUnits(array $data)
{
$codeUnits = [];
foreach ($data as $filename => $lines) {
foreach ($lines as $line) {
$codeUnits[] = $this->wizard->lookup($filename, $line);
}
}
return \array_unique($codeUnits);
}
}
@@ -24,6 +24,6 @@ class HHVM extends Xdebug
*/
public function start($determineUnusedAndDead = true)
{
xdebug_start_code_coverage();
\xdebug_start_code_coverage();
}
}
@@ -30,7 +30,7 @@ class PHPDBG implements Driver
);
}
if (!function_exists('phpdbg_start_oplog')) {
if (!\function_exists('phpdbg_start_oplog')) {
throw new RuntimeException(
'This build of PHPDBG does not support code coverage'
);
@@ -61,9 +61,9 @@ class PHPDBG implements Driver
if ($fetchedLines == []) {
$sourceLines = phpdbg_get_executable();
} else {
$newFiles = array_diff(
get_included_files(),
array_keys($fetchedLines)
$newFiles = \array_diff(
\get_included_files(),
\array_keys($fetchedLines)
);
if ($newFiles) {
@@ -81,7 +81,7 @@ class PHPDBG implements Driver
}
}
$fetchedLines = array_merge($fetchedLines, $sourceLines);
$fetchedLines = \array_merge($fetchedLines, $sourceLines);
return $this->detectExecutedLines($fetchedLines, $dbgData);
}
@@ -31,12 +31,12 @@ class Xdebug implements Driver
*/
public function __construct()
{
if (!extension_loaded('xdebug')) {
if (!\extension_loaded('xdebug')) {
throw new RuntimeException('This driver requires Xdebug');
}
if (version_compare(phpversion('xdebug'), '2.2.1', '>=') &&
!ini_get('xdebug.coverage_enable')) {
if (\version_compare(\phpversion('xdebug'), '2.2.1', '>=') &&
!\ini_get('xdebug.coverage_enable')) {
throw new RuntimeException(
'xdebug.coverage_enable=On has to be set in php.ini'
);
@@ -51,9 +51,9 @@ class Xdebug implements Driver
public function start($determineUnusedAndDead = true)
{
if ($determineUnusedAndDead) {
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
\xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
} else {
xdebug_start_code_coverage();
\xdebug_start_code_coverage();
}
}
@@ -64,8 +64,8 @@ class Xdebug implements Driver
*/
public function stop()
{
$data = xdebug_get_code_coverage();
xdebug_stop_code_coverage();
$data = \xdebug_get_code_coverage();
\xdebug_stop_code_coverage();
return $this->cleanup($data);
}
@@ -77,13 +77,13 @@ class Xdebug implements Driver
*/
private function cleanup(array $data)
{
foreach (array_keys($data) as $file) {
foreach (\array_keys($data) as $file) {
unset($data[$file][0]);
if (strpos($file, 'xdebug://debug-eval') !== 0 && file_exists($file)) {
if (\strpos($file, 'xdebug://debug-eval') !== 0 && \file_exists($file)) {
$numLines = $this->getNumberOfLinesInFile($file);
foreach (array_keys($data[$file]) as $line) {
foreach (\array_keys($data[$file]) as $line) {
if ($line > $numLines) {
unset($data[$file][$line]);
}
@@ -102,10 +102,10 @@ class Xdebug implements Driver
private function getNumberOfLinesInFile($file)
{
if (!isset($this->cacheNumLines[$file])) {
$buffer = file_get_contents($file);
$lines = substr_count($buffer, "\n");
$buffer = \file_get_contents($file);
$lines = \substr_count($buffer, "\n");
if (substr($buffer, -1) !== "\n") {
if (\substr($buffer, -1) !== "\n") {
$lines++;
}
@@ -21,13 +21,13 @@ class InvalidArgumentException extends \InvalidArgumentException implements Exce
*/
public static function create($argument, $type, $value = null)
{
$stack = debug_backtrace(0);
$stack = \debug_backtrace(0);
return new self(
sprintf(
\sprintf(
'Argument #%d%sof %s::%s() must be a %s',
$argument,
$value !== null ? ' (' . gettype($value) . '#' . $value . ')' : ' (No Value) ',
$value !== null ? ' (' . \gettype($value) . '#' . $value . ')' : ' (No Value) ',
$stack[1]['class'],
$stack[1]['function'],
$type
+12 -12
View File
@@ -46,7 +46,7 @@ class Filter
*/
public function addFileToWhitelist($filename)
{
$this->whitelistedFiles[realpath($filename)] = true;
$this->whitelistedFiles[\realpath($filename)] = true;
}
/**
@@ -85,7 +85,7 @@ class Filter
*/
public function removeFileFromWhitelist($filename)
{
$filename = realpath($filename);
$filename = \realpath($filename);
unset($this->whitelistedFiles[$filename]);
}
@@ -100,17 +100,17 @@ class Filter
public function isFile($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, '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) {
return false;
}
return file_exists($filename);
return \file_exists($filename);
}
/**
@@ -126,7 +126,7 @@ class Filter
return true;
}
$filename = realpath($filename);
$filename = \realpath($filename);
return !isset($this->whitelistedFiles[$filename]);
}
@@ -138,7 +138,7 @@ class Filter
*/
public function getWhitelist()
{
return array_keys($this->whitelistedFiles);
return \array_keys($this->whitelistedFiles);
}
/**
@@ -48,10 +48,10 @@ abstract class AbstractNode implements \Countable
* @param string $name
* @param AbstractNode $parent
*/
public function __construct($name, AbstractNode $parent = null)
public function __construct($name, self $parent = null)
{
if (substr($name, -1) == '/') {
$name = substr($name, 0, -1);
if (\substr($name, -1) == '/') {
$name = \substr($name, 0, -1);
}
$this->name = $name;
@@ -80,7 +80,7 @@ abstract class AbstractNode implements \Countable
$parentId = $parent->getId();
if ($parentId == 'index') {
$this->id = str_replace(':', '_', $this->name);
$this->id = \str_replace(':', '_', $this->name);
} else {
$this->id = $parentId . '/' . $this->name;
}
@@ -165,7 +165,7 @@ abstract class AbstractNode implements \Countable
}
/**
* Returns the percentage of traits that has been tested.
* Returns the percentage of classes and traits that has been tested.
*
* @param bool $asString
*
@@ -180,6 +180,22 @@ abstract class AbstractNode implements \Countable
);
}
/**
* Returns the percentage of functions that has been tested.
*
* @param bool $asString
*
* @return int
*/
public function getTestedFunctionsPercent($asString = true)
{
return Util::percent(
$this->getNumTestedFunctions(),
$this->getNumFunctions(),
$asString
);
}
/**
* Returns the percentage of methods that has been tested.
*
@@ -196,6 +212,22 @@ abstract class AbstractNode implements \Countable
);
}
/**
* Returns the percentage of functions and methods that has been tested.
*
* @param bool $asString
*
* @return int
*/
public function getTestedFunctionsAndMethodsPercent($asString = true)
{
return Util::percent(
$this->getNumTestedFunctionsAndMethods(),
$this->getNumFunctionsAndMethods(),
$asString
);
}
/**
* Returns the percentage of executed lines.
*
@@ -239,7 +271,37 @@ abstract class AbstractNode implements \Countable
*/
public function getClassesAndTraits()
{
return array_merge($this->getClasses(), $this->getTraits());
return \array_merge($this->getClasses(), $this->getTraits());
}
/**
* Returns the number of functions and methods.
*
* @return int
*/
public function getNumFunctionsAndMethods()
{
return $this->getNumFunctions() + $this->getNumMethods();
}
/**
* Returns the number of tested functions and methods.
*
* @return int
*/
public function getNumTestedFunctionsAndMethods()
{
return $this->getNumTestedFunctions() + $this->getNumTestedMethods();
}
/**
* Returns the functions and methods of this node.
*
* @return array
*/
public function getFunctionsAndMethods()
{
return \array_merge($this->getFunctions(), $this->getMethods());
}
/**
@@ -47,10 +47,10 @@ class Builder
private function addItems(Directory $root, array $items, array $tests, $cacheTokens)
{
foreach ($items as $key => $value) {
if (substr($key, -2) == '/f') {
$key = substr($key, 0, -2);
if (\substr($key, -2) == '/f') {
$key = \substr($key, 0, -2);
if (file_exists($root->getPath() . DIRECTORY_SEPARATOR . $key)) {
if (\file_exists($root->getPath() . DIRECTORY_SEPARATOR . $key)) {
$root->addFile($key, $value, $tests, $cacheTokens);
}
} else {
@@ -109,9 +109,9 @@ class Builder
$result = [];
foreach ($files as $path => $file) {
$path = explode('/', $path);
$path = \explode('/', $path);
$pointer = &$result;
$max = count($path);
$max = \count($path);
for ($i = 0; $i < $max; $i++) {
if ($i == ($max - 1)) {
@@ -177,26 +177,26 @@ class Builder
}
$commonPath = '';
$paths = array_keys($files);
$paths = \array_keys($files);
if (count($files) == 1) {
$commonPath = dirname($paths[0]) . '/';
$files[basename($paths[0])] = $files[$paths[0]];
if (\count($files) == 1) {
$commonPath = \dirname($paths[0]) . '/';
$files[\basename($paths[0])] = $files[$paths[0]];
unset($files[$paths[0]]);
return $commonPath;
}
$max = count($paths);
$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] = strtr($paths[$i], '/', DIRECTORY_SEPARATOR);
if (\strpos($paths[$i], 'phar://') === 0) {
$paths[$i] = \substr($paths[$i], 7);
$paths[$i] = \strtr($paths[$i], '/', DIRECTORY_SEPARATOR);
}
$paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]);
$paths[$i] = \explode(DIRECTORY_SEPARATOR, $paths[$i]);
if (empty($paths[$i][0])) {
$paths[$i][0] = DIRECTORY_SEPARATOR;
@@ -204,14 +204,15 @@ class Builder
}
$done = false;
$max = count($paths);
$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]) {
!isset($paths[$i + 1][0]) ||
$paths[$i][0] != $paths[$i + 1][0]) {
$done = true;
break;
}
}
@@ -224,21 +225,21 @@ class Builder
}
for ($i = 0; $i < $max; $i++) {
array_shift($paths[$i]);
\array_shift($paths[$i]);
}
}
}
$original = array_keys($files);
$max = count($original);
$original = \array_keys($files);
$max = \count($original);
for ($i = 0; $i < $max; $i++) {
$files[implode('/', $paths[$i])] = $files[$original[$i]];
$files[\implode('/', $paths[$i])] = $files[$original[$i]];
unset($files[$original[$i]]);
}
ksort($files);
\ksort($files);
return substr($commonPath, 0, -1);
return \substr($commonPath, 0, -1);
}
}
@@ -118,7 +118,7 @@ class Directory extends AbstractNode implements \IteratorAggregate
$this->numFiles = 0;
foreach ($this->children as $child) {
$this->numFiles += count($child);
$this->numFiles += \count($child);
}
}
@@ -150,7 +150,7 @@ class Directory extends AbstractNode implements \IteratorAggregate
$directory = new self($name, $this);
$this->children[] = $directory;
$this->directories[] = &$this->children[count($this->children) - 1];
$this->directories[] = &$this->children[\count($this->children) - 1];
return $directory;
}
@@ -178,7 +178,7 @@ class Directory extends AbstractNode implements \IteratorAggregate
);
$this->children[] = $file;
$this->files[] = &$this->children[count($this->children) - 1];
$this->files[] = &$this->children[\count($this->children) - 1];
$this->numExecutableLines = -1;
$this->numExecutedLines = -1;
@@ -227,7 +227,7 @@ class Directory extends AbstractNode implements \IteratorAggregate
$this->classes = [];
foreach ($this->children as $child) {
$this->classes = array_merge(
$this->classes = \array_merge(
$this->classes,
$child->getClasses()
);
@@ -248,7 +248,7 @@ class Directory extends AbstractNode implements \IteratorAggregate
$this->traits = [];
foreach ($this->children as $child) {
$this->traits = array_merge(
$this->traits = \array_merge(
$this->traits,
$child->getTraits()
);
@@ -269,7 +269,7 @@ class Directory extends AbstractNode implements \IteratorAggregate
$this->functions = [];
foreach ($this->children as $child) {
$this->functions = array_merge(
$this->functions = \array_merge(
$this->functions,
$child->getFunctions()
);
@@ -292,8 +292,8 @@ class Directory extends AbstractNode implements \IteratorAggregate
foreach ($this->children as $child) {
$linesOfCode = $child->getLinesOfCode();
$this->linesOfCode['loc'] += $linesOfCode['loc'];
$this->linesOfCode['cloc'] += $linesOfCode['cloc'];
$this->linesOfCode['loc'] += $linesOfCode['loc'];
$this->linesOfCode['cloc'] += $linesOfCode['cloc'];
$this->linesOfCode['ncloc'] += $linesOfCode['ncloc'];
}
}
@@ -60,13 +60,23 @@ class File extends AbstractNode
/**
* @var int
*/
private $numTestedTraits = 0;
private $numClasses = null;
/**
* @var int
*/
private $numTestedClasses = 0;
/**
* @var int
*/
private $numTraits = null;
/**
* @var int
*/
private $numTestedTraits = 0;
/**
* @var int
*/
@@ -110,7 +120,7 @@ class File extends AbstractNode
*/
public function __construct($name, AbstractNode $parent, array $coverageData, array $testData, $cacheTokens)
{
if (!is_bool($cacheTokens)) {
if (!\is_bool($cacheTokens)) {
throw InvalidArgumentException::create(
1,
'boolean'
@@ -223,7 +233,21 @@ class File extends AbstractNode
*/
public function getNumClasses()
{
return count($this->classes);
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;
}
/**
@@ -243,7 +267,21 @@ class File extends AbstractNode
*/
public function getNumTraits()
{
return count($this->traits);
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;
}
/**
@@ -325,7 +363,7 @@ class File extends AbstractNode
*/
public function getNumFunctions()
{
return count($this->functions);
return \count($this->functions);
}
/**
@@ -412,7 +450,7 @@ class File extends AbstractNode
$this->numExecutableLines++;
if (count($this->coverageData[$lineNumber]) > 0) {
if (\count($this->coverageData[$lineNumber]) > 0) {
if (isset($currentClass)) {
$currentClass['executedLines']++;
}
@@ -439,8 +477,8 @@ class File extends AbstractNode
unset($currentClass);
if ($classStack) {
end($classStack);
$key = key($classStack);
\end($classStack);
$key = \key($classStack);
$currentClass = &$classStack[$key];
unset($classStack[$key]);
}
@@ -455,8 +493,8 @@ class File extends AbstractNode
unset($currentFunction);
if ($functionStack) {
end($functionStack);
$key = key($functionStack);
\end($functionStack);
$key = \key($functionStack);
$currentFunction = &$functionStack[$key];
unset($functionStack[$key]);
}
@@ -484,14 +522,14 @@ class File extends AbstractNode
if ($trait['executableLines'] > 0) {
$trait['coverage'] = ($trait['executedLines'] /
$trait['executableLines']) * 100;
if ($trait['coverage'] == 100) {
$this->numTestedClasses++;
}
} else {
$trait['coverage'] = 100;
}
if ($trait['coverage'] == 100) {
$this->numTestedClasses++;
}
$trait['crap'] = $this->crap(
$trait['ccn'],
$trait['coverage']
@@ -518,19 +556,37 @@ class File extends AbstractNode
if ($class['executableLines'] > 0) {
$class['coverage'] = ($class['executedLines'] /
$class['executableLines']) * 100;
if ($class['coverage'] == 100) {
$this->numTestedClasses++;
}
} else {
$class['coverage'] = 100;
}
if ($class['coverage'] == 100) {
$this->numTestedClasses++;
}
$class['crap'] = $this->crap(
$class['ccn'],
$class['coverage']
);
}
foreach ($this->functions as &$function) {
if ($function['executableLines'] > 0) {
$function['coverage'] = ($function['executedLines'] /
$function['executableLines']) * 100;
} else {
$function['coverage'] = 100;
}
if ($function['coverage'] == 100) {
$this->numTestedFunctions++;
}
$function['crap'] = $this->crap(
$function['ccn'],
$function['coverage']
);
}
}
/**
@@ -544,6 +600,10 @@ class File extends AbstractNode
$link = $this->getId() . '.html#';
foreach ($classes as $className => $class) {
if (!empty($class['package']['namespace'])) {
$className = $class['package']['namespace'] . '\\' . $className;
}
$this->classes[$className] = [
'className' => $className,
'methods' => [],
@@ -645,16 +705,16 @@ class File extends AbstractNode
protected function crap($ccn, $coverage)
{
if ($coverage == 0) {
return (string) (pow($ccn, 2) + $ccn);
return (string) (\pow($ccn, 2) + $ccn);
}
if ($coverage >= 95) {
return (string) $ccn;
}
return sprintf(
return \sprintf(
'%01.2F',
pow($ccn, 2) * pow(1 - $coverage/100, 3) + $ccn
\pow($ccn, 2) * \pow(1 - $coverage / 100, 3) + $ccn
);
}
@@ -48,7 +48,7 @@ class Iterator implements \RecursiveIterator
*/
public function valid()
{
return $this->position < count($this->nodes);
return $this->position < \count($this->nodes);
}
/**
@@ -37,7 +37,7 @@ class Clover
$xmlProject = $xmlDocument->createElement('project');
$xmlProject->setAttribute('timestamp', (int) $_SERVER['REQUEST_TIME']);
if (is_string($name)) {
if (\is_string($name)) {
$xmlProject->setAttribute('name', $name);
}
@@ -69,12 +69,12 @@ class Clover
$classMethods = 0;
foreach ($class['methods'] as $methodName => $method) {
if ($method['executableLines'] == 0) {
if ($method['executableLines'] == 0) {
continue;
}
$classMethods++;
$classStatements += $method['executableLines'];
$classStatements += $method['executableLines'];
$coveredClassStatements += $method['executedLines'];
if ($method['coverage'] == 100) {
@@ -83,9 +83,9 @@ class Clover
$methodCount = 0;
foreach (range($method['startLine'], $method['endLine']) as $line) {
foreach (\range($method['startLine'], $method['endLine']) as $line) {
if (isset($coverage[$line]) && ($coverage[$line] !== null)) {
$methodCount = max($methodCount, count($coverage[$line]));
$methodCount = \max($methodCount, \count($coverage[$line]));
}
}
@@ -156,11 +156,11 @@ class Clover
}
$lines[$line] = [
'count' => count($data), 'type' => 'stmt'
'count' => \count($data), 'type' => 'stmt'
];
}
ksort($lines);
\ksort($lines);
foreach ($lines as $line => $data) {
$xmlLine = $xmlDocument->createElement('line');
@@ -222,7 +222,7 @@ class Clover
$linesOfCode = $report->getLinesOfCode();
$xmlMetrics = $xmlDocument->createElement('metrics');
$xmlMetrics->setAttribute('files', count($report));
$xmlMetrics->setAttribute('files', \count($report));
$xmlMetrics->setAttribute('loc', $linesOfCode['loc']);
$xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']);
$xmlMetrics->setAttribute('classes', $report->getNumClassesAndTraits());
@@ -239,11 +239,11 @@ class Clover
$buffer = $xmlDocument->saveXML();
if ($target !== null) {
if (!is_dir(dirname($target))) {
mkdir(dirname($target), 0777, true);
if (!\is_dir(\dirname($target))) {
\mkdir(\dirname($target), 0777, true);
}
file_put_contents($target, $buffer);
\file_put_contents($target, $buffer);
}
return $buffer;
@@ -11,8 +11,8 @@
namespace SebastianBergmann\CodeCoverage\Report;
use SebastianBergmann\CodeCoverage\CodeCoverage;
use SebastianBergmann\CodeCoverage\Node\File;
use SebastianBergmann\CodeCoverage\InvalidArgumentException;
use SebastianBergmann\CodeCoverage\Node\File;
class Crap4j
{
@@ -26,7 +26,7 @@ class Crap4j
*/
public function __construct($threshold = 30)
{
if (!is_int($threshold)) {
if (!\is_int($threshold)) {
throw InvalidArgumentException::create(
1,
'integer'
@@ -51,9 +51,9 @@ class Crap4j
$root = $document->createElement('crap_result');
$document->appendChild($root);
$project = $document->createElement('project', is_string($name) ? $name : '');
$project = $document->createElement('project', \is_string($name) ? $name : '');
$root->appendChild($project);
$root->appendChild($document->createElement('timestamp', date('Y-m-d H:i:s', (int) $_SERVER['REQUEST_TIME'])));
$root->appendChild($document->createElement('timestamp', \date('Y-m-d H:i:s', (int) $_SERVER['REQUEST_TIME'])));
$stats = $document->createElement('stats');
$methodsNode = $document->createElement('methods');
@@ -82,7 +82,7 @@ class Crap4j
foreach ($class['methods'] as $methodName => $method) {
$crapLoad = $this->getCrapLoad($method['crap'], $method['ccn'], $method['coverage']);
$fullCrap += $method['crap'];
$fullCrap += $method['crap'];
$fullCrapLoad += $crapLoad;
$fullMethodCount++;
@@ -99,12 +99,12 @@ class Crap4j
$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('methodSignature', \htmlspecialchars($method['signature'])));
$methodNode->appendChild($document->createElement('fullMethod', \htmlspecialchars($method['signature'])));
$methodNode->appendChild($document->createElement('crap', $this->roundValue($method['crap'])));
$methodNode->appendChild($document->createElement('complexity', $method['ccn']));
$methodNode->appendChild($document->createElement('coverage', $this->roundValue($method['coverage'])));
$methodNode->appendChild($document->createElement('crapLoad', round($crapLoad)));
$methodNode->appendChild($document->createElement('crapLoad', \round($crapLoad)));
$methodsNode->appendChild($methodNode);
}
@@ -114,7 +114,7 @@ class Crap4j
$stats->appendChild($document->createElement('name', 'Method Crap Stats'));
$stats->appendChild($document->createElement('methodCount', $fullMethodCount));
$stats->appendChild($document->createElement('crapMethodCount', $fullCrapMethodCount));
$stats->appendChild($document->createElement('crapLoad', round($fullCrapLoad)));
$stats->appendChild($document->createElement('crapLoad', \round($fullCrapLoad)));
$stats->appendChild($document->createElement('totalCrap', $fullCrap));
if ($fullMethodCount > 0) {
@@ -131,11 +131,11 @@ class Crap4j
$buffer = $document->saveXML();
if ($target !== null) {
if (!is_dir(dirname($target))) {
mkdir(dirname($target), 0777, true);
if (!\is_dir(\dirname($target))) {
\mkdir(\dirname($target), 0777, true);
}
file_put_contents($target, $buffer);
\file_put_contents($target, $buffer);
}
return $buffer;
@@ -167,6 +167,6 @@ class Crap4j
*/
private function roundValue($value)
{
return round($value, 2);
return \round($value, 2);
}
}
@@ -65,10 +65,10 @@ class Facade
unset($coverage);
if (!isset($_SERVER['REQUEST_TIME'])) {
$_SERVER['REQUEST_TIME'] = time();
$_SERVER['REQUEST_TIME'] = \time();
}
$date = date('D M j G:i:s T Y', $_SERVER['REQUEST_TIME']);
$date = \date('D M j G:i:s T Y', $_SERVER['REQUEST_TIME']);
$dashboard = new Dashboard(
$this->templatePath,
@@ -101,17 +101,17 @@ class Facade
$id = $node->getId();
if ($node instanceof DirectoryNode) {
if (!file_exists($target . $id)) {
mkdir($target . $id, 0777, true);
if (!\file_exists($target . $id)) {
\mkdir($target . $id, 0777, true);
}
$directory->render($node, $target . $id . '/index.html');
$dashboard->render($node, $target . $id . '/dashboard.html');
} else {
$dir = dirname($target . $id);
$dir = \dirname($target . $id);
if (!file_exists($dir)) {
mkdir($dir, 0777, true);
if (!\file_exists($dir)) {
\mkdir($dir, 0777, true);
}
$file->render($node, $target . $id . '.html');
@@ -126,26 +126,37 @@ class Facade
*/
private function copyFiles($target)
{
$dir = $this->getDirectory($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');
$dir = $this->getDirectory($target . '.css');
$dir = $this->getDirectory($target . 'fonts');
copy($this->templatePath . 'fonts/glyphicons-halflings-regular.eot', $dir . 'glyphicons-halflings-regular.eot');
copy($this->templatePath . 'fonts/glyphicons-halflings-regular.svg', $dir . 'glyphicons-halflings-regular.svg');
copy($this->templatePath . 'fonts/glyphicons-halflings-regular.ttf', $dir . 'glyphicons-halflings-regular.ttf');
copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff', $dir . 'glyphicons-halflings-regular.woff');
copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff2', $dir . 'glyphicons-halflings-regular.woff2');
\file_put_contents(
$dir . 'bootstrap.min.css',
\str_replace(
'url(../fonts/',
'url(../.fonts/',
\file_get_contents($this->templatePath . 'css/bootstrap.min.css')
)
$dir = $this->getDirectory($target . 'js');
copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js');
copy($this->templatePath . 'js/d3.min.js', $dir . 'd3.min.js');
copy($this->templatePath . 'js/holder.min.js', $dir . 'holder.min.js');
copy($this->templatePath . 'js/html5shiv.min.js', $dir . 'html5shiv.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/respond.min.js', $dir . 'respond.min.js');
);
\copy($this->templatePath . 'css/nv.d3.min.css', $dir . 'nv.d3.min.css');
\copy($this->templatePath . 'css/style.css', $dir . 'style.css');
$dir = $this->getDirectory($target . '.fonts');
\copy($this->templatePath . 'fonts/glyphicons-halflings-regular.eot', $dir . 'glyphicons-halflings-regular.eot');
\copy($this->templatePath . 'fonts/glyphicons-halflings-regular.svg', $dir . 'glyphicons-halflings-regular.svg');
\copy($this->templatePath . 'fonts/glyphicons-halflings-regular.ttf', $dir . 'glyphicons-halflings-regular.ttf');
\copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff', $dir . 'glyphicons-halflings-regular.woff');
\copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff2', $dir . 'glyphicons-halflings-regular.woff2');
$dir = $this->getDirectory($target . '.js');
\copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js');
\copy($this->templatePath . 'js/d3.min.js', $dir . 'd3.min.js');
\copy($this->templatePath . 'js/holder.min.js', $dir . 'holder.min.js');
\copy($this->templatePath . 'js/html5shiv.min.js', $dir . 'html5shiv.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/respond.min.js', $dir . 'respond.min.js');
\copy($this->templatePath . 'js/file.js', $dir . 'file.js');
}
/**
@@ -157,20 +168,20 @@ class Facade
*/
private function getDirectory($directory)
{
if (substr($directory, -1, 1) != DIRECTORY_SEPARATOR) {
if (\substr($directory, -1, 1) != DIRECTORY_SEPARATOR) {
$directory .= DIRECTORY_SEPARATOR;
}
if (is_dir($directory)) {
if (\is_dir($directory)) {
return $directory;
}
if (@mkdir($directory, 0777, true)) {
if (@\mkdir($directory, 0777, true)) {
return $directory;
}
throw new RuntimeException(
sprintf(
\sprintf(
'Directory "%s" does not exist.',
$directory
)
@@ -11,10 +11,10 @@
namespace SebastianBergmann\CodeCoverage\Report\Html;
use SebastianBergmann\CodeCoverage\Node\AbstractNode;
use SebastianBergmann\CodeCoverage\Node\File as FileNode;
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
use SebastianBergmann\CodeCoverage\Node\File as FileNode;
use SebastianBergmann\CodeCoverage\Version;
use SebastianBergmann\Environment\Runtime;
use SebastianBergmann\Version;
/**
* Base class for node renderers.
@@ -62,14 +62,12 @@ abstract class Renderer
*/
public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
{
$version = new Version('4.0.2', dirname(dirname(dirname(dirname(__DIR__)))));
$this->templatePath = $templatePath;
$this->generator = $generator;
$this->date = $date;
$this->lowUpperBound = $lowUpperBound;
$this->highLowerBound = $highLowerBound;
$this->version = $version->getVersion();
$this->version = Version::id();
}
/**
@@ -92,9 +90,10 @@ abstract class Renderer
$data['testedClassesPercent']
);
} else {
$classesLevel = 'success';
$classesNumber = '0' . $numSeparator . '0';
$classesBar = $this->getCoverageBar(100);
$classesLevel = '';
$classesNumber = '0' . $numSeparator . '0';
$classesBar = '';
$data['testedClassesPercentAsString'] = 'n/a';
}
if ($data['numMethods'] > 0) {
@@ -107,10 +106,10 @@ abstract class Renderer
$data['testedMethodsPercent']
);
} else {
$methodsLevel = 'success';
$methodsLevel = '';
$methodsNumber = '0' . $numSeparator . '0';
$methodsBar = $this->getCoverageBar(100);
$data['testedMethodsPercentAsString'] = '100.00%';
$methodsBar = '';
$data['testedMethodsPercentAsString'] = 'n/a';
}
if ($data['numExecutableLines'] > 0) {
@@ -123,10 +122,10 @@ abstract class Renderer
$data['linesExecutedPercent']
);
} else {
$linesLevel = 'success';
$linesLevel = '';
$linesNumber = '0' . $numSeparator . '0';
$linesBar = $this->getCoverageBar(100);
$data['linesExecutedPercentAsString'] = '100.00%';
$linesBar = '';
$data['linesExecutedPercentAsString'] = 'n/a';
}
$template->setVar(
@@ -179,21 +178,21 @@ abstract class Renderer
$breadcrumbs = '';
$path = $node->getPathAsArray();
$pathToRoot = [];
$max = count($path);
$max = \count($path);
if ($node instanceof FileNode) {
$max--;
}
for ($i = 0; $i < $max; $i++) {
$pathToRoot[] = str_repeat('../', $i);
$pathToRoot[] = \str_repeat('../', $i);
}
foreach ($path as $step) {
if ($step !== $node) {
$breadcrumbs .= $this->getInactiveBreadcrumb(
$step,
array_pop($pathToRoot)
\array_pop($pathToRoot)
);
} else {
$breadcrumbs .= $this->getActiveBreadcrumb($step);
@@ -205,7 +204,7 @@ abstract class Renderer
protected function getActiveBreadcrumb(AbstractNode $node)
{
$buffer = sprintf(
$buffer = \sprintf(
' <li class="active">%s</li>' . "\n",
$node->getName()
);
@@ -219,7 +218,7 @@ abstract class Renderer
protected function getInactiveBreadcrumb(AbstractNode $node, $pathToRoot)
{
return sprintf(
return \sprintf(
' <li><a href="%sindex.html">%s</a></li>' . "\n",
$pathToRoot,
$node->getName()
@@ -229,14 +228,14 @@ abstract class Renderer
protected function getPathToRoot(AbstractNode $node)
{
$id = $node->getId();
$depth = substr_count($id, '/');
$depth = \substr_count($id, '/');
if ($id != 'index' &&
$node instanceof DirectoryNode) {
$depth++;
}
return str_repeat('../', $depth);
return \str_repeat('../', $depth);
}
protected function getCoverageBar($percent)
@@ -249,7 +248,7 @@ abstract class Renderer
'}}'
);
$template->setVar(['level' => $level, 'percent' => sprintf('%.2F', $percent)]);
$template->setVar(['level' => $level, 'percent' => \sprintf('%.2F', $percent)]);
return $template->render();
}
@@ -264,7 +263,7 @@ abstract class Renderer
if ($percent <= $this->lowUpperBound) {
return 'danger';
} elseif ($percent > $this->lowUpperBound &&
$percent < $this->highLowerBound) {
$percent < $this->highLowerBound) {
return 'warning';
} else {
return 'success';
@@ -278,7 +277,7 @@ abstract class Renderer
{
$runtime = new Runtime;
$buffer = sprintf(
$buffer = \sprintf(
'<a href="%s" target="_top">%s %s</a>',
$runtime->getVendorUrl(),
$runtime->getName(),
@@ -286,9 +285,9 @@ abstract class Renderer
);
if ($runtime->hasXdebug() && !$runtime->hasPHPDBGCodeCoverage()) {
$buffer .= sprintf(
$buffer .= \sprintf(
' with <a href="https://xdebug.org/">Xdebug %s</a>',
phpversion('xdebug')
\phpversion('xdebug')
);
}
@@ -21,6 +21,8 @@ class Dashboard extends Renderer
/**
* @param DirectoryNode $node
* @param string $file
*
* @throws \InvalidArgumentException
*/
public function render(DirectoryNode $node, $file)
{
@@ -69,16 +71,16 @@ class Dashboard extends Renderer
foreach ($classes as $className => $class) {
foreach ($class['methods'] as $methodName => $method) {
if ($className != '*') {
if ($className !== '*') {
$methodName = $className . '::' . $methodName;
}
$result['method'][] = [
$method['coverage'],
$method['ccn'],
sprintf(
\sprintf(
'<a href="%s">%s</a>',
str_replace($baseLink, '', $method['link']),
\str_replace($baseLink, '', $method['link']),
$methodName
)
];
@@ -87,17 +89,17 @@ class Dashboard extends Renderer
$result['class'][] = [
$class['coverage'],
$class['ccn'],
sprintf(
\sprintf(
'<a href="%s">%s</a>',
str_replace($baseLink, '', $class['link']),
\str_replace($baseLink, '', $class['link']),
$className
)
];
}
return [
'class' => json_encode($result['class']),
'method' => json_encode($result['method'])
'class' => \json_encode($result['class']),
'method' => \json_encode($result['method'])
];
}
@@ -143,31 +145,31 @@ class Dashboard extends Renderer
foreach ($classes as $class) {
foreach ($class['methods'] as $methodName => $method) {
if ($method['coverage'] == 0) {
if ($method['coverage'] === 0) {
$result['method']['0%']++;
} elseif ($method['coverage'] == 100) {
} elseif ($method['coverage'] === 100) {
$result['method']['100%']++;
} else {
$key = floor($method['coverage'] / 10) * 10;
$key = \floor($method['coverage'] / 10) * 10;
$key = $key . '-' . ($key + 10) . '%';
$result['method'][$key]++;
}
}
if ($class['coverage'] == 0) {
if ($class['coverage'] === 0) {
$result['class']['0%']++;
} elseif ($class['coverage'] == 100) {
} elseif ($class['coverage'] === 100) {
$result['class']['100%']++;
} else {
$key = floor($class['coverage'] / 10) * 10;
$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']))
'class' => \json_encode(\array_values($result['class'])),
'method' => \json_encode(\array_values($result['method']))
];
}
@@ -188,10 +190,10 @@ class Dashboard extends Renderer
foreach ($classes as $className => $class) {
foreach ($class['methods'] as $methodName => $method) {
if ($method['coverage'] < $this->highLowerBound) {
if ($className != '*') {
$key = $methodName;
if ($className !== '*') {
$key = $className . '::' . $methodName;
} else {
$key = $methodName;
}
$leastTestedMethods[$key] = $method['coverage'];
@@ -203,24 +205,24 @@ class Dashboard extends Renderer
}
}
asort($leastTestedClasses);
asort($leastTestedMethods);
\asort($leastTestedClasses);
\asort($leastTestedMethods);
foreach ($leastTestedClasses as $className => $coverage) {
$result['class'] .= sprintf(
$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']),
\str_replace($baseLink, '', $classes[$className]['link']),
$className,
$coverage
);
}
foreach ($leastTestedMethods as $methodName => $coverage) {
list($class, $method) = explode('::', $methodName);
list($class, $method) = \explode('::', $methodName);
$result['method'] .= sprintf(
$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']),
\str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']),
$methodName,
$method,
$coverage
@@ -248,7 +250,7 @@ class Dashboard extends Renderer
foreach ($class['methods'] as $methodName => $method) {
if ($method['coverage'] < $this->highLowerBound &&
$method['ccn'] > 1) {
if ($className != '*') {
if ($className !== '*') {
$key = $className . '::' . $methodName;
} else {
$key = $methodName;
@@ -259,29 +261,29 @@ class Dashboard extends Renderer
}
if ($class['coverage'] < $this->highLowerBound &&
$class['ccn'] > count($class['methods'])) {
$class['ccn'] > \count($class['methods'])) {
$classRisks[$className] = $class['crap'];
}
}
arsort($classRisks);
arsort($methodRisks);
\arsort($classRisks);
\arsort($methodRisks);
foreach ($classRisks as $className => $crap) {
$result['class'] .= sprintf(
$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']),
\str_replace($baseLink, '', $classes[$className]['link']),
$className,
$crap
);
}
foreach ($methodRisks as $methodName => $crap) {
list($class, $method) = explode('::', $methodName);
list($class, $method) = \explode('::', $methodName);
$result['method'] .= sprintf(
$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']),
\str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']),
$methodName,
$method,
$crap
@@ -293,7 +295,7 @@ class Dashboard extends Renderer
protected function getActiveBreadcrumb(AbstractNode $node)
{
return sprintf(
return \sprintf(
' <li><a href="index.html">%s</a></li>' . "\n" .
' <li class="active">(Dashboard)</li>' . "\n",
$node->getName()
@@ -59,14 +59,14 @@ class Directory extends Renderer
$data = [
'numClasses' => $node->getNumClassesAndTraits(),
'numTestedClasses' => $node->getNumTestedClassesAndTraits(),
'numMethods' => $node->getNumMethods(),
'numTestedMethods' => $node->getNumTestedMethods(),
'numMethods' => $node->getNumFunctionsAndMethods(),
'numTestedMethods' => $node->getNumTestedFunctionsAndMethods(),
'linesExecutedPercent' => $node->getLineExecutedPercent(false),
'linesExecutedPercentAsString' => $node->getLineExecutedPercent(),
'numExecutedLines' => $node->getNumExecutedLines(),
'numExecutableLines' => $node->getNumExecutableLines(),
'testedMethodsPercent' => $node->getTestedMethodsPercent(false),
'testedMethodsPercentAsString' => $node->getTestedMethodsPercent(),
'testedMethodsPercent' => $node->getTestedFunctionsAndMethodsPercent(false),
'testedMethodsPercentAsString' => $node->getTestedFunctionsAndMethodsPercent(),
'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false),
'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent()
];
@@ -75,7 +75,7 @@ class Directory extends Renderer
$data['name'] = 'Total';
} else {
if ($node instanceof DirectoryNode) {
$data['name'] = sprintf(
$data['name'] = \sprintf(
'<a href="%s/index.html">%s</a>',
$node->getName(),
$node->getName()
@@ -83,7 +83,7 @@ class Directory extends Renderer
$data['icon'] = '<span class="glyphicon glyphicon-folder-open"></span> ';
} else {
$data['name'] = sprintf(
$data['name'] = \sprintf(
'<a href="%s.html">%s</a>',
$node->getName(),
$node->getName()
@@ -88,14 +88,14 @@ class File extends Renderer
'name' => 'Total',
'numClasses' => $node->getNumClassesAndTraits(),
'numTestedClasses' => $node->getNumTestedClassesAndTraits(),
'numMethods' => $node->getNumMethods(),
'numTestedMethods' => $node->getNumTestedMethods(),
'numMethods' => $node->getNumFunctionsAndMethods(),
'numTestedMethods' => $node->getNumTestedFunctionsAndMethods(),
'linesExecutedPercent' => $node->getLineExecutedPercent(false),
'linesExecutedPercentAsString' => $node->getLineExecutedPercent(),
'numExecutedLines' => $node->getNumExecutedLines(),
'numExecutableLines' => $node->getNumExecutableLines(),
'testedMethodsPercent' => $node->getTestedMethodsPercent(false),
'testedMethodsPercentAsString' => $node->getTestedMethodsPercent(),
'testedMethodsPercent' => $node->getTestedFunctionsAndMethodsPercent(false),
'testedMethodsPercentAsString' => $node->getTestedFunctionsAndMethodsPercent(),
'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false),
'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent(),
'crap' => '<abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr>'
@@ -138,7 +138,7 @@ class File extends Renderer
$buffer = '';
foreach ($items as $name => $item) {
$numMethods = count($item['methods']);
$numMethods = \count($item['methods']);
$numTestedMethods = 0;
foreach ($item['methods'] as $method) {
@@ -147,12 +147,26 @@ class File extends Renderer
}
}
if ($item['executableLines'] > 0) {
$numClasses = 1;
$numTestedClasses = $numTestedMethods == $numMethods ? 1 : 0;
$linesExecutedPercentAsString = Util::percent(
$item['executedLines'],
$item['executableLines'],
true
);
} else {
$numClasses = 'n/a';
$numTestedClasses = 'n/a';
$linesExecutedPercentAsString = 'n/a';
}
$buffer .= $this->renderItemTemplate(
$template,
[
'name' => $name,
'numClasses' => 1,
'numTestedClasses' => $numTestedMethods == $numMethods ? 1 : 0,
'numClasses' => $numClasses,
'numTestedClasses' => $numTestedClasses,
'numMethods' => $numMethods,
'numTestedMethods' => $numTestedMethods,
'linesExecutedPercent' => Util::percent(
@@ -160,11 +174,7 @@ class File extends Renderer
$item['executableLines'],
false
),
'linesExecutedPercentAsString' => Util::percent(
$item['executedLines'],
$item['executableLines'],
true
),
'linesExecutedPercentAsString' => $linesExecutedPercentAsString,
'numExecutedLines' => $item['executedLines'],
'numExecutableLines' => $item['executableLines'],
'testedMethodsPercent' => Util::percent(
@@ -239,11 +249,11 @@ class File extends Renderer
return $this->renderItemTemplate(
$template,
[
'name' => sprintf(
'name' => \sprintf(
'%s<a href="#%d"><abbr title="%s">%s</abbr></a>',
$indent,
$item['startLine'],
htmlspecialchars($item['signature']),
\htmlspecialchars($item['signature']),
isset($item['functionName']) ? $item['functionName'] : $item['methodName']
),
'numMethods' => 1,
@@ -293,8 +303,8 @@ class File extends Renderer
$popoverContent = '';
$popoverTitle = '';
if (array_key_exists($i, $coverageData)) {
$numTests = count($coverageData[$i]);
if (\array_key_exists($i, $coverageData)) {
$numTests = ($coverageData[$i] ? \count($coverageData[$i]) : 0);
if ($coverageData[$i] === null) {
$trClass = ' class="warning"';
@@ -322,39 +332,46 @@ class File extends Renderer
switch ($testData[$test]['size']) {
case 'small':
$testCSS = ' class="covered-by-small-tests"';
break;
case 'medium':
$testCSS = ' class="covered-by-medium-tests"';
break;
default:
$testCSS = ' class="covered-by-large-tests"';
break;
}
break;
case 1:
case 2:
$testCSS = ' class="warning"';
break;
case 3:
$testCSS = ' class="danger"';
break;
case 4:
$testCSS = ' class="danger"';
break;
default:
$testCSS = '';
}
$popoverContent .= sprintf(
$popoverContent .= \sprintf(
'<li%s>%s</li>',
$testCSS,
htmlspecialchars($test)
\htmlspecialchars($test)
);
}
@@ -364,16 +381,16 @@ class File extends Renderer
}
if (!empty($popoverTitle)) {
$popover = sprintf(
$popover = \sprintf(
' data-title="%s" data-content="%s" data-placement="bottom" data-html="true"',
$popoverTitle,
htmlspecialchars($popoverContent)
\htmlspecialchars($popoverContent)
);
} else {
$popover = '';
}
$lines .= sprintf(
$lines .= \sprintf(
' <tr%s%s><td><div align="right"><a name="%d"></a><a href="#%d">%d</a></div></td><td class="codeLine">%s</td></tr>' . "\n",
$trClass,
$popover,
@@ -396,28 +413,28 @@ class File extends Renderer
*/
protected function loadFile($file)
{
$buffer = file_get_contents($file);
$tokens = token_get_all($buffer);
$buffer = \file_get_contents($file);
$tokens = \token_get_all($buffer);
$result = [''];
$i = 0;
$stringFlag = false;
$fileEndsWithNewLine = substr($buffer, -1) == "\n";
$fileEndsWithNewLine = \substr($buffer, -1) == "\n";
unset($buffer);
foreach ($tokens as $j => $token) {
if (is_string($token)) {
if (\is_string($token)) {
if ($token === '"' && $tokens[$j - 1] !== '\\') {
$result[$i] .= sprintf(
$result[$i] .= \sprintf(
'<span class="string">%s</span>',
htmlspecialchars($token)
\htmlspecialchars($token)
);
$stringFlag = !$stringFlag;
} else {
$result[$i] .= sprintf(
$result[$i] .= \sprintf(
'<span class="keyword">%s</span>',
htmlspecialchars($token)
\htmlspecialchars($token)
);
}
@@ -426,19 +443,19 @@ class File extends Renderer
list($token, $value) = $token;
$value = str_replace(
$value = \str_replace(
["\t", ' '],
['&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;'],
htmlspecialchars($value, $this->htmlspecialcharsFlags)
\htmlspecialchars($value, $this->htmlspecialcharsFlags)
);
if ($value === "\n") {
$result[++$i] = '';
} else {
$lines = explode("\n", $value);
$lines = \explode("\n", $value);
foreach ($lines as $jj => $line) {
$line = trim($line);
$line = \trim($line);
if ($line !== '') {
if ($stringFlag) {
@@ -447,11 +464,13 @@ class File extends Renderer
switch ($token) {
case T_INLINE_HTML:
$colour = 'html';
break;
case T_COMMENT:
case T_DOC_COMMENT:
$colour = 'comment';
break;
case T_ABSTRACT:
@@ -511,6 +530,7 @@ class File extends Renderer
case T_WHILE:
case T_YIELD:
$colour = 'keyword';
break;
default:
@@ -518,7 +538,7 @@ class File extends Renderer
}
}
$result[$i] .= sprintf(
$result[$i] .= \sprintf(
'<span class="%s">%s</span>',
$colour,
$line
@@ -533,7 +553,7 @@ class File extends Renderer
}
if ($fileEndsWithNewLine) {
unset($result[count($result)-1]);
unset($result[\count($result) - 1]);
}
return $result;
@@ -1,6 +1,6 @@
/*!
* Bootstrap v3.3.6 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc.
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\Line truncated
*//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\Line truncated
/*# sourceMappingURL=bootstrap.min.css.map */
@@ -4,12 +4,12 @@
<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">
<link href="{{path_to_root}}css/nv.d3.min.css" rel="stylesheet">
<link href="{{path_to_root}}css/style.css" rel="stylesheet">
<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">
<!--[if lt IE 9]>
<script src="{{path_to_root}}js/html5shiv.min.js"></script>
<script src="{{path_to_root}}js/respond.min.js"></script>
<script src="{{path_to_root}}.js/html5shiv.min.js"></script>
<script src="{{path_to_root}}.js/respond.min.js"></script>
<![endif]-->
</head>
<body>
@@ -138,11 +138,11 @@
</p>
</footer>
</div>
<script src="{{path_to_root}}js/jquery.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/holder.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 src="{{path_to_root}}.js/jquery.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/holder.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() {
@@ -4,11 +4,11 @@
<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">
<link href="{{path_to_root}}css/style.css" rel="stylesheet">
<link href="{{path_to_root}}.css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="{{path_to_root}}.css/style.css" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="{{path_to_root}}js/html5shiv.min.js"></script>
<script src="{{path_to_root}}js/respond.min.js"></script>
<script src="{{path_to_root}}.js/html5shiv.min.js"></script>
<script src="{{path_to_root}}.js/respond.min.js"></script>
<![endif]-->
</head>
<body>
@@ -54,8 +54,8 @@
</p>
</footer>
</div>
<script src="{{path_to_root}}js/jquery.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/holder.min.js" type="text/javascript"></script>
<script src="{{path_to_root}}.js/jquery.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/holder.min.js" type="text/javascript"></script>
</body>
</html>
@@ -4,11 +4,11 @@
<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">
<link href="{{path_to_root}}css/style.css" rel="stylesheet">
<link href="{{path_to_root}}.css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="{{path_to_root}}.css/style.css" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="{{path_to_root}}js/html5shiv.min.js"></script>
<script src="{{path_to_root}}js/respond.min.js"></script>
<script src="{{path_to_root}}.js/html5shiv.min.js"></script>
<script src="{{path_to_root}}.js/respond.min.js"></script>
<![endif]-->
</head>
<body>
@@ -60,31 +60,9 @@
<a title="Back to the top" id="toplink" href="#"><span class="glyphicon glyphicon-arrow-up"></span></a>
</footer>
</div>
<script src="{{path_to_root}}js/jquery.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/holder.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
var $window = $(window)
, $top_link = $('#toplink')
, $body = $('body, html')
, offset = $('#code').offset().top;
$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: 'hover'});
});
</script>
<script src="{{path_to_root}}.js/jquery.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/holder.min.js" type="text/javascript"></script>
<script src="{{path_to_root}}.js/file.js" type="text/javascript"></script>
</body>
</html>
@@ -1,7 +1,7 @@
/*!
* Bootstrap v3.3.6 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc.
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under the MIT license
*/
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-Api blur.bs.button.data-Api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b|Line truncated
d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.6",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:tLine truncated
this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e<c&&"top";if("bottom"==this.affixed)return null!=c?!(e+this.unpin<=f.top)&&"bottom":!(e+g<=a-d)&&"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&e<=c?"top":null!=d&&i+j>=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
@@ -0,0 +1,61 @@
$(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);
$target.data('popover-hover', true);
// popover already displayed
if ($target.next('.popover').length) {
return;
}
// show the popover
$target.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($target);
}
})
.addClass('popover-initialized');
},
'mouseleave.popover': function () {
hidePopover($(this));
}
});
});
@@ -1,5 +1,4 @@
/*! jQuery v1.12.3 | (c) jQuery Foundation | jquery.org/license */
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.3",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|Line truncated
}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName("body")[0],c&&c.style?(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(d.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),V=["Top","Right","Bottom","Left"],W=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFraLine truncated
return b?(parseFloat(Sa(a,"marginLeft"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}):0))+"px":void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k="none"===j?n._data(a,"olddisplay")||Ma(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==Ma(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))"inline"===("none"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(Line truncated
})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});
/*! jQuery v3.1.1 | (c) jQuery Foundation | jquery.org/license */
!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+Line truncated
a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Y=/[A-Z]/g;function Z(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:X.test(a)?JSON.parse(a):a)}function $(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Y,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=Z(c)}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.hasData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=W.get(f),1===f.nodeType&&!V.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),$(f,d,e[d])));V.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=$(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=V.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var _=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,aa=new RegExp("^(?:([+-])=|)("+_+")([a-z%]*)$","i"),ba=["Top","Right","Bottom","Left"],ca=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},da=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function ea(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&aa.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var fa={};function ga(a){var b,c=a.ownerDocument,d=a.nodeName,e=fa[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),fLine truncated
void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),ib={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=jb[b]||r.find.attr;jb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=jb[g],jb[g]=e,e=null!=c(a,b,d)?g:null,jb[g]=f),e}});var kb=/^(?:input|select|textarea|button)$/i,lb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):kb.test(a.nodeName)||lb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function mb(a){var b=a.match(K)||[];return b.join(" ")}function nb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,nb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,nb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,nb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=nb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(nb(c))+" ").indexOf(b)>-1)return!0;return!1}});var ob=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(ob,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:mb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[Line truncated
@@ -27,7 +27,7 @@ class PHP
{
$filter = $coverage->filter();
$output = sprintf(
$output = \sprintf(
'<?php
$coverage = new SebastianBergmann\CodeCoverage\CodeCoverage;
$coverage->setData(%s);
@@ -37,13 +37,13 @@ $filter = $coverage->filter();
$filter->setWhitelistedFiles(%s);
return $coverage;',
var_export($coverage->getData(true), 1),
var_export($coverage->getTests(), 1),
var_export($filter->getWhitelistedFiles(), 1)
\var_export($coverage->getData(true), 1),
\var_export($coverage->getTests(), 1),
\var_export($filter->getWhitelistedFiles(), 1)
);
if ($target !== null) {
return file_put_contents($target, $output);
return \file_put_contents($target, $output);
} else {
return $output;
}
@@ -88,7 +88,7 @@ class Text
$colors['eol'] = $this->colors['eol'];
}
$classes = sprintf(
$classes = \sprintf(
' Classes: %6s (%d/%d)',
Util::percent(
$report->getNumTestedClassesAndTraits(),
@@ -99,7 +99,7 @@ class Text
$report->getNumClassesAndTraits()
);
$methods = sprintf(
$methods = \sprintf(
' Methods: %6s (%d/%d)',
Util::percent(
$report->getNumTestedMethods(),
@@ -110,7 +110,7 @@ class Text
$report->getNumMethods()
);
$lines = sprintf(
$lines = \sprintf(
' Lines: %6s (%d/%d)',
Util::percent(
$report->getNumExecutedLines(),
@@ -121,15 +121,15 @@ class Text
$report->getNumExecutableLines()
);
$padding = max(array_map('strlen', [$classes, $methods, $lines]));
$padding = \max(\array_map('strlen', [$classes, $methods, $lines]));
if ($this->showOnlySummary) {
$title = 'Code Coverage Report Summary:';
$padding = max($padding, strlen($title));
$padding = \max($padding, \strlen($title));
$output .= $this->format($colors['header'], $padding, $title);
} else {
$date = date(' Y-m-d H:i:s', $_SERVER['REQUEST_TIME']);
$date = \date(' Y-m-d H:i:s', $_SERVER['REQUEST_TIME']);
$title = 'Code Coverage Report:';
$output .= $this->format($colors['header'], $padding, $title);
@@ -167,7 +167,7 @@ class Text
}
$classMethods++;
$classStatements += $method['executableLines'];
$classStatements += $method['executableLines'];
$coveredClassStatements += $method['executedLines'];
if ($method['coverage'] == 100) {
$coveredMethods++;
@@ -193,7 +193,7 @@ class Text
}
}
ksort($classCoverage);
\ksort($classCoverage);
$methodColor = '';
$linesColor = '';
@@ -244,14 +244,14 @@ class Text
true,
true
) .
' (' . sprintf($format, $numberOfCoveredElements) . '/' .
sprintf($format, $totalNumberOfElements) . ')';
' (' . \sprintf($format, $numberOfCoveredElements) . '/' .
\sprintf($format, $totalNumberOfElements) . ')';
}
private function format($color, $padding, $string)
{
$reset = $color ? $this->colors['reset'] : '';
return $color . str_pad($string, $padding) . $reset . PHP_EOL;
return $color . \str_pad($string, $padding) . $reset . PHP_EOL;
}
}
@@ -0,0 +1,101 @@
<?php
/*
* This file is part of the php-code-coverage package.
*
* (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 SebastianBergmann\Environment\Runtime;
class BuildInformation
{
/**
* @var \DOMElement
*/
private $contextNode;
/**
* @param \DOMElement $contextNode
*/
public function __construct(\DOMElement $contextNode)
{
$this->contextNode = $contextNode;
}
/**
* @param Runtime $runtime
*/
public function setRuntimeInformation(Runtime $runtime)
{
$runtimeNode = $this->getNodeByName('runtime');
$runtimeNode->setAttribute('name', $runtime->getName());
$runtimeNode->setAttribute('version', $runtime->getVersion());
$runtimeNode->setAttribute('url', $runtime->getVendorUrl());
$driverNode = $this->getNodeByName('driver');
if ($runtime->isHHVM()) {
$driverNode->setAttribute('name', 'hhvm');
$driverNode->setAttribute('version', \constant('HHVM_VERSION'));
return;
}
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'));
}
}
/**
* @param $name
*
* @return \DOMElement
*/
private function getNodeByName($name)
{
$node = $this->contextNode->getElementsByTagNameNS(
'http://schema.phpunit.de/coverage/1.0',
$name
)->item(0);
if (!$node) {
$node = $this->contextNode->appendChild(
$this->contextNode->ownerDocument->createElementNS(
'http://schema.phpunit.de/coverage/1.0',
$name
)
);
}
return $node;
}
/**
* @param \DateTime $date
*/
public function setBuildTime(\DateTime $date)
{
$this->contextNode->setAttribute('time', $date->format('D M j G:i:s T Y'));
}
/**
* @param string $phpUnitVersion
* @param string $coverageVersion
*/
public function setGeneratorVersions($phpUnitVersion, $coverageVersion)
{
$this->contextNode->setAttribute('phpunit', $phpUnitVersion);
$this->contextNode->setAttribute('coverage', $coverageVersion);
}
}
@@ -33,7 +33,7 @@ class Coverage
{
$this->contextNode = $context;
$this->writer = new \XMLWriter;
$this->writer = new \XMLWriter();
$this->writer->openMemory();
$this->writer->startElementNs(null, $context->nodeName, 'http://schema.phpunit.de/coverage/1.0');
$this->writer->writeAttribute('nr', $line);
@@ -15,6 +15,8 @@ use SebastianBergmann\CodeCoverage\Node\AbstractNode;
use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
use SebastianBergmann\CodeCoverage\Node\File as FileNode;
use SebastianBergmann\CodeCoverage\RuntimeException;
use SebastianBergmann\CodeCoverage\Version;
use SebastianBergmann\Environment\Runtime;
class Facade
{
@@ -28,6 +30,19 @@ class Facade
*/
private $project;
/**
* @var string
*/
private $phpUnitVersion;
/**
* @param string $version
*/
public function __construct($version)
{
$this->phpUnitVersion = $version;
}
/**
* @param CodeCoverage $coverage
* @param string $target
@@ -36,7 +51,7 @@ class Facade
*/
public function process(CodeCoverage $coverage, $target)
{
if (substr($target, -1, 1) != DIRECTORY_SEPARATOR) {
if (\substr($target, -1, 1) != DIRECTORY_SEPARATOR) {
$target .= DIRECTORY_SEPARATOR;
}
@@ -49,33 +64,39 @@ class Facade
$coverage->getReport()->getName()
);
$this->setBuildInformation();
$this->processTests($coverage->getTests());
$this->processDirectory($report, $this->project);
$index = $this->project->asDom();
$index->formatOutput = true;
$index->preserveWhiteSpace = false;
$index->save($target . '/index.xml');
$this->saveDocument($this->project->asDom(), 'index');
}
private function setBuildInformation()
{
$buildNode = $this->project->getBuildInformation();
$buildNode->setRuntimeInformation(new Runtime());
$buildNode->setBuildTime(\DateTime::createFromFormat('U', $_SERVER['REQUEST_TIME']));
$buildNode->setGeneratorVersions($this->phpUnitVersion, Version::id());
}
/**
* @param string $directory
*/
private function initTargetDirectory($directory)
protected function initTargetDirectory($directory)
{
if (file_exists($directory)) {
if (!is_dir($directory)) {
if (\file_exists($directory)) {
if (!\is_dir($directory)) {
throw new RuntimeException(
"'$directory' exists but is not a directory."
);
}
if (!is_writable($directory)) {
if (!\is_writable($directory)) {
throw new RuntimeException(
"'$directory' exists but is not writable."
);
}
} elseif (!@mkdir($directory, 0777, true)) {
} elseif (!@\mkdir($directory, 0777, true)) {
throw new RuntimeException(
"'$directory' could not be created."
);
@@ -84,24 +105,20 @@ class Facade
private function processDirectory(DirectoryNode $directory, Node $context)
{
$dirObject = $context->addDirectory($directory->getName());
$dirname = $directory->getName();
if ($this->project->getProjectSourceDirectory() === $dirname) {
$dirname = '/';
}
$dirObject = $context->addDirectory($dirname);
$this->setTotals($directory, $dirObject->getTotals());
foreach ($directory as $node) {
if ($node instanceof DirectoryNode) {
$this->processDirectory($node, $dirObject);
continue;
}
foreach ($directory->getDirectories() as $node) {
$this->processDirectory($node, $dirObject);
}
if ($node instanceof FileNode) {
$this->processFile($node, $dirObject);
continue;
}
throw new RuntimeException(
'Unknown node type for XML report'
);
foreach ($directory->getFiles() as $node) {
$this->processFile($node, $dirObject);
}
}
@@ -114,7 +131,11 @@ class Facade
$this->setTotals($file, $fileObject->getTotals());
$fileReport = new Report($file->getName());
$path = \substr(
$file->getPath(),
\strlen($this->project->getProjectSourceDirectory())
);
$fileReport = new Report($path);
$this->setTotals($file, $fileReport->getTotals());
@@ -127,7 +148,7 @@ class Facade
}
foreach ($file->getCoverageData() as $line => $tests) {
if (!is_array($tests) || count($tests) == 0) {
if (!\is_array($tests) || \count($tests) === 0) {
continue;
}
@@ -140,14 +161,11 @@ class Facade
$coverage->finalize();
}
$this->initTargetDirectory(
$this->target . dirname($file->getId()) . '/'
$fileReport->getSource()->setSourceCode(
\file_get_contents($file->getPath())
);
$fileDom = $fileReport->asDom();
$fileDom->formatOutput = true;
$fileDom->preserveWhiteSpace = false;
$fileDom->save($this->target . $file->getId() . '.xml');
$this->saveDocument($fileReport->asDom(), $file->getId());
}
private function processUnit($unit, Report $report)
@@ -243,4 +261,23 @@ class Facade
$node->getNumTestedFunctions()
);
}
/**
* @return string
*/
protected function getTargetDirectory()
{
return $this->target;
}
protected function saveDocument(\DOMDocument $document, $name)
{
$filename = \sprintf('%s/%s.xml', $this->getTargetDirectory(), $name);
$document->formatOutput = true;
$document->preserveWhiteSpace = false;
$this->initTargetDirectory(\dirname($filename));
$document->save($filename);
}
}
@@ -15,12 +15,12 @@ class File
/**
* @var \DOMDocument
*/
protected $dom;
private $dom;
/**
* @var \DOMElement
*/
protected $contextNode;
private $contextNode;
public function __construct(\DOMElement $context)
{
@@ -28,6 +28,22 @@ class File
$this->contextNode = $context;
}
/**
* @return \DOMElement
*/
protected function getContextNode()
{
return $this->contextNode;
}
/**
* @return \DOMDocument
*/
protected function getDomDocument()
{
return $this->dom;
}
public function getTotals()
{
$totalsContainer = $this->contextNode->firstChild;
@@ -12,16 +12,19 @@ namespace SebastianBergmann\CodeCoverage\Report\Xml;
class Project extends Node
{
public function __construct($name)
/**
* @param string $directory
*/
public function __construct($directory)
{
$this->init();
$this->setProjectName($name);
$this->setProjectSourceDirectory($directory);
}
private function init()
{
$dom = new \DOMDocument;
$dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><project/></phpunit>');
$dom = new \DOMDocument();
$dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><build/><project/></phpunit>');
$this->setContextNode(
$dom->getElementsByTagNameNS(
@@ -31,9 +34,39 @@ class Project extends Node
);
}
private function setProjectName($name)
private function setProjectSourceDirectory($name)
{
$this->getContextNode()->setAttribute('name', $name);
$this->getContextNode()->setAttribute('source', $name);
}
/**
* @return string
*/
public function getProjectSourceDirectory()
{
return $this->getContextNode()->getAttribute('source');
}
/**
* @return BuildInformation
*/
public function getBuildInformation()
{
$buildNode = $this->getDom()->getElementsByTagNameNS(
'http://schema.phpunit.de/coverage/1.0',
'build'
)->item(0);
if (!$buildNode) {
$buildNode = $this->getDom()->documentElement->appendChild(
$this->getDom()->createElementNS(
'http://schema.phpunit.de/coverage/1.0',
'build'
)
);
}
return new BuildInformation($buildNode);
}
public function getTests()
@@ -14,31 +14,33 @@ class Report extends File
{
public function __construct($name)
{
$this->dom = new \DOMDocument;
$this->dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><file /></phpunit>');
$dom = new \DOMDocument();
$dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><file /></phpunit>');
$this->contextNode = $this->dom->getElementsByTagNameNS(
$contextNode = $dom->getElementsByTagNameNS(
'http://schema.phpunit.de/coverage/1.0',
'file'
)->item(0);
parent::__construct($contextNode);
$this->setName($name);
}
private function setName($name)
{
$this->contextNode->setAttribute('name', $name);
$this->getContextNode()->setAttribute('name', \basename($name));
$this->getContextNode()->setAttribute('path', \dirname($name));
}
public function asDom()
{
return $this->dom;
return $this->getDomDocument();
}
public function getFunctionObject($name)
{
$node = $this->contextNode->appendChild(
$this->dom->createElementNS(
$node = $this->getContextNode()->appendChild(
$this->getDomDocument()->createElementNS(
'http://schema.phpunit.de/coverage/1.0',
'function'
)
@@ -59,8 +61,8 @@ class Report extends File
private function getUnitObject($tagName, $name)
{
$node = $this->contextNode->appendChild(
$this->dom->createElementNS(
$node = $this->getContextNode()->appendChild(
$this->getDomDocument()->createElementNS(
'http://schema.phpunit.de/coverage/1.0',
$tagName
)
@@ -68,4 +70,23 @@ class Report extends File
return new Unit($node, $name);
}
public function getSource()
{
$source = $this->getContextNode()->getElementsByTagNameNS(
'http://schema.phpunit.de/coverage/1.0',
'source'
)->item(0);
if (!$source) {
$source = $this->getContextNode()->appendChild(
$this->getDomDocument()->createElementNS(
'http://schema.phpunit.de/coverage/1.0',
'source'
)
);
}
return new Source($source);
}
}
@@ -0,0 +1,45 @@
<?php
/*
* This file is part of the php-code-coverage package.
*
* (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 TheSeer\Tokenizer\NamespaceUri;
use TheSeer\Tokenizer\Tokenizer;
use TheSeer\Tokenizer\XMLSerializer;
class Source
{
/** @var \DOMElement */
private $context;
/**
* @param \DOMElement $context
*/
public function __construct(\DOMElement $context)
{
$this->context = $context;
}
/**
* @param string $source
*/
public function setSourceCode(string $source)
{
$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
);
}
}
@@ -95,7 +95,7 @@ class Totals
$this->linesNode->setAttribute('executed', $executed);
$this->linesNode->setAttribute(
'percent',
Util::percent($executed, $executable, true)
$executable === 0 ? 0 : \sprintf('%01.2F', Util::percent($executed, $executable, false))
);
}
@@ -105,7 +105,7 @@ class Totals
$this->classesNode->setAttribute('tested', $tested);
$this->classesNode->setAttribute(
'percent',
Util::percent($tested, $count, true)
$count === 0 ? 0 : \sprintf('%01.2F', Util::percent($tested, $count, false))
);
}
@@ -115,7 +115,7 @@ class Totals
$this->traitsNode->setAttribute('tested', $tested);
$this->traitsNode->setAttribute(
'percent',
Util::percent($tested, $count, true)
$count === 0 ? 0 : \sprintf('%01.2F', Util::percent($tested, $count, false))
);
}
@@ -125,7 +125,7 @@ class Totals
$this->methodsNode->setAttribute('tested', $tested);
$this->methodsNode->setAttribute(
'percent',
Util::percent($tested, $count, true)
$count === 0 ? 0 : \sprintf('%01.2F', Util::percent($tested, $count, false))
);
}
@@ -135,7 +135,7 @@ class Totals
$this->functionsNode->setAttribute('tested', $tested);
$this->functionsNode->setAttribute(
'percent',
Util::percent($tested, $count, true)
$count === 0 ? 0 : \sprintf('%01.2F', Util::percent($tested, $count, false))
);
}
}
+6 -8
View File
@@ -29,20 +29,18 @@ class Util
return '';
}
$percent = 100;
if ($b > 0) {
$percent = ($a / $b) * 100;
} else {
$percent = 100;
}
if ($asString) {
if ($fixedWidth) {
return sprintf('%6.2F%%', $percent);
}
$format = $fixedWidth ? '%6.2F%%' : '%01.2F%%';
return sprintf('%01.2F%%', $percent);
} else {
return $percent;
return \sprintf($format, $percent);
}
return $percent;
}
}
@@ -0,0 +1,31 @@
<?php
/*
* This file is part of the php-code-coverage package.
*
* (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 SebastianBergmann\Version as VersionId;
class Version
{
private static $version;
/**
* @return string
*/
public static function id()
{
if (self::$version === null) {
$version = new VersionId('5.3.0', \dirname(__DIR__));
self::$version = $version->getVersion();
}
return self::$version;
}
}
@@ -17,7 +17,7 @@ use SebastianBergmann\CodeCoverage\Driver\Xdebug;
*
* @since Class available since Release 1.0.0
*/
abstract class TestCase extends \PHPUnit_Framework_TestCase
abstract class TestCase extends \PHPUnit\Framework\TestCase
{
protected static $TEST_TMP_PATH;
@@ -1,7 +1,9 @@
<?php
require_once 'BankAccount.php';
class BankAccountTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class BankAccountTest extends TestCase
{
protected $ba;
@@ -1,5 +1,7 @@
<?php
class CoverageClassExtendedTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageClassExtendedTest extends TestCase
{
/**
* @covers CoveredClass<extended>
@@ -1,5 +1,7 @@
<?php
class CoverageClassTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageClassTest extends TestCase
{
/**
* @covers CoveredClass
@@ -1,5 +1,7 @@
<?php
class CoverageFunctionParenthesesTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageFunctionParenthesesTest extends TestCase
{
/**
* @covers ::globalFunction()
@@ -1,5 +1,7 @@
<?php
class CoverageFunctionParenthesesWhitespaceTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageFunctionParenthesesWhitespaceTest extends TestCase
{
/**
* @covers ::globalFunction ( )
@@ -1,5 +1,7 @@
<?php
class CoverageFunctionTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageFunctionTest extends TestCase
{
/**
* @covers ::globalFunction
@@ -1,6 +1,7 @@
<?php
use PHPUnit\Framework\TestCase;
class CoverageMethodOneLineAnnotationTest extends PHPUnit_Framework_TestCase
class CoverageMethodOneLineAnnotationTest extends TestCase
{
/** @covers CoveredClass::publicMethod */
public function testSomething()
@@ -1,5 +1,7 @@
<?php
class CoverageMethodParenthesesTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageMethodParenthesesTest extends TestCase
{
/**
* @covers CoveredClass::publicMethod()
@@ -1,5 +1,7 @@
<?php
class CoverageMethodParenthesesWhitespaceTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageMethodParenthesesWhitespaceTest extends TestCase
{
/**
* @covers CoveredClass::publicMethod ( )
@@ -1,5 +1,7 @@
<?php
class CoverageMethodTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageMethodTest extends TestCase
{
/**
* @covers CoveredClass::publicMethod
@@ -1,5 +1,7 @@
<?php
class CoverageNoneTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageNoneTest extends TestCase
{
public function testSomething()
{
@@ -1,5 +1,7 @@
<?php
class CoverageNotPrivateTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageNotPrivateTest extends TestCase
{
/**
* @covers CoveredClass::<!private>
@@ -1,5 +1,7 @@
<?php
class CoverageNotProtectedTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageNotProtectedTest extends TestCase
{
/**
* @covers CoveredClass::<!protected>
@@ -1,5 +1,7 @@
<?php
class CoverageNotPublicTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageNotPublicTest extends TestCase
{
/**
* @covers CoveredClass::<!public>
@@ -1,5 +1,7 @@
<?php
class CoverageNothingTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageNothingTest extends TestCase
{
/**
* @covers CoveredClass::publicMethod
@@ -1,5 +1,7 @@
<?php
class CoveragePrivateTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoveragePrivateTest extends TestCase
{
/**
* @covers CoveredClass::<private>
@@ -1,5 +1,7 @@
<?php
class CoverageProtectedTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoverageProtectedTest extends TestCase
{
/**
* @covers CoveredClass::<protected>
@@ -1,5 +1,7 @@
<?php
class CoveragePublicTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class CoveragePublicTest extends TestCase
{
/**
* @covers CoveredClass::<public>
@@ -1,5 +1,4 @@
<?php
/**
* @coversDefaultClass \NamespaceOne
* @coversDefaultClass \AnotherDefault\Name\Space\Does\Not\Work
@@ -1,5 +1,7 @@
<?php
class NamespaceCoverageClassExtendedTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class NamespaceCoverageClassExtendedTest extends TestCase
{
/**
* @covers Foo\CoveredClass<extended>
@@ -1,5 +1,7 @@
<?php
class NamespaceCoverageClassTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class NamespaceCoverageClassTest extends TestCase
{
/**
* @covers Foo\CoveredClass
@@ -1,8 +1,10 @@
<?php
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass \Foo\CoveredClass
*/
class NamespaceCoverageCoversClassPublicTest extends PHPUnit_Framework_TestCase
class NamespaceCoverageCoversClassPublicTest extends TestCase
{
/**
* @covers ::publicMethod
@@ -1,8 +1,10 @@
<?php
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass \Foo\CoveredClass
*/
class NamespaceCoverageCoversClassTest extends PHPUnit_Framework_TestCase
class NamespaceCoverageCoversClassTest extends TestCase
{
/**
* @covers ::privateMethod
@@ -1,5 +1,7 @@
<?php
class NamespaceCoverageMethodTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class NamespaceCoverageMethodTest extends TestCase
{
/**
* @covers Foo\CoveredClass::publicMethod
@@ -1,5 +1,7 @@
<?php
class NamespaceCoverageNotPrivateTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class NamespaceCoverageNotPrivateTest extends TestCase
{
/**
* @covers Foo\CoveredClass::<!private>
@@ -1,5 +1,7 @@
<?php
class NamespaceCoverageNotProtectedTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class NamespaceCoverageNotProtectedTest extends TestCase
{
/**
* @covers Foo\CoveredClass::<!protected>
@@ -1,5 +1,7 @@
<?php
class NamespaceCoverageNotPublicTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class NamespaceCoverageNotPublicTest extends TestCase
{
/**
* @covers Foo\CoveredClass::<!public>
@@ -1,5 +1,7 @@
<?php
class NamespaceCoveragePrivateTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class NamespaceCoveragePrivateTest extends TestCase
{
/**
* @covers Foo\CoveredClass::<private>
@@ -1,5 +1,7 @@
<?php
class NamespaceCoverageProtectedTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class NamespaceCoverageProtectedTest extends TestCase
{
/**
* @covers Foo\CoveredClass::<protected>
@@ -1,5 +1,7 @@
<?php
class NamespaceCoveragePublicTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class NamespaceCoveragePublicTest extends TestCase
{
/**
* @covers Foo\CoveredClass::<public>
@@ -1,5 +1,7 @@
<?php
class NotExistingCoveredElementTest extends PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class NotExistingCoveredElementTest extends TestCase
{
/**
* @covers NotExistingClass
@@ -4,11 +4,11 @@
<meta charset="UTF-8">
<title>Code Coverage for %s/BankAccount.php</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link href=".css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href=".css/style.css" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="js/html5shiv.min.js"></script>
<script src="js/respond.min.js"></script>
<script src=".js/html5shiv.min.js"></script>
<script src=".js/respond.min.js"></script>
<![endif]-->
</head>
<body>
@@ -232,36 +232,14 @@
<span class="warning"><strong>Dead Code</strong></span>
</p>
<p>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="http%sphp.net/" target="_top">PHP%s</a>%s at %s.</small>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
</p>
<a title="Back to the top" id="toplink" href="#"><span class="glyphicon glyphicon-arrow-up"></span></a>
</footer>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/holder.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
var $window = $(window)
, $top_link = $('#toplink')
, $body = $('body, html')
, offset = $('#code').offset().top;
$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: 'hover'});
});
</script>
<script src=".js/jquery.min.js" type="text/javascript"></script>
<script src=".js/bootstrap.min.js" type="text/javascript"></script>
<script src=".js/holder.min.js" type="text/javascript"></script>
<script src=".js/file.js" type="text/javascript"></script>
</body>
</html>
@@ -4,12 +4,12 @@
<meta charset="UTF-8">
<title>Dashboard for %s</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/nv.d3.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link href=".css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href=".css/nv.d3.min.css" rel="stylesheet" type="text/css">
<link href=".css/style.css" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="js/html5shiv.min.js"></script>
<script src="js/respond.min.js"></script>
<script src=".js/html5shiv.min.js"></script>
<script src=".js/respond.min.js"></script>
<![endif]-->
</head>
<body>
@@ -140,15 +140,15 @@
<footer>
<hr/>
<p>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="http%sphp.net/" target="_top">PHP%s</a>%s at %s.</small>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
</p>
</footer>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/holder.min.js" type="text/javascript"></script>
<script src="js/d3.min.js" type="text/javascript"></script>
<script src="js/nv.d3.min.js" type="text/javascript"></script>
<script src=".js/jquery.min.js" type="text/javascript"></script>
<script src=".js/bootstrap.min.js" type="text/javascript"></script>
<script src=".js/holder.min.js" type="text/javascript"></script>
<script src=".js/d3.min.js" type="text/javascript"></script>
<script src=".js/nv.d3.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
nv.addGraph(function() {
@@ -4,11 +4,11 @@
<meta charset="UTF-8">
<title>Code Coverage for %s</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link href=".css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href=".css/style.css" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="js/html5shiv.min.js"></script>
<script src="js/respond.min.js"></script>
<script src=".js/html5shiv.min.js"></script>
<script src=".js/respond.min.js"></script>
<![endif]-->
</head>
<body>
@@ -108,12 +108,12 @@
<span class="success"><strong>High</strong>: 90% to 100%</span>
</p>
<p>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="http%sphp.net/" target="_top">PHP%s</a>%s at %s.</small>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
</p>
</footer>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/holder.min.js" type="text/javascript"></script>
<script src=".js/jquery.min.js" type="text/javascript"></script>
<script src=".js/bootstrap.min.js" type="text/javascript"></script>
<script src=".js/holder.min.js" type="text/javascript"></script>
</body>
</html>
@@ -4,12 +4,12 @@
<meta charset="UTF-8">
<title>Dashboard for %s</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/nv.d3.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link href=".css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href=".css/nv.d3.min.css" rel="stylesheet" type="text/css">
<link href=".css/style.css" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="js/html5shiv.min.js"></script>
<script src="js/respond.min.js"></script>
<script src=".js/html5shiv.min.js"></script>
<script src=".js/respond.min.js"></script>
<![endif]-->
</head>
<body>
@@ -138,15 +138,15 @@
<footer>
<hr/>
<p>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="http%sphp.net/" target="_top">PHP%s</a>%s at %s.</small>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
</p>
</footer>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/holder.min.js" type="text/javascript"></script>
<script src="js/d3.min.js" type="text/javascript"></script>
<script src="js/nv.d3.min.js" type="text/javascript"></script>
<script src=".js/jquery.min.js" type="text/javascript"></script>
<script src=".js/bootstrap.min.js" type="text/javascript"></script>
<script src=".js/holder.min.js" type="text/javascript"></script>
<script src=".js/d3.min.js" type="text/javascript"></script>
<script src=".js/nv.d3.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
nv.addGraph(function() {
@@ -251,7 +251,7 @@ $(document).ready(function() {
chart.yAxis.axisLabel('Method Complexity');
d3.select('#methodComplexity svg')
.datum(getComplexityData([[66.666666666667,1,"<a href=\"source_with_class_and_anonymous_function.php.html#5\">CoveredClassWithAnonymousFunctionInStaticMethod::runAnonymous<\/a>"],[100,1,"<a href=\"source_with_class_and_anonymous_function.php.html#11\">CoveredClassWithAnonymousFunctionInStaticMethod::anonymous function<\/a>"]], 'Method Complexity'))
.datum(getComplexityData([[66.666666666667,1,"<a href=\"source_with_class_and_anonymous_function.php.html#5\">CoveredClassWithAnonymousFunctionInStaticMethod::runAnonymous<\/a>"],[100,1,"<a href=\"source_with_class_and_anonymous_function.php.html#11\">CoveredClassWithAnonymousFunctionInStaticMethod::anonymousFunction:11#41<\/a>"]], 'Method Complexity'))
.transition()
.duration(500)
.call(chart);
@@ -4,11 +4,11 @@
<meta charset="UTF-8">
<title>Code Coverage for %s</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link href=".css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href=".css/style.css" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="js/html5shiv.min.js"></script>
<script src="js/respond.min.js"></script>
<script src=".js/html5shiv.min.js"></script>
<script src=".js/respond.min.js"></script>
<![endif]-->
</head>
<body>
@@ -108,12 +108,12 @@
<span class="success"><strong>High</strong>: 90% to 100%</span>
</p>
<p>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="http%sphp.net/" target="_top">PHP%s</a>%s at %s.</small>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
</p>
</footer>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/holder.min.js" type="text/javascript"></script>
<script src=".js/jquery.min.js" type="text/javascript"></script>
<script src=".js/bootstrap.min.js" type="text/javascript"></script>
<script src=".js/holder.min.js" type="text/javascript"></script>
</body>
</html>
@@ -4,11 +4,11 @@
<meta charset="UTF-8">
<title>Code Coverage for %s/source_with_class_and_anonymous_function.php</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link href=".css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href=".css/style.css" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="js/html5shiv.min.js"></script>
<script src="js/respond.min.js"></script>
<script src=".js/html5shiv.min.js"></script>
<script src=".js/respond.min.js"></script>
<![endif]-->
</head>
<body>
@@ -120,7 +120,7 @@
</tr>
<tr>
<td class="success" colspan="4">&nbsp;<a href="#11"><abbr title="anonymous function (&amp;$val, $key)">anonymous function</abbr></a></td>
<td class="success" colspan="4">&nbsp;<a href="#11"><abbr title="anonymousFunction (&amp;$val, $key)">anonymousFunction:11#41</abbr></a></td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
@@ -176,36 +176,14 @@
<span class="warning"><strong>Dead Code</strong></span>
</p>
<p>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="http%sphp.net/" target="_top">PHP%s</a>%s at %s.</small>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
</p>
<a title="Back to the top" id="toplink" href="#"><span class="glyphicon glyphicon-arrow-up"></span></a>
</footer>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/holder.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
var $window = $(window)
, $top_link = $('#toplink')
, $body = $('body, html')
, offset = $('#code').offset().top;
$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: 'hover'});
});
</script>
<script src=".js/jquery.min.js" type="text/javascript"></script>
<script src=".js/bootstrap.min.js" type="text/javascript"></script>
<script src=".js/holder.min.js" type="text/javascript"></script>
<script src=".js/file.js" type="text/javascript"></script>
</body>
</html>
@@ -4,12 +4,12 @@
<meta charset="UTF-8">
<title>Dashboard for %s</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/nv.d3.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link href=".css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href=".css/nv.d3.min.css" rel="stylesheet" type="text/css">
<link href=".css/style.css" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="js/html5shiv.min.js"></script>
<script src="js/respond.min.js"></script>
<script src=".js/html5shiv.min.js"></script>
<script src=".js/respond.min.js"></script>
<![endif]-->
</head>
<body>
@@ -136,15 +136,15 @@
<footer>
<hr/>
<p>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="http%sphp.net/" target="_top">PHP%s</a>%s at %s.</small>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
</p>
</footer>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/holder.min.js" type="text/javascript"></script>
<script src="js/d3.min.js" type="text/javascript"></script>
<script src="js/nv.d3.min.js" type="text/javascript"></script>
<script src=".js/jquery.min.js" type="text/javascript"></script>
<script src=".js/bootstrap.min.js" type="text/javascript"></script>
<script src=".js/holder.min.js" type="text/javascript"></script>
<script src=".js/d3.min.js" type="text/javascript"></script>
<script src=".js/nv.d3.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
nv.addGraph(function() {
@@ -4,11 +4,11 @@
<meta charset="UTF-8">
<title>Code Coverage for %s</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link href=".css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href=".css/style.css" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="js/html5shiv.min.js"></script>
<script src="js/respond.min.js"></script>
<script src=".js/html5shiv.min.js"></script>
<script src=".js/respond.min.js"></script>
<![endif]-->
</head>
<body>
@@ -57,15 +57,10 @@
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">0&nbsp;/&nbsp;0</div></td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
</div>
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">2&nbsp;/&nbsp;2</div></td>
<td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
<td class=" big"></td>
<td class=" small"><div align="right">n/a</div></td>
<td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
</tr>
<tr>
@@ -85,15 +80,10 @@
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">0&nbsp;/&nbsp;0</div></td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
</div>
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">2&nbsp;/&nbsp;2</div></td>
<td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
<td class=" big"></td>
<td class=" small"><div align="right">n/a</div></td>
<td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
</tr>
@@ -108,12 +98,12 @@
<span class="success"><strong>High</strong>: 90% to 100%</span>
</p>
<p>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="http%sphp.net/" target="_top">PHP%s</a>%s at %s.</small>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
</p>
</footer>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/holder.min.js" type="text/javascript"></script>
<script src=".js/jquery.min.js" type="text/javascript"></script>
<script src=".js/bootstrap.min.js" type="text/javascript"></script>
<script src=".js/holder.min.js" type="text/javascript"></script>
</body>
</html>
@@ -2,13 +2,13 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Code Coverage for %s/source_with_ignore.php</title>
<title>Code Coverage for %s</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link href=".css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href=".css/style.css" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="js/html5shiv.min.js"></script>
<script src="js/respond.min.js"></script>
<script src=".js/html5shiv.min.js"></script>
<script src=".js/respond.min.js"></script>
<![endif]-->
</head>
<body>
@@ -41,7 +41,10 @@
</thead>
<tbody>
<tr>
<td class="success">Total</td>
<td class="">Total</td>
<td class=" big"></td>
<td class=" small"><div align="right">n/a</div></td>
<td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
@@ -49,15 +52,7 @@
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">2&nbsp;/&nbsp;2</div></td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
</div>
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">0&nbsp;/&nbsp;0</div></td>
<td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
<td class="success small"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></td>
<td class="danger big"> <div class="progress">
<div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="50.00" aria-valuemin="0" aria-valuemax="100" style="width: 50.00%">
@@ -79,27 +74,17 @@
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
<td class="success small">0</td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
</div>
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">0&nbsp;/&nbsp;0</div></td>
<td class="success small">1</td>
<td class=" big"></td>
<td class=" small"><div align="right">n/a</div></td>
<td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
</tr>
<tr>
<td class="success">Foo</td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
</div>
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
<td class="">Foo</td>
<td class=" big"></td>
<td class=" small"><div align="right">n/a</div></td>
<td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
@@ -109,14 +94,9 @@
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
<td class="success small">1</td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
</div>
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">0&nbsp;/&nbsp;0</div></td>
<td class=" big"></td>
<td class=" small"><div align="right">n/a</div></td>
<td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
</tr>
<tr>
@@ -130,26 +110,16 @@
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
<td class="success small">1</td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
</div>
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">0&nbsp;/&nbsp;0</div></td>
<td class=" big"></td>
<td class=" small"><div align="right">n/a</div></td>
<td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
</tr>
<tr>
<td class="success">Bar</td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
</div>
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
<td class="">Bar</td>
<td class=" big"></td>
<td class=" small"><div align="right">n/a</div></td>
<td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
@@ -159,14 +129,9 @@
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
<td class="success small">1</td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
</div>
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">0&nbsp;/&nbsp;0</div></td>
<td class=" big"></td>
<td class=" small"><div align="right">n/a</div></td>
<td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
</tr>
<tr>
@@ -180,14 +145,9 @@
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
<td class="success small">1</td>
<td class="success big"> <div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
<span class="sr-only">100.00% covered (success)</span>
</div>
</div>
</td>
<td class="success small"><div align="right">100.00%</div></td>
<td class="success small"><div align="right">0&nbsp;/&nbsp;0</div></td>
<td class=" big"></td>
<td class=" small"><div align="right">n/a</div></td>
<td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
</tr>
@@ -244,36 +204,14 @@
<span class="warning"><strong>Dead Code</strong></span>
</p>
<p>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="http%sphp.net/" target="_top">PHP%s</a>%s at %s.</small>
<small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
</p>
<a title="Back to the top" id="toplink" href="#"><span class="glyphicon glyphicon-arrow-up"></span></a>
</footer>
</div>
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/holder.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
var $window = $(window)
, $top_link = $('#toplink')
, $body = $('body, html')
, offset = $('#code').offset().top;
$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: 'hover'});
});
</script>
<script src=".js/jquery.min.js" type="text/javascript"></script>
<script src=".js/bootstrap.min.js" type="text/javascript"></script>
<script src=".js/holder.min.js" type="text/javascript"></script>
<script src=".js/file.js" type="text/javascript"></script>
</body>
</html>
@@ -1,12 +1,12 @@
<?xml version="1.0"?>
<phpunit xmlns="http://schema.phpunit.de/coverage/1.0">
<file name="BankAccount.php">
<file name="BankAccount.php" path="/">
<totals>
<lines total="33" comments="0" code="33" executable="10" executed="5" percent="50.00%"/>
<methods count="4" tested="3" percent="75.00%"/>
<functions count="0" tested="0" percent=""/>
<classes count="1" tested="0" percent="0.00%"/>
<traits count="0" tested="0" percent=""/>
<lines total="33" comments="0" code="33" executable="10" executed="5" percent="50.00"/>
<methods count="4" tested="3" percent="75.00"/>
<functions count="0" tested="0" percent="0"/>
<classes count="1" tested="0" percent="0.00"/>
<traits count="0" tested="0" percent="0"/>
</totals>
<class name="BankAccount" start="2" executable="10" executed="5" crap="8.12">
<package full="" name="" sub="" category=""/>
@@ -36,5 +36,227 @@
<covered by="BankAccountTest::testDepositWithdrawMoney"/>
</line>
</coverage>
<source>
<line no="1">
<token name="T_OPEN_TAG">&lt;?php</token>
</line>
<line no="2">
<token name="T_CLASS">class</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">BankAccount</token>
</line>
<line no="3">
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="4">
<token name="T_WHITESPACE"> </token>
<token name="T_PROTECTED">protected</token>
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$balance</token>
<token name="T_WHITESPACE"> </token>
<token name="T_EQUAL">=</token>
<token name="T_WHITESPACE"> </token>
<token name="T_LNUMBER">0</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="5"/>
<line no="6">
<token name="T_WHITESPACE"> </token>
<token name="T_PUBLIC">public</token>
<token name="T_WHITESPACE"> </token>
<token name="T_FUNCTION">function</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">getBalance</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_CLOSE_BRACKET">)</token>
</line>
<line no="7">
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="8">
<token name="T_WHITESPACE"> </token>
<token name="T_RETURN">return</token>
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$this</token>
<token name="T_OBJECT_OPERATOR">-&gt;</token>
<token name="T_STRING">balance</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="9">
<token name="T_WHITESPACE"> </token>
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="10"/>
<line no="11">
<token name="T_WHITESPACE"> </token>
<token name="T_PROTECTED">protected</token>
<token name="T_WHITESPACE"> </token>
<token name="T_FUNCTION">function</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">setBalance</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_VARIABLE">$balance</token>
<token name="T_CLOSE_BRACKET">)</token>
</line>
<line no="12">
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="13">
<token name="T_WHITESPACE"> </token>
<token name="T_IF">if</token>
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_VARIABLE">$balance</token>
<token name="T_WHITESPACE"> </token>
<token name="T_IS_GREATER_OR_EQUAL">&gt;=</token>
<token name="T_WHITESPACE"> </token>
<token name="T_LNUMBER">0</token>
<token name="T_CLOSE_BRACKET">)</token>
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="14">
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$this</token>
<token name="T_OBJECT_OPERATOR">-&gt;</token>
<token name="T_STRING">balance</token>
<token name="T_WHITESPACE"> </token>
<token name="T_EQUAL">=</token>
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$balance</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="15">
<token name="T_WHITESPACE"> </token>
<token name="T_CLOSE_CURLY">}</token>
<token name="T_WHITESPACE"> </token>
<token name="T_ELSE">else</token>
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="16">
<token name="T_WHITESPACE"> </token>
<token name="T_THROW">throw</token>
<token name="T_WHITESPACE"> </token>
<token name="T_NEW">new</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">RuntimeException</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="17">
<token name="T_WHITESPACE"> </token>
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="18">
<token name="T_WHITESPACE"> </token>
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="19"/>
<line no="20">
<token name="T_WHITESPACE"> </token>
<token name="T_PUBLIC">public</token>
<token name="T_WHITESPACE"> </token>
<token name="T_FUNCTION">function</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">depositMoney</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_VARIABLE">$balance</token>
<token name="T_CLOSE_BRACKET">)</token>
</line>
<line no="21">
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="22">
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$this</token>
<token name="T_OBJECT_OPERATOR">-&gt;</token>
<token name="T_STRING">setBalance</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_VARIABLE">$this</token>
<token name="T_OBJECT_OPERATOR">-&gt;</token>
<token name="T_STRING">getBalance</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_CLOSE_BRACKET">)</token>
<token name="T_WHITESPACE"> </token>
<token name="T_PLUS">+</token>
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$balance</token>
<token name="T_CLOSE_BRACKET">)</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="23"/>
<line no="24">
<token name="T_WHITESPACE"> </token>
<token name="T_RETURN">return</token>
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$this</token>
<token name="T_OBJECT_OPERATOR">-&gt;</token>
<token name="T_STRING">getBalance</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_CLOSE_BRACKET">)</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="25">
<token name="T_WHITESPACE"> </token>
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="26"/>
<line no="27">
<token name="T_WHITESPACE"> </token>
<token name="T_PUBLIC">public</token>
<token name="T_WHITESPACE"> </token>
<token name="T_FUNCTION">function</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">withdrawMoney</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_VARIABLE">$balance</token>
<token name="T_CLOSE_BRACKET">)</token>
</line>
<line no="28">
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="29">
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$this</token>
<token name="T_OBJECT_OPERATOR">-&gt;</token>
<token name="T_STRING">setBalance</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_VARIABLE">$this</token>
<token name="T_OBJECT_OPERATOR">-&gt;</token>
<token name="T_STRING">getBalance</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_CLOSE_BRACKET">)</token>
<token name="T_WHITESPACE"> </token>
<token name="T_MINUS">-</token>
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$balance</token>
<token name="T_CLOSE_BRACKET">)</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="30"/>
<line no="31">
<token name="T_WHITESPACE"> </token>
<token name="T_RETURN">return</token>
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$this</token>
<token name="T_OBJECT_OPERATOR">-&gt;</token>
<token name="T_STRING">getBalance</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_CLOSE_BRACKET">)</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="32">
<token name="T_WHITESPACE"> </token>
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="33">
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="34"/>
</source>
</file>
</phpunit>
@@ -1,6 +1,10 @@
<?xml version="1.0"?>
<phpunit xmlns="http://schema.phpunit.de/coverage/1.0">
<project name="%s">
<build time="%s" phpunit="%s" coverage="%s">
<runtime name="%s" version="%s" url="%s"/>
<driver name="%s" version="%s"/>
</build>
<project source="%s">
<tests>
<test name="BankAccountTest::testBalanceIsInitiallyZero" size="unknown" result="0" status="PASSED"/>
<test name="BankAccountTest::testBalanceCannotBecomeNegative" size="unknown" result="0" status="PASSED"/>
@@ -9,19 +13,19 @@
</tests>
<directory name="%s">
<totals>
<lines total="33" comments="0" code="33" executable="10" executed="5" percent="50.00%"/>
<methods count="4" tested="3" percent="75.00%"/>
<functions count="0" tested="0" percent=""/>
<classes count="1" tested="0" percent="0.00%"/>
<traits count="0" tested="0" percent=""/>
<lines total="33" comments="0" code="33" executable="10" executed="5" percent="50.00"/>
<methods count="4" tested="3" percent="75.00"/>
<functions count="0" tested="0" percent="0"/>
<classes count="1" tested="0" percent="0.00"/>
<traits count="0" tested="0" percent="0"/>
</totals>
<file name="BankAccount.php" href="BankAccount.php.xml">
<totals>
<lines total="33" comments="0" code="33" executable="10" executed="5" percent="50.00%"/>
<methods count="4" tested="3" percent="75.00%"/>
<functions count="0" tested="0" percent=""/>
<classes count="1" tested="0" percent="0.00%"/>
<traits count="0" tested="0" percent=""/>
<lines total="33" comments="0" code="33" executable="10" executed="5" percent="50.00"/>
<methods count="4" tested="3" percent="75.00"/>
<functions count="0" tested="0" percent="0"/>
<classes count="1" tested="0" percent="0.00"/>
<traits count="0" tested="0" percent="0"/>
</totals>
</file>
</directory>
@@ -1,24 +1,28 @@
<?xml version="1.0"?>
<phpunit xmlns="http://schema.phpunit.de/coverage/1.0">
<project name="%s">
<build time="%s" phpunit="%s" coverage="%s">
<runtime name="%s" version="%s" url="%s"/>
<driver name="%s" version="%s"/>
</build>
<project source="%s">
<tests>
<test name="ClassWithAnonymousFunction" size="unknown" result="0" status="PASSED"/>
</tests>
<directory name="%s">
<totals>
<lines total="19" comments="2" code="17" executable="8" executed="7" percent="87.50%"/>
<methods count="2" tested="1" percent="50.00%"/>
<functions count="0" tested="0" percent=""/>
<classes count="1" tested="0" percent="0.00%"/>
<traits count="0" tested="0" percent=""/>
<lines total="19" comments="2" code="17" executable="8" executed="7" percent="87.50"/>
<methods count="2" tested="1" percent="50.00"/>
<functions count="0" tested="0" percent="0"/>
<classes count="1" tested="0" percent="0.00"/>
<traits count="0" tested="0" percent="0"/>
</totals>
<file name="source_with_class_and_anonymous_function.php" href="source_with_class_and_anonymous_function.php.xml">
<totals>
<lines total="19" comments="2" code="17" executable="8" executed="7" percent="87.50%"/>
<methods count="2" tested="1" percent="50.00%"/>
<functions count="0" tested="0" percent=""/>
<classes count="1" tested="0" percent="0.00%"/>
<traits count="0" tested="0" percent=""/>
<lines total="19" comments="2" code="17" executable="8" executed="7" percent="87.50"/>
<methods count="2" tested="1" percent="50.00"/>
<functions count="0" tested="0" percent="0"/>
<classes count="1" tested="0" percent="0.00"/>
<traits count="0" tested="0" percent="0"/>
</totals>
</file>
</directory>
@@ -1,18 +1,18 @@
<?xml version="1.0"?>
<phpunit xmlns="http://schema.phpunit.de/coverage/1.0">
<file name="source_with_class_and_anonymous_function.php">
<file name="source_with_class_and_anonymous_function.php" path="/">
<totals>
<lines total="19" comments="2" code="17" executable="8" executed="7" percent="87.50%"/>
<methods count="2" tested="1" percent="50.00%"/>
<functions count="0" tested="0" percent=""/>
<classes count="1" tested="0" percent="0.00%"/>
<traits count="0" tested="0" percent=""/>
<lines total="19" comments="2" code="17" executable="8" executed="7" percent="87.50"/>
<methods count="2" tested="1" percent="50.00"/>
<functions count="0" tested="0" percent="0"/>
<classes count="1" tested="0" percent="0.00"/>
<traits count="0" tested="0" percent="0"/>
</totals>
<class name="CoveredClassWithAnonymousFunctionInStaticMethod" start="3" executable="8" executed="7" crap="2.01">
<package full="" name="" sub="" category=""/>
<namespace name=""/>
<method name="runAnonymous" signature="runAnonymous()" start="5" end="18" crap="1.04" executable="3" executed="2" coverage="66.666666666667"/>
<method name="anonymous function" signature="anonymous function (&amp;$val, $key)" start="11" end="13" crap="1" executable="2" executed="2" coverage="100"/>
<method name="anonymousFunction:11#41" signature="anonymousFunction (&amp;$val, $key)" start="11" end="13" crap="1" executable="2" executed="2" coverage="100"/>
</class>
<coverage>
<line nr="7">
@@ -37,5 +37,126 @@
<covered by="ClassWithAnonymousFunction"/>
</line>
</coverage>
<source>
<line no="1">
<token name="T_OPEN_TAG">&lt;?php</token>
</line>
<line no="2"/>
<line no="3">
<token name="T_CLASS">class</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">CoveredClassWithAnonymousFunctionInStaticMethod</token>
</line>
<line no="4">
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="5">
<token name="T_WHITESPACE"> </token>
<token name="T_PUBLIC">public</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STATIC">static</token>
<token name="T_WHITESPACE"> </token>
<token name="T_FUNCTION">function</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">runAnonymous</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_CLOSE_BRACKET">)</token>
</line>
<line no="6">
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="7">
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$filter</token>
<token name="T_WHITESPACE"> </token>
<token name="T_EQUAL">=</token>
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_SQUARE">[</token>
<token name="T_CONSTANT_ENCAPSED_STRING">'abc124'</token>
<token name="T_COMMA">,</token>
<token name="T_WHITESPACE"> </token>
<token name="T_CONSTANT_ENCAPSED_STRING">'abc123'</token>
<token name="T_COMMA">,</token>
<token name="T_WHITESPACE"> </token>
<token name="T_CONSTANT_ENCAPSED_STRING">'123'</token>
<token name="T_CLOSE_SQUARE">]</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="8"/>
<line no="9">
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">array_walk</token>
<token name="T_OPEN_BRACKET">(</token>
</line>
<line no="10">
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$filter</token>
<token name="T_COMMA">,</token>
</line>
<line no="11">
<token name="T_WHITESPACE"> </token>
<token name="T_FUNCTION">function</token>
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_AMPERSAND">&amp;</token>
<token name="T_VARIABLE">$val</token>
<token name="T_COMMA">,</token>
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$key</token>
<token name="T_CLOSE_BRACKET">)</token>
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="12">
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$val</token>
<token name="T_WHITESPACE"> </token>
<token name="T_EQUAL">=</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">preg_replace</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_CONSTANT_ENCAPSED_STRING">'|[^0-9]|'</token>
<token name="T_COMMA">,</token>
<token name="T_WHITESPACE"> </token>
<token name="T_CONSTANT_ENCAPSED_STRING">''</token>
<token name="T_COMMA">,</token>
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$val</token>
<token name="T_CLOSE_BRACKET">)</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="13">
<token name="T_WHITESPACE"> </token>
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="14">
<token name="T_WHITESPACE"> </token>
<token name="T_CLOSE_BRACKET">)</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="15"/>
<line no="16">
<token name="T_WHITESPACE"> </token>
<token name="T_COMMENT">// Should be covered</token>
</line>
<line no="17">
<token name="T_WHITESPACE"> </token>
<token name="T_VARIABLE">$extravar</token>
<token name="T_WHITESPACE"> </token>
<token name="T_EQUAL">=</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">true</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="18">
<token name="T_WHITESPACE"> </token>
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="19">
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="20"/>
</source>
</file>
</phpunit>
@@ -1,24 +1,28 @@
<?xml version="1.0"?>
<phpunit xmlns="http://schema.phpunit.de/coverage/1.0">
<project name="%s">
<build time="%s" phpunit="%s" coverage="%s">
<runtime name="%s" version="%s" url="%s"/>
<driver name="%s" version="%s"/>
</build>
<project source="%s">
<tests>
<test name="FileWithIgnoredLines" size="unknown" result="0" status="PASSED"/>
</tests>
<directory name="%s">
<totals>
<lines total="37" comments="12" code="25" executable="2" executed="1" percent="50.00%"/>
<methods count="0" tested="0" percent=""/>
<functions count="1" tested="0" percent="0.00%"/>
<classes count="2" tested="2" percent="100.00%"/>
<traits count="0" tested="0" percent=""/>
<lines total="37" comments="12" code="25" executable="2" executed="1" percent="50.00"/>
<methods count="0" tested="0" percent="0"/>
<functions count="1" tested="1" percent="100.00"/>
<classes count="0" tested="0" percent="0"/>
<traits count="0" tested="0" percent="0"/>
</totals>
<file name="source_with_ignore.php" href="source_with_ignore.php.xml">
<totals>
<lines total="37" comments="12" code="25" executable="2" executed="1" percent="50.00%"/>
<methods count="0" tested="0" percent=""/>
<functions count="1" tested="0" percent="0.00%"/>
<classes count="2" tested="2" percent="100.00%"/>
<traits count="0" tested="0" percent=""/>
<lines total="37" comments="12" code="25" executable="2" executed="1" percent="50.00"/>
<methods count="0" tested="0" percent="0"/>
<functions count="1" tested="1" percent="100.00"/>
<classes count="0" tested="0" percent="0"/>
<traits count="0" tested="0" percent="0"/>
</totals>
</file>
</directory>
@@ -1,12 +1,12 @@
<?xml version="1.0"?>
<phpunit xmlns="http://schema.phpunit.de/coverage/1.0">
<file name="source_with_ignore.php">
<file name="source_with_ignore.php" path="/">
<totals>
<lines total="37" comments="12" code="25" executable="2" executed="1" percent="50.00%"/>
<methods count="0" tested="0" percent=""/>
<functions count="1" tested="0" percent="0.00%"/>
<classes count="2" tested="2" percent="100.00%"/>
<traits count="0" tested="0" percent=""/>
<lines total="37" comments="12" code="25" executable="2" executed="1" percent="50.00"/>
<methods count="0" tested="0" percent="0"/>
<functions count="1" tested="1" percent="100.00"/>
<classes count="0" tested="0" percent="0"/>
<traits count="0" tested="0" percent="0"/>
</totals>
<class name="Foo" start="11" executable="0" executed="0" crap="1">
<package full="" name="" sub="" category=""/>
@@ -18,11 +18,170 @@
<namespace name=""/>
<method name="foo" signature="foo()" start="23" end="25" crap="1" executable="0" executed="0" coverage="100"/>
</class>
<function name="baz" signature="baz()" start="28" crap="0" executable="0" executed="0" coverage="0"/>
<function name="baz" signature="baz()" start="28" crap="1" executable="0" executed="0" coverage="100"/>
<coverage>
<line nr="2">
<covered by="FileWithIgnoredLines"/>
</line>
</coverage>
<source>
<line no="1">
<token name="T_OPEN_TAG">&lt;?php</token>
</line>
<line no="2">
<token name="T_IF">if</token>
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_VARIABLE">$neverHappens</token>
<token name="T_CLOSE_BRACKET">)</token>
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="3">
<token name="T_WHITESPACE"> </token>
<token name="T_COMMENT">// @codeCoverageIgnoreStart</token>
</line>
<line no="4">
<token name="T_WHITESPACE"> </token>
<token name="T_PRINT">print</token>
<token name="T_WHITESPACE"> </token>
<token name="T_CONSTANT_ENCAPSED_STRING">'*'</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="5">
<token name="T_WHITESPACE"> </token>
<token name="T_COMMENT">// @codeCoverageIgnoreEnd</token>
</line>
<line no="6">
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="7"/>
<line no="8">
<token name="T_DOC_COMMENT">/**</token>
</line>
<line no="9">
<token name="T_DOC_COMMENT"> * @codeCoverageIgnore</token>
</line>
<line no="10">
<token name="T_DOC_COMMENT"> */</token>
</line>
<line no="11">
<token name="T_CLASS">class</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">Foo</token>
</line>
<line no="12">
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="13">
<token name="T_WHITESPACE"> </token>
<token name="T_PUBLIC">public</token>
<token name="T_WHITESPACE"> </token>
<token name="T_FUNCTION">function</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">bar</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_CLOSE_BRACKET">)</token>
</line>
<line no="14">
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="15">
<token name="T_WHITESPACE"> </token>
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="16">
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="17"/>
<line no="18">
<token name="T_CLASS">class</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">Bar</token>
</line>
<line no="19">
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="20">
<token name="T_WHITESPACE"> </token>
<token name="T_DOC_COMMENT">/**</token>
</line>
<line no="21">
<token name="T_DOC_COMMENT"> * @codeCoverageIgnore</token>
</line>
<line no="22">
<token name="T_DOC_COMMENT"> */</token>
</line>
<line no="23">
<token name="T_WHITESPACE"> </token>
<token name="T_PUBLIC">public</token>
<token name="T_WHITESPACE"> </token>
<token name="T_FUNCTION">function</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">foo</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_CLOSE_BRACKET">)</token>
</line>
<line no="24">
<token name="T_WHITESPACE"> </token>
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="25">
<token name="T_WHITESPACE"> </token>
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="26">
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="27"/>
<line no="28">
<token name="T_FUNCTION">function</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">baz</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_CLOSE_BRACKET">)</token>
</line>
<line no="29">
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="30">
<token name="T_WHITESPACE"> </token>
<token name="T_PRINT">print</token>
<token name="T_WHITESPACE"> </token>
<token name="T_CONSTANT_ENCAPSED_STRING">'*'</token>
<token name="T_SEMICOLON">;</token>
<token name="T_WHITESPACE"> </token>
<token name="T_COMMENT">// @codeCoverageIgnore</token>
</line>
<line no="31">
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="32"/>
<line no="33">
<token name="T_INTERFACE">interface</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">Bor</token>
</line>
<line no="34">
<token name="T_OPEN_CURLY">{</token>
</line>
<line no="35">
<token name="T_WHITESPACE"> </token>
<token name="T_PUBLIC">public</token>
<token name="T_WHITESPACE"> </token>
<token name="T_FUNCTION">function</token>
<token name="T_WHITESPACE"> </token>
<token name="T_STRING">foo</token>
<token name="T_OPEN_BRACKET">(</token>
<token name="T_CLOSE_BRACKET">)</token>
<token name="T_SEMICOLON">;</token>
</line>
<line no="36"/>
<line no="37">
<token name="T_CLOSE_CURLY">}</token>
</line>
<line no="38"/>
</source>
</file>
</phpunit>
@@ -9,7 +9,7 @@
<line num="7" type="stmt" count="1"/>
<line num="9" type="stmt" count="1"/>
<line num="10" type="stmt" count="0"/>
<line num="11" type="method" name="anonymous function" complexity="1" crap="1" count="1"/>
<line num="11" type="method" name="anonymousFunction:11#41" complexity="1" crap="1" count="1"/>
<line num="12" type="stmt" count="1"/>
<line num="13" type="stmt" count="1"/>
<line num="14" type="stmt" count="1"/>
Loaded 100 of 2349 files, more files were not shown because too many files have changed in this diff. Show more