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