From 9cc0b03056c8ebd4eed13a503221d00661b80122 Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 11:41:35 -0600 Subject: [PATCH 01/13] Added build scripts to composer.json. Pointed travis and build.xml to composer scripts. --- .travis.yml | 2 +- build.sh | 19 ------------------- build.xml | 34 +++++++++++++--------------------- composer.json | 17 +++++++++++++++++ 4 files changed, 31 insertions(+), 41 deletions(-) delete mode 100755 build.sh diff --git a/.travis.yml b/.travis.yml index 83c3c4d55..6398582bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,4 @@ before_script: - composer install - cp src/config.php.dist src/config.php script: -- ./build.sh + - composer build diff --git a/build.sh b/build.sh deleted file mode 100755 index 0a7560724..000000000 --- a/build.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -set -e - -vendor/bin/parallel-lint --exclude vendor . -git diff origin/master... > diff.txt - -vendor/bin/phpcs \ - --standard=tools/codesniffer/JoindInPSR2/ruleset.xml \ - --ignore=**/config.php,**/database.php,vendor,tools,tests/bootstrap.php \ - --extensions=php \ - --runtime-set ignore_warnings_on_exit true \ - -p \ - . - - -php vendor/bin/security-checker security:check composer.lock - -vendor/bin/phpunit -vendor/bin/diffFilter --phpunit diff.txt build/logs/clover.xml 80 diff --git a/build.xml b/build.xml index 096ddb7a5..c99c31f6c 100644 --- a/build.xml +++ b/build.xml @@ -4,6 +4,13 @@ + + + + + + + @@ -18,12 +25,12 @@ - + - + @@ -39,16 +46,7 @@ - - - - - - - - - - + @@ -77,17 +75,11 @@ - - - - - - - - + + - + diff --git a/composer.json b/composer.json index 535ef0b8d..ceda73fd7 100644 --- a/composer.json +++ b/composer.json @@ -51,6 +51,23 @@ "tests/views" ] }, + "scripts": { + "test": "phpunit -c . tests/", + "lint": "parallel-lint --exclude vendor .", + "smell": "phpcs --standard=tools/codesniffer/JoindInPSR2/ruleset.xml --ignore=**/config.php,**/database.php,vendor,tools,tests/bootstrap.php --extensions=php --report-checkstyle=build/logs/checkstyle.xml --runtime-set ignore_warnings_on_exit true -p .", + "security": "security-checker security:check composer.lock", + "diff": [ + "git diff origin/master... > diff.txt", + "diffFilter --phpunit diff.txt build/logs/clover.xml 80" + ], + "build": [ + "@lint", + "@smell", + "@security", + "@test", + "@diff" + ] + }, "config" : { "preferred-install": "dist", "platform" : { From 849b2c16e6373df98dee2e390c9b5a2f108626fc Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 11:51:06 -0600 Subject: [PATCH 02/13] Create logs dir if it doesn't exist. --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index ceda73fd7..b6c17dd99 100644 --- a/composer.json +++ b/composer.json @@ -61,6 +61,7 @@ "diffFilter --phpunit diff.txt build/logs/clover.xml 80" ], "build": [ + "mkdir -p build/logs", "@lint", "@smell", "@security", From f50dc79299f87dbbf1c03e1df1eabe079e22fb58 Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 11:56:25 -0600 Subject: [PATCH 03/13] Origin Error Fix for Travis Attempt 1. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b6c17dd99..7644f145f 100644 --- a/composer.json +++ b/composer.json @@ -57,7 +57,7 @@ "smell": "phpcs --standard=tools/codesniffer/JoindInPSR2/ruleset.xml --ignore=**/config.php,**/database.php,vendor,tools,tests/bootstrap.php --extensions=php --report-checkstyle=build/logs/checkstyle.xml --runtime-set ignore_warnings_on_exit true -p .", "security": "security-checker security:check composer.lock", "diff": [ - "git diff origin/master... > diff.txt", + "git diff 'origin/master...' > diff.txt", "diffFilter --phpunit diff.txt build/logs/clover.xml 80" ], "build": [ From 742cd174c9fe32f0b24b1d334c9a220e7e66bc39 Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 12:17:53 -0600 Subject: [PATCH 04/13] Origin Error Fix for Travis Attempt 2. --- composer.json | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 7644f145f..dd515c95c 100644 --- a/composer.json +++ b/composer.json @@ -56,17 +56,14 @@ "lint": "parallel-lint --exclude vendor .", "smell": "phpcs --standard=tools/codesniffer/JoindInPSR2/ruleset.xml --ignore=**/config.php,**/database.php,vendor,tools,tests/bootstrap.php --extensions=php --report-checkstyle=build/logs/checkstyle.xml --runtime-set ignore_warnings_on_exit true -p .", "security": "security-checker security:check composer.lock", - "diff": [ - "git diff 'origin/master...' > diff.txt", - "diffFilter --phpunit diff.txt build/logs/clover.xml 80" - ], "build": [ + "git diff origin/master... > diff.txt", "mkdir -p build/logs", "@lint", "@smell", "@security", "@test", - "@diff" + "diffFilter --phpunit diff.txt build/logs/clover.xml 80" ] }, "config" : { From e0bf9a552a4c30cc20edbc57d8d95e435af4bfeb Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 12:22:33 -0600 Subject: [PATCH 05/13] Origin Error Fix for Travis Attempt 3. --- .travis.yml | 2 ++ composer.json | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6398582bc..8198922cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,5 +12,7 @@ matrix: before_script: - composer install - cp src/config.php.dist src/config.php + - git diff origin/master... > diff.txt script: - composer build + - composer diff diff --git a/composer.json b/composer.json index dd515c95c..255fdf394 100644 --- a/composer.json +++ b/composer.json @@ -56,14 +56,13 @@ "lint": "parallel-lint --exclude vendor .", "smell": "phpcs --standard=tools/codesniffer/JoindInPSR2/ruleset.xml --ignore=**/config.php,**/database.php,vendor,tools,tests/bootstrap.php --extensions=php --report-checkstyle=build/logs/checkstyle.xml --runtime-set ignore_warnings_on_exit true -p .", "security": "security-checker security:check composer.lock", + "diff": "diffFilter --phpunit diff.txt build/logs/clover.xml 80", "build": [ - "git diff origin/master... > diff.txt", "mkdir -p build/logs", "@lint", "@smell", "@security", - "@test", - "diffFilter --phpunit diff.txt build/logs/clover.xml 80" + "@test" ] }, "config" : { From efdaf1b4ba5e597ebe36b4943c92412237d03b49 Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 12:32:12 -0600 Subject: [PATCH 06/13] Origin Error Fix for Travis Attempt 4. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8198922cf..1b07cc21b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ matrix: before_script: - composer install - cp src/config.php.dist src/config.php - - git diff origin/master... > diff.txt + - git diff origin/master... -- > diff.txt script: - composer build - composer diff From 18e50195977484b4fa7f9aac2e5213e5de2643f6 Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 12:42:17 -0600 Subject: [PATCH 07/13] Origin Error Fix for Travis Attempt 5. --- .travis.yml | 4 ++-- composer.json | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1b07cc21b..55cc8dd06 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ matrix: before_script: - composer install - cp src/config.php.dist src/config.php - - git diff origin/master... -- > diff.txt + - git remote set-branches --add origin master + - git fetch script: - composer build - - composer diff diff --git a/composer.json b/composer.json index 255fdf394..338968f2d 100644 --- a/composer.json +++ b/composer.json @@ -56,13 +56,17 @@ "lint": "parallel-lint --exclude vendor .", "smell": "phpcs --standard=tools/codesniffer/JoindInPSR2/ruleset.xml --ignore=**/config.php,**/database.php,vendor,tools,tests/bootstrap.php --extensions=php --report-checkstyle=build/logs/checkstyle.xml --runtime-set ignore_warnings_on_exit true -p .", "security": "security-checker security:check composer.lock", - "diff": "diffFilter --phpunit diff.txt build/logs/clover.xml 80", + "diff": [ + "git diff origin/master... -- > diff.txt", + "diffFilter --phpunit diff.txt build/logs/clover.xml 80" + ], "build": [ "mkdir -p build/logs", "@lint", "@smell", "@security", - "@test" + "@test", + "@diff" ] }, "config" : { From 912c849686c93caf93752a18747b180aac28a325 Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 13:14:03 -0600 Subject: [PATCH 08/13] Changed whole test suite from "build" to "test". Changed phpunit from "test" to "unit" --- .travis.yml | 2 +- build.xml | 2 +- composer.json | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 55cc8dd06..3fcbc4fad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,4 @@ before_script: - git remote set-branches --add origin master - git fetch script: - - composer build + - composer test diff --git a/build.xml b/build.xml index c99c31f6c..b00e0b737 100644 --- a/build.xml +++ b/build.xml @@ -25,7 +25,7 @@ - + diff --git a/composer.json b/composer.json index 338968f2d..09d88fc3c 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ ] }, "scripts": { - "test": "phpunit -c . tests/", + "unit": "phpunit -c . tests/", "lint": "parallel-lint --exclude vendor .", "smell": "phpcs --standard=tools/codesniffer/JoindInPSR2/ruleset.xml --ignore=**/config.php,**/database.php,vendor,tools,tests/bootstrap.php --extensions=php --report-checkstyle=build/logs/checkstyle.xml --runtime-set ignore_warnings_on_exit true -p .", "security": "security-checker security:check composer.lock", @@ -60,12 +60,12 @@ "git diff origin/master... -- > diff.txt", "diffFilter --phpunit diff.txt build/logs/clover.xml 80" ], - "build": [ + "test": [ "mkdir -p build/logs", "@lint", "@smell", "@security", - "@test", + "@unit", "@diff" ] }, From 4ea799c175351067b9178ae26030e74c4f5b0619 Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 13:32:43 -0600 Subject: [PATCH 09/13] Changed whole test suite from "test" to "check". Changed phpunit from "unit" back to "test" --- .travis.yml | 2 +- build.xml | 2 +- composer.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3fcbc4fad..d57935b1e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,4 @@ before_script: - git remote set-branches --add origin master - git fetch script: - - composer test + - composer check diff --git a/build.xml b/build.xml index b00e0b737..c99c31f6c 100644 --- a/build.xml +++ b/build.xml @@ -25,7 +25,7 @@ - + diff --git a/composer.json b/composer.json index 09d88fc3c..c056404c1 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ ] }, "scripts": { - "unit": "phpunit -c . tests/", + "test": "phpunit -c . tests/", "lint": "parallel-lint --exclude vendor .", "smell": "phpcs --standard=tools/codesniffer/JoindInPSR2/ruleset.xml --ignore=**/config.php,**/database.php,vendor,tools,tests/bootstrap.php --extensions=php --report-checkstyle=build/logs/checkstyle.xml --runtime-set ignore_warnings_on_exit true -p .", "security": "security-checker security:check composer.lock", @@ -60,7 +60,7 @@ "git diff origin/master... -- > diff.txt", "diffFilter --phpunit diff.txt build/logs/clover.xml 80" ], - "test": [ + "check": [ "mkdir -p build/logs", "@lint", "@smell", From 7df8692712ef4ff950a3db7b303efae90ba99d73 Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 16:37:49 -0600 Subject: [PATCH 10/13] Update composer.json --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index c056404c1..84dfa34db 100644 --- a/composer.json +++ b/composer.json @@ -54,7 +54,7 @@ "scripts": { "test": "phpunit -c . tests/", "lint": "parallel-lint --exclude vendor .", - "smell": "phpcs --standard=tools/codesniffer/JoindInPSR2/ruleset.xml --ignore=**/config.php,**/database.php,vendor,tools,tests/bootstrap.php --extensions=php --report-checkstyle=build/logs/checkstyle.xml --runtime-set ignore_warnings_on_exit true -p .", + "sniff": "phpcs --standard=tools/codesniffer/JoindInPSR2/ruleset.xml --ignore=**/config.php,**/database.php,vendor,tools,tests/bootstrap.php --extensions=php --report-checkstyle=build/logs/checkstyle.xml --runtime-set ignore_warnings_on_exit true -p .", "security": "security-checker security:check composer.lock", "diff": [ "git diff origin/master... -- > diff.txt", @@ -63,9 +63,9 @@ "check": [ "mkdir -p build/logs", "@lint", - "@smell", + "@snill", "@security", - "@unit", + "@test", "@diff" ] }, From 856335d8f1a6db213d3e08443e692fe47eaf724c Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 16:38:45 -0600 Subject: [PATCH 11/13] Update build.xml --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index c99c31f6c..1b92dd925 100644 --- a/build.xml +++ b/build.xml @@ -46,7 +46,7 @@ - + From 1f6e59c4b35705fd568a49079dbe30013e687b09 Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 16:45:11 -0600 Subject: [PATCH 12/13] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 84dfa34db..4c31abba9 100644 --- a/composer.json +++ b/composer.json @@ -63,7 +63,7 @@ "check": [ "mkdir -p build/logs", "@lint", - "@snill", + "@sniff", "@security", "@test", "@diff" From 886f09590a86dd52bfc5992a66425a98c5632bbe Mon Sep 17 00:00:00 2001 From: "Paul L. McNeely" Date: Sat, 16 Feb 2019 17:09:44 -0600 Subject: [PATCH 13/13] Changed diff to Coverage Added temporary fix for errors being generated in php 7 from phpunit 5 html coverage. --- composer.json | 7 +- tests/compatibility/File.php | 569 +++++++++++++++++++++++++++++++++++ 2 files changed, 573 insertions(+), 3 deletions(-) create mode 100644 tests/compatibility/File.php diff --git a/composer.json b/composer.json index 4c31abba9..dd5aa6832 100644 --- a/composer.json +++ b/composer.json @@ -49,14 +49,15 @@ "tests/models", "tests/routers", "tests/views" - ] + ], + "files": ["tests/compatibility/File.php"] }, "scripts": { "test": "phpunit -c . tests/", "lint": "parallel-lint --exclude vendor .", "sniff": "phpcs --standard=tools/codesniffer/JoindInPSR2/ruleset.xml --ignore=**/config.php,**/database.php,vendor,tools,tests/bootstrap.php --extensions=php --report-checkstyle=build/logs/checkstyle.xml --runtime-set ignore_warnings_on_exit true -p .", "security": "security-checker security:check composer.lock", - "diff": [ + "coverage": [ "git diff origin/master... -- > diff.txt", "diffFilter --phpunit diff.txt build/logs/clover.xml 80" ], @@ -66,7 +67,7 @@ "@sniff", "@security", "@test", - "@diff" + "@coverage" ] }, "config" : { diff --git a/tests/compatibility/File.php b/tests/compatibility/File.php new file mode 100644 index 000000000..2aa752aaf --- /dev/null +++ b/tests/compatibility/File.php @@ -0,0 +1,569 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage\Report\Html; + +use SebastianBergmann\CodeCoverage\Node\File as FileNode; +use SebastianBergmann\CodeCoverage\Util; + +/** + * This is a temporary fix for phpunit 5 coverage running in php 7 + * This will throw an exception requiring removal when phpunit is upgraded + * past 6.1.1 that has the fix. + */ + +if (PHP_MAJOR_VERSION >= 7) { + if (class_exists('\PHPUnit\Runner\Version')) { + $version = new \PHPUnit\Runner\Version(); + $version = explode(".", $version->id()); + if ($version[0] >= 6 && $version[1] > 1) { + throw new \Exception( + "This file is no longer needed with version of php and phpunit, please remove from composer.json" + ); + } + } +} + +/** + * Renders a file node. + */ +class File extends Renderer +{ + /** + * @var int + */ + private $htmlspecialcharsFlags; + + /** + * Constructor. + * + * @param string $templatePath + * @param string $generator + * @param string $date + * @param int $lowUpperBound + * @param int $highLowerBound + */ + public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound) + { + parent::__construct( + $templatePath, + $generator, + $date, + $lowUpperBound, + $highLowerBound + ); + + $this->htmlspecialcharsFlags = ENT_COMPAT; + + $this->htmlspecialcharsFlags = $this->htmlspecialcharsFlags | ENT_HTML401 | ENT_SUBSTITUTE; + } + + /** + * @param FileNode $node + * @param string $file + */ + public function render(FileNode $node, $file) + { + $template = new \Text_Template($this->templatePath . 'file.html', '{{', '}}'); + + $template->setVar( + [ + 'items' => $this->renderItems($node), + 'lines' => $this->renderSource($node) + ] + ); + + $this->setCommonTemplateVariables($template, $node); + + $template->renderTo($file); + } + + /** + * @param FileNode $node + * + * @return string + */ + protected function renderItems(FileNode $node) + { + $template = new \Text_Template($this->templatePath . 'file_item.html', '{{', '}}'); + + $methodItemTemplate = new \Text_Template( + $this->templatePath . 'method_item.html', + '{{', + '}}' + ); + + $items = $this->renderItemTemplate( + $template, + [ + 'name' => 'Total', + 'numClasses' => $node->getNumClassesAndTraits(), + 'numTestedClasses' => $node->getNumTestedClassesAndTraits(), + 'numMethods' => $node->getNumMethods(), + 'numTestedMethods' => $node->getNumTestedMethods(), + 'linesExecutedPercent' => $node->getLineExecutedPercent(false), + 'linesExecutedPercentAsString' => $node->getLineExecutedPercent(), + 'numExecutedLines' => $node->getNumExecutedLines(), + 'numExecutableLines' => $node->getNumExecutableLines(), + 'testedMethodsPercent' => $node->getTestedMethodsPercent(false), + 'testedMethodsPercentAsString' => $node->getTestedMethodsPercent(), + 'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false), + 'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent(), + 'crap' => 'CRAP' + ] + ); + + $items .= $this->renderFunctionItems( + $node->getFunctions(), + $methodItemTemplate + ); + + $items .= $this->renderTraitOrClassItems( + $node->getTraits(), + $template, + $methodItemTemplate + ); + + $items .= $this->renderTraitOrClassItems( + $node->getClasses(), + $template, + $methodItemTemplate + ); + + return $items; + } + + /** + * @param array $items + * @param \Text_Template $template + * @param \Text_Template $methodItemTemplate + * + * @return string + */ + protected function renderTraitOrClassItems(array $items, \Text_Template $template, \Text_Template $methodItemTemplate) + { + if (empty($items)) { + return ''; + } + + $buffer = ''; + + foreach ($items as $name => $item) { + $numMethods = count($item['methods']); + $numTestedMethods = 0; + + foreach ($item['methods'] as $method) { + if ($method['executedLines'] == $method['executableLines']) { + $numTestedMethods++; + } + } + + 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' => $numClasses, + 'numTestedClasses' => $numTestedClasses, + 'numMethods' => $numMethods, + 'numTestedMethods' => $numTestedMethods, + 'linesExecutedPercent' => Util::percent( + $item['executedLines'], + $item['executableLines'], + false + ), + 'linesExecutedPercentAsString' => $linesExecutedPercentAsString, + 'numExecutedLines' => $item['executedLines'], + 'numExecutableLines' => $item['executableLines'], + 'testedMethodsPercent' => Util::percent( + $numTestedMethods, + $numMethods, + false + ), + 'testedMethodsPercentAsString' => Util::percent( + $numTestedMethods, + $numMethods, + true + ), + 'testedClassesPercent' => Util::percent( + $numTestedMethods == $numMethods ? 1 : 0, + 1, + false + ), + 'testedClassesPercentAsString' => Util::percent( + $numTestedMethods == $numMethods ? 1 : 0, + 1, + true + ), + 'crap' => $item['crap'] + ] + ); + + foreach ($item['methods'] as $method) { + $buffer .= $this->renderFunctionOrMethodItem( + $methodItemTemplate, + $method, + ' ' + ); + } + } + + return $buffer; + } + + /** + * @param array $functions + * @param \Text_Template $template + * + * @return string + */ + protected function renderFunctionItems(array $functions, \Text_Template $template) + { + if (empty($functions)) { + return ''; + } + + $buffer = ''; + + foreach ($functions as $function) { + $buffer .= $this->renderFunctionOrMethodItem( + $template, + $function + ); + } + + return $buffer; + } + + /** + * @param \Text_Template $template + * + * @return string + */ + protected function renderFunctionOrMethodItem(\Text_Template $template, array $item, $indent = '') + { + $numTestedItems = $item['executedLines'] == $item['executableLines'] ? 1 : 0; + + return $this->renderItemTemplate( + $template, + [ + 'name' => sprintf( + '%s%s', + $indent, + $item['startLine'], + htmlspecialchars($item['signature']), + isset($item['functionName']) ? $item['functionName'] : $item['methodName'] + ), + 'numMethods' => 1, + 'numTestedMethods' => $numTestedItems, + 'linesExecutedPercent' => Util::percent( + $item['executedLines'], + $item['executableLines'], + false + ), + 'linesExecutedPercentAsString' => Util::percent( + $item['executedLines'], + $item['executableLines'], + true + ), + 'numExecutedLines' => $item['executedLines'], + 'numExecutableLines' => $item['executableLines'], + 'testedMethodsPercent' => Util::percent( + $numTestedItems, + 1, + false + ), + 'testedMethodsPercentAsString' => Util::percent( + $numTestedItems, + 1, + true + ), + 'crap' => $item['crap'] + ] + ); + } + + /** + * @param FileNode $node + * + * @return string + */ + protected function renderSource(FileNode $node) + { + $coverageData = $node->getCoverageData(); + $testData = $node->getTestData(); + $codeLines = $this->loadFile($node->getPath()); + $lines = ''; + $i = 1; + + foreach ($codeLines as $line) { + $trClass = ''; + $popoverContent = ''; + $popoverTitle = ''; + + if (array_key_exists($i, $coverageData)) { + $numTests = ($coverageData[$i] ? count($coverageData[$i]) : 0); + + if ($coverageData[$i] === null) { + $trClass = ' class="warning"'; + } elseif ($numTests == 0) { + $trClass = ' class="danger"'; + } else { + $lineCss = 'covered-by-large-tests'; + $popoverContent = '
    '; + + if ($numTests > 1) { + $popoverTitle = $numTests . ' tests cover line ' . $i; + } else { + $popoverTitle = '1 test covers line ' . $i; + } + + foreach ($coverageData[$i] as $test) { + if ($lineCss == 'covered-by-large-tests' && $testData[$test]['size'] == 'medium') { + $lineCss = 'covered-by-medium-tests'; + } elseif ($testData[$test]['size'] == 'small') { + $lineCss = 'covered-by-small-tests'; + } + + switch ($testData[$test]['status']) { + case 0: + 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( + '%s', + $testCSS, + htmlspecialchars($test) + ); + } + + $popoverContent .= '
'; + $trClass = ' class="' . $lineCss . ' popin"'; + } + } + + if (!empty($popoverTitle)) { + $popover = sprintf( + ' data-title="%s" data-content="%s" data-placement="bottom" data-html="true"', + $popoverTitle, + htmlspecialchars($popoverContent) + ); + } else { + $popover = ''; + } + + $lines .= sprintf( + ' %s' . "\n", + $trClass, + $popover, + $i, + $i, + $i, + $line + ); + + $i++; + } + + return $lines; + } + + /** + * @param string $file + * + * @return array + */ + protected function loadFile($file) + { + $buffer = file_get_contents($file); + $tokens = token_get_all($buffer); + $result = ['']; + $i = 0; + $stringFlag = false; + $fileEndsWithNewLine = substr($buffer, -1) == "\n"; + + unset($buffer); + + foreach ($tokens as $j => $token) { + if (is_string($token)) { + if ($token === '"' && $tokens[$j - 1] !== '\\') { + $result[$i] .= sprintf( + '%s', + htmlspecialchars($token) + ); + + $stringFlag = !$stringFlag; + } else { + $result[$i] .= sprintf( + '%s', + htmlspecialchars($token) + ); + } + + continue; + } + + list($token, $value) = $token; + + $value = str_replace( + ["\t", ' '], + ['    ', ' '], + htmlspecialchars($value, $this->htmlspecialcharsFlags) + ); + + if ($value === "\n") { + $result[++$i] = ''; + } else { + $lines = explode("\n", $value); + + foreach ($lines as $jj => $line) { + $line = trim($line); + + if ($line !== '') { + if ($stringFlag) { + $colour = 'string'; + } else { + switch ($token) { + case T_INLINE_HTML: + $colour = 'html'; + break; + + case T_COMMENT: + case T_DOC_COMMENT: + $colour = 'comment'; + break; + + case T_ABSTRACT: + case T_ARRAY: + case T_AS: + case T_BREAK: + case T_CALLABLE: + case T_CASE: + case T_CATCH: + case T_CLASS: + case T_CLONE: + case T_CONTINUE: + case T_DEFAULT: + case T_ECHO: + case T_ELSE: + case T_ELSEIF: + case T_EMPTY: + case T_ENDDECLARE: + case T_ENDFOR: + case T_ENDFOREACH: + case T_ENDIF: + case T_ENDSWITCH: + case T_ENDWHILE: + case T_EXIT: + case T_EXTENDS: + case T_FINAL: + case T_FINALLY: + case T_FOREACH: + case T_FUNCTION: + case T_GLOBAL: + case T_IF: + case T_IMPLEMENTS: + case T_INCLUDE: + case T_INCLUDE_ONCE: + case T_INSTANCEOF: + case T_INSTEADOF: + case T_INTERFACE: + case T_ISSET: + case T_LOGICAL_AND: + case T_LOGICAL_OR: + case T_LOGICAL_XOR: + case T_NAMESPACE: + case T_NEW: + case T_PRIVATE: + case T_PROTECTED: + case T_PUBLIC: + case T_REQUIRE: + case T_REQUIRE_ONCE: + case T_RETURN: + case T_STATIC: + case T_THROW: + case T_TRAIT: + case T_TRY: + case T_UNSET: + case T_USE: + case T_VAR: + case T_WHILE: + case T_YIELD: + $colour = 'keyword'; + break; + + default: + $colour = 'default'; + } + } + + $result[$i] .= sprintf( + '%s', + $colour, + $line + ); + } + + if (isset($lines[$jj + 1])) { + $result[++$i] = ''; + } + } + } + } + + if ($fileEndsWithNewLine) { + unset($result[count($result)-1]); + } + + return $result; + } +}