ComplexityCalculatingVisitorTest.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. <?php declare(strict_types=1);
  2. /*
  3. * This file is part of sebastian/complexity.
  4. *
  5. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace SebastianBergmann\Complexity;
  11. use function file_get_contents;
  12. use PhpParser\Node;
  13. use PhpParser\NodeTraverser;
  14. use PhpParser\NodeVisitor\NameResolver;
  15. use PhpParser\NodeVisitor\ParentConnectingVisitor;
  16. use PhpParser\NodeVisitorAbstract;
  17. use PhpParser\ParserFactory;
  18. use PHPUnit\Framework\TestCase;
  19. /**
  20. * @covers \SebastianBergmann\Complexity\ComplexityCalculatingVisitor
  21. *
  22. * @uses \SebastianBergmann\Complexity\Complexity
  23. * @uses \SebastianBergmann\Complexity\ComplexityCollection
  24. * @uses \SebastianBergmann\Complexity\ComplexityCollectionIterator
  25. * @uses \SebastianBergmann\Complexity\CyclomaticComplexityCalculatingVisitor
  26. *
  27. * @small
  28. */
  29. final class ComplexityCalculatingVisitorTest extends TestCase
  30. {
  31. /**
  32. * @dataProvider shortCircuitTraversalProvider
  33. */
  34. public function testCalculatesComplexityForAbstractSyntaxTree(bool $shortCircuitTraversal): void
  35. {
  36. $nodes = (new ParserFactory)->createForHostVersion()->parse(
  37. file_get_contents(__DIR__ . '/../_fixture/ExampleClass.php')
  38. );
  39. $traverser = new NodeTraverser;
  40. $complexityCalculatingVisitor = new ComplexityCalculatingVisitor($shortCircuitTraversal);
  41. $shortCircuitVisitor = new class extends NodeVisitorAbstract {
  42. private $numberOfNodesVisited = 0;
  43. public function enterNode(Node $node): void
  44. {
  45. $this->numberOfNodesVisited++;
  46. }
  47. public function numberOfNodesVisited(): int
  48. {
  49. return $this->numberOfNodesVisited;
  50. }
  51. };
  52. $traverser->addVisitor(new NameResolver);
  53. $traverser->addVisitor(new ParentConnectingVisitor);
  54. $traverser->addVisitor($complexityCalculatingVisitor);
  55. $traverser->addVisitor($shortCircuitVisitor);
  56. /* @noinspection UnusedFunctionResultInspection */
  57. $traverser->traverse($nodes);
  58. $this->assertSame(14, $complexityCalculatingVisitor->result()->cyclomaticComplexity());
  59. if ($shortCircuitTraversal) {
  60. $this->assertSame(9, $shortCircuitVisitor->numberOfNodesVisited());
  61. } else {
  62. $this->assertSame(70, $shortCircuitVisitor->numberOfNodesVisited());
  63. }
  64. }
  65. public function shortCircuitTraversalProvider(): array
  66. {
  67. return [
  68. 'short-circuit traversal' => [true],
  69. 'no short-circuit traversal' => [false],
  70. ];
  71. }
  72. }