diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..821bcea0
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,3 @@
+# These are supported funding model platforms
+
+github: [Halleck45]
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..68f6edee
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,72 @@
+name: CI
+
+on:
+ push:
+ branches: [ master, main ]
+ pull_request:
+ branches: [ master, main ]
+ release:
+ types: [created]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ php-version: [5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4]
+ include:
+ - php-version: nightly
+ fail-fast: false
+
+ services:
+ docker:
+ image: docker:20.10.16
+ options: --privileged
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up PHP ${{ matrix.php-version }}
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-version }}
+
+ - name: "Remove ': void' return type hint for older PHP versions"
+ run: |
+ # if php version < 7.1, remove ': void' return type hint
+ if [[ "${{ matrix.php-version }}" < "7.1" ]]; then
+ echo "Removing ': void' return type hint for PHP version ${{ matrix.php-version }}"
+ # Find and replace ': void' in all PHP files
+ find . -type f -name "*.php" -exec sed -i 's/: void//g' {} +
+ fi
+
+ - name: Install Composer dependencies (${{ matrix.php-version }})
+ run: composer install --no-interaction --prefer-dist --no-progress
+
+ - name: Run tests (${{ matrix.php-version }})
+ run: make test
+
+ build:
+ if: github.event_name == 'release' && startsWith(github.ref, 'refs/tags/')
+ needs: test
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 7.0
+
+ - name: Build project
+ run: make build
+
+ - name: Add build artifact
+ run: git add -f build/phpmetrics.phar
+
+ - name: Upload release asset
+ uses: softprops/action-gh-release@v2
+ with:
+ files: build/phpmetrics.phar
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 2799b96c..fb488c20 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
composer.lock
vendor
+tooling/vendor
.idea
md5sums
control
@@ -8,3 +9,12 @@ build/phpmetrics.dsc
build/phpmetrics.deb
build/phpmetrics.tar.gz
build/phpmetrics.changes
+.php-cs-fixer.cache
+.phpunit.result.cache
+
+# build
+buildroot/
+downloads/
+pkgroot/
+source/
+spc
diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php
new file mode 100644
index 00000000..779c7070
--- /dev/null
+++ b/.php-cs-fixer.php
@@ -0,0 +1,14 @@
+in(__DIR__ . '/src')
+;
+
+return (new PhpCsFixer\Config())
+ ->setRules([
+ '@PER-CS' => true,
+ '@PHP82Migration' => true,
+ ])
+ ->setFinder($finder)
+ ->setUnsupportedPhpVersionAllowed(true)
+ ;
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 6f624134..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,73 +0,0 @@
-sudo: false
-dist: trusty
-language: php
-
-php:
- - 5.5
- - 5.6
- - 7.0
- - 7.1
- - 7.2
- - 7.3
- - 7.4
- - 8.0
- - nightly
- - hhvm
- - hhvm-nightly
-
-env:
- matrix:
- - DEPENDENCIES="--prefer-lowest --prefer-stable"
- - DEPENDENCIES=""
-
-matrix:
- fast_finish: true
- allow_failures:
- - php: nightly
- - php: hhvm
- - php: hhvm-nightly
-
-services:
- - docker
-
-install:
- - docker build -t test_phpmetrics .
- - composer self-update --quiet
- - travis_retry composer update --no-interaction --prefer-dist --no-progress $DEPENDENCIES
-
-before_script:
- # Disable JIT compilation in hhvm, as the JIT is useless for short live scripts like tests.
- - if [[ $TRAVIS_PHP_VERSION = hhvm* ]]; then echo 'hhvm.jit = 0' >> /etc/hhvm/php.ini; fi
-
-script:
- - make test
- - make phpcs
- - docker run --rm test_phpmetrics
-
-before_deploy:
- - make build
- - git add -f build/phpmetrics.phar # build/phpmetrics.deb
-
-deploy:
- - provider: releases
- api_key:
- secure: DfUbGENVB2IK6bggZeI89zJizOCSUbYqMEpXYVjhlbP73c7a+s4P6MrmTk8BiLACBeoyaoQDHW06DTHuc3MzgadXcTsPxzdxmZmSHaNsmGuUUJPlBR44Ypw/6ZccILrMVowzMbgRSAvk63XEIaV18DwcDMQaMhYU9uPf2WNpHL4=
- file:
- - "releases/phpmetrics.phar"
- on:
- repo: phpmetrics/PhpMetrics
- tags: true
- php: '7.0'
- condition: '-z "$DEPENDENCIES"'
- skip_cleanup: true
- - provider: bintray
- file: artifacts/bintray.json
- user: "halleck45"
- key:
- secure: Pa7uB1ePY9bYKGHovrdC/F2HlrjXGapKTp6McAFcnIksvuwu06Xug0BszqQeUSzKX/y1kivC7ksIp6kI3icHv0cm6K0MvAi+PLxplqtwLsKJPtwoxX5L6r0VOQ8uNaNU2K7+9Gb/5WNov7SfESXpyxOmUUj/QwwnRkj2RqlL9rg=
- on:
- repo: phpmetrics/PhpMetrics
- tags: true
- php: '7.0'
- condition: '-z "$DEPENDENCIES"'
- skip_cleanup: true
diff --git a/Makefile b/Makefile
index eeb073e8..3b255d1a 100644
--- a/Makefile
+++ b/Makefile
@@ -2,17 +2,13 @@
include artifacts/Makefile
-# Run unit tests
+# Run unit tests
test:
- ./vendor/bin/phpunit -c phpunit.xml.dist
+ ./vendor/bin/phpunit -c phpunit.xml.dist --exclude-group binary
-# Codesniffer check
-phpcs:
- ./vendor/bin/phpcs src/ tests/ --extensions=php -n
-
-# Codesniffer fix
-phpcbf:
- ./vendor/bin/phpcbf src/ tests/ --extensions=php -n
+# Compatibility check
+compatibility:
+ (docker run --rm -v `pwd`:/www --workdir=/www php:5.6-cli find src -iname "*.php" -exec php -l {} \; |grep -v "Php7NodeTraverser.php" | grep -v "No syntax errors detected") && echo OK
# Used for tag releasing
# Don't use directly, use `make release` instead
diff --git a/artifacts/Makefile b/artifacts/Makefile
index 32c41f3f..e763bf39 100644
--- a/artifacts/Makefile
+++ b/artifacts/Makefile
@@ -4,6 +4,7 @@ BUILD_DIR=releases
include artifacts/phar/Makefile
include artifacts/debian/Makefile
+include artifacts/standalone/Makefile
prepare-build:
@# Disable the deletion of all releases packages as task build-debian is disabled.
@@ -12,5 +13,5 @@ prepare-build:
@# Only remove the phar that must be replaced by the new release.
@rm -f ${BUILD_DIR}/phpmetrics.phar
-build: prepare-build build-phar build-deb
+build: prepare-build build-phar build-deb build-standalone
diff --git a/artifacts/standalone/Makefile b/artifacts/standalone/Makefile
new file mode 100644
index 00000000..7882e7d5
--- /dev/null
+++ b/artifacts/standalone/Makefile
@@ -0,0 +1,10 @@
+build-standalone: build-standalone-linux
+
+build-standalone-linux:
+ mkdir -p ${BUILD_DIR}
+ curl -fsSL -o spc.tgz https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64.tar.gz && tar -zxvf spc.tgz && rm spc.tgz
+ ./spc download --with-php=8.4 --for-extensions "apcu,phar,curl,dom,fileinfo,filter,intl,mbstring,mysqlnd,openssl,tokenizer,zlib" --prefer-pre-built
+ ./spc install-pkg upx
+ ./spc build --build-micro "apcu,phar,curl,dom,fileinfo,filter,intl,mbstring,mysqlnd,openssl,tokenizer,zlib" --with-upx-pack
+ ./spc micro:combine ${BUILD_DIR}/phpmetrics.phar --output=${BUILD_DIR}/phpmetrics-linux-x86_64
+
diff --git a/composer.json b/composer.json
index 475f1de7..edfdaebe 100644
--- a/composer.json
+++ b/composer.json
@@ -30,22 +30,23 @@
},
"files": ["./src/functions.php"]
},
+ "autoload-dev": {
+ "psr-4": {
+ "Test\\Hal\\": "tests/"
+ }
+ },
"require": {
- "php": ">=5.5",
"ext-dom": "*",
"ext-tokenizer": "*",
- "nikic/php-parser": "^3|^4"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14",
- "sebastian/comparator": ">=1.2.3",
- "squizlabs/php_codesniffer": "^3.5",
- "symfony/dom-crawler": "^3.0 || ^4.0 || ^5.0"
+ "nikic/php-parser": "^3|^4|^5"
},
"bin": [
"bin/phpmetrics"
],
"config": {
"sort-packages": true
+ },
+ "require-dev": {
+ "phpunit/phpunit": "*"
}
}
diff --git a/craft.yml b/craft.yml
new file mode 100644
index 00000000..8f3ca668
--- /dev/null
+++ b/craft.yml
@@ -0,0 +1,6 @@
+php-version: 8.4
+extensions: "apcu,phar,curl,dom,fileinfo,filter,intl,mbstring,mysqlnd,openssl,tokenizer,zlib"
+sapi: micro
+build-options:
+ with-upx-pack: true
+ prefer-pre-built: true
diff --git a/doc/contributing.md b/doc/contributing.md
index 918470fa..be51ba63 100644
--- a/doc/contributing.md
+++ b/doc/contributing.md
@@ -11,6 +11,27 @@ Then, in order to run the test suite:
Thanks for your help.
+## Why the code is so old?
+
+### Philosophy
+
+PhpMetrics has several goals:
++ be stable
++ be performant
++ run on the **maximum of PHP versions** (PHP 5.3 to PHP 8.4)
++ be installable everywhere, **without dependency conflicts**
+
+For these reasons, the code of PhpMetrics is intentionally written in "legacy" PHP.
+
+### Dependencies
+
+Not all projects are on the latest version of PHP, Symfony, or Laravel. Yes, there are projects that use Symfony 2. And these projects may also need metrics and quality.
+
+For these reasons, PhpMetrics comes with the minimum of dependencies. Only the dependency on `nikic/php-parser` is accepted.
+
+No Pull Request that modifies the `require` block will be accepted.
+
+
## Releasing
Please NEVER tag manually.
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
deleted file mode 100644
index 28f5b8a4..00000000
--- a/phpcs.xml.dist
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
- The coding standard of PhpMetrics package
-
-
-
-
-
-
-
-
-
- */tests/*/examples/*.php
- */src/functions.php
-
-
-
- */tests/*
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 10
-
-
- 10
-
-
- 10
-
-
-
-
-
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index de4ebec4..ec987918 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,15 +1,11 @@
-
@@ -23,10 +19,4 @@
binary
-
-
-
- ./src
-
-
diff --git a/rector.php b/rector.php
new file mode 100644
index 00000000..c9a4ae89
--- /dev/null
+++ b/rector.php
@@ -0,0 +1,19 @@
+withPaths([
+ __DIR__ . '/src',
+ __DIR__ . '/tests',
+ ])
+ ->withSets([
+ \Rector\PHPUnit\Set\PHPUnitSetList::PHPUNIT_110,
+ ])
+ ->withRules([
+ \Rector\TypeDeclaration\Rector\Class_\AddTestsVoidReturnTypeWhereNoReturnRector::class,
+ \Rector\PHPUnit\CodeQuality\Rector\Class_\AddParentSetupCallOnSetupRector::class,
+ \Rector\PHPUnit\PHPUnit60\Rector\ClassMethod\ExceptionAnnotationRector::class,
+ \Rector\PHPUnit\PHPUnit100\Rector\StmtsAwareInterface\WithConsecutiveRector::class,
+ \Rector\PHPUnit\PHPUnit100\Rector\Class_\StaticDataProviderClassMethodRector::class,
+ ]);
diff --git a/src/Hal/Application/Analyze.php b/src/Hal/Application/Analyze.php
index eec78e2c..8fa01219 100644
--- a/src/Hal/Application/Analyze.php
+++ b/src/Hal/Application/Analyze.php
@@ -1,8 +1,11 @@
create(ParserFactory::PREFER_PHP7);
- $traverser = new NodeTraverser(false, $whenToStop);
- $traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver());
- $traverser->addVisitor(new ClassEnumVisitor($metrics));
- $traverser->addVisitor(new CyclomaticComplexityVisitor($metrics));
- $traverser->addVisitor(new ExternalsVisitor($metrics));
- $traverser->addVisitor(new LcomVisitor($metrics));
- $traverser->addVisitor(new HalsteadVisitor($metrics));
- $traverser->addVisitor(new LengthVisitor($metrics));
- $traverser->addVisitor(new CyclomaticComplexityVisitor($metrics));
- $traverser->addVisitor(new MaintainabilityIndexVisitor($metrics));
- $traverser->addVisitor(new KanDefectVisitor($metrics));
- $traverser->addVisitor(new SystemComplexityVisitor($metrics));
- $traverser->addVisitor(new PackageCollectingVisitor($metrics));
+ $parser = (new ParserFactoryBridge())->create();
+ $traverser = new NodeTraverser();
+
+ (new ParserTraverserVisitorsAssigner())->assign(
+ $traverser,
+ [
+ new NameResolver(),
+ new ClassEnumVisitor($metrics),
+ new CyclomaticComplexityVisitor($metrics),
+ new ExternalsVisitor($metrics),
+ new LcomVisitor($metrics),
+ new HalsteadVisitor($metrics),
+ new LengthVisitor($metrics),
+ new CyclomaticComplexityVisitor($metrics),
+ new MaintainabilityIndexVisitor($metrics),
+ new KanDefectVisitor($metrics),
+ new SystemComplexityVisitor($metrics),
+ new PackageCollectingVisitor($metrics)
+ ]
+ );
// create a new progress bar (50 units)
$progress = new ProgressBar($this->output, count($files));
diff --git a/src/Hal/Application/Application.php b/src/Hal/Application/Application.php
index cc9544f1..5b755fe7 100644
--- a/src/Hal/Application/Application.php
+++ b/src/Hal/Application/Application.php
@@ -17,7 +17,6 @@
class Application
{
-
/**
* @param array $argv
*/
@@ -46,8 +45,10 @@ public function run(array $argv)
// Version
if ($config->has('version')) {
- $output->writeln(sprintf("PhpMetrics %s \nby Jean-François Lépine \n",
- getVersion()));
+ $output->writeln(sprintf(
+ "PhpMetrics %s \nby Jean-François Lépine \n",
+ getVersion()
+ ));
exit(0);
}
@@ -113,8 +114,10 @@ public function run(array $argv)
}
if (!empty($shouldExitDueToCriticalViolationsCount)) {
$output->writeln('');
- $output->writeln(sprintf('[ERR] Failed du to %d critical violations',
- $shouldExitDueToCriticalViolationsCount));
+ $output->writeln(sprintf(
+ '[ERR] Failed du to %d critical violations',
+ $shouldExitDueToCriticalViolationsCount
+ ));
$output->writeln('');
exit(1);
}
diff --git a/src/Hal/Application/Config/Config.php b/src/Hal/Application/Config/Config.php
index 9dc0cf28..ab4d991d 100644
--- a/src/Hal/Application/Config/Config.php
+++ b/src/Hal/Application/Config/Config.php
@@ -1,9 +1,9 @@
set('composer', (bool)$jsonData['composer']);
+ $config->set('composer', (bool) $jsonData['composer']);
}
// Search
diff --git a/src/Hal/Application/Config/Parser.php b/src/Hal/Application/Config/Parser.php
index 2e675366..7cec93d2 100644
--- a/src/Hal/Application/Config/Parser.php
+++ b/src/Hal/Application/Config/Parser.php
@@ -1,4 +1,5 @@
has('exclude')) {
- $config->set('exclude',
- 'vendor,test,Test,tests,Tests,testing,Testing,bower_components,node_modules,cache,spec');
+ $config->set(
+ 'exclude',
+ 'vendor,test,Test,tests,Tests,testing,Testing,bower_components,node_modules,cache,spec'
+ );
}
// retro-compatibility with excludes as string in config files
@@ -61,7 +63,18 @@ public function validate(Config $config)
if (!$config->has('composer')) {
$config->set('composer', true);
}
- $config->set('composer', filter_var($config->get('composer'), FILTER_VALIDATE_BOOLEAN));
+
+ if (function_exists('filter_var')) {
+ $config->set('composer', filter_var($config->get('composer'), FILTER_VALIDATE_BOOLEAN));
+ } else {
+ // When PHP is not compiled with the filter extension, we need to do it manually
+ $bool = $config->get('composer');
+ if( is_string($bool) ) {
+ $bool = strtolower($bool);
+ $bool = in_array($bool, ['true', '1', 'yes', 'on'], true);
+ }
+ $config->set('composer', (bool) $bool);
+ }
// Search
$validator = new SearchesValidator();
@@ -121,7 +134,6 @@ public function help()
Analyze the "./src" and "./lib" directories, and generate the "./build/violations.xml" file. This file could
be read by any Continuous Integration Platform, and follows the "PMD Violation" standards.
-
EOT;
}
@@ -129,7 +141,6 @@ public function metrics()
{
$help = <<
*
@@ -8,7 +9,9 @@
namespace Hal\Component\Ast;
-if (PHP_VERSION_ID >= 70000) {
+if (PHP_VERSION_ID >= 80000) {
+ class_alias(Php8NodeTraverser::class, __NAMESPACE__ . '\\ActualNodeTraverser');
+}elseif (PHP_VERSION_ID >= 70000) {
class_alias(Php7NodeTraverser::class, __NAMESPACE__ . '\\ActualNodeTraverser');
} else {
class_alias(Php5NodeTraverser::class, __NAMESPACE__ . '\\ActualNodeTraverser');
@@ -21,6 +24,4 @@ class_alias(Php5NodeTraverser::class, __NAMESPACE__ . '\\ActualNodeTraverser');
* @see https://github.com/phpmetrics/PhpMetrics/issues/373
*/
/** @noinspection PhpUndefinedClassInspection */
-class NodeTraverser extends ActualNodeTraverser
-{
-}
+class NodeTraverser extends ActualNodeTraverser {}
diff --git a/src/Hal/Component/Ast/NodeTyper.php b/src/Hal/Component/Ast/NodeTyper.php
new file mode 100644
index 00000000..5a046eae
--- /dev/null
+++ b/src/Hal/Component/Ast/NodeTyper.php
@@ -0,0 +1,35 @@
+create($kind);
+ }
+
+ if ($kind !== null) {
+ return (new \PhpParser\ParserFactory())->createForVersion($kind);
+ }
+
+ return (new \PhpParser\ParserFactory())->createForNewestSupportedVersion();
+ }
+}
diff --git a/src/Hal/Component/Ast/ParserTraverserVisitorsAssigner.php b/src/Hal/Component/Ast/ParserTraverserVisitorsAssigner.php
new file mode 100644
index 00000000..61811e10
--- /dev/null
+++ b/src/Hal/Component/Ast/ParserTraverserVisitorsAssigner.php
@@ -0,0 +1,25 @@
+= v5, visitors are traversed in LIFO order.
+ // With nikic/php-parser < v5, visitors are traversed in FIFO order.
+
+ if (! method_exists('PhpParser\ParserFactory', 'create')) {
+ $visitors = array_reverse($visitors);
+ }
+
+ foreach ($visitors as $visitor) {
+ $traverser->addVisitor($visitor);
+ }
+ }
+}
diff --git a/src/Hal/Component/Ast/Php5NodeTraverser.php b/src/Hal/Component/Ast/Php5NodeTraverser.php
index c2ac9420..29e9df60 100644
--- a/src/Hal/Component/Ast/Php5NodeTraverser.php
+++ b/src/Hal/Component/Ast/Php5NodeTraverser.php
@@ -1,4 +1,5 @@
traverser = new Traverser($this, $stopCondition);
- }
-
- public function traverseNode(Node $node): Node
- {
- return parent::traverseNode($node);
- }
-
- protected function traverseArray(array $nodes): array
- {
- return $this->traverser->traverseArray($nodes, $this->visitors);
- }
}
diff --git a/src/Hal/Component/Ast/Php8NodeTraverser.php b/src/Hal/Component/Ast/Php8NodeTraverser.php
new file mode 100644
index 00000000..bb8753f7
--- /dev/null
+++ b/src/Hal/Component/Ast/Php8NodeTraverser.php
@@ -0,0 +1,14 @@
+enterNode($node);
if (Mother::DONT_TRAVERSE_CHILDREN === $return) {
$traverseChildren = false;
- } else if (null !== $return) {
+ } elseif (null !== $return) {
$node = $return;
}
}
diff --git a/src/Hal/Component/File/Finder.php b/src/Hal/Component/File/Finder.php
index 5ae3ce03..6269b6ae 100644
--- a/src/Hal/Component/File/Finder.php
+++ b/src/Hal/Component/File/Finder.php
@@ -18,7 +18,6 @@
*/
class Finder
{
-
/**
* Follow symlinks
*/
diff --git a/src/Hal/Component/Issue/Issuer.php b/src/Hal/Component/Issue/Issuer.php
index 58c802e1..bd1a7225 100644
--- a/src/Hal/Component/Issue/Issuer.php
+++ b/src/Hal/Component/Issue/Issuer.php
@@ -73,15 +73,14 @@ public function onError($errno, $errstr, $errfile, $errline)
$message = <<We're sorry : an unexpected error occured.
-
-Can you help us ? Please open a new issue at https://github.com/phpmetrics/PhpMetrics/issues/new, and copy-paste the content
+
+Can you help us ? Please open a new issue at https://github.com/phpmetrics/PhpMetrics/issues/new, and copy-paste the content
of this file: $logfile ?
Thanks for your help :)
-
EOT;
- $log = <<
-
EOT;
$this->output->write($message);
diff --git a/src/Hal/Component/Output/ProgressBar.php b/src/Hal/Component/Output/ProgressBar.php
index c5715d75..8ffeb510 100644
--- a/src/Hal/Component/Output/ProgressBar.php
+++ b/src/Hal/Component/Output/ProgressBar.php
@@ -14,7 +14,6 @@
*/
class ProgressBar
{
-
/**
* @var Output
*/
diff --git a/src/Hal/Component/Output/TestOutput.php b/src/Hal/Component/Output/TestOutput.php
index 35700a52..f5b70ab2 100644
--- a/src/Hal/Component/Output/TestOutput.php
+++ b/src/Hal/Component/Output/TestOutput.php
@@ -47,9 +47,7 @@ public function err($message)
/**
* @inheritdoc
*/
- public function clearln()
- {
- }
+ public function clearln() {}
/**
* @inheritdoc
diff --git a/src/Hal/Component/Tree/GraphException.php b/src/Hal/Component/Tree/GraphException.php
index 4682071c..428d3202 100644
--- a/src/Hal/Component/Tree/GraphException.php
+++ b/src/Hal/Component/Tree/GraphException.php
@@ -9,6 +9,4 @@
namespace Hal\Component\Tree;
-class GraphException extends \LogicException
-{
-}
+class GraphException extends \LogicException {}
diff --git a/src/Hal/Component/Tree/Node.php b/src/Hal/Component/Tree/Node.php
index f472a944..48f01025 100644
--- a/src/Hal/Component/Tree/Node.php
+++ b/src/Hal/Component/Tree/Node.php
@@ -11,7 +11,6 @@
class Node
{
-
/**
* @var mixed
*/
diff --git a/src/Hal/Metric/BagTrait.php b/src/Hal/Metric/BagTrait.php
index c7440816..0a2d792f 100644
--- a/src/Hal/Metric/BagTrait.php
+++ b/src/Hal/Metric/BagTrait.php
@@ -1,4 +1,5 @@
namespacedName->toString());
$class->set('interface', true);
$class->set('abstract', true);
} else {
- $name = (string)(isset($node->namespacedName) ? $node->namespacedName : 'anonymous@' . spl_object_hash($node));
+ $name = getNameOfNode($node);
$class = new ClassMetric($name);
$class->set('interface', false);
- $class->set('abstract', $node instanceof Stmt\Trait_ || $node->isAbstract());
- $class->set('final', !$node instanceof Stmt\Trait_ && $node->isFinal());
+
+ $isAbstract = false;
+ if ($node instanceof Stmt\Class_) {
+ $isAbstract = $node->isAbstract();
+ } elseif ($node instanceof Stmt\Trait_) {
+ $isAbstract = true; // Traits are always abstract
+ }
+
+ $isFinal = false;
+ if ($node instanceof Stmt\Class_) {
+ $isFinal = $node->isFinal();
+ } elseif ($node instanceof Stmt\Trait_) {
+ $isFinal = false; // Traits cannot be final
+ }
+
+ $class->set('abstract', $isAbstract);
+ $class->set('final', $isFinal);
}
$methods = [];
diff --git a/src/Hal/Metric/Class_/Complexity/CyclomaticComplexityVisitor.php b/src/Hal/Metric/Class_/Complexity/CyclomaticComplexityVisitor.php
index 52a19588..70aafcee 100644
--- a/src/Hal/Metric/Class_/Complexity/CyclomaticComplexityVisitor.php
+++ b/src/Hal/Metric/Class_/Complexity/CyclomaticComplexityVisitor.php
@@ -2,7 +2,7 @@
namespace Hal\Metric\Class_\Complexity;
-use Hal\Metric\Helper\MetricClassNameGenerator;
+use Hal\Component\Ast\NodeTyper;
use Hal\Metric\Helper\RoleOfMethodDetector;
use Hal\Metric\Metrics;
use PhpParser\Node;
@@ -53,11 +53,11 @@ public function __construct(Metrics $metrics)
public function leaveNode(Node $node)
{
- if ($node instanceof Stmt\Class_
- || $node instanceof Stmt\Interface_
- || $node instanceof Stmt\Trait_
- ) {
- $class = $this->metrics->get(MetricClassNameGenerator::getName($node));
+ if (NodeTyper::isOrganizedStructure($node)) {
+ $class = $this->metrics->get(getNameOfNode($node));
+ if ($class === null) {
+ throw new \RuntimeException('Class metric not found for ' . getNameOfNode($node));
+ }
$ccn = 1;
$wmc = 0;
diff --git a/src/Hal/Metric/Class_/Complexity/KanDefectVisitor.php b/src/Hal/Metric/Class_/Complexity/KanDefectVisitor.php
index b2492260..bb055e75 100644
--- a/src/Hal/Metric/Class_/Complexity/KanDefectVisitor.php
+++ b/src/Hal/Metric/Class_/Complexity/KanDefectVisitor.php
@@ -1,8 +1,9 @@
metrics->get(MetricClassNameGenerator::getName($node));
+ if (NodeTyper::isOrganizedStructure($node)) {
+ $class = $this->metrics->get(getNameOfNode($node));
$select = $while = $if = 0;
diff --git a/src/Hal/Metric/Class_/Component/MaintainabilityIndexVisitor.php b/src/Hal/Metric/Class_/Component/MaintainabilityIndexVisitor.php
index 3d33a4d9..cca79094 100644
--- a/src/Hal/Metric/Class_/Component/MaintainabilityIndexVisitor.php
+++ b/src/Hal/Metric/Class_/Component/MaintainabilityIndexVisitor.php
@@ -1,6 +1,8 @@
namespacedName) ? $node->namespacedName : 'anonymous@' . spl_object_hash($node));
+ if (NodeTyper::isOrganizedLogicalClassStructure($node)) {
+ $name = getNameOfNode($node);
$classOrFunction = $this->metrics->get($name);
+ if(null === $classOrFunction) {
+ throw new \LogicException('class or function ' . $name . ' not found in metrics');
+ }
+
if (null === $lloc = $classOrFunction->get('lloc')) {
throw new \LogicException('please enable length (lloc) visitor first');
}
@@ -68,7 +73,8 @@ public function leaveNode(Node $node)
// maintainability index without comment
$MIwoC = max(
- (171
+ (
+ 171
- (5.2 * \log($volume))
- (0.23 * $ccn)
- (16.2 * \log($lloc))
diff --git a/src/Hal/Metric/Class_/Coupling/ExternalsVisitor.php b/src/Hal/Metric/Class_/Coupling/ExternalsVisitor.php
index 86acf15c..be3870c4 100644
--- a/src/Hal/Metric/Class_/Coupling/ExternalsVisitor.php
+++ b/src/Hal/Metric/Class_/Coupling/ExternalsVisitor.php
@@ -1,7 +1,8 @@
uses = array_merge($this->uses, $node->uses);
}
- if ($node instanceof Stmt\Class_
- || $node instanceof Stmt\Interface_
- || $node instanceof Stmt\Trait_
- ) {
- $class = $this->metrics->get(MetricClassNameGenerator::getName($node));
+ if (NodeTyper::isOrganizedStructure($node)) {
+ $class = $this->metrics->get(getNameOfNode($node));
+
+ if(null === $class) {
+ throw new \RuntimeException('Class metric not found for ' . getNameOfNode($node));
+ }
+
$parents = [];
$interfaces = [];
@@ -59,21 +61,21 @@ public function leaveNode(Node $node)
// extends
if (isset($node->extends)) {
if (is_array($node->extends)) {
- foreach ((array)$node->extends as $interface) {
- $this->pushToDependencies($dependencies, (string)$interface);
- array_push($parents, (string)$interface);
+ foreach ((array) $node->extends as $interface) {
+ $this->pushToDependencies($dependencies, (string) $interface);
+ array_push($parents, (string) $interface);
}
} else {
- $this->pushToDependencies($dependencies, (string)$node->extends);
- array_push($parents, (string)$node->extends);
+ $this->pushToDependencies($dependencies, (string) $node->extends);
+ array_push($parents, (string) $node->extends);
}
}
// implements
if (isset($node->implements)) {
foreach ($node->implements as $interface) {
- $this->pushToDependencies($dependencies, (string)$interface);
- array_push($interfaces, (string)$interface);
+ $this->pushToDependencies($dependencies, (string) $interface);
+ array_push($interfaces, (string) $interface);
}
}
@@ -82,7 +84,7 @@ public function leaveNode(Node $node)
// return
if (isset($stmt->returnType)) {
if ($stmt->returnType instanceof Node\Name\FullyQualified) {
- $this->pushToDependencies($dependencies, (string)$stmt->returnType);
+ $this->pushToDependencies($dependencies, (string) $stmt->returnType);
}
}
@@ -90,7 +92,7 @@ public function leaveNode(Node $node)
foreach ($stmt->params as $param) {
if ($param->type) {
if ($param->type instanceof Node\Name\FullyQualified) {
- $this->pushToDependencies($dependencies, (string)$param->type);
+ $this->pushToDependencies($dependencies, (string) $param->type);
}
}
}
@@ -115,13 +117,13 @@ public function leaveNode(Node $node)
foreach ($matches[1] as $check) {
foreach ($this->uses as $use) {
if (method_exists($use, 'getAlias')) {
- if (((string)$use->getAlias()) === $check) {
- $this->pushToDependencies($dependencies, (string)($use->name));
+ if (((string) $use->getAlias()) === $check) {
+ $this->pushToDependencies($dependencies, (string) ($use->name));
}
continue;
}
if ($use->alias === $check) {
- $this->pushToDependencies($dependencies, (string)($use->name));
+ $this->pushToDependencies($dependencies, (string) ($use->name));
}
}
}
@@ -141,6 +143,6 @@ private function pushToDependencies(array &$dependencies, $dependency)
if ('self' === $lowercase || 'parent' === $lowercase) {
return;
}
- array_push($dependencies, (string)$dependency);
+ array_push($dependencies, (string) $dependency);
}
}
diff --git a/src/Hal/Metric/Class_/Structural/LcomVisitor.php b/src/Hal/Metric/Class_/Structural/LcomVisitor.php
index c537ca7b..4c93565b 100644
--- a/src/Hal/Metric/Class_/Structural/LcomVisitor.php
+++ b/src/Hal/Metric/Class_/Structural/LcomVisitor.php
@@ -1,9 +1,10 @@
metrics->get(MetricClassNameGenerator::getName($node));
+ $class = $this->metrics->get(getNameOfNode($node));
$roleDetector = new RoleOfMethodDetector();
diff --git a/src/Hal/Metric/Class_/Structural/SystemComplexityVisitor.php b/src/Hal/Metric/Class_/Structural/SystemComplexityVisitor.php
index e7aae6de..e4ccd95b 100644
--- a/src/Hal/Metric/Class_/Structural/SystemComplexityVisitor.php
+++ b/src/Hal/Metric/Class_/Structural/SystemComplexityVisitor.php
@@ -1,7 +1,8 @@
metrics->get(MetricClassNameGenerator::getName($node));
+ if (NodeTyper::isOrganizedLogicalClassStructure($node)) {
+ $class = $this->metrics->get(getNameOfNode($node));
+ if (null === $class) {
+ throw new \RuntimeException('Class metric not found for ' . getNameOfNode($node));
+ }
$sy = $dc = $sc = [];
diff --git a/src/Hal/Metric/Class_/Text/HalsteadVisitor.php b/src/Hal/Metric/Class_/Text/HalsteadVisitor.php
index f620f7a1..6e7d793b 100644
--- a/src/Hal/Metric/Class_/Text/HalsteadVisitor.php
+++ b/src/Hal/Metric/Class_/Text/HalsteadVisitor.php
@@ -2,6 +2,7 @@
namespace Hal\Metric\Class_\Text;
+use Hal\Component\Ast\NodeTyper;
use Hal\Metric\FunctionMetric;
use Hal\Metric\Metrics;
use Hoa\Ruler\Model\Bag\Scalar;
@@ -23,7 +24,6 @@
*/
class HalsteadVisitor extends NodeVisitorAbstract
{
-
/**
* @var Metrics
*/
@@ -42,12 +42,15 @@ public function __construct(Metrics $metrics)
*/
public function leaveNode(Node $node)
{
- if ($node instanceof Stmt\Class_ || $node instanceof Stmt\Function_ || $node instanceof Stmt\Trait_) {
- if ($node instanceof Stmt\Class_ || $node instanceof Stmt\Trait_) {
- $name = (string)(isset($node->namespacedName) ? $node->namespacedName : 'anonymous@' . spl_object_hash($node));
+ if (
+ NodeTyper::isOrganizedLogicalClassStructure($node)
+ || $node instanceof Stmt\Function_
+ ) {
+ if (NodeTyper::isOrganizedLogicalClassStructure($node) ) {
+ $name = getNameOfNode($node);
$classOrFunction = $this->metrics->get($name);
} else {
- $classOrFunction = new FunctionMetric((string)$node->name);
+ $classOrFunction = new FunctionMetric((string) $node->name);
$this->metrics->attach($classOrFunction);
}
diff --git a/src/Hal/Metric/Class_/Text/LengthVisitor.php b/src/Hal/Metric/Class_/Text/LengthVisitor.php
index e69c41f8..0fa26bf6 100644
--- a/src/Hal/Metric/Class_/Text/LengthVisitor.php
+++ b/src/Hal/Metric/Class_/Text/LengthVisitor.php
@@ -1,6 +1,8 @@
namespacedName) ? $node->namespacedName : 'anonymous@' . spl_object_hash($node));
+ if (
+ NodeTyper::isOrganizedLogicalClassStructure($node)
+ || $node instanceof Stmt\Function_
+ ) {
+ if (
+ NodeTyper::isOrganizedLogicalClassStructure($node)
+ ) {
+ $name = getNameOfNode($node);
$classOrFunction = $this->metrics->get($name);
} else {
- $classOrFunction = new FunctionMetric((string)$node->name);
+ $classOrFunction = new FunctionMetric((string) $node->name);
$this->metrics->attach($classOrFunction);
}
diff --git a/src/Hal/Metric/Consolidated.php b/src/Hal/Metric/Consolidated.php
index df3e9bd7..02b92c48 100644
--- a/src/Hal/Metric/Consolidated.php
+++ b/src/Hal/Metric/Consolidated.php
@@ -1,4 +1,5 @@
0,
'cloc' => 0,
'lloc' => 0,
'nbMethods' => 0,
];
- $avg = (object)[
+ $avg = (object) [
'wmc' => [],
'ccn' => [],
'bugs' => [],
@@ -107,7 +108,7 @@ public function __construct(Metrics $metrics)
foreach ($avg as &$a) {
if (count($a) > 0) {
- $a = round(array_sum((array)$a) / count($a), 2);
+ $a = round(array_sum((array) $a) / count($a), 2);
} else {
$a = 0;
}
@@ -166,7 +167,7 @@ public function __construct(Metrics $metrics)
$violations[$name]++;
}
}
- $sum->violations = (object)$violations;
+ $sum->violations = (object) $violations;
$this->avg = $avg;
$this->sum = $sum;
diff --git a/src/Hal/Metric/FileMetric.php b/src/Hal/Metric/FileMetric.php
index c4414910..67494477 100644
--- a/src/Hal/Metric/FileMetric.php
+++ b/src/Hal/Metric/FileMetric.php
@@ -1,4 +1,5 @@
isAnonymous()) ?
- 'anonymous@' . spl_object_hash($node) :
- $node->namespacedName->toString();
- }
-}
diff --git a/src/Hal/Metric/Helper/RoleOfMethodDetector.php b/src/Hal/Metric/Helper/RoleOfMethodDetector.php
index ed9633f4..10e00949 100644
--- a/src/Hal/Metric/Helper/RoleOfMethodDetector.php
+++ b/src/Hal/Metric/Helper/RoleOfMethodDetector.php
@@ -1,4 +1,5 @@
namespace = (string)$node->name;
+ $this->namespace = (string) $node->name;
}
}
@@ -51,8 +51,8 @@ public function leaveNode(Node $node)
$this->metrics->attach($packageMetric);
}
/* @var PackageMetric $packageMetric */
- $elementName = isset($node->namespacedName) ? $node->namespacedName : 'anonymous@' . spl_object_hash($node);
- $elementName = (string)$elementName;
+ $elementName = getNameOfNode($node);
+ $elementName = (string) $elementName;
$packageMetric->addClass($elementName);
$this->metrics->get($elementName)->set('package', $packageName);
diff --git a/src/Hal/Metric/Package/PackageDistance.php b/src/Hal/Metric/Package/PackageDistance.php
index 34f7a823..54881c8b 100644
--- a/src/Hal/Metric/Package/PackageDistance.php
+++ b/src/Hal/Metric/Package/PackageDistance.php
@@ -1,4 +1,5 @@
getOutgoingPackageDependencies());
$dependentInstabilities = array_combine(
diff --git a/src/Hal/Metric/PackageMetric.php b/src/Hal/Metric/PackageMetric.php
index ebc2cfce..46e31b49 100644
--- a/src/Hal/Metric/PackageMetric.php
+++ b/src/Hal/Metric/PackageMetric.php
@@ -18,7 +18,7 @@ public function getClasses()
public function addClass($name)
{
$elements = $this->get('classes');
- $elements[] = (string)$name;
+ $elements[] = (string) $name;
$this->set('classes', $elements);
}
@@ -26,7 +26,7 @@ public function addClass($name)
public function setAbstraction($abstraction)
{
if ($abstraction !== null) {
- $abstraction = (float)$abstraction;
+ $abstraction = (float) $abstraction;
}
$this->set('abstraction', $abstraction);
}
@@ -41,7 +41,7 @@ public function getAbstraction()
public function setInstability($instability)
{
if ($instability !== null) {
- $instability = (float)$instability;
+ $instability = (float) $instability;
}
$this->set('instability', $instability);
}
diff --git a/src/Hal/Metric/ProjectMetric.php b/src/Hal/Metric/ProjectMetric.php
index 04ffde84..70cce4d3 100644
--- a/src/Hal/Metric/ProjectMetric.php
+++ b/src/Hal/Metric/ProjectMetric.php
@@ -1,4 +1,5 @@
"PageRank for component",
];
- public function allForProject()
- {
- }
+ public function allForProject() {}
public function allForStructures()
{
diff --git a/src/Hal/Metric/SearchMetric.php b/src/Hal/Metric/SearchMetric.php
index 1be1fdf5..5de228d9 100644
--- a/src/Hal/Metric/SearchMetric.php
+++ b/src/Hal/Metric/SearchMetric.php
@@ -1,4 +1,5 @@
config->get('exclude'));
+ $exclude = $this->config->has('exclude') ? $this->config->get('exclude') : [];
+ $finder = new Finder(['json'], $exclude);
// include root dir by default
- $files = array_merge($this->config->get('files'), ['./']);
+ $files = $this->config->has('files') ? $this->config->get('files') : [];
+ $files = array_merge($files, ['./']);
$files = $finder->fetch($files);
foreach ($files as $filename) {
if (!\preg_match('/composer(-dist)?\.json/', $filename)) {
continue;
}
- $composerJson = (object)\json_decode(\file_get_contents($filename));
+ $composerJson = (object) \json_decode(\file_get_contents($filename));
if (!isset($composerJson->require)) {
continue;
}
- $rawRequirements[] = (array)$composerJson->require;
+ $rawRequirements[] = (array) $composerJson->require;
}
return \call_user_func_array('array_merge', $rawRequirements);
@@ -111,10 +112,12 @@ protected function getComposerLockInstalled($rootPackageRequirements)
$rawInstalled = [[]];
// Find composer.lock file
- $finder = new Finder(['lock'], $this->config->get('exclude'));
+ $exclude = $this->config->has('exclude') ? $this->config->get('exclude') : [];
+ $finder = new Finder(['lock'], $exclude);
// include root dir by default
- $files = array_merge($this->config->get('files'), ['./']);
+ $files = $this->config->has('files') ? $this->config->get('files') : [];
+ $files = array_merge($files, ['./']);
$files = $finder->fetch($files);
// List all composer.lock found in the project.
@@ -122,7 +125,7 @@ protected function getComposerLockInstalled($rootPackageRequirements)
if (false === \strpos($filename, 'composer.lock')) {
continue;
}
- $composerLockJson = (object)\json_decode(\file_get_contents($filename));
+ $composerLockJson = (object) \json_decode(\file_get_contents($filename));
if (!isset($composerLockJson->packages)) {
continue;
diff --git a/src/Hal/Metric/System/Packages/Composer/Packagist.php b/src/Hal/Metric/System/Packages/Composer/Packagist.php
index 3c130361..2880f30e 100644
--- a/src/Hal/Metric/System/Packages/Composer/Packagist.php
+++ b/src/Hal/Metric/System/Packages/Composer/Packagist.php
@@ -1,4 +1,5 @@
latest = null;
$response->license = [];
$response->homepage = null;
@@ -56,7 +56,7 @@ public function get($package)
// get latest version
$latest = '0.0.0';
- foreach ((array)$json->package->versions as $version => $datas) {
+ foreach ((array) $json->package->versions as $version => $datas) {
if ($version[0] === 'v') {
$version = substr($version, 1);
}
@@ -67,7 +67,7 @@ public function get($package)
$latest = $version;
$response->name = $package;
$response->latest = $version;
- $response->license = (array)$datas->license;
+ $response->license = (array) $datas->license;
$response->homepage = $datas->homepage;
$response->time = $datas->time;
$response->zip = $datas->dist->url;
diff --git a/src/Hal/Metric/System/UnitTesting/UnitTesting.php b/src/Hal/Metric/System/UnitTesting/UnitTesting.php
index fcfd1681..d8614812 100644
--- a/src/Hal/Metric/System/UnitTesting/UnitTesting.php
+++ b/src/Hal/Metric/System/UnitTesting/UnitTesting.php
@@ -1,8 +1,11 @@
query('//testsuite[@file]') as $suite) {
- array_push($testsuites, (object)[
+ array_push($testsuites, (object) [
'file' => $suite->getAttribute('file'),
'name' => $suite->getAttribute('name'),
'assertions' => $suite->getAttribute('assertions'),
@@ -98,7 +100,7 @@ public function calculate(Metrics $metrics)
$assertions = $case === $suite->firstChild->nextSibling ? $suite->getAttribute('assertions') : 0;
}
- $testsuites[$case->getAttribute('class')] = (object)[
+ $testsuites[$case->getAttribute('class')] = (object) [
'file' => $case->getAttribute('file'),
'name' => $case->getAttribute('class'),
'assertions' => $assertions,
@@ -110,11 +112,13 @@ public function calculate(Metrics $metrics)
// This code is slow and can be optimized
foreach ($testsuites as $suite) {
$metricsOfUnitTest = new Metrics();
- $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$traverser = new \PhpParser\NodeTraverser();
- $traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver());
- $traverser->addVisitor(new ClassEnumVisitor($metricsOfUnitTest));
- $traverser->addVisitor(new ExternalsVisitor($metricsOfUnitTest));
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new \PhpParser\NodeVisitor\NameResolver(),
+ new ClassEnumVisitor($metricsOfUnitTest),
+ new ExternalsVisitor($metricsOfUnitTest)
+ ]);
if (!file_exists($suite->file) || !is_readable($suite->file)) {
throw new \LogicException('Cannot find source file referenced in testsuite: ' . $suite->file);
@@ -130,10 +134,10 @@ public function calculate(Metrics $metrics)
// list of externals sources of unit test
$metric = $metricsOfUnitTest->get($suite->name);
- $externals = (array)$metric->get('externals');
+ $externals = (array) $metric->get('externals');
// global stats for each test
- $infoAboutTests[$suite->name] = (object)[
+ $infoAboutTests[$suite->name] = (object) [
'nbExternals' => count(array_unique($externals)),
'externals' => array_unique($externals),
'filename' => $suite->file,
diff --git a/src/Hal/Report/Cli/Reporter.php b/src/Hal/Report/Cli/Reporter.php
index 4a512ab1..d8e3f57a 100644
--- a/src/Hal/Report/Cli/Reporter.php
+++ b/src/Hal/Report/Cli/Reporter.php
@@ -1,4 +1,5 @@
config->get('searches')->get($searchName)->getConfig();
- if(!empty($foundSearch) && !empty($config->failIfFound) && true === $config->failIfFound) {
+ if (!empty($foundSearch) && !empty($config->failIfFound) && true === $config->failIfFound) {
$title = sprintf(
'[ERR] Found %d occurrences for search "%s"',
sizeof($foundSearch),
diff --git a/src/Hal/Report/Csv/Reporter.php b/src/Hal/Report/Csv/Reporter.php
index a09fa3e7..2e9ba022 100644
--- a/src/Hal/Report/Csv/Reporter.php
+++ b/src/Hal/Report/Csv/Reporter.php
@@ -1,4 +1,5 @@
$consolidated->getAvg(),
- 'sum' => $consolidated->getSum()
+ 'sum' => $consolidated->getSum(),
];
$files = glob($logDir . '/js/history-*.json');
$next = count($files) + 1;
@@ -252,7 +252,7 @@ protected function getTrend($type, $key, $lowIsBetter = false, $highIsBetter = f
}
$oldValue = $last->$type->$key;
- $newValue = isset($this->$type->$key) ? $this->$type->$key : 0;
+ $newValue = isset($this->sum->$type->$key) ? $this->sum->$type->$key : 0;
if ($newValue > $oldValue) {
$r = 'gt';
} elseif ($newValue < $oldValue) {
diff --git a/src/Hal/Report/Json/Reporter.php b/src/Hal/Report/Json/Reporter.php
index 49e13b0c..35637c4c 100644
--- a/src/Hal/Report/Json/Reporter.php
+++ b/src/Hal/Report/Json/Reporter.php
@@ -1,4 +1,5 @@
$this->sum->violations->error,
'warning' => $this->sum->violations->warning,
'information' => $this->sum->violations->information,
- ]
+ ],
];
}
}
diff --git a/src/Hal/Report/Violations/Xml/Reporter.php b/src/Hal/Report/Violations/Xml/Reporter.php
index 9cf57b8d..11682dd4 100644
--- a/src/Hal/Report/Violations/Xml/Reporter.php
+++ b/src/Hal/Report/Violations/Xml/Reporter.php
@@ -1,4 +1,5 @@
output->writeln('The DOM extension is not available. Please install it if you want to use the Xml Violations report.');
return;
}
diff --git a/src/Hal/Search/Search.php b/src/Hal/Search/Search.php
index 0cec8f6d..dec71bd7 100644
--- a/src/Hal/Search/Search.php
+++ b/src/Hal/Search/Search.php
@@ -26,7 +26,7 @@ class Search
public function __construct($name, array $config)
{
$this->name = $name;
- $this->config = (object)$config;
+ $this->config = (object) $config;
}
/**
@@ -47,7 +47,7 @@ public function getConfig()
public function matches(Metric $metric)
{
- $configAsArray = (array)$this->config;
+ $configAsArray = (array) $this->config;
if (!empty($this->config->type)) {
// Does the search concerns type ?
@@ -125,7 +125,7 @@ private function matchInstanceOf(Metric $metric, $instanceOf)
{
foreach ($instanceOf as $expectedInterface) {
$expectedInterface = ltrim($expectedInterface, '\\');
- if (!in_array($expectedInterface, (array)$metric->get('implements'))) {
+ if (!in_array($expectedInterface, (array) $metric->get('implements'))) {
return false;
}
}
@@ -136,7 +136,7 @@ private function matchInstanceOf(Metric $metric, $instanceOf)
private function usesClasses(Metric $metric, $usesClasses)
{
foreach ($usesClasses as $expectedClass) {
- foreach ((array)$metric->get('externals') as $use) {
+ foreach ((array) $metric->get('externals') as $use) {
if (preg_match('@' . $expectedClass . '@i', $use)) {
return true;
}
diff --git a/src/Hal/Search/Searches.php b/src/Hal/Search/Searches.php
index 86aa4692..817ecc9e 100644
--- a/src/Hal/Search/Searches.php
+++ b/src/Hal/Search/Searches.php
@@ -4,7 +4,6 @@
class Searches
{
-
/**
* @var array
*/
diff --git a/src/Hal/Search/SearchesValidator.php b/src/Hal/Search/SearchesValidator.php
index 38f526fd..f7014623 100644
--- a/src/Hal/Search/SearchesValidator.php
+++ b/src/Hal/Search/SearchesValidator.php
@@ -17,12 +17,12 @@ public function validates(Searches $searches)
'nameMatches',
'instanceOf',
'usesClasses',
- 'failIfFound'
+ 'failIfFound',
];
$registry = new Registry();
$allowedKeys = array_merge($allowedKeys, $registry->allForStructures());
- $diff = array_diff(array_keys((array)$config), $allowedKeys);
+ $diff = array_diff(array_keys((array) $config), $allowedKeys);
if (count($diff) > 0) {
throw new ConfigException(
sprintf(
diff --git a/src/Hal/Violation/Class_/Blob.php b/src/Hal/Violation/Class_/Blob.php
index de91e619..b90f0bdf 100644
--- a/src/Hal/Violation/Class_/Blob.php
+++ b/src/Hal/Violation/Class_/Blob.php
@@ -1,4 +1,5 @@
metric->get('nbMethodsPublic')}, excluding getters and setters)
-* object has a high Lack of cohesion of methods (LCOM={$this->metric->get('lcom')})
-* object knows everything (and use lot of external classes)
+ * object has lot of public methods ({$this->metric->get('nbMethodsPublic')}, excluding getters and setters)
+ * object has a high Lack of cohesion of methods (LCOM={$this->metric->get('lcom')})
+ * object knows everything (and use lot of external classes)
-Maybe you should reducing the number of methods splitting this object in many sub objects.
+ Maybe you should reducing the number of methods splitting this object in many sub objects.
EOT;
}
}
diff --git a/src/Hal/Violation/Class_/ProbablyBugged.php b/src/Hal/Violation/Class_/ProbablyBugged.php
index c0472de8..1b12fa26 100644
--- a/src/Hal/Violation/Class_/ProbablyBugged.php
+++ b/src/Hal/Violation/Class_/ProbablyBugged.php
@@ -1,4 +1,5 @@
metric->get('bugs')} bugs.
+ This component contains in theory {$this->metric->get('bugs')} bugs.
-* Calculation is based on number of operators, operands, cyclomatic complexity
-* See more details at https://en.wikipedia.org/wiki/Halstead_complexity_measures
-* {$this->metric->get('numberOfUnitTests')} testsuites has dependency to this class.
+ * Calculation is based on number of operators, operands, cyclomatic complexity
+ * See more details at https://en.wikipedia.org/wiki/Halstead_complexity_measures
+ * {$this->metric->get('numberOfUnitTests')} testsuites has dependency to this class.
-Maybe you should check your unit tests for this class.
+ Maybe you should check your unit tests for this class.
EOT;
}
}
diff --git a/src/Hal/Violation/Class_/TooComplexClassCode.php b/src/Hal/Violation/Class_/TooComplexClassCode.php
index 1e697ad1..d772b003 100644
--- a/src/Hal/Violation/Class_/TooComplexClassCode.php
+++ b/src/Hal/Violation/Class_/TooComplexClassCode.php
@@ -1,4 +1,5 @@
metric->get('ccn')})
-* Component uses {$this->metric->get('number_operators')} operators
+ * Algorithms are complex (Total cyclomatic complexity of class is {$this->metric->get('ccn')})
+ * Component uses {$this->metric->get('number_operators')} operators
-Maybe you should delegate some code to other objects.
+ Maybe you should delegate some code to other objects.
EOT;
}
}
diff --git a/src/Hal/Violation/Class_/TooComplexMethodCode.php b/src/Hal/Violation/Class_/TooComplexMethodCode.php
index 8e111c7a..38e9274b 100644
--- a/src/Hal/Violation/Class_/TooComplexMethodCode.php
+++ b/src/Hal/Violation/Class_/TooComplexMethodCode.php
@@ -1,4 +1,5 @@
metric->get('ccnMethodMax')})
+ * Algorithms are complex (Max cyclomatic complexity of class methods is {$this->metric->get('ccnMethodMax')})
-Maybe you should delegate some code to other objects or split complex method.
+ Maybe you should delegate some code to other objects or split complex method.
EOT;
}
}
diff --git a/src/Hal/Violation/Class_/TooDependent.php b/src/Hal/Violation/Class_/TooDependent.php
index a727346a..60d3fbfb 100644
--- a/src/Hal/Violation/Class_/TooDependent.php
+++ b/src/Hal/Violation/Class_/TooDependent.php
@@ -1,4 +1,5 @@
metric->get('efferentCoupling')}, so this class uses {$this->metric->get('efferentCoupling')} different external components.
+ * Efferent coupling is {$this->metric->get('efferentCoupling')}, so this class uses {$this->metric->get('efferentCoupling')} different external components.
-Maybe you should check why this class has lot of dependencies.
+ Maybe you should check why this class has lot of dependencies.
EOT;
}
}
diff --git a/src/Hal/Violation/Class_/TooLong.php b/src/Hal/Violation/Class_/TooLong.php
index 1c7b6da3..7d3ef77a 100644
--- a/src/Hal/Violation/Class_/TooLong.php
+++ b/src/Hal/Violation/Class_/TooLong.php
@@ -1,4 +1,5 @@
metric->get('lloc')} logical lines of code
-* Class has {$this->metric->get('loc')} lines of code
+ * Class has {$this->metric->get('lloc')} logical lines of code
+ * Class has {$this->metric->get('loc')} lines of code
-Maybe your class should not exceed 200 lines of logical code
+ Maybe your class should not exceed 200 lines of logical code
EOT;
}
}
diff --git a/src/Hal/Violation/Package/StableAbstractionsPrinciple.php b/src/Hal/Violation/Package/StableAbstractionsPrinciple.php
index c8ad81b4..c5894b11 100644
--- a/src/Hal/Violation/Package/StableAbstractionsPrinciple.php
+++ b/src/Hal/Violation/Package/StableAbstractionsPrinciple.php
@@ -21,7 +21,7 @@ public function apply(Metric $metric)
if (! $metric instanceof PackageMetric) {
return;
}
- if (abs($metric->getDistance()) > sqrt(2)/4) {
+ if (abs($metric->getDistance()) > sqrt(2) / 4) {
$this->metric = $metric;
$metric->get('violations')->add($this);
}
@@ -39,9 +39,9 @@ public function getDescription()
: 'stable and concrete';
return <<violatingInstabilities), $this->violatingInstabilities));
return <<all() as $metric) {
- $metric->set('violations', new Violations);
+ $metric->set('violations', new Violations());
foreach ($violations as $violation) {
$violation->apply($metric);
diff --git a/src/Hal/Violation/Violations.php b/src/Hal/Violation/Violations.php
index 70a1502a..91ae0193 100644
--- a/src/Hal/Violation/Violations.php
+++ b/src/Hal/Violation/Violations.php
@@ -1,4 +1,5 @@
namespacedName) && null !== $node->namespacedName) {
+ // Return the fully qualified name of the class, interface, or trait
+ return (string) $node->namespacedName;
+ }
+
if ($node instanceof \PhpParser\Node\Name\FullyQualified) {
- return (string)$node;
+ return (string) $node;
}
+
if ($node instanceof \PhpParser\Node\Expr\New_) {
return getNameOfNode($node->class);
}
@@ -97,7 +102,10 @@ function getNameOfNode($node)
}
if ($node instanceof \PhpParser\Node\Name) {
- return (string)implode($node->parts);
+ if(!property_exists($node, 'parts') || null === $node->parts) {
+ return (string) $node->name;
+ }
+ return (string) implode($node->parts);
}
if (isset($node->name) && $node->name instanceof \PhpParser\Node\Expr\Variable) {
@@ -124,12 +132,13 @@ function getNameOfNode($node)
return getNameOfNode($node->name);
}
- if (isset($node->name) && null === $node->name) {
+ // do not use isset here, we want to check if property is set
+ if (property_exists($node, 'name') && null === $node->name) {
return 'anonymous@' . spl_object_hash($node);
}
if (isset($node->name)) {
- return (string)$node->name;
+ return (string) $node->name;
}
return null;
@@ -175,16 +184,16 @@ function gradientAlphaFor($array, $attribute, $currentValue)
{
// memory cache
static $caches;
- if(null === $caches) {
+ if (null === $caches) {
$caches = [];
}
- if(!isset($caches[$attribute])) {
+ if (!isset($caches[$attribute])) {
// avoid to iterate over array too many times
$max = 0;
$min = 1;
- foreach($array as $item) {
- if(!isset($item[$attribute])) {
+ foreach ($array as $item) {
+ if (!isset($item[$attribute])) {
continue;
}
@@ -211,7 +220,8 @@ function gradientAlphaFor($array, $attribute, $currentValue)
* @param mixed $currentValue
* @return string
*/
-function gradientStyleFor($array, $attribute, $currentValue) {
+function gradientStyleFor($array, $attribute, $currentValue)
+{
return sprintf(' style="background-color: hsla(203, 82%%, 76%%, %s);"', gradientAlphaFor($array, $attribute, $currentValue));
}
diff --git a/tests/Application/Config/File/ConfigFileReaderTest.php b/tests/Application/Config/File/ConfigFileReaderTest.php
index 2dc8fa04..e843d766 100644
--- a/tests/Application/Config/File/ConfigFileReaderTest.php
+++ b/tests/Application/Config/File/ConfigFileReaderTest.php
@@ -11,7 +11,7 @@
*/
class ConfigFileReaderTest extends \PHPUnit\Framework\TestCase
{
- public function testICanParseBasicJsonFIle()
+ public function testICanParseBasicJsonFIle(): void
{
$filename = __DIR__ . '/examples/config.json';
@@ -55,7 +55,7 @@ private function getExpectedData()
];
}
- public function testICanParseConfigWithSearch()
+ public function testICanParseConfigWithSearch(): void
{
$filename = __DIR__ . '/examples/config-with-search.json';
diff --git a/tests/Application/Config/ParserTest.php b/tests/Application/Config/ParserTest.php
index 62a57d20..aa4cfbcf 100644
--- a/tests/Application/Config/ParserTest.php
+++ b/tests/Application/Config/ParserTest.php
@@ -2,6 +2,7 @@
namespace Test\Hal\Application\Config;
use Hal\Application\Config\Parser;
+use PHPUnit\Framework\Attributes\DataProvider;
/**
* @group application
@@ -12,14 +13,15 @@ class ParserTest extends \PHPUnit\Framework\TestCase
/**
* @dataProvider providesExample
*/
- public function testICanParseArguments($argv, $expected)
+ #[DataProvider('providesExample')]
+ public function testICanParseArguments($argv, $expected): void
{
$parser = new Parser();
$config = $parser->parse($argv);
$this->assertEquals($expected, $config->all());
}
- public function providesExample()
+ public static function providesExample()
{
return [
[
diff --git a/tests/Component/Ast/NodeTraverserTest.php b/tests/Component/Ast/NodeTraverserTest.php
index 1593285f..601db156 100644
--- a/tests/Component/Ast/NodeTraverserTest.php
+++ b/tests/Component/Ast/NodeTraverserTest.php
@@ -7,7 +7,7 @@
class NodeTraverserTest extends TestCase
{
- public function testItCanBeInstantiated()
+ public function testItCanBeInstantiated(): void
{
$this->assertInstanceOf(BaseTraverser::class, new NodeTraverser());
}
diff --git a/tests/Component/Ast/SupportedVersionTest.php b/tests/Component/Ast/SupportedVersionTest.php
new file mode 100644
index 00000000..3d9ea49b
--- /dev/null
+++ b/tests/Component/Ast/SupportedVersionTest.php
@@ -0,0 +1,70 @@
+analyze([__DIR__ . '/dataset/' . $filename . '.php']);
+
+ /** @var ClassMetric $class */
+ $class = $metrics->get($classname);
+ $this->assertInstanceOf(ClassMetric::class, $class);
+ foreach ($expected as $key => $value) {
+ $this->assertEquals($value, $class->get($key), "[PHP $filename] Class $classname metric $key does not match expected value");
+ }
+ }
+
+ public static function providesCases()
+ {
+ // for php < 7.0, the class is not supported
+ if (version_compare(PHP_VERSION, '7.0.0', '<')) {
+ return [];
+ }
+
+ $cases = [];
+ if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
+ $cases['php7.1.void'] = ['php7.1.void', 'Foo', ['nbMethods' => 1, 'number_operands_unique' => 1]];
+ }
+ if (version_compare(PHP_VERSION, '7.2.0', '>=')) {
+ $cases['php7.2.trailcomma'] = ['php7.2.trailcomma', 'Foo', ['nbMethods' => 1, 'number_operands_unique' => 2]];
+ }
+ if (version_compare(PHP_VERSION, '7.3.0', '>=')) {
+ $cases['php7.3.heredoc'] = ['php7.3.heredoc', 'Foo', ['nbMethods' => 1, 'number_operands_unique' => 2]];
+ }
+ if (version_compare(PHP_VERSION, '7.4.0', '>=')) {
+ $cases['php7.4.typedprop'] = ['php7.4.typedprop', 'Foo', ['nbMethods' => 1, 'number_operands_unique' => 1]];
+ }
+ if (version_compare(PHP_VERSION, '8.0.0', '>=')) {
+ $cases['php8.0.uniontype'] = ['php8.0.uniontype', 'Foo', ['nbMethods' => 1, 'number_operands_unique' => 1]];
+ }
+ if (version_compare(PHP_VERSION, '8.1.0', '>=')) {
+ $cases['php8.1.readonlyproperty'] = ['php8.1.readonlyproperty', 'Foo', ['nbMethods' => 0, 'number_operands_unique' => 2]];
+ }
+ if (version_compare(PHP_VERSION, '8.2.0', '>=')) {
+ $cases['php8.2.truetype'] = ['php8.2.truetype', 'Foo', ['nbMethods' => 1, 'number_operands_unique' => 1]];
+ }
+ if (version_compare(PHP_VERSION, '8.3.0', '>=')) {
+ $cases['php8.3.jsonconst'] = ['php8.3.jsonconst', 'Foo', ['nbMethods' => 1, 'number_operands_unique' => 1]];
+ }
+ if (version_compare(PHP_VERSION, '8.4.0', '>=')) {
+ $cases['php8.4.propertyhook'] = ['php8.4.propertyhook', 'Foo', ['nbMethods' => 0, 'number_operands_unique' => 2]];
+ }
+
+ return $cases;
+ }
+}
diff --git a/tests/Component/Ast/dataset/php7.0.coalesce.php b/tests/Component/Ast/dataset/php7.0.coalesce.php
new file mode 100644
index 00000000..3bf68d37
--- /dev/null
+++ b/tests/Component/Ast/dataset/php7.0.coalesce.php
@@ -0,0 +1,9 @@
+bar = $bar;
+ }
+}
diff --git a/tests/Component/Ast/dataset/php8.2.truetype.php b/tests/Component/Ast/dataset/php8.2.truetype.php
new file mode 100644
index 00000000..24857d33
--- /dev/null
+++ b/tests/Component/Ast/dataset/php8.2.truetype.php
@@ -0,0 +1,8 @@
+countryCode = strtoupper($countryCode);
+ }
+ }
+}
diff --git a/tests/Component/File/FinderTest.php b/tests/Component/File/FinderTest.php
index 3e1a6590..ae971b0b 100644
--- a/tests/Component/File/FinderTest.php
+++ b/tests/Component/File/FinderTest.php
@@ -10,7 +10,7 @@
*/
class FinderTest extends TestCase
{
- public function testPathsGivenAreRecoveredOverExcluded()
+ public function testPathsGivenAreRecoveredOverExcluded(): void
{
$exampleRoot = __DIR__ . DIRECTORY_SEPARATOR . 'examples';
@@ -37,7 +37,7 @@ public function testPathsGivenAreRecoveredOverExcluded()
static::assertSame($expected, $files);
}
- public function testGivenPathsAreIgnoredRegardingExclusion()
+ public function testGivenPathsAreIgnoredRegardingExclusion(): void
{
$exampleRoot = __DIR__ . DIRECTORY_SEPARATOR . 'examples';
$actualFoundFiles = (new Finder(['php'], ['tests']))->fetch([$exampleRoot]);
diff --git a/tests/Component/Issuer/IssuerTest.php b/tests/Component/Issuer/IssuerTest.php
index cf7550c6..bfd830fc 100644
--- a/tests/Component/Issuer/IssuerTest.php
+++ b/tests/Component/Issuer/IssuerTest.php
@@ -2,36 +2,47 @@
namespace Test\Hal\Component\Issue;
+use Hal\Component\Ast\ParserFactoryBridge;
use Hal\Component\Issue\Issuer;
use Hal\Component\Output\TestOutput;
use PhpParser\ParserFactory;
+use PHPUnit\Framework\Attributes\RequiresPhp;
+use Polyfill\TestCaseCompatible;
/**
* @group issue
*/
class IssuerTest extends \PHPUnit\Framework\TestCase
{
- public function testICanEnableIssuerPhp5()
+ use TestCaseCompatible;
+ /**
+ * @requires PHP < 7.0
+ */
+ #[RequiresPhp('< 7.0')]
+ public function testICanEnableIssuerPhp5(): void
{
$output = new TestOutput();
$issuer = (new TestIssuer($output))->enable();
$issuer->set('Firstname', 'Jean-François');
try {
- trigger_error('Object of class stdClass could not be converted to string', E_USER_ERROR);
+ trigger_error('Object of class stdClass could not be converted to string', E_USER_WARNING);
} catch (\Exception $e) {
}
- $this->assertContains('Object of class stdClass could not be converted to string', $issuer->log);
- $this->assertContains('Operating System', $issuer->log);
- $this->assertContains('Details', $issuer->log);
- $this->assertContains('https://github.com/phpmetrics/PhpMetrics/issues/new', $output->output);
- $this->assertContains('Firstname: Jean-François', $issuer->log);
- $this->assertContains('IssuerTest.php (line 21)', $issuer->log);
+ $this->assertStringContainsString('Object of class stdClass could not be converted to string', $issuer->log);
+ $this->assertStringContainsString('Operating System', $issuer->log);
+ $this->assertStringContainsString('Details', $issuer->log);
+ $this->assertStringContainsString('https://github.com/phpmetrics/PhpMetrics/issues/new', $output->output);
+ $this->assertStringContainsString('Firstname: Jean-François', $issuer->log);
+ $this->assertStringContainsString('IssuerTest.php (line 29)', $issuer->log);
$issuer->disable();
}
- public function testIssuerDisplayStatements()
+ /**
+ * @requires PHP < 7.0
+ */
+ public function testIssuerDisplayStatements(): void
{
$output = new TestOutput();
$issuer = (new TestIssuer($output))->enable();
@@ -39,12 +50,12 @@ public function testIssuerDisplayStatements()
create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$stmt = $parser->parse($code);
$issuer->set('code', $stmt);
@@ -54,7 +65,7 @@ public function foo() {
}
$issuer->disable();
- $this->assertContains('class A', $issuer->log);
+ $this->assertStringContainsString('class A', $issuer->log);
}
}
diff --git a/tests/Component/Tree/GraphDeduplicatedTest.php b/tests/Component/Tree/GraphDeduplicatedTest.php
index 139000e0..03ee7563 100644
--- a/tests/Component/Tree/GraphDeduplicatedTest.php
+++ b/tests/Component/Tree/GraphDeduplicatedTest.php
@@ -12,7 +12,7 @@
class GraphDeduplicatedTest extends \PHPUnit\Framework\TestCase
{
- public function testEdgeDeduplication()
+ public function testEdgeDeduplication(): void
{
$graph = new GraphDeduplicated();
$a = new Node('A');
diff --git a/tests/Component/Tree/GraphTest.php b/tests/Component/Tree/GraphTest.php
index bc12875c..1f8aabfc 100644
--- a/tests/Component/Tree/GraphTest.php
+++ b/tests/Component/Tree/GraphTest.php
@@ -10,7 +10,7 @@
*/
class GraphTest extends \PHPUnit\Framework\TestCase
{
- public function testICanAddEdge()
+ public function testICanAddEdge(): void
{
$graph = new Graph();
$a = new Node('node_a');
@@ -27,11 +27,9 @@ public function testICanAddEdge()
$this->assertSame($b, $a->getEdges()[0]->getTo());
}
- /**
- * @expectedException \LogicException
- */
- public function testICanAddEdgeWithUnexistantFromNode()
+ public function testICanAddEdgeWithUnexistantFromNode(): void
{
+ $this->expectException(\LogicException::class);
$graph = new Graph();
$a = new Node('A');
$b = new Node('B');
@@ -40,11 +38,9 @@ public function testICanAddEdgeWithUnexistantFromNode()
$graph->addEdge($a, $b);
}
- /**
- * @expectedException \LogicException
- */
- public function testICanAddEdgeWithUnexistantToNode()
+ public function testICanAddEdgeWithUnexistantToNode(): void
{
+ $this->expectException(\LogicException::class);
$graph = new Graph();
$a = new Node('A');
$b = new Node('B');
@@ -53,18 +49,16 @@ public function testICanAddEdgeWithUnexistantToNode()
$graph->addEdge($a, $b);
}
- /**
- * @expectedException \LogicException
- */
- public function testICanInsertSameNodeTwice()
+ public function testICanInsertSameNodeTwice(): void
{
+ $this->expectException(\LogicException::class);
$graph = new Graph();
$node = new Node('A');
$graph->insert($node);
$graph->insert($node);
}
- public function testICanListEdges()
+ public function testICanListEdges(): void
{
$graph = new Graph();
$a = new Node('A');
@@ -77,7 +71,7 @@ public function testICanListEdges()
$this->assertCount(1, $graph->getEdges());
}
- public function testEdgeIsAddedToFromAndToNode()
+ public function testEdgeIsAddedToFromAndToNode(): void
{
$graph = new Graph();
$a = new Node('A');
@@ -96,7 +90,7 @@ public function testEdgeIsAddedToFromAndToNode()
}
- public function testICanListRootNodes()
+ public function testICanListRootNodes(): void
{
$graph = new Graph();
$a = new Node('A'); // root
diff --git a/tests/Component/Tree/HashMapTest.php b/tests/Component/Tree/HashMapTest.php
index 16b81004..b37d5779 100644
--- a/tests/Component/Tree/HashMapTest.php
+++ b/tests/Component/Tree/HashMapTest.php
@@ -11,7 +11,7 @@
class HashMapTest extends \PHPUnit\Framework\TestCase
{
- public function testICanWorkWithHashMap()
+ public function testICanWorkWithHashMap(): void
{
$hash = new HashMap;
$hash
@@ -28,7 +28,7 @@ public function testICanWorkWithHashMap()
$this->assertEquals($node2, $hash->get('B'));
}
- public function testICanIterateThroughHashMap()
+ public function testICanIterateThroughHashMap(): void
{
$hash = new HashMap;
$hash
diff --git a/tests/Component/Tree/NodeTest.php b/tests/Component/Tree/NodeTest.php
index cb6f2996..588c368f 100644
--- a/tests/Component/Tree/NodeTest.php
+++ b/tests/Component/Tree/NodeTest.php
@@ -10,7 +10,7 @@
*/
class NodeTest extends \PHPUnit\Framework\TestCase
{
- public function testICanWorkWithNode()
+ public function testICanWorkWithNode(): void
{
$node = new Node('A');
$to = new Node('B');
diff --git a/tests/Component/Tree/Operator/CycleDetectorTest.php b/tests/Component/Tree/Operator/CycleDetectorTest.php
index ab0986b8..87f5be52 100644
--- a/tests/Component/Tree/Operator/CycleDetectorTest.php
+++ b/tests/Component/Tree/Operator/CycleDetectorTest.php
@@ -11,7 +11,7 @@
*/
class CycleDetectorTest extends \PHPUnit\Framework\TestCase
{
- public function testCycleIsDetected()
+ public function testCycleIsDetected(): void
{
$graph = new Graph();
$a = new Node('A');
@@ -45,7 +45,7 @@ public function testCycleIsDetected()
$this->assertFalse($f->cyclic);
}
- public function testAllCyclesAreFound()
+ public function testAllCyclesAreFound(): void
{
$graph = new Graph();
$a = new Node('A');
@@ -79,7 +79,7 @@ public function testAllCyclesAreFound()
$this->assertTrue($f->cyclic);
}
- public function testCycleIsNotDetected()
+ public function testCycleIsNotDetected(): void
{
$graph = new Graph();
$a = new Node('A');
@@ -112,7 +112,7 @@ public function testCycleIsNotDetected()
$this->assertFalse($f->cyclic);
}
- public function testPartCycleIsDetected()
+ public function testPartCycleIsDetected(): void
{
$graph = new Graph();
$a = new Node('A');
diff --git a/tests/Component/Tree/Operator/SizeOfTreeTest.php b/tests/Component/Tree/Operator/SizeOfTreeTest.php
index 10b62ef3..3db8befd 100644
--- a/tests/Component/Tree/Operator/SizeOfTreeTest.php
+++ b/tests/Component/Tree/Operator/SizeOfTreeTest.php
@@ -13,12 +13,10 @@
class SizeOfTreeTest extends \PHPUnit\Framework\TestCase
{
- /**
- * @expectedException LogicException
- * @expectedExceptionMessage Cannot get size informations of cyclic graph
- */
- public function testICannotGetInfoAboutGraphWhenItIsCyclic()
+ public function testICannotGetInfoAboutGraphWhenItIsCyclic(): void
{
+ $this->expectException(\LogicException::class);
+ $this->expectExceptionMessage('Cannot get size informations of cyclic graph');
$graph = new Graph();
$a = new Node('A');
$b = new Node('B');
@@ -32,7 +30,7 @@ public function testICannotGetInfoAboutGraphWhenItIsCyclic()
$size = new SizeOfTree($graph);
}
- public function testICanGetDepthOfNode()
+ public function testICanGetDepthOfNode(): void
{
$graph = new Graph();
$a = new Node('A');
@@ -58,7 +56,7 @@ public function testICanGetDepthOfNode()
$this->assertEquals(1, $size->getDepthOfNode($e));
}
- public function testICanGetNbChildsOfNode()
+ public function testICanGetNbChildsOfNode(): void
{
$graph = new Graph();
$a = new Node('A');
@@ -84,7 +82,7 @@ public function testICanGetNbChildsOfNode()
$this->assertEquals(0, $size->getNumberOfChilds($e));
}
- public function testICanGetInfoAboutAverageHeightOfTree()
+ public function testICanGetInfoAboutAverageHeightOfTree(): void
{
$graph = new Graph();
$a = new Node('A');
diff --git a/tests/Functions/GetNameOfNodeTest.php b/tests/Functions/GetNameOfNodeTest.php
new file mode 100644
index 00000000..fc53d4b4
--- /dev/null
+++ b/tests/Functions/GetNameOfNodeTest.php
@@ -0,0 +1,86 @@
+create();
+ $stmts = $parser->parse($code);
+
+ $traverser = new NodeTraverser();
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new NameResolver()
+ ]);
+ $traverser->traverse($stmts);
+
+ $node = $stmts[0];
+ $name = getNameOfNode($node);
+ $this->assertEquals('Foo', $name);
+ }
+
+ public function testNameInNamespaceIsCorrect(): void
+ {
+ $code = 'create();
+ $stmts = $parser->parse($code);
+
+ $traverser = new NodeTraverser();
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new NameResolver()
+ ]);
+ $traverser->traverse($stmts);
+
+ // namespace
+ $node = $stmts[0];
+ $name = getNameOfNode($node);
+ $this->assertEquals('Bar', $name);
+
+ // class
+ $node = $node->stmts[0];
+ $this->assertInstanceOf(Class_::class, $node);
+ $name = getNameOfNode($node);
+ $this->assertEquals('Bar\\Foo', $name);
+ }
+ public function testItCanNameAnonymousClass() : void
+ {
+ $code = 'create();
+ $stmts = $parser->parse($code);
+
+ $traverser = new NodeTraverser();
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new NameResolver()
+ ]);
+ $traverser->traverse($stmts);
+
+ // class
+ $node = $stmts[0];
+ $name = getNameOfNode($node);
+ $this->assertEquals('Foo', $name);
+
+ // anonymous class
+ $node = $node->stmts[0]->stmts[0]->expr->class;
+
+ if(method_exists($this, 'assertMatchesRegularExpression')) {
+ $this->assertMatchesRegularExpression('/^anonymous/', getNameOfNode($node));
+ } else {
+ $this->assertRegExp('/^anonymous/', getNameOfNode($node));;
+ }
+ }
+}
diff --git a/tests/Metric/Class_/ClassEnumVisitorTest.php b/tests/Metric/Class_/ClassEnumVisitorTest.php
index 76cb6c89..b44654fc 100644
--- a/tests/Metric/Class_/ClassEnumVisitorTest.php
+++ b/tests/Metric/Class_/ClassEnumVisitorTest.php
@@ -1,11 +1,13 @@
analyzeCode($code);
@@ -62,7 +65,7 @@ public static function provideExamples()
private function analyzeCode($code)
{
$metrics = new Metrics();
- $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$traverser = new NodeTraverser();
$traverser->addVisitor(new NameResolver());
$traverser->addVisitor(new ClassEnumVisitor($metrics));
@@ -73,7 +76,7 @@ private function analyzeCode($code)
return $metrics;
}
- public function testAnonymousClassIsHandledCorrectly()
+ public function testAnonymousClassIsHandledCorrectly(): void
{
$code = 'analyzeCode($code);
@@ -84,7 +87,7 @@ public function testAnonymousClassIsHandledCorrectly()
/**
* @link https://github.com/phpmetrics/PhpMetrics/issues/238
*/
- public function testDynamicAttributeClassIsHandledCorrectly()
+ public function testDynamicAttributeClassIsHandledCorrectly(): void
{
$code = '
class A {
@@ -105,7 +108,7 @@ public function foo() {
/**
* @link https://github.com/phpmetrics/PhpMetrics/issues/238#issuecomment-292466274
*/
- public function testDynamicAttributeClassIsHandledCorrectly2()
+ public function testDynamicAttributeClassIsHandledCorrectly2(): void
{
$code = 'assertInstanceOf(Metrics::class, $metrics);
}
- public function testItDoesNotMarkClassesAsAbstract()
+ public function testItDoesNotMarkClassesAsAbstract(): void
{
$code = 'analyzeCode($code);
$this->assertFalse($metrics->get('Foo')->get('abstract'));
}
- public function testItMarksAbstractClassesAsAbstract()
+ public function testItMarksAbstractClassesAsAbstract(): void
{
$code = 'analyzeCode($code);
$this->assertTrue($metrics->get('Foo')->get('abstract'));
}
- public function testItMarksInterfacesAsAbstract()
+ public function testItMarksInterfacesAsAbstract(): void
{
$code = 'analyzeCode($code);
$this->assertTrue($metrics->get('Foo')->get('abstract'));
}
- public function testItMarksTraitsAsAbstract()
+ public function testItMarksTraitsAsAbstract(): void
{
$code = 'analyzeCode($code);
diff --git a/tests/Metric/Class_/Complexity/CyclomaticComplexityVisitorTest.php b/tests/Metric/Class_/Complexity/CyclomaticComplexityVisitorTest.php
index 2f0c523d..be7fd42c 100644
--- a/tests/Metric/Class_/Complexity/CyclomaticComplexityVisitorTest.php
+++ b/tests/Metric/Class_/Complexity/CyclomaticComplexityVisitorTest.php
@@ -1,27 +1,33 @@
create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$traverser = new NodeTraverser();
- $traverser->addVisitor(new NameResolver());
- $traverser->addVisitor(new ClassEnumVisitor($metrics));
- $traverser->addVisitor(new CyclomaticComplexityVisitor($metrics));
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new NameResolver(),
+ new ClassEnumVisitor($metrics),
+ new CyclomaticComplexityVisitor($metrics),
+ ]);
$code = file_get_contents($example);
$stmts = $parser->parse($code);
@@ -33,15 +39,18 @@ public function testCcnOfClassesIsWellCalculated($example, $classname, $expected
/**
* @dataProvider provideExamplesForWmc
*/
- public function testWeightedMethodCountOfClassesIsWellCalculated($example, $classname, $expectedWmc)
+ #[DataProvider('provideExamplesForWmc')]
+ public function testWeightedMethodCountOfClassesIsWellCalculated($example, $classname, $expectedWmc): void
{
$metrics = new Metrics();
- $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge)->create();
$traverser = new NodeTraverser();
- $traverser->addVisitor(new NameResolver());
- $traverser->addVisitor(new ClassEnumVisitor($metrics));
- $traverser->addVisitor(new CyclomaticComplexityVisitor($metrics));
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new NameResolver(),
+ new ClassEnumVisitor($metrics),
+ new CyclomaticComplexityVisitor($metrics),
+ ]);
$code = file_get_contents($example);
$stmts = $parser->parse($code);
@@ -53,15 +62,18 @@ public function testWeightedMethodCountOfClassesIsWellCalculated($example, $clas
/**
* @dataProvider provideExamplesForMaxCc
*/
- public function testMaximalCyclomaticComplexityOfMethodsIsWellCalculated($example, $classname, $expectedCcnMethodMax)
+ #[DataProvider('provideExamplesForMaxCc')]
+ public function testMaximalCyclomaticComplexityOfMethodsIsWellCalculated($example, $classname, $expectedCcnMethodMax): void
{
$metrics = new Metrics();
- $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge)->create();
$traverser = new NodeTraverser();
- $traverser->addVisitor(new NameResolver());
- $traverser->addVisitor(new ClassEnumVisitor($metrics));
- $traverser->addVisitor(new CyclomaticComplexityVisitor($metrics));
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new NameResolver(),
+ new ClassEnumVisitor($metrics),
+ new CyclomaticComplexityVisitor($metrics),
+ ]);
$code = file_get_contents($example);
$stmts = $parser->parse($code);
diff --git a/tests/Metric/Class_/Complexity/KanDefectVisitorTest.php b/tests/Metric/Class_/Complexity/KanDefectVisitorTest.php
index e78c51b5..d39b072f 100644
--- a/tests/Metric/Class_/Complexity/KanDefectVisitorTest.php
+++ b/tests/Metric/Class_/Complexity/KanDefectVisitorTest.php
@@ -1,10 +1,14 @@
create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$traverser = new \PhpParser\NodeTraverser();
- $traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver());
- $traverser->addVisitor(new ClassEnumVisitor($metrics));
- $traverser->addVisitor(new KanDefectVisitor($metrics));
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new NameResolver(),
+ new ClassEnumVisitor($metrics),
+ new KanDefectVisitor($metrics)
+ ]);
$code = file_get_contents($example);
$stmts = $parser->parse($code);
@@ -33,7 +40,7 @@ public function testLackOfCohesionOfMethodsIsWellCalculated($example, $classname
$this->assertSame($expected, $metrics->get($classname)->get('kanDefect'));
}
- public function provideExamples()
+ public static function provideExamples()
{
return [
[ __DIR__ . '/../../examples/kan1.php', 'A', .89],
diff --git a/tests/Metric/Class_/Complexity/SystemComplexityVisitorTest.php b/tests/Metric/Class_/Complexity/SystemComplexityVisitorTest.php
index 91b5522d..b4266d9a 100644
--- a/tests/Metric/Class_/Complexity/SystemComplexityVisitorTest.php
+++ b/tests/Metric/Class_/Complexity/SystemComplexityVisitorTest.php
@@ -1,10 +1,14 @@
create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$traverser = new \PhpParser\NodeTraverser();
- $traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver());
- $traverser->addVisitor(new ClassEnumVisitor($metrics));
- $traverser->addVisitor(new SystemComplexityVisitor($metrics));
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new NameResolver(),
+ new ClassEnumVisitor($metrics),
+ new SystemComplexityVisitor($metrics),
+ ]);
$code = file_get_contents($filename);
$stmts = $parser->parse($code);
@@ -35,7 +42,7 @@ public function testLackOfCohesionOfMethodsIsWellCalculated($filename, $class, $
$this->assertSame($rsysc, $metrics->get('A')->get('relativeSystemComplexity'));
}
- public function provideExamples()
+ public static function provideExamples()
{
return [
[ __DIR__ . '/../../examples/systemcomplexity1.php', 'A', 0.5, 36.0, 36.5],
diff --git a/tests/Metric/Class_/Component/MaintainabilityIndexVisitorTest.php b/tests/Metric/Class_/Component/MaintainabilityIndexVisitorTest.php
index 0a7b3524..3b2a0e77 100644
--- a/tests/Metric/Class_/Component/MaintainabilityIndexVisitorTest.php
+++ b/tests/Metric/Class_/Component/MaintainabilityIndexVisitorTest.php
@@ -1,9 +1,13 @@
prophesize('Hal\Metric\ClassMetric');
- $prophet->getName()->willReturn('A');
- $prophet->get('lloc')->willReturn($lloc);
- $prophet->get('loc')->willReturn($lloc + $cloc);
- $prophet->get('ccn')->willReturn($ccn);
- $prophet->get('cloc')->willReturn($cloc);
- $prophet->get('volume')->willReturn($volume);
+ $classMetrics = new ClassMetric('A');
+ $classMetrics->set('lloc', $lloc);
+ $classMetrics->set('loc', $lloc + $cloc);
+ $classMetrics->set('ccn', $ccn);
+ $classMetrics->set('cloc', $cloc);
+ $classMetrics->set('volume', $volume);
+ $metrics->attach($classMetrics);
- // spy
- $prophet->set('mIwoC', $mIwoC)->will(function () use ($prophet) {
- return $prophet->reveal();
- })->shouldBeCalled();
- $prophet->set('mi', $mi)->will(function () use ($prophet) {
- return $prophet->reveal();
- })->shouldBeCalled();
- $prophet->set('commentWeight', $commentWeight)->will(function () use ($prophet) {
- return $prophet->reveal();
- })->shouldBeCalled();
-
- $class = $prophet->reveal();
- $metrics->attach($class);
-
- $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$traverser = new \PhpParser\NodeTraverser();
- $traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver());
- $traverser->addVisitor(new MaintainabilityIndexVisitor($metrics));
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new \PhpParser\NodeVisitor\NameResolver(),
+ new MaintainabilityIndexVisitor($metrics)
+ ]);
$code = <<parse($code);
$traverser->traverse($stmts);
+
+ // And now, mi, mIwoC and commentWeight should be set
+ $this->assertEquals($mi, $classMetrics->get('mi'));
+ $this->assertEquals($mIwoC, $classMetrics->get('mIwoC'));
+ $this->assertEquals($commentWeight, $classMetrics->get('commentWeight'));
}
- public function provideValues()
+ public static function provideValues()
{
return [
// CC LLOC CLOC Volume MIwoC mi commentWeight
diff --git a/tests/Metric/Class_/Coupling/ExternalsVisitorTest.php b/tests/Metric/Class_/Coupling/ExternalsVisitorTest.php
index 8c51dfc2..140621e5 100644
--- a/tests/Metric/Class_/Coupling/ExternalsVisitorTest.php
+++ b/tests/Metric/Class_/Coupling/ExternalsVisitorTest.php
@@ -1,10 +1,13 @@
create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$traverser = new \PhpParser\NodeTraverser();
- $traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver());
- $traverser->addVisitor(new ClassEnumVisitor($metrics));
- $traverser->addVisitor(new ExternalsVisitor($metrics));
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new \PhpParser\NodeVisitor\NameResolver(),
+ new ClassEnumVisitor($metrics),
+ new ExternalsVisitor($metrics)
+ ]);
$code = file_get_contents($example);
$stmts = $parser->parse($code);
@@ -33,7 +39,7 @@ public function testDependenciesAreFound($example, $classname, $expected)
$this->assertSame($expected, $metrics->get($classname)->get('externals'));
}
- public function provideExamples()
+ public static function provideExamples()
{
return [
[ __DIR__ . '/../../examples/externals1.php', 'A', ['H', 'C', 'B', 'D']],
@@ -52,15 +58,18 @@ public function provideExamples()
/**
* @dataProvider provideExamplesAnnotation
*/
- public function testDependenciesAreFoundEvenInAnnotation($example, $classname, $expected)
+ #[DataProvider('provideExamplesAnnotation')]
+ public function testDependenciesAreFoundEvenInAnnotation($example, $classname, $expected): void
{
$metrics = new Metrics();
- $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$traverser = new \PhpParser\NodeTraverser();
- $traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver());
- $traverser->addVisitor(new ClassEnumVisitor($metrics));
- $traverser->addVisitor(new ExternalsVisitor($metrics));
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new \PhpParser\NodeVisitor\NameResolver(),
+ new ClassEnumVisitor($metrics),
+ new ExternalsVisitor($metrics)
+ ]);
$code = file_get_contents($example);
$stmts = $parser->parse($code);
@@ -69,7 +78,7 @@ public function testDependenciesAreFoundEvenInAnnotation($example, $classname, $
$this->assertSame($expected, $metrics->get($classname)->get('externals'));
}
- public function provideExamplesAnnotation()
+ public static function provideExamplesAnnotation()
{
return [
[ __DIR__ . '/../../examples/annotations1.php', 'C\\A', ['A\\Route', 'B\\Json']],
diff --git a/tests/Metric/Class_/Structural/LcomVisitorTest.php b/tests/Metric/Class_/Structural/LcomVisitorTest.php
index ad3a2525..ad77e921 100644
--- a/tests/Metric/Class_/Structural/LcomVisitorTest.php
+++ b/tests/Metric/Class_/Structural/LcomVisitorTest.php
@@ -1,25 +1,32 @@
create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$traverser = new \PhpParser\NodeTraverser();
- $traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver());
- $traverser->addVisitor(new ClassEnumVisitor($metrics));
- $traverser->addVisitor(new LcomVisitor($metrics));
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new \PhpParser\NodeVisitor\NameResolver(),
+ new ClassEnumVisitor($metrics),
+ new LcomVisitor($metrics),
+ ]);
$code = file_get_contents($example);
$stmts = $parser->parse($code);
@@ -28,7 +35,7 @@ public function testLackOfCohesionOfMethodsIsWellCalculated($example, $classname
$this->assertEquals($expected, $metrics->get($classname)->get('lcom'));
}
- public function provideExamples()
+ public static function provideExamples()
{
return [
[ __DIR__ . '/../../examples/lcom1.php', 'MyClassA', 2]
diff --git a/tests/Metric/Class_/Text/HalsteadVisitorTest.php b/tests/Metric/Class_/Text/HalsteadVisitorTest.php
index 63f0cf3d..bff16fa7 100644
--- a/tests/Metric/Class_/Text/HalsteadVisitorTest.php
+++ b/tests/Metric/Class_/Text/HalsteadVisitorTest.php
@@ -1,10 +1,12 @@
create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$traverser = new \PhpParser\NodeTraverser();
$traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver());
$traverser->addVisitor(new ClassEnumVisitor($metrics));
@@ -46,7 +49,7 @@ public function testLackOfCohesionOfMethodsIsWellCalculated($example, $functionN
);
}
- public function provideExamples()
+ public static function provideExamples()
{
return [
[ __DIR__ . '/../../examples/halstead1.php', 'twice', 2, 3, 1.5],
diff --git a/tests/Metric/Class_/Text/LengthVisitorTest.php b/tests/Metric/Class_/Text/LengthVisitorTest.php
index f83caf46..91801ec0 100644
--- a/tests/Metric/Class_/Text/LengthVisitorTest.php
+++ b/tests/Metric/Class_/Text/LengthVisitorTest.php
@@ -1,10 +1,14 @@
create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$traverser = new \PhpParser\NodeTraverser();
- $traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver());
- $traverser->addVisitor(new ClassEnumVisitor($metrics));
- $traverser->addVisitor(new LengthVisitor($metrics));
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new \PhpParser\NodeVisitor\NameResolver(),
+ new ClassEnumVisitor($metrics),
+ new LengthVisitor($metrics)
+ ]);
$code = file_get_contents($example);
$stmts = $parser->parse($code);
@@ -34,7 +41,7 @@ public function testLineCountsAreWellCalculated($example, $functionName, $loc, $
$this->assertEquals($loc, $metrics->get($functionName)->get('loc'));
}
- public function provideExamples()
+ public static function provideExamples()
{
return [
[ __DIR__ . '/../../examples/loc1.php', 'A', 21, 13, 8],
diff --git a/tests/Metric/Helper/RoleOfMethodDetectorTest.php b/tests/Metric/Helper/RoleOfMethodDetectorTest.php
index af16be3c..3a39b9e6 100644
--- a/tests/Metric/Helper/RoleOfMethodDetectorTest.php
+++ b/tests/Metric/Helper/RoleOfMethodDetectorTest.php
@@ -1,10 +1,12 @@
create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$stmt = $parser->parse($code);
$helper = new RoleOfMethodDetector();
@@ -35,7 +38,7 @@ public function testICanDetectRoleOfMethod($expected, $code)
}
}
- public function provideExamples()
+ public static function provideExamples()
{
$examples = [
'getter' => ['getter', 'name; } } ?>'],
diff --git a/tests/Metric/Package/PackageAbstractionTest.php b/tests/Metric/Package/PackageAbstractionTest.php
index cc427112..e51ab369 100644
--- a/tests/Metric/Package/PackageAbstractionTest.php
+++ b/tests/Metric/Package/PackageAbstractionTest.php
@@ -15,7 +15,7 @@
*/
class PackageAbstractionTest extends TestCase
{
- public function testItCalculatesTheAbstractionOfEachPackage()
+ public function testItCalculatesTheAbstractionOfEachPackage(): void
{
$metrics = $this->metricsOf([
$this->aPackage('SemiAbstract\\', [
diff --git a/tests/Metric/Package/PackageCollectingVisitorTest.php b/tests/Metric/Package/PackageCollectingVisitorTest.php
index aa8c49d5..942f143b 100644
--- a/tests/Metric/Package/PackageCollectingVisitorTest.php
+++ b/tests/Metric/Package/PackageCollectingVisitorTest.php
@@ -2,6 +2,8 @@
namespace Test\Hal\Metric\Package;
+use Hal\Component\Ast\ParserFactoryBridge;
+use Hal\Component\Ast\ParserTraverserVisitorsAssigner;
use Hal\Metric\Class_\ClassEnumVisitor;
use Hal\Metric\Metrics;
use Hal\Metric\Package\PackageCollectingVisitor;
@@ -17,7 +19,7 @@
*/
class PackageCollectingVisitorTest extends TestCase
{
- public function testItUsesThePackageAndTheSubpackageAnnotationAsPackageName()
+ public function testItUsesThePackageAndTheSubpackageAnnotationAsPackageName(): void
{
$metrics = $this->analyzeCode(<<<'CODE'
assertSame('PackA\\SubA\\', $metrics->get('PackageA\\ClassA')->get('package'));
}
- public function testItUsesThePackageAnnotationAsPackageNameIfNoSubpackageAnnotationExist()
+ public function testItUsesThePackageAnnotationAsPackageNameIfNoSubpackageAnnotationExist(): void
{
$metrics = $this->analyzeCode(<<<'CODE'
assertSame('PackA\\', $metrics->get('PackageA\\ClassA')->get('package'));
}
- public function testItUsesTheNamespaceAsPackageNameIfNoPackageAnnotationAreAvailable()
+ public function testItUsesTheNamespaceAsPackageNameIfNoPackageAnnotationAreAvailable(): void
{
$metrics = $this->analyzeCode(<<<'CODE'
create(ParserFactory::PREFER_PHP7);
+ $parser = (new ParserFactoryBridge())->create();
$traverser = new NodeTraverser();
- $traverser->addVisitor(new NameResolver());
- $traverser->addVisitor(new ClassEnumVisitor($metrics));
- $traverser->addVisitor(new PackageCollectingVisitor($metrics));
+ (new ParserTraverserVisitorsAssigner())->assign($traverser, [
+ new \PhpParser\NodeVisitor\NameResolver(),
+ new ClassEnumVisitor($metrics),
+ new PackageCollectingVisitor($metrics)
+ ]);
$stmts = $parser->parse($code);
$traverser->traverse($stmts);
diff --git a/tests/Metric/Package/PackageDependenciesTest.php b/tests/Metric/Package/PackageDependenciesTest.php
index da74d85c..6a217b09 100644
--- a/tests/Metric/Package/PackageDependenciesTest.php
+++ b/tests/Metric/Package/PackageDependenciesTest.php
@@ -14,7 +14,7 @@
*/
class PackageDependenciesTest extends TestCase
{
- public function testItCollectsAllIncomingAndOutgoingPackageDependencies()
+ public function testItCollectsAllIncomingAndOutgoingPackageDependencies(): void
{
$packageA = new PackageMetric('PackageA\\');
$packageB = new PackageMetric('PackageB\\');
@@ -45,26 +45,26 @@ public function testItCollectsAllIncomingAndOutgoingPackageDependencies()
$this->assertSame(['PackageA\\'], $packageB->getIncomingPackageDependencies());
}
- public function testItSkipsClassesThatHasNoDependencies()
+ public function testItSkipsClassesThatHasNoDependencies(): void
{
$classMetric = (new ClassMetric('OneClass'))->set('package', 'PackageA\\');
$metrics = $this->getMockBuilder(Metrics::class)->disableOriginalConstructor()->getMock();
$metrics
->expects($this->once())
->method('all')
- ->will($this->returnValue([$classMetric]));
+ ->willReturn([$classMetric]);
(new PackageDependencies())->calculate($metrics);
}
- public function testItSkipsClassesThatHasNoPackage()
+ public function testItSkipsClassesThatHasNoPackage(): void
{
$classMetric = (new ClassMetric('OneClass'))->set('externals', ['AnotherClass']);
$metrics = $this->getMockBuilder(Metrics::class)->disableOriginalConstructor()->getMock();
$metrics
->expects($this->once())
->method('all')
- ->will($this->returnValue([$classMetric]));
+ ->willReturn([$classMetric]);
(new PackageDependencies())->calculate($metrics);
}
diff --git a/tests/Metric/Package/PackageDistanceTest.php b/tests/Metric/Package/PackageDistanceTest.php
index 205f2166..3099ec75 100644
--- a/tests/Metric/Package/PackageDistanceTest.php
+++ b/tests/Metric/Package/PackageDistanceTest.php
@@ -6,6 +6,7 @@
use Hal\Metric\Metrics;
use Hal\Metric\Package\PackageDistance;
use Hal\Metric\PackageMetric;
+use PHPUnit\Framework\Attributes\DataProvider;
use \PHPUnit\Framework\TestCase;
/**
@@ -16,11 +17,9 @@ class PackageDistanceTest extends TestCase
{
/**
* @dataProvider provideExamples
- * @param float|null $instability
- * @param float|null $abstraction
- * @param float|null $expectedDistance
*/
- public function testItCalculatesTheNormalizedDistanceOfAllPackages($instability, $abstraction, $expectedDistance)
+ #[DataProvider('provideExamples')]
+ public function testItCalculatesTheNormalizedDistanceOfAllPackages($instability, $abstraction, $expectedDistance): void
{
$metrics = new Metrics();
$metrics->attach(new ClassMetric('Ignored'));
diff --git a/tests/Metric/Package/PackageInstabilityTest.php b/tests/Metric/Package/PackageInstabilityTest.php
index 2eceac59..70b7514a 100644
--- a/tests/Metric/Package/PackageInstabilityTest.php
+++ b/tests/Metric/Package/PackageInstabilityTest.php
@@ -13,7 +13,7 @@
*/
class PackageInstabilityTest extends TestCase
{
- public function testItCalculatesTheInstabilityOfEachPackage()
+ public function testItCalculatesTheInstabilityOfEachPackage(): void
{
$packageA = new PackageMetric('PackageA\\');
$packageB = new PackageMetric('PackageB\\');
@@ -37,7 +37,7 @@ public function testItCalculatesTheInstabilityOfEachPackage()
$this->assertSame(0.0, $packageC->getInstability());
}
- public function testItStoresTheInstabilityOfTheDependentPackagesOfEachPackage()
+ public function testItStoresTheInstabilityOfTheDependentPackagesOfEachPackage(): void
{
$packageA = new PackageMetric('PackageA\\');
$packageB = new PackageMetric('PackageB\\');
@@ -61,7 +61,7 @@ public function testItStoresTheInstabilityOfTheDependentPackagesOfEachPackage()
$this->assertSame([], $packageC->getDependentInstabilities());
}
- public function testItDoesNotCrashIfOnePackageHasNoIncomingAndNoOutgoingDependencies()
+ public function testItDoesNotCrashIfOnePackageHasNoIncomingAndNoOutgoingDependencies(): void
{
$package = new PackageMetric('PackageA\\');
diff --git a/tests/Metric/PackageMetricTest.php b/tests/Metric/PackageMetricTest.php
index 88e5e609..422953bc 100644
--- a/tests/Metric/PackageMetricTest.php
+++ b/tests/Metric/PackageMetricTest.php
@@ -8,12 +8,12 @@
class PackageMetricTest extends TestCase
{
- public function testItIsAMetric()
+ public function testItIsAMetric(): void
{
$this->assertInstanceOf(Metric::class, new PackageMetric('PackageName\\'));
}
- public function testItAppendsClasses()
+ public function testItAppendsClasses(): void
{
$metric = new PackageMetric('PackageName\\');
@@ -26,7 +26,7 @@ public function testItAppendsClasses()
$this->assertSame(['Foo', 'Bar'], $metric->getClasses());
}
- public function testItMayHasAnAbstraction()
+ public function testItMayHasAnAbstraction(): void
{
$metric = new PackageMetric('PackageName\\');
$this->assertNull($metric->getAbstraction());
@@ -35,7 +35,7 @@ public function testItMayHasAnAbstraction()
$this->assertSame(0.8, $metric->getAbstraction());
}
- public function testItMayHasAnInstability()
+ public function testItMayHasAnInstability(): void
{
$metric = new PackageMetric('PackageName\\');
$this->assertNull($metric->getInstability());
@@ -44,7 +44,7 @@ public function testItMayHasAnInstability()
$this->assertSame(0.8, $metric->getInstability());
}
- public function testItHasAUniqueListOfOutgoingClassDependencies()
+ public function testItHasAUniqueListOfOutgoingClassDependencies(): void
{
$metric = new PackageMetric('PackageName\\');
$this->assertSame([], $metric->getOutgoingClassDependencies());
@@ -55,14 +55,14 @@ public function testItHasAUniqueListOfOutgoingClassDependencies()
$this->assertSame(['PackageA\\AnyClass'], $metric->getOutgoingClassDependencies());
}
- public function testItDoesNotAddClassesOfItselfAsOutgoingClassDependencies()
+ public function testItDoesNotAddClassesOfItselfAsOutgoingClassDependencies(): void
{
$metric = new PackageMetric('PackageA\\');
$metric->addOutgoingClassDependency('PackageA\\AnyClass', 'PackageA\\');
$this->assertSame([], $metric->getOutgoingClassDependencies());
}
- public function testItHasAUniqueListOfOutgoingPackageDependencies()
+ public function testItHasAUniqueListOfOutgoingPackageDependencies(): void
{
$metric = new PackageMetric('PackageName\\');
$this->assertSame([], $metric->getOutgoingPackageDependencies());
@@ -73,14 +73,14 @@ public function testItHasAUniqueListOfOutgoingPackageDependencies()
$this->assertSame(['PackageA\\'], $metric->getOutgoingPackageDependencies());
}
- public function testItDoesNotAddItselfAsOutgoingClassDependencies()
+ public function testItDoesNotAddItselfAsOutgoingClassDependencies(): void
{
$metric = new PackageMetric('PackageA\\');
$metric->addOutgoingClassDependency('PackageA\\AnyClass', 'PackageA\\');
$this->assertSame([], $metric->getOutgoingPackageDependencies());
}
- public function testItHasAUniqueListOfIncomingClassDependencies()
+ public function testItHasAUniqueListOfIncomingClassDependencies(): void
{
$metric = new PackageMetric('PackageName\\');
$this->assertSame([], $metric->getOutgoingClassDependencies());
@@ -91,14 +91,14 @@ public function testItHasAUniqueListOfIncomingClassDependencies()
$this->assertSame(['PackageA\\AnyClass'], $metric->getIncomingClassDependencies());
}
- public function testItDoesNotAddClassesOfItselfAsIncomingClassDependencies()
+ public function testItDoesNotAddClassesOfItselfAsIncomingClassDependencies(): void
{
$metric = new PackageMetric('PackageA\\');
$metric->addIncomingClassDependency('PackageA\\AnyClass', 'PackageA\\');
$this->assertSame([], $metric->getIncomingClassDependencies());
}
- public function testItHasAUniqueListOfIncomingPackageDependencies()
+ public function testItHasAUniqueListOfIncomingPackageDependencies(): void
{
$metric = new PackageMetric('PackageName\\');
$this->assertSame([], $metric->getIncomingPackageDependencies());
@@ -109,14 +109,14 @@ public function testItHasAUniqueListOfIncomingPackageDependencies()
$this->assertSame(['PackageA\\'], $metric->getIncomingPackageDependencies());
}
- public function testItDoesNotAddItselfAsIncomingClassDependencies()
+ public function testItDoesNotAddItselfAsIncomingClassDependencies(): void
{
$metric = new PackageMetric('PackageA\\');
$metric->addIncomingClassDependency('PackageA\\AnyClass', 'PackageA\\');
$this->assertSame([], $metric->getIncomingPackageDependencies());
}
- public function testItMayHasADistanceAndANormalizedDistance()
+ public function testItMayHasADistanceAndANormalizedDistance(): void
{
$metric = new PackageMetric('PackageA\\');
$this->assertNull($metric->getDistance());
@@ -127,7 +127,7 @@ public function testItMayHasADistanceAndANormalizedDistance()
$this->assertSame(1/sqrt(2), $metric->getDistance());
}
- public function testItMyaHasDependentInstabilities()
+ public function testItMyaHasDependentInstabilities(): void
{
$metric = new PackageMetric('PackageB\\');
$this->assertSame([], $metric->getDependentInstabilities());
diff --git a/tests/Metric/System/UnitTesting/UnitTestingTest.php b/tests/Metric/System/UnitTesting/UnitTestingTest.php
index 31514f6d..0b80bacd 100644
--- a/tests/Metric/System/UnitTesting/UnitTestingTest.php
+++ b/tests/Metric/System/UnitTesting/UnitTestingTest.php
@@ -11,7 +11,7 @@
class UnitTestingTest extends \PHPUnit\Framework\TestCase
{
- public function testICanParseJunitXmlFile()
+ public function testICanParseJunitXmlFile(): void
{
$config = new Config();
$config->set('junit', __DIR__ . '/xml/junit1.xml');
@@ -31,11 +31,9 @@ public function testICanParseJunitXmlFile()
$this->assertEquals(6, $tests['Test\Hal\Component\Issue\IssuerTest']->assertions);
}
- /**
- * @expectedException Hal\Application\Config\ConfigException
- */
- public function testExceptionIsThrownIfJunitFileDoesNotExist()
+ public function testExceptionIsThrownIfJunitFileDoesNotExist(): void
{
+ $this->expectException(\Hal\Application\Config\ConfigException::class);
$config = new Config();
$config->set('junit', __DIR__ . '/xml/junit-not-found.xml');
$unit = new UnitTesting($config, []);
@@ -43,7 +41,7 @@ public function testExceptionIsThrownIfJunitFileDoesNotExist()
$unit->calculate($metrics);
}
- public function testICanParseCodeceptionFile()
+ public function testICanParseCodeceptionFile(): void
{
$config = new Config();
$config->set('junit', __DIR__ . '/xml/codeception1.xml');
diff --git a/tests/PhpUnit/WithAnalyzer.php b/tests/PhpUnit/WithAnalyzer.php
new file mode 100644
index 00000000..cf29f49f
--- /dev/null
+++ b/tests/PhpUnit/WithAnalyzer.php
@@ -0,0 +1,27 @@
+fetch($filesToAnalyze);
+
+ // disable composer
+ $config->set('composer', false);
+
+ $output = new TestOutput();
+ $issuer = new Issuer($output);
+ return (new Analyze($config, $output, $issuer))->run($files);
+ }
+}
diff --git a/tests/Polyfill/TestCaseCompatible.php b/tests/Polyfill/TestCaseCompatible.php
new file mode 100644
index 00000000..08a6d0bb
--- /dev/null
+++ b/tests/Polyfill/TestCaseCompatible.php
@@ -0,0 +1,24 @@
+assertContains($needle, $haystack, $message);
+ }
+
+ public function assertMatchesRegularExpression($pattern, $string, $message = '')
+ {
+ $this->assertRegExp($pattern, $string, $message);
+ }
+ }
+} else {
+ trait TestCaseCompatible
+ {
+ }
+}
+
+
diff --git a/tests/Polyfill/each.php b/tests/Polyfill/each.php
new file mode 100644
index 00000000..bfc53169
--- /dev/null
+++ b/tests/Polyfill/each.php
@@ -0,0 +1,38 @@
+ $value,
+ 'value' => $value,
+ 0 => $key,
+ 'key' => $key
+ );
+ }
+}
diff --git a/tests/Polyfill/testcase.php b/tests/Polyfill/testcase.php
new file mode 100644
index 00000000..0a8727ca
--- /dev/null
+++ b/tests/Polyfill/testcase.php
@@ -0,0 +1,8 @@
+assertEquals($expectedTableHeader, $actualTableHeader);
}
- public function tableHeaderDataProvider()
+ public static function tableHeaderDataProvider()
{
$defaultTableHeader = [
'Class',
@@ -80,12 +82,24 @@ public function tableHeaderDataProvider()
private function getActualTableHeader($content)
{
- $tableHeaderColumnNodes = (new Crawler($content))
- ->filterXPath('.//table[contains(concat(" ",normalize-space(@class)," ")," js-sort-table ")]/thead/tr')
- ->children();
+ $dom = new \DOMDocument();
+ @$dom->loadHTML($content);
- return array_map(function (DomNode $node) {
- return $node->textContent;
- }, iterator_to_array($tableHeaderColumnNodes));
+ $xpath = new \DOMXPath($dom);
+ $rows = $xpath->query('//table[contains(concat(" ",normalize-space(@class)," ")," js-sort-table ")]/thead/tr');
+
+ if ($rows->length === 0) {
+ return [];
+ }
+
+ $headerRow = $rows->item(0);
+ $headers = [];
+ foreach ($headerRow->childNodes as $node) {
+ if ($node->nodeType === XML_ELEMENT_NODE) {
+ $headers[] = $node->textContent;
+ }
+ }
+
+ return $headers;
}
}
diff --git a/tests/Report/Html/ReporterTest.php b/tests/Report/Html/ReporterTest.php
index 1d52aa5b..42d8bedb 100644
--- a/tests/Report/Html/ReporterTest.php
+++ b/tests/Report/Html/ReporterTest.php
@@ -8,6 +8,7 @@
use Hal\Metric\Metrics;
use Hal\Report\Html\Reporter;
use PHPUnit\Framework\TestCase;
+use Polyfill\TestCaseCompatible;
/**
* @group reporter
@@ -15,7 +16,9 @@
*/
class ReporterTest extends TestCase
{
- public function testICanGenerateHtmlReport()
+ use TestCaseCompatible;
+
+ public function testICanGenerateHtmlReport(): void
{
$config = new Config();
$output = new TestOutput();
@@ -46,6 +49,6 @@ public function testICanGenerateHtmlReport()
// ensure basic content is generated
$content = file_get_contents(sprintf('%s/index.html', $destination));
- $this->assertContains('PhpMetrics report', $content);
+ $this->assertStringContainsString('PhpMetrics report', $content);
}
}
diff --git a/tests/Search/SearchFactoryTest.php b/tests/Search/SearchFactoryTest.php
index 811ff49e..68a7c0e6 100644
--- a/tests/Search/SearchFactoryTest.php
+++ b/tests/Search/SearchFactoryTest.php
@@ -11,7 +11,7 @@
class SearchFactoryTest extends TestCase
{
- public function testIShoulBeAbleToFactorySearches()
+ public function testIShoulBeAbleToFactorySearches(): void
{
$config = [
'search1' => [
diff --git a/tests/Search/SearchTest.php b/tests/Search/SearchTest.php
index a6d96048..9ff43c9e 100644
--- a/tests/Search/SearchTest.php
+++ b/tests/Search/SearchTest.php
@@ -6,6 +6,7 @@
use Hal\Metric\InterfaceMetric;
use Hal\Metric\Metric;
use Hal\Search\Search;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
/**
@@ -14,7 +15,7 @@
class SearchTest extends TestCase
{
- public function testSearchCanReduceSearchByName()
+ public function testSearchCanReduceSearchByName(): void
{
$config = [
'nameMatches' => 'awesome'
@@ -24,14 +25,14 @@ public function testSearchCanReduceSearchByName()
$metric
->expects($this->once())
->method('getName')
- ->will($this->returnValue('My\\AwesomeClass'));
+ ->willReturn('My\\AwesomeClass');
$search = new Search('my-search', $config);
$this->assertTrue($search->matches($metric));
}
- public function testSearchCanReduceSearchByType()
+ public function testSearchCanReduceSearchByType(): void
{
$config = [
'type' => 'class'
@@ -49,7 +50,8 @@ public function testSearchCanReduceSearchByType()
/**
* @dataProvider providesMetrics
*/
- public function testSearchCanReduceSearchByMetric($searchExpression, $value, $expected)
+ #[DataProvider('providesMetrics')]
+ public function testSearchCanReduceSearchByMetric($searchExpression, $value, $expected): void
{
$config = [
'ccn' => $searchExpression
@@ -59,14 +61,14 @@ public function testSearchCanReduceSearchByMetric($searchExpression, $value, $ex
$metric
->expects($this->once())
->method('get')
- ->will($this->returnValue($value));
+ ->willReturn($value);
$search = new Search('my-search', $config);
$this->assertEquals($expected, $search->matches($metric));
}
- public function providesMetrics()
+ public static function providesMetrics()
{
return [
['>=2.5', 6, true],
diff --git a/tests/Violation/Class_/BlobTest.php b/tests/Violation/Class_/BlobTest.php
index be8da94c..457f70ff 100644
--- a/tests/Violation/Class_/BlobTest.php
+++ b/tests/Violation/Class_/BlobTest.php
@@ -5,6 +5,7 @@
use Hal\Metric\ClassMetric;
use Hal\Violation\Class_\Blob;
use Hal\Violation\Violations;
+use PHPUnit\Framework\Attributes\DataProvider;
/**
* @group violation
@@ -14,7 +15,8 @@ class BlobTest extends \PHPUnit\Framework\TestCase
/**
* @dataProvider provideExamples
*/
- public function testGlobIsFound($expected, $nbMethodsPublic, $lcom, $nbExternals)
+ #[DataProvider('provideExamples')]
+ public function testGlobIsFound($expected, $nbMethodsPublic, $lcom, $nbExternals): void
{
$class = $this->getMockBuilder(ClassMetric::class)->disableOriginalConstructor()->getMock();
@@ -42,7 +44,7 @@ public function testGlobIsFound($expected, $nbMethodsPublic, $lcom, $nbExternals
$this->assertEquals($expected, $class->get('violations')->count());
}
- public function provideExamples()
+ public static function provideExamples()
{
return [
[1, 9, 3, 10],
diff --git a/tests/Violation/Package/StableAbstractionsPrincipleTest.php b/tests/Violation/Package/StableAbstractionsPrincipleTest.php
index 17351468..2475dc6a 100644
--- a/tests/Violation/Package/StableAbstractionsPrincipleTest.php
+++ b/tests/Violation/Package/StableAbstractionsPrincipleTest.php
@@ -6,6 +6,7 @@
use Hal\Metric\PackageMetric;
use Hal\Violation\Package\StableAbstractionsPrinciple;
use Hal\Violation\Violations;
+use PHPUnit\Framework\Attributes\DataProvider;
use \PHPUnit\Framework\TestCase;
/**
@@ -13,24 +14,26 @@
*/
class StableAbstractionsPrincipleTest extends TestCase
{
- public function testItIgnoresNonPackageMetrics()
+ public function testItIgnoresNonPackageMetrics(): void
{
- $metric = $this->prophesize(Metric::class);
+ $metric = $this->getMockBuilder(Metric::class)
+ ->disableOriginalConstructor()
+ ->getMock();
- $object = new StableAbstractionsPrinciple();
+ $metric->expects($this->never())
+ ->method('get')
+ ->with('violations');
- $object->apply($metric->reveal());
+ $object = new StableAbstractionsPrinciple();
- $metric->get('violations')->shouldNotHaveBeenCalled();
+ $object->apply($metric);
}
/**
* @dataProvider provideExamples
- * @param float $abstractness
- * @param float $instability
- * @param int $expectedViolationCount
*/
- public function testItAddsViolationsIfAPackageIsEitherStableAndConcreteOrInstableAndAbstract($abstractness, $instability, $expectedViolationCount)
+ #[DataProvider('provideExamples')]
+ public function testItAddsViolationsIfAPackageIsEitherStableAndConcreteOrInstableAndAbstract($abstractness, $instability, $expectedViolationCount): void
{
$metric = new PackageMetric('package');
$metric->set('violations', new Violations());
diff --git a/tests/Violation/Package/StableDependenciesPrincipleTest.php b/tests/Violation/Package/StableDependenciesPrincipleTest.php
index 4eb870f4..6e4cbce3 100644
--- a/tests/Violation/Package/StableDependenciesPrincipleTest.php
+++ b/tests/Violation/Package/StableDependenciesPrincipleTest.php
@@ -6,6 +6,7 @@
use Hal\Metric\PackageMetric;
use Hal\Violation\Package\StableDependenciesPrinciple;
use Hal\Violation\Violations;
+use PHPUnit\Framework\Attributes\DataProvider;
use \PHPUnit\Framework\TestCase;
/**
@@ -13,7 +14,7 @@
*/
class StableDependenciesPrincipleTest extends TestCase
{
- public function testItIgnoresNonPackageMetrics()
+ public function testItIgnoresNonPackageMetrics(): void
{
$metric = $this->getMockBuilder(Metric::class)->getMock();
$metric->expects($this->never())->method('get');
@@ -24,15 +25,13 @@ public function testItIgnoresNonPackageMetrics()
/**
* @dataProvider provideExamples
- * @param float $packageInstability
- * @param float[] $dependentInstabilities
- * @param int $expectedViolationCount
*/
+ #[DataProvider('provideExamples')]
public function testItAddsViolationsIfOneDependentPackageIsMoreUnstableOrAsUnstableAsThePackageItself(
$packageInstability,
array $dependentInstabilities,
$expectedViolationCount
- ) {
+ ): void {
$violations = new Violations();
$metric = $this->getMockBuilder(PackageMetric::class)->disableOriginalConstructor()->getMock();
$metric->method('getInstability')->willReturn($packageInstability);
diff --git a/tests/binary/BinTest.php b/tests/binary/BinTest.php
index aada20b1..839d4154 100644
--- a/tests/binary/BinTest.php
+++ b/tests/binary/BinTest.php
@@ -1,35 +1,42 @@
phar = __DIR__ . '/../../bin/phpmetrics';
}
- public function testICanRunBinFile()
+ public function testICanRunBinFile(): void
{
$command = sprintf('%s --version', $this->phar);
$r = shell_exec($command);
- $this->assertContains('PhpMetrics', $r);
+ $this->assertStringContainsString('PhpMetrics', $r);
}
- public function testICanProvideOneDirectoryToParse()
+ public function testICanProvideOneDirectoryToParse(): void
{
$command = sprintf('%s --exclude="" %s 2>&1', $this->phar, __DIR__ . '/examples/1');
$r = shell_exec($command);
- $this->assertContains('Object oriented programming', $r);
- $this->assertContains('LOC', $r);
- $this->assertRegExp('!Classes\s+2!', $r);
+ $this->assertStringContainsString('Object oriented programming', $r);
+ $this->assertStringContainsString('LOC', $r);
+ $this->assertMatchesRegularExpression('!Classes\s+2!', $r);
}
- public function testICanProvideMultipleDirectoriesToParse()
+ public function testICanProvideMultipleDirectoriesToParse(): void
{
$command = sprintf(
'%s --exclude="" %s,%s 2>&1',
@@ -38,8 +45,8 @@ public function testICanProvideMultipleDirectoriesToParse()
__DIR__ . '/examples/2'
);
$r = shell_exec($command);
- $this->assertContains('Object oriented programming', $r);
- $this->assertContains('LOC', $r);
- $this->assertRegExp('!Classes\s+4!', $r);
+ $this->assertStringContainsString('Object oriented programming', $r);
+ $this->assertStringContainsString('LOC', $r);
+ $this->assertMatchesRegularExpression('!Classes\s+4!', $r);
}
}
diff --git a/tests/binary/PharTest.php b/tests/binary/PharTest.php
index cecb304b..a56835e3 100644
--- a/tests/binary/PharTest.php
+++ b/tests/binary/PharTest.php
@@ -1,35 +1,43 @@
phar = __DIR__ . '/../../releases/phpmetrics.phar';
}
- public function testICanRunPhar()
+ public function testICanRunPhar(): void
{
$command = sprintf('%s --version', $this->phar);
$r = shell_exec($command);
- $this->assertContains('PhpMetrics', $r);
+ $this->assertStringContainsString('PhpMetrics', $r);
}
- public function testICanProvideOneDirectoryToParse()
+ public function testICanProvideOneDirectoryToParse(): void
{
$command = sprintf('%s --exclude="" %s 2>&1', $this->phar, __DIR__ . '/examples/1');
$r = shell_exec($command);
- $this->assertContains('Object oriented programming', $r);
- $this->assertContains('LOC', $r);
- $this->assertRegExp('!Classes\s+2!', $r);
+ $this->assertStringContainsString('Object oriented programming', $r);
+ $this->assertStringContainsString('LOC', $r);
+ $this->assertMatchesRegularExpression('!Classes\s+2!', $r);
}
- public function testICanProvideMultipleDirectoriesToParse()
+ public function testICanProvideMultipleDirectoriesToParse(): void
{
$command = sprintf(
'%s --exclude="" %s,%s 2>&1',
@@ -38,8 +46,8 @@ public function testICanProvideMultipleDirectoriesToParse()
__DIR__ . '/examples/2'
);
$r = shell_exec($command);
- $this->assertContains('Object oriented programming', $r);
- $this->assertContains('LOC', $r);
- $this->assertRegExp('!Classes\s+4!', $r);
+ $this->assertStringContainsString('Object oriented programming', $r);
+ $this->assertStringContainsString('LOC', $r);
+ $this->assertMatchesRegularExpression('!Classes\s+4!', $r);
}
}
diff --git a/tests/binary/ReportTest.php b/tests/binary/ReportTest.php
index 351d9048..2a6b10d8 100644
--- a/tests/binary/ReportTest.php
+++ b/tests/binary/ReportTest.php
@@ -1,35 +1,42 @@
phar = __DIR__ . '/../../bin/phpmetrics';
}
- public function testICanRunBinFile()
+ public function testICanRunBinFile(): void
{
$command = sprintf('%s --version', $this->phar);
$r = shell_exec($command);
- $this->assertContains('PhpMetrics', $r);
+ $this->assertStringContainsString('PhpMetrics', $r);
}
- public function testICanProvideOneDirectoryToParse()
+ public function testICanProvideOneDirectoryToParse(): void
{
$command = sprintf('%s --exclude="" %s 2>&1', $this->phar, __DIR__ . '/examples/1');
$r = shell_exec($command);
- $this->assertContains('Object oriented programming', $r);
- $this->assertContains('LOC', $r);
- $this->assertRegExp('!Classes\s+2!', $r);
+ $this->assertStringContainsString('Object oriented programming', $r);
+ $this->assertStringContainsString('LOC', $r);
+ $this->assertMatchesRegularExpression('!Classes\s+2!', $r);
}
- public function testICanProvideMultipleDirectoriesToParse()
+ public function testICanProvideMultipleDirectoriesToParse(): void
{
$command = sprintf(
'%s --exclude="" %s,%s 2>&1',
@@ -38,12 +45,12 @@ public function testICanProvideMultipleDirectoriesToParse()
__DIR__ . '/examples/2'
);
$r = shell_exec($command);
- $this->assertContains('Object oriented programming', $r);
- $this->assertContains('LOC', $r);
- $this->assertRegExp('!Classes\s+4!', $r);
+ $this->assertStringContainsString('Object oriented programming', $r);
+ $this->assertStringContainsString('LOC', $r);
+ $this->assertMatchesRegularExpression('!Classes\s+4!', $r);
}
- public function testICanGenerateCsvReport()
+ public function testICanGenerateCsvReport(): void
{
$destination = '/tmp/report.csv';
if (file_exists($destination)) {
@@ -60,7 +67,7 @@ public function testICanGenerateCsvReport()
$this->assertFileExists($destination);
}
- public function testICanGenerateJsonReport()
+ public function testICanGenerateJsonReport(): void
{
$destination = '/tmp/report.json';
if (file_exists($destination)) {
diff --git a/tests/binary/StandaloneTest.php b/tests/binary/StandaloneTest.php
new file mode 100644
index 00000000..5d6d6448
--- /dev/null
+++ b/tests/binary/StandaloneTest.php
@@ -0,0 +1,53 @@
+binary = __DIR__ . '/../../releases/phpmetrics-linux-x86_64';
+ }
+
+ public function testICanRunStandaloneBinary(): void
+ {
+ $command = sprintf('%s --version', $this->binary);
+ $r = shell_exec($command);
+ $this->assertStringContainsString('PhpMetrics', $r);
+ }
+
+ public function testICanProvideOneDirectoryToParse(): void
+ {
+ $command = sprintf('%s --exclude="" %s 2>&1', $this->binary, __DIR__ . '/examples/1');
+ $r = shell_exec($command);
+ $this->assertStringContainsString('Object oriented programming', $r);
+ $this->assertStringContainsString('LOC', $r);
+ $this->assertMatchesRegularExpression('!Classes\s+2!', $r);
+ }
+
+ public function testICanProvideMultipleDirectoriesToParse(): void
+ {
+ $command = sprintf(
+ '%s --exclude="" %s,%s 2>&1',
+ $this->binary,
+ __DIR__ . '/examples/1',
+ __DIR__ . '/examples/2'
+ );
+ $r = shell_exec($command);
+ $this->assertStringContainsString('Object oriented programming', $r);
+ $this->assertStringContainsString('LOC', $r);
+ $this->assertMatchesRegularExpression('!Classes\s+4!', $r);
+ }
+}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
new file mode 100644
index 00000000..dc2a6a2a
--- /dev/null
+++ b/tests/bootstrap.php
@@ -0,0 +1,12 @@
+