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