xref: /dokuwiki/_test/tests/Parsing/ParserMode/GfmDeletedTest.php (revision 0244be5c08829b6ca187d7158bca94e7c2fd7be3)
1*0244be5cSAndreas Gohr<?php
2*0244be5cSAndreas Gohr
3*0244be5cSAndreas Gohrnamespace dokuwiki\test\Parsing\ParserMode;
4*0244be5cSAndreas Gohr
5*0244be5cSAndreas Gohruse dokuwiki\Parsing\ModeRegistry;
6*0244be5cSAndreas Gohruse dokuwiki\Parsing\ParserMode\GfmDeleted;
7*0244be5cSAndreas Gohr
8*0244be5cSAndreas Gohr/**
9*0244be5cSAndreas Gohr * Tests for the GFM strikethrough mode (`~~text~~`).
10*0244be5cSAndreas Gohr */
11*0244be5cSAndreas Gohrclass GfmDeletedTest extends ParserTestBase
12*0244be5cSAndreas Gohr{
13*0244be5cSAndreas Gohr    public function setUp(): void
14*0244be5cSAndreas Gohr    {
15*0244be5cSAndreas Gohr        parent::setUp();
16*0244be5cSAndreas Gohr        global $conf;
17*0244be5cSAndreas Gohr        $conf['syntax'] = 'markdown';
18*0244be5cSAndreas Gohr        ModeRegistry::reset();
19*0244be5cSAndreas Gohr    }
20*0244be5cSAndreas Gohr
21*0244be5cSAndreas Gohr    public function tearDown(): void
22*0244be5cSAndreas Gohr    {
23*0244be5cSAndreas Gohr        ModeRegistry::reset();
24*0244be5cSAndreas Gohr        parent::tearDown();
25*0244be5cSAndreas Gohr    }
26*0244be5cSAndreas Gohr
27*0244be5cSAndreas Gohr    function testBasicStrikethrough()
28*0244be5cSAndreas Gohr    {
29*0244be5cSAndreas Gohr        $this->P->addMode('gfm_deleted', new GfmDeleted());
30*0244be5cSAndreas Gohr        $this->P->parse('Foo ~~Bar~~ Baz');
31*0244be5cSAndreas Gohr        $calls = [
32*0244be5cSAndreas Gohr            ['document_start', []],
33*0244be5cSAndreas Gohr            ['p_open', []],
34*0244be5cSAndreas Gohr            ['cdata', ["\nFoo "]],
35*0244be5cSAndreas Gohr            ['deleted_open', []],
36*0244be5cSAndreas Gohr            ['cdata', ['Bar']],
37*0244be5cSAndreas Gohr            ['deleted_close', []],
38*0244be5cSAndreas Gohr            ['cdata', [' Baz']],
39*0244be5cSAndreas Gohr            ['p_close', []],
40*0244be5cSAndreas Gohr            ['document_end', []],
41*0244be5cSAndreas Gohr        ];
42*0244be5cSAndreas Gohr        $this->assertCalls($calls, $this->H->calls);
43*0244be5cSAndreas Gohr    }
44*0244be5cSAndreas Gohr
45*0244be5cSAndreas Gohr    function testSingleCharacterBody()
46*0244be5cSAndreas Gohr    {
47*0244be5cSAndreas Gohr        $this->P->addMode('gfm_deleted', new GfmDeleted());
48*0244be5cSAndreas Gohr        $this->P->parse('foo ~~b~~ bar');
49*0244be5cSAndreas Gohr        $calls = [
50*0244be5cSAndreas Gohr            ['document_start', []],
51*0244be5cSAndreas Gohr            ['p_open', []],
52*0244be5cSAndreas Gohr            ['cdata', ["\nfoo "]],
53*0244be5cSAndreas Gohr            ['deleted_open', []],
54*0244be5cSAndreas Gohr            ['cdata', ['b']],
55*0244be5cSAndreas Gohr            ['deleted_close', []],
56*0244be5cSAndreas Gohr            ['cdata', [' bar']],
57*0244be5cSAndreas Gohr            ['p_close', []],
58*0244be5cSAndreas Gohr            ['document_end', []],
59*0244be5cSAndreas Gohr        ];
60*0244be5cSAndreas Gohr        $this->assertCalls($calls, $this->H->calls);
61*0244be5cSAndreas Gohr    }
62*0244be5cSAndreas Gohr
63*0244be5cSAndreas Gohr    function testMultipleWords()
64*0244be5cSAndreas Gohr    {
65*0244be5cSAndreas Gohr        $this->P->addMode('gfm_deleted', new GfmDeleted());
66*0244be5cSAndreas Gohr        $this->P->parse('~~three four five~~');
67*0244be5cSAndreas Gohr        $calls = [
68*0244be5cSAndreas Gohr            ['document_start', []],
69*0244be5cSAndreas Gohr            ['p_open', []],
70*0244be5cSAndreas Gohr            ['cdata', ["\n"]],
71*0244be5cSAndreas Gohr            ['deleted_open', []],
72*0244be5cSAndreas Gohr            ['cdata', ['three four five']],
73*0244be5cSAndreas Gohr            ['deleted_close', []],
74*0244be5cSAndreas Gohr            ['cdata', ['']],
75*0244be5cSAndreas Gohr            ['p_close', []],
76*0244be5cSAndreas Gohr            ['document_end', []],
77*0244be5cSAndreas Gohr        ];
78*0244be5cSAndreas Gohr        $this->assertCalls($calls, $this->H->calls);
79*0244be5cSAndreas Gohr    }
80*0244be5cSAndreas Gohr
81*0244be5cSAndreas Gohr    function testTwoSeparateStrikethroughsOnOneLine()
82*0244be5cSAndreas Gohr    {
83*0244be5cSAndreas Gohr        $this->P->addMode('gfm_deleted', new GfmDeleted());
84*0244be5cSAndreas Gohr        $this->P->parse('~~one~~ and ~~two~~');
85*0244be5cSAndreas Gohr        $calls = [
86*0244be5cSAndreas Gohr            ['document_start', []],
87*0244be5cSAndreas Gohr            ['p_open', []],
88*0244be5cSAndreas Gohr            ['cdata', ["\n"]],
89*0244be5cSAndreas Gohr            ['deleted_open', []],
90*0244be5cSAndreas Gohr            ['cdata', ['one']],
91*0244be5cSAndreas Gohr            ['deleted_close', []],
92*0244be5cSAndreas Gohr            ['cdata', [' and ']],
93*0244be5cSAndreas Gohr            ['deleted_open', []],
94*0244be5cSAndreas Gohr            ['cdata', ['two']],
95*0244be5cSAndreas Gohr            ['deleted_close', []],
96*0244be5cSAndreas Gohr            ['cdata', ['']],
97*0244be5cSAndreas Gohr            ['p_close', []],
98*0244be5cSAndreas Gohr            ['document_end', []],
99*0244be5cSAndreas Gohr        ];
100*0244be5cSAndreas Gohr        $this->assertCalls($calls, $this->H->calls);
101*0244be5cSAndreas Gohr    }
102*0244be5cSAndreas Gohr
103*0244be5cSAndreas Gohr    function testUnmatchedOpenerDoesNotStrike()
104*0244be5cSAndreas Gohr    {
105*0244be5cSAndreas Gohr        $this->P->addMode('gfm_deleted', new GfmDeleted());
106*0244be5cSAndreas Gohr        $this->P->parse('foo ~~bar with no closer');
107*0244be5cSAndreas Gohr        $calls = [
108*0244be5cSAndreas Gohr            ['document_start', []],
109*0244be5cSAndreas Gohr            ['p_open', []],
110*0244be5cSAndreas Gohr            ['cdata', ["\nfoo ~~bar with no closer"]],
111*0244be5cSAndreas Gohr            ['p_close', []],
112*0244be5cSAndreas Gohr            ['document_end', []],
113*0244be5cSAndreas Gohr        ];
114*0244be5cSAndreas Gohr        $this->assertCalls($calls, $this->H->calls);
115*0244be5cSAndreas Gohr    }
116*0244be5cSAndreas Gohr
117*0244be5cSAndreas Gohr    function testOpenerFollowedBySpaceDoesNotStrike()
118*0244be5cSAndreas Gohr    {
119*0244be5cSAndreas Gohr        $this->P->addMode('gfm_deleted', new GfmDeleted());
120*0244be5cSAndreas Gohr        $this->P->parse('foo ~~ bar~~ baz');
121*0244be5cSAndreas Gohr        $calls = [
122*0244be5cSAndreas Gohr            ['document_start', []],
123*0244be5cSAndreas Gohr            ['p_open', []],
124*0244be5cSAndreas Gohr            ['cdata', ["\nfoo ~~ bar~~ baz"]],
125*0244be5cSAndreas Gohr            ['p_close', []],
126*0244be5cSAndreas Gohr            ['document_end', []],
127*0244be5cSAndreas Gohr        ];
128*0244be5cSAndreas Gohr        $this->assertCalls($calls, $this->H->calls);
129*0244be5cSAndreas Gohr    }
130*0244be5cSAndreas Gohr
131*0244be5cSAndreas Gohr    function testEmptyDelimiterDoesNotStrike()
132*0244be5cSAndreas Gohr    {
133*0244be5cSAndreas Gohr        $this->P->addMode('gfm_deleted', new GfmDeleted());
134*0244be5cSAndreas Gohr        $this->P->parse('foo ~~~~ bar');
135*0244be5cSAndreas Gohr        $modes = array_column($this->H->calls, 0);
136*0244be5cSAndreas Gohr        $this->assertNotContains('deleted_open', $modes,
137*0244be5cSAndreas Gohr            'Empty `~~~~` must stay literal');
138*0244be5cSAndreas Gohr    }
139*0244be5cSAndreas Gohr
140*0244be5cSAndreas Gohr    function testTripleTildeDoesNotStrike()
141*0244be5cSAndreas Gohr    {
142*0244be5cSAndreas Gohr        // `~~~` is the GFM fenced-code-block marker; strikethrough must not
143*0244be5cSAndreas Gohr        // consume a run of three or more tildes.
144*0244be5cSAndreas Gohr        $this->P->addMode('gfm_deleted', new GfmDeleted());
145*0244be5cSAndreas Gohr        $this->P->parse('foo ~~~bar~~~ baz');
146*0244be5cSAndreas Gohr        $modes = array_column($this->H->calls, 0);
147*0244be5cSAndreas Gohr        $this->assertNotContains('deleted_open', $modes,
148*0244be5cSAndreas Gohr            'Run of 3+ tildes must not trigger strikethrough');
149*0244be5cSAndreas Gohr    }
150*0244be5cSAndreas Gohr
151*0244be5cSAndreas Gohr    function testMultilineStrikethrough()
152*0244be5cSAndreas Gohr    {
153*0244be5cSAndreas Gohr        $this->P->addMode('gfm_deleted', new GfmDeleted());
154*0244be5cSAndreas Gohr        $this->P->parse("~~line\nline\nline~~");
155*0244be5cSAndreas Gohr        $calls = [
156*0244be5cSAndreas Gohr            ['document_start', []],
157*0244be5cSAndreas Gohr            ['p_open', []],
158*0244be5cSAndreas Gohr            ['cdata', ["\n"]],
159*0244be5cSAndreas Gohr            ['deleted_open', []],
160*0244be5cSAndreas Gohr            ['cdata', ["line\nline\nline"]],
161*0244be5cSAndreas Gohr            ['deleted_close', []],
162*0244be5cSAndreas Gohr            ['cdata', ['']],
163*0244be5cSAndreas Gohr            ['p_close', []],
164*0244be5cSAndreas Gohr            ['document_end', []],
165*0244be5cSAndreas Gohr        ];
166*0244be5cSAndreas Gohr        $this->assertCalls($calls, $this->H->calls);
167*0244be5cSAndreas Gohr    }
168*0244be5cSAndreas Gohr
169*0244be5cSAndreas Gohr    function testDoesNotSpanParagraphBoundary()
170*0244be5cSAndreas Gohr    {
171*0244be5cSAndreas Gohr        // An unclosed `~~` followed by a blank line must stay literal.
172*0244be5cSAndreas Gohr        // Mirrors GFM spec example 492.
173*0244be5cSAndreas Gohr        $this->P->addMode('gfm_deleted', new GfmDeleted());
174*0244be5cSAndreas Gohr        $this->P->parse("This ~~has a\n\nnew paragraph~~.");
175*0244be5cSAndreas Gohr        $modes = array_column($this->H->calls, 0);
176*0244be5cSAndreas Gohr        $this->assertNotContains('deleted_open', $modes,
177*0244be5cSAndreas Gohr            'GfmDeleted must not open when the closing `~~` is past a blank line');
178*0244be5cSAndreas Gohr    }
179*0244be5cSAndreas Gohr
180*0244be5cSAndreas Gohr    function testAllowsSingleNewline()
181*0244be5cSAndreas Gohr    {
182*0244be5cSAndreas Gohr        $this->P->addMode('gfm_deleted', new GfmDeleted());
183*0244be5cSAndreas Gohr        $this->P->parse("~~open\nclose~~");
184*0244be5cSAndreas Gohr        $modes = array_column($this->H->calls, 0);
185*0244be5cSAndreas Gohr        $this->assertContains('deleted_open', $modes,
186*0244be5cSAndreas Gohr            'GfmDeleted must still match across a single newline');
187*0244be5cSAndreas Gohr    }
188*0244be5cSAndreas Gohr
189*0244be5cSAndreas Gohr    function testTrailingWhitespaceBeforeCloserDoesNotStrike()
190*0244be5cSAndreas Gohr    {
191*0244be5cSAndreas Gohr        $this->P->addMode('gfm_deleted', new GfmDeleted());
192*0244be5cSAndreas Gohr        $this->P->parse('~~foo bar ~~');
193*0244be5cSAndreas Gohr        $modes = array_column($this->H->calls, 0);
194*0244be5cSAndreas Gohr        $this->assertNotContains('deleted_open', $modes,
195*0244be5cSAndreas Gohr            'Closer preceded by whitespace must not match');
196*0244be5cSAndreas Gohr    }
197*0244be5cSAndreas Gohr
198*0244be5cSAndreas Gohr    function testSortValue()
199*0244be5cSAndreas Gohr    {
200*0244be5cSAndreas Gohr        $mode = new GfmDeleted();
201*0244be5cSAndreas Gohr        $this->assertSame(130, $mode->getSort());
202*0244be5cSAndreas Gohr    }
203*0244be5cSAndreas Gohr}
204