|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace Tests\Feature; |
| 4 | + |
| 5 | +use App\Http\Controllers\ShowDocumentationController; |
| 6 | +use Tests\TestCase; |
| 7 | + |
| 8 | +class DocumentationTableOfContentsTest extends TestCase |
| 9 | +{ |
| 10 | + public function test_extracts_headings_from_rendered_html(): void |
| 11 | + { |
| 12 | + $html = '<h2 id="installation"><a href="#installation"><span>#</span></a>Installation</h2>' |
| 13 | + .'<p>Some text.</p>' |
| 14 | + .'<h3 id="sub-heading"><a href="#sub-heading"><span>#</span></a>Sub Heading</h3>'; |
| 15 | + |
| 16 | + $controller = new ShowDocumentationController; |
| 17 | + |
| 18 | + $result = $this->invokeMethod($controller, 'extractTableOfContents', [$html]); |
| 19 | + |
| 20 | + $this->assertCount(2, $result); |
| 21 | + $this->assertEquals(['level' => 2, 'title' => 'Installation', 'anchor' => 'installation'], $result[0]); |
| 22 | + $this->assertEquals(['level' => 3, 'title' => 'Sub Heading', 'anchor' => 'sub-heading'], $result[1]); |
| 23 | + } |
| 24 | + |
| 25 | + public function test_anchors_match_heading_ids_for_inline_code(): void |
| 26 | + { |
| 27 | + $html = '<h2 id="using-codeconfigcode"><a href="#using-codeconfigcode"><span>#</span></a>Using <code>config()</code></h2>'; |
| 28 | + |
| 29 | + $controller = new ShowDocumentationController; |
| 30 | + |
| 31 | + $result = $this->invokeMethod($controller, 'extractTableOfContents', [$html]); |
| 32 | + |
| 33 | + $this->assertCount(1, $result); |
| 34 | + $this->assertEquals('using-codeconfigcode', $result[0]['anchor']); |
| 35 | + $this->assertEquals('Using config()', $result[0]['title']); |
| 36 | + } |
| 37 | + |
| 38 | + public function test_returns_empty_array_when_no_headings(): void |
| 39 | + { |
| 40 | + $html = '<p>Just a paragraph.</p>'; |
| 41 | + |
| 42 | + $controller = new ShowDocumentationController; |
| 43 | + |
| 44 | + $result = $this->invokeMethod($controller, 'extractTableOfContents', [$html]); |
| 45 | + |
| 46 | + $this->assertEmpty($result); |
| 47 | + } |
| 48 | + |
| 49 | + public function test_decodes_html_entities_in_title(): void |
| 50 | + { |
| 51 | + $html = '<h2 id="installation-amp-setup"><a href="#installation-amp-setup"><span>#</span></a>Installation & Setup</h2>'; |
| 52 | + |
| 53 | + $controller = new ShowDocumentationController; |
| 54 | + |
| 55 | + $result = $this->invokeMethod($controller, 'extractTableOfContents', [$html]); |
| 56 | + |
| 57 | + $this->assertCount(1, $result); |
| 58 | + $this->assertEquals('Installation & Setup', $result[0]['title']); |
| 59 | + } |
| 60 | + |
| 61 | + public function test_ignores_h1_and_h4_headings(): void |
| 62 | + { |
| 63 | + $html = '<h1 id="title"><a href="#title"><span>#</span></a>Title</h1>' |
| 64 | + .'<h2 id="section"><a href="#section"><span>#</span></a>Section</h2>' |
| 65 | + .'<h4 id="deep"><a href="#deep"><span>#</span></a>Deep</h4>'; |
| 66 | + |
| 67 | + $controller = new ShowDocumentationController; |
| 68 | + |
| 69 | + $result = $this->invokeMethod($controller, 'extractTableOfContents', [$html]); |
| 70 | + |
| 71 | + $this->assertCount(1, $result); |
| 72 | + $this->assertEquals('section', $result[0]['anchor']); |
| 73 | + } |
| 74 | + |
| 75 | + /** |
| 76 | + * @param array<mixed> $args |
| 77 | + */ |
| 78 | + protected function invokeMethod(object $object, string $method, array $args = []): mixed |
| 79 | + { |
| 80 | + $reflection = new \ReflectionMethod($object, $method); |
| 81 | + |
| 82 | + return $reflection->invoke($object, ...$args); |
| 83 | + } |
| 84 | +} |
0 commit comments