diff --git a/src/AbstractOpenAPIObjectVisitor.php b/src/AbstractOpenAPIObjectVisitor.php new file mode 100644 index 00000000..13d24af9 --- /dev/null +++ b/src/AbstractOpenAPIObjectVisitor.php @@ -0,0 +1,14 @@ +enterType($type); + $this->enterType($type, $path); $propertiesWithNodes = $this->getNodes($type); @@ -23,28 +23,28 @@ public function traverse($type): void $node = $type->$propertyWithNode; if (! is_array($node)) { - $this->traverse($node); + $this->traverse($node, [...$path, $propertyWithNode]); } else { - foreach ($node as $item) { - $this->traverse($item); + foreach ($node as $i => $item) { + $this->traverse($item, [...$path, $propertyWithNode, $i]); } } } - $this->leaveType($type); + $this->leaveType($type, $path); } - private function enterType($type): void + private function enterType($type, $path): void { foreach ($this->visitors as $visitor) { - $visitor->enter($type); + $visitor->enter($type, $path); } } - private function leaveType($type): void + private function leaveType($type, $path): void { foreach ($this->visitors as $visitor) { - $visitor->leave($type); + $visitor->leave($type, $path); } } diff --git a/tests/OpenAPITraverserTest.php b/tests/OpenAPITraverserTest.php new file mode 100644 index 00000000..d661dcc2 --- /dev/null +++ b/tests/OpenAPITraverserTest.php @@ -0,0 +1,35 @@ +setInfo(new InfoObject(title: 'app')); + $document->addPath($path = new Path('/test')); + $path->addOperation(new Operation('GET')); + + $traverser = new \Dedoc\Scramble\OpenAPITraverser([ + $visitor = new class extends AbstractOpenAPIObjectVisitor { + public array $paths = []; + /** @inheritdoc */ + public function enter($object, $path = []) + { + $this->paths[] = join('.', $path); + } + } + ]); + + $traverser->traverse($document); + + expect($visitor->paths)->toBe([ + '#', + '#.info', + '#.components', + '#.paths.0', + '#.paths.0.operations.GET', + ]); +});