xref: /dokuwiki/_test/tests/Parsing/ParserMode/GfmHrTest.php (revision 13a62f810fbd091d15ab734b467eaec0a6bf829a)
1<?php
2
3namespace dokuwiki\test\Parsing\ParserMode;
4
5use dokuwiki\Parsing\ModeRegistry;
6use dokuwiki\Parsing\ParserMode\Eol;
7use dokuwiki\Parsing\ParserMode\GfmHr;
8
9/**
10 * Tests for the unified horizontal-rule mode.
11 *
12 * Covers both pattern flavors: pure `dw` (4-or-more dashes only)
13 * and the wider GFM flavor that loads in `md`, `dw+md`, `md+dw`
14 * (3-or-more of `-` / `*` / `_`). No leading, trailing, or internal
15 * whitespace tolerance in either flavor.
16 */
17class GfmHrTest extends ParserTestBase
18{
19    public function setUp(): void
20    {
21        parent::setUp();
22        ModeRegistry::reset();
23    }
24
25    public function tearDown(): void
26    {
27        ModeRegistry::reset();
28        parent::tearDown();
29    }
30
31    protected function setSyntax(string $syntax): void
32    {
33        global $conf;
34        $conf['syntax'] = $syntax;
35    }
36
37    /**
38     * Whether at least one `hr` call was emitted for the given input
39     * under the given syntax. Returns the call count for richer
40     * assertion messages.
41     */
42    protected function countHrCalls(string $syntax, string $input): int
43    {
44        $this->setUp();
45        $this->setSyntax($syntax);
46        $this->P->addMode('gfm_hr', new GfmHr());
47        $this->P->parse($input);
48        return count(array_filter($this->H->calls, static fn($c) => $c[0] === 'hr'));
49    }
50
51    // ------------------------------------------------------------------
52    // DW flavor (`$conf['syntax'] = 'dw'`)
53    // ------------------------------------------------------------------
54
55    public function testDwFourDashes()
56    {
57        $this->assertSame(1, $this->countHrCalls('dw', "\n----\n"));
58    }
59
60    public function testDwManyDashes()
61    {
62        $this->assertSame(1, $this->countHrCalls('dw', "\n--------\n"));
63    }
64
65    public function testDwThreeDashesNotHr()
66    {
67        $this->assertSame(0, $this->countHrCalls('dw', "\n---\n"));
68    }
69
70    public function testDwAsterisksNotHr()
71    {
72        $this->assertSame(0, $this->countHrCalls('dw', "\n***\n"));
73        $this->assertSame(0, $this->countHrCalls('dw', "\n********\n"));
74    }
75
76    public function testDwUnderscoresNotHr()
77    {
78        $this->assertSame(0, $this->countHrCalls('dw', "\n___\n"));
79        $this->assertSame(0, $this->countHrCalls('dw', "\n_____\n"));
80    }
81
82    public function testDwLeadingSpaceNotHr()
83    {
84        $this->assertSame(0, $this->countHrCalls('dw', "\n ----\n"));
85    }
86
87    public function testDwTrailingSpaceNotHr()
88    {
89        $this->assertSame(0, $this->countHrCalls('dw', "\n---- \n"));
90    }
91
92    public function testDwInterruptsParagraph()
93    {
94        $this->setSyntax('dw');
95        $this->P->addMode('gfm_hr', new GfmHr());
96        $this->P->parse("Foo\n----\nBar");
97        $calls = [
98            ['document_start', []],
99            ['p_open', []],
100            ['cdata', ["\nFoo"]],
101            ['p_close', []],
102            ['hr', []],
103            ['p_open', []],
104            ['cdata', ["\nBar"]],
105            ['p_close', []],
106            ['document_end', []],
107        ];
108        $this->assertCalls($calls, $this->H->calls);
109    }
110
111    // ------------------------------------------------------------------
112    // GFM flavor (any non-`dw` syntax setting)
113    // ------------------------------------------------------------------
114
115    public function testMdDashes()
116    {
117        foreach (['md', 'dw+md', 'md+dw'] as $syntax) {
118            $this->assertSame(1, $this->countHrCalls($syntax, "\n---\n"),
119                "syntax=$syntax: bare `---` must produce hr");
120        }
121    }
122
123    public function testMdAsterisks()
124    {
125        foreach (['md', 'dw+md', 'md+dw'] as $syntax) {
126            $this->assertSame(1, $this->countHrCalls($syntax, "\n***\n"),
127                "syntax=$syntax: bare `***` must produce hr");
128        }
129    }
130
131    public function testMdUnderscores()
132    {
133        foreach (['md', 'dw+md', 'md+dw'] as $syntax) {
134            $this->assertSame(1, $this->countHrCalls($syntax, "\n___\n"),
135                "syntax=$syntax: bare `___` must produce hr");
136        }
137    }
138
139    public function testMdManyChars()
140    {
141        $this->assertSame(1, $this->countHrCalls('md', "\n--------\n"));
142        $this->assertSame(1, $this->countHrCalls('md', "\n********\n"));
143        $this->assertSame(1, $this->countHrCalls('md', "\n________\n"));
144    }
145
146    public function testMdTooFew()
147    {
148        $this->assertSame(0, $this->countHrCalls('md', "\n--\n"));
149        $this->assertSame(0, $this->countHrCalls('md', "\n**\n"));
150        $this->assertSame(0, $this->countHrCalls('md', "\n__\n"));
151    }
152
153    public function testMdInternalSpacesNotSupported()
154    {
155        $this->assertSame(0, $this->countHrCalls('md', "\n- - -\n"));
156        $this->assertSame(0, $this->countHrCalls('md', "\n* * *\n"));
157        $this->assertSame(0, $this->countHrCalls('md', "\n_ _ _\n"));
158    }
159
160    public function testMdLeadingSpaceNotSupported()
161    {
162        $this->assertSame(0, $this->countHrCalls('md', "\n ***\n"));
163        $this->assertSame(0, $this->countHrCalls('md', "\n   ---\n"));
164    }
165
166    public function testMdTrailingSpaceNotSupported()
167    {
168        $this->assertSame(0, $this->countHrCalls('md', "\n--- \n"));
169    }
170
171    public function testMdMixedChars()
172    {
173        $this->assertSame(0, $this->countHrCalls('md', "\n-*-\n"));
174        $this->assertSame(0, $this->countHrCalls('md', "\n***---\n"));
175    }
176
177    public function testMdLetterMixed()
178    {
179        $this->assertSame(0, $this->countHrCalls('md', "\n---a\n"));
180        $this->assertSame(0, $this->countHrCalls('md', "\na---\n"));
181        $this->assertSame(0, $this->countHrCalls('md', "\n---a---\n"));
182    }
183
184    public function testMdInterruptsParagraph()
185    {
186        $this->setSyntax('md');
187        $this->P->addMode('gfm_hr', new GfmHr());
188        $this->P->addMode('eol', new Eol());
189        $this->P->parse("Foo\n***\nbar");
190        $modes = array_column($this->H->calls, 0);
191        $this->assertContains('hr', $modes,
192            'thematic break interrupts paragraph without blank line (spec 28)');
193    }
194
195    // ------------------------------------------------------------------
196    // Common
197    // ------------------------------------------------------------------
198
199    public function testSortValue()
200    {
201        $mode = new GfmHr();
202        $this->assertSame(160, $mode->getSort());
203    }
204}
205