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