1<?php 2 3namespace dokuwiki\test\Parsing\Markdown; 4 5class SpecReaderTest extends \DokuWikiTest 6{ 7 /** Where to write a throwaway fixture. TMP_DIR is created by the test 8 * bootstrap and removed by its shutdown handler — no per-test cleanup 9 * needed. */ 10 private const FIXTURE_PATH = TMP_DIR . '/spec-reader-test.txt'; 11 12 private function writeFixture(string $content): SpecReader 13 { 14 file_put_contents(self::FIXTURE_PATH, $content); 15 return new SpecReader(self::FIXTURE_PATH); 16 } 17 18 public function testSingleOrdinaryExample() 19 { 20 $reader = $this->writeFixture(<<<SPEC 21## Simple Headings 22 23`````````` example 24# foo 25. 26<h1>foo</h1> 27`````````` 28 29trailing prose 30SPEC); 31 32 $examples = iterator_to_array($reader->examples(), false); 33 $this->assertCount(1, $examples); 34 $this->assertSame(1, $examples[0]['number']); 35 $this->assertSame('Simple Headings', $examples[0]['section']); 36 $this->assertNull($examples[0]['extension']); 37 $this->assertSame("# foo", $examples[0]['markdown']); 38 $this->assertSame("<h1>foo</h1>", $examples[0]['html']); 39 } 40 41 public function testSectionTracking() 42 { 43 $reader = $this->writeFixture(<<<SPEC 44## Section One 45 46`````````` example 47a 48. 49<p>a</p> 50`````````` 51 52## Section Two 53 54`````````` example 55b 56. 57<p>b</p> 58`````````` 59SPEC); 60 61 $examples = iterator_to_array($reader->examples(), false); 62 $this->assertCount(2, $examples); 63 $this->assertSame(1, $examples[0]['number']); 64 $this->assertSame('Section One', $examples[0]['section']); 65 $this->assertSame(2, $examples[1]['number']); 66 $this->assertSame('Section Two', $examples[1]['section']); 67 } 68 69 public function testExampleWithExtensionLabel() 70 { 71 $reader = $this->writeFixture(<<<SPEC 72## Tables 73 74`````````` example table 75| a | b | 76| - | - | 77| 1 | 2 | 78. 79<table>…</table> 80`````````` 81SPEC); 82 83 $examples = iterator_to_array($reader->examples(), false); 84 $this->assertCount(1, $examples); 85 $this->assertSame('table', $examples[0]['extension']); 86 $this->assertStringContainsString('| a | b |', $examples[0]['markdown']); 87 } 88 89 public function testMultilineMarkdownAndHtml() 90 { 91 $reader = $this->writeFixture(<<<SPEC 92## Multiline 93 94`````````` example 95line one 96line two 97 98line four 99. 100<p>line one 101line two</p> 102<p>line four</p> 103`````````` 104SPEC); 105 106 $examples = iterator_to_array($reader->examples(), false); 107 $this->assertSame( 108 "line one\nline two\n\nline four", 109 $examples[0]['markdown'] 110 ); 111 $this->assertSame( 112 "<p>line one\nline two</p>\n<p>line four</p>", 113 $examples[0]['html'] 114 ); 115 } 116 117 public function testBackticksInsideExampleAreNotConfusedForFence() 118 { 119 // Opening fence is 14 backticks; a shorter run inside must not close. 120 $reader = $this->writeFixture(<<<SPEC 121## Code 122 123`````````````` example 124here is `code` with backticks 125. 126<p>here is <code>code</code> with backticks</p> 127`````````````` 128SPEC); 129 130 $examples = iterator_to_array($reader->examples(), false); 131 $this->assertCount(1, $examples); 132 $this->assertStringContainsString('`code`', $examples[0]['markdown']); 133 } 134 135 public function testNumbersAreSequential() 136 { 137 $body = ''; 138 for ($i = 1; $i <= 5; $i++) { 139 $body .= "`````````` example\nmd$i\n.\nhtml$i\n``````````\n\n"; 140 } 141 $reader = $this->writeFixture($body); 142 $examples = iterator_to_array($reader->examples(), false); 143 $this->assertCount(5, $examples); 144 foreach ($examples as $i => $ex) { 145 $this->assertSame($i + 1, $ex['number']); 146 } 147 } 148 149 public function testUnclosedFenceThrows() 150 { 151 $reader = $this->writeFixture(<<<SPEC 152`````````` example 153no closer ever arrives 154. 155<p>x</p> 156SPEC); 157 $this->expectException(\RuntimeException::class); 158 iterator_to_array($reader->examples(), false); 159 } 160 161 public function testMissingFileThrows() 162 { 163 $reader = new SpecReader('/nonexistent/path/spec.txt'); 164 $this->expectException(\RuntimeException::class); 165 iterator_to_array($reader->examples(), false); 166 } 167} 168