diff --git a/.github/flake.lock b/.github/flake.lock new file mode 100644 index 0000000..df035e8 --- /dev/null +++ b/.github/flake.lock @@ -0,0 +1,25 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1673606088, + "narHash": "sha256-wdYD41UwNwPhTdMaG0AIe7fE1bAdyHe6bB4HLUqUvck=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "37b97ae3dd714de9a17923d004a2c5b5543dfa6d", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/.github/flake.nix b/.github/flake.nix new file mode 100644 index 0000000..9bb3e54 --- /dev/null +++ b/.github/flake.nix @@ -0,0 +1,43 @@ +{ + description = "A php test environment flake"; + + outputs = { self, nixpkgs }: + let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages."${system}"; + + phpEnv = phpPackage: (phpPackage.buildEnv { + extensions = { enabled, all }: (enabled ++ [ all.xdebug ]); + extraConfig = '' + memory_limit=-1 + xdebug.mode=coverage + '' + + pkgs.lib.optionalString (pkgs.lib.versionOlder phpPackage.version "8.0") '' + xdebug.coverage_enable=1 + ''; + }); + + phpVersions = [ + "php80" + "php81" + "php82" + ]; + in + { + packages."${system}" = builtins.listToAttrs + (builtins.map + (name: + { + name = "env-${name}"; + value = pkgs.symlinkJoin { + name = "env-${name}"; + paths = [ + (phpEnv pkgs."${name}") + (phpEnv pkgs."${name}").packages.composer + ]; + }; + } + ) + phpVersions); + }; +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..71a96f8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,33 @@ +name: Simple Nix Flakes powered php ci. + +on: [push, pull_request] + +jobs: + ci: + + runs-on: ubuntu-latest + + strategy: + matrix: + php: [php80, php81, php82] + + steps: + - uses: actions/checkout@v2 + with: + # Nix Flakes doesn't work on shallow clones + fetch-depth: 0 + + - uses: cachix/install-nix-action@v18 + + - name: Cache Composer dependencies + uses: actions/cache@v2 + with: + path: /home/runner/.cache/composer + key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - run: | + rm -fr vendor + nix shell .github#env-${{ matrix.php }} --command composer ci-prepare + nix shell .github#env-${{ matrix.php }} --command composer ci diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 4391de5..0000000 --- a/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -language: php -matrix: - include: - - php: 7.1 - env: DEPENDENCIES=lowest - - php: 7.1 - env: DEPENDENCIES=highest - - php: 7.2 - env: DEPENDENCIES=lowest - - php: 7.2 - env: DEPENDENCIES=highest - -before_script: - - phpenv config-rm xdebug.ini - - if [ "${DEPENDENCIES}" = "lowest" ]; then composer update --prefer-lowest --prefer-dist --no-interaction --no-progress; fi; - - if [ "${DEPENDENCIES}" = "highest" ]; then composer update --prefer-dist --no-interaction --no-progress; fi; - -script: - - vendor/bin/phpcs -s --standard=MO4 src/PHPCodeBrowser/ - - vendor/bin/phpstan analyse --no-progress --level=1 src/PHPCodeBrowser/ - - vendor/bin/phpunit diff --git a/bin/phpcb b/bin/phpcb index 7ee5aa1..8ae4b8d 100755 --- a/bin/phpcb +++ b/bin/phpcb @@ -53,5 +53,5 @@ if (file_exists(__DIR__ . '/../../../autoload.php')) { include_once __DIR__ . '/../vendor/autoload.php'; } -$app = new PHPCodeBrowser\Application('PHP_CodeBrowser', '1.1.4'); +$app = new PHPCodeBrowser\Application('PHP_CodeBrowser', '4.0.1'); $app->run(); diff --git a/box.json b/box.json index c720920..7a7d53a 100644 --- a/box.json +++ b/box.json @@ -1,12 +1,10 @@ { "alias": "phpcb.phar", - "chmod": "0755", "compactors": [ - "Herrera\\Box\\Compactor\\Json", - "Herrera\\Box\\Compactor\\Php" + "KevinGH\\Box\\Compactor\\Json", + "KevinGH\\Box\\Compactor\\Php" ], "directories": ["src", "templates"], - "extract": true, "files": [ "LICENSE", "vendor/autoload.php" @@ -15,17 +13,12 @@ { "name": "*.php", "path": [ - "composer", - "herrera-io/json", - "herrera-io/phar-update", "monolog/monolog", - "myclabs/deep-copy", - "phpseclib/phpseclib", "phpunit/php-file-iterator", "psr/log", "symfony/console", - "symfony/polyfill-mbstring", - "symfony/polyfill-ctype" + "symfony/service-contracts", + "symfony/string" ], "notPath": [ "Tests", @@ -37,7 +30,5 @@ ], "git-commit": "git-commit", "git-version": "git-version", - "main": "bin/phpcb", - "output": "phpcb-@git-version@.phar", - "stub": true + "output": "phpcb-4.0.1.phar" } diff --git a/composer.json b/composer.json index 4518c6b..8369bbd 100644 --- a/composer.json +++ b/composer.json @@ -15,21 +15,26 @@ "role": "developer" } ], + "minimum-stability": "dev", + "prefer-stable": true, "require": { - "php": "^7.1", + "php": "^8.0", "ext-dom": "*", - "monolog/monolog": "~1.7", - "phpunit/php-file-iterator": "~2.0", - "symfony/console": "~2.1|~3.0|~4.0|~5.0" + "monolog/monolog": "~1.7||~2.0||~3.0", + "phpunit/php-file-iterator": "~2.0||^3.0", + "symfony/console": "~3.4||~4.0||~5.0||~6.0" }, "require-dev": { - "kherge/box": "~2.7", - "mayflower/mo4-coding-standard": "^3.0", + "humbug/box": "^3.13", + "mayflower/mo4-coding-standard": "^9.0", "phploc/phploc": "*", - "phpmd/phpmd": "1.5.*|~2.6", - "phpstan/phpstan": "^0.10.5", - "phpunit/phpunit": "~7.3", - "sebastian/phpcpd": "*" + "phpmd/phpmd": "1.5.*||~2.6", + "phpstan/phpstan": "^1.0", + "phpunit/phpunit": "^9.5", + "sebastian/phpcpd": "*", + "phpstan/phpstan-strict-rules": "^1.5", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan-phpunit": "^1.3" }, "autoload": { "psr-0": {"PHPCodeBrowser\\": "src/"} @@ -39,9 +44,9 @@ "demo": [ "@clean", "php -c php.ini vendor/bin/phpunit -c phpunit.xml.dist", - "phpcpd -q --log-pmd=build/logs/pmd-cpd.xml src || true", + "phpcpd --log-pmd=build/logs/pmd-cpd.xml src || true", "phpmd src xml cleancode,codesize,controversial,design,naming,unusedcode --reportfile build/logs/pmd.xml || true", - "phpcs -q --standard=MO4 --report-checkstyle=build/logs/checkstyle.xml src || true", + "phpcs -q --report-checkstyle=build/logs/checkstyle.xml || true", "@browser" ], "nope": [ @@ -50,13 +55,22 @@ "phploc -q --log-xml=build/logs/phploc.xml src || true", "@browser" ], - "travis": [ - "phpcs -s --standard=MO4 src/PHPCodeBrowser/", - "phpstan analyse --no-progress --level=1 src/PHPCodeBrowser/", + "ci-prepare": [ + "composer update --prefer-dist --no-interaction --no-progress" + ], + "ci": [ + "phpcs -s", + "phpstan analyse --no-progress", "phpunit" ], "clean": "rm -rf build/logs/* build/code-browser", "browser": "bin/phpcb -l build/logs -o build/code-browser -s src", - "phar": "php -d phar.readonly=0 vendor/bin/box build" + "phar": "php vendor/bin/box compile" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true, + "phpstan/extension-installer": true + } } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..e8a5c50 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,9 @@ + + + The coding standard. + + src + + + + diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..6b5b9b5 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,7 @@ +parameters: + level: 5 + paths: + - %rootDir%/../../../src/PHPCodeBrowser + +includes: + - phpstan_baseline.neon diff --git a/phpstan_baseline.neon b/phpstan_baseline.neon new file mode 100644 index 0000000..f45121d --- /dev/null +++ b/phpstan_baseline.neon @@ -0,0 +1,81 @@ +parameters: + ignoreErrors: + - + message: "#^Only booleans are allowed in a negated boolean, array\\ given\\.$#" + count: 1 + path: src/PHPCodeBrowser/CLIController.php + + - + message: "#^Only booleans are allowed in a negated boolean, mixed given\\.$#" + count: 4 + path: src/PHPCodeBrowser/Command/RunCommand.php + + - + message: "#^Only booleans are allowed in an if condition, mixed given\\.$#" + count: 1 + path: src/PHPCodeBrowser/Command/RunCommand.php + + - + message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" + count: 2 + path: src/PHPCodeBrowser/Helper/IOHelper.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, DOMNode\\|null given\\.$#" + count: 1 + path: src/PHPCodeBrowser/IssueXML.php + + - + message: "#^Only booleans are allowed in a negated boolean, string given\\.$#" + count: 1 + path: src/PHPCodeBrowser/Plugins/ErrorCRAP.php + + - + message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" + count: 1 + path: src/PHPCodeBrowser/View/ViewAbstract.php + + - + message: "#^Only booleans are allowed in a negated boolean, string given\\.$#" + count: 2 + path: src/PHPCodeBrowser/View/ViewAbstract.php + + - + message: "#^Comparison operation \"\\<\" between 1 and int\\<2, max\\> is always true\\.$#" + count: 1 + path: src/PHPCodeBrowser/View/ViewReview.php + + - + message: "#^Comparison operation \"\\<\\=\" between int\\<32, 255\\> and 55295 is always true\\.$#" + count: 1 + path: src/PHPCodeBrowser/View/ViewReview.php + + - + message: "#^Comparison operation \"\\>\\=\" between int\\<0, 8\\>\\|int\\<11, 12\\>\\|int\\<14, 31\\> and 57344 is always false\\.$#" + count: 1 + path: src/PHPCodeBrowser/View/ViewReview.php + + - + message: "#^Comparison operation \"\\>\\=\" between int\\<0, 8\\>\\|int\\<11, 12\\>\\|int\\<14, 31\\> and 65536 is always false\\.$#" + count: 1 + path: src/PHPCodeBrowser/View/ViewReview.php + + - + message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" + count: 1 + path: src/PHPCodeBrowser/View/ViewReview.php + + - + message: "#^Only booleans are allowed in a negated boolean, array given\\.$#" + count: 1 + path: src/PHPCodeBrowser/View/ViewReview.php + + - + message: "#^Result of && is always false\\.$#" + count: 2 + path: src/PHPCodeBrowser/View/ViewReview.php + + - + message: "#^Switch condition type \\(int\\<0, max\\>\\) does not match case condition 1 \\< \\$lineErrorCount \\(bool\\)\\.$#" + count: 1 + path: src/PHPCodeBrowser/View/ViewReview.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 422b86d..676ec30 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,4 @@ - @@ -16,19 +17,21 @@ - - + + ./src - - ./src/PHPCodeBrowser/Tests - - - + + + ./src/PHPCodeBrowser/Tests + + + + + - - - + + diff --git a/src/PHPCodeBrowser/AbstractPlugin.php b/src/PHPCodeBrowser/AbstractPlugin.php index 7ded64f..89c3ad9 100644 --- a/src/PHPCodeBrowser/AbstractPlugin.php +++ b/src/PHPCodeBrowser/AbstractPlugin.php @@ -1,4 +1,5 @@ - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.0 + * @since File available since 0.1.0 */ + namespace PHPCodeBrowser; -use \DOMElement; -use \DOMNode; -use \DOMNodeList; +use DOMElement; +use DOMNodeList; /** * AbstractPlugin * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ abstract class AbstractPlugin { @@ -84,7 +85,7 @@ abstract class AbstractPlugin * * @var string */ - public $pluginName; + protected $pluginName; /** * The IssueXML object @@ -152,11 +153,12 @@ public function __construct(IssueXML $issueXml, array $options = []) /** * Gets a list of File objects, including their issues. * - * @return File[] List of files with issues. + * @return array List of files with issues. */ public function getFileList(): array { $files = []; + foreach ($this->getFilesWithIssues() as $name) { $files[] = new File($name, $this->getIssuesByFile($name)); } @@ -175,8 +177,9 @@ public function getFileList(): array public function getIssuesByFile(string $filename): array { $issues = []; + foreach ($this->getIssueNodes($filename) as $issueNode) { - $issues = array_merge( + $issues = \array_merge( $issues, $this->mapIssues($issueNode, $filename) ); @@ -194,13 +197,18 @@ public function getFilesWithIssues(): array { $fileNames = []; $issueNodes = $this->issueXml->query( - sprintf('/*/%s/file[@name]', $this->pluginName) + \sprintf('/*/%s/file[@name]', $this->pluginName) ); + foreach ($issueNodes as $node) { + if (!($node instanceof DOMElement)) { + continue; + } + $fileNames[] = $node->getAttribute('name'); } - return array_unique($fileNames); + return \array_unique($fileNames); } /** @@ -209,18 +217,20 @@ public function getFilesWithIssues(): array * This method provides a default behaviour an can be overloaded to * implement special behavior for other plugins. * - * @param DOMNode $element The XML plugin node with its errors - * @param string $filename Name of the file to return issues for. + * @param \DOMNode $element The XML plugin node with its errors + * @param string $filename Name of the file to return issues for. * - * @return array array of issue objects. + * @return array */ - public function mapIssues(DOMNode $element, string $filename): array + public function mapIssues(\DOMNode $element, string $filename): array { $errorList = []; + foreach ($element->childNodes as $child) { if (!($child instanceof DOMElement)) { continue; } + $errorList[] = new Issue( $filename, $this->getLineStart($child), @@ -244,12 +254,13 @@ public function mapIssues(DOMNode $element, string $filename): array protected function getIssueNodes(string $filename): DOMNodeList { return $this->issueXml->query( - sprintf('/*/%s/file[@name="%s"]', $this->pluginName, $filename) + \sprintf('/*/%s/file[@name="%s"]', $this->pluginName, $filename) ); } /** * Default method for retrieving the first line of an issue. + * * @see self::mapIssues * * @param DOMElement $element @@ -263,6 +274,7 @@ protected function getLineStart(DOMElement $element): int /** * Default method for retrieving the last line of an issue. + * * @see self::mapIssues * * @param DOMElement $element @@ -276,6 +288,7 @@ protected function getLineEnd(DOMElement $element): int /** * Default method for retrieving the source of an issue. + * * @see self::mapIssues * * @return string @@ -287,6 +300,7 @@ protected function getSource(): string /** * Default method for retrieving the description of an issue. + * * @see self::mapIssues * * @param DOMElement $element @@ -295,11 +309,12 @@ protected function getSource(): string */ protected function getDescription(DOMElement $element): string { - return htmlentities($element->getAttribute($this->descriptionAttr)); + return \htmlentities($element->getAttribute($this->descriptionAttr), ENT_COMPAT); } /** * Default method for retrieving the severity of an issue. + * * @see self::mapIssues * * @param DOMElement $element @@ -308,6 +323,6 @@ protected function getDescription(DOMElement $element): string */ protected function getSeverity(DOMElement $element): string { - return htmlentities($element->getAttribute($this->severityAttr)); + return \htmlentities($element->getAttribute($this->severityAttr), ENT_COMPAT); } } diff --git a/src/PHPCodeBrowser/Application.php b/src/PHPCodeBrowser/Application.php index 6b22cb6..ad448f4 100644 --- a/src/PHPCodeBrowser/Application.php +++ b/src/PHPCodeBrowser/Application.php @@ -1,4 +1,5 @@ + * @author Robin Gloster * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 1.1 + * @since File available since 1.1 */ + namespace PHPCodeBrowser; use PHPCodeBrowser\Command\RunCommand; @@ -82,6 +84,8 @@ public function getDefinition(): InputDefinition * * @param InputInterface $input * + * @phpcs:disable SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter + * * @return string The command name */ protected function getCommandName(InputInterface $input): string @@ -92,7 +96,7 @@ protected function getCommandName(InputInterface $input): string /** * Gets the default commands that should always be available. * - * @return Command[] An array of default Command instances + * @return array An array of default Command instances */ protected function getDefaultCommands(): array { diff --git a/src/PHPCodeBrowser/CLIController.php b/src/PHPCodeBrowser/CLIController.php index 6ba8b24..ed909b8 100644 --- a/src/PHPCodeBrowser/CLIController.php +++ b/src/PHPCodeBrowser/CLIController.php @@ -1,4 +1,5 @@ - * @author Simon Kohlmeyer + * @author Elger Thiele + * @author Simon Kohlmeyer * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.0 + * @since File available since 0.1.0 */ namespace PHPCodeBrowser; @@ -59,31 +60,24 @@ use PHPCodeBrowser\View\ViewReview; use SebastianBergmann\FileIterator\Factory as FileIteratorFactory; -if (!defined('PHPCB_ROOT_DIR')) { - define('PHPCB_ROOT_DIR', \dirname(__FILE__, 2).'/'); -} -if (!defined('PHPCB_TEMPLATE_DIR')) { - define('PHPCB_TEMPLATE_DIR', \dirname(__FILE__, 3).'/templates'); -} - /** * CLIController * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Michel Hartmann - * @author Simon Kohlmeyer + * @author Elger Thiele + * @author Michel Hartmann + * @author Simon Kohlmeyer * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class CLIController { @@ -192,9 +186,11 @@ public function __construct(?string $logPath, ?array $projectSource, string $htm $this->htmlOutputDir = $htmlOutputDir; $this->excludeExpressions = $excludeExpressions; $this->excludePatterns = $excludePatterns; + foreach ($pluginOptions as $plugin => $options) { $this->pluginOptions["Error{$plugin}"] = $options; } + $this->ioHelper = $ioHelper; $this->debugLog = $debugLog; $this->registeredPlugins = []; @@ -233,16 +229,17 @@ public function addErrorPlugins($classNames): void public function run(): void { // clear and create output directory - if (is_dir($this->htmlOutputDir)) { + if (\is_dir($this->htmlOutputDir)) { $this->ioHelper->deleteDirectory($this->htmlOutputDir); - } elseif (is_file($this->htmlOutputDir)) { + } elseif (\is_file($this->htmlOutputDir)) { $this->ioHelper->deleteFile($this->htmlOutputDir); } + $this->ioHelper->createDirectory($this->htmlOutputDir); // init needed classes $viewReview = new ViewReview( - PHPCB_TEMPLATE_DIR, + \getenv('PHPCB_TEMPLATE_DIR') ? \getenv('PHPCB_TEMPLATE_DIR') : \dirname(__FILE__, 3).'/templates', $this->htmlOutputDir, $this->ioHelper, $this->phpSuffixes @@ -258,7 +255,8 @@ public function run(): void // conversion of XML file cc to cb format foreach ($this->registeredPlugins as $className) { - $plugin = array_key_exists($className, $this->pluginOptions) ? new $className( + /** @var AbstractPlugin $plugin */ + $plugin = \array_key_exists($className, $this->pluginOptions) ? new $className( $issueXml, $this->pluginOptions[$className] ) : new $className($issueXml); @@ -268,10 +266,10 @@ public function run(): void if (null !== $this->projectSource) { foreach ($this->projectSource as $source) { - if (is_dir($source)) { + if (\is_dir($source)) { $factory = new FileIteratorFactory(); - $suffixes = array_merge( + $suffixes = \array_merge( $this->phpSuffixes, ['php', 'js', 'css', 'html'] ); @@ -288,11 +286,11 @@ public function run(): void } } - array_walk( + \array_walk( $this->excludeExpressions, [$sourceHandler, 'excludeMatchingPCRE'] ); - array_walk( + \array_walk( $this->excludePatterns, [$sourceHandler, 'excludeMatchingPattern'] ); diff --git a/src/PHPCodeBrowser/Command/RunCommand.php b/src/PHPCodeBrowser/Command/RunCommand.php index 5aaf04c..abb1008 100644 --- a/src/PHPCodeBrowser/Command/RunCommand.php +++ b/src/PHPCodeBrowser/Command/RunCommand.php @@ -1,4 +1,5 @@ + * @author Robin Gloster * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 1.1 + * @since File available since 1.1 */ namespace PHPCodeBrowser\Command; @@ -79,14 +80,13 @@ class RunCommand extends Command */ protected function configure(): void { - $plugins = array_map( - function ($class) { - return '"'.substr($class, \strlen('Error')).'"'; + $plugins = \array_map( + static function ($class) { + return '"'.\substr($class, \strlen('Error')).'"'; }, $this->getAvailablePlugins() ); - $this->setName('phpcb') ->setHelp( 'A Code browser for PHP files with syntax highlighting and colored error-sections found by quality assurance tools like PHPUnit, PHPMD or PHP_CodeSniffer.' @@ -139,7 +139,7 @@ function ($class) { 'disablePlugin', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, - 'Disable single Plugins. Can be one of '.implode(', ', $plugins) + 'Disable single Plugins. Can be one of '.\implode(', ', $plugins) )->addOption( 'crapThreshold', null, @@ -154,9 +154,11 @@ function ($class) { * @param InputInterface $input An InputInterface instance * @param OutputInterface $output * - * @return int|null null or 0 if everything went fine, or an error code + * @phpcs:disable SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter + * + * @return int 0 if everything went fine, or an error code */ - protected function execute(InputInterface $input, OutputInterface $output): ?int + protected function execute(InputInterface $input, OutputInterface $output): int { $this->checkErrors($input); @@ -182,7 +184,7 @@ protected function execute(InputInterface $input, OutputInterface $output): ?int ['CRAP' => ['threshold' => $input->getOption('crapThreshold')]], new IOHelper(), $logger, - array_merge($extensions, ['php']), + \array_merge($extensions, ['php']), (bool) $input->getOption('excludeOK') ); @@ -193,7 +195,7 @@ protected function execute(InputInterface $input, OutputInterface $output): ?int try { $controller->run(); } catch (Exception $e) { - error_log( + \error_log( <<getMessage()} @@ -205,7 +207,6 @@ protected function execute(InputInterface $input, OutputInterface $output): ?int return 0; } - /** * @param InputInterface $input * @@ -217,15 +218,15 @@ protected function checkErrors(InputInterface $input): void if (!$input->getOption('source')) { throw new \InvalidArgumentException('Missing log or source argument.'); } - } elseif (!file_exists((string) $input->getOption('log'))) { + } elseif (!\file_exists((string) $input->getOption('log'))) { throw new \InvalidArgumentException('Log directory does not exist.'); - } elseif (!is_dir((string) $input->getOption('log'))) { + } elseif (!\is_dir((string) $input->getOption('log'))) { throw new \InvalidArgumentException('Log argument must be a directory, a file was given.'); } if ($input->getOption('source')) { foreach ($input->getOption('source') as $s) { - if (!file_exists($s)) { + if (!\file_exists($s)) { throw new \InvalidArgumentException("Source '{$s}' does not exist"); } } @@ -235,7 +236,7 @@ protected function checkErrors(InputInterface $input): void throw new \InvalidArgumentException('Missing output argument.'); } - if (file_exists((string) $input->getOption('output')) && !is_dir((string) $input->getOption('output'))) { + if (\file_exists((string) $input->getOption('output')) && !\is_dir((string) $input->getOption('output'))) { throw new \InvalidArgumentException('Output argument must be a directory, a file was given.'); } } @@ -245,7 +246,7 @@ protected function checkErrors(InputInterface $input): void * * Currently hard-coded. * - * @return string[] Class names of error plugins + * @return array Class names of error plugins */ protected function getAvailablePlugins(): array { @@ -267,14 +268,15 @@ protected function getAvailablePlugins(): array */ protected function disablePlugins(array $disabledPlugins, array $plugins): array { - $disabledPlugins = array_map( + $disabledPlugins = \array_map( 'strtolower', $disabledPlugins ); foreach ($plugins as $pluginKey => $plugin) { - $name = substr($plugin, \strlen('Error')); - if (!\in_array(strtolower($name), $disabledPlugins)) { + $name = \substr($plugin, \strlen('Error')); + + if (!\in_array(\strtolower($name), $disabledPlugins, true)) { continue; } @@ -295,13 +297,15 @@ protected function disablePlugins(array $disabledPlugins, array $plugins): array */ protected function convertIgnores(array $ignored, array $excludePCRE): array { - $dirSep = preg_quote(DIRECTORY_SEPARATOR, '/'); + $dirSep = \preg_quote(DIRECTORY_SEPARATOR, '/'); + foreach ($ignored as $ignore) { - $ig = realpath($ignore); + $ig = \realpath($ignore); + if (!$ig) { - error_log("[Warning] {$ignore} does not exists"); + \error_log("[Warning] {$ignore} does not exists"); } else { - $ig = preg_quote($ig, '/'); + $ig = \preg_quote($ig, '/'); $excludePCRE[] = "/^{$ig}({$dirSep}|$)/"; } } @@ -318,9 +322,9 @@ protected function convertIgnores(array $ignored, array $excludePCRE): array */ private function handleBackwardCompatibility(array $option): array { - if (\count($option) === 1 && strpos($option[0], ',') !== false) { - $option = explode(',', $option[0]); - error_log('Usage of comma-separated options is deprecated, specify them one-by-one.', E_DEPRECATED); + if (\count($option) === 1 && \str_contains($option[0], ',')) { + $option = \explode(',', $option[0]); + \error_log('Usage of comma-separated options is deprecated, specify them one-by-one.', E_DEPRECATED); } return $option; diff --git a/src/PHPCodeBrowser/File.php b/src/PHPCodeBrowser/File.php index f2fb9fe..46da426 100644 --- a/src/PHPCodeBrowser/File.php +++ b/src/PHPCodeBrowser/File.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.2.0 + * @since File available since 0.2.0 */ namespace PHPCodeBrowser; @@ -61,19 +62,19 @@ * An object of this class represents a single source file * with it's issues, if any. * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Simon Kohlmeyer + * @author Simon Kohlmeyer * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://github.com/mayflowergmbh + * @link http://github.com/mayflowergmbh * - * @since Class available since 0.2.0 + * @since Class available since 0.2.0 */ class File { @@ -87,20 +88,20 @@ class File /** * Issues associated with this file. * - * @var Issue[] + * @var array */ private $issues; /** * Default constructor. * - * @param string $name The name of the file. - * @param Issue[] $issues + * @param string $name The name of the file. + * @param array $issues */ public function __construct(string $name, array $issues = []) { if (DIRECTORY_SEPARATOR !== '/') { - $name = str_replace('/', DIRECTORY_SEPARATOR, $name); + $name = \str_replace('/', DIRECTORY_SEPARATOR, $name); } $this->name = $name; @@ -116,18 +117,19 @@ public function __construct(string $name, array $issues = []) */ public function addIssue(Issue $issue): void { - if ($issue->fileName !== $this->name) { + if ($issue->getFileName() !== $this->name) { throw new \InvalidArgumentException( 'Tried to add issue to wrong file.' ); } + $this->issues[] = $issue; } /** * Gets an array containing the issues for this file. * - * @return Issue[] The issues. + * @return array The issues. */ public function getIssues(): array { @@ -151,7 +153,7 @@ public function name(): string */ public function basename(): string { - return basename($this->name); + return \basename($this->name); } /** @@ -182,8 +184,9 @@ public function getIssueCount(): int public function getErrorCount(): int { $count = 0; + foreach ($this->issues as $issue) { - if (strcasecmp($issue->severity, 'error') !== 0) { + if (\strcasecmp($issue->getSeverity(), 'error') !== 0) { continue; } @@ -217,17 +220,18 @@ public function mergeWith(File $file): void 'Tried to merge different files' ); } - $this->issues = array_merge($this->issues, $file->issues); + + $this->issues = \array_merge($this->issues, $file->issues); } /** * Sorts an array of Files. Key value association will be preserved. * - * @param File[] $files The files to sort. + * @param array $files The files to sort. */ public static function sort(array &$files): void { - uasort($files, 'PHPCodeBrowser\File::internalSort'); + \uasort($files, 'PHPCodeBrowser\File::internalSort'); } /** @@ -246,16 +250,16 @@ protected static function internalSort(File $first, File $second): int $prefix = IOHelper::getCommonPathPrefix([$firstName, $secondName]); $prefixLength = \strlen($prefix); - $firstSubName = substr($firstName, $prefixLength); - $secondSubName = substr($secondName, $prefixLength); + $firstSubName = \substr($firstName, $prefixLength); + $secondSubName = \substr($secondName, $prefixLength); - $firstIsInSubDir = (substr_count($firstSubName, DIRECTORY_SEPARATOR) !== 0); - $secondIsInSubDir = (substr_count($secondSubName, DIRECTORY_SEPARATOR) !== 0); + $firstIsInSubDir = (\str_contains($firstSubName, DIRECTORY_SEPARATOR)); + $secondIsInSubDir = (\str_contains($secondSubName, DIRECTORY_SEPARATOR)); if ($firstIsInSubDir) { - return $secondIsInSubDir ? strcmp($firstSubName, $secondSubName) : -1; + return $secondIsInSubDir ? \strcmp($firstSubName, $secondSubName) : -1; } - return $secondIsInSubDir ? 1 : strcmp($firstSubName, $secondSubName); + return $secondIsInSubDir ? 1 : \strcmp($firstSubName, $secondSubName); } } diff --git a/src/PHPCodeBrowser/Helper/IOHelper.php b/src/PHPCodeBrowser/Helper/IOHelper.php index 98e463b..a18c0ad 100644 --- a/src/PHPCodeBrowser/Helper/IOHelper.php +++ b/src/PHPCodeBrowser/Helper/IOHelper.php @@ -1,4 +1,5 @@ + * @author Elger Thiele * * @copyright 2007-2009 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.0 + * @since File available since 0.1.0 */ - namespace PHPCodeBrowser\Helper; use DirectoryIterator; @@ -62,24 +62,23 @@ * Input output helper class provides several methods for writing and * reading files or directories. * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Christopher Weckerle + * @author Elger Thiele + * @author Christopher Weckerle * * @copyright 2007-2009 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class IOHelper { - /** * Creates a file with given name and content. * If directories to file do not exists they will be created. @@ -91,13 +90,14 @@ class IOHelper */ public function createFile(string $fileName, string $fileContent): void { - $realName = basename($fileName); - $path = substr($fileName, 0, - 1 * (\strlen($realName))); + $realName = \basename($fileName); + $path = \substr($fileName, 0, - 1 * (\strlen($realName))); if (!empty($path)) { $this->createDirectory($path); } - file_put_contents(realpath($path).'/'.$realName, $fileContent); + + \file_put_contents(\realpath($path).'/'.$realName, $fileContent); } /** @@ -111,11 +111,11 @@ public function createFile(string $fileName, string $fileContent): void */ public function deleteFile(string $fileName): void { - if (!file_exists($fileName)) { + if (!\file_exists($fileName)) { return; } - unlink($fileName); + \unlink($fileName); } /** @@ -131,11 +131,11 @@ public function deleteFile(string $fileName): void */ public function copyFile(string $fileSource, string $sourceFolder): void { - if (!file_exists($fileSource)) { - throw new \Exception(sprintf('File %s does not exist!', $fileSource)); + if (!\file_exists($fileSource)) { + throw new \Exception(\sprintf('File %s does not exist!', $fileSource)); } - $fileName = basename($fileSource); + $fileName = \basename($fileSource); $this->createFile( $sourceFolder.'/'.$fileName, $this->loadFile($fileSource) @@ -153,11 +153,11 @@ public function copyFile(string $fileSource, string $sourceFolder): void */ public function loadFile(string $fileName): string { - if (!file_exists($fileName)) { - throw new \Exception(sprintf('File %s does not exist!', $fileName)); + if (!\file_exists($fileName)) { + throw new \Exception(\sprintf('File %s does not exist!', $fileName)); } - return trim(file_get_contents($fileName)); + return \trim(\file_get_contents($fileName)); } /** @@ -170,14 +170,14 @@ public function loadFile(string $fileName): string */ public function createDirectory(string $target): void { - $target = rtrim($target, DIRECTORY_SEPARATOR); + $target = \rtrim($target, DIRECTORY_SEPARATOR); - if (is_dir($target)) { + if (\is_dir($target)) { return; } - if (!mkdir($target, 0777, true) && !is_dir($target)) { - throw new \RuntimeException(sprintf('Directory "%s" was not created', $target)); + if (!\mkdir($target, 0777, true) && !\is_dir($target)) { + throw new \RuntimeException(\sprintf('Directory "%s" was not created', $target)); } } @@ -194,8 +194,9 @@ public function createDirectory(string $target): void public function deleteDirectory(string $source): void { $iterator = new DirectoryIterator($source); + while ($iterator->valid()) { - $src = realpath($source.'/'.$iterator->current()); + $src = \realpath($source.'/'.$iterator->current()); // delete file if ($iterator->isFile()) { @@ -209,28 +210,29 @@ public function deleteDirectory(string $source): void $iterator->next(); } + unset($iterator); // delete the source root folder as well - if (!rmdir($source)) { - throw new \Exception(sprintf('Could not delete directory %s', $source)); + if (!\rmdir($source)) { + throw new \Exception(\sprintf('Could not delete directory %s', $source)); } } /** * Copy a directory within all its items. * - * @param string $source The source directory - * @param string $target The target to create - * @param array $exclude List of files / folders that should not be copyed + * @param string $source The source directory + * @param string $target The target to create * * @return void */ - public function copyDirectory(string $source, string $target, array $exclude = []): void + public function copyDirectory(string $source, string $target): void { // first check for target itself $this->createDirectory($target); $iterator = new DirectoryIterator($source); + while ($iterator->valid()) { $item = $iterator->current(); @@ -242,19 +244,20 @@ public function copyDirectory(string $source, string $target, array $exclude = [ // create folder recursive if (!$iterator->isDot() && $iterator->isDir() - && !\in_array($item, $exclude) ) { $this->copyDirectory( $source.'/'.$item, $target.'/'.$item ); } + $iterator->next(); } } /** * Get the prefix all paths in an array of paths have in common. + * * @param array $fileNames * * @return string @@ -264,12 +267,14 @@ public static function getCommonPathPrefix(array $fileNames): string if (empty($fileNames)) { return '/'; } - $prefix = \dirname(array_shift($fileNames)); + + $prefix = \dirname(\array_shift($fileNames)); + foreach ($fileNames as $filename) { $prefix = self::getCurrentCommonPathPrefix($prefix, $filename); } - if (substr($prefix, -1, 1) !== DIRECTORY_SEPARATOR) { + if (\substr($prefix, -1, 1) !== DIRECTORY_SEPARATOR) { $prefix .= DIRECTORY_SEPARATOR; } @@ -278,6 +283,7 @@ public static function getCommonPathPrefix(array $fileNames): string /** * Get the part of currentPrefix that currentPrefix and path have in common. + * * @param string $currentPrefix * @param string $path * @@ -285,11 +291,11 @@ public static function getCommonPathPrefix(array $fileNames): string */ protected static function getCurrentCommonPathPrefix(string $currentPrefix, string $path): string { - if (0 === strpos($path, $currentPrefix.DIRECTORY_SEPARATOR) + if (\str_starts_with($path, $currentPrefix.DIRECTORY_SEPARATOR) || DIRECTORY_SEPARATOR === $currentPrefix || '' === $currentPrefix || '.' === $currentPrefix - || preg_match('/^[A-Z]\:\\\\$/', $currentPrefix) === 1 + || \preg_match('/^[A-Z]\:\\\\$/', $currentPrefix) === 1 ) { return $currentPrefix; } diff --git a/src/PHPCodeBrowser/Issue.php b/src/PHPCodeBrowser/Issue.php index 9bd01ab..7d58329 100644 --- a/src/PHPCodeBrowser/Issue.php +++ b/src/PHPCodeBrowser/Issue.php @@ -1,4 +1,5 @@ - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.2 + * @since File available since 0.1.2 */ namespace PHPCodeBrowser; @@ -60,20 +61,20 @@ * Object Model for issues. * This object is used for working with common issues types. * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://github.com/mayflowergmbh + * @link http://github.com/mayflowergmbh * - * @since Class available since 0.1.2 + * @since Class available since 0.1.2 */ class Issue { @@ -82,21 +83,21 @@ class Issue * * @var string */ - public $fileName; + private $fileName; /** * Starting Line of the Issue. * * @var int */ - public $lineStart; + private $lineStart; /** * Ending Line of the Issue. * * @var int */ - public $lineEnd; + private $lineEnd; /** * Name of the Plugin that found the Issue. @@ -104,21 +105,21 @@ class Issue * * @var string */ - public $foundBy; + private $foundBy; /** * Issue Description text. * * @var string */ - public $description; + private $description; /** * Severity of the issue. * * @var string */ - public $severity; + private $severity; /** * Default constructor @@ -139,4 +140,52 @@ public function __construct(string $fileName, int $lineStart, int $lineEnd, stri $this->description = $description; $this->severity = $severity; } + + /** + * @return string + */ + public function getFileName(): string + { + return $this->fileName; + } + + /** + * @return int + */ + public function getLineStart(): int + { + return $this->lineStart; + } + + /** + * @return int + */ + public function getLineEnd(): int + { + return $this->lineEnd; + } + + /** + * @return string + */ + public function getFoundBy(): string + { + return $this->foundBy; + } + + /** + * @return string + */ + public function getDescription(): string + { + return $this->description; + } + + /** + * @return string + */ + public function getSeverity(): string + { + return $this->severity; + } } diff --git a/src/PHPCodeBrowser/IssueXML.php b/src/PHPCodeBrowser/IssueXML.php index b246315..1911f1b 100644 --- a/src/PHPCodeBrowser/IssueXML.php +++ b/src/PHPCodeBrowser/IssueXML.php @@ -1,4 +1,5 @@ - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.0 + * @since File available since 0.1.0 */ namespace PHPCodeBrowser; -use \DOMDocument; -use \DOMNode; -use \DOMNodeList; -use \DOMXPath; +use DOMDocument; +use DOMDocumentType; +use DOMNode; +use DOMNodeList; +use DOMXPath; use SebastianBergmann\FileIterator\Factory as FileIteratorFactory; /** @@ -68,20 +70,20 @@ * It is used to merge issue XML files and execute plugins * against it to retrieve the issues from them. * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class IssueXML extends DOMDocument { @@ -92,21 +94,6 @@ class IssueXML extends DOMDocument */ protected $xpath; - /** - * Do not preserve white spaces. - * @see DOMDocument - * - * @var bool - */ - public $preserveWhiteSpace = false; - - /** - * Provide nice output. - * - * @var bool - */ - public $formatOutput = true; - /** * Default constructor * @@ -119,6 +106,8 @@ public function __construct(string $version = '1.0', string $encoding = 'UTF-8') $this->appendChild( $this->createElement('codebrowser') ); + $this->preserveWhiteSpace = false; + $this->formatOutput = true; } /** @@ -135,21 +124,23 @@ public function addDirectory(string $directory): IssueXML $iterator = $factory->getFileIterator($directory, 'xml'); foreach ($iterator as $current) { - $realFileName = realpath($current); + $realFileName = \realpath($current); $xml = new DOMDocument('1.0', 'UTF-8'); $xml->validateOnParse = true; - if (@$xml->load(realpath($current))) { + + if (@$xml->load(\realpath($current))) { $this->addXMLFile($xml); } else { - error_log( + \error_log( "[Warning] Could not read file '{$realFileName}'. ".'Make sure it contains valid xml.' ); } + unset($xml); } if (!$this->documentElement->hasChildNodes()) { - error_log("[Warning] No valid log files found in '{$directory}'"); + \error_log("[Warning] No valid log files found in '{$directory}'"); } return $this; @@ -165,18 +156,23 @@ public function addDirectory(string $directory): IssueXML public function addXMLFile(DOMDocument $domDocument): void { foreach ($domDocument->childNodes as $node) { + if ($node instanceof DOMDocumentType) { + continue; + } + $this->documentElement->appendChild($this->importNode($node, true)); } } /** * Perform a XPath-Query on the document. + * * @see DOMXPath::query * - * @param string $expression Xpath expression to query for. - * @param DOMNode $contextNode Node to use as context (optional) + * @param string $expression Xpath expression to query for. + * @param DOMNode|null $contextNode Node to use as context (optional) * - * @return DOMNodeList List of all matching nodes. + * @return DOMNodeList List of all matching nodes. */ public function query(string $expression, ?DOMNode $contextNode = null): DOMNodeList { diff --git a/src/PHPCodeBrowser/Plugins/ErrorCPD.php b/src/PHPCodeBrowser/Plugins/ErrorCPD.php index b4f6160..6aa4a3a 100644 --- a/src/PHPCodeBrowser/Plugins/ErrorCPD.php +++ b/src/PHPCodeBrowser/Plugins/ErrorCPD.php @@ -1,4 +1,5 @@ - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.0 + * @since File available since 0.1.0 */ namespace PHPCodeBrowser\Plugins; use DOMElement; -use DOMNode; use DOMNodeList; use PHPCodeBrowser\AbstractPlugin; use PHPCodeBrowser\Issue; @@ -63,38 +63,39 @@ /** * ErrorCPD * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class ErrorCPD extends AbstractPlugin { /** * @var string $pluginName */ - public $pluginName = 'pmd-cpd'; + protected $pluginName = 'pmd-cpd'; /** * Mapper method for this plugin. * - * @param DOMNode $element The XML plugin node with its errors - * @param string $filename + * @param \DOMNode $element The XML plugin node with its errors + * @param string $filename * - * @return array + * @return array */ - public function mapIssues(DOMNode $element, string $filename): array + public function mapIssues(\DOMNode $element, string $filename): array { + /** @var DOMElement $parentNode */ $parentNode = $element->parentNode; $files = $this->issueXml->query( 'file[@path="'.$filename.'"]', @@ -103,15 +104,18 @@ public function mapIssues(DOMNode $element, string $filename): array $lineCount = (int) $parentNode->getAttribute('lines'); $result = []; + foreach ($files as $file) { + if (!($file instanceof DOMElement)) { + continue; + } + $result[] = new Issue( $file->getAttribute('path'), (int) $file->getAttribute('line'), (int) $file->getAttribute('line') + $lineCount, 'Duplication', - htmlentities( - $this->getCpdDescription($parentNode->childNodes, $file) - ), + \htmlentities($this->getCpdDescription($parentNode->childNodes, $file), ENT_COMPAT), 'notice' ); } @@ -130,10 +134,14 @@ public function getFilesWithIssues(): array ); foreach ($nodes as $node) { + if (!($node instanceof DOMElement)) { + continue; + } + $fileNames[] = $node->getAttribute('path'); } - return array_unique($fileNames); + return \array_unique($fileNames); } /** @@ -155,13 +163,14 @@ protected function getIssueNodes(string $filename): DOMNodeList * to find duplicates. * * @param DOMNodeList $allNodes - * @param DOMNode $currentNode + * @param DOMElement $currentNode * * @return string */ - protected function getCpdDescription(DOMNodeList $allNodes, DOMNode $currentNode): string + protected function getCpdDescription(DOMNodeList $allNodes, DOMElement $currentNode): string { $source = []; + foreach ($allNodes as $node) { if (!($node instanceof DOMElement) || $node->isSameNode($currentNode) @@ -169,13 +178,13 @@ protected function getCpdDescription(DOMNodeList $allNodes, DOMNode $currentNode continue; } - $source[] = sprintf( + $source[] = \sprintf( '%s (%d)', $node->getAttribute('path'), $node->getAttribute('line') ); } - return "Copy paste from:\n".implode("\n", $source); + return "Copy paste from:\n".\implode("\n", $source); } } diff --git a/src/PHPCodeBrowser/Plugins/ErrorCRAP.php b/src/PHPCodeBrowser/Plugins/ErrorCRAP.php index 128df5b..a85b3c8 100644 --- a/src/PHPCodeBrowser/Plugins/ErrorCRAP.php +++ b/src/PHPCodeBrowser/Plugins/ErrorCRAP.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.2.0 + * @since File available since 0.2.0 */ namespace PHPCodeBrowser\Plugins; use DOMElement; -use DOMNode; use DOMNodeList; use PHPCodeBrowser\AbstractPlugin; use PHPCodeBrowser\Issue; @@ -62,19 +62,19 @@ /** * ErrorCRAP * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Simon Kohlmeyer + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.2.0 + * @since Class available since 0.2.0 */ class ErrorCRAP extends AbstractPlugin { @@ -84,7 +84,7 @@ class ErrorCRAP extends AbstractPlugin * * @var string */ - public $pluginName = 'coverage'; + protected $pluginName = 'coverage'; /** * Name of the attribute that holds the number of the first line @@ -97,12 +97,14 @@ class ErrorCRAP extends AbstractPlugin /** * Name of the attribute that holds the number of the last line * of the issue. + * * @var string */ protected $lineEndAttr = 'num'; /** * Default string to use as source for issue. + * * @var string */ protected $source = 'CRAP'; @@ -113,12 +115,12 @@ class ErrorCRAP extends AbstractPlugin * This method provides a default behaviour an can be overloaded to * implement special behavior for other plugins. * - * @param DOMNode $element The XML plugin node with its errors - * @param string $filename Name of the file to return issues for. + * @param \DOMNode $element The XML plugin node with its errors + * @param string $filename Name of the file to return issues for. * - * @return array array of issue objects. + * @return array */ - public function mapIssues(DOMNode $element, string $filename): array + public function mapIssues(\DOMNode $element, string $filename): array { $errorList = []; @@ -131,11 +133,12 @@ public function mapIssues(DOMNode $element, string $filename): array } $crap = $child->getAttribute('crap'); + if (!$crap) { continue; } - if (array_key_exists('threshold', $this->options) + if (\array_key_exists('threshold', $this->options) && $crap <= $this->options['threshold'] ) { continue; @@ -167,10 +170,14 @@ public function getFilesWithIssues(): array ); foreach ($issueNodes as $node) { + if (!($node instanceof DOMElement)) { + continue; + } + $fileNames[] = $node->getAttribute('name'); } - return array_unique($fileNames); + return \array_unique($fileNames); } /** diff --git a/src/PHPCodeBrowser/Plugins/ErrorCheckstyle.php b/src/PHPCodeBrowser/Plugins/ErrorCheckstyle.php index 0909939..4ed5d45 100644 --- a/src/PHPCodeBrowser/Plugins/ErrorCheckstyle.php +++ b/src/PHPCodeBrowser/Plugins/ErrorCheckstyle.php @@ -1,4 +1,5 @@ - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.0 + * @since File available since 0.1.0 */ namespace PHPCodeBrowser\Plugins; @@ -59,34 +60,36 @@ /** * ErrorCheckstyle * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Christopher Weckerle - * @author Michel Hartmann + * @author Elger Thiele + * @author Christopher Weckerle + * @author Michel Hartmann * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class ErrorCheckstyle extends AbstractPlugin { /** * Name of this plugin. * Used to read issues from XML. + * * @var string */ - public $pluginName = 'checkstyle'; + protected $pluginName = 'checkstyle'; /** * Name of the attribute that holds the number of the first line * of the issue. + * * @var string */ protected $lineStartAttr = 'line'; @@ -94,24 +97,28 @@ class ErrorCheckstyle extends AbstractPlugin /** * Name of the attribute that holds the number of the last line * of the issue. + * * @var string */ protected $lineEndAttr = 'line'; /** * Name of the attribute that holds message of the issue. + * * @var string */ protected $descriptionAttr = 'message'; /** * Name of the attribute that holds severity of the issue. + * * @var string */ protected $severityAttr = 'severity'; /** * Default string to use as source for issue. + * * @var string */ protected $source = 'Checkstyle'; diff --git a/src/PHPCodeBrowser/Plugins/ErrorCoverage.php b/src/PHPCodeBrowser/Plugins/ErrorCoverage.php index d979a3d..f417d45 100644 --- a/src/PHPCodeBrowser/Plugins/ErrorCoverage.php +++ b/src/PHPCodeBrowser/Plugins/ErrorCoverage.php @@ -1,4 +1,5 @@ - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.0 + * @since File available since 0.1.0 */ namespace PHPCodeBrowser\Plugins; @@ -63,33 +64,35 @@ /** * ErrorCoverage * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class ErrorCoverage extends AbstractPlugin { /** * Name of this plugin. * Used to read issues from XML. + * * @var string */ - public $pluginName = 'coverage'; + protected $pluginName = 'coverage'; /** * Name of the attribute that holds the number of the first line * of the issue. + * * @var string */ protected $lineStartAttr = 'num'; @@ -97,12 +100,14 @@ class ErrorCoverage extends AbstractPlugin /** * Name of the attribute that holds the number of the last line * of the issue. + * * @var string */ protected $lineEndAttr = 'num'; /** * Default string to use as source for issue. + * * @var string */ protected $source = 'Coverage'; @@ -116,7 +121,7 @@ class ErrorCoverage extends AbstractPlugin * @param DOMNode $element The XML plugin node with its errors * @param string $filename Name of the file to return issues for. * - * @return array array of issue objects. + * @return array */ public function mapIssues(DOMNode $element, string $filename): array { @@ -126,6 +131,7 @@ public function mapIssues(DOMNode $element, string $filename): array $childCount = $children->length; for ($next = 0; $next < $childCount; ++$next) { + /** @var DOMElement $child */ $child = $children->item($next); if (!$this->representsUncoveredLOC($child)) { @@ -136,12 +142,16 @@ public function mapIssues(DOMNode $element, string $filename): array $end = $begin; ++$next; + while ($next < $childCount) { $child = $children->item($next); + if (!$child instanceof DOMElement) { ++$next; + continue; } + if (!$this->representsUncoveredLOC($child)) { break; } @@ -176,10 +186,14 @@ public function getFilesWithIssues(): array ); foreach ($issueNodes as $node) { + if (!($node instanceof DOMElement)) { + continue; + } + $fileNames[] = $node->getAttribute('name'); } - return array_unique($fileNames); + return \array_unique($fileNames); } /** diff --git a/src/PHPCodeBrowser/Plugins/ErrorPMD.php b/src/PHPCodeBrowser/Plugins/ErrorPMD.php index 82f0dd8..dbb645e 100644 --- a/src/PHPCodeBrowser/Plugins/ErrorPMD.php +++ b/src/PHPCodeBrowser/Plugins/ErrorPMD.php @@ -1,4 +1,5 @@ - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.0 + * @since File available since 0.1.0 */ namespace PHPCodeBrowser\Plugins; @@ -58,46 +59,51 @@ /** * ErrorPMD * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Christopher Weckerle - * @author Michel Hartmann + * @author Elger Thiele + * @author Christopher Weckerle + * @author Michel Hartmann * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class ErrorPMD extends AbstractPlugin { /** * Name of this plugin. * Used to read issues from XML. + * * @var string */ - public $pluginName = 'pmd'; + protected $pluginName = 'pmd'; /** * Name of the attribute that holds the number of the first line * of the issue. + * * @var string */ protected $lineStartAttr = 'beginline'; + /** * Name of the attribute that holds the number of the last line * of the issue. + * * @var string */ protected $lineEndAttr = 'endline'; /** * Default string to use as source for issue. + * * @var string */ protected $source = 'PMD'; @@ -108,6 +114,8 @@ class ErrorPMD extends AbstractPlugin * * @param DOMElement $element * + * @phpcs:disable SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter + * * @return string */ protected function getSeverity(DOMElement $element): string @@ -125,10 +133,10 @@ protected function getSeverity(DOMElement $element): string */ protected function getDescription(DOMElement $element): string { - return str_replace( + return \str_replace( ' ', '', - htmlentities($element->textContent) + \htmlentities($element->textContent, ENT_COMPAT) ); } } diff --git a/src/PHPCodeBrowser/Plugins/ErrorPadawan.php b/src/PHPCodeBrowser/Plugins/ErrorPadawan.php index 88b534e..ad83969 100644 --- a/src/PHPCodeBrowser/Plugins/ErrorPadawan.php +++ b/src/PHPCodeBrowser/Plugins/ErrorPadawan.php @@ -1,4 +1,5 @@ - * @author Michel Hartmann + * @author Elger Thiele + * @author Michel Hartmann * - * @copyright 2007-2009 Mayflower GmbH + * @copyright 2007-2009 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.0 + * @since File available since 0.1.0 */ namespace PHPCodeBrowser\Plugins; @@ -59,21 +60,21 @@ /** * ErrorPadawan * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Christopher Weckerle - * @author Michel Hartmann + * @author Elger Thiele + * @author Christopher Weckerle + * @author Michel Hartmann * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class ErrorPadawan extends AbstractPlugin { @@ -82,11 +83,12 @@ class ErrorPadawan extends AbstractPlugin * * @var string */ - public $pluginName = 'padawan'; + protected $pluginName = 'padawan'; /** * Name of the attribute that holds the number of the first line * of the issue. + * * @var string */ protected $lineStartAttr = 'line'; @@ -94,24 +96,28 @@ class ErrorPadawan extends AbstractPlugin /** * Name of the attribute that holds the number of the last line * of the issue. + * * @var string */ protected $lineEndAttr = 'line'; /** * Name of the attribute that holds message of the issue. + * * @var string */ protected $descriptionAttr = 'message'; /** * Name of the attribute that holds severity of the issue. + * * @var string */ protected $severityAttr = 'severity'; /** * Default string to use as source for issue. + * * @var string */ protected $source = 'Padawan'; diff --git a/src/PHPCodeBrowser/SourceHandler.php b/src/PHPCodeBrowser/SourceHandler.php index b628df7..faf0187 100644 --- a/src/PHPCodeBrowser/SourceHandler.php +++ b/src/PHPCodeBrowser/SourceHandler.php @@ -1,4 +1,5 @@ - * @author Michel Hartmann - * @author Simon Kohlmeyer + * @author Elger Thiele + * @author Michel Hartmann + * @author Simon Kohlmeyer * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.2.0 + * @since File available since 0.2.0 */ namespace PHPCodeBrowser; @@ -66,29 +67,29 @@ * This class manages lists of source files and their issues. * For providing these lists the prior generated IssueXML is parsed. * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Christopher Weckerle - * @author Michel Hartmann - * @author Simon Kohlmeyer + * @author Elger Thiele + * @author Christopher Weckerle + * @author Michel Hartmann + * @author Simon Kohlmeyer * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.2.0 + * @since Class available since 0.2.0 */ class SourceHandler { /** * Files to be included in the report * - * @var File[] + * @var array */ protected $files = []; @@ -108,7 +109,7 @@ class SourceHandler public function __construct(Logger $debugLog, array $plugins = []) { $this->debugLog = $debugLog; - array_walk($plugins, [$this, 'addPlugin']); + \array_walk($plugins, [$this, 'addPlugin']); } /** @@ -119,7 +120,7 @@ public function __construct(Logger $debugLog, array $plugins = []) public function addPlugin(AbstractPlugin $plugin): void { foreach ($plugin->getFileList() as $file) { - if (array_key_exists($file->name(), $this->files)) { + if (\array_key_exists($file->name(), $this->files)) { $this->files[$file->name()]->mergeWith($file); } else { $this->files[$file->name()] = $file; @@ -130,7 +131,7 @@ public function addPlugin(AbstractPlugin $plugin): void /** * Add source files to the list. * - * @param SplFileInfo[]|string[]|\AppendIterator $files The files to add + * @param array|\AppendIterator $files The files to add */ public function addSourceFiles($files): void { @@ -150,9 +151,9 @@ public function addSourceFile($file): void { if (\is_string($file)) { $filename = $file; - $file = realpath($file); + $file = \realpath($file); } else { - $filename = $file->getPathName(); + $filename = $file->getPathname(); $file = $file->getRealPath(); } @@ -160,7 +161,7 @@ public function addSourceFile($file): void throw new Exception("{$filename} is no regular file"); } - if (array_key_exists($file, $this->files)) { + if (\array_key_exists($file, $this->files)) { return; } @@ -174,13 +175,13 @@ public function addSourceFile($file): void */ public function getCommonPathPrefix(): string { - return IOHelper::getCommonPathPrefix(array_keys($this->files)); + return IOHelper::getCommonPathPrefix(\array_keys($this->files)); } /** * Returns a sorted array of the files that should be in the report. * - * @return File[] + * @return array */ public function getFiles(): array { @@ -196,7 +197,7 @@ public function getFiles(): array */ public function getFilesWithIssues(): array { - return array_keys($this->files); + return \array_keys($this->files); } /** @@ -208,8 +209,8 @@ public function getFilesWithIssues(): array */ public function excludeMatchingPCRE(string $expr): void { - foreach (array_keys($this->files) as $filename) { - if (!preg_match($expr, $filename)) { + foreach (\array_keys($this->files) as $filename) { + if (!\preg_match($expr, $filename)) { continue; } @@ -230,8 +231,8 @@ public function excludeMatchingPCRE(string $expr): void */ public function excludeMatchingPattern(string $pattern): void { - foreach (array_keys($this->files) as $filename) { - if (!fnmatch($pattern, $filename)) { + foreach (\array_keys($this->files) as $filename) { + if (!\fnmatch($pattern, $filename)) { continue; } diff --git a/src/PHPCodeBrowser/Tests/AbstractTestCase.php b/src/PHPCodeBrowser/Tests/AbstractTestCase.php index abea4db..98ab92d 100644 --- a/src/PHPCodeBrowser/Tests/AbstractTestCase.php +++ b/src/PHPCodeBrowser/Tests/AbstractTestCase.php @@ -1,4 +1,5 @@ + * @author Elger Thiele * - * @copyright 2007-2009 Mayflower GmbH + * @copyright 2007-2009 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.0 + * @since File available since 0.1.0 */ namespace PHPCodeBrowser\Tests; +use PHPUnit\Framework\TestCase; + /** * AbstractTests * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele + * @author Elger Thiele * - * @copyright 2007-2009 Mayflower GmbH + * @copyright 2007-2009 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ -class AbstractTestCase extends \PHPUnit\Framework\TestCase +class AbstractTestCase extends TestCase { /** * PHP_CodeBrowser test output dir @@ -115,31 +118,32 @@ protected function setUp(): void parent::setUp(); if (!\defined('PHPCB_SOURCE_DIR')) { - \define('PHPCB_SOURCE_DIR', realpath(__DIR__.'/../')); + \define('PHPCB_SOURCE_DIR', \realpath(__DIR__.'/../')); } if (!\defined('PHPCB_TEST_DIR')) { \define( 'PHPCB_TEST_DIR', - realpath(PHPCB_SOURCE_DIR).DIRECTORY_SEPARATOR.'Tests'.DIRECTORY_SEPARATOR.'testData' + \realpath(PHPCB_SOURCE_DIR).DIRECTORY_SEPARATOR.'Tests'.DIRECTORY_SEPARATOR.'testData' ); } + if (!\defined('PHPCB_TEST_LOGS')) { \define('PHPCB_TEST_LOGS', PHPCB_TEST_DIR.'/logs'); } self::$xmlBasic = PHPCB_TEST_LOGS.'/basic.xml'; - self::$phpcbSourceDir = realpath(__DIR__.'/Fixtures'); + self::$phpcbSourceDir = \realpath(__DIR__.'/Fixtures'); self::$testOutputDir = PHPCB_TEST_DIR.DIRECTORY_SEPARATOR.'output'; - if (is_dir(self::$testOutputDir)) { + if (\is_dir(self::$testOutputDir)) { $this->cleanUp(self::$testOutputDir); - rmdir(self::$testOutputDir); + \rmdir(self::$testOutputDir); } - mkdir(self::$testOutputDir); + \mkdir(self::$testOutputDir); } /** @@ -153,7 +157,7 @@ protected function tearDown(): void parent::tearDown(); $this->cleanUp(self::$testOutputDir); - rmdir(self::$testOutputDir); + \rmdir(self::$testOutputDir); } /** @@ -163,7 +167,7 @@ protected function tearDown(): void */ protected function getSerializedErrors(): array { - return unserialize(file_get_contents(self::$serializedErrors)); + return \unserialize(\file_get_contents(self::$serializedErrors)); } /** @@ -176,19 +180,22 @@ protected function getSerializedErrors(): array protected function cleanUp(string $dir): void { $iterator = new \DirectoryIterator($dir); + while ($iterator->valid()) { // delete file if ($iterator->isFile()) { - unlink($dir.'/'.$iterator->current()); + \unlink($dir.'/'.$iterator->current()); } // delete folder recursive if (!$iterator->isDot() && $iterator->isDir()) { $this->cleanUp($dir.'/'.$iterator->current()); - rmdir($dir.'/'.$iterator->current()); + \rmdir($dir.'/'.$iterator->current()); } + $iterator->next(); } + unset($iterator); } } diff --git a/src/PHPCodeBrowser/Tests/ApplicationTest.php b/src/PHPCodeBrowser/Tests/ApplicationTest.php index a54fb78..591e1a2 100644 --- a/src/PHPCodeBrowser/Tests/ApplicationTest.php +++ b/src/PHPCodeBrowser/Tests/ApplicationTest.php @@ -4,12 +4,13 @@ use PHPCodeBrowser\Application; use PHPCodeBrowser\Command\RunCommand; +use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Input\InputArgument; /** * Class ApplicationTest */ -class ApplicationTest extends \PHPUnit\Framework\TestCase +class ApplicationTest extends TestCase { /** * @var Application @@ -29,7 +30,7 @@ protected function setUp(): void */ public function testCommand(): void { - $this->assertInstanceOf(RunCommand::class, $this->application->get('phpcb')); + static::assertInstanceOf(RunCommand::class, $this->application->get('phpcb')); } /** @@ -39,6 +40,6 @@ public function testGetDefinitionClearsArguments(): void { $this->application->getDefinition()->setArguments([new InputArgument('foo')]); - $this->assertEquals(0, $this->application->getDefinition()->getArgumentCount()); + static::assertEquals(0, $this->application->getDefinition()->getArgumentCount()); } } diff --git a/src/PHPCodeBrowser/Tests/CLIControllerTest.php b/src/PHPCodeBrowser/Tests/CLIControllerTest.php index 26320e8..32f2ea9 100644 --- a/src/PHPCodeBrowser/Tests/CLIControllerTest.php +++ b/src/PHPCodeBrowser/Tests/CLIControllerTest.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class CLIControllerTest extends AbstractTestCase { /** * @var CLIController $controller */ - public $controller; + private $controller; /** * Create and configure a CLIController instance. @@ -140,15 +140,15 @@ public function testRunCreatesFilesAndDirs(): void */ public function testRunCleansExistingOutputDir(): void { - mkdir(self::$testOutputDir.'/clear-directory'); - touch(self::$testOutputDir.'/clear-file'); - touch(self::$testOutputDir.'/clear-directory/clear-file'); + \mkdir(self::$testOutputDir.'/clear-directory'); + \touch(self::$testOutputDir.'/clear-file'); + \touch(self::$testOutputDir.'/clear-directory/clear-file'); $this->controller->run(); $this->assertOutputIsPresent(); - $this->assertDirectoryNotExists(self::$testOutputDir.'/clear-directory'); - $this->assertFileNotExists(self::$testOutputDir.'/clear-file'); + static::assertDirectoryDoesNotExist(self::$testOutputDir.'/clear-directory'); + static::assertFileDoesNotExist(self::$testOutputDir.'/clear-file'); } /** @@ -156,8 +156,8 @@ public function testRunCleansExistingOutputDir(): void */ public function testRunCleansExistingOutputFile(): void { - rmdir(self::$testOutputDir); - touch(self::$testOutputDir); + \rmdir(self::$testOutputDir); + \touch(self::$testOutputDir); $this->controller->run(); @@ -183,11 +183,11 @@ public function testRunExcludingAllSources(): void $this->controller->run(); - $this->assertFileExists(self::$testOutputDir.'/index.html'); - $this->assertFileNotExists(self::$testOutputDir.'/Bad.php.html'); - $this->assertFileNotExists(self::$testOutputDir.'/Good.php.html'); - $this->assertDirectoryNotExists(self::$testOutputDir.'/css'); - $this->assertDirectoryNotExists(self::$testOutputDir.'/img'); - $this->assertDirectoryNotExists(self::$testOutputDir.'/js'); + static::assertFileExists(self::$testOutputDir.'/index.html'); + static::assertFileDoesNotExist(self::$testOutputDir.'/Bad.php.html'); + static::assertFileDoesNotExist(self::$testOutputDir.'/Good.php.html'); + static::assertDirectoryDoesNotExist(self::$testOutputDir.'/css'); + static::assertDirectoryDoesNotExist(self::$testOutputDir.'/img'); + static::assertDirectoryDoesNotExist(self::$testOutputDir.'/js'); } } diff --git a/src/PHPCodeBrowser/Tests/FileTest.php b/src/PHPCodeBrowser/Tests/FileTest.php index a3a68ae..d0768f5 100644 --- a/src/PHPCodeBrowser/Tests/FileTest.php +++ b/src/PHPCodeBrowser/Tests/FileTest.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class FileTest extends AbstractTestCase { @@ -83,31 +84,24 @@ class FileTest extends AbstractTestCase /** * Some issues to work with. * - * @var Issue[] + * @var array */ protected $issues; /** - * Constructor. Initialize some values. + * (non-PHPDoc) + * + * @see AbstractTests#setUp() */ - public function __construct() + protected function setUp(): void { - parent::__construct(); + parent::setUp(); $this->issues = [ new Issue('/some/file/name.php', 39, 39, 'Checkstyle', 'm3', 'error'), new Issue('/some/file/name.php', 50, 52, 'Checkstyle', 'm4', 'warning'), new Issue('/some/file/name.php', 40, 40, 'Checkstyle', 'm4', 'error'), ]; - } - - /** - * (non-PHPDoc) - * @see AbstractTests#setUp() - */ - protected function setUp(): void - { - parent::setUp(); - $this->file = new File('/some/file/name.php'); + $this->file = new File('/some/file/name.php'); } /** @@ -117,12 +111,12 @@ protected function setUp(): void */ public function testInstantiation(): void { - $this->assertEquals('/some/file/name.php', $this->file->name()); + static::assertEquals('/some/file/name.php', $this->file->name()); $this->file = new File('/some/file/name.php', $this->issues); - $this->assertEquals('/some/file/name.php', $this->file->name()); - $this->assertEquals($this->issues, $this->file->getIssues()); + static::assertEquals('/some/file/name.php', $this->file->name()); + static::assertEquals($this->issues, $this->file->getIssues()); } /** @@ -133,7 +127,7 @@ public function testInstantiation(): void public function testIssueAdding(): void { $this->file->addIssue($this->issues[0]); - $this->assertEquals( + static::assertEquals( [$this->issues[0]], $this->file->getIssues() ); @@ -152,7 +146,6 @@ public function testAddingIssueToWrongFile(): void $this->file->addIssue($issue); } - /** * Test the basename function * @@ -160,7 +153,7 @@ public function testAddingIssueToWrongFile(): void */ public function testBasename(): void { - $this->assertEquals('name.php', $this->file->basename()); + static::assertEquals('name.php', $this->file->basename()); } /** @@ -170,7 +163,7 @@ public function testBasename(): void */ public function testDirName(): void { - $this->assertEquals('/some/file', $this->file->dirName()); + static::assertEquals('/some/file', $this->file->dirName()); } /** @@ -180,19 +173,19 @@ public function testDirName(): void */ public function testIssueCount(): void { - $this->assertEquals(0, $this->file->getIssueCount()); + static::assertEquals(0, $this->file->getIssueCount()); $this->file->addIssue($this->issues[0]); - $this->assertEquals(1, $this->file->getIssueCount()); + static::assertEquals(1, $this->file->getIssueCount()); $this->file = new File( '/some/file/name.php', [$this->issues[0]] ); - $this->assertEquals(1, $this->file->getIssueCount()); + static::assertEquals(1, $this->file->getIssueCount()); $this->file->addIssue($this->issues[1]); - $this->assertEquals(2, $this->file->getIssueCount()); + static::assertEquals(2, $this->file->getIssueCount()); } /** @@ -203,7 +196,7 @@ public function testIssueCount(): void public function testErrorCount(): void { $this->file = new File('/some/file/name.php', $this->issues); - $this->assertEquals(2, $this->file->getErrorCount()); + static::assertEquals(2, $this->file->getErrorCount()); } /** @@ -214,7 +207,7 @@ public function testErrorCount(): void public function testEarningCount(): void { $this->file = new File('/some/file/name.php', $this->issues); - $this->assertEquals(1, $this->file->getWarningCount()); + static::assertEquals(1, $this->file->getWarningCount()); } /** @@ -234,11 +227,11 @@ public function testMergeWith(): void ); $this->file->mergeWith($otherFile); - $this->assertEquals(2, $this->file->getErrorCount()); - $this->assertEquals(1, $this->file->getWarningCount()); - $this->assertEquals( - array_values($this->issues), - array_values($this->file->getIssues()) + static::assertEquals(2, $this->file->getErrorCount()); + static::assertEquals(1, $this->file->getWarningCount()); + static::assertEquals( + \array_values($this->issues), + \array_values($this->file->getIssues()) ); } @@ -302,7 +295,7 @@ public function testSort(): void ]; File::sort($mixed); - $mixed = array_values($mixed); - $this->assertEquals($sorted, $mixed); + $mixed = \array_values($mixed); + static::assertEquals($sorted, $mixed); } } diff --git a/src/PHPCodeBrowser/Tests/Fixtures/Bad.php b/src/PHPCodeBrowser/Tests/Fixtures/Bad.php index 0a664c0..0506c29 100644 --- a/src/PHPCodeBrowser/Tests/Fixtures/Bad.php +++ b/src/PHPCodeBrowser/Tests/Fixtures/Bad.php @@ -4,5 +4,4 @@ class Bad { - } diff --git a/src/PHPCodeBrowser/Tests/Fixtures/Good.php b/src/PHPCodeBrowser/Tests/Fixtures/Good.php index 4874e9e..4ea4985 100644 --- a/src/PHPCodeBrowser/Tests/Fixtures/Good.php +++ b/src/PHPCodeBrowser/Tests/Fixtures/Good.php @@ -4,5 +4,4 @@ class Good { - } diff --git a/src/PHPCodeBrowser/Tests/Helper/IOHelperTest.php b/src/PHPCodeBrowser/Tests/Helper/IOHelperTest.php index 0c84927..fb4b1c6 100644 --- a/src/PHPCodeBrowser/Tests/Helper/IOHelperTest.php +++ b/src/PHPCodeBrowser/Tests/Helper/IOHelperTest.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class IOHelperTest extends AbstractTestCase { @@ -83,6 +83,7 @@ class IOHelperTest extends AbstractTestCase /** * (non-PHPDoc) + * * @see AbstractTestCase::setUp() */ protected function setUp(): void @@ -102,15 +103,15 @@ public function testFileCreation(): void $filename = self::$testOutputDir.'/tmpfile'; $content = 'Lorem ipsum'; - if (file_exists($filename)) { - unlink($filename); + if (\file_exists($filename)) { + \unlink($filename); } $this->ioHelper->createFile($filename, $content); - $this->assertFileExists($filename); - $this->assertEquals($content, file_get_contents($filename)); + static::assertFileExists($filename); + static::assertEquals($content, \file_get_contents($filename)); - unlink($filename); + \unlink($filename); } /** @@ -124,20 +125,20 @@ public function testCreationOfFileWithPath(): void $filename = $dirName.'/tmpfile'; $content = 'Lorem ipsum'; - if (file_exists($filename)) { - unlink($filename); - rmdir($dirName); - } elseif (file_exists($dirName)) { - rmdir($dirName); + if (\file_exists($filename)) { + \unlink($filename); + \rmdir($dirName); + } elseif (\file_exists($dirName)) { + \rmdir($dirName); } $this->ioHelper->createFile($filename, $content); - $this->assertFileExists($dirName); - $this->assertFileExists($filename); - $this->assertEquals($content, file_get_contents($filename)); + static::assertFileExists($dirName); + static::assertFileExists($filename); + static::assertEquals($content, \file_get_contents($filename)); - unlink($filename); - rmdir($dirName); + \unlink($filename); + \rmdir($dirName); } /** @@ -149,12 +150,12 @@ public function testFileDeletion(): void { $filename = self::$testOutputDir.'/tmpfile'; - if (!file_exists($filename)) { - file_put_contents($filename, 'Lorem ipsum'); + if (!\file_exists($filename)) { + \file_put_contents($filename, 'Lorem ipsum'); } $this->ioHelper->deleteFile($filename); - $this->assertFileNotExists($filename); + static::assertFileDoesNotExist($filename); } /** @@ -168,12 +169,12 @@ public function testDirectoryDeletion(): void $file = $dir.'/file'; $subDir = $dir.'/subDir'; - mkdir($dir); - mkdir($subDir); - touch($file); + \mkdir($dir); + \mkdir($subDir); + \touch($file); $this->ioHelper->deleteDirectory($dir); - $this->assertFileNotExists($dir); + static::assertFileDoesNotExist($dir); } /** @@ -188,25 +189,26 @@ public function testCopyFile(): void $dstFile = $dstDir.'/tmpfile'; $content = 'Lorem ipsum'; - if (file_exists($srcFile)) { - unlink($srcFile); + if (\file_exists($srcFile)) { + \unlink($srcFile); } - if (file_exists($dstFile)) { - rmdir($dstFile); + + if (\file_exists($dstFile)) { + \rmdir($dstFile); } - file_put_contents($srcFile, $content); + \file_put_contents($srcFile, $content); $this->ioHelper->copyFile($srcFile, $dstDir); - $this->assertFileExists($srcFile); - $this->assertFileExists($dstDir); - $this->assertFileExists($dstFile); - $this->assertEquals($content, file_get_contents($dstFile)); - $this->assertEquals($content, file_get_contents($srcFile)); - - unlink($dstFile); - rmdir($dstDir); - unlink($srcFile); + static::assertFileExists($srcFile); + static::assertFileExists($dstDir); + static::assertFileExists($dstFile); + static::assertEquals($content, \file_get_contents($dstFile)); + static::assertEquals($content, \file_get_contents($srcFile)); + + \unlink($dstFile); + \rmdir($dstDir); + \unlink($srcFile); } /** @@ -219,13 +221,14 @@ public function testLoadFileWithNonexistentFile(): void $this->expectException(\Exception::class); $sourceFile = self::$testOutputDir.'/doesNotExist'; - if (file_exists($sourceFile)) { - unlink(self::$testOutputDir.'/doesNotExist'); + + if (\file_exists($sourceFile)) { + \unlink(self::$testOutputDir.'/doesNotExist'); } + $this->ioHelper->loadFile($sourceFile); } - /** * Test copyFile function for non-existent source file * @@ -238,8 +241,8 @@ public function testCopyFileNonExisting(): void $file = self::$testOutputDir.'/tmpfile'; $dstDir = self::$testOutputDir.'/tmpdir'; - if (file_exists($file)) { - unlink($file); + if (\file_exists($file)) { + \unlink($file); } $this->ioHelper->copyFile($file, $dstDir); @@ -252,7 +255,7 @@ public function testCopyFileNonExisting(): void */ public function testGetCommonPathPrefixForNoFiles(): void { - $this->assertEquals( + static::assertEquals( '/', $this->ioHelper::getCommonPathPrefix([]) ); diff --git a/src/PHPCodeBrowser/Tests/IssueTest.php b/src/PHPCodeBrowser/Tests/IssueTest.php index e0a013e..8c56fbf 100644 --- a/src/PHPCodeBrowser/Tests/IssueTest.php +++ b/src/PHPCodeBrowser/Tests/IssueTest.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class IssueTest extends AbstractTestCase { @@ -81,6 +82,7 @@ class IssueTest extends AbstractTestCase /** * (non-PHPDoc) + * * @see tests/cbAbstractTests#setUp() */ protected function setUp(): void @@ -98,6 +100,7 @@ protected function setUp(): void /** * (non-PHPDoc) + * * @see tests/cbAbstractTests#tearDown() */ protected function tearDown(): void @@ -112,11 +115,11 @@ protected function tearDown(): void */ public function testInstantiation(): void { - $this->assertSame($this->issue->fileName, 'testFileName'); - $this->assertSame($this->issue->lineStart, 23); - $this->assertSame($this->issue->lineEnd, 27); - $this->assertSame($this->issue->foundBy, 'testFinder'); - $this->assertSame($this->issue->description, 'testDescription'); - $this->assertSame($this->issue->severity, 'notice'); + static::assertSame('testFileName', $this->issue->getFileName()); + static::assertSame(23, $this->issue->getLineStart()); + static::assertSame(27, $this->issue->getLineEnd()); + static::assertSame('testFinder', $this->issue->getFoundBy()); + static::assertSame('testDescription', $this->issue->getDescription()); + static::assertSame('notice', $this->issue->getSeverity()); } } diff --git a/src/PHPCodeBrowser/Tests/Plugins/ErrorCPDTest.php b/src/PHPCodeBrowser/Tests/Plugins/ErrorCPDTest.php index 1c4698d..4b0f3f9 100644 --- a/src/PHPCodeBrowser/Tests/Plugins/ErrorCPDTest.php +++ b/src/PHPCodeBrowser/Tests/Plugins/ErrorCPDTest.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.9.0 + * @since Class available since 0.9.0 */ class ErrorCPDTest extends AbstractTestCase { @@ -104,6 +105,7 @@ class ErrorCPDTest extends AbstractTestCase /** * (non-PHPDoc) + * * @see tests/cbAbstractTests#setUp() */ protected function setUp(): void @@ -119,7 +121,7 @@ protected function setUp(): void /** * Test getFileList * - * @return void + * @return void */ public function testGettingFileList(): void { @@ -152,6 +154,6 @@ public function testGettingFileList(): void ), ]; $actual = $this->errorCPD->getFileList(); - $this->assertEquals($expected, $actual); + static::assertEquals($expected, $actual); } } diff --git a/src/PHPCodeBrowser/Tests/Plugins/ErrorCRAPTest.php b/src/PHPCodeBrowser/Tests/Plugins/ErrorCRAPTest.php index 73fe2ac..949912d 100644 --- a/src/PHPCodeBrowser/Tests/Plugins/ErrorCRAPTest.php +++ b/src/PHPCodeBrowser/Tests/Plugins/ErrorCRAPTest.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.9.0 + * @since Class available since 0.9.0 */ class ErrorCRAPTest extends AbstractTestCase { @@ -129,6 +130,7 @@ class ErrorCRAPTest extends AbstractTestCase /** * (non-PHPDoc) + * * @see tests/cbAbstractTests#setUp() */ protected function setUp(): void @@ -144,7 +146,7 @@ protected function setUp(): void /** * Test getFileList * - * @return void + * @return void */ public function testGettingFileList(): void { @@ -176,13 +178,13 @@ public function testGettingFileList(): void ), ]; $actual = $this->errorCrap->getFileList(); - $this->assertEquals($expected, $actual); + static::assertEquals($expected, $actual); } /** * Test getFileList with limit set * - * @return void + * @return void */ public function testGetFileListWithLimit(): void { @@ -215,6 +217,6 @@ public function testGetFileListWithLimit(): void ), ]; $actual = $this->errorCrap->getFileList(); - $this->assertEquals($expected, $actual); + static::assertEquals($expected, $actual); } } diff --git a/src/PHPCodeBrowser/Tests/Plugins/ErrorCheckstyleTest.php b/src/PHPCodeBrowser/Tests/Plugins/ErrorCheckstyleTest.php index 82e9054..bc6cb62 100644 --- a/src/PHPCodeBrowser/Tests/Plugins/ErrorCheckstyleTest.php +++ b/src/PHPCodeBrowser/Tests/Plugins/ErrorCheckstyleTest.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.9.0 + * @since Class available since 0.9.0 */ class ErrorCheckstyleTest extends AbstractTestCase { @@ -118,6 +119,7 @@ class ErrorCheckstyleTest extends AbstractTestCase /** * (non-PHPDoc) + * * @see tests/cbAbstractTests#setUp() */ protected function setUp(): void @@ -134,7 +136,7 @@ protected function setUp(): void /** * Test getFileList * - * @return void + * @return void */ public function testGettingFileList(): void { @@ -179,6 +181,6 @@ public function testGettingFileList(): void ), ]; $actual = $this->errorCheckstyle->getFileList(); - $this->assertEquals($expected, $actual); + static::assertEquals($expected, $actual); } } diff --git a/src/PHPCodeBrowser/Tests/Plugins/ErrorCoverageTest.php b/src/PHPCodeBrowser/Tests/Plugins/ErrorCoverageTest.php index 8ae78fb..1d5db97 100644 --- a/src/PHPCodeBrowser/Tests/Plugins/ErrorCoverageTest.php +++ b/src/PHPCodeBrowser/Tests/Plugins/ErrorCoverageTest.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.9.0 + * @since Class available since 0.9.0 */ class ErrorCoverageTest extends AbstractTestCase { @@ -130,6 +131,7 @@ class ErrorCoverageTest extends AbstractTestCase /** * (non-PHPDoc) + * * @see tests/cbAbstractTests#setUp() */ protected function setUp(): void @@ -145,7 +147,7 @@ protected function setUp(): void /** * Test getFileList * - * @return void + * @return void */ public function testGettingFileList(): void { @@ -182,6 +184,6 @@ public function testGettingFileList(): void ), ]; $actual = $this->errorCoverage->getFileList(); - $this->assertEquals($expected, $actual); + static::assertEquals($expected, $actual); } } diff --git a/src/PHPCodeBrowser/Tests/Plugins/ErrorPMDTest.php b/src/PHPCodeBrowser/Tests/Plugins/ErrorPMDTest.php index 87bd051..104abbe 100644 --- a/src/PHPCodeBrowser/Tests/Plugins/ErrorPMDTest.php +++ b/src/PHPCodeBrowser/Tests/Plugins/ErrorPMDTest.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.9.0 + * @since Class available since 0.9.0 */ class ErrorPMDTest extends AbstractTestCase { @@ -120,6 +121,7 @@ class="SomeClass" /** * (non-PHPDoc) + * * @see tests/cbAbstractTests#setUp() */ protected function setUp(): void @@ -135,7 +137,7 @@ protected function setUp(): void /** * Test getFileList * - * @return void + * @return void */ public function testGettingFileList(): void { @@ -180,6 +182,6 @@ public function testGettingFileList(): void ), ]; $actual = $this->errorPmd->getFileList(); - $this->assertEquals($expected, $actual); + static::assertEquals($expected, $actual); } } diff --git a/src/PHPCodeBrowser/Tests/SourceHandlerTest.php b/src/PHPCodeBrowser/Tests/SourceHandlerTest.php index b7247ca..a1a7972 100644 --- a/src/PHPCodeBrowser/Tests/SourceHandlerTest.php +++ b/src/PHPCodeBrowser/Tests/SourceHandlerTest.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class SourceHandlerTest extends AbstractTestCase { @@ -102,11 +103,14 @@ class SourceHandlerTest extends AbstractTestCase private $logger; /** - * Initializes common values. + * (non-PHPDoc) + * + * @see AbstractTests#setUp() */ - public function __construct() + protected function setUp(): void { - parent::__construct(); + parent::setUp(); + $xmlStrings = [ << @@ -118,7 +122,7 @@ public function __construct() HERE - , + , << @@ -134,34 +138,27 @@ public function __construct() HERE - , + , ]; $issueXML = new IssueXML(); + foreach ($xmlStrings as $xmlString) { $xml = new \DOMDocument('1.0', 'UTF-8'); $xml->validateOnParse = true; $xml->loadXML($xmlString); $issueXML->addXMLFile($xml); } + $this->plugins = [ new ErrorCheckstyle($issueXML), new ErrorPMD($issueXML), ]; - } - - /** - * (non-PHPDoc) - * @see AbstractTests#setUp() - */ - protected function setUp(): void - { - parent::setUp(); $this->logger = new Logger('PHPCodeBrowser'); $this->logger->pushHandler(new NullHandler()); $this->sourceHandler = new SourceHandler($this->logger); - array_walk( + \array_walk( $this->plugins, [$this->sourceHandler, 'addPlugin'] ); @@ -178,7 +175,7 @@ public function testInstantiation(): void $this->logger, $this->plugins ); - $this->assertEquals($this->sourceHandler, $sourceHandler); + static::assertEquals($this->sourceHandler, $sourceHandler); } /** @@ -207,7 +204,7 @@ public function testGetFiles(): void File::sort($expected); $actual = $this->sourceHandler->getFiles(); - $this->assertEquals($expected, $actual); + static::assertEquals($expected, $actual); } /** @@ -222,7 +219,7 @@ public function testGetFilesWithIssues(): void '/a/nother/dir/src.php', ]; $actualFiles = $this->sourceHandler->getFilesWithIssues(); - $this->assertEquals($expectedFiles, $actualFiles); + static::assertEquals($expectedFiles, $actualFiles); } /** @@ -235,7 +232,7 @@ public function testAddSourceFiles(): void $this->sourceHandler->addSourceFiles( [new SplFileInfo(__FILE__), __FILE__] ); - $this->assertContains(__FILE__, array_keys($this->sourceHandler->getFiles())); + static::assertContains(__FILE__, \array_keys($this->sourceHandler->getFiles())); } /** @@ -261,7 +258,7 @@ public function testGetCommonPathPrefix(): void { $expected = '/a/'; $actual = $this->sourceHandler->getCommonPathPrefix(); - $this->assertEquals($expected, $actual); + static::assertEquals($expected, $actual); } /** @@ -280,7 +277,7 @@ public function testExcludeMatchingPCRE(): void ), ]; $this->sourceHandler->excludeMatchingPCRE('/^\/a.*src\.php$/'); - $this->assertEquals($expected, $this->sourceHandler->getFiles()); + static::assertEquals($expected, $this->sourceHandler->getFiles()); } /** @@ -299,6 +296,6 @@ public function testExcludeMatchingPattern(): void ), ]; $this->sourceHandler->excludeMatchingPattern('*src.php'); - $this->assertEquals($expected, $this->sourceHandler->getFiles()); + static::assertEquals($expected, $this->sourceHandler->getFiles()); } } diff --git a/src/PHPCodeBrowser/Tests/View/ViewReviewTest.php b/src/PHPCodeBrowser/Tests/View/ViewReviewTest.php index 5a8b950..119f042 100644 --- a/src/PHPCodeBrowser/Tests/View/ViewReviewTest.php +++ b/src/PHPCodeBrowser/Tests/View/ViewReviewTest.php @@ -1,4 +1,5 @@ + * @author Simon Kohlmeyer * - * @copyright 2007-2010 Mayflower GmbH + * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class ViewReviewTest extends AbstractTestCase { @@ -87,12 +88,13 @@ class ViewReviewTest extends AbstractTestCase /** * IOHelper mock to simulate filesystem interaction. * - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $ioMock; /** * (non-PHPDoc) + * * @see tests/cbAbstractTests#setUp() */ protected function setUp(): void @@ -102,7 +104,7 @@ protected function setUp(): void $this->ioMock = $this->createMock(IOHelper::class); $this->viewReview = new ViewReview( - PHPCB_ROOT_DIR.'/../templates/', + \getenv('PHPCB_TEMPLATE_DIR') ? \getenv('PHPCB_TEMPLATE_DIR') : \dirname(__FILE__, 5).'/templates', self::$testOutputDir, $this->ioMock ); @@ -115,15 +117,15 @@ protected function setUp(): void */ public function testGenerateNoIssues(): void { - $expectedFile = self::$testOutputDir.DIRECTORY_SEPARATOR.basename(__FILE__).'.html'; + $expectedFile = self::$testOutputDir.DIRECTORY_SEPARATOR.\basename(__FILE__).'.html'; - $this->ioMock->expects($this->once()) - ->method('loadFile') - ->with($this->equalTo(__FILE__)) - ->will($this->returnValue(file_get_contents(__FILE__))); - $this->ioMock->expects($this->once()) - ->method('createFile') - ->with($this->equalTo($expectedFile)); + $this->ioMock->expects(static::once()) + ->method('loadFile') + ->with(static::equalTo(__FILE__)) + ->willReturn(\file_get_contents(__FILE__)); + $this->ioMock->expects(static::once()) + ->method('createFile') + ->with(static::equalTo($expectedFile)); $this->viewReview->generate( [], @@ -150,14 +152,14 @@ public function testGenerate(): void ), ]; - $expectedFile = self::$testOutputDir.DIRECTORY_SEPARATOR.basename(__FILE__).'.html'; - $this->ioMock->expects($this->once()) - ->method('loadFile') - ->with($this->equalTo(__FILE__)) - ->will($this->returnValue(file_get_contents(__FILE__))); - $this->ioMock->expects($this->once()) - ->method('createFile') - ->with($this->equalTo($expectedFile)); + $expectedFile = self::$testOutputDir.DIRECTORY_SEPARATOR.\basename(__FILE__).'.html'; + $this->ioMock->expects(static::once()) + ->method('loadFile') + ->with(static::equalTo(__FILE__)) + ->willReturn(\file_get_contents(__FILE__)); + $this->ioMock->expects(static::once()) + ->method('createFile') + ->with(static::equalTo($expectedFile)); $this->viewReview->generate( $issueList, @@ -178,14 +180,14 @@ public function testGenerateMultiple(): void new Issue(__FILE__, 80, 80, 'other finder', 'other description', 'more severe'), ]; - $expectedFile = self::$testOutputDir.DIRECTORY_SEPARATOR.basename(__FILE__).'.html'; - $this->ioMock->expects($this->once()) - ->method('loadFile') - ->with($this->equalTo(__FILE__)) - ->will($this->returnValue(file_get_contents(__FILE__))); - $this->ioMock->expects($this->once()) - ->method('createFile') - ->with($this->equalTo($expectedFile)); + $expectedFile = self::$testOutputDir.DIRECTORY_SEPARATOR.\basename(__FILE__).'.html'; + $this->ioMock->expects(static::once()) + ->method('loadFile') + ->with(static::equalTo(__FILE__)) + ->willReturn(\file_get_contents(__FILE__)); + $this->ioMock->expects(static::once()) + ->method('createFile') + ->with(static::equalTo($expectedFile)); $this->viewReview->generate( $issueList, @@ -201,8 +203,8 @@ public function testGenerateMultiple(): void */ public function testGenerateWithTextHighlighter(): void { - if (!class_exists('Text_Highlighter')) { - $this->markTestIncomplete(); + if (!\class_exists('Text_Highlighter')) { + static::markTestIncomplete(); } $html = <<< EOT @@ -219,13 +221,13 @@ public function testGenerateWithTextHighlighter(): void $fileName = $prefix.'file.html'; $expectedFile = self::$testOutputDir.'/file.html.html'; - $this->ioMock->expects($this->once()) - ->method('loadFile') - ->with($this->equalTo($fileName)) - ->will($this->returnValue($html)); - $this->ioMock->expects($this->once()) - ->method('createFile') - ->with($this->equalTo($expectedFile)); + $this->ioMock->expects(static::once()) + ->method('loadFile') + ->with(static::equalTo($fileName)) + ->willReturn($html); + $this->ioMock->expects(static::once()) + ->method('createFile') + ->with(static::equalTo($expectedFile)); $issues = [ new Issue($fileName, 5, 5, 'finder', 'description', 'severity'), @@ -241,11 +243,11 @@ public function testGenerateWithTextHighlighter(): void */ public function testGenerateUnknownType(): void { - $expectedFile = self::$testOutputDir.DIRECTORY_SEPARATOR.basename(self::$xmlBasic).'.html'; + $expectedFile = self::$testOutputDir.DIRECTORY_SEPARATOR.\basename(self::$xmlBasic).'.html'; - $this->ioMock->expects($this->once()) - ->method('createFile') - ->with($this->equalTo($expectedFile)); + $this->ioMock->expects(static::once()) + ->method('createFile') + ->with(static::equalTo($expectedFile)); $issueList = [ new Issue(self::$xmlBasic, 5, 5, 'finder', 'description', 'severity'), @@ -265,13 +267,13 @@ public function testGenerateUnknownType(): void */ public function testCopyResourceFolders(): void { - $this->ioMock->expects($this->exactly(3)) - ->method('copyDirectory') - ->with( - $this->matchesRegularExpression( - '|^'.realpath(__DIR__.'/../../../templates/').'|' - ) - ); + $this->ioMock->expects(static::exactly(3)) + ->method('copyDirectory') + ->with( + static::matchesRegularExpression( + '|^'.\realpath(__DIR__.'/../../../templates/').'|' + ) + ); $this->viewReview->copyResourceFolders(); } @@ -288,13 +290,13 @@ public function testGenerateIndex(): void 's/B/anotherfile.php' => new File('s/B/anotherfile.php'), ]; - $this->ioMock->expects($this->once()) - ->method('createFile') - ->with( - $this->logicalAnd( - $this->stringEndsWith('index.html') - ) - ); + $this->ioMock->expects(static::once()) + ->method('createFile') + ->with( + static::logicalAnd( + static::stringEndsWith('index.html') + ) + ); $this->viewReview->generateIndex($files); } } diff --git a/src/PHPCodeBrowser/View/ViewAbstract.php b/src/PHPCodeBrowser/View/ViewAbstract.php index 90f0529..e5404e8 100644 --- a/src/PHPCodeBrowser/View/ViewAbstract.php +++ b/src/PHPCodeBrowser/View/ViewAbstract.php @@ -1,4 +1,5 @@ - * @author Jan Mergler - * @author Simon Kohlmeyer + * @author Elger Thiele + * @author Jan Mergler + * @author Simon Kohlmeyer * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.0 + * @since File available since 0.1.0 */ namespace PHPCodeBrowser\View; @@ -64,21 +65,21 @@ * * This class is generating the highlighted and formatted html view for file. * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Jan Mergler - * @author Simon Kohlmeyer + * @author Elger Thiele + * @author Jan Mergler + * @author Simon Kohlmeyer * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class ViewAbstract { @@ -122,6 +123,7 @@ class ViewAbstract public function __construct(string $templateDir, string $outputDir, IOHelper $ioHelper) { $this->templateDir = $templateDir; + if (!$this->templateDir) { throw new Exception( "Specified template directory '{$templateDir}' does not exist" @@ -129,11 +131,13 @@ public function __construct(string $templateDir, string $outputDir, IOHelper $io } $this->outputDir = $outputDir; + if (!$this->outputDir) { throw new Exception( "Specified output directory '{$outputDir}' does not exist" ); } + $this->outputDir .= DIRECTORY_SEPARATOR; $this->ioHelper = $ioHelper; @@ -184,7 +188,7 @@ public function generateIndex(array $fileList, bool $excludeOK = false): void { //we want to exclude files without issues if ($excludeOK) { - $fileList = array_filter($fileList, [ViewAbstract::class, 'hasFileAnyIssues']); + $fileList = \array_filter($fileList, [ViewAbstract::class, 'hasFileAnyIssues']); } $data = []; @@ -215,8 +219,8 @@ public static function hasFileAnyIssues(File $file): bool /** * Convert a list of files to a html fragment for jstree. * - * @param File[] $fileList The files, format: array('name' => File). - * @param string $hrefPrefix The prefix to put before all href= tags. + * @param array $fileList The files, format: array('name' => File). + * @param string $hrefPrefix The prefix to put before all href= tags. * * @return string The html fragment. */ @@ -227,35 +231,36 @@ protected function getTreeListHtml(array $fileList, string $hrefPrefix = ''): st * This is important so that $curDir doesn't become empty if we go * up to the root directory ('/' on linux) */ - $curDir = IOHelper::getCommonPathPrefix(array_keys($fileList)); + $curDir = IOHelper::getCommonPathPrefix(\array_keys($fileList)); $preLen = \strlen($curDir); $indentStep = 4; $indent = $indentStep; $ret = '
    '.PHP_EOL; + foreach ($fileList as $name => $file) { $dir = \dirname($name).DIRECTORY_SEPARATOR; // Go back until the file is somewhere below curDir - while (strpos($dir, $curDir) !== 0) { + while (!\str_starts_with($dir, $curDir)) { // chop off one subDir from $curDir - $curDir = substr( + $curDir = \substr( $curDir, 0, - strrpos($curDir, DIRECTORY_SEPARATOR, -2) + 1 + \strrpos($curDir, DIRECTORY_SEPARATOR, -2) + 1 ); - $ret .= str_pad(' ', $indent); + $ret .= \str_pad(' ', $indent); $ret .= '
'.PHP_EOL; $indent -= $indentStep; - $ret .= str_pad(' ', $indent); + $ret .= \str_pad(' ', $indent); $ret .= ''.PHP_EOL; } if ($dir !== $curDir) { // File is in a subDir of current directory // relDir has no leading or trailing slash. - $relDir = substr($dir, \strlen($curDir), -1); - $relDirs = explode(DIRECTORY_SEPARATOR, $relDir); + $relDir = \substr($dir, \strlen($curDir), -1); + $relDirs = \explode(DIRECTORY_SEPARATOR, $relDir); foreach ($relDirs as $dirName) { $curDir .= $dirName.DIRECTORY_SEPARATOR; @@ -263,33 +268,38 @@ protected function getTreeListHtml(array $fileList, string $hrefPrefix = ''): st //TODO: Optimize this. Counts get recalculated for subDirs. $errors = 0; $warnings = 0; - foreach (array_keys($fileList) as $fName) { - if (strncmp($fName, $curDir, \strlen($curDir)) !== 0) { + + foreach (\array_keys($fileList) as $fName) { + if (\strncmp($fName, $curDir, \strlen($curDir)) !== 0) { continue; } $errors += $fileList[$fName]->getErrorCount(); $warnings += $fileList[$fName]->getWarningCount(); } + $count = ''; + if (0 !== $errors || 0 !== $warnings) { $count .= '('; $count .= $errors; $count .= '|'; $count .= $warnings.')'; } - $ret .= str_pad(' ', $indent); + + $ret .= \str_pad(' ', $indent); $ret .= "
  • {$dirName} {$count}".PHP_EOL; $indent += $indentStep; - $ret .= str_pad(' ', $indent); + $ret .= \str_pad(' ', $indent); $ret .= '
      '.PHP_EOL; } } - $name = str_replace('\\', '/', $name); - $shortName = substr($name, $preLen); - $fileName = basename($name); + $name = \str_replace('\\', '/', $name); + $shortName = \substr($name, $preLen); + $fileName = \basename($name); $count = ''; + if (0 !== $file->getErrorCount() || 0 !== $file->getWarningCount()) { $count .= '('; $count .= $file->getErrorCount(); @@ -298,7 +308,7 @@ protected function getTreeListHtml(array $fileList, string $hrefPrefix = ''): st $count .= ')'; } - $ret .= str_pad(' ', $indent); + $ret .= \str_pad(' ', $indent); $ret .= '
    • '; $ret .= "{$fileName} {$count}
    • ".PHP_EOL; @@ -306,10 +316,10 @@ protected function getTreeListHtml(array $fileList, string $hrefPrefix = ''): st while ($indent > $indentStep) { $indent -= $indentStep; - $ret .= str_pad(' ', $indent); + $ret .= \str_pad(' ', $indent); $ret .= '
    '.PHP_EOL; $indent -= $indentStep; - $ret .= str_pad(' ', $indent); + $ret .= \str_pad(' ', $indent); $ret .= '
  • '.PHP_EOL; } @@ -333,12 +343,11 @@ protected function render(string $templateName, array $data): string { $filePath = $this->templateDir.DIRECTORY_SEPARATOR.$templateName.'.tpl'; - extract($data, EXTR_SKIP); + \extract($data, EXTR_SKIP); - ob_start(); - include($filePath); - $contents = ob_get_contents(); - ob_end_clean(); + \ob_start(); + include $filePath; + $contents = \ob_get_clean(); return $contents; } diff --git a/src/PHPCodeBrowser/View/ViewReview.php b/src/PHPCodeBrowser/View/ViewReview.php index 2671d8a..05f36fc 100644 --- a/src/PHPCodeBrowser/View/ViewReview.php +++ b/src/PHPCodeBrowser/View/ViewReview.php @@ -1,4 +1,5 @@ - * @author Jan Mergler - * @author Simon Kohlmeyer + * @author Elger Thiele + * @author Jan Mergler + * @author Simon Kohlmeyer * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version SVN: $Id$ + * @version SVN: $Id$ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since File available since 0.1.0 + * @since File available since 0.1.0 */ namespace PHPCodeBrowser\View; use DOMDocument; use DOMElement; +use DOMText; use DOMXPath; use PHPCodeBrowser\Helper\IOHelper; @@ -65,21 +67,21 @@ * * This class is generating the highlighted and formatted html view for file. * - * @category PHP_CodeBrowser + * @category PHP_CodeBrowser * - * @author Elger Thiele - * @author Jan Mergler - * @author Simon Kohlmeyer + * @author Elger Thiele + * @author Jan Mergler + * @author Simon Kohlmeyer * * @copyright 2007-2010 Mayflower GmbH * - * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @license http://www.opensource.org/licenses/bsd-license.php BSD License * - * @version Release: @package_version@ + * @version Release: @package_version@ * - * @link http://www.phpunit.de/ + * @link http://www.phpunit.de/ * - * @since Class available since 0.1.0 + * @since Class available since 0.1.0 */ class ViewReview extends ViewAbstract { @@ -112,11 +114,11 @@ public function __construct(string $templateDir, string $outputDir, IOHelper $io parent::__construct($templateDir, $outputDir, $ioHelper); $this->phpHighlightColorMap = [ - ini_get('highlight.string') => 'string', - ini_get('highlight.comment') => 'comment', - ini_get('highlight.keyword') => 'keyword', - ini_get('highlight.default') => 'default', - ini_get('highlight.html') => 'html', + \ini_get('highlight.string') => 'string', + \ini_get('highlight.comment') => 'comment', + \ini_get('highlight.keyword') => 'keyword', + \ini_get('highlight.default') => 'default', + \ini_get('highlight.html') => 'html', ]; $this->phpSuffixes = $phpSuffixes; @@ -144,7 +146,7 @@ public function __construct(string $templateDir, string $outputDir, IOHelper $io public function generate(array $issueList, string $fileName, string $commonPathPrefix, bool $excludeOK = false): void { $issues = $this->formatIssues($issueList); - $shortFilename = substr($fileName, \strlen($commonPathPrefix)); + $shortFilename = \substr($fileName, \strlen($commonPathPrefix)); $data = []; @@ -152,13 +154,14 @@ public function generate(array $issueList, string $fileName, string $commonPathP $data['filepath'] = $shortFilename; $data['source'] = $this->formatSourceCode($fileName, $issues); - $depth = substr_count($shortFilename, DIRECTORY_SEPARATOR); - $data['csspath'] = str_repeat('../', $depth - 1 >= 0 ? $depth - 1 : 0); + $depth = \substr_count($shortFilename, DIRECTORY_SEPARATOR); + $data['csspath'] = \str_repeat('../', \max($depth - 1, 0)); //we want to exclude files without issues and there are no issues in this one if ($excludeOK && !$data['issues']) { return; } + $this->ioHelper->createFile( $this->outputDir.$shortFilename.'.html', $this->render('review', $data) @@ -178,16 +181,19 @@ public function generate(array $issueList, string $fileName, string $commonPathP */ protected function highlightPhpCode(string $sourceCode): DOMDocument { - $code = highlight_string($sourceCode, true); - if (\extension_loaded('mbstring') && !mb_check_encoding($code, 'UTF-8')) { - $detectOrder = mb_detect_order(); + $code = \highlight_string($sourceCode, true); + + if (\extension_loaded('mbstring') && !\mb_check_encoding($code, 'UTF-8')) { + $detectOrder = (array) \mb_detect_order(); $detectOrder[] = 'iso-8859-1'; - $encoding = mb_detect_encoding($code, $detectOrder, true); + $encoding = \mb_detect_encoding($code, $detectOrder, true); + if (false === $encoding) { - error_log('Error detecting file encoding'); + \error_log('Error detecting file encoding'); } - $code = mb_convert_encoding( + + $code = \mb_convert_encoding( $code, 'UTF-8', $encoding @@ -198,8 +204,8 @@ protected function highlightPhpCode(string $sourceCode): DOMDocument $sourceDom->loadHTML(''.$code); //fetch ->->children from php generated html - $sourceElements = $sourceDom->getElementsByTagname('code')->item(0) - ->childNodes->item(0)->childNodes; + $sourceElements = $sourceDom->getElementsByTagName('code')->item(0) + ->childNodes->item(0)->childNodes; //create target dom $targetDom = new DOMDocument(); @@ -212,10 +218,13 @@ protected function highlightPhpCode(string $sourceCode): DOMDocument // iterate through all elements foreach ($sourceElements as $sourceElement) { - if (!$sourceElement instanceof DOMElement) { + if ($sourceElement instanceof DOMText) { $span = $targetDom->createElement('span'); - $span->nodeValue = htmlspecialchars($sourceElement->wholeText); + $span->nodeValue = \htmlspecialchars($sourceElement->wholeText, ENT_COMPAT); $liElement->appendChild($span); + } + + if (!$sourceElement instanceof DOMElement) { continue; } @@ -223,6 +232,7 @@ protected function highlightPhpCode(string $sourceCode): DOMDocument // create new li and new line $liElement = $targetDom->createElement('li'); $targetNode->appendChild($liElement); + continue; } @@ -240,7 +250,7 @@ protected function highlightPhpCode(string $sourceCode): DOMDocument } else { // append content to current li element $span = $targetDom->createElement('span'); - $span->nodeValue = htmlspecialchars($sourceChildElement->textContent); + $span->nodeValue = \htmlspecialchars($sourceChildElement->textContent, ENT_COMPAT); $span->setAttribute('class', $elementClass); $liElement->appendChild($span); } @@ -259,7 +269,7 @@ protected function highlightPhpCode(string $sourceCode): DOMDocument */ protected function mapPhpColors(string $style): string { - $color = substr($style, 7); + $color = \substr($style, 7); return $this->phpHighlightColorMap[$color]; } @@ -278,18 +288,13 @@ protected function mapPhpColors(string $style): string protected function highlightCode(string $file): DOMDocument { $sourceCode = $this->ioHelper->loadFile($file); - $extension = pathinfo($file, PATHINFO_EXTENSION); + $extension = \pathinfo($file, PATHINFO_EXTENSION); - if (\in_array($extension, $this->phpSuffixes)) { + if (\in_array($extension, $this->phpSuffixes, true)) { return $this->highlightPhpCode($sourceCode); } - $sourceCode = preg_replace( - '/^.*$/m', - '
  • $0
  • ', - htmlentities($sourceCode) - ); - $sourceCode = preg_replace('/ /', ' ', $sourceCode); + $sourceCode = \preg_replace(['/^.*$/m', '/ /'], ['
  • $0
  • ', ' '], \htmlentities($sourceCode, ENT_COMPAT)); $sourceCode = '
      '.$sourceCode.'
    '; $sourceCode = $this->stripInvalidXml($sourceCode); @@ -323,42 +328,49 @@ private function formatSourceCode(string $filename, array $outputIssues): string } $lineNumber = 0; - $linePlaces = floor(log($lines->length, 10)) + 1; + $linePlaces = \floor(\log($lines->length, 10)) + 1; - /** @var DOMElement:: $line */ foreach ($lines as $line) { + /** + * @var DOMElement $line + */ + $line = $line; ++$lineNumber; $line->setAttribute('id', 'line_'.$lineNumber); $lineClasses = [ - ($lineNumber % 2) ? 'odd' : 'even', + ($lineNumber % 2 === 0) ? 'odd' : 'even', ]; if (isset($outputIssues[$lineNumber])) { $lineClasses[] = 'hasIssues'; $message = '|'; + foreach ($outputIssues[$lineNumber] as $issue) { - $message .= sprintf( + $message .= \sprintf( '
    %s
    %s
    ', - $issue->foundBy, - $issue->foundBy, - $issue->description + $issue->getFoundBy(), + $issue->getFoundBy(), + $issue->getDescription() ); } - $line->setAttribute('title', utf8_encode($message)); + + $line->setAttribute('title', $message); } // Add line number $nuSpan = $sourceDom->createElement('span'); $nuSpan->setAttribute('class', 'lineNumber'); + for ($i = 0; $i < $linePlaces - \strlen((string) $lineNumber); ++$i) { $nuSpan->appendChild($sourceDom->createEntityReference('nbsp')); } + $nuSpan->appendChild($sourceDom->createTextNode((string) $lineNumber)); $nuSpan->appendChild($sourceDom->createEntityReference('nbsp')); $line->insertBefore($nuSpan, $line->firstChild); @@ -368,25 +380,32 @@ private function formatSourceCode(string $filename, array $outputIssues): string $anchor->setAttribute('name', 'line_'.$lineNumber); $line->appendChild($anchor); + $lineErrorCount = (isset($outputIssues[$lineNumber]) + ? \count($outputIssues[$lineNumber]) + : 0); + // set li css class depending on line errors - switch ($tmp = (isset($outputIssues[$lineNumber]) - ? \count($outputIssues[$lineNumber]) - : 0)) { + switch ($lineErrorCount) { case 0: break; case 1: - $lineClasses[] = $outputIssues[$lineNumber][0]->foundBy; + $lineClasses[] = $outputIssues[$lineNumber][0]->getFoundBy(); + break; - case 1 < $tmp: + case 1 < $lineErrorCount: $lineClasses[] = 'moreErrors'; + break; + // This can't happen, count always returns >= 0 // @codeCoverageIgnoreStart default: break; + // @codeCoverageIgnoreEnd } - $line->setAttribute('class', implode(' ', $lineClasses)); + + $line->setAttribute('class', \implode(' ', $lineClasses)); } return $sourceDom->saveHTML(); @@ -403,8 +422,9 @@ private function formatSourceCode(string $filename, array $outputIssues): string private function formatIssues(array $issueList): array { $outputIssues = []; + foreach ($issueList as $issue) { - for ($i = $issue->lineStart; $i <= $issue->lineEnd; ++$i) { + for ($i = $issue->getLineStart(); $i <= $issue->getLineEnd(); ++$i) { $outputIssues[$i][] = $issue; } } @@ -430,8 +450,10 @@ private function stripInvalidXml(string $value): string } $length = \strlen($value); + for ($i = 0; $i < $length; ++$i) { - $current = \ord($value{$i}); + $current = \ord($value[$i]); + if ((0x9 === $current) || (0xA === $current) || (0xD === $current) diff --git a/templates/index.tpl b/templates/index.tpl index 7cf59e0..ec719b8 100644 --- a/templates/index.tpl +++ b/templates/index.tpl @@ -52,7 +52,7 @@ $occuringErrorTypes = array ( foreach ($fileList as $file) { /** @var $file PHPCodeBrowser\File */ foreach ($file->getIssues() as $issue) { - $occuringErrorTypes[$issue->foundBy] = true; + $occuringErrorTypes[$issue->getFoundBy()] = true; } } @@ -85,7 +85,7 @@ foreach ($fileList as $filename => $f) { $counts = array_fill_keys($occuringErrorTypes, 0); foreach ($f->getIssues() as $issue) { - $counts[$issue->foundBy] += 1; + $counts[$issue->getFoundBy()] += 1; } echo " " . PHP_EOL; diff --git a/templates/review.tpl b/templates/review.tpl index 4c98bdb..c51b4c8 100644 --- a/templates/review.tpl +++ b/templates/review.tpl @@ -57,24 +57,24 @@ - + - - lineStart; ?> + + getLineStart(); ?> - lineEnd; ?>', {duration: 1.5}); return false"> - lineEnd;?> + getLineEnd(); ?>', {duration: 1.5}); return false"> + getLineEnd();?> - lineEnd; ?>', {duration: 1.5}); return false"> - description;?> + getLineEnd(); ?>', {duration: 1.5}); return false"> + getDescription();?> - foundBy;?> + getFoundBy();?> - severity;?> + getSeverity();?>