10244be5cSAndreas Gohr<?php 20244be5cSAndreas Gohr 30244be5cSAndreas Gohrnamespace dokuwiki\test\Parsing\ParserMode; 40244be5cSAndreas Gohr 50244be5cSAndreas Gohruse dokuwiki\Parsing\ParserMode\GfmDeleted; 60244be5cSAndreas Gohr 70244be5cSAndreas Gohr/** 80244be5cSAndreas Gohr * Tests for the GFM strikethrough mode (`~~text~~`). 90244be5cSAndreas Gohr */ 100244be5cSAndreas Gohrclass GfmDeletedTest extends ParserTestBase 110244be5cSAndreas Gohr{ 120244be5cSAndreas Gohr public function setUp(): void 130244be5cSAndreas Gohr { 140244be5cSAndreas Gohr parent::setUp(); 15*47a02a10SAndreas Gohr $this->setSyntax('md'); 160244be5cSAndreas Gohr } 170244be5cSAndreas Gohr 180244be5cSAndreas Gohr function testBasicStrikethrough() 190244be5cSAndreas Gohr { 200244be5cSAndreas Gohr $this->P->addMode('gfm_deleted', new GfmDeleted()); 210244be5cSAndreas Gohr $this->P->parse('Foo ~~Bar~~ Baz'); 220244be5cSAndreas Gohr $calls = [ 230244be5cSAndreas Gohr ['document_start', []], 240244be5cSAndreas Gohr ['p_open', []], 250244be5cSAndreas Gohr ['cdata', ["\nFoo "]], 260244be5cSAndreas Gohr ['deleted_open', []], 270244be5cSAndreas Gohr ['cdata', ['Bar']], 280244be5cSAndreas Gohr ['deleted_close', []], 290244be5cSAndreas Gohr ['cdata', [' Baz']], 300244be5cSAndreas Gohr ['p_close', []], 310244be5cSAndreas Gohr ['document_end', []], 320244be5cSAndreas Gohr ]; 330244be5cSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 340244be5cSAndreas Gohr } 350244be5cSAndreas Gohr 360244be5cSAndreas Gohr function testSingleCharacterBody() 370244be5cSAndreas Gohr { 380244be5cSAndreas Gohr $this->P->addMode('gfm_deleted', new GfmDeleted()); 390244be5cSAndreas Gohr $this->P->parse('foo ~~b~~ bar'); 400244be5cSAndreas Gohr $calls = [ 410244be5cSAndreas Gohr ['document_start', []], 420244be5cSAndreas Gohr ['p_open', []], 430244be5cSAndreas Gohr ['cdata', ["\nfoo "]], 440244be5cSAndreas Gohr ['deleted_open', []], 450244be5cSAndreas Gohr ['cdata', ['b']], 460244be5cSAndreas Gohr ['deleted_close', []], 470244be5cSAndreas Gohr ['cdata', [' bar']], 480244be5cSAndreas Gohr ['p_close', []], 490244be5cSAndreas Gohr ['document_end', []], 500244be5cSAndreas Gohr ]; 510244be5cSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 520244be5cSAndreas Gohr } 530244be5cSAndreas Gohr 540244be5cSAndreas Gohr function testMultipleWords() 550244be5cSAndreas Gohr { 560244be5cSAndreas Gohr $this->P->addMode('gfm_deleted', new GfmDeleted()); 570244be5cSAndreas Gohr $this->P->parse('~~three four five~~'); 580244be5cSAndreas Gohr $calls = [ 590244be5cSAndreas Gohr ['document_start', []], 600244be5cSAndreas Gohr ['p_open', []], 610244be5cSAndreas Gohr ['cdata', ["\n"]], 620244be5cSAndreas Gohr ['deleted_open', []], 630244be5cSAndreas Gohr ['cdata', ['three four five']], 640244be5cSAndreas Gohr ['deleted_close', []], 650244be5cSAndreas Gohr ['cdata', ['']], 660244be5cSAndreas Gohr ['p_close', []], 670244be5cSAndreas Gohr ['document_end', []], 680244be5cSAndreas Gohr ]; 690244be5cSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 700244be5cSAndreas Gohr } 710244be5cSAndreas Gohr 720244be5cSAndreas Gohr function testTwoSeparateStrikethroughsOnOneLine() 730244be5cSAndreas Gohr { 740244be5cSAndreas Gohr $this->P->addMode('gfm_deleted', new GfmDeleted()); 750244be5cSAndreas Gohr $this->P->parse('~~one~~ and ~~two~~'); 760244be5cSAndreas Gohr $calls = [ 770244be5cSAndreas Gohr ['document_start', []], 780244be5cSAndreas Gohr ['p_open', []], 790244be5cSAndreas Gohr ['cdata', ["\n"]], 800244be5cSAndreas Gohr ['deleted_open', []], 810244be5cSAndreas Gohr ['cdata', ['one']], 820244be5cSAndreas Gohr ['deleted_close', []], 830244be5cSAndreas Gohr ['cdata', [' and ']], 840244be5cSAndreas Gohr ['deleted_open', []], 850244be5cSAndreas Gohr ['cdata', ['two']], 860244be5cSAndreas Gohr ['deleted_close', []], 870244be5cSAndreas Gohr ['cdata', ['']], 880244be5cSAndreas Gohr ['p_close', []], 890244be5cSAndreas Gohr ['document_end', []], 900244be5cSAndreas Gohr ]; 910244be5cSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 920244be5cSAndreas Gohr } 930244be5cSAndreas Gohr 940244be5cSAndreas Gohr function testUnmatchedOpenerDoesNotStrike() 950244be5cSAndreas Gohr { 960244be5cSAndreas Gohr $this->P->addMode('gfm_deleted', new GfmDeleted()); 970244be5cSAndreas Gohr $this->P->parse('foo ~~bar with no closer'); 980244be5cSAndreas Gohr $calls = [ 990244be5cSAndreas Gohr ['document_start', []], 1000244be5cSAndreas Gohr ['p_open', []], 1010244be5cSAndreas Gohr ['cdata', ["\nfoo ~~bar with no closer"]], 1020244be5cSAndreas Gohr ['p_close', []], 1030244be5cSAndreas Gohr ['document_end', []], 1040244be5cSAndreas Gohr ]; 1050244be5cSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 1060244be5cSAndreas Gohr } 1070244be5cSAndreas Gohr 1080244be5cSAndreas Gohr function testOpenerFollowedBySpaceDoesNotStrike() 1090244be5cSAndreas Gohr { 1100244be5cSAndreas Gohr $this->P->addMode('gfm_deleted', new GfmDeleted()); 1110244be5cSAndreas Gohr $this->P->parse('foo ~~ bar~~ baz'); 1120244be5cSAndreas Gohr $calls = [ 1130244be5cSAndreas Gohr ['document_start', []], 1140244be5cSAndreas Gohr ['p_open', []], 1150244be5cSAndreas Gohr ['cdata', ["\nfoo ~~ bar~~ baz"]], 1160244be5cSAndreas Gohr ['p_close', []], 1170244be5cSAndreas Gohr ['document_end', []], 1180244be5cSAndreas Gohr ]; 1190244be5cSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 1200244be5cSAndreas Gohr } 1210244be5cSAndreas Gohr 1220244be5cSAndreas Gohr function testEmptyDelimiterDoesNotStrike() 1230244be5cSAndreas Gohr { 1240244be5cSAndreas Gohr $this->P->addMode('gfm_deleted', new GfmDeleted()); 1250244be5cSAndreas Gohr $this->P->parse('foo ~~~~ bar'); 1260244be5cSAndreas Gohr $modes = array_column($this->H->calls, 0); 1270244be5cSAndreas Gohr $this->assertNotContains('deleted_open', $modes, 1280244be5cSAndreas Gohr 'Empty `~~~~` must stay literal'); 1290244be5cSAndreas Gohr } 1300244be5cSAndreas Gohr 1310244be5cSAndreas Gohr function testTripleTildeDoesNotStrike() 1320244be5cSAndreas Gohr { 1330244be5cSAndreas Gohr // `~~~` is the GFM fenced-code-block marker; strikethrough must not 1340244be5cSAndreas Gohr // consume a run of three or more tildes. 1350244be5cSAndreas Gohr $this->P->addMode('gfm_deleted', new GfmDeleted()); 1360244be5cSAndreas Gohr $this->P->parse('foo ~~~bar~~~ baz'); 1370244be5cSAndreas Gohr $modes = array_column($this->H->calls, 0); 1380244be5cSAndreas Gohr $this->assertNotContains('deleted_open', $modes, 1390244be5cSAndreas Gohr 'Run of 3+ tildes must not trigger strikethrough'); 1400244be5cSAndreas Gohr } 1410244be5cSAndreas Gohr 1420244be5cSAndreas Gohr function testMultilineStrikethrough() 1430244be5cSAndreas Gohr { 1440244be5cSAndreas Gohr $this->P->addMode('gfm_deleted', new GfmDeleted()); 1450244be5cSAndreas Gohr $this->P->parse("~~line\nline\nline~~"); 1460244be5cSAndreas Gohr $calls = [ 1470244be5cSAndreas Gohr ['document_start', []], 1480244be5cSAndreas Gohr ['p_open', []], 1490244be5cSAndreas Gohr ['cdata', ["\n"]], 1500244be5cSAndreas Gohr ['deleted_open', []], 1510244be5cSAndreas Gohr ['cdata', ["line\nline\nline"]], 1520244be5cSAndreas Gohr ['deleted_close', []], 1530244be5cSAndreas Gohr ['cdata', ['']], 1540244be5cSAndreas Gohr ['p_close', []], 1550244be5cSAndreas Gohr ['document_end', []], 1560244be5cSAndreas Gohr ]; 1570244be5cSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 1580244be5cSAndreas Gohr } 1590244be5cSAndreas Gohr 1600244be5cSAndreas Gohr function testDoesNotSpanParagraphBoundary() 1610244be5cSAndreas Gohr { 1620244be5cSAndreas Gohr // An unclosed `~~` followed by a blank line must stay literal. 1630244be5cSAndreas Gohr // Mirrors GFM spec example 492. 1640244be5cSAndreas Gohr $this->P->addMode('gfm_deleted', new GfmDeleted()); 1650244be5cSAndreas Gohr $this->P->parse("This ~~has a\n\nnew paragraph~~."); 1660244be5cSAndreas Gohr $modes = array_column($this->H->calls, 0); 1670244be5cSAndreas Gohr $this->assertNotContains('deleted_open', $modes, 1680244be5cSAndreas Gohr 'GfmDeleted must not open when the closing `~~` is past a blank line'); 1690244be5cSAndreas Gohr } 1700244be5cSAndreas Gohr 1710244be5cSAndreas Gohr function testAllowsSingleNewline() 1720244be5cSAndreas Gohr { 1730244be5cSAndreas Gohr $this->P->addMode('gfm_deleted', new GfmDeleted()); 1740244be5cSAndreas Gohr $this->P->parse("~~open\nclose~~"); 1750244be5cSAndreas Gohr $modes = array_column($this->H->calls, 0); 1760244be5cSAndreas Gohr $this->assertContains('deleted_open', $modes, 1770244be5cSAndreas Gohr 'GfmDeleted must still match across a single newline'); 1780244be5cSAndreas Gohr } 1790244be5cSAndreas Gohr 1800244be5cSAndreas Gohr function testTrailingWhitespaceBeforeCloserDoesNotStrike() 1810244be5cSAndreas Gohr { 1820244be5cSAndreas Gohr $this->P->addMode('gfm_deleted', new GfmDeleted()); 1830244be5cSAndreas Gohr $this->P->parse('~~foo bar ~~'); 1840244be5cSAndreas Gohr $modes = array_column($this->H->calls, 0); 1850244be5cSAndreas Gohr $this->assertNotContains('deleted_open', $modes, 1860244be5cSAndreas Gohr 'Closer preceded by whitespace must not match'); 1870244be5cSAndreas Gohr } 1880244be5cSAndreas Gohr 1890244be5cSAndreas Gohr function testSortValue() 1900244be5cSAndreas Gohr { 1910244be5cSAndreas Gohr $mode = new GfmDeleted(); 1920244be5cSAndreas Gohr $this->assertSame(130, $mode->getSort()); 1930244be5cSAndreas Gohr } 1940244be5cSAndreas Gohr} 195