diff --git a/.travis.yml b/.travis.yml index 5674ee2..d84137a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ cache: before_script: - composer self-update - - composer update --prefer-source script: - ./bin/phpspec run diff --git a/spec/CouplingDetectorSpec.php b/spec/CouplingDetectorSpec.php index 2f497c4..7b9b6e0 100644 --- a/spec/CouplingDetectorSpec.php +++ b/spec/CouplingDetectorSpec.php @@ -6,6 +6,7 @@ use Akeneo\CouplingDetector\Domain\RuleInterface; use Akeneo\CouplingDetector\Domain\ViolationInterface; use Akeneo\CouplingDetector\Event\Events; +use Akeneo\CouplingDetector\NodeParser\ExtractionException; use Akeneo\CouplingDetector\NodeParser\NodeParserInterface; use Akeneo\CouplingDetector\NodeParser\NodeParserResolver; use Akeneo\CouplingDetector\RuleChecker; @@ -17,28 +18,28 @@ class CouplingDetectorSpec extends ObjectBehavior { function let( - NodeParserResolver $nodeExtractorResolver, + NodeParserResolver $nodeParserResolver, RuleChecker $ruleChecker, EventDispatcherInterface $eventDispatcher ) { - $this->beConstructedWith($nodeExtractorResolver, $ruleChecker, $eventDispatcher); + $this->beConstructedWith($nodeParserResolver, $ruleChecker, $eventDispatcher); } function it_detects_the_violations_of_files( $ruleChecker, - $nodeExtractorResolver, + $nodeParserResolver, $eventDispatcher, NodeInterface $node, ViolationInterface $violation, Finder $finder, RuleInterface $rule1, RuleInterface $rule2, - NodeParserInterface $extractor + NodeParserInterface $parser ) { $file = new \SplFileObject(__FILE__); $finder->getIterator()->willReturn(new \ArrayIterator(array($file))); - $nodeExtractorResolver->resolve(Argument::any())->willReturn($extractor); - $extractor->parse($file)->willReturn($node); + $nodeParserResolver->resolve(Argument::any())->willReturn($parser); + $parser->parse($file)->willReturn($node); $ruleChecker->check($rule1, $node)->willReturn(null); $ruleChecker->check($rule2, $node)->willReturn($violation); @@ -56,4 +57,26 @@ function it_detects_the_violations_of_files( $violations->shouldBeArray(); $violations[0]->shouldBeAnInstanceOf('Akeneo\CouplingDetector\Domain\ViolationInterface'); } + + function it_ignores_invalid_nodes( + $nodeParserResolver, + $eventDispatcher, + Finder $finder, + NodeParserInterface $parser + ) { + $file = new \SplFileObject(__DIR__.'/fixtures/InvalidNode.php'); + $finder->getIterator()->willReturn(new \ArrayIterator([$file])); + $nodeParserResolver->resolve(Argument::any())->willReturn($parser); + $parser->parse(Argument::any())->willThrow(ExtractionException::class); + + $eventDispatcher->dispatch(Events::PRE_NODES_PARSED, Argument::type('Akeneo\CouplingDetector\Event\PreNodesParsedEvent'))->shouldBeCalled(); + $eventDispatcher->dispatch(Events::NODE_PARSED, Argument::type('Akeneo\CouplingDetector\Event\NodeParsedEvent'))->shouldNotBeCalled(); + $eventDispatcher->dispatch(Events::POST_NODES_PARSED, Argument::type('Akeneo\CouplingDetector\Event\PostNodesParsedEvent'))->shouldBeCalled(); + $eventDispatcher->dispatch(Events::PRE_RULES_CHECKED, Argument::type('Akeneo\CouplingDetector\Event\PreRulesCheckedEvent'))->shouldBeCalled(); + $eventDispatcher->dispatch(Events::POST_RULES_CHECKED, Argument::type('Akeneo\CouplingDetector\Event\PostRulesCheckedEvent'))->shouldBeCalled(); + + $violations = $this->detect($finder, []); + $violations->shouldHaveCount(0); + $violations->shouldBeArray(); + } } diff --git a/spec/fixtures/InvalidNode.php b/spec/fixtures/InvalidNode.php new file mode 100644 index 0000000..e69de29 diff --git a/src/CouplingDetector.php b/src/CouplingDetector.php index bed36a2..f675a47 100644 --- a/src/CouplingDetector.php +++ b/src/CouplingDetector.php @@ -15,6 +15,7 @@ use Akeneo\CouplingDetector\Event\PreRulesCheckedEvent; use Akeneo\CouplingDetector\Event\RuleCheckedEvent; use Akeneo\CouplingDetector\Event\PostRulesCheckedEvent; +use Akeneo\CouplingDetector\NodeParser\ExtractionException; use Akeneo\CouplingDetector\NodeParser\NodeParserResolver; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Finder\Finder; @@ -111,9 +112,14 @@ private function parseNodes(Finder $finder): array foreach ($finder as $file) { $parser = $this->nodeParserResolver->resolve($file); if (null !== $parser) { - $node = $parser->parse($file); - $nodes[] = $node; - $this->eventDispatcher->dispatch(Events::NODE_PARSED, new NodeParsedEvent($node)); + try { + $node = $parser->parse($file); + $nodes[] = $node; + $this->eventDispatcher->dispatch(Events::NODE_PARSED, new NodeParsedEvent($node)); + } catch (ExtractionException $e) { + // at the moment, let's just ignore invalid node + // need to fix that with a better design + } } } diff --git a/src/NodeParser/PhpClassNodeParser.php b/src/NodeParser/PhpClassNodeParser.php index b632e40..f13660f 100644 --- a/src/NodeParser/PhpClassNodeParser.php +++ b/src/NodeParser/PhpClassNodeParser.php @@ -42,8 +42,14 @@ public function parse(\SplFileInfo $file): NodeInterface } $tokens = Tokens::fromCode($content); - $classNamespace = $namespaceExtractor->extract($tokens); - $className = $classNameExtractor->extract($tokens); + try { + $classNamespace = $namespaceExtractor->extract($tokens); + $className = $classNameExtractor->extract($tokens); + } catch (ExtractionException $e) { + throw new ExtractionException( + 'File is not a class file, ignoring.', $e->getCode(), $e + ); + } $classFullName = sprintf('%s\%s', $classNamespace, $className); $useDeclarations = $useDeclarationExtractor->extract($tokens);