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