pax_global_header 0000666 0000000 0000000 00000000064 13765763404 0014531 g ustar 00root root 0000000 0000000 52 comment=cc8b3f2e9b4b3c788470f1ded24f6e6163279151
phpunit-complexity-2.0.2/ 0000775 0000000 0000000 00000000000 13765763404 0015414 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/.github/ 0000775 0000000 0000000 00000000000 13765763404 0016754 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/.github/FUNDING.yml 0000664 0000000 0000000 00000000032 13765763404 0020564 0 ustar 00root root 0000000 0000000 github: sebastianbergmann
phpunit-complexity-2.0.2/.github/workflows/ 0000775 0000000 0000000 00000000000 13765763404 0021011 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/.github/workflows/ci.yml 0000664 0000000 0000000 00000007031 13765763404 0022130 0 ustar 00root root 0000000 0000000 # https://help.github.com/en/categories/automating-your-workflow-with-github-actions
on:
- "pull_request"
- "push"
name: "CI"
jobs:
coding-guidelines:
name: "Coding Guidelines"
runs-on: "ubuntu-latest"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Run friendsofphp/php-cs-fixer"
run: "php7.4 ./tools/php-cs-fixer fix --diff-format=udiff --dry-run --show-progress=dots --using-cache=no --verbose"
type-checker:
name: "Type Checker"
runs-on: "ubuntu-latest"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Update dependencies with composer"
run: "php7.4 ./tools/composer update --no-ansi --no-interaction --no-progress"
- name: "Run vimeo/psalm"
run: "php7.4 ./tools/psalm --config=.psalm/config.xml --no-progress --shepherd --show-info=false --stats"
backward-compatibility:
name: Backward Compatibility
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Fetch tags
run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Install PHP with extensions
uses: shivammathur/setup-php@v2
with:
php-version: 7.4
coverage: none
extensions: intl
tests:
name: "Tests"
runs-on: "ubuntu-latest"
strategy:
fail-fast: false
matrix:
php-version:
- "7.3"
- "7.4"
- "8.0"
- "8.1"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Install PHP with extensions"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
coverage: "pcov"
- name: "Cache dependencies installed with composer"
uses: "actions/cache@v1"
with:
path: "~/.composer/cache"
key: "php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }}"
restore-keys: "php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-"
- name: "Install dependencies with composer"
run: "./tools/composer update --no-ansi --no-interaction --no-progress"
- name: "Run tests with phpunit/phpunit"
run: "vendor/bin/phpunit --coverage-clover=coverage.xml"
- name: "Send code coverage report to Codecov.io"
env:
CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}"
run: "bash <(curl -s https://codecov.io/bash) || true"
mutation-tests:
name: "Mutation Tests"
runs-on: "ubuntu-latest"
strategy:
matrix:
php-version:
- "7.4"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Install PHP with extensions"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
coverage: "pcov"
- name: "Cache dependencies installed with composer"
uses: "actions/cache@v1"
with:
path: "~/.composer/cache"
key: "php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }}"
restore-keys: "php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-"
- name: "Install dependencies with composer"
run: "./tools/composer update --no-ansi --no-interaction --no-progress"
- name: "Run mutation tests with infection/infection"
run: "./tools/infection --show-mutations --only-covered"
phpunit-complexity-2.0.2/.gitignore 0000664 0000000 0000000 00000000115 13765763404 0017401 0 ustar 00root root 0000000 0000000 /.idea
/.php_cs
/.php_cs.cache
/.phpunit.result.cache
/composer.lock
/vendor
phpunit-complexity-2.0.2/.phive/ 0000775 0000000 0000000 00000000000 13765763404 0016605 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/.phive/phars.xml 0000664 0000000 0000000 00000001034 13765763404 0020442 0 ustar 00root root 0000000 0000000
phpunit-complexity-2.0.2/.php_cs.dist 0000664 0000000 0000000 00000020703 13765763404 0017635 0 ustar 00root root 0000000 0000000
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
EOF;
$finder = PhpCsFixer\Finder::create()
->files()
->in(__DIR__ . '/src')
->in(__DIR__ . '/tests/unit')
->in(__DIR__ . '/tests/integration');
return PhpCsFixer\Config::create()
->setFinder($finder)
->setRiskyAllowed(true)
->setRules([
'align_multiline_comment' => true,
'array_indentation' => true,
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => [
'operators' => [
'=' => 'align_single_space_minimal',
'=>' => 'align_single_space_minimal',
],
],
'blank_line_after_namespace' => true,
'blank_line_before_statement' => [
'statements' => [
'break',
'continue',
'declare',
'default',
'die',
'do',
'exit',
'for',
'foreach',
'goto',
'if',
'include',
'include_once',
'require',
'require_once',
'return',
'switch',
'throw',
'try',
'while',
'yield',
],
],
'braces' => true,
'cast_spaces' => true,
'class_attributes_separation' => ['elements' => ['const', 'method', 'property']],
'combine_consecutive_issets' => true,
'combine_consecutive_unsets' => true,
'compact_nullable_typehint' => true,
'concat_space' => ['spacing' => 'one'],
'constant_case' => true,
'declare_equal_normalize' => ['space' => 'none'],
'declare_strict_types' => true,
'dir_constant' => true,
'elseif' => true,
'encoding' => true,
'explicit_indirect_variable' => true,
'explicit_string_variable' => true,
'full_opening_tag' => true,
'fully_qualified_strict_types' => true,
'function_declaration' => true,
'global_namespace_import' => [
'import_classes' => true,
'import_constants' => true,
'import_functions' => true,
],
'header_comment' => ['header' => $header, 'separate' => 'none'],
'heredoc_to_nowdoc' => true,
'increment_style' => [
'style' => PhpCsFixer\Fixer\Operator\IncrementStyleFixer::STYLE_POST,
],
'indentation_type' => true,
'is_null' => true,
'line_ending' => true,
'list_syntax' => ['syntax' => 'short'],
'logical_operators' => true,
'lowercase_keywords' => true,
'lowercase_static_reference' => true,
'magic_constant_casing' => true,
'magic_method_casing' => true,
'method_argument_space' => ['ensure_fully_multiline' => true],
'modernize_types_casting' => true,
'multiline_comment_opening_closing' => true,
'multiline_whitespace_before_semicolons' => true,
'native_constant_invocation' => false,
'native_function_casing' => false,
'native_function_invocation' => false,
'native_function_type_declaration_casing' => true,
'new_with_braces' => false,
'no_alias_functions' => true,
'no_alternative_syntax' => true,
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_blank_lines_before_namespace' => true,
'no_closing_tag' => true,
'no_empty_comment' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_extra_blank_lines' => true,
'no_homoglyph_names' => true,
'no_leading_import_slash' => true,
'no_leading_namespace_whitespace' => true,
'no_mixed_echo_print' => ['use' => 'print'],
'no_multiline_whitespace_around_double_arrow' => true,
'no_null_property_initialization' => true,
'no_php4_constructor' => true,
'no_short_bool_cast' => true,
'no_short_echo_tag' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_spaces_after_function_name' => true,
'no_spaces_around_offset' => true,
'no_spaces_inside_parenthesis' => true,
'no_superfluous_elseif' => true,
'no_superfluous_phpdoc_tags' => [
'allow_mixed' => true,
],
'no_trailing_comma_in_list_call' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_trailing_whitespace' => true,
'no_trailing_whitespace_in_comment' => true,
'no_unneeded_control_parentheses' => true,
'no_unneeded_curly_braces' => true,
'no_unneeded_final_method' => true,
'no_unreachable_default_argument_value' => true,
'no_unset_on_property' => true,
'no_unused_imports' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'no_whitespace_before_comma_in_array' => true,
'no_whitespace_in_blank_line' => true,
'non_printable_character' => true,
'normalize_index_brace' => true,
'object_operator_without_whitespace' => true,
'ordered_class_elements' => [
'order' => [
'use_trait',
'constant_public',
'constant_protected',
'constant_private',
'property_public_static',
'property_protected_static',
'property_private_static',
'property_public',
'property_protected',
'property_private',
'method_public_static',
'construct',
'destruct',
'magic',
'phpunit',
'method_public',
'method_protected',
'method_private',
'method_protected_static',
'method_private_static',
],
],
'ordered_imports' => [
'imports_order' => [
PhpCsFixer\Fixer\Import\OrderedImportsFixer::IMPORT_TYPE_CONST,
PhpCsFixer\Fixer\Import\OrderedImportsFixer::IMPORT_TYPE_FUNCTION,
PhpCsFixer\Fixer\Import\OrderedImportsFixer::IMPORT_TYPE_CLASS,
]
],
'ordered_interfaces' => [
'direction' => 'ascend',
'order' => 'alpha',
],
'phpdoc_add_missing_param_annotation' => false,
'phpdoc_align' => true,
'phpdoc_annotation_without_dot' => true,
'phpdoc_indent' => true,
'phpdoc_no_access' => true,
'phpdoc_no_empty_return' => true,
'phpdoc_no_package' => true,
'phpdoc_order' => true,
'phpdoc_return_self_reference' => true,
'phpdoc_scalar' => true,
'phpdoc_separation' => true,
'phpdoc_single_line_var_spacing' => true,
'phpdoc_summary' => true,
'phpdoc_to_comment' => true,
'phpdoc_trim' => true,
'phpdoc_trim_consecutive_blank_line_separation' => true,
'phpdoc_types' => ['groups' => ['simple', 'meta']],
'phpdoc_types_order' => true,
'phpdoc_var_without_name' => true,
'pow_to_exponentiation' => true,
'protected_to_private' => true,
'return_assignment' => true,
'return_type_declaration' => ['space_before' => 'none'],
'self_accessor' => true,
'self_static_accessor' => true,
'semicolon_after_instruction' => true,
'set_type_to_cast' => true,
'short_scalar_cast' => true,
'simple_to_complex_string_variable' => true,
'simplified_null_return' => false,
'single_blank_line_at_eof' => true,
'single_import_per_statement' => true,
'single_line_after_imports' => true,
'single_quote' => true,
'standardize_not_equals' => true,
'strict_param' => true,
'ternary_to_null_coalescing' => true,
'trailing_comma_in_multiline_array' => true,
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'visibility_required' => [
'elements' => [
'const',
'method',
'property',
],
],
'void_return' => true,
'whitespace_after_comma_in_array' => true,
]);
phpunit-complexity-2.0.2/.psalm/ 0000775 0000000 0000000 00000000000 13765763404 0016606 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/.psalm/baseline.xml 0000664 0000000 0000000 00000000157 13765763404 0021115 0 ustar 00root root 0000000 0000000
phpunit-complexity-2.0.2/.psalm/config.xml 0000664 0000000 0000000 00000000752 13765763404 0020601 0 ustar 00root root 0000000 0000000
phpunit-complexity-2.0.2/ChangeLog.md 0000664 0000000 0000000 00000001600 13765763404 0017562 0 ustar 00root root 0000000 0000000 # ChangeLog
All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
## [2.0.2] - 2020-10-26
### Fixed
* `SebastianBergmann\Complexity\Exception` now correctly extends `\Throwable`
## [2.0.1] - 2020-09-28
### Changed
* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
## [2.0.0] - 2020-07-25
### Removed
* The `ParentConnectingVisitor` has been removed (it should have been marked as `@internal`)
## [1.0.0] - 2020-07-22
* Initial release
[2.0.2]: https://github.com/sebastianbergmann/complexity/compare/2.0.1...2.0.2
[2.0.1]: https://github.com/sebastianbergmann/complexity/compare/2.0.0...2.0.1
[2.0.0]: https://github.com/sebastianbergmann/complexity/compare/1.0.0...2.0.0
[1.0.0]: https://github.com/sebastianbergmann/complexity/compare/70ee0ad32d9e2be3f85beffa3e2eb474193f2487...1.0.0
phpunit-complexity-2.0.2/LICENSE 0000664 0000000 0000000 00000003016 13765763404 0016421 0 ustar 00root root 0000000 0000000 sebastian/complexity
Copyright (c) 2020, Sebastian Bergmann .
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
phpunit-complexity-2.0.2/README.md 0000664 0000000 0000000 00000002034 13765763404 0016672 0 ustar 00root root 0000000 0000000 # sebastian/complexity
Library for calculating the complexity of PHP code units.
[](https://packagist.org/packages/sebastian/complexity)
[](https://php.net/)
[](https://phpunit.de/build-status.html)
[](https://shepherd.dev/github/sebastianbergmann/complexity)
## Installation
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
```
composer require sebastian/complexity
```
If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
```
composer require --dev sebastian/complexity
```
phpunit-complexity-2.0.2/build.xml 0000664 0000000 0000000 00000002024 13765763404 0017233 0 ustar 00root root 0000000 0000000
phpunit-complexity-2.0.2/composer.json 0000664 0000000 0000000 00000001701 13765763404 0020135 0 ustar 00root root 0000000 0000000 {
"name": "sebastian/complexity",
"description": "Library for calculating the complexity of PHP code units",
"type": "library",
"homepage": "https://github.com/sebastianbergmann/complexity",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"support": {
"issues": "https://github.com/sebastianbergmann/complexity/issues"
},
"require": {
"php": ">=7.3",
"nikic/php-parser": "^4.7"
},
"require-dev": {
"phpunit/phpunit": "^9.3"
},
"config": {
"platform": {
"php": "7.3.0"
},
"optimize-autoloader": true,
"sort-packages": true
},
"autoload": {
"classmap": [
"src/"
]
},
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
}
}
}
phpunit-complexity-2.0.2/infection.json 0000664 0000000 0000000 00000001130 13765763404 0020260 0 ustar 00root root 0000000 0000000 {
"source": {
"directories": [
"src"
]
},
"mutators": {
"@default": true,
"TrueValue": {
"ignore": [
"SebastianBergmann\\Complexity\\Calculator::calculateForAbstractSyntaxTree"
]
},
"InstanceOf_": {
"ignore": [
"SebastianBergmann\\Complexity\\ComplexityCalculatingVisitor::classMethodName",
"SebastianBergmann\\Complexity\\ComplexityCalculatingVisitor::functionName"
]
}
},
"minMsi": 100,
"minCoveredMsi": 100
}
phpunit-complexity-2.0.2/phpunit.xml 0000664 0000000 0000000 00000001512 13765763404 0017624 0 ustar 00root root 0000000 0000000
tests
src
phpunit-complexity-2.0.2/src/ 0000775 0000000 0000000 00000000000 13765763404 0016203 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/src/Calculator.php 0000664 0000000 0000000 00000004643 13765763404 0021014 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
use PhpParser\Error;
use PhpParser\Lexer;
use PhpParser\Node;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitor\NameResolver;
use PhpParser\NodeVisitor\ParentConnectingVisitor;
use PhpParser\Parser;
use PhpParser\ParserFactory;
final class Calculator
{
/**
* @throws RuntimeException
*/
public function calculateForSourceFile(string $sourceFile): ComplexityCollection
{
return $this->calculateForSourceString(file_get_contents($sourceFile));
}
/**
* @throws RuntimeException
*/
public function calculateForSourceString(string $source): ComplexityCollection
{
try {
$nodes = $this->parser()->parse($source);
assert($nodes !== null);
return $this->calculateForAbstractSyntaxTree($nodes);
// @codeCoverageIgnoreStart
} catch (Error $error) {
throw new RuntimeException(
$error->getMessage(),
(int) $error->getCode(),
$error
);
}
// @codeCoverageIgnoreEnd
}
/**
* @param Node[] $nodes
*
* @throws RuntimeException
*/
public function calculateForAbstractSyntaxTree(array $nodes): ComplexityCollection
{
$traverser = new NodeTraverser;
$complexityCalculatingVisitor = new ComplexityCalculatingVisitor(true);
$traverser->addVisitor(new NameResolver);
$traverser->addVisitor(new ParentConnectingVisitor);
$traverser->addVisitor($complexityCalculatingVisitor);
try {
/* @noinspection UnusedFunctionResultInspection */
$traverser->traverse($nodes);
// @codeCoverageIgnoreStart
} catch (Error $error) {
throw new RuntimeException(
$error->getMessage(),
(int) $error->getCode(),
$error
);
}
// @codeCoverageIgnoreEnd
return $complexityCalculatingVisitor->result();
}
private function parser(): Parser
{
return (new ParserFactory)->create(ParserFactory::PREFER_PHP7, new Lexer);
}
}
phpunit-complexity-2.0.2/src/Complexity/ 0000775 0000000 0000000 00000000000 13765763404 0020340 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/src/Complexity/Complexity.php 0000664 0000000 0000000 00000001531 13765763404 0023206 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
/**
* @psalm-immutable
*/
final class Complexity
{
/**
* @var string
*/
private $name;
/**
* @var int
*/
private $cyclomaticComplexity;
public function __construct(string $name, int $cyclomaticComplexity)
{
$this->name = $name;
$this->cyclomaticComplexity = $cyclomaticComplexity;
}
public function name(): string
{
return $this->name;
}
public function cyclomaticComplexity(): int
{
return $this->cyclomaticComplexity;
}
}
phpunit-complexity-2.0.2/src/Complexity/ComplexityCollection.php 0000664 0000000 0000000 00000002722 13765763404 0025225 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
use function count;
use Countable;
use IteratorAggregate;
/**
* @psalm-immutable
*/
final class ComplexityCollection implements Countable, IteratorAggregate
{
/**
* @psalm-var list
*/
private $items = [];
public static function fromList(Complexity ...$items): self
{
return new self($items);
}
/**
* @psalm-param list $items
*/
private function __construct(array $items)
{
$this->items = $items;
}
/**
* @psalm-return list
*/
public function asArray(): array
{
return $this->items;
}
public function getIterator(): ComplexityCollectionIterator
{
return new ComplexityCollectionIterator($this);
}
public function count(): int
{
return count($this->items);
}
public function isEmpty(): bool
{
return empty($this->items);
}
public function cyclomaticComplexity(): int
{
$cyclomaticComplexity = 0;
foreach ($this as $item) {
$cyclomaticComplexity += $item->cyclomaticComplexity();
}
return $cyclomaticComplexity;
}
}
phpunit-complexity-2.0.2/src/Complexity/ComplexityCollectionIterator.php 0000664 0000000 0000000 00000002045 13765763404 0026735 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
use Iterator;
final class ComplexityCollectionIterator implements Iterator
{
/**
* @psalm-var list
*/
private $items;
/**
* @var int
*/
private $position = 0;
public function __construct(ComplexityCollection $items)
{
$this->items = $items->asArray();
}
public function rewind(): void
{
$this->position = 0;
}
public function valid(): bool
{
return isset($this->items[$this->position]);
}
public function key(): int
{
return $this->position;
}
public function current(): Complexity
{
return $this->items[$this->position];
}
public function next(): void
{
$this->position++;
}
}
phpunit-complexity-2.0.2/src/Exception/ 0000775 0000000 0000000 00000000000 13765763404 0020141 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/src/Exception/Exception.php 0000664 0000000 0000000 00000000555 13765763404 0022615 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
use Throwable;
interface Exception extends Throwable
{
}
phpunit-complexity-2.0.2/src/Exception/RuntimeException.php 0000664 0000000 0000000 00000000603 13765763404 0024153 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
final class RuntimeException extends \RuntimeException implements Exception
{
}
phpunit-complexity-2.0.2/src/Visitor/ 0000775 0000000 0000000 00000000000 13765763404 0017642 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/src/Visitor/ComplexityCalculatingVisitor.php 0000664 0000000 0000000 00000005561 13765763404 0026246 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
use function assert;
use function is_array;
use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Trait_;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitorAbstract;
final class ComplexityCalculatingVisitor extends NodeVisitorAbstract
{
/**
* @psalm-var list
*/
private $result = [];
/**
* @var bool
*/
private $shortCircuitTraversal;
public function __construct(bool $shortCircuitTraversal)
{
$this->shortCircuitTraversal = $shortCircuitTraversal;
}
public function enterNode(Node $node): ?int
{
if (!$node instanceof ClassMethod && !$node instanceof Function_) {
return null;
}
if ($node instanceof ClassMethod) {
$name = $this->classMethodName($node);
} else {
$name = $this->functionName($node);
}
$statements = $node->getStmts();
assert(is_array($statements));
$this->result[] = new Complexity(
$name,
$this->cyclomaticComplexity($statements)
);
if ($this->shortCircuitTraversal) {
return NodeTraverser::DONT_TRAVERSE_CHILDREN;
}
return null;
}
public function result(): ComplexityCollection
{
return ComplexityCollection::fromList(...$this->result);
}
/**
* @param Stmt[] $statements
*/
private function cyclomaticComplexity(array $statements): int
{
$traverser = new NodeTraverser;
$cyclomaticComplexityCalculatingVisitor = new CyclomaticComplexityCalculatingVisitor;
$traverser->addVisitor($cyclomaticComplexityCalculatingVisitor);
/* @noinspection UnusedFunctionResultInspection */
$traverser->traverse($statements);
return $cyclomaticComplexityCalculatingVisitor->cyclomaticComplexity();
}
private function classMethodName(ClassMethod $node): string
{
$parent = $node->getAttribute('parent');
assert($parent instanceof Class_ || $parent instanceof Trait_);
assert(isset($parent->namespacedName));
assert($parent->namespacedName instanceof Name);
return $parent->namespacedName->toString() . '::' . $node->name->toString();
}
private function functionName(Function_ $node): string
{
assert(isset($node->namespacedName));
assert($node->namespacedName instanceof Name);
return $node->namespacedName->toString();
}
}
phpunit-complexity-2.0.2/src/Visitor/CyclomaticComplexityCalculatingVisitor.php 0000664 0000000 0000000 00000003222 13765763404 0030246 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
use function get_class;
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
use PhpParser\Node\Expr\BinaryOp\LogicalAnd;
use PhpParser\Node\Expr\BinaryOp\LogicalOr;
use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Stmt\Case_;
use PhpParser\Node\Stmt\Catch_;
use PhpParser\Node\Stmt\ElseIf_;
use PhpParser\Node\Stmt\For_;
use PhpParser\Node\Stmt\Foreach_;
use PhpParser\Node\Stmt\If_;
use PhpParser\Node\Stmt\While_;
use PhpParser\NodeVisitorAbstract;
final class CyclomaticComplexityCalculatingVisitor extends NodeVisitorAbstract
{
/**
* @var int
*/
private $cyclomaticComplexity = 1;
public function enterNode(Node $node): void
{
/* @noinspection GetClassMissUseInspection */
switch (get_class($node)) {
case BooleanAnd::class:
case BooleanOr::class:
case Case_::class:
case Catch_::class:
case ElseIf_::class:
case For_::class:
case Foreach_::class:
case If_::class:
case LogicalAnd::class:
case LogicalOr::class:
case Ternary::class:
case While_::class:
$this->cyclomaticComplexity++;
}
}
public function cyclomaticComplexity(): int
{
return $this->cyclomaticComplexity;
}
}
phpunit-complexity-2.0.2/tests/ 0000775 0000000 0000000 00000000000 13765763404 0016556 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/tests/_fixture/ 0000775 0000000 0000000 00000000000 13765763404 0020403 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/tests/_fixture/ExampleClass.php 0000664 0000000 0000000 00000002032 13765763404 0023472 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity\TestFixture;
final class ExampleClass
{
public function method(): void
{
if (true || false) {
if (true && false) {
for ($i = 0; $i <= 1; $i++) {
$a = true ? 'foo' : 'bar';
}
foreach (range(0, 1) as $i) {
switch ($i) {
case 0:
break;
case 1:
break;
default:
}
}
}
} elseif (null) {
try {
} catch (Throwable $t) {
}
}
while (true) {
}
do {
} while (false);
}
}
phpunit-complexity-2.0.2/tests/_fixture/ExampleTrait.php 0000664 0000000 0000000 00000002024 13765763404 0023511 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity\TestFixture;
trait ExampleTrait
{
public function method(): void
{
if (true || false) {
if (true && false) {
for ($i = 0; $i <= 1; $i++) {
$a = true ? 'foo' : 'bar';
}
foreach (range(0, 1) as $i) {
switch ($i) {
case 0:
break;
case 1:
break;
default:
}
}
}
} elseif (null) {
try {
} catch (Throwable $t) {
}
}
while (true) {
}
do {
} while (false);
}
}
phpunit-complexity-2.0.2/tests/_fixture/example_function.php 0000664 0000000 0000000 00000001625 13765763404 0024460 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity\TestFixture;
function example_function(): void
{
if (true or false) {
if (true and false) {
for ($i = 0; $i <= 1; $i++) {
$a = true ? 'foo' : 'bar';
}
foreach (range(0, 1) as $i) {
switch ($i) {
case 0:
break;
case 1:
break;
default:
}
}
}
} elseif (null) {
try {
} catch (Throwable $t) {
}
}
while (true) {
}
do {
} while (false);
}
phpunit-complexity-2.0.2/tests/integration/ 0000775 0000000 0000000 00000000000 13765763404 0021101 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/tests/integration/CalculatorTest.php 0000664 0000000 0000000 00000006056 13765763404 0024552 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
use function file_get_contents;
use PhpParser\Lexer;
use PhpParser\Parser;
use PhpParser\ParserFactory;
use PHPUnit\Framework\TestCase;
/**
* @covers \SebastianBergmann\Complexity\Calculator
* @covers \SebastianBergmann\Complexity\ComplexityCalculatingVisitor
* @covers \SebastianBergmann\Complexity\CyclomaticComplexityCalculatingVisitor
*
* @uses \SebastianBergmann\Complexity\Complexity
* @uses \SebastianBergmann\Complexity\ComplexityCollection
* @uses \SebastianBergmann\Complexity\ComplexityCollectionIterator
*
* @medium
*/
final class CalculatorTest extends TestCase
{
public function testCalculatesCyclomaticComplexityOfClassMethodInSourceFile(): void
{
$result = (new Calculator)->calculateForSourceFile(__DIR__ . '/../_fixture/ExampleClass.php')->asArray();
$this->assertSame('SebastianBergmann\Complexity\TestFixture\ExampleClass::method', $result[0]->name());
$this->assertSame(14, $result[0]->cyclomaticComplexity());
}
public function testCalculatesCyclomaticComplexityOfTraitMethodInSourceFile(): void
{
$result = (new Calculator)->calculateForSourceFile(__DIR__ . '/../_fixture/ExampleTrait.php')->asArray();
$this->assertSame('SebastianBergmann\Complexity\TestFixture\ExampleTrait::method', $result[0]->name());
$this->assertSame(14, $result[0]->cyclomaticComplexity());
}
public function testCalculatesCyclomaticComplexityOfFunctionInSourceFile(): void
{
$result = (new Calculator)->calculateForSourceFile(__DIR__ . '/../_fixture/example_function.php')->asArray();
$this->assertSame('SebastianBergmann\Complexity\TestFixture\example_function', $result[0]->name());
$this->assertSame(14, $result[0]->cyclomaticComplexity());
}
public function testCalculatesCyclomaticComplexityInSourceString(): void
{
$result = (new Calculator)->calculateForSourceString(file_get_contents(__DIR__ . '/../_fixture/ExampleClass.php'))->asArray();
$this->assertSame('SebastianBergmann\Complexity\TestFixture\ExampleClass::method', $result[0]->name());
$this->assertSame(14, $result[0]->cyclomaticComplexity());
}
public function testCalculatesCyclomaticComplexityInAbstractSyntaxTree(): void
{
$nodes = $this->parser()->parse(file_get_contents(__DIR__ . '/../_fixture/ExampleClass.php'));
assert($nodes !== null);
$result = (new Calculator)->calculateForAbstractSyntaxTree($nodes)->asArray();
$this->assertSame('SebastianBergmann\Complexity\TestFixture\ExampleClass::method', $result[0]->name());
$this->assertSame(14, $result[0]->cyclomaticComplexity());
}
private function parser(): Parser
{
return (new ParserFactory)->create(ParserFactory::PREFER_PHP7, new Lexer);
}
}
phpunit-complexity-2.0.2/tests/unit/ 0000775 0000000 0000000 00000000000 13765763404 0017535 5 ustar 00root root 0000000 0000000 phpunit-complexity-2.0.2/tests/unit/ComplexityCalculatingVisitorTest.php 0000664 0000000 0000000 00000005502 13765763404 0026774 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
use function file_get_contents;
use PhpParser\Lexer;
use PhpParser\Node;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitor\NameResolver;
use PhpParser\NodeVisitor\ParentConnectingVisitor;
use PhpParser\NodeVisitorAbstract;
use PhpParser\Parser;
use PhpParser\ParserFactory;
use PHPUnit\Framework\TestCase;
/**
* @covers \SebastianBergmann\Complexity\ComplexityCalculatingVisitor
*
* @uses \SebastianBergmann\Complexity\Complexity
* @uses \SebastianBergmann\Complexity\ComplexityCollection
* @uses \SebastianBergmann\Complexity\ComplexityCollectionIterator
* @uses \SebastianBergmann\Complexity\CyclomaticComplexityCalculatingVisitor
*
* @small
*/
final class ComplexityCalculatingVisitorTest extends TestCase
{
/**
* @dataProvider shortCircuitTraversalProvider
*/
public function testCalculatesComplexityForAbstractSyntaxTree(bool $shortCircuitTraversal): void
{
$nodes = $this->parser()->parse(
file_get_contents(__DIR__ . '/../_fixture/ExampleClass.php')
);
$traverser = new NodeTraverser;
$complexityCalculatingVisitor = new ComplexityCalculatingVisitor($shortCircuitTraversal);
$shortCircuitVisitor = new class extends NodeVisitorAbstract {
private $numberOfNodesVisited = 0;
public function enterNode(Node $node): void
{
$this->numberOfNodesVisited++;
}
public function numberOfNodesVisited(): int
{
return $this->numberOfNodesVisited;
}
};
$traverser->addVisitor(new NameResolver);
$traverser->addVisitor(new ParentConnectingVisitor);
$traverser->addVisitor($complexityCalculatingVisitor);
$traverser->addVisitor($shortCircuitVisitor);
/* @noinspection UnusedFunctionResultInspection */
$traverser->traverse($nodes);
$this->assertSame(14, $complexityCalculatingVisitor->result()->cyclomaticComplexity());
if ($shortCircuitTraversal) {
$this->assertSame(9, $shortCircuitVisitor->numberOfNodesVisited());
} else {
$this->assertSame(70, $shortCircuitVisitor->numberOfNodesVisited());
}
}
public function shortCircuitTraversalProvider(): array
{
return [
'short-circuit traversal' => [true],
'no short-circuit traversal' => [false],
];
}
private function parser(): Parser
{
return (new ParserFactory)->create(ParserFactory::PREFER_PHP7, new Lexer);
}
}
phpunit-complexity-2.0.2/tests/unit/ComplexityCollectionTest.php 0000664 0000000 0000000 00000004063 13765763404 0025262 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
use PHPUnit\Framework\TestCase;
/**
* @covers \SebastianBergmann\Complexity\ComplexityCollection
* @covers \SebastianBergmann\Complexity\ComplexityCollectionIterator
*
* @uses \SebastianBergmann\Complexity\Complexity
*
* @small
*/
final class ComplexityCollectionTest extends TestCase
{
/**
* @psalm-var list
*/
private $array;
protected function setUp(): void
{
$this->array = [
new Complexity('Class::method', 1),
new Complexity('function', 2),
];
}
/**
* @testdox Can be created from list of Complexity objects
*/
public function testCanBeCreatedFromListOfObjects(): void
{
$collection = ComplexityCollection::fromList($this->array[0], $this->array[1]);
$this->assertSame($this->array, $collection->asArray());
}
public function testCanBeCounted(): void
{
$collection = ComplexityCollection::fromList($this->array[0], $this->array[1]);
$this->assertCount(2, $collection);
$this->assertFalse($collection->isEmpty());
}
public function testCanBeIterated(): void
{
$array = [];
foreach (ComplexityCollection::fromList($this->array[0], $this->array[1]) as $key => $value) {
$array[$key] = $value;
}
$this->assertCount(2, $array);
$this->assertArrayHasKey(0, $array);
$this->assertSame($this->array[0], $array[0]);
$this->assertArrayHasKey(1, $array);
$this->assertSame($this->array[1], $array[1]);
}
public function testHasCyclomaticComplexity(): void
{
$collection = ComplexityCollection::fromList($this->array[0], $this->array[1]);
$this->assertSame(3, $collection->cyclomaticComplexity());
}
}
phpunit-complexity-2.0.2/tests/unit/ComplexityTest.php 0000664 0000000 0000000 00000001476 13765763404 0023253 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
use PHPUnit\Framework\TestCase;
/**
* @covers \SebastianBergmann\Complexity\Complexity
*
* @small
*/
final class ComplexityTest extends TestCase
{
public function testHasName(): void
{
$this->assertSame('Foo::bar', $this->complexity()->name());
}
public function testHasCyclomaticComplexity(): void
{
$this->assertSame(1, $this->complexity()->cyclomaticComplexity());
}
private function complexity(): Complexity
{
return new Complexity('Foo::bar', 1);
}
}
phpunit-complexity-2.0.2/tests/unit/CyclomaticComplexityCalculatingVisitorTest.php 0000664 0000000 0000000 00000002451 13765763404 0031004 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Complexity;
use function file_get_contents;
use PhpParser\Lexer;
use PhpParser\NodeTraverser;
use PhpParser\Parser;
use PhpParser\ParserFactory;
use PHPUnit\Framework\TestCase;
/**
* @covers \SebastianBergmann\Complexity\CyclomaticComplexityCalculatingVisitor
*
* @small
*/
final class CyclomaticComplexityCalculatingVisitorTest extends TestCase
{
public function testCalculatesCyclomaticComplexityForAbstractSyntaxTree(): void
{
$nodes = $this->parser()->parse(
file_get_contents(__DIR__ . '/../_fixture/example_function.php')
);
$traverser = new NodeTraverser;
$visitor = new CyclomaticComplexityCalculatingVisitor;
$traverser->addVisitor($visitor);
/* @noinspection UnusedFunctionResultInspection */
$traverser->traverse($nodes);
$this->assertSame(14, $visitor->cyclomaticComplexity());
}
private function parser(): Parser
{
return (new ParserFactory)->create(ParserFactory::PREFER_PHP7, new Lexer);
}
}