xref: /dokuwiki/_test/tests/Parsing/ParserMode/GfmFileTest.php (revision 13a62f810fbd091d15ab734b467eaec0a6bf829a)
1<?php
2
3namespace dokuwiki\test\Parsing\ParserMode;
4
5use dokuwiki\Parsing\ModeRegistry;
6use dokuwiki\Parsing\ParserMode\Eol;
7use dokuwiki\Parsing\ParserMode\GfmFile;
8
9/**
10 * Tests for GFM tilde-fenced code blocks (`GfmFile`).
11 */
12class GfmFileTest extends ParserTestBase
13{
14    public function setUp(): void
15    {
16        parent::setUp();
17        global $conf;
18        $conf['syntax'] = 'md';
19        ModeRegistry::reset();
20    }
21
22    public function tearDown(): void
23    {
24        ModeRegistry::reset();
25        parent::tearDown();
26    }
27
28    private function addModes(): void
29    {
30        $this->P->addMode('gfm_file', new GfmFile());
31        $this->P->addMode('eol', new Eol());
32    }
33
34    function testBasicTildeFence()
35    {
36        $this->addModes();
37        $this->P->parse("~~~\nhello\n~~~");
38        $fileCalls = array_values(array_filter(
39            $this->H->calls,
40            static fn($c) => $c[0] === 'file'
41        ));
42        $this->assertCount(1, $fileCalls);
43        $this->assertSame("hello\n", $fileCalls[0][1][0]);
44        $this->assertNull($fileCalls[0][1][1]);
45        $this->assertNull($fileCalls[0][1][2]);
46    }
47
48    function testLanguageFromInfoString()
49    {
50        $this->addModes();
51        $this->P->parse("~~~ruby\nx\n~~~");
52        $fileCalls = array_values(array_filter(
53            $this->H->calls,
54            static fn($c) => $c[0] === 'file'
55        ));
56        $this->assertCount(1, $fileCalls);
57        $this->assertSame('ruby', $fileCalls[0][1][1]);
58    }
59
60    function testTildeInfoAcceptsBackticks()
61    {
62        // GFM spec example 116: tilde fences allow backticks in the info
63        // string; first word is the language.
64        $this->addModes();
65        $this->P->parse("~~~ aa ``` ~~~\nfoo\n~~~");
66        $fileCalls = array_values(array_filter(
67            $this->H->calls,
68            static fn($c) => $c[0] === 'file'
69        ));
70        $this->assertCount(1, $fileCalls);
71        $this->assertSame('aa', $fileCalls[0][1][1]);
72    }
73
74    function testBacktickLineDoesNotCloseTildeFence()
75    {
76        $this->addModes();
77        $this->P->parse("~~~\naaa\n```\nbbb\n~~~");
78        $fileCalls = array_values(array_filter(
79            $this->H->calls,
80            static fn($c) => $c[0] === 'file'
81        ));
82        $this->assertCount(1, $fileCalls);
83        $this->assertSame("aaa\n```\nbbb\n", $fileCalls[0][1][0]);
84    }
85
86    function testUnclosedFenceStaysLiteral()
87    {
88        // Unclosed fences stay literal — same rule as GfmCode. See
89        // GfmCode class docblock for the rationale.
90        $this->addModes();
91        $this->P->parse("~~~\nabc\ndef");
92        $modes = array_column($this->H->calls, 0);
93        $this->assertNotContains('file', $modes,
94            'Unclosed tilde fences must stay literal, not emit file');
95    }
96
97    function testEmptyBody()
98    {
99        $this->addModes();
100        $this->P->parse("~~~\n~~~");
101        $fileCalls = array_values(array_filter(
102            $this->H->calls,
103            static fn($c) => $c[0] === 'file'
104        ));
105        $this->assertCount(1, $fileCalls);
106        $this->assertSame('', $fileCalls[0][1][0]);
107    }
108
109    function testSortValue()
110    {
111        $this->assertSame(210, (new GfmFile())->getSort());
112    }
113}
114