public function testFormaterReturnsXml() { // all results $rs1 = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultSet')->disableOriginalConstructor()->getMock(); $rs1->expects($this->any())->method('asArray')->will($this->returnValue(array('volume' => 5))); $rs1->expects($this->any())->method('getFilename')->will($this->returnValue('path2/file1.php')); $rs2 = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultSet')->disableOriginalConstructor()->getMock(); $rs2->expects($this->any())->method('asArray')->will($this->returnValue(array('volume' => 15))); $rs2->expects($this->any())->method('getFilename')->will($this->returnValue('path1/file1.php')); $collection = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultCollection')->disableOriginalConstructor()->getMock(); $collection->expects($this->any())->method('getIterator')->will($this->returnValue(new \ArrayIterator(array($rs1, $rs2)))); $collection->expects($this->any())->method('getFilename')->will($this->returnValue('abc')); $collection->expects($this->any())->method('asArray')->will($this->returnValue(array(array('volume' => 5), array('volume' => 15)))); $bounds = new Bounds(); // grouped results $groupedResults = new ResultCollection(); $result = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultAggregate')->disableOriginalConstructor()->getMock(); $result->expects($this->any())->method('getName')->will($this->returnValue('path1')); $result->expects($this->any())->method('getBounds')->will($this->returnValue($this->getMock('\\Hal\\Component\\Bounds\\Result\\ResultInterface'))); $groupedResults->push($result); $result = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultAggregate')->disableOriginalConstructor()->getMock(); $result->expects($this->any())->method('getName')->will($this->returnValue('path2')); $result->expects($this->any())->method('getBounds')->will($this->returnValue($this->getMock('\\Hal\\Component\\Bounds\\Result\\ResultInterface'))); $groupedResults->push($result); // formater $validator = $this->getMockBuilder('\\Hal\\Application\\Rule\\Validator')->disableOriginalConstructor()->getMock(); $formater = new Xml($validator, $bounds, $this->getMockBuilder('\\Hal\\Application\\Extension\\ExtensionService')->disableOriginalConstructor()->getMock()); $output = $formater->terminate($collection, $groupedResults); $xml = new \SimpleXMLElement($output); $p = $xml->xpath('//project'); $this->assertEquals('10', $p[0]['volume']); $m = $xml->xpath('//project/modules/module[@namespace="path1"]'); $m = $m[0]; $this->assertCount(2, $xml->xpath('//project/modules/module')); }
public function execute(array $files) { $object = new FileSystemComplexity($this->classMap); foreach ($files as $filename) { $result = $object->calculate($filename); $this->collection->get($filename)->setSystemComplexity($result); } }
public function execute(array $files) { $fileCoupling = new FileLackOfCohesionOfMethods($this->classMap); foreach ($files as $filename) { $result = $fileCoupling->calculate($filename); $this->collection->get($filename)->setLcom($result); } }
/** * Terminate process * * @param ResultCollection $collection * @param ResultCollection $groupedResults * @return string */ public function terminate(ResultCollection $collection, ResultCollection $groupedResults) { // use pretty print for readability if according php version given if ($this->prettyPrint && version_compare(PHP_VERSION, '5.4.0') >= 0) { return json_encode($collection->asArray(), JSON_PRETTY_PRINT); } else { return json_encode($collection->asArray()); } }
/** * @inheritdoc */ public function terminate(ResultCollection $collection, ResultCollection $groupedResults) { \Twig_Autoloader::register(); $loader = new \Twig_Loader_Filesystem(__DIR__ . '/../../../../../templates/html'); $twig = new \Twig_Environment($loader, array('cache' => false)); $twig->addExtension(new FormatingExtension($this->validator)); $bound = $this->bound->calculate($collection); return $twig->render('summary/report.html.twig', array('keys' => array_keys(current($collection->asArray())), 'results' => $collection->asArray(), 'groupedResults' => $groupedResults, 'root' => $groupedResults->getIterator()->current(), 'relations' => $this->prepareDataRelations($collection), 'scores' => $collection->getScore()->all(), 'ruleSet' => $this->validator->getRuleSet(), 'bounds' => $bound, 'withOOP' => null !== $bound->getSum('instability'))); }
public function execute(array $files) { $coupling = new Coupling(); $couplingMap = $coupling->calculate($this->classMap); // link between coupling and files $fileCoupling = new FileCoupling($this->classMap, $couplingMap); foreach ($files as $filename) { $rCoupling = $fileCoupling->calculate($filename); $this->collection->get($filename)->setCoupling($rCoupling); } }
public function testICanKnowTheInstabilityOfPackage() { $results = new ResultCollection(); $coupling = $this->getMockBuilder('\\Hal\\Metrics\\Complexity\\Structural\\HenryAndKafura\\Result')->disableOriginalConstructor()->getMock(); $coupling->expects($this->any())->method('getAfferentCoupling')->will($this->returnValue(1.5)); $coupling->expects($this->any())->method('getEfferentCoupling')->will($this->returnValue(0.8)); $resultSet = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultSet')->disableOriginalConstructor()->getMock(); $resultSet->expects($this->any())->method('getCoupling')->will($this->returnValue($coupling)); $results->push($resultSet); $instability = new Instability(); $r = $instability->calculate($results); $this->assertEquals(0.35, $r->getInstability()); }
/** * @dataProvider provideAbstractness */ public function testICanKnowTheAbstractnessOfPackage($expected, $abstractClasses, $concreteClasses) { $instability = new Abstractness(); $results = new ResultCollection(); $oop = $this->getMockBuilder('\\Hal\\Component\\OOP\\Extractor\\Result')->disableOriginalConstructor()->getMock(); $oop->expects($this->any())->method('getConcreteClasses')->will($this->returnValue(array_pad(array(), $concreteClasses, null))); $oop->expects($this->any())->method('getAbstractClasses')->will($this->returnValue(array_pad(array(), $abstractClasses, null))); $resultSet = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultSet')->disableOriginalConstructor()->getMock(); $resultSet->expects($this->any())->method('getOOP')->will($this->returnValue($oop)); $results->push($resultSet); $r = $instability->calculate($results); $this->assertEquals($expected, $r->getAbstractness()); }
/** * @inheritdoc */ public function terminate(ResultCollection $collection, ResultCollection $groupedResults) { $this->output->write(str_pad("\r", 80, " ")); $this->output->writeln(''); // score $score = $collection->getScore(); // if($score) { foreach ($score->all() as $name => $value) { $this->output->writeln(sprintf('%s %s', str_pad($name, 35, '.'), str_pad($value, 5, ' ', STR_PAD_LEFT) . ' / ' . Scoring::MAX)); } $this->output->writeln(''); // } }
/** * @inheritdoc */ public function terminate(ResultCollection $collection, ResultCollection $groupedResults) { $output = new ConsoleOutput(OutputInterface::VERBOSITY_NORMAL, true); $output->write(str_pad("\r", 80, " ")); $output->writeln(''); // score $score = $collection->getScore(); // if($score) { foreach ($score->all() as $name => $value) { $output->writeln(sprintf('%s %s', str_pad($name, 35, '.'), str_pad($value, 5, ' ', STR_PAD_LEFT) . ' / ' . Scoring::MAX)); } $output->writeln(''); // } }
/** * @inheritdoc * @return \Hal\Component\Bounds\Result\ResultInterface */ public function calculate(ResultCollection $collection) { $array = $collection->asArray(); $arrayMerged = call_user_func_array('array_merge_recursive', $array); $min = $max = $average = $sum = array(); foreach ($arrayMerged as $key => $values) { $values = (array) $values; $max[$key] = max($values); $min[$key] = min($values); $sum[$key] = array_sum($values); $average[$key] = round($sum[$key] / count($values, COUNT_NORMAL), 2); } return new BoundsResult($min, $max, $average, $sum); }
public function testICanAcessToResultCollectionAsAnArray() { $rs1 = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultSet')->disableOriginalConstructor()->getMock(); $rs1->expects($this->once())->method('getName')->will($this->returnValue('f1.php')); $rs2 = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultSet')->disableOriginalConstructor()->getMock(); $collection = new ResultCollection(); $collection->push($rs1); $collection['f2.php'] = $rs2; $i = 0; foreach ($collection as $n) { $i++; } $this->assertEquals(2, $i); $this->assertEquals(2, sizeof($collection)); $this->assertEquals($rs1, $collection['f1.php']); unset($collection['f2.php']); $this->assertEquals(1, sizeof($collection)); $this->assertFalse(isset($collection['f2.php'])); }
/** * @inheritdoc */ public function terminate(ResultCollection $collection, ResultCollection $groupedResults) { $this->output->write(str_pad("\r", 80, " ")); $this->output->writeln(''); // score $score = $collection->getScore(); foreach ($score->all() as $name => $value) { $this->output->writeln(sprintf('%s %s', str_pad($name, 35, '.'), str_pad($value, 5, ' ', STR_PAD_LEFT) . ' / ' . Scoring::MAX)); } $this->output->writeln(''); // extensions foreach ($this->extensionsService->getRepository()->all() as $plugin) { $helper = $plugin->getReporterCliSummary(); if (!$helper) { continue; } $this->output->write($helper->render()); } }
public function testFormaterReturnsXml() { // all results $rs1 = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultSet')->disableOriginalConstructor()->getMock(); $rs1->expects($this->any())->method('asArray')->will($this->returnValue(array('loc' => 5))); $rs1->expects($this->any())->method('getFilename')->will($this->returnValue('path2/file1.php')); $rs2 = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultSet')->disableOriginalConstructor()->getMock(); $rs2->expects($this->any())->method('asArray')->will($this->returnValue(array('loc' => 15))); $rs2->expects($this->any())->method('getFilename')->will($this->returnValue('path1/file1.php')); $collection = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultCollection')->disableOriginalConstructor()->getMock(); $collection->expects($this->any())->method('getIterator')->will($this->returnValue(new \ArrayIterator(array($rs1, $rs2)))); $collection->expects($this->any())->method('getFilename')->will($this->returnValue('abc')); $collection->expects($this->any())->method('asArray')->will($this->returnValue(array(array('loc' => 5), array('loc' => 15)))); $bounds = new Bounds(); // grouped results $groupedResults = new ResultCollection(); $result = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultAggregate')->disableOriginalConstructor()->getMock(); $result->expects($this->any())->method('getName')->will($this->returnValue('path1')); $result->expects($this->any())->method('getBounds')->will($this->returnValue($this->getMock('\\Hal\\Component\\Bounds\\Result\\ResultInterface'))); $groupedResults->push($result); $result = $this->getMockBuilder('\\Hal\\Component\\Result\\ResultAggregate')->disableOriginalConstructor()->getMock(); $result->expects($this->any())->method('getName')->will($this->returnValue('path2')); $result->expects($this->any())->method('getBounds')->will($this->returnValue($this->getMock('\\Hal\\Component\\Bounds\\Result\\ResultInterface'))); $groupedResults->push($result); // formater $ruleSet = $this->getMock('\\Hal\\Application\\Rule\\RuleSet'); $ruleSet->expects($this->any())->method('getRule')->will($this->returnValue(array(3, 2, 1.5))); $validator = $this->getMockBuilder('\\Hal\\Application\\Rule\\Validator')->disableOriginalConstructor()->getMock(); $validator->expects($this->any())->method('getRuleSet')->willReturn($ruleSet); $formater = new Xml($validator, $bounds); $output = $formater->terminate($collection, $groupedResults); $xml = new \SimpleXMLElement($output); $p = $xml->xpath('//pmd/file/violation'); $this->assertCount(2, $p); $this->assertEquals('loc', $p[0]['rule']); $this->assertEquals('5', $p[0]['endline']); $this->assertEquals('loc', $p[1]['rule']); $this->assertEquals('15', $p[1]['endline']); }
/** * @inheritdoc */ public function execute(ResultCollection $collection, ResultCollection $aggregatedResults) { $this->output->write(str_pad("\rGrouping results by package/directory. This will take few minutes...", 80, " ")); // Aggregates results $groupedResults = $this->aggregator->aggregates($collection); // metrics tools $abstractness = new Abstractness(); $bounds = new Bounds(); $instability = new Instability(); foreach ($groupedResults as $namespace => $results) { // we filter aggregates to conserve only direct results $childs = new ResultCollection(); foreach ($results as $r) { if ($namespace === dirname($r->getName())) { $childs->push($r); } } $resultAggregate = new ResultAggregate($namespace); $resultAggregate->setAbstractness($abstractness->calculate($results))->setInstability($instability->calculate($results))->setBounds($bounds->calculate($results))->setChilds($childs); $aggregatedResults->push($resultAggregate); } }
/** * @inheritdoc */ public function execute(ResultCollection $collection, ResultCollection $aggregatedResults) { $files = $this->finder->find($this->path); if (0 == sizeof($files, COUNT_NORMAL)) { throw new \LogicException('No file found'); } $progress = new ProgressBar($this->output); $progress->start(sizeof($files, COUNT_NORMAL)); // tools $classMap = new ClassMap(); $tokenizer = new Tokenizer(); $syntaxChecker = new SyntaxChecker(); $fileAnalyzer = new FileAnalyzer($this->output, $this->withOOP, new Extractor(), new \Hal\Metrics\Complexity\Text\Halstead\Halstead(new \Hal\Component\Token\TokenType()), new \Hal\Metrics\Complexity\Text\Length\Loc(), new \Hal\Metrics\Design\Component\MaintainabilityIndex\MaintainabilityIndex(), new \Hal\Metrics\Complexity\Component\McCabe\McCabe(), new \Hal\Metrics\Complexity\Component\Myer\Myer(), $classMap); foreach ($files as $k => $filename) { $progress->advance(); // Integrity if (!$this->ignoreErrors && !$syntaxChecker->isCorrect($filename)) { $this->output->writeln(sprintf('<error>file %s is not valid and has been skipped</error>', $filename)); unset($files[$k]); continue; } // Analyze try { $tokens = $tokenizer->tokenize($filename); $resultSet = $fileAnalyzer->execute($filename, $tokens); } catch (NoTokenizableException $e) { $this->output->writeln(sprintf("<error>file %s has been skipped: \n%s</error>", $filename, $e->getMessage())); unset($files[$k]); continue; } catch (\Exception $e) { throw new \Exception(sprintf("a '%s' exception occured analyzing file %s\nMessage: %s", get_class($e), $filename, $e->getMessage()) . sprintf("\n------------\nStack:\n%s", $e->getTraceAsString()) . sprintf("\n------------\nDo not hesitate to report a bug: https://github.com/PhpMetrics/PhpMetrics/issues"), 0, $e->getPrevious()); } $collection->push($resultSet); } $progress->clear(); $progress->finish(); if ($this->withOOP) { // COUPLING (should be done after parsing files) $this->output->write(str_pad("\rAnalyzing coupling. This will take few minutes...", 80, " ")); $couplingAnalyzer = new CouplingAnalyzer($classMap, $collection); $couplingAnalyzer->execute($files); // LCOM (should be done after parsing files) $this->output->write(str_pad("\rLack of cohesion of method (lcom). This will take few minutes...", 80, " ")); $lcomAnalyzer = new LcomAnalyzer($classMap, $collection); $lcomAnalyzer->execute($files); // Card and Agresti (should be done after parsing files) $this->output->write(str_pad("\rAnalyzing System complexity. This will take few minutes...", 80, " ")); $lcomAnalyzer = new CardAndAgrestiAnalyzer($classMap, $collection); $lcomAnalyzer->execute($files); } }
/** * @inheritdoc */ public function execute(ResultCollection $collection, ResultCollection $aggregatedResults) { $files = $this->finder->find($this->path); if (0 == sizeof($files, COUNT_NORMAL)) { throw new \LogicException('No file found'); } $progress = new ProgressHelper(); $progress->start($this->output, sizeof($files, COUNT_NORMAL)); // tools $classMap = new ClassMap(); $tokenizer = new Tokenizer(); $syntaxChecker = new SyntaxChecker(); $fileAnalyzer = new FileAnalyzer($this->output, $this->withOOP, new Extractor($tokenizer), new \Hal\Metrics\Complexity\Text\Halstead\Halstead($tokenizer, new \Hal\Component\Token\TokenType()), new \Hal\Metrics\Complexity\Text\Length\Loc($tokenizer), new \Hal\Metrics\Design\Component\MaintenabilityIndex\MaintenabilityIndex($tokenizer), new \Hal\Metrics\Complexity\Component\McCabe\McCabe($tokenizer), new \Hal\Metrics\Complexity\Component\Myer\Myer($tokenizer), $classMap); foreach ($files as $k => $filename) { $progress->advance(); // Integrity if (!$syntaxChecker->isCorrect($filename)) { $this->output->writeln(sprintf('<error>file %s is not valid and has been skipped</error>', $filename)); unset($files[$k]); continue; } // Analyze $resultSet = $fileAnalyzer->execute($filename); $collection->push($resultSet); } $progress->clear(); $progress->finish(); if ($this->withOOP) { // COUPLING (should be done after parsing files) $this->output->write(str_pad("\rAnalyzing coupling. This will take few minutes...", 80, " ")); $couplingAnalyzer = new CouplingAnalyzer($classMap, $collection); $couplingAnalyzer->execute($files); // LCOM (should be done after parsing files) $this->output->write(str_pad("\rLack of cohesion of method (lcom). This will take few minutes...", 80, " ")); $lcomAnalyzer = new LcomAnalyzer($classMap, $collection); $lcomAnalyzer->execute($files); // Card and Agresti (should be done after parsing files) $this->output->write(str_pad("\rAnalyzing System complexity. This will take few minutes...", 80, " ")); $lcomAnalyzer = new CardAndAgrestiAnalyzer($classMap, $collection); $lcomAnalyzer->execute($files); } }
public function testICanAggregatesResults() { $collection = new ResultCollection(); $collection->push(new ResultSet(str_replace('/', DIRECTORY_SEPARATOR, '/root1/folder1/file1.php'))); $collection->push(new ResultSet(str_replace('/', DIRECTORY_SEPARATOR, '/root1/folder1/file2.php'))); $collection->push(new ResultSet(str_replace('/', DIRECTORY_SEPARATOR, '/root1/folder1/file3.php'))); $collection->push(new ResultSet(str_replace('/', DIRECTORY_SEPARATOR, '/root1/folder2/file1.php'))); $collection->push(new ResultSet(str_replace('/', DIRECTORY_SEPARATOR, '/root2/file1.php'))); $aggregator = new DirectoryRecursiveAggregator(0); $results = $aggregator->aggregates($collection); $this->assertArrayHasKey('.', $results); $results = $results['.']; $this->assertEquals(2, sizeof($results, COUNT_NORMAL), 'root'); $this->assertArrayHasKey('root1', $results); $this->assertEquals(2, sizeof($results['root1'], COUNT_NORMAL), 'first level'); $this->assertArrayHasKey('folder1', $results['root1']); $this->assertEquals(3, sizeof($results['root1']['folder1'], COUNT_NORMAL), 'second level'); $this->assertEquals(1, sizeof($results['root1']['folder2'], COUNT_NORMAL), 'second level B'); $this->assertEquals(1, sizeof($results['root2'], COUNT_NORMAL), 'fist level B'); }