pax_global_header 0000666 0000000 0000000 00000000064 13767732007 0014526 g ustar 00root root 0000000 0000000 52 comment=816c79a4c66137254c56ca18c0d0fcbce092cfe3
phploc-7.0.2/ 0000775 0000000 0000000 00000000000 13767732007 0013021 5 ustar 00root root 0000000 0000000 phploc-7.0.2/.github/ 0000775 0000000 0000000 00000000000 13767732007 0014361 5 ustar 00root root 0000000 0000000 phploc-7.0.2/.github/FUNDING.yml 0000664 0000000 0000000 00000000032 13767732007 0016171 0 ustar 00root root 0000000 0000000 github: sebastianbergmann
phploc-7.0.2/.github/workflows/ 0000775 0000000 0000000 00000000000 13767732007 0016416 5 ustar 00root root 0000000 0000000 phploc-7.0.2/.github/workflows/ci.yml 0000664 0000000 0000000 00000004053 13767732007 0017536 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: "./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: "./tools/composer update --no-ansi --no-interaction --no-progress"
- name: "Run vimeo/psalm"
run: "./tools/psalm --config=.psalm/config.xml --no-progress --shepherd --show-info=false --stats"
tests:
name: "Tests"
runs-on: "ubuntu-latest"
strategy:
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: "./tools/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"
phploc-7.0.2/.gitignore 0000664 0000000 0000000 00000000130 13767732007 0015003 0 ustar 00root root 0000000 0000000 /build/phar
/build/*.phar*
/.idea
/composer.lock
/vendor
/.php_cs.cache
/.phpunit.cache
phploc-7.0.2/.phive/ 0000775 0000000 0000000 00000000000 13767732007 0014212 5 ustar 00root root 0000000 0000000 phploc-7.0.2/.phive/phars.xml 0000664 0000000 0000000 00000001111 13767732007 0016043 0 ustar 00root root 0000000 0000000
phploc-7.0.2/.php_cs.dist 0000664 0000000 0000000 00000020614 13767732007 0015243 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');
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,
]);
phploc-7.0.2/.psalm/ 0000775 0000000 0000000 00000000000 13767732007 0014213 5 ustar 00root root 0000000 0000000 phploc-7.0.2/.psalm/baseline.xml 0000664 0000000 0000000 00000044176 13767732007 0016533 0 ustar 00root root 0000000 0000000
false
$start + 2
$start + 1
$start - 2
$start - 1
$previousTokenIndex
bool
bool
bool
$next
$n
countFiles
$file
$className
$tokens[$currentToken][1]
$tokens[$currentToken][1]
$tokens[$i + 2][1]
$tokens[$j][0]
$tokens[$j + 1][1]
$tokens[$i + 1][0]
$tokens[++$i][1]
$tokens[$currentToken][0]
$tokens[$currentToken][1]
$tokens[$currentToken][1]
$tokens[$start + 1][0]
$tokens[$start - 1][0]
$tokens[$previousTokenIndex][0]
$this->classes[$parent]
$file
$namespace
$className
$parent
$parent
string
toArray
$tokens[$j + 1][1]
$namespace
$className
$className
$namespace
$namespace
$namespace
$namespace
$visibility === T_PRIVATE
$namespace !== false
!$namespaced && $namespace !== false
$block === $functionName
$block === $className
$result
$result
$directories
$suffixes
$exclude
$directories
$csvLogfile
$jsonLogfile
$xmlLogfile
$argv
$option[0]
$option[1]
$option[1]
$option[1]
$option[1]
$option[1]
$directories
$option
$suffixes[]
$exclude[]
$csvLogfile
$jsonLogfile
$xmlLogfile
$filename
$number
$number
$name
$name
$namespace
$key
$name
$key
$value
$key
$number
$key
$default
$counts
$currentClassComplexity
$currentClassLines
$currentMethodComplexity
$currentMethodLines
$currentNumberOfMethods
getPublisher
$this->counts
$filename
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->currentClassComplexity
$this->currentClassLines
$this->currentNumberOfMethods
$this->currentMethodComplexity
$this->currentMethodLines
$this->counts[$key]
$colmap
$this->colmap
$count[$key]
$name
$values[]
$count['directories']
$count['files']
$count['loc']
$count['cloc']
$count['loc'] > 0 ? ($count['cloc'] / $count['loc']) * 100 : 0
$count['ncloc']
$count['loc'] > 0 ? ($count['ncloc'] / $count['loc']) * 100 : 0
$count['lloc']
$count['loc'] > 0 ? ($count['lloc'] / $count['loc']) * 100 : 0
$count['llocClasses']
$count['lloc'] > 0 ? ($count['llocClasses'] / $count['lloc']) * 100 : 0
$count['classLlocAvg']
$count['classLlocMin']
$count['classLlocMax']
$count['methodLlocAvg']
$count['methodLlocMin']
$count['methodLlocMax']
$count['averageMethodsPerClass']
$count['minimumMethodsPerClass']
$count['maximumMethodsPerClass']
$count['llocFunctions']
$count['lloc'] > 0 ? ($count['llocFunctions'] / $count['lloc']) * 100 : 0
$count['llocByNof']
$count['llocGlobal']
$count['lloc'] > 0 ? ($count['llocGlobal'] / $count['lloc']) * 100 : 0
$count['ccnByLloc']
$count['classCcnAvg']
$count['classCcnMin']
$count['classCcnMax']
$count['methodCcnAvg']
$count['methodCcnMin']
$count['methodCcnMax']
$count['globalAccesses']
$count['globalConstantAccesses']
$count['globalAccesses'] > 0 ? ($count['globalConstantAccesses'] / $count['globalAccesses']) * 100 : 0
$count['globalVariableAccesses']
$count['globalAccesses'] > 0 ? ($count['globalVariableAccesses'] / $count['globalAccesses']) * 100 : 0
$count['superGlobalVariableAccesses']
$count['globalAccesses'] > 0 ? ($count['superGlobalVariableAccesses'] / $count['globalAccesses']) * 100 : 0
$count['attributeAccesses']
$count['instanceAttributeAccesses']
$count['attributeAccesses'] > 0 ? ($count['instanceAttributeAccesses'] / $count['attributeAccesses']) * 100 : 0
$count['staticAttributeAccesses']
$count['attributeAccesses'] > 0 ? ($count['staticAttributeAccesses'] / $count['attributeAccesses']) * 100 : 0
$count['methodCalls']
$count['instanceMethodCalls']
$count['methodCalls'] > 0 ? ($count['instanceMethodCalls'] / $count['methodCalls']) * 100 : 0
$count['staticMethodCalls']
$count['methodCalls'] > 0 ? ($count['staticMethodCalls'] / $count['methodCalls']) * 100 : 0
$count['namespaces']
$count['interfaces']
$count['traits']
$count['classes']
$count['abstractClasses']
$count['classes'] > 0 ? ($count['abstractClasses'] / $count['classes']) * 100 : 0
$count['concreteClasses']
$count['classes'] > 0 ? ($count['concreteClasses'] / $count['classes']) * 100 : 0
$count['finalClasses']
$count['concreteClasses'] > 0 ? ($count['finalClasses'] / $count['concreteClasses']) * 100 : 0
$count['nonFinalClasses']
$count['concreteClasses'] > 0 ? ($count['nonFinalClasses'] / $count['concreteClasses']) * 100 : 0
$count['methods']
$count['nonStaticMethods']
$count['methods'] > 0 ? ($count['nonStaticMethods'] / $count['methods']) * 100 : 0
$count['staticMethods']
$count['methods'] > 0 ? ($count['staticMethods'] / $count['methods']) * 100 : 0
$count['publicMethods']
$count['methods'] > 0 ? ($count['publicMethods'] / $count['methods']) * 100 : 0
$count['protectedMethods']
$count['methods'] > 0 ? ($count['protectedMethods'] / $count['methods']) * 100 : 0
$count['privateMethods']
$count['methods'] > 0 ? ($count['privateMethods'] / $count['methods']) * 100 : 0
$count['functions']
$count['namedFunctions']
$count['functions'] > 0 ? ($count['namedFunctions'] / $count['functions']) * 100 : 0
$count['anonymousFunctions']
$count['functions'] > 0 ? ($count['anonymousFunctions'] / $count['functions']) * 100 : 0
$count['constants']
$count['globalConstants']
$count['constants'] > 0 ? ($count['globalConstants'] / $count['constants']) * 100 : 0
$count['classConstants']
$count['constants'] > 0 ? ($count['classConstants'] / $count['constants']) * 100 : 0
$count['publicClassConstants']
$count['classConstants'] > 0 ? ($count['publicClassConstants'] / $count['classConstants']) * 100 : 0
$count['nonPublicClassConstants']
$count['classConstants'] > 0 ? ($count['nonPublicClassConstants'] / $count['classConstants']) * 100 : 0
$count['testClasses']
$count['testMethods']
$count['cloc']
$count['ncloc']
$count['lloc']
$count['llocClasses']
$count['llocFunctions']
$count['llocGlobal']
$count['globalConstantAccesses']
$count['globalVariableAccesses']
$count['superGlobalVariableAccesses']
$count['instanceAttributeAccesses']
$count['staticAttributeAccesses']
$count['instanceMethodCalls']
$count['staticMethodCalls']
$count['abstractClasses']
$count['concreteClasses']
$count['finalClasses']
$count['nonFinalClasses']
$count['nonStaticMethods']
$count['staticMethods']
$count['publicMethods']
$count['protectedMethods']
$count['privateMethods']
$count['namedFunctions']
$count['anonymousFunctions']
$count['globalConstants']
$count['classConstants']
$count['publicClassConstants']
$count['nonPublicClassConstants']
$k
$v
$key
$key
$key
$key
$key
$key
$default
$x
$y
getDirectories
getFiles
getLines
getCommentLines
getNonCommentLines
getLogicalLines
getClassLines
getAverageClassLength
getMinimumClassLength
getMaximumClassLength
getAverageMethodLength
getMinimumMethodLength
getMaximumMethodLength
getAverageMethodsPerClass
getMinimumMethodsPerClass
getMaximumMethodsPerClass
getFunctionLines
getAverageFunctionLength
getNotInClassesOrFunctions
getComplexity
getMethodComplexity
getAverageComplexityPerLogicalLine
getAverageComplexityPerClass
getMinimumClassComplexity
getMaximumClassComplexity
getAverageComplexityPerMethod
getMinimumMethodComplexity
getMaximumMethodComplexity
getGlobalAccesses
getGlobalConstantAccesses
getGlobalVariableAccesses
getSuperGlobalVariableAccesses
getAttributeAccesses
getNonStaticAttributeAccesses
getStaticAttributeAccesses
getMethodCalls
getNonStaticMethodCalls
getStaticMethodCalls
getNamespaces
getInterfaces
getTraits
getClasses
getAbstractClasses
getConcreteClasses
getFinalClasses
getNonFinalClasses
getMethods
getNonStaticMethods
getStaticMethods
getPublicMethods
getNonPublicMethods
getProtectedMethods
getPrivateMethods
getFunctions
getNamedFunctions
getAnonymousFunctions
getConstants
getGlobalConstants
getPublicClassConstants
getNonPublicClassConstants
getClassConstants
getTestClasses
getTestMethods
toArray
getAverage
getCount
getSum
getMaximum
getMinimum
getValue
divide
$this->getValue('possible constant accesses', [])
$this->getValue('constant', [])
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->counts[$key]
$this->getCount('directories')
$this->getLines()
$this->getLogicalLines()
$this->getGlobalConstantAccesses()
$this->getNonStaticAttributeAccesses()
$this->getNonStaticMethodCalls()
$this->getAbstractClasses()
$this->getFinalClasses()
$this->getNonStaticMethods()
$this->getProtectedMethods()
$this->getNamedFunctions()
$this->getGlobalConstants()
$this->getPublicClassConstants()
$x
phploc-7.0.2/.psalm/config.xml 0000664 0000000 0000000 00000000710 13767732007 0016200 0 ustar 00root root 0000000 0000000
phploc-7.0.2/ChangeLog.md 0000664 0000000 0000000 00000005204 13767732007 0015173 0 ustar 00root root 0000000 0000000 # Changes in PHPLOC
All notable changes in PHPLOC are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [7.0.2] - 2020-12-07
### Changed
* Changed PHP version constraint in `composer.json` from `^7.3` to `>=7.3`
## [7.0.1] - 2020-08-18
### Fixed
* The `--exclude` CLI option was not handled correctly
## [7.0.0] - 2020-08-13
### Removed
* The `--names` CLI option has been removed; use the `--suffix` CLI option instead
* The `--names-exclude` CLI option has been removed; use the `--exclude` CLI option instead
## [6.0.2] - 2020-02-28
### Fixed
* [#207](https://github.com/sebastianbergmann/phploc/issues/207): `TypeError` in `DOMDocument::createElement()` calls
## [6.0.1] - 2020-02-27
### Fixed
* [#205](https://github.com/sebastianbergmann/phploc/pull/205): `TypeError` in `ini_set()` calls
## [6.0.0] - 2020-02-20
### Removed
* This tool is no longer supported on PHP 7.2
## [5.0.0] - 2019-03-16
### Fixed
* [#182](https://github.com/sebastianbergmann/phploc/pull/182): `"continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"`
### Removed
* This tool is no longer supported on PHP 5.6, PHP 7.0, and PHP 7.1
## [4.0.1] - 2017-11-18
### Changed
* This tool is now compatible with Symfony Console 4
## [4.0.0] - 2017-06-06
### Removed
* Removed the `--git-repository` option (and the corresponding functionality)
* Removed the `--progress` option (and the corresponding functionality)
## [3.0.1] - 2016-04-25
### Fixed
* [#139](https://github.com/sebastianbergmann/phploc/issues/139): Introduction of `T_USE` in `Analyser.php` gives `PHP Notice: Undefined index: ccn`
* [#141](https://github.com/sebastianbergmann/phploc/issues/141): `Undefined index: ccn in phar:///usr/local/bin/phploc/src/Analyser.php on line 507`
### Fixed
## [3.0.0] - 2016-01-13
[7.0.2]: https://github.com/sebastianbergmann/phploc/compare/7.0.1...7.0.2
[7.0.1]: https://github.com/sebastianbergmann/phploc/compare/7.0.0...7.0.1
[7.0.0]: https://github.com/sebastianbergmann/phploc/compare/6.0.2...7.0.0
[6.0.2]: https://github.com/sebastianbergmann/phploc/compare/6.0.1...6.0.2
[6.0.1]: https://github.com/sebastianbergmann/phploc/compare/6.0.0...6.0.1
[6.0.0]: https://github.com/sebastianbergmann/phploc/compare/5.0.0...6.0.0
[5.0.0]: https://github.com/sebastianbergmann/phploc/compare/4.0.1...5.0.0
[4.0.1]: https://github.com/sebastianbergmann/phploc/compare/4.0.0...4.0.1
[4.0.0]: https://github.com/sebastianbergmann/phploc/compare/3.0...4.0.0
[3.0.1]: https://github.com/sebastianbergmann/phploc/compare/3.0.0...3.0.1
[3.0.0]: https://github.com/sebastianbergmann/phploc/compare/2.1.5...3.0.0
phploc-7.0.2/LICENSE 0000664 0000000 0000000 00000003005 13767732007 0014024 0 ustar 00root root 0000000 0000000 phploc
Copyright (c) 2009-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.
phploc-7.0.2/README.md 0000664 0000000 0000000 00000007250 13767732007 0014304 0 ustar 00root root 0000000 0000000 # PHPLOC
`phploc` is a tool for quickly measuring the size and analyzing the structure of a PHP project.
## Installation
This tool is distributed as a [PHP Archive (PHAR)](https://php.net/phar):
```bash
$ wget https://phar.phpunit.de/phploc.phar
$ php phploc.phar --version
```
Using [Phive](https://phar.io/) is the recommended way for managing the tool dependencies of your project:
```bash
$ phive install phploc
$ ./tools/phploc --version
```
**[It is not recommended to use Composer to download and install this tool.](https://twitter.com/s_bergmann/status/999635212723212288)**
## Usage Examples
### Analyse a directory and print the result
```
$ php phploc.phar src
phploc 7.0.0 by Sebastian Bergmann.
Directories 3
Files 10
Size
Lines of Code (LOC) 1882
Comment Lines of Code (CLOC) 255 (13.55%)
Non-Comment Lines of Code (NCLOC) 1627 (86.45%)
Logical Lines of Code (LLOC) 377 (20.03%)
Classes 351 (93.10%)
Average Class Length 35
Minimum Class Length 0
Maximum Class Length 172
Average Method Length 2
Minimum Method Length 1
Maximum Method Length 117
Functions 0 (0.00%)
Average Function Length 0
Not in classes or functions 26 (6.90%)
Cyclomatic Complexity
Average Complexity per LLOC 0.49
Average Complexity per Class 19.60
Minimum Class Complexity 1.00
Maximum Class Complexity 139.00
Average Complexity per Method 2.43
Minimum Method Complexity 1.00
Maximum Method Complexity 96.00
Dependencies
Global Accesses 0
Global Constants 0 (0.00%)
Global Variables 0 (0.00%)
Super-Global Variables 0 (0.00%)
Attribute Accesses 85
Non-Static 85 (100.00%)
Static 0 (0.00%)
Method Calls 280
Non-Static 276 (98.57%)
Static 4 (1.43%)
Structure
Namespaces 3
Interfaces 1
Traits 0
Classes 9
Abstract Classes 0 (0.00%)
Concrete Classes 9 (100.00%)
Methods 130
Scope
Non-Static Methods 130 (100.00%)
Static Methods 0 (0.00%)
Visibility
Public Methods 103 (79.23%)
Non-Public Methods 27 (20.77%)
Functions 0
Named Functions 0 (0.00%)
Anonymous Functions 0 (0.00%)
Constants 0
Global Constants 0 (0.00%)
Class Constants 0 (0.00%)
```
phploc-7.0.2/build.xml 0000664 0000000 0000000 00000010615 13767732007 0014645 0 ustar 00root root 0000000 0000000
phploc-7.0.2/build/ 0000775 0000000 0000000 00000000000 13767732007 0014120 5 ustar 00root root 0000000 0000000 phploc-7.0.2/build/phar-autoload.php.in 0000664 0000000 0000000 00000001630 13767732007 0017776 0 ustar 00root root 0000000 0000000 #!/usr/bin/env php
run($_SERVER['argv']));
__HALT_COMPILER();
phploc-7.0.2/build/phar-manifest.php 0000775 0000000 0000000 00000001337 13767732007 0017376 0 ustar 00root root 0000000 0000000 #!/usr/bin/env php
&1');
if (strpos($tag, '-') === false && strpos($tag, 'No names found') === false) {
print $tag;
} else {
$branch = @exec('git rev-parse --abbrev-ref HEAD');
$hash = @exec('git log -1 --format="%H"');
print $branch . '@' . $hash;
}
print "\n";
$lock = json_decode(file_get_contents(__DIR__ . '/../composer.lock'));
foreach ($lock->packages as $package) {
print $package->name . ': ' . $package->version;
if (!preg_match('/^[v= ]*(([0-9]+)(\\.([0-9]+)(\\.([0-9]+)(-([0-9]+))?(-?([a-zA-Z-+][a-zA-Z0-9\\.\\-:]*)?)?)?)?)$/', $package->version)) {
print '@' . $package->source->reference;
}
print "\n";
}
phploc-7.0.2/composer.json 0000664 0000000 0000000 00000002010 13767732007 0015534 0 ustar 00root root 0000000 0000000 {
"name": "phploc/phploc",
"description": "A tool for quickly measuring the size of a PHP project.",
"homepage": "https://github.com/sebastianbergmann/phploc",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"support": {
"issues": "https://github.com/sebastianbergmann/phploc/issues"
},
"config": {
"platform": {
"php": "7.3.0"
},
"optimize-autoloader": true,
"sort-packages": true
},
"require": {
"php": ">=7.3",
"ext-dom": "*",
"ext-json": "*",
"sebastian/cli-parser": "^1.0",
"sebastian/version": "^3.0",
"phpunit/php-file-iterator": "^3.0"
},
"autoload": {
"classmap": [
"src/"
]
},
"bin": [
"phploc"
],
"extra": {
"branch-alias": {
"dev-master": "7.0-dev"
}
}
}
phploc-7.0.2/phploc 0000775 0000000 0000000 00000001407 13767732007 0014236 0 ustar 00root root 0000000 0000000 #!/usr/bin/env php
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
$loaded = false;
foreach (array(__DIR__ . '/../../autoload.php', __DIR__ . '/vendor/autoload.php') as $file) {
if (file_exists($file)) {
require $file;
$loaded = true;
break;
}
}
if (!$loaded) {
die(
'You need to set up the project dependencies using the following commands:' . PHP_EOL .
'wget http://getcomposer.org/composer.phar' . PHP_EOL .
'php composer.phar install' . PHP_EOL
);
}
exit((new \SebastianBergmann\PHPLOC\Application)->run($_SERVER['argv']));
phploc-7.0.2/phpunit.xml 0000664 0000000 0000000 00000001646 13767732007 0015241 0 ustar 00root root 0000000 0000000
tests
src
phploc-7.0.2/src/ 0000775 0000000 0000000 00000000000 13767732007 0013610 5 ustar 00root root 0000000 0000000 phploc-7.0.2/src/Analyser.php 0000664 0000000 0000000 00000055167 13767732007 0016115 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\PHPLOC;
use const T_ABSTRACT;
use const T_BOOLEAN_AND;
use const T_BOOLEAN_OR;
use const T_CASE;
use const T_CATCH;
use const T_CLASS;
use const T_COMMENT;
use const T_CONST;
use const T_CONSTANT_ENCAPSED_STRING;
use const T_CURLY_OPEN;
use const T_DECLARE;
use const T_DOC_COMMENT;
use const T_DOLLAR_OPEN_CURLY_BRACES;
use const T_DOUBLE_COLON;
use const T_ELSEIF;
use const T_EXTENDS;
use const T_FINAL;
use const T_FOR;
use const T_FOREACH;
use const T_FUNCTION;
use const T_GLOBAL;
use const T_IF;
use const T_INTERFACE;
use const T_LOGICAL_AND;
use const T_LOGICAL_OR;
use const T_NAMESPACE;
use const T_NEW;
use const T_NS_SEPARATOR;
use const T_OBJECT_OPERATOR;
use const T_PRIVATE;
use const T_PROTECTED;
use const T_PUBLIC;
use const T_STATIC;
use const T_STRING;
use const T_TRAIT;
use const T_USE;
use const T_VARIABLE;
use const T_WHILE;
use const T_WHITESPACE;
use function array_pop;
use function count;
use function file_get_contents;
use function in_array;
use function is_array;
use function is_string;
use function rtrim;
use function str_replace;
use function strpos;
use function strtolower;
use function substr;
use function substr_count;
use function token_get_all;
use function trim;
final class Analyser
{
/**
* @var Collector
*/
private $collector;
/**
* @var array
*/
private $classes = [];
/**
* @var array
*/
private $superGlobals = [
'$_ENV' => true,
'$_POST' => true,
'$_GET' => true,
'$_COOKIE' => true,
'$_SERVER' => true,
'$_FILES' => true,
'$_REQUEST' => true,
'$HTTP_ENV_VARS' => true,
'$HTTP_POST_VARS' => true,
'$HTTP_GET_VARS' => true,
'$HTTP_COOKIE_VARS' => true,
'$HTTP_SERVER_VARS' => true,
'$HTTP_POST_FILES' => true,
];
public function __construct()
{
$this->collector = new Collector;
}
public function countFiles(array $files, bool $countTests)
{
foreach ($files as $file) {
$this->countFile($file, $countTests);
}
return $this->collector->getPublisher()->toArray();
}
public function preProcessFile(string $filename): void
{
$tokens = token_get_all(file_get_contents($filename));
$numTokens = count($tokens);
$namespace = false;
for ($i = 0; $i < $numTokens; $i++) {
if (is_string($tokens[$i])) {
continue;
}
switch ($tokens[$i][0]) {
case T_NAMESPACE:
$namespace = $this->getNamespaceName($tokens, $i);
break;
case T_CLASS:
if (!$this->isClassDeclaration($tokens, $i)) {
break;
}
$className = $this->getClassName($namespace, $tokens, $i);
if (isset($tokens[$i + 4]) && is_array($tokens[$i + 4]) &&
$tokens[$i + 4][0] === T_EXTENDS) {
$parent = $this->getClassName($namespace, $tokens, $i + 4);
} else {
$parent = null;
}
$this->classes[$className] = $parent;
break;
}
}
}
/**
* Processes a single file.
*
* @param string $filename
* @param bool $countTests
*/
public function countFile($filename, $countTests): void
{
if ($countTests) {
$this->preProcessFile($filename);
}
$buffer = file_get_contents($filename);
$this->collector->incrementLines(substr_count($buffer, "\n"));
$tokens = token_get_all($buffer);
$numTokens = count($tokens);
unset($buffer);
$this->collector->addFile($filename);
$blocks = [];
$currentBlock = false;
$namespace = false;
$className = null;
$functionName = null;
$testClass = false;
$this->collector->currentClassReset();
$isLogicalLine = true;
$isInMethod = false;
for ($i = 0; $i < $numTokens; $i++) {
if (is_string($tokens[$i])) {
$token = trim($tokens[$i]);
if ($token === ';') {
if ($isLogicalLine) {
if ($className !== null && !$testClass) {
$this->collector->currentClassIncrementLines();
if ($functionName !== null) {
$this->collector->currentMethodIncrementLines();
}
} elseif ($functionName !== null) {
$this->collector->incrementFunctionLines();
}
$this->collector->incrementLogicalLines();
}
$isLogicalLine = true;
} elseif ($token === '?' && !$testClass) {
if ($className !== null) {
$this->collector->currentClassIncrementComplexity();
$this->collector->currentMethodIncrementComplexity();
}
$this->collector->incrementComplexity();
} elseif ($token === '{') {
if ($currentBlock == T_CLASS) {
$block = $className;
} elseif ($currentBlock == T_FUNCTION) {
$block = $functionName;
} else {
$block = false;
}
$blocks[] = $block;
$currentBlock = false;
} elseif ($token === '}') {
$block = array_pop($blocks);
if ($block !== false && $block !== null) {
if ($block === $functionName) {
$functionName = null;
if ($isInMethod) {
$this->collector->currentMethodStop();
$isInMethod = false;
}
} elseif ($block === $className) {
$className = null;
$testClass = false;
$this->collector->currentClassStop();
$this->collector->currentClassReset();
}
}
}
continue;
}
[$token, $value] = $tokens[$i];
switch ($token) {
case T_NAMESPACE:
$namespace = $this->getNamespaceName($tokens, $i);
$this->collector->addNamespace($namespace);
$isLogicalLine = false;
break;
case T_CLASS:
case T_INTERFACE:
case T_TRAIT:
if (!$this->isClassDeclaration($tokens, $i)) {
break;
}
$this->collector->currentClassReset();
$this->collector->currentClassIncrementComplexity();
$className = $this->getClassName($namespace, $tokens, $i);
$currentBlock = T_CLASS;
if ($token === T_TRAIT) {
$this->collector->incrementTraits();
} elseif ($token === T_INTERFACE) {
$this->collector->incrementInterfaces();
} else {
if ($countTests && $this->isTestClass($className)) {
$testClass = true;
$this->collector->incrementTestClasses();
} else {
$classModifierToken = $this->getPreviousNonWhitespaceNonCommentTokenPos($tokens, $i);
if ($classModifierToken !== false &&
$tokens[$classModifierToken][0] === T_ABSTRACT
) {
$this->collector->incrementAbstractClasses();
} elseif (
$classModifierToken !== false &&
$tokens[$classModifierToken][0] === T_FINAL
) {
$this->collector->incrementFinalClasses();
} else {
$this->collector->incrementNonFinalClasses();
}
}
}
break;
case T_FUNCTION:
$prev = $this->getPreviousNonWhitespaceTokenPos($tokens, $i);
if ($tokens[$prev][0] === T_USE) {
break;
}
$currentBlock = T_FUNCTION;
$next = $this->getNextNonWhitespaceTokenPos($tokens, $i);
if (!is_array($tokens[$next]) && $tokens[$next] === '&') {
$next = $this->getNextNonWhitespaceTokenPos($tokens, $next);
}
if (is_array($tokens[$next]) &&
$tokens[$next][0] === T_STRING) {
$functionName = $tokens[$next][1];
} else {
$currentBlock = 'anonymous function';
$functionName = 'anonymous function';
$this->collector->incrementAnonymousFunctions();
}
if ($currentBlock === T_FUNCTION) {
if ($className === null &&
$functionName !== 'anonymous function') {
$this->collector->incrementNamedFunctions();
} else {
$static = false;
$visibility = T_PUBLIC;
for ($j = $i; $j > 0; $j--) {
if (is_string($tokens[$j])) {
if ($tokens[$j] === '{' ||
$tokens[$j] === '}' ||
$tokens[$j] === ';') {
break;
}
continue;
}
if (isset($tokens[$j][0])) {
switch ($tokens[$j][0]) {
case T_PRIVATE:
$visibility = T_PRIVATE;
break;
case T_PROTECTED:
$visibility = T_PROTECTED;
break;
case T_STATIC:
$static = true;
break;
}
}
}
if ($testClass &&
$this->isTestMethod($functionName, $visibility, $static, $tokens, $i)) {
$this->collector->incrementTestMethods();
} elseif (!$testClass) {
$isInMethod = true;
$this->collector->currentMethodStart();
$this->collector->currentClassIncrementMethods();
if (!$static) {
$this->collector->incrementNonStaticMethods();
} else {
$this->collector->incrementStaticMethods();
}
if ($visibility === T_PUBLIC) {
$this->collector->incrementPublicMethods();
} elseif ($visibility === T_PROTECTED) {
$this->collector->incrementProtectedMethods();
} elseif ($visibility === T_PRIVATE) {
$this->collector->incrementPrivateMethods();
}
}
}
}
break;
case T_CURLY_OPEN:
$currentBlock = T_CURLY_OPEN;
$blocks[] = $currentBlock;
break;
case T_DOLLAR_OPEN_CURLY_BRACES:
$currentBlock = T_DOLLAR_OPEN_CURLY_BRACES;
$blocks[] = $currentBlock;
break;
case T_IF:
case T_ELSEIF:
case T_FOR:
case T_FOREACH:
case T_WHILE:
case T_CASE:
case T_CATCH:
case T_BOOLEAN_AND:
case T_LOGICAL_AND:
case T_BOOLEAN_OR:
case T_LOGICAL_OR:
if (!$testClass) {
if ($isInMethod) {
$this->collector->currentClassIncrementComplexity();
$this->collector->currentMethodIncrementComplexity();
}
$this->collector->incrementComplexity();
}
break;
case T_COMMENT:
case T_DOC_COMMENT:
// We want to count all intermediate lines before the token ends
// But sometimes a new token starts after a newline, we don't want to count that.
// That happened with /* */ and /** */, but not with // since it'll end at the end
$this->collector->incrementCommentLines(substr_count(rtrim($value, "\n"), "\n") + 1);
break;
case T_CONST:
$possibleScopeToken = $this->getPreviousNonWhitespaceNonCommentTokenPos($tokens, $i);
if ($possibleScopeToken !== false
&& in_array($tokens[$possibleScopeToken][0], [T_PRIVATE, T_PROTECTED], true)
) {
$this->collector->incrementNonPublicClassConstants();
} else {
$this->collector->incrementPublicClassConstants();
}
break;
case T_STRING:
if ($value === 'define') {
$this->collector->incrementGlobalConstants();
$j = $i + 1;
while (isset($tokens[$j]) && $tokens[$j] !== ';') {
if (is_array($tokens[$j]) &&
$tokens[$j][0] === T_CONSTANT_ENCAPSED_STRING) {
$this->collector->addConstant(str_replace('\'', '', $tokens[$j][1]));
break;
}
$j++;
}
} else {
$this->collector->addPossibleConstantAccesses($value);
}
break;
case T_DOUBLE_COLON:
case T_OBJECT_OPERATOR:
$n = $this->getNextNonWhitespaceTokenPos($tokens, $i);
$nn = $this->getNextNonWhitespaceTokenPos($tokens, $n);
if ($n && $nn &&
isset($tokens[$n][0]) &&
($tokens[$n][0] === T_STRING ||
$tokens[$n][0] === T_VARIABLE) &&
$tokens[$nn] === '(') {
if ($token === T_DOUBLE_COLON) {
$this->collector->incrementStaticMethodCalls();
} else {
$this->collector->incrementNonStaticMethodCalls();
}
} else {
if ($token === T_DOUBLE_COLON &&
$tokens[$n][0] === T_VARIABLE) {
$this->collector->incrementStaticAttributeAccesses();
} elseif ($token === T_OBJECT_OPERATOR) {
$this->collector->incrementNonStaticAttributeAccesses();
}
}
break;
case T_GLOBAL:
$this->collector->incrementGlobalVariableAccesses();
break;
case T_VARIABLE:
if ($value === '$GLOBALS') {
$this->collector->incrementGlobalVariableAccesses();
} elseif (isset($this->superGlobals[$value])) {
$this->collector->incrementSuperGlobalVariableAccesses();
}
break;
case T_USE:
case T_DECLARE:
$isLogicalLine = false;
break;
}
}
}
/**
* @param int $i
*
* @return string
*/
private function getNamespaceName(array $tokens, $i)
{
if (isset($tokens[$i + 2][1])) {
$namespace = $tokens[$i + 2][1];
for ($j = $i + 3;; $j += 2) {
if (isset($tokens[$j]) && $tokens[$j][0] === T_NS_SEPARATOR) {
$namespace .= '\\' . $tokens[$j + 1][1];
} else {
break;
}
}
return $namespace;
}
return false;
}
/**
* @param string $namespace
* @param int $i
*
* @return string
*/
private function getClassName($namespace, array $tokens, $i)
{
$i += 2;
if (!isset($tokens[$i][1])) {
return 'invalid class name';
}
$className = $tokens[$i][1];
$namespaced = $className === '\\';
while (isset($tokens[$i + 1]) && is_array($tokens[$i + 1]) && $tokens[$i + 1][0] !== T_WHITESPACE) {
$className .= $tokens[++$i][1];
}
if (!$namespaced && $namespace !== false) {
$className = $namespace . '\\' . $className;
}
return strtolower($className);
}
/**
* @param string $className
*
* @return bool
*/
private function isTestClass($className)
{
$parent = $this->classes[$className];
$count = 0;
// Check ancestry for PHPUnit_Framework_TestCase.
while ($parent !== null) {
$count++;
if ($count > 100) {
// Prevent infinite loops and just bail
break;
}
if ($parent === 'phpunit_framework_testcase' ||
$parent === '\\phpunit_framework_testcase' ||
// TODO: Recognize PHPUnit\Framework\TestCase when it is imported
$parent === 'phpunit\\framework\\testcase' ||
$parent === '\\phpunit\\framework\\testcase') {
return true;
}
if (isset($this->classes[$parent]) && $parent !== $this->classes[$parent]) {
$parent = $this->classes[$parent];
} else {
// Class has a parent that is declared in a file
// that was not pre-processed.
break;
}
}
// Fallback: Treat the class as a test case class if the name
// of the parent class ends with "TestCase".
return substr((string) $this->classes[$className], -8) === 'testcase';
}
/**
* @param string $functionName
* @param int $visibility
* @param bool $static
* @param int $currentToken
*
* @return bool
*/
private function isTestMethod($functionName, $visibility, $static, array $tokens, $currentToken)
{
if ($static || $visibility != T_PUBLIC) {
return false;
}
if (strpos($functionName, 'test') === 0) {
return true;
}
while ($tokens[$currentToken][0] !== T_DOC_COMMENT) {
if ($tokens[$currentToken] === '{' || $tokens[$currentToken] === '}') {
return false;
}
$currentToken--;
}
return strpos($tokens[$currentToken][1], '@test') !== false ||
strpos($tokens[$currentToken][1], '@scenario') !== false;
}
/**
* @param int $start
*
* @return bool
*/
private function getNextNonWhitespaceTokenPos(array $tokens, $start)
{
if (isset($tokens[$start + 1])) {
if (isset($tokens[$start + 1][0]) &&
$tokens[$start + 1][0] === T_WHITESPACE &&
isset($tokens[$start + 2])) {
return $start + 2;
}
return $start + 1;
}
return false;
}
/**
* @param int $start
*
* @return bool
*/
private function getPreviousNonWhitespaceTokenPos(array $tokens, $start)
{
if (isset($tokens[$start - 1])) {
if (isset($tokens[$start - 1][0]) &&
$tokens[$start - 1][0] === T_WHITESPACE &&
isset($tokens[$start - 2])) {
return $start - 2;
}
return $start - 1;
}
return false;
}
/**
* @return bool
*/
private function getPreviousNonWhitespaceNonCommentTokenPos(array $tokens, int $start)
{
$previousTokenIndex = $start - 1;
if (isset($tokens[$previousTokenIndex])) {
if (in_array($tokens[$previousTokenIndex][0], [
T_WHITESPACE,
T_COMMENT,
T_DOC_COMMENT,
], true)
) {
return $this->getPreviousNonWhitespaceNonCommentTokenPos($tokens, $previousTokenIndex);
}
return $previousTokenIndex;
}
return false;
}
/**
* @param int $i
*
* @return bool
*/
private function isClassDeclaration(array $tokens, $i)
{
$n = $this->getPreviousNonWhitespaceTokenPos($tokens, $i);
return !isset($tokens[$n])
|| !is_array($tokens[$n])
|| !in_array($tokens[$n][0], [T_DOUBLE_COLON, T_NEW], true);
}
}
phploc-7.0.2/src/CLI/ 0000775 0000000 0000000 00000000000 13767732007 0014217 5 ustar 00root root 0000000 0000000 phploc-7.0.2/src/CLI/Application.php 0000664 0000000 0000000 00000005763 13767732007 0017206 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\PHPLOC;
use const PHP_EOL;
use function printf;
use SebastianBergmann\FileIterator\Facade;
use SebastianBergmann\PHPLOC\Log\Csv as CsvPrinter;
use SebastianBergmann\PHPLOC\Log\Json as JsonPrinter;
use SebastianBergmann\PHPLOC\Log\Text as TextPrinter;
use SebastianBergmann\PHPLOC\Log\Xml as XmlPrinter;
use SebastianBergmann\Version;
final class Application
{
private const VERSION = '7.0.2';
public function run(array $argv): int
{
$this->printVersion();
try {
$arguments = (new ArgumentsBuilder)->build($argv);
} catch (Exception $e) {
print PHP_EOL . $e->getMessage() . PHP_EOL;
return 1;
}
if ($arguments->version()) {
return 0;
}
print PHP_EOL;
if ($arguments->help()) {
$this->help();
return 0;
}
$files = (new Facade)->getFilesAsArray(
$arguments->directories(),
$arguments->suffixes(),
'',
$arguments->exclude()
);
if (empty($files)) {
print 'No files found to scan' . PHP_EOL;
return 1;
}
$result = (new Analyser)->countFiles($files, $arguments->countTests());
(new TextPrinter)->printResult($result, $arguments->countTests());
if ($arguments->csvLogfile()) {
$printer = new CsvPrinter;
$printer->printResult($arguments->csvLogfile(), $result);
}
if ($arguments->jsonLogfile()) {
$printer = new JsonPrinter;
$printer->printResult($arguments->jsonLogfile(), $result);
}
if ($arguments->xmlLogfile()) {
$printer = new XmlPrinter;
$printer->printResult($arguments->xmlLogfile(), $result);
}
return 0;
}
private function printVersion(): void
{
printf(
'phploc %s by Sebastian Bergmann.' . PHP_EOL,
(new Version(self::VERSION, dirname(__DIR__)))->getVersion()
);
}
private function help(): void
{
print <<<'EOT'
Usage:
phploc [options]
Options for selecting files:
--suffix Include files with names ending in in the analysis
(default: .php; can be given multiple times)
--exclude Exclude files with in their path from the analysis
(can be given multiple times)
Options for analysing files:
--count-tests Count PHPUnit test case classes and test methods
Options for report generation:
--log-csv Write results in CSV format to
--log-json Write results in JSON format to
--log-xml Write results in XML format to
EOT;
}
}
phploc-7.0.2/src/CLI/Arguments.php 0000664 0000000 0000000 00000004501 13767732007 0016675 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\PHPLOC;
final class Arguments
{
/**
* @psalm-var list
*/
private $directories;
/**
* @psalm-var list
*/
private $suffixes;
/**
* @psalm-var list
*/
private $exclude;
/**
* @var bool
*/
private $countTests;
/**
* @var ?string
*/
private $csvLogfile;
/**
* @var ?string
*/
private $jsonLogfile;
/**
* @var ?string
*/
private $xmlLogfile;
/**
* @var bool
*/
private $help;
/**
* @var bool
*/
private $version;
public function __construct(array $directories, array $suffixes, array $exclude, bool $countTests, ?string $csvLogfile, ?string $jsonLogfile, ?string $xmlLogfile, bool $help, bool $version)
{
$this->directories = $directories;
$this->suffixes = $suffixes;
$this->exclude = $exclude;
$this->countTests = $countTests;
$this->csvLogfile = $csvLogfile;
$this->jsonLogfile = $jsonLogfile;
$this->xmlLogfile = $xmlLogfile;
$this->help = $help;
$this->version = $version;
}
/**
* @psalm-return list
*/
public function directories(): array
{
return $this->directories;
}
/**
* @psalm-return list
*/
public function suffixes(): array
{
return $this->suffixes;
}
/**
* @psalm-return list
*/
public function exclude(): array
{
return $this->exclude;
}
public function countTests(): bool
{
return $this->countTests;
}
public function csvLogfile(): ?string
{
return $this->csvLogfile;
}
public function jsonLogfile(): ?string
{
return $this->jsonLogfile;
}
public function xmlLogfile(): ?string
{
return $this->xmlLogfile;
}
public function help(): bool
{
return $this->help;
}
public function version(): bool
{
return $this->version;
}
}
phploc-7.0.2/src/CLI/ArgumentsBuilder.php 0000664 0000000 0000000 00000005476 13767732007 0020220 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\PHPLOC;
use SebastianBergmann\CliParser\Exception as CliParserException;
use SebastianBergmann\CliParser\Parser as CliParser;
final class ArgumentsBuilder
{
/**
* @throws ArgumentsBuilderException
*/
public function build(array $argv): Arguments
{
try {
$options = (new CliParser)->parse(
$argv,
'hv',
[
'suffix=',
'exclude=',
'count-tests',
'log-csv=',
'log-json=',
'log-xml=',
'help',
'version',
]
);
} catch (CliParserException $e) {
throw new ArgumentsBuilderException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
}
$directories = $options[1];
$exclude = [];
$suffixes = ['.php'];
$countTests = false;
$csvLogfile = null;
$jsonLogfile = null;
$xmlLogfile = null;
$help = false;
$version = false;
foreach ($options[0] as $option) {
switch ($option[0]) {
case '--suffix':
$suffixes[] = $option[1];
break;
case '--exclude':
$exclude[] = $option[1];
break;
case '--count-tests':
$countTests = true;
break;
case '--log-csv':
$csvLogfile = $option[1];
break;
case '--log-json':
$jsonLogfile = $option[1];
break;
case '--log-xml':
$xmlLogfile = $option[1];
break;
case 'h':
case '--help':
$help = true;
break;
case 'v':
case '--version':
$version = true;
break;
}
}
if (empty($options[1]) && !$help && !$version) {
throw new ArgumentsBuilderException(
'No directory specified'
);
}
return new Arguments(
$directories,
$suffixes,
$exclude,
$countTests,
$csvLogfile,
$jsonLogfile,
$xmlLogfile,
$help,
$version,
);
}
}
phploc-7.0.2/src/Collector.php 0000664 0000000 0000000 00000014442 13767732007 0016254 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\PHPLOC;
use function dirname;
class Collector
{
private $counts = [];
private $currentClassComplexity = 0;
private $currentClassLines = 0;
private $currentMethodComplexity = 0;
private $currentMethodLines = 0;
private $currentNumberOfMethods = 0;
public function getPublisher()
{
return new Publisher($this->counts);
}
public function addFile($filename): void
{
$this->increment('files');
$this->addUnique('directories', dirname($filename));
}
public function incrementLines($number): void
{
$this->increment('lines', $number);
}
public function incrementCommentLines($number): void
{
$this->increment('comment lines', $number);
}
public function incrementLogicalLines(): void
{
$this->increment('logical lines');
}
public function currentClassReset(): void
{
if ($this->currentClassComplexity > 0) {
$this->addToArray('class complexity', $this->currentClassComplexity);
$this->addToArray('class lines', $this->currentClassLines);
}
$this->currentClassComplexity = 0;
$this->currentClassLines = 0;
$this->currentNumberOfMethods = 0;
}
public function currentClassStop(): void
{
$this->addToArray('methods per class', $this->currentNumberOfMethods);
}
public function currentClassIncrementComplexity(): void
{
$this->currentClassComplexity++;
}
public function currentClassIncrementLines(): void
{
$this->currentClassLines++;
}
public function currentMethodStart(): void
{
$this->currentMethodComplexity = 1;
$this->currentMethodLines = 0;
}
public function currentClassIncrementMethods(): void
{
$this->currentNumberOfMethods++;
}
public function currentMethodIncrementComplexity(): void
{
$this->currentMethodComplexity++;
$this->increment('total method complexity');
}
public function currentMethodIncrementLines(): void
{
$this->currentMethodLines++;
}
public function currentMethodStop(): void
{
$this->addToArray('method complexity', $this->currentMethodComplexity);
$this->addToArray('method lines', $this->currentMethodLines);
}
public function incrementFunctionLines(): void
{
$this->increment('function lines');
}
public function incrementComplexity(): void
{
$this->increment('complexity');
}
public function addPossibleConstantAccesses($name): void
{
$this->addToArray('possible constant accesses', $name);
}
public function addConstant($name): void
{
$this->addToArray('constant', $name);
}
public function incrementGlobalVariableAccesses(): void
{
$this->increment('global variable accesses');
}
public function incrementSuperGlobalVariableAccesses(): void
{
$this->increment('super global variable accesses');
}
public function incrementNonStaticAttributeAccesses(): void
{
$this->increment('non-static attribute accesses');
}
public function incrementStaticAttributeAccesses(): void
{
$this->increment('static attribute accesses');
}
public function incrementNonStaticMethodCalls(): void
{
$this->increment('non-static method calls');
}
public function incrementStaticMethodCalls(): void
{
$this->increment('static method calls');
}
public function addNamespace($namespace): void
{
$this->addUnique('namespaces', $namespace);
}
public function incrementInterfaces(): void
{
$this->increment('interfaces');
}
public function incrementTraits(): void
{
$this->increment('traits');
}
public function incrementAbstractClasses(): void
{
$this->increment('abstract classes');
}
public function incrementNonFinalClasses(): void
{
$this->increment('non-final classes');
}
public function incrementFinalClasses(): void
{
$this->increment('final classes');
}
public function incrementNonStaticMethods(): void
{
$this->increment('non-static methods');
}
public function incrementStaticMethods(): void
{
$this->increment('static methods');
}
public function incrementPublicMethods(): void
{
$this->increment('public methods');
}
public function incrementProtectedMethods(): void
{
$this->increment('protected methods');
}
public function incrementPrivateMethods(): void
{
$this->increment('private methods');
}
public function incrementNamedFunctions(): void
{
$this->increment('named functions');
}
public function incrementAnonymousFunctions(): void
{
$this->increment('anonymous functions');
}
public function incrementGlobalConstants(): void
{
$this->increment('global constants');
}
public function incrementPublicClassConstants(): void
{
$this->increment('public class constants');
}
public function incrementNonPublicClassConstants(): void
{
$this->increment('non-public class constants');
}
public function incrementTestClasses(): void
{
$this->increment('test classes');
}
public function incrementTestMethods(): void
{
$this->increment('test methods');
}
private function addUnique($key, $name): void
{
$this->check($key, []);
$this->counts[$key][$name] = true;
}
private function addToArray($key, $value): void
{
$this->check($key, []);
$this->counts[$key][] = $value;
}
private function increment($key, $number = 1): void
{
$this->check($key, 0);
$this->counts[$key] += $number;
}
private function check($key, $default): void
{
if (!isset($this->counts[$key])) {
$this->counts[$key] = $default;
}
}
}
phploc-7.0.2/src/Exception/ 0000775 0000000 0000000 00000000000 13767732007 0015546 5 ustar 00root root 0000000 0000000 phploc-7.0.2/src/Exception/ArgumentsBuilderException.php 0000664 0000000 0000000 00000000620 13767732007 0023410 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\PHPLOC;
use RuntimeException;
final class ArgumentsBuilderException extends RuntimeException implements Exception
{
}
phploc-7.0.2/src/Exception/Exception.php 0000664 0000000 0000000 00000000533 13767732007 0020216 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\PHPLOC;
use Throwable;
interface Exception extends Throwable
{
}
phploc-7.0.2/src/Exception/RuntimeException.php 0000664 0000000 0000000 00000000553 13767732007 0021564 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\PHPLOC;
class RuntimeException extends \RuntimeException implements Exception
{
}
phploc-7.0.2/src/Log/ 0000775 0000000 0000000 00000000000 13767732007 0014331 5 ustar 00root root 0000000 0000000 phploc-7.0.2/src/Log/Csv.php 0000664 0000000 0000000 00000011046 13767732007 0015577 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\PHPLOC\Log;
use const PHP_EOL;
use function array_values;
use function file_put_contents;
use function implode;
use InvalidArgumentException;
final class Csv
{
private $colmap = [
'directories' => 'Directories',
'files' => 'Files',
'loc' => 'Lines of Code (LOC)',
'ccnByLloc' => 'Cyclomatic Complexity / Lines of Code',
'cloc' => 'Comment Lines of Code (CLOC)',
'ncloc' => 'Non-Comment Lines of Code (NCLOC)',
'lloc' => 'Logical Lines of Code (LLOC)',
'llocGlobal' => 'LLOC outside functions or classes',
'namespaces' => 'Namespaces',
'interfaces' => 'Interfaces',
'traits' => 'Traits',
'classes' => 'Classes',
'abstractClasses' => 'Abstract Classes',
'concreteClasses' => 'Concrete Classes',
'finalClasses' => 'Final Classes',
'nonFinalClasses' => 'Non-Final Classes',
'llocClasses' => 'Classes Length (LLOC)',
'methods' => 'Methods',
'nonStaticMethods' => 'Non-Static Methods',
'staticMethods' => 'Static Methods',
'publicMethods' => 'Public Methods',
'nonPublicMethods' => 'Non-Public Methods',
'protectedMethods' => 'Protected Methods',
'privateMethods' => 'Private Methods',
'classCcnAvg' => 'Cyclomatic Complexity / Number of Classes' /* In Text output: 'Average Complexity per Class' */,
'methodCcnAvg' => 'Cyclomatic Complexity / Number of Methods',
'functions' => 'Functions',
'namedFunctions' => 'Named Functions',
'anonymousFunctions' => 'Anonymous Functions',
'llocFunctions' => 'Functions Length (LLOC)',
'llocByNof' => 'Average Function Length (LLOC)',
'classLlocAvg' => 'Average Class Length',
'methodLlocAvg' => 'Average Method Length',
'averageMethodsPerClass' => 'Average Methods per Class',
'constants' => 'Constants',
'globalConstants' => 'Global Constants',
'classConstants' => 'Class Constants',
'publicClassConstants' => 'Public Class Constants',
'nonPublicClassConstants' => 'Non-Public Class Constants',
'attributeAccesses' => 'Attribute Accesses',
'instanceAttributeAccesses' => 'Non-Static Attribute Accesses',
'staticAttributeAccesses' => 'Static Attribute Accesses',
'methodCalls' => 'Method Calls',
'instanceMethodCalls' => 'Non-Static Method Calls',
'staticMethodCalls' => 'Static Method Calls',
'globalAccesses' => 'Global Accesses',
'globalVariableAccesses' => 'Global Variable Accesses',
'superGlobalVariableAccesses' => 'Super-Global Variable Accesses',
'globalConstantAccesses' => 'Global Constant Accesses',
'testClasses' => 'Test Classes',
'testMethods' => 'Test Methods',
];
public function printResult(string $filename, array $count): void
{
file_put_contents(
$filename,
$this->getKeysLine($count) . $this->getValuesLine($count)
);
}
private function getKeysLine(array $count): string
{
return implode(',', array_values($this->colmap)) . PHP_EOL;
}
/**
* @throws InvalidArgumentException
*/
private function getValuesLine(array $count): string
{
$values = [];
foreach ($this->colmap as $key => $name) {
if (isset($count[$key])) {
$values[] = $count[$key];
} else {
throw new InvalidArgumentException('Attempted to print row with missing keys');
}
}
return '"' . implode('","', $values) . '"' . PHP_EOL;
}
}
phploc-7.0.2/src/Log/Json.php 0000664 0000000 0000000 00000001703 13767732007 0015754 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\PHPLOC\Log;
use const JSON_PRETTY_PRINT;
use function array_merge;
use function file_put_contents;
use function json_encode;
final class Json
{
public function printResult(string $filename, array $count): void
{
$directories = [];
if ($count['directories'] > 0) {
$directories = [
'directories' => $count['directories'],
'files' => $count['files'],
];
}
unset($count['directories'], $count['files']);
$report = array_merge($directories, $count);
file_put_contents(
$filename,
json_encode($report, JSON_PRETTY_PRINT)
);
}
}
phploc-7.0.2/src/Log/Text.php 0000664 0000000 0000000 00000021736 13767732007 0015777 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\PHPLOC\Log;
use const PHP_EOL;
final class Text
{
public function printResult(array $count, bool $printTests): void
{
if ($count['directories'] > 0) {
\printf(
'Directories %10d' . PHP_EOL .
'Files %10d' . PHP_EOL . PHP_EOL,
$count['directories'],
$count['files']
);
}
$format = <<<'END'
Size
Lines of Code (LOC) %10d
Comment Lines of Code (CLOC) %10d (%.2f%%)
Non-Comment Lines of Code (NCLOC) %10d (%.2f%%)
Logical Lines of Code (LLOC) %10d (%.2f%%)
Classes %10d (%.2f%%)
Average Class Length %10d
Minimum Class Length %10d
Maximum Class Length %10d
Average Method Length %10d
Minimum Method Length %10d
Maximum Method Length %10d
Average Methods Per Class %10d
Minimum Methods Per Class %10d
Maximum Methods Per Class %10d
Functions %10d (%.2f%%)
Average Function Length %10d
Not in classes or functions %10d (%.2f%%)
Cyclomatic Complexity
Average Complexity per LLOC %10.2f
Average Complexity per Class %10.2f
Minimum Class Complexity %10.2f
Maximum Class Complexity %10.2f
Average Complexity per Method %10.2f
Minimum Method Complexity %10.2f
Maximum Method Complexity %10.2f
Dependencies
Global Accesses %10d
Global Constants %10d (%.2f%%)
Global Variables %10d (%.2f%%)
Super-Global Variables %10d (%.2f%%)
Attribute Accesses %10d
Non-Static %10d (%.2f%%)
Static %10d (%.2f%%)
Method Calls %10d
Non-Static %10d (%.2f%%)
Static %10d (%.2f%%)
Structure
Namespaces %10d
Interfaces %10d
Traits %10d
Classes %10d
Abstract Classes %10d (%.2f%%)
Concrete Classes %10d (%.2f%%)
Final Classes %10d (%.2f%%)
Non-Final Classes %10d (%.2f%%)
Methods %10d
Scope
Non-Static Methods %10d (%.2f%%)
Static Methods %10d (%.2f%%)
Visibility
Public Methods %10d (%.2f%%)
Protected Methods %10d (%.2f%%)
Private Methods %10d (%.2f%%)
Functions %10d
Named Functions %10d (%.2f%%)
Anonymous Functions %10d (%.2f%%)
Constants %10d
Global Constants %10d (%.2f%%)
Class Constants %10d (%.2f%%)
Public Constants %10d (%.2f%%)
Non-Public Constants %10d (%.2f%%)
END;
printf(
$format,
$count['loc'],
$count['cloc'],
$count['loc'] > 0 ? ($count['cloc'] / $count['loc']) * 100 : 0,
$count['ncloc'],
$count['loc'] > 0 ? ($count['ncloc'] / $count['loc']) * 100 : 0,
$count['lloc'],
$count['loc'] > 0 ? ($count['lloc'] / $count['loc']) * 100 : 0,
$count['llocClasses'],
$count['lloc'] > 0 ? ($count['llocClasses'] / $count['lloc']) * 100 : 0,
$count['classLlocAvg'],
$count['classLlocMin'],
$count['classLlocMax'],
$count['methodLlocAvg'],
$count['methodLlocMin'],
$count['methodLlocMax'],
$count['averageMethodsPerClass'],
$count['minimumMethodsPerClass'],
$count['maximumMethodsPerClass'],
$count['llocFunctions'],
$count['lloc'] > 0 ? ($count['llocFunctions'] / $count['lloc']) * 100 : 0,
$count['llocByNof'],
$count['llocGlobal'],
$count['lloc'] > 0 ? ($count['llocGlobal'] / $count['lloc']) * 100 : 0,
$count['ccnByLloc'],
$count['classCcnAvg'],
$count['classCcnMin'],
$count['classCcnMax'],
$count['methodCcnAvg'],
$count['methodCcnMin'],
$count['methodCcnMax'],
$count['globalAccesses'],
$count['globalConstantAccesses'],
$count['globalAccesses'] > 0 ? ($count['globalConstantAccesses'] / $count['globalAccesses']) * 100 : 0,
$count['globalVariableAccesses'],
$count['globalAccesses'] > 0 ? ($count['globalVariableAccesses'] / $count['globalAccesses']) * 100 : 0,
$count['superGlobalVariableAccesses'],
$count['globalAccesses'] > 0 ? ($count['superGlobalVariableAccesses'] / $count['globalAccesses']) * 100 : 0,
$count['attributeAccesses'],
$count['instanceAttributeAccesses'],
$count['attributeAccesses'] > 0 ? ($count['instanceAttributeAccesses'] / $count['attributeAccesses']) * 100 : 0,
$count['staticAttributeAccesses'],
$count['attributeAccesses'] > 0 ? ($count['staticAttributeAccesses'] / $count['attributeAccesses']) * 100 : 0,
$count['methodCalls'],
$count['instanceMethodCalls'],
$count['methodCalls'] > 0 ? ($count['instanceMethodCalls'] / $count['methodCalls']) * 100 : 0,
$count['staticMethodCalls'],
$count['methodCalls'] > 0 ? ($count['staticMethodCalls'] / $count['methodCalls']) * 100 : 0,
$count['namespaces'],
$count['interfaces'],
$count['traits'],
$count['classes'],
$count['abstractClasses'],
$count['classes'] > 0 ? ($count['abstractClasses'] / $count['classes']) * 100 : 0,
$count['concreteClasses'],
$count['classes'] > 0 ? ($count['concreteClasses'] / $count['classes']) * 100 : 0,
$count['finalClasses'],
$count['concreteClasses'] > 0 ? ($count['finalClasses'] / $count['concreteClasses']) * 100 : 0,
$count['nonFinalClasses'],
$count['concreteClasses'] > 0 ? ($count['nonFinalClasses'] / $count['concreteClasses']) * 100 : 0,
$count['methods'],
$count['nonStaticMethods'],
$count['methods'] > 0 ? ($count['nonStaticMethods'] / $count['methods']) * 100 : 0,
$count['staticMethods'],
$count['methods'] > 0 ? ($count['staticMethods'] / $count['methods']) * 100 : 0,
$count['publicMethods'],
$count['methods'] > 0 ? ($count['publicMethods'] / $count['methods']) * 100 : 0,
$count['protectedMethods'],
$count['methods'] > 0 ? ($count['protectedMethods'] / $count['methods']) * 100 : 0,
$count['privateMethods'],
$count['methods'] > 0 ? ($count['privateMethods'] / $count['methods']) * 100 : 0,
$count['functions'],
$count['namedFunctions'],
$count['functions'] > 0 ? ($count['namedFunctions'] / $count['functions']) * 100 : 0,
$count['anonymousFunctions'],
$count['functions'] > 0 ? ($count['anonymousFunctions'] / $count['functions']) * 100 : 0,
$count['constants'],
$count['globalConstants'],
$count['constants'] > 0 ? ($count['globalConstants'] / $count['constants']) * 100 : 0,
$count['classConstants'],
$count['constants'] > 0 ? ($count['classConstants'] / $count['constants']) * 100 : 0,
$count['publicClassConstants'],
$count['classConstants'] > 0 ? ($count['publicClassConstants'] / $count['classConstants']) * 100 : 0,
$count['nonPublicClassConstants'],
$count['classConstants'] > 0 ? ($count['nonPublicClassConstants'] / $count['classConstants']) * 100 : 0
);
if ($printTests) {
\printf(
PHP_EOL . 'Tests' . PHP_EOL .
' Classes %10d' . PHP_EOL .
' Methods %10d' . PHP_EOL,
$count['testClasses'],
$count['testMethods']
);
}
}
}
phploc-7.0.2/src/Log/Xml.php 0000664 0000000 0000000 00000002404 13767732007 0015602 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\PHPLOC\Log;
use function file_put_contents;
use DOMDocument;
final class Xml
{
/** @noinspection UnusedFunctionResultInspection */
public function printResult(string $filename, array $count): void
{
$document = new DOMDocument('1.0', 'UTF-8');
$document->formatOutput = true;
$root = $document->createElement('phploc');
$document->appendChild($root);
if ($count['directories'] > 0) {
$root->appendChild(
$document->createElement('directories', (string) $count['directories'])
);
$root->appendChild(
$document->createElement('files', (string) $count['files'])
);
}
unset($count['directories'], $count['files']);
foreach ($count as $k => $v) {
$root->appendChild(
$document->createElement($k, (string) $v)
);
}
file_put_contents($filename, $document->saveXML());
}
}
phploc-7.0.2/src/Publisher.php 0000664 0000000 0000000 00000032200 13767732007 0016253 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\PHPLOC;
use function array_intersect;
use function array_sum;
use function count;
use function max;
use function min;
class Publisher
{
private $counts;
public function __construct(array $counts)
{
$this->counts = $counts;
}
public function getDirectories()
{
return $this->getCount('directories') - 1;
}
public function getFiles()
{
return $this->getValue('files');
}
public function getLines()
{
return $this->getValue('lines');
}
public function getCommentLines()
{
return $this->getValue('comment lines');
}
public function getNonCommentLines()
{
return $this->getLines() - $this->getCommentLines();
}
public function getLogicalLines()
{
return $this->getValue('logical lines');
}
public function getClassLines()
{
return $this->getSum('class lines');
}
public function getAverageClassLength()
{
return $this->getAverage('class lines');
}
public function getMinimumClassLength()
{
return $this->getMinimum('class lines');
}
public function getMaximumClassLength()
{
return $this->getMaximum('class lines');
}
public function getAverageMethodLength()
{
return $this->getAverage('method lines');
}
public function getMinimumMethodLength()
{
return $this->getMinimum('method lines');
}
public function getMaximumMethodLength()
{
return $this->getMaximum('method lines');
}
public function getAverageMethodsPerClass()
{
return $this->getAverage('methods per class');
}
public function getMinimumMethodsPerClass()
{
return $this->getMinimum('methods per class');
}
public function getMaximumMethodsPerClass()
{
return $this->getMaximum('methods per class');
}
public function getFunctionLines()
{
return $this->getValue('function lines');
}
public function getAverageFunctionLength()
{
return $this->divide($this->getFunctionLines(), $this->getFunctions());
}
public function getNotInClassesOrFunctions()
{
return $this->getLogicalLines() - $this->getClassLines() - $this->getFunctionLines();
}
public function getComplexity()
{
return $this->getValue('complexity');
}
public function getMethodComplexity()
{
return $this->getValue('total method complexity');
}
public function getAverageComplexityPerLogicalLine()
{
return $this->divide($this->getComplexity(), $this->getLogicalLines());
}
public function getAverageComplexityPerClass()
{
return $this->getAverage('class complexity');
}
public function getMinimumClassComplexity()
{
return $this->getMinimum('class complexity');
}
public function getMaximumClassComplexity()
{
return $this->getMaximum('class complexity');
}
public function getAverageComplexityPerMethod()
{
return $this->getAverage('method complexity');
}
public function getMinimumMethodComplexity()
{
return $this->getMinimum('method complexity');
}
public function getMaximumMethodComplexity()
{
return $this->getMaximum('method complexity');
}
public function getGlobalAccesses()
{
return $this->getGlobalConstantAccesses() + $this->getGlobalVariableAccesses() + $this->getSuperGlobalVariableAccesses();
}
public function getGlobalConstantAccesses()
{
return count(array_intersect($this->getValue('possible constant accesses', []), $this->getValue('constant', [])));
}
public function getGlobalVariableAccesses()
{
return $this->getValue('global variable accesses');
}
public function getSuperGlobalVariableAccesses()
{
return $this->getValue('super global variable accesses');
}
public function getAttributeAccesses()
{
return $this->getNonStaticAttributeAccesses() + $this->getStaticAttributeAccesses();
}
public function getNonStaticAttributeAccesses()
{
return $this->getValue('non-static attribute accesses');
}
public function getStaticAttributeAccesses()
{
return $this->getValue('static attribute accesses');
}
public function getMethodCalls()
{
return $this->getNonStaticMethodCalls() + $this->getStaticMethodCalls();
}
public function getNonStaticMethodCalls()
{
return $this->getValue('non-static method calls');
}
public function getStaticMethodCalls()
{
return $this->getValue('static method calls');
}
public function getNamespaces()
{
return $this->getCount('namespaces');
}
public function getInterfaces()
{
return $this->getValue('interfaces');
}
public function getTraits()
{
return $this->getValue('traits');
}
public function getClasses()
{
return $this->getAbstractClasses() + $this->getConcreteClasses();
}
public function getAbstractClasses()
{
return $this->getValue('abstract classes');
}
public function getConcreteClasses()
{
return $this->getFinalClasses() + $this->getNonFinalClasses();
}
public function getFinalClasses()
{
return $this->getValue('final classes');
}
public function getNonFinalClasses()
{
return $this->getValue('non-final classes');
}
public function getMethods()
{
return $this->getNonStaticMethods() + $this->getStaticMethods();
}
public function getNonStaticMethods()
{
return $this->getValue('non-static methods');
}
public function getStaticMethods()
{
return $this->getValue('static methods');
}
public function getPublicMethods()
{
return $this->getValue('public methods');
}
public function getNonPublicMethods()
{
return $this->getProtectedMethods() + $this->getPrivateMethods();
}
public function getProtectedMethods()
{
return $this->getValue('protected methods');
}
public function getPrivateMethods()
{
return $this->getValue('private methods');
}
public function getFunctions()
{
return $this->getNamedFunctions() + $this->getAnonymousFunctions();
}
public function getNamedFunctions()
{
return $this->getValue('named functions');
}
public function getAnonymousFunctions()
{
return $this->getValue('anonymous functions');
}
public function getConstants()
{
return $this->getGlobalConstants() + $this->getClassConstants();
}
public function getGlobalConstants()
{
return $this->getValue('global constants');
}
public function getPublicClassConstants()
{
return $this->getValue('public class constants');
}
public function getNonPublicClassConstants()
{
return $this->getValue('non-public class constants');
}
public function getClassConstants()
{
return $this->getPublicClassConstants() + $this->getNonPublicClassConstants();
}
public function getTestClasses()
{
return $this->getValue('test classes');
}
public function getTestMethods()
{
return $this->getValue('test methods');
}
public function toArray()
{
return [
'files' => $this->getFiles(),
'loc' => $this->getLines(),
'lloc' => $this->getLogicalLines(),
'llocClasses' => $this->getClassLines(),
'llocFunctions' => $this->getFunctionLines(),
'llocGlobal' => $this->getNotInClassesOrFunctions(),
'cloc' => $this->getCommentLines(),
'ccn' => $this->getComplexity(),
'ccnMethods' => $this->getMethodComplexity(),
'interfaces' => $this->getInterfaces(),
'traits' => $this->getTraits(),
'classes' => $this->getClasses(),
'abstractClasses' => $this->getAbstractClasses(),
'concreteClasses' => $this->getConcreteClasses(),
'finalClasses' => $this->getFinalClasses(),
'nonFinalClasses' => $this->getNonFinalClasses(),
'functions' => $this->getFunctions(),
'namedFunctions' => $this->getNamedFunctions(),
'anonymousFunctions' => $this->getAnonymousFunctions(),
'methods' => $this->getMethods(),
'publicMethods' => $this->getPublicMethods(),
'nonPublicMethods' => $this->getNonPublicMethods(),
'protectedMethods' => $this->getProtectedMethods(),
'privateMethods' => $this->getPrivateMethods(),
'nonStaticMethods' => $this->getNonStaticMethods(),
'staticMethods' => $this->getStaticMethods(),
'constants' => $this->getConstants(),
'classConstants' => $this->getClassConstants(),
'publicClassConstants' => $this->getPublicClassConstants(),
'nonPublicClassConstants' => $this->getNonPublicClassConstants(),
'globalConstants' => $this->getGlobalConstants(),
'testClasses' => $this->getTestClasses(),
'testMethods' => $this->getTestMethods(),
'ccnByLloc' => $this->getAverageComplexityPerLogicalLine(),
'llocByNof' => $this->getAverageFunctionLength(),
'methodCalls' => $this->getMethodCalls(),
'staticMethodCalls' => $this->getStaticMethodCalls(),
'instanceMethodCalls' => $this->getNonStaticMethodCalls(),
'attributeAccesses' => $this->getAttributeAccesses(),
'staticAttributeAccesses' => $this->getStaticAttributeAccesses(),
'instanceAttributeAccesses' => $this->getNonStaticAttributeAccesses(),
'globalAccesses' => $this->getGlobalAccesses(),
'globalVariableAccesses' => $this->getGlobalVariableAccesses(),
'superGlobalVariableAccesses' => $this->getSuperGlobalVariableAccesses(),
'globalConstantAccesses' => $this->getGlobalConstantAccesses(),
'directories' => $this->getDirectories(),
'classCcnMin' => $this->getMinimumClassComplexity(),
'classCcnAvg' => $this->getAverageComplexityPerClass(),
'classCcnMax' => $this->getMaximumClassComplexity(),
'classLlocMin' => $this->getMinimumClassLength(),
'classLlocAvg' => $this->getAverageClassLength(),
'classLlocMax' => $this->getMaximumClassLength(),
'methodCcnMin' => $this->getMinimumMethodComplexity(),
'methodCcnAvg' => $this->getAverageComplexityPerMethod(),
'methodCcnMax' => $this->getMaximumMethodComplexity(),
'methodLlocMin' => $this->getMinimumMethodLength(),
'methodLlocAvg' => $this->getAverageMethodLength(),
'methodLlocMax' => $this->getMaximumMethodLength(),
'averageMethodsPerClass' => $this->getAverageMethodsPerClass(),
'minimumMethodsPerClass' => $this->getMinimumMethodsPerClass(),
'maximumMethodsPerClass' => $this->getMaximumMethodsPerClass(),
'namespaces' => $this->getNamespaces(),
'ncloc' => $this->getNonCommentLines(),
];
}
private function getAverage($key)
{
return $this->divide($this->getSum($key), $this->getCount($key));
}
private function getCount($key)
{
return isset($this->counts[$key]) ? count($this->counts[$key]) : 0;
}
private function getSum($key)
{
return isset($this->counts[$key]) ? array_sum($this->counts[$key]) : 0;
}
private function getMaximum($key)
{
return isset($this->counts[$key]) ? max($this->counts[$key]) : 0;
}
private function getMinimum($key)
{
return isset($this->counts[$key]) ? min($this->counts[$key]) : 0;
}
private function getValue($key, $default = 0)
{
return $this->counts[$key] ?? $default;
}
private function divide($x, $y)
{
return $y != 0 ? $x / $y : 0;
}
}
phploc-7.0.2/tests/ 0000775 0000000 0000000 00000000000 13767732007 0014163 5 ustar 00root root 0000000 0000000 phploc-7.0.2/tests/_files/ 0000775 0000000 0000000 00000000000 13767732007 0015424 5 ustar 00root root 0000000 0000000 phploc-7.0.2/tests/_files/class_constants.php 0000664 0000000 0000000 00000000545 13767732007 0021342 0 ustar 00root root 0000000 0000000 m();
$o->$m();
$o->a;
$o->$a;
}
public function aPublicMethod()
{
$a = true ? true : false;
c::m();
c::$m();
c::$a;
c::$a;
c::aConstant;
}
protected function aProtectedMethod()
{
if (true) {
}
$c::m();
$c::$m();
$c::$a;
$c::$a;
}
private function aPrivateMethod()
{
$function = function() {};
echo "This is {$great}";
echo "This is ${great}";
}
}
phploc-7.0.2/tests/_files/tests.php 0000664 0000000 0000000 00000000451 13767732007 0017277 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\PHPLOC;
use const E_ALL;
use function error_reporting;
use function sprintf;
use PHPUnit\Framework\TestCase;
/**
* @covers \SebastianBergmann\PHPLOC\Analyser
*/
final class AnalyserTest extends TestCase
{
/**
* @var Analyser
*/
private $analyser;
protected function setUp(): void
{
$this->analyser = new Analyser;
}
public function testWithoutTests(): void
{
$this->assertEqualsWithDelta(
[
'files' => 1,
'loc' => 75,
'lloc' => 24,
'llocClasses' => 22,
'llocFunctions' => 1,
'llocGlobal' => 1,
'cloc' => 7,
'ccn' => 2,
'ccnMethods' => 2,
'interfaces' => 1,
'traits' => 0,
'classes' => 2,
'abstractClasses' => 1,
'concreteClasses' => 1,
'nonFinalClasses' => 1,
'finalClasses' => 0,
'functions' => 2,
'namedFunctions' => 1,
'anonymousFunctions' => 1,
'methods' => 4,
'publicMethods' => 2,
'nonPublicMethods' => 2,
'protectedMethods' => 1,
'privateMethods' => 1,
'nonStaticMethods' => 3,
'staticMethods' => 1,
'constants' => 2,
'classConstants' => 1,
'publicClassConstants' => 1,
'nonPublicClassConstants' => 0,
'globalConstants' => 1,
'testClasses' => 0,
'testMethods' => 0,
'ccnByLloc' => 0.08,
'llocByNof' => 0.5,
'methodCalls' => 6,
'staticMethodCalls' => 4,
'instanceMethodCalls' => 2,
'attributeAccesses' => 6,
'staticAttributeAccesses' => 4,
'instanceAttributeAccesses' => 2,
'globalAccesses' => 4,
'globalVariableAccesses' => 2,
'superGlobalVariableAccesses' => 1,
'globalConstantAccesses' => 1,
'directories' => 0,
'namespaces' => 1,
'ncloc' => 68,
'classCcnMin' => 1,
'classCcnAvg' => 1.65,
'classCcnMax' => 3,
'methodCcnMin' => 1,
'methodCcnAvg' => 1.65,
'methodCcnMax' => 2,
'classLlocMin' => 0,
'classLlocAvg' => 7.3,
'classLlocMax' => 22,
'methodLlocMin' => 4,
'methodLlocAvg' => 5.6,
'methodLlocMax' => 7,
'averageMethodsPerClass' => 1.33,
'minimumMethodsPerClass' => 0,
'maximumMethodsPerClass' => 4,
],
$this->analyser->countFiles(
[__DIR__ . '/../_files/source.php'],
false
),
0.1
);
}
public function testWithTests(): void
{
$this->assertEqualsWithDelta(
[
'files' => 2,
'loc' => 98,
'lloc' => 24,
'llocClasses' => 22,
'llocFunctions' => 1,
'llocGlobal' => 1,
'cloc' => 11,
'ccn' => 2,
'ccnMethods' => 2,
'interfaces' => 1,
'traits' => 0,
'classes' => 2,
'abstractClasses' => 1,
'concreteClasses' => 1,
'nonFinalClasses' => 1,
'finalClasses' => 0,
'functions' => 2,
'namedFunctions' => 1,
'anonymousFunctions' => 1,
'methods' => 4,
'publicMethods' => 2,
'nonPublicMethods' => 2,
'protectedMethods' => 1,
'privateMethods' => 1,
'nonStaticMethods' => 3,
'staticMethods' => 1,
'constants' => 2,
'publicClassConstants' => 1,
'nonPublicClassConstants' => 0,
'classConstants' => 1,
'globalConstants' => 1,
'testClasses' => 1,
'testMethods' => 2,
'ccnByLloc' => 0.08,
'llocByNof' => 0.5,
'methodCalls' => 6,
'staticMethodCalls' => 4,
'instanceMethodCalls' => 2,
'attributeAccesses' => 6,
'staticAttributeAccesses' => 4,
'instanceAttributeAccesses' => 2,
'globalAccesses' => 4,
'globalVariableAccesses' => 2,
'superGlobalVariableAccesses' => 1,
'globalConstantAccesses' => 1,
'directories' => 0,
'namespaces' => 1,
'ncloc' => 87,
'classCcnMin' => 1,
'classCcnAvg' => 1.5,
'classCcnMax' => 3,
'methodCcnMin' => 1,
'methodCcnAvg' => 1.66,
'methodCcnMax' => 2,
'classLlocMin' => 0,
'classLlocAvg' => 5.5,
'classLlocMax' => 22,
'methodLlocMin' => 4,
'methodLlocAvg' => 5.6,
'methodLlocMax' => 7,
'averageMethodsPerClass' => 1,
'minimumMethodsPerClass' => 0,
'maximumMethodsPerClass' => 4,
],
$this->analyser->countFiles(
[
__DIR__ . '/../_files/source.php',
__DIR__ . '/../_files/tests.php',
],
true
),
0.1
);
}
public function testFilesThatExtendPHPUnitTestCaseAreCountedAsTests(): void
{
$result = $this->analyser->countFiles(
[
__DIR__ . '/../_files/tests.php',
],
true
);
$this->assertSame(1, $result['testClasses']);
}
public function testFilesThatExtendPHPUnitTestCaseAreCountedAsTests2(): void
{
$result = $this->analyser->countFiles(
[
__DIR__ . '/../_files/tests_old.php',
],
true
);
$this->assertSame(1, $result['testClasses']);
}
public function testFilesThatIndirectlyExtendPHPUnitTestCaseAreCountedAsTests(): void
{
$result = $this->analyser->countFiles(
[
__DIR__ . '/../_files/twoTestsThatIndirectlyExtendOldPHPUnitTestCase.php',
],
true
);
$this->assertSame(3, $result['testClasses']);
}
public function testFilesThatIndirectlyExtendPHPUnitTestCaseAreCountedAsTests2(): void
{
$result = $this->analyser->countFiles(
[
__DIR__ . '/../_files/twoTestsThatIndirectlyExtendPHPUnitTestCase.php',
],
true
);
$this->assertSame(3, $result['testClasses']);
}
public function testTraitsAreCountedCorrectly(): void
{
$result = $this->analyser->countFiles(
[
__DIR__ . '/../_files/trait.php',
],
false
);
$this->assertSame(1, $result['traits']);
}
/**
* @ticket 64
*/
public function testIssue64IsFixed(): void
{
$result = $this->analyser->countFiles(
[
__DIR__ . '/../_files/issue_62.php',
],
false
);
$this->assertSame(1, $result['cloc']);
}
/**
* @ticket 112
*/
public function testIssue112IsFixed(): void
{
$result = $this->analyser->countFiles(
[
__DIR__ . '/../_files/issue_112.php',
],
false
);
$this->assertSame(5, $result['loc']);
}
/**
* @ticket 126
* @dataProvider issue126Provider
*/
public function testIssue126IsFixed($fileNumber, $cloc): void
{
$file = __DIR__ . '/../_files/issue_126/issue_126_' . $fileNumber . '.php';
$result = $this->analyser->countFiles([$file], false);
$assertString = sprintf(
'Failed asserting that %s matches expected %s in issue_126_%d.php',
$result['cloc'],
$cloc,
$fileNumber
);
$this->assertSame($cloc, $result['cloc'], $assertString);
}
public function issue126Provider()
{
// issue_126_X.php => CLOC
return [
[1, 1],
[2, 1],
[3, 1],
[4, 2],
[5, 3],
[6, 3],
[7, 3],
];
}
/**
* @requires PHP 7
* @ticket 138
*/
public function testIssue138IsFixed(): void
{
error_reporting(E_ALL);
$result = $this->analyser->countFiles(
[
__DIR__ . '/../_files/issue_138.php',
],
false
);
$this->assertSame(1, $result['classes']);
}
/**
* @ticket 139
*/
public function testIssue139IsFixed(): void
{
error_reporting(E_ALL);
$result = $this->analyser->countFiles(
[
__DIR__ . '/../_files/issue_139.php',
],
false
);
$this->assertSame(1, $result['anonymousFunctions']);
}
public function testDeclareIsNotLogicalLine(): void
{
$result = $this->analyser->countFiles([__DIR__ . '/../_files/with_declare.php'], false);
$this->assertSame(0, $result['llocGlobal']);
}
public function testNamespaceIsNotLogicalLine(): void
{
$result = $this->analyser->countFiles([__DIR__ . '/../_files/with_namespace.php'], false);
$this->assertSame(0, $result['llocGlobal']);
}
public function testImportIsNotLogicalLine(): void
{
$result = $this->analyser->countFiles([__DIR__ . '/../_files/with_import.php'], false);
$this->assertSame(0, $result['llocGlobal']);
}
public function test_it_makes_a_distinction_between_public_and_non_public_class_constants(): void
{
$result = $this->analyser->countFiles([__DIR__ . '/../_files/class_constants.php'], false);
$this->assertSame(2, $result['publicClassConstants']);
$this->assertSame(3, $result['nonPublicClassConstants']);
$this->assertSame(5, $result['classConstants']);
$this->assertSame(5, $result['constants']);
}
public function test_it_collects_the_number_of_final_non_final_and_abstract_classes(): void
{
$result = $this->analyser->countFiles([__DIR__ . '/../_files/classes.php'], false);
$this->assertSame(9, $result['classes']);
$this->assertSame(2, $result['finalClasses']);
$this->assertSame(3, $result['nonFinalClasses']);
$this->assertSame(4, $result['abstractClasses']);
}
public function test_it_makes_a_distinction_between_protected_and_private_methods(): void
{
$result = $this->analyser->countFiles([__DIR__ . '/../_files/methods.php'], false);
$this->assertSame(2, $result['publicMethods']);
$this->assertSame(1, $result['protectedMethods']);
$this->assertSame(3, $result['privateMethods']);
$this->assertSame(6, $result['methods']);
}
public function test_it_provides_average_minimum_and_maximum_number_of_methods_per_class(): void
{
$result = $this->analyser->countFiles([__DIR__ . '/../_files/methods_per_class.php'], false);
$this->assertSame(2, $result['averageMethodsPerClass']);
$this->assertSame(0, $result['minimumMethodsPerClass']);
$this->assertSame(4, $result['maximumMethodsPerClass']);
}
public function test_use_trait_is_not_counted_as_logical_line(): void
{
$result = $this->analyser->countFiles([__DIR__ . '/../_files/class_using_trait.php'], false);
$this->assertSame(1, $result['lloc']);
$this->assertSame(1, $result['llocClasses']);
}
}
phploc-7.0.2/tests/unit/Log/ 0000775 0000000 0000000 00000000000 13767732007 0015663 5 ustar 00root root 0000000 0000000 phploc-7.0.2/tests/unit/Log/CsvTest.php 0000664 0000000 0000000 00000011713 13767732007 0017772 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\PHPLOC;
use function count;
use function explode;
use function ob_end_clean;
use function ob_get_clean;
use function ob_start;
use function trim;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
/**
* @covers \SebastianBergmann\PHPLOC\Log\Csv
*/
final class CsvTest extends TestCase
{
/**
* @var \SebastianBergmann\PHPLOC\Log\Csv
*/
private $single;
private $sample_row = [
'directories' => 1,
'files' => 2,
'loc' => 3,
'ccnByLloc' => 4,
'cloc' => 5,
'ncloc' => 6,
'lloc' => 7,
'llocGlobal' => 8,
'namespaces' => 9,
'interfaces' => 10,
'traits' => 11,
'classes' => 12,
'abstractClasses' => 13,
'concreteClasses' => 14,
'finalClasses' => 8,
'nonFinalClasses' => 6,
'llocClasses' => 15,
'methods' => 16,
'nonStaticMethods' => 17,
'staticMethods' => 18,
'publicMethods' => 19,
'nonPublicMethods' => 20,
'protectedMethods' => 14,
'privateMethods' => 6,
'methodCcnAvg' => 21,
'functions' => 22,
'namedFunctions' => 23,
'anonymousFunctions' => 24,
'llocFunctions' => 25,
'llocByNof' => 26,
'constants' => 27,
'globalConstants' => 28,
'classConstants' => 29,
'publicClassConstants' => 15,
'nonPublicClassConstants' => 14,
'attributeAccesses' => 30,
'instanceAttributeAccesses' => 31,
'staticAttributeAccesses' => 32,
'methodCalls' => 33,
'instanceMethodCalls' => 34,
'staticMethodCalls' => 35,
'globalAccesses' => 36,
'globalVariableAccesses' => 37,
'superGlobalVariableAccesses' => 38,
'globalConstantAccesses' => 39,
'testClasses' => 40,
'testMethods' => 41,
'classCcnAvg' => 42,
'classLlocAvg' => 43,
'methodLlocAvg' => 44,
'averageMethodsPerClass' => 5,
];
protected function setUp(): void
{
$this->single = new \SebastianBergmann\PHPLOC\Log\Csv;
}
public function testPrintedResultContainsHeadings(): void
{
ob_start();
$this->single->printResult('php://output', $this->sample_row);
$output = ob_get_clean();
$this->assertMatchesRegularExpression('#Directories,Files.+$#is', $output, 'Printed result does not contain a heading line');
}
public function testPrintedResultContainsData(): void
{
ob_start();
$this->single->printResult('php://output', $this->sample_row);
$output = ob_get_clean();
$this->assertMatchesRegularExpression('#"1","2".+$#is', $output, 'Printed result does not contain a value line');
}
public function testPrintedResultContainsEqualNumHeadingsAndValues(): void
{
ob_start();
$this->single->printResult('php://output', $this->sample_row);
$output = ob_get_clean();
$rows = explode("\n", $output);
$headings = explode(',', $rows[0]);
$vals = explode(',', $rows[1]);
$this->assertEquals(
count($headings),
count($vals),
'Printed result does not contain same number of headings and values'
);
}
public function testExactlyTwoRowsArePrinted(): void
{
ob_start();
$this->single->printResult('php://output', $this->sample_row);
$output = ob_get_clean();
$rows = explode("\n", trim($output));
$this->assertEquals(2, count($rows), 'Printed result contained more or less than expected 2 rows');
}
public function testPrintPartialRow(): void
{
$this->expectException(InvalidArgumentException::class);
$count = $this->sample_row;
unset($count['llocByNof']);
try {
ob_start();
$this->single->printResult('php://output', $count);
} finally {
ob_end_clean();
}
$this->fail('No exception was raised for malformed input var');
}
}