PK ^GMbJ .travis.ymlnu W+A language: php
install:
- travis_retry composer install --no-interaction --prefer-source
php:
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
script: phpunit --configuration ./build/travis-ci.xml
matrix:
allow_failures:
- php: hhvm
notifications:
email: false
PK ^GM6 build/phar-autoload.php.innu W+A #!/usr/bin/env php
run();
__HALT_COMPILER();
PK ^GMa_ build/phpunit.xmlnu W+A
../tests
../src
PK ^GMj build/travis-ci.xmlnu W+A
../tests
../src
../src/autoload.php
PK ^GM? build/phar-manifest.phpnu W+A #!/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";
}
PK ^GM(x x README.mdnu W+A [![Latest Stable Version](https://poser.pugx.org/phploc/phploc/v/stable.png)](https://packagist.org/packages/phploc/phploc)
[![Build Status](https://travis-ci.org/sebastianbergmann/phploc.png?branch=master)](https://travis-ci.org/sebastianbergmann/phploc)
# PHPLOC
`phploc` is a tool for quickly measuring the size and analyzing the structure of a PHP project.
## Installation
### PHP Archive (PHAR)
The easiest way to obtain PHPLOC is to download a [PHP Archive (PHAR)](http://php.net/phar) that has all required dependencies of PHPLOC bundled in a single file:
wget https://phar.phpunit.de/phploc.phar
chmod +x phploc.phar
mv phploc.phar /usr/local/bin/phploc
You can also immediately use the PHAR after you have downloaded it, of course:
wget https://phar.phpunit.de/phploc.phar
php phploc.phar
### Composer
Simply add a dependency on `phploc/phploc` to your project's `composer.json` file if you use [Composer](http://getcomposer.org/) to manage the dependencies of your project. Here is a minimal example of a `composer.json` file that just defines a development-time dependency on PHPLOC:
{
"require-dev": {
"phploc/phploc": "*"
}
}
For a system-wide installation via Composer, you can run:
composer global require 'phploc/phploc=*'
Make sure you have `~/.composer/vendor/bin/` in your path.
## Usage Examples
### Analyse a directory and print the result
➜ ~ phploc src
phploc 2.0.4 by Sebastian Bergmann.
Directories 3
Files 8
Size
Lines of Code (LOC) 1858
Comment Lines of Code (CLOC) 560 (30.14%)
Non-Comment Lines of Code (NCLOC) 1298 (69.86%)
Logical Lines of Code (LLOC) 289 (15.55%)
Classes 260 (89.97%)
Average Class Length 37
Average Method Length 9
Functions 5 (1.73%)
Average Function Length 5
Not in classes or functions 24 (8.30%)
Complexity
Cyclomatic Complexity / LLOC 0.67
Cyclomatic Complexity / Number of Methods 7.86
Dependencies
Global Accesses 2
Global Constants 2 (100.00%)
Global Variables 0 (0.00%)
Super-Global Variables 0 (0.00%)
Attribute Accesses 48
Non-Static 48 (100.00%)
Static 0 (0.00%)
Method Calls 96
Non-Static 91 (94.79%)
Static 5 (5.21%)
Structure
Namespaces 4
Interfaces 0
Traits 0
Classes 7
Abstract Classes 0 (0.00%)
Concrete Classes 7 (100.00%)
Methods 28
Scope
Non-Static Methods 28 (100.00%)
Static Methods 0 (0.00%)
Visibility
Public Method 10 (35.71%)
Non-Public Methods 18 (64.29%)
Functions 1
Named Functions 0 (0.00%)
Anonymous Functions 1 (100.00%)
Constants 1
Global Constants 1 (100.00%)
Class Constants 0 (0.00%)
### Analyse a directory for each revision in a Git repository and write the result in CSV format
➜ ~ phploc --log-csv log.csv --progress --git-repository . src
phploc 2.0.4 by Sebastian Bergmann.
295/295 [============================] 100%
PK ^GM,
.gitignorenu W+A build/phar
build/SebastianBergmann
build/phploc.bat
build/phploc.php
build/*.phar*
build/*.tgz
.idea
cache.properties
composer.phar
composer.lock
vendor
PK ^GMNhc hc src/Analyser.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\PHPLOC;
/**
* PHPLOC code analyser.
*
* @author Sebastian Bergmann
* @copyright Sebastian Bergmann
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phploc/tree
* @since Class available since Release 1.0.0
*/
class Analyser
{
/**
* @var array
*/
private $namespaces = [];
/**
* @var array
*/
private $classes = [];
/**
* @var array
*/
private $constants = [];
/**
* @var array
*/
private $possibleConstantAccesses = [];
/**
* @var array
*/
private $count = [
'files' => 0,
'loc' => 0,
'lloc' => 0,
'llocClasses' => 0,
'llocFunctions' => 0,
'llocGlobal' => 0,
'cloc' => 0,
'ccn' => 0,
'ccnMethods' => 0,
'interfaces' => 0,
'traits' => 0,
'classes' => 0,
'abstractClasses' => 0,
'concreteClasses' => 0,
'functions' => 0,
'namedFunctions' => 0,
'anonymousFunctions' => 0,
'methods' => 0,
'publicMethods' => 0,
'nonPublicMethods' => 0,
'nonStaticMethods' => 0,
'staticMethods' => 0,
'constants' => 0,
'classConstants' => 0,
'globalConstants' => 0,
'testClasses' => 0,
'testMethods' => 0,
'ccnByLloc' => 0,
'llocByNof' => 0,
'methodCalls' => 0,
'staticMethodCalls' => 0,
'instanceMethodCalls' => 0,
'attributeAccesses' => 0,
'staticAttributeAccesses' => 0,
'instanceAttributeAccesses' => 0,
'globalAccesses' => 0,
'globalVariableAccesses' => 0,
'superGlobalVariableAccesses' => 0,
'globalConstantAccesses' => 0
];
/**
* @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
];
/**
* @var array
*/
private $classCcn = [];
/**
* @var array
*/
private $classLloc = [];
/**
* @var array
*/
private $methodCcn = [];
/**
* @var array
*/
private $methodLloc = [];
/**
* Processes a set of files.
*
* @param array $files
* @param boolean $countTests
* @return array
* @since Method available since Release 1.2.0
*/
public function countFiles(array $files, $countTests)
{
if ($countTests) {
foreach ($files as $file) {
$this->preProcessFile($file);
}
}
$directories = [];
foreach ($files as $file) {
$directory = dirname($file);
if (!isset($directories[$directory])) {
$directories[$directory] = true;
}
$this->countFile($file, $countTests);
}
$count = $this->count;
$count['directories'] = count($directories) - 1;
$count['namespaces'] = count($this->namespaces);
$count['classes'] = $count['abstractClasses'] +
$count['concreteClasses'];
$count['functions'] = $count['namedFunctions'] +
$count['anonymousFunctions'];
$count['constants'] = $count['classConstants'] +
$count['globalConstants'];
$count['attributeAccesses'] = $count['staticAttributeAccesses'] +
$count['instanceAttributeAccesses'];
$count['methodCalls'] = $count['staticMethodCalls'] +
$count['instanceMethodCalls'];
$count['llocGlobal'] = $count['lloc'] -
$count['llocClasses'] -
$count['llocFunctions'];
$count['ncloc'] = $count['loc'] - $count['cloc'];
foreach ($this->possibleConstantAccesses as $possibleConstantAccess) {
if (in_array($possibleConstantAccess, $this->constants)) {
$count['globalConstantAccesses']++;
}
}
$count['globalAccesses'] = $count['globalConstantAccesses'] +
$count['globalVariableAccesses'] +
$count['superGlobalVariableAccesses'];
if ($count['lloc'] > 0) {
$count['ccnByLloc'] = $count['ccn'] / $count['lloc'];
}
if (count($this->classCcn) > 0) {
$count['classCcnMin'] = min($this->classCcn);
$count['classCcnAvg'] = array_sum($this->classCcn) / count($this->classCcn);
$count['classCcnMax'] = max($this->classCcn);
}
if (count($this->methodCcn) > 0) {
$count['methodCcnMin'] = min($this->methodCcn);
$count['methodCcnAvg'] = array_sum($this->methodCcn) / count($this->methodCcn);
$count['methodCcnMax'] = max($this->methodCcn);
}
if (count($this->classLloc) > 0) {
$count['classLlocMin'] = min($this->classLloc);
$count['classLlocAvg'] = array_sum($this->classLloc) / count($this->classLloc);
$count['classLlocMax'] = max($this->classLloc);
}
if (count($this->methodLloc) > 0) {
$count['methodLlocMin'] = min($this->methodLloc);
$count['methodLlocAvg'] = array_sum($this->methodLloc) / count($this->methodLloc);
$count['methodLlocMax'] = max($this->methodLloc);
}
if ($count['functions'] > 0) {
$count['llocByNof'] = $count['llocFunctions'] / $count['functions'];
}
return $count;
}
/**
* Pre-processes a single file.
*
* @param string $filename
* @since Method available since Release 1.2.0
*/
public function preProcessFile($filename)
{
$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)) {
continue;
}
$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 boolean $countTests
*/
public function countFile($filename, $countTests)
{
$buffer = file_get_contents($filename);
$this->count['loc'] += substr_count($buffer, "\n");
$tokens = token_get_all($buffer);
$numTokens = count($tokens);
unset($buffer);
$this->count['files']++;
$blocks = [];
$currentBlock = false;
$namespace = false;
$className = null;
$functionName = null;
$testClass = false;
$currentClassData = null;
$currentMethodData = null;
for ($i = 0; $i < $numTokens; $i++) {
if (is_string($tokens[$i])) {
$token = trim($tokens[$i]);
if ($token == ';') {
if ($className !== null && !$testClass) {
$this->count['llocClasses']++;
$currentClassData['lloc']++;
if ($functionName !== null) {
$currentMethodData['lloc']++;
}
} elseif ($functionName !== null) {
$this->count['llocFunctions']++;
}
$this->count['lloc']++;
} elseif ($token == '?' && !$testClass) {
if ($className !== null) {
$this->count['ccnMethods']++;
$currentClassData['ccn']++;
$currentMethodData['ccn']++;
}
$this->count['ccn']++;
} elseif ($token == '{') {
if ($currentBlock == T_CLASS) {
$block = $className;
} elseif ($currentBlock == T_FUNCTION) {
$block = $functionName;
} else {
$block = false;
}
array_push($blocks, $block);
$currentBlock = false;
} elseif ($token == '}') {
$block = array_pop($blocks);
if ($block !== false && $block !== null) {
if ($block == $functionName) {
$functionName = null;
if ($currentMethodData !== null) {
$this->methodCcn[] = $currentMethodData['ccn'];
$this->methodLloc[] = $currentMethodData['lloc'];
$currentMethodData = null;
}
} elseif ($block == $className) {
$className = null;
$testClass = false;
$this->classCcn[] = $currentClassData['ccn'];
$this->classLloc[] = $currentClassData['lloc'];
$currentClassData = null;
}
}
}
continue;
}
list ($token, $value) = $tokens[$i];
switch ($token) {
case T_NAMESPACE:
$namespace = $this->getNamespaceName($tokens, $i);
if (!isset($this->namespaces[$namespace])) {
$this->namespaces[$namespace] = true;
}
break;
case T_CLASS:
case T_INTERFACE:
case T_TRAIT:
if (!$this->isClassDeclaration($tokens, $i)) {
continue;
}
$currentClassData = ['ccn' => 1, 'lloc' => 0];
$className = $this->getClassName($namespace, $tokens, $i);
$currentBlock = T_CLASS;
if ($token == T_TRAIT) {
$this->count['traits']++;
} elseif ($token == T_INTERFACE) {
$this->count['interfaces']++;
} else {
if ($countTests && $this->isTestClass($className)) {
$testClass = true;
$this->count['testClasses']++;
} else {
if (isset($tokens[$i-2]) &&
is_array($tokens[$i-2]) &&
$tokens[$i-2][0] == T_ABSTRACT) {
$this->count['abstractClasses']++;
} else {
$this->count['concreteClasses']++;
}
}
}
break;
case T_FUNCTION:
$currentBlock = T_FUNCTION;
if (is_array($tokens[$i+2]) &&
$tokens[$i+2][0] == T_STRING) {
$functionName = $tokens[$i+2][1];
} elseif ($tokens[$i+2] == '&' &&
is_array($tokens[$i+3]) &&
$tokens[$i+3][0] == T_STRING) {
$functionName = $tokens[$i+3][1];
} else {
$currentBlock = 'anonymous function';
$functionName = 'anonymous function';
$this->count['anonymousFunctions']++;
}
if ($currentBlock == T_FUNCTION) {
if ($className === null &&
$functionName != 'anonymous function') {
$this->count['namedFunctions']++;
} 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->count['testMethods']++;
} elseif (!$testClass) {
$currentMethodData = ['ccn' => 1, 'lloc' => 0];
if (!$static) {
$this->count['nonStaticMethods']++;
} else {
$this->count['staticMethods']++;
}
if ($visibility == T_PUBLIC) {
$this->count['publicMethods']++;
} else {
$this->count['nonPublicMethods']++;
}
$this->count['methods']++;
}
}
}
break;
case T_CURLY_OPEN:
$currentBlock = T_CURLY_OPEN;
array_push($blocks, $currentBlock);
break;
case T_DOLLAR_OPEN_CURLY_BRACES:
$currentBlock = T_DOLLAR_OPEN_CURLY_BRACES;
array_push($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 ($currentMethodData !== null) {
$this->count['ccnMethods']++;
$currentClassData['ccn']++;
$currentMethodData['ccn']++;
}
$this->count['ccn']++;
}
break;
case T_COMMENT:
case T_DOC_COMMENT:
$lf = substr_count($value, "\n");
$this->count['cloc'] += $lf;
if ($lf > 1) {
$this->count['cloc']++;
}
break;
case T_CONST:
$this->count['classConstants']++;
break;
case T_STRING:
if ($value == 'define') {
$this->count['globalConstants']++;
$j = $i + 1;
while (isset($tokens[$j]) && $tokens[$j] != ';') {
if (is_array($tokens[$j]) &&
$tokens[$j][0] == T_CONSTANT_ENCAPSED_STRING) {
$this->constants[] = str_replace('\'', '', $tokens[$j][1]);
break;
}
$j++;
}
} else {
$this->possibleConstantAccesses[] = $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->count['staticMethodCalls']++;
} else {
$this->count['instanceMethodCalls']++;
}
} else {
if ($token == T_DOUBLE_COLON &&
$tokens[$n][0] == T_VARIABLE) {
$this->count['staticAttributeAccesses']++;
} elseif ($token == T_OBJECT_OPERATOR) {
$this->count['instanceAttributeAccesses']++;
}
}
break;
case T_GLOBAL:
$this->count['globalVariableAccesses']++;
break;
case T_VARIABLE:
if ($value == '$GLOBALS') {
$this->count['globalVariableAccesses']++;
} elseif (isset($this->superGlobals[$value])) {
$this->count['superGlobalVariableAccesses']++;
}
break;
}
}
}
/**
* @param array $tokens
* @param integer $i
* @return string
* @since Method available since Release 1.3.0
*/
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 array $tokens
* @param integer $i
* @return string
* @since Method available since Release 1.3.0
*/
private function getClassName($namespace, array $tokens, $i)
{
$i += 2;
$namespaced = false;
if (!isset($tokens[$i][1])) {
return 'invalid class name';
}
$className = $tokens[$i][1];
if ($className === '\\') {
$namespaced = true;
}
while (is_array($tokens[$i+1]) && $tokens[$i+1][0] !== T_WHITESPACE) {
$className .= $tokens[++$i][1];
}
if (!$namespaced && $namespace !== false) {
$className = $namespace . '\\' . $className;
}
return $className;
}
/**
* @param string $className
* @return boolean
* @since Method available since Release 1.2.0
*/
private function isTestClass($className)
{
$parent = $this->classes[$className];
$result = false;
$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') {
$result = true;
break;
}
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".
if (!$result) {
if (substr($this->classes[$className], -8) == 'TestCase') {
$result = true;
}
}
return $result;
}
/**
* @param string $functionName
* @param integer $visibility
* @param boolean $static
* @param array $tokens
* @param integer $currentToken
* @return boolean
* @since Method available since Release 2.0.0
*/
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 array $tokens
* @param integer $start
* @return boolean
*/
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;
} else {
return $start + 1;
}
}
return false;
}
/**
* @param array $tokens
* @param integer $start
* @return boolean
*/
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;
} else {
return $start - 1;
}
}
return false;
}
/**
* @param array $tokens
* @param integer $i
* @return boolean
*/
private function isClassDeclaration(array $tokens, $i)
{
$n = $this->getPreviousNonWhitespaceTokenPos($tokens, $i);
if (isset($tokens[$n]) && is_array($tokens[$n]) &&
$tokens[$n][0] == T_DOUBLE_COLON) {
return false;
}
return true;
}
}
PK ^GMtL. . src/Log/XML.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\PHPLOC\Log;
/**
* An XML ResultPrinter for the TextUI.
*
* @author Sebastian Bergmann
* @copyright Sebastian Bergmann
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phploc/tree
* @since Class available since Release 1.1.0
*/
class XML
{
/**
* Prints a result set.
*
* @param string $filename
* @param array $count
*/
public function printResult($filename, array $count)
{
$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', $count['directories'])
);
$root->appendChild(
$document->createElement('files', $count['files'])
);
}
unset($count['directories']);
unset($count['files']);
foreach ($count as $k => $v) {
$root->appendChild(
$document->createElement($k, $v)
);
}
file_put_contents($filename, $document->saveXML());
}
}
PK ^GM(z;m" m" src/Log/Text.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\PHPLOC\Log;
use Symfony\Component\Console\Output\OutputInterface;
/**
* A ResultPrinter for the TextUI.
*
* @author Sebastian Bergmann
* @copyright Sebastian Bergmann
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phploc/tree
* @since Class available since Release 1.0.0
*/
class Text
{
/**
* Prints a result set.
*
* @param OutputInterface $output
* @param array $count
* @param boolean $printTests
*/
public function printResult(OutputInterface $output, array $count, $printTests)
{
if ($count['directories'] > 0) {
$output->write(
sprintf(
"Directories %10d\n" .
"Files %10d\n\n",
$count['directories'],
$count['files']
)
);
}
$format = <<write(
sprintf(
$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['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['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['nonPublicMethods'],
$count['methods'] > 0 ? ($count['nonPublicMethods'] / $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
)
);
if ($printTests) {
$output->write(
sprintf(
"\nTests\n" .
" Classes %10d\n" .
" Methods %10d\n",
$count['testClasses'],
$count['testMethods']
)
);
}
}
}
PK ^GM! src/Log/CSV/Single.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\PHPLOC\Log\CSV;
/**
* A CSV ResultPrinter for the TextUI.
*
* @author Sebastian Bergmann
* @copyright Sebastian Bergmann
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phploc/tree
* @since Class available since Release 1.6.0
*/
class Single
{
/**
* Mapping between internal and human-readable metric names
*
* @var array
*/
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',
'llocClasses' => 'Classes Length (LLOC)',
'methods' => 'Methods',
'nonStaticMethods' => 'Non-Static Methods',
'staticMethods' => 'Static Methods',
'publicMethods' => 'Public Methods',
'nonPublicMethods' => 'Non-Public Methods',
'methodCcnAvg' => 'Cyclomatic Complexity / Number of Methods',
'functions' => 'Functions',
'namedFunctions' => 'Named Functions',
'anonymousFunctions' => 'Anonymous Functions',
'llocFunctions' => 'Functions Length (LLOC)',
'llocByNof' => 'Average Function Length (LLOC)',
'constants' => 'Constants',
'globalConstants' => 'Global Constants',
'classConstants' => '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'
];
/**
* Prints a result set.
*
* @param string $filename
* @param array $count
*/
public function printResult($filename, array $count)
{
file_put_contents(
$filename,
$this->getKeysLine($count) . $this->getValuesLine($count)
);
}
/**
* @param array $count
* @return string
*/
protected function getKeysLine(array $count)
{
return implode(',', array_values($this->colmap)) . PHP_EOL;
}
/**
* @param array $count
* @throws \InvalidArgumentException
* @return string
*/
protected function getValuesLine(array $count)
{
$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;
}
}
PK ^GMsd src/Log/CSV/History.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\PHPLOC\Log\CSV;
/**
* A CSV ResultPrinter for the TextUI.
*
* @author Sebastian Bergmann
* @copyright Sebastian Bergmann
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phploc/tree
* @since Class available since Release 2.0.0
*/
class History extends Single
{
/**
* Prints a result set.
*
* @param string $filename
* @param array $count
*/
public function printResult($filename, array $count)
{
$buffer = $this->getKeysLine($count);
foreach ($count as $date => $data) {
$buffer .= $date . ',' . $this->getValuesLine($data);
}
file_put_contents($filename, $buffer);
}
/**
* @param array $count
* @return string
*/
protected function getValuesLine(array $count)
{
$values = ['commit' => $count['commit']];
return '"' . implode('","', $values) . '",' . parent::getValuesLine($count);
}
/**
* @param array $count
* @return string
*/
protected function getKeysLine(array $count)
{
$keys = ['Date', 'Commit'];
return implode(',', $keys) . ',' . parent::getKeysLine($count);
}
}
PK ^GMԒY src/CLI/Command.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\PHPLOC\CLI;
use SebastianBergmann\FinderFacade\FinderFacade;
use SebastianBergmann\Git\Git;
use SebastianBergmann\PHPLOC\Analyser;
use SebastianBergmann\PHPLOC\Log\CSV\History;
use SebastianBergmann\PHPLOC\Log\CSV\Single;
use SebastianBergmann\PHPLOC\Log\Text;
use SebastianBergmann\PHPLOC\Log\XML;
use Symfony\Component\Console\Command\Command as AbstractCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\ProgressBar;
/**
* @author Sebastian Bergmann
* @copyright Sebastian Bergmann
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phploc/tree
* @since Class available since Release 2.0.0
*/
class Command extends AbstractCommand
{
/**
* Configures the current command.
*/
protected function configure()
{
$this->setName('phploc')
->setDefinition(
[
new InputArgument(
'values',
InputArgument::IS_ARRAY
)
]
)
->addOption(
'names',
null,
InputOption::VALUE_REQUIRED,
'A comma-separated list of file names to check',
['*.php']
)
->addOption(
'names-exclude',
null,
InputOption::VALUE_REQUIRED,
'A comma-separated list of file names to exclude',
[]
)
->addOption(
'count-tests',
null,
InputOption::VALUE_NONE,
'Count PHPUnit test case classes and test methods'
)
->addOption(
'git-repository',
null,
InputOption::VALUE_REQUIRED,
'Collect metrics over the history of a Git repository'
)
->addOption(
'exclude',
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'Exclude a directory from code analysis'
)
->addOption(
'log-csv',
null,
InputOption::VALUE_REQUIRED,
'Write result in CSV format to file'
)
->addOption(
'log-xml',
null,
InputOption::VALUE_REQUIRED,
'Write result in XML format to file'
)
->addOption(
'progress',
null,
InputOption::VALUE_NONE,
'Show progress bar'
);
}
/**
* Executes the current command.
*
* @param InputInterface $input An InputInterface instance
* @param OutputInterface $output An OutputInterface instance
*
* @return null|integer null or 0 if everything went fine, or an error code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if (!$input->getOption('git-repository')) {
return $this->executeSingle($input, $output);
} else {
return $this->executeHistory($input, $output);
}
}
/**
* @param InputInterface $input An InputInterface instance
* @param OutputInterface $output An OutputInterface instance
*
* @return null|integer null or 0 if everything went fine, or an error code
*/
private function executeSingle(InputInterface $input, OutputInterface $output)
{
$count = $this->count(
$input->getArgument('values'),
$input->getOption('exclude'),
$this->handleCSVOption($input, 'names'),
$this->handleCSVOption($input, 'names-exclude'),
$input->getOption('count-tests')
);
if (!$count) {
$output->writeln('No files found to scan');
exit(1);
}
$printer = new Text;
$printer->printResult(
$output,
$count,
$input->getOption('count-tests')
);
if ($input->getOption('log-csv')) {
$printer = new Single;
$printer->printResult($input->getOption('log-csv'), $count);
}
if ($input->getOption('log-xml')) {
$printer = new XML;
$printer->printResult($input->getOption('log-xml'), $count);
}
}
/**
* @param InputInterface $input An InputInterface instance
* @param OutputInterface $output An OutputInterface instance
*
* @return null|integer null or 0 if everything went fine, or an error code
*/
private function executeHistory(InputInterface $input, OutputInterface $output)
{
$git = new Git($input->getOption('git-repository'));
$currentBranch = $git->getCurrentBranch();
$revisions = $git->getRevisions();
$count = [];
$progressBar = null;
if ($input->getOption('progress')) {
$progressBar = new ProgressBar($output, count($revisions));
$progressBar->start();
}
foreach ($revisions as $revision) {
$git->checkout($revision['sha1']);
$directories = [];
foreach ($input->getArgument('values') as $value) {
$directory = realpath($value);
if ($directory) {
$directories[] = $directory;
}
}
$_count = $this->count(
$directories,
$input->getOption('exclude'),
$this->handleCSVOption($input, 'names'),
$this->handleCSVOption($input, 'names-exclude'),
$input->getOption('count-tests')
);
if ($_count) {
$_count['commit'] = $revision['sha1'];
$count[$revision['date']->format(\DateTime::W3C)] = $_count;
}
if ($progressBar !== null) {
$progressBar->advance();
}
}
$git->checkout($currentBranch);
if ($progressBar !== null) {
$progressBar->finish();
$output->writeln('');
}
if ($input->getOption('log-csv')) {
$printer = new History;
$printer->printResult($input->getOption('log-csv'), $count);
}
}
private function count(array $arguments, $excludes, $names, $namesExclude, $countTests)
{
try {
$finder = new FinderFacade($arguments, $excludes, $names, $namesExclude);
$files = $finder->findFiles();
} catch (\InvalidArgumentException $ex) {
return false;
}
if (empty($files)) {
return false;
}
$analyser = new Analyser;
return $analyser->countFiles($files, $countTests);
}
/**
* @param InputInterface $input
* @param string $option
* @return array
*/
private function handleCSVOption(InputInterface $input, $option)
{
$result = $input->getOption($option);
if (!is_array($result)) {
$result = explode(',', $result);
array_map('trim', $result);
}
return $result;
}
}
PK ^GM1= = src/CLI/Application.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\PHPLOC\CLI;
use SebastianBergmann\Version;
use Symfony\Component\Console\Application as AbstractApplication;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\ArrayInput;
/**
* TextUI frontend for PHPLOC.
*
* @author Sebastian Bergmann
* @copyright Sebastian Bergmann
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phploc/tree
* @since Class available since Release 2.0.0
*/
class Application extends AbstractApplication
{
public function __construct()
{
$version = new Version('2.1.0', dirname(dirname(__DIR__)));
parent::__construct('phploc', $version->getVersion());
}
/**
* Gets the name of the command based on input.
*
* @param InputInterface $input The input interface
*
* @return string The command name
*/
protected function getCommandName(InputInterface $input)
{
return 'phploc';
}
/**
* Gets the default commands that should always be available.
*
* @return array An array of default Command instances
*/
protected function getDefaultCommands()
{
$defaultCommands = parent::getDefaultCommands();
$defaultCommands[] = new Command;
return $defaultCommands;
}
/**
* Overridden so that the application doesn't expect the command
* name to be the first argument.
*/
public function getDefinition()
{
$inputDefinition = parent::getDefinition();
$inputDefinition->setArguments();
return $inputDefinition;
}
/**
* Runs the current application.
*
* @param InputInterface $input An Input instance
* @param OutputInterface $output An Output instance
*
* @return integer 0 if everything went fine, or an error code
*/
public function doRun(InputInterface $input, OutputInterface $output)
{
if (!$input->hasParameterOption('--quiet')) {
$output->write(
sprintf(
"phploc %s by Sebastian Bergmann.\n\n",
$this->getVersion()
)
);
}
if ($input->hasParameterOption('--version') ||
$input->hasParameterOption('-V')) {
exit;
}
if (!$input->getFirstArgument()) {
$input = new ArrayInput(['--help']);
}
parent::doRun($input, $output);
}
}
PK ^GMrsX .gitattributesnu W+A *.php diff=php
PK ^GMI| phplocnu W+A #!/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
);
}
$application = new SebastianBergmann\PHPLOC\CLI\Application;
$application->run();
PK ^GMh6 6 build.xmlnu W+A
PK ^GMC5Σ tests/Log/CSV/HistoryTest.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class HistoryTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \SebastianBergmann\PHPLOC\Log\CSV\Single
*/
private $history;
private $sample_data = [
'2014-06-09T00:00:00' => [
'commit' => 'foo',
'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,
'llocClasses' => 15,
'methods' => 16,
'nonStaticMethods' => 17,
'staticMethods' => 18,
'publicMethods' => 19,
'nonPublicMethods' => 20,
'methodCcnAvg' => 21,
'functions' => 22,
'namedFunctions' => 23,
'anonymousFunctions' => 24,
'llocFunctions' => 25,
'llocByNof' => 26,
'constants' => 27,
'globalConstants' => 28,
'classConstants' => 29,
'attributeAccesses' => 30,
'instanceAttributeAccesses' => 31,
'staticAttributeAccesses' => 32,
'methodCalls' => 33,
'instanceMethodCalls' => 34,
'staticMethodCalls' => 35,
'globalAccesses' => 36,
'globalVariableAccesses' => 37,
'superGlobalVariableAccesses' => 38,
'globalConstantAccesses' => 39,
'testClasses' => 40,
'testMethods' => 41
],
'2014-07-09T00:00:00' => [
'commit' => 'bar',
'directories' => 42,
'files' => 43,
'loc' => 44,
'ccnByLloc' => 45,
'cloc' => 46,
'ncloc' => 47,
'lloc' => 48,
'llocGlobal' => 49,
'namespaces' => 50,
'interfaces' => 51,
'traits' => 52,
'classes' => 53,
'abstractClasses' => 54,
'concreteClasses' => 55,
'llocClasses' => 56,
'methods' => 57,
'nonStaticMethods' => 58,
'staticMethods' => 59,
'publicMethods' => 60,
'nonPublicMethods' => 61,
'methodCcnAvg' => 62,
'functions' => 63,
'namedFunctions' => 64,
'anonymousFunctions' => 65,
'llocFunctions' => 66,
'llocByNof' => 67,
'constants' => 68,
'globalConstants' => 69,
'classConstants' => 70,
'attributeAccesses' => 71,
'instanceAttributeAccesses' => 72,
'staticAttributeAccesses' => 73,
'methodCalls' => 74,
'instanceMethodCalls' => 75,
'staticMethodCalls' => 76,
'globalAccesses' => 77,
'globalVariableAccesses' => 78,
'superGlobalVariableAccesses' => 79,
'globalConstantAccesses' => 80,
'testClasses' => 81,
'testMethods' => 82
]
];
public function setUp()
{
$this->history = new \SebastianBergmann\PHPLOC\Log\CSV\History();
}
public function testPrintedResultContainsHeadings()
{
ob_start();
$this->history->printResult('php://output', $this->sample_data);
$output = ob_get_clean();
$this->assertRegExp('#^Date,Commit,Directories,Files.+$#mis', $output, "Printed result does not contain a heading line");
}
public function testPrintedResultContainsData()
{
ob_start();
$this->history->printResult('php://output', $this->sample_data);
$output = ob_get_clean();
$this->assertRegExp('#^2014-06-09T00:00:00,"foo","1".+$#mis', $output, "Printed result does not contain a value line");
}
public function testExactlyThreeRowsArePrinted()
{
ob_start();
$this->history->printResult('php://output', $this->sample_data);
$output = ob_get_clean();
$rows = explode("\n", trim($output));
$this->assertEquals(3, count($rows), "Printed result contained more or less than expected 2 rows");
}
}
PK ^GM tests/Log/CSV/SingleTest.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class SingleTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \SebastianBergmann\PHPLOC\Log\CSV\Single
*/
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,
'llocClasses' => 15,
'methods' => 16,
'nonStaticMethods' => 17,
'staticMethods' => 18,
'publicMethods' => 19,
'nonPublicMethods' => 20,
'methodCcnAvg' => 21,
'functions' => 22,
'namedFunctions' => 23,
'anonymousFunctions' => 24,
'llocFunctions' => 25,
'llocByNof' => 26,
'constants' => 27,
'globalConstants' => 28,
'classConstants' => 29,
'attributeAccesses' => 30,
'instanceAttributeAccesses' => 31,
'staticAttributeAccesses' => 32,
'methodCalls' => 33,
'instanceMethodCalls' => 34,
'staticMethodCalls' => 35,
'globalAccesses' => 36,
'globalVariableAccesses' => 37,
'superGlobalVariableAccesses' => 38,
'globalConstantAccesses' => 39,
'testClasses' => 40,
'testMethods' => 41
];
public function setUp()
{
$this->single = new \SebastianBergmann\PHPLOC\Log\CSV\Single();
}
public function testPrintedResultContainsHeadings()
{
ob_start();
$this->single->printResult('php://output', $this->sample_row);
$output = ob_get_clean();
$this->assertRegExp('#Directories,Files.+$#is', $output, "Printed result does not contain a heading line");
}
public function testPrintedResultContainsData()
{
ob_start();
$this->single->printResult('php://output', $this->sample_row);
$output = ob_get_clean();
$this->assertRegExp('#"1","2".+$#is', $output, "Printed result does not contain a value line");
}
public function testPrintedResultContainsEqualNumHeadingsAndValues()
{
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()
{
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");
}
/**
* @expectedException \InvalidArgumentException
*/
public function testPrintPartialRow()
{
$count = $this->sample_row;
unset($count['llocByNof']);
ob_start();
$this->single->printResult('php://output', $count);
ob_end_clean();
$this->fail("No exception was raised for malformed input var");
}
}
PK ^GMNj tests/AnalyzerTest.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Tests for the PHPLOC_Analyser class.
*
* @package PHPLOC
* @subpackage Tests
* @author Sebastian Bergmann
* @copyright Sebastian Bergmann
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
* @link http://github.com/sebastianbergmann/phploc/
* @since Class available since Release 1.3.0
*/
class PHPLOC_AnalyserTest extends PHPUnit_Framework_TestCase
{
/**
* @var SebastianBergmann\PHPLOC\Analyser
*/
protected $analyser;
protected function setUp()
{
$this->analyser = new SebastianBergmann\PHPLOC\Analyser;
}
public function testWithoutTests()
{
$this->assertEquals(
[
'files' => 1,
'loc' => 73,
'lloc' => 25,
'llocClasses' => 22,
'llocFunctions' => 1,
'llocGlobal' => 2,
'cloc' => 7,
'ccn' => 2,
'ccnMethods' => 2,
'interfaces' => 1,
'traits' => 0,
'classes' => 2,
'abstractClasses' => 1,
'concreteClasses' => 1,
'functions' => 2,
'namedFunctions' => 1,
'anonymousFunctions' => 1,
'methods' => 4,
'publicMethods' => 2,
'nonPublicMethods' => 2,
'nonStaticMethods' => 3,
'staticMethods' => 1,
'constants' => 2,
'classConstants' => 1,
'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' => 66,
'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
],
$this->analyser->countFiles(
[__DIR__ . '/_files/source.php'],
false
),
'',
0.1
);
}
public function testWithTests()
{
$this->assertEquals(
[
'files' => 2,
'loc' => 96,
'lloc' => 25,
'llocClasses' => 22,
'llocFunctions' => 1,
'llocGlobal' => 2,
'cloc' => 11,
'ccn' => 2,
'ccnMethods' => 2,
'interfaces' => 1,
'traits' => 0,
'classes' => 2,
'abstractClasses' => 1,
'concreteClasses' => 1,
'functions' => 2,
'namedFunctions' => 1,
'anonymousFunctions' => 1,
'methods' => 4,
'publicMethods' => 2,
'nonPublicMethods' => 2,
'nonStaticMethods' => 3,
'staticMethods' => 1,
'constants' => 2,
'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' => 85,
'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
],
$this->analyser->countFiles(
[
__DIR__ . '/_files/source.php',
__DIR__ . '/_files/tests.php'
],
true
),
'',
0.1
);
}
public function testFilesThatExtendPHPUnitTestCaseAreCountedAsTests() {
$result = $this->analyser->countFiles(
[
__DIR__ . '/_files/tests.php'
],
true
);
$this->assertEquals(1, $result['testClasses']);
}
public function testFilesThatIndirectlyExtendPHPUnitTestCaseAreCountedAsTests() {
$result = $this->analyser->countFiles(
[
__DIR__ . '/_files/twoTestsThatIndirectlyExtendPHPUnitTestCase.php'
],
true
);
$this->assertEquals(3, $result['testClasses']);
}
public function testTraitsAreCountedCorrectly()
{
$result = $this->analyser->countFiles(
[
__DIR__ . '/_files/trait.php'
],
false
);
$this->assertEquals(1, $result['traits']);
}
/**
* @ticket 64
*/
public function testIssue64IsFixed()
{
$result = $this->analyser->countFiles(
[
__DIR__ . '/_files/issue_62.php'
],
false
);
$this->assertEquals(1, $result['cloc']);
}
}
PK ^GMϥמ <