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