xref: /dokuwiki/_test/tests/Parsing/ParserMode/GfmEmphasisTest.php (revision 884caed926ca0aa0af6ce3f34ae3aa7317a3361a)
1<?php
2
3namespace dokuwiki\test\Parsing\ParserMode;
4
5use dokuwiki\Parsing\ParserMode\GfmEmphasis;
6
7/**
8 * Tests for the GFM asterisk emphasis mode (`*text*`).
9 */
10class GfmEmphasisTest extends ParserTestBase
11{
12    public function setUp(): void
13    {
14        parent::setUp();
15        $this->setSyntax('md');
16    }
17
18    function testBasicAsterisk()
19    {
20        $this->P->addMode('gfm_emphasis', new GfmEmphasis());
21        $this->P->parse('Foo *Bar* Baz');
22        $calls = [
23            ['document_start', []],
24            ['p_open', []],
25            ['cdata', ["\nFoo "]],
26            ['emphasis_open', []],
27            ['cdata', ['Bar']],
28            ['emphasis_close', []],
29            ['cdata', [' Baz']],
30            ['p_close', []],
31            ['document_end', []],
32        ];
33        $this->assertCalls($calls, $this->H->calls);
34    }
35
36    function testSingleCharacter()
37    {
38        $this->P->addMode('gfm_emphasis', new GfmEmphasis());
39        $this->P->parse('foo *b* bar');
40        $calls = [
41            ['document_start', []],
42            ['p_open', []],
43            ['cdata', ["\nfoo "]],
44            ['emphasis_open', []],
45            ['cdata', ['b']],
46            ['emphasis_close', []],
47            ['cdata', [' bar']],
48            ['p_close', []],
49            ['document_end', []],
50        ];
51        $this->assertCalls($calls, $this->H->calls);
52    }
53
54    function testMultipleWords()
55    {
56        $this->P->addMode('gfm_emphasis', new GfmEmphasis());
57        $this->P->parse('*three four five*');
58        $calls = [
59            ['document_start', []],
60            ['p_open', []],
61            ['cdata', ["\n"]],
62            ['emphasis_open', []],
63            ['cdata', ['three four five']],
64            ['emphasis_close', []],
65            ['cdata', ['']],
66            ['p_close', []],
67            ['document_end', []],
68        ];
69        $this->assertCalls($calls, $this->H->calls);
70    }
71
72    function testTwoSeparateEmphasisOnOneLine()
73    {
74        $this->P->addMode('gfm_emphasis', new GfmEmphasis());
75        $this->P->parse('*one* and *two*');
76        $calls = [
77            ['document_start', []],
78            ['p_open', []],
79            ['cdata', ["\n"]],
80            ['emphasis_open', []],
81            ['cdata', ['one']],
82            ['emphasis_close', []],
83            ['cdata', [' and ']],
84            ['emphasis_open', []],
85            ['cdata', ['two']],
86            ['emphasis_close', []],
87            ['cdata', ['']],
88            ['p_close', []],
89            ['document_end', []],
90        ];
91        $this->assertCalls($calls, $this->H->calls);
92    }
93
94    function testUnmatchedOpenerDoesNotEmphasise()
95    {
96        $this->P->addMode('gfm_emphasis', new GfmEmphasis());
97        $this->P->parse('foo *bar with no closer');
98        $calls = [
99            ['document_start', []],
100            ['p_open', []],
101            ['cdata', ["\nfoo *bar with no closer"]],
102            ['p_close', []],
103            ['document_end', []],
104        ];
105        $this->assertCalls($calls, $this->H->calls);
106    }
107
108    function testOpenerFollowedBySpaceDoesNotEmphasise()
109    {
110        $this->P->addMode('gfm_emphasis', new GfmEmphasis());
111        $this->P->parse('foo * bar* baz');
112        $calls = [
113            ['document_start', []],
114            ['p_open', []],
115            ['cdata', ["\nfoo * bar* baz"]],
116            ['p_close', []],
117            ['document_end', []],
118        ];
119        $this->assertCalls($calls, $this->H->calls);
120    }
121
122    function testEmptyDelimiterDoesNotEmphasise()
123    {
124        $this->P->addMode('gfm_emphasis', new GfmEmphasis());
125        $this->P->parse('foo ** bar');
126        $calls = [
127            ['document_start', []],
128            ['p_open', []],
129            ['cdata', ["\nfoo ** bar"]],
130            ['p_close', []],
131            ['document_end', []],
132        ];
133        $this->assertCalls($calls, $this->H->calls);
134    }
135
136    function testUnderscoreIsNotEmphasised()
137    {
138        // GfmEmphasis handles `*` only — `_` is reserved to avoid the
139        // `__underline__` conflict with DokuWiki's underline syntax;
140        // GfmEmphasisUnderscore handles `_` separately when MD-preferred.
141        $this->P->addMode('gfm_emphasis', new GfmEmphasis());
142        $this->P->parse('foo _bar_ baz');
143        $calls = [
144            ['document_start', []],
145            ['p_open', []],
146            ['cdata', ["\nfoo _bar_ baz"]],
147            ['p_close', []],
148            ['document_end', []],
149        ];
150        $this->assertCalls($calls, $this->H->calls);
151    }
152
153    function testMultilineEmphasis()
154    {
155        $this->P->addMode('gfm_emphasis', new GfmEmphasis());
156        $this->P->parse("*line\nline\nline*");
157        $calls = [
158            ['document_start', []],
159            ['p_open', []],
160            ['cdata', ["\n"]],
161            ['emphasis_open', []],
162            ['cdata', ["line\nline\nline"]],
163            ['emphasis_close', []],
164            ['cdata', ['']],
165            ['p_close', []],
166            ['document_end', []],
167        ];
168        $this->assertCalls($calls, $this->H->calls);
169    }
170
171    function testModeNameIsDistinctFromInstructionName()
172    {
173        // The lexer mode is registered as 'gfm_emphasis' (to avoid collision
174        // with DW Emphasis), but instructions are 'emphasis_open/close'
175        // so the existing XHTML renderer emits <em>.
176        $mode = new GfmEmphasis();
177        $this->assertSame(80, $mode->getSort());
178    }
179
180    function testDoesNotSpanParagraphBoundary()
181    {
182        // An unclosed `*` followed by a blank line must stay literal — the
183        // entry pattern's lookahead is paragraph-boundary-safe.
184        $this->P->addMode('gfm_emphasis', new GfmEmphasis());
185        $this->P->parse("*open\n\nclose*");
186        $modes = array_column($this->H->calls, 0);
187        $this->assertNotContains('emphasis_open', $modes,
188            'GfmEmphasis must not open when the closing `*` is past a blank line');
189    }
190
191    function testAllowsSingleNewline()
192    {
193        // Single newlines are fine inside emphasis (multi-line emphasis).
194        $this->P->addMode('gfm_emphasis', new GfmEmphasis());
195        $this->P->parse("*open\nclose*");
196        $modes = array_column($this->H->calls, 0);
197        $this->assertContains('emphasis_open', $modes,
198            'GfmEmphasis must still match across a single newline');
199    }
200}
201