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