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