xref: /dokuwiki/_test/tests/Parsing/ParserMode/GfmEmphasisStrongTest.php (revision fe58309edafb067d90f3f40ef3d416100d558a04)
1<?php
2
3namespace dokuwiki\test\Parsing\ParserMode;
4
5use dokuwiki\Parsing\ParserMode\GfmEmphasisStrong;
6
7/**
8 * Tests for the GFM em-wrapping-strong mode (`***text***`).
9 *
10 * Only the exact 3+3 symmetric variant is handled. Longer symmetric runs
11 * (4+4, 6+6, ...) and asymmetric variants fall through to other modes or
12 * stay literal.
13 */
14class GfmEmphasisStrongTest extends ParserTestBase
15{
16    public function setUp(): void
17    {
18        parent::setUp();
19        $this->setSyntax('md');
20    }
21
22    public function testBasic()
23    {
24        $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong());
25        $this->P->parse('Foo ***Bar*** Baz');
26
27        $calls = [
28            ['document_start', []],
29            ['p_open', []],
30            ['cdata', ["\nFoo "]],
31            ['emphasis_open', []],
32            ['strong_open', []],
33            ['cdata', ['Bar']],
34            ['strong_close', []],
35            ['emphasis_close', []],
36            ['cdata', [' Baz']],
37            ['p_close', []],
38            ['document_end', []],
39        ];
40        $this->assertCalls($calls, $this->H->calls);
41    }
42
43    public function testSingleCharacter()
44    {
45        $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong());
46        $this->P->parse('***a***');
47
48        $modes = array_column($this->H->calls, 0);
49        $this->assertContains('emphasis_open', $modes);
50        $this->assertContains('strong_open', $modes);
51        $this->assertContains('strong_close', $modes);
52        $this->assertContains('emphasis_close', $modes);
53    }
54
55    public function testLeadingWhitespaceDoesNotMatch()
56    {
57        $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong());
58        $this->P->parse('*** foo***');
59        $this->assertNotContains('emphasis_open', array_column($this->H->calls, 0));
60    }
61
62    public function testTrailingWhitespaceDoesNotMatch()
63    {
64        $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong());
65        $this->P->parse('***foo ***');
66        $this->assertNotContains('emphasis_open', array_column($this->H->calls, 0));
67    }
68
69    public function testDoesNotSpanParagraphBoundary()
70    {
71        $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong());
72        $this->P->parse("***foo\n\nbar***");
73        $this->assertNotContains('emphasis_open', array_column($this->H->calls, 0));
74    }
75
76    public function testLongerSymmetricRunDoesNotMatch()
77    {
78        // `****foo****` has 4 asterisks each side. The entry pattern requires
79        // the opener run to be exactly 3 (via `(?<!\*)` and `(?!\*)` on the
80        // closer), so this mode doesn't fire. It falls through to other
81        // modes (which is tested via the full spec suite).
82        $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong());
83        $this->P->parse('****foo****');
84        $this->assertNotContains('emphasis_open', array_column($this->H->calls, 0));
85    }
86
87    public function testAsymmetricDoesNotMatch()
88    {
89        // `***foo**` has 3 asterisks on the left but only 2 on the right.
90        // The entry's closing-delimiter lookahead requires exactly 3 `*`s
91        // not followed by another `*`, so there's no valid closer.
92        $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong());
93        $this->P->parse('***foo**');
94        $this->assertNotContains('emphasis_open', array_column($this->H->calls, 0));
95    }
96
97    public function testSortValue()
98    {
99        $this->assertSame(65, (new GfmEmphasisStrong())->getSort());
100    }
101
102    public function testRejectedOpenerBeforeValidSpanStaysLiteral()
103    {
104        $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong());
105        $this->P->parse('*** foo ***bar***');
106        $this->assertContains('emphasis_open', array_column($this->H->calls, 0));
107        $this->assertStringContainsString('*** foo ', $this->H->calls[2][1][0]);
108    }
109}
110