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