1*3e6baeffSAndreas Gohr<?php 2*3e6baeffSAndreas Gohr 3*3e6baeffSAndreas Gohrnamespace dokuwiki\test\Parsing\ParserMode; 4*3e6baeffSAndreas Gohr 5*3e6baeffSAndreas Gohruse dokuwiki\Parsing\ModeRegistry; 6*3e6baeffSAndreas Gohruse dokuwiki\Parsing\ParserMode\Eol; 7*3e6baeffSAndreas Gohruse dokuwiki\Parsing\ParserMode\GfmHr; 8*3e6baeffSAndreas Gohr 9*3e6baeffSAndreas Gohr/** 10*3e6baeffSAndreas Gohr * Tests for the unified horizontal-rule mode. 11*3e6baeffSAndreas Gohr * 12*3e6baeffSAndreas Gohr * Covers both pattern flavors: pure `dokuwiki` (4-or-more dashes only) 13*3e6baeffSAndreas Gohr * and the wider GFM flavor that loads in `markdown`, `dw+md`, `md+dw` 14*3e6baeffSAndreas Gohr * (3-or-more of `-` / `*` / `_`). No leading, trailing, or internal 15*3e6baeffSAndreas Gohr * whitespace tolerance in either flavor. 16*3e6baeffSAndreas Gohr */ 17*3e6baeffSAndreas Gohrclass GfmHrTest extends ParserTestBase 18*3e6baeffSAndreas Gohr{ 19*3e6baeffSAndreas Gohr public function setUp(): void 20*3e6baeffSAndreas Gohr { 21*3e6baeffSAndreas Gohr parent::setUp(); 22*3e6baeffSAndreas Gohr ModeRegistry::reset(); 23*3e6baeffSAndreas Gohr } 24*3e6baeffSAndreas Gohr 25*3e6baeffSAndreas Gohr public function tearDown(): void 26*3e6baeffSAndreas Gohr { 27*3e6baeffSAndreas Gohr ModeRegistry::reset(); 28*3e6baeffSAndreas Gohr parent::tearDown(); 29*3e6baeffSAndreas Gohr } 30*3e6baeffSAndreas Gohr 31*3e6baeffSAndreas Gohr protected function setSyntax(string $syntax): void 32*3e6baeffSAndreas Gohr { 33*3e6baeffSAndreas Gohr global $conf; 34*3e6baeffSAndreas Gohr $conf['syntax'] = $syntax; 35*3e6baeffSAndreas Gohr } 36*3e6baeffSAndreas Gohr 37*3e6baeffSAndreas Gohr /** 38*3e6baeffSAndreas Gohr * Whether at least one `hr` call was emitted for the given input 39*3e6baeffSAndreas Gohr * under the given syntax. Returns the call count for richer 40*3e6baeffSAndreas Gohr * assertion messages. 41*3e6baeffSAndreas Gohr */ 42*3e6baeffSAndreas Gohr protected function countHrCalls(string $syntax, string $input): int 43*3e6baeffSAndreas Gohr { 44*3e6baeffSAndreas Gohr $this->setUp(); 45*3e6baeffSAndreas Gohr $this->setSyntax($syntax); 46*3e6baeffSAndreas Gohr $this->P->addMode('gfm_hr', new GfmHr()); 47*3e6baeffSAndreas Gohr $this->P->parse($input); 48*3e6baeffSAndreas Gohr return count(array_filter($this->H->calls, static fn($c) => $c[0] === 'hr')); 49*3e6baeffSAndreas Gohr } 50*3e6baeffSAndreas Gohr 51*3e6baeffSAndreas Gohr // ------------------------------------------------------------------ 52*3e6baeffSAndreas Gohr // DW flavor (`$conf['syntax'] = 'dokuwiki'`) 53*3e6baeffSAndreas Gohr // ------------------------------------------------------------------ 54*3e6baeffSAndreas Gohr 55*3e6baeffSAndreas Gohr public function testDwFourDashes() 56*3e6baeffSAndreas Gohr { 57*3e6baeffSAndreas Gohr $this->assertSame(1, $this->countHrCalls('dokuwiki', "\n----\n")); 58*3e6baeffSAndreas Gohr } 59*3e6baeffSAndreas Gohr 60*3e6baeffSAndreas Gohr public function testDwManyDashes() 61*3e6baeffSAndreas Gohr { 62*3e6baeffSAndreas Gohr $this->assertSame(1, $this->countHrCalls('dokuwiki', "\n--------\n")); 63*3e6baeffSAndreas Gohr } 64*3e6baeffSAndreas Gohr 65*3e6baeffSAndreas Gohr public function testDwThreeDashesNotHr() 66*3e6baeffSAndreas Gohr { 67*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('dokuwiki', "\n---\n")); 68*3e6baeffSAndreas Gohr } 69*3e6baeffSAndreas Gohr 70*3e6baeffSAndreas Gohr public function testDwAsterisksNotHr() 71*3e6baeffSAndreas Gohr { 72*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('dokuwiki', "\n***\n")); 73*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('dokuwiki', "\n********\n")); 74*3e6baeffSAndreas Gohr } 75*3e6baeffSAndreas Gohr 76*3e6baeffSAndreas Gohr public function testDwUnderscoresNotHr() 77*3e6baeffSAndreas Gohr { 78*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('dokuwiki', "\n___\n")); 79*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('dokuwiki', "\n_____\n")); 80*3e6baeffSAndreas Gohr } 81*3e6baeffSAndreas Gohr 82*3e6baeffSAndreas Gohr public function testDwLeadingSpaceNotHr() 83*3e6baeffSAndreas Gohr { 84*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('dokuwiki', "\n ----\n")); 85*3e6baeffSAndreas Gohr } 86*3e6baeffSAndreas Gohr 87*3e6baeffSAndreas Gohr public function testDwTrailingSpaceNotHr() 88*3e6baeffSAndreas Gohr { 89*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('dokuwiki', "\n---- \n")); 90*3e6baeffSAndreas Gohr } 91*3e6baeffSAndreas Gohr 92*3e6baeffSAndreas Gohr public function testDwInterruptsParagraph() 93*3e6baeffSAndreas Gohr { 94*3e6baeffSAndreas Gohr $this->setSyntax('dokuwiki'); 95*3e6baeffSAndreas Gohr $this->P->addMode('gfm_hr', new GfmHr()); 96*3e6baeffSAndreas Gohr $this->P->parse("Foo\n----\nBar"); 97*3e6baeffSAndreas Gohr $calls = [ 98*3e6baeffSAndreas Gohr ['document_start', []], 99*3e6baeffSAndreas Gohr ['p_open', []], 100*3e6baeffSAndreas Gohr ['cdata', ["\nFoo"]], 101*3e6baeffSAndreas Gohr ['p_close', []], 102*3e6baeffSAndreas Gohr ['hr', []], 103*3e6baeffSAndreas Gohr ['p_open', []], 104*3e6baeffSAndreas Gohr ['cdata', ["\nBar"]], 105*3e6baeffSAndreas Gohr ['p_close', []], 106*3e6baeffSAndreas Gohr ['document_end', []], 107*3e6baeffSAndreas Gohr ]; 108*3e6baeffSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 109*3e6baeffSAndreas Gohr } 110*3e6baeffSAndreas Gohr 111*3e6baeffSAndreas Gohr // ------------------------------------------------------------------ 112*3e6baeffSAndreas Gohr // GFM flavor (any non-`dokuwiki` syntax setting) 113*3e6baeffSAndreas Gohr // ------------------------------------------------------------------ 114*3e6baeffSAndreas Gohr 115*3e6baeffSAndreas Gohr public function testMdDashes() 116*3e6baeffSAndreas Gohr { 117*3e6baeffSAndreas Gohr foreach (['markdown', 'dw+md', 'md+dw'] as $syntax) { 118*3e6baeffSAndreas Gohr $this->assertSame(1, $this->countHrCalls($syntax, "\n---\n"), 119*3e6baeffSAndreas Gohr "syntax=$syntax: bare `---` must produce hr"); 120*3e6baeffSAndreas Gohr } 121*3e6baeffSAndreas Gohr } 122*3e6baeffSAndreas Gohr 123*3e6baeffSAndreas Gohr public function testMdAsterisks() 124*3e6baeffSAndreas Gohr { 125*3e6baeffSAndreas Gohr foreach (['markdown', 'dw+md', 'md+dw'] as $syntax) { 126*3e6baeffSAndreas Gohr $this->assertSame(1, $this->countHrCalls($syntax, "\n***\n"), 127*3e6baeffSAndreas Gohr "syntax=$syntax: bare `***` must produce hr"); 128*3e6baeffSAndreas Gohr } 129*3e6baeffSAndreas Gohr } 130*3e6baeffSAndreas Gohr 131*3e6baeffSAndreas Gohr public function testMdUnderscores() 132*3e6baeffSAndreas Gohr { 133*3e6baeffSAndreas Gohr foreach (['markdown', 'dw+md', 'md+dw'] as $syntax) { 134*3e6baeffSAndreas Gohr $this->assertSame(1, $this->countHrCalls($syntax, "\n___\n"), 135*3e6baeffSAndreas Gohr "syntax=$syntax: bare `___` must produce hr"); 136*3e6baeffSAndreas Gohr } 137*3e6baeffSAndreas Gohr } 138*3e6baeffSAndreas Gohr 139*3e6baeffSAndreas Gohr public function testMdManyChars() 140*3e6baeffSAndreas Gohr { 141*3e6baeffSAndreas Gohr $this->assertSame(1, $this->countHrCalls('markdown', "\n--------\n")); 142*3e6baeffSAndreas Gohr $this->assertSame(1, $this->countHrCalls('markdown', "\n********\n")); 143*3e6baeffSAndreas Gohr $this->assertSame(1, $this->countHrCalls('markdown', "\n________\n")); 144*3e6baeffSAndreas Gohr } 145*3e6baeffSAndreas Gohr 146*3e6baeffSAndreas Gohr public function testMdTooFew() 147*3e6baeffSAndreas Gohr { 148*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n--\n")); 149*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n**\n")); 150*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n__\n")); 151*3e6baeffSAndreas Gohr } 152*3e6baeffSAndreas Gohr 153*3e6baeffSAndreas Gohr public function testMdInternalSpacesNotSupported() 154*3e6baeffSAndreas Gohr { 155*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n- - -\n")); 156*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n* * *\n")); 157*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n_ _ _\n")); 158*3e6baeffSAndreas Gohr } 159*3e6baeffSAndreas Gohr 160*3e6baeffSAndreas Gohr public function testMdLeadingSpaceNotSupported() 161*3e6baeffSAndreas Gohr { 162*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n ***\n")); 163*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n ---\n")); 164*3e6baeffSAndreas Gohr } 165*3e6baeffSAndreas Gohr 166*3e6baeffSAndreas Gohr public function testMdTrailingSpaceNotSupported() 167*3e6baeffSAndreas Gohr { 168*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n--- \n")); 169*3e6baeffSAndreas Gohr } 170*3e6baeffSAndreas Gohr 171*3e6baeffSAndreas Gohr public function testMdMixedChars() 172*3e6baeffSAndreas Gohr { 173*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n-*-\n")); 174*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n***---\n")); 175*3e6baeffSAndreas Gohr } 176*3e6baeffSAndreas Gohr 177*3e6baeffSAndreas Gohr public function testMdLetterMixed() 178*3e6baeffSAndreas Gohr { 179*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n---a\n")); 180*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\na---\n")); 181*3e6baeffSAndreas Gohr $this->assertSame(0, $this->countHrCalls('markdown', "\n---a---\n")); 182*3e6baeffSAndreas Gohr } 183*3e6baeffSAndreas Gohr 184*3e6baeffSAndreas Gohr public function testMdInterruptsParagraph() 185*3e6baeffSAndreas Gohr { 186*3e6baeffSAndreas Gohr $this->setSyntax('markdown'); 187*3e6baeffSAndreas Gohr $this->P->addMode('gfm_hr', new GfmHr()); 188*3e6baeffSAndreas Gohr $this->P->addMode('eol', new Eol()); 189*3e6baeffSAndreas Gohr $this->P->parse("Foo\n***\nbar"); 190*3e6baeffSAndreas Gohr $modes = array_column($this->H->calls, 0); 191*3e6baeffSAndreas Gohr $this->assertContains('hr', $modes, 192*3e6baeffSAndreas Gohr 'thematic break interrupts paragraph without blank line (spec 28)'); 193*3e6baeffSAndreas Gohr } 194*3e6baeffSAndreas Gohr 195*3e6baeffSAndreas Gohr // ------------------------------------------------------------------ 196*3e6baeffSAndreas Gohr // Common 197*3e6baeffSAndreas Gohr // ------------------------------------------------------------------ 198*3e6baeffSAndreas Gohr 199*3e6baeffSAndreas Gohr public function testSortValue() 200*3e6baeffSAndreas Gohr { 201*3e6baeffSAndreas Gohr $mode = new GfmHr(); 202*3e6baeffSAndreas Gohr $this->assertSame(160, $mode->getSort()); 203*3e6baeffSAndreas Gohr } 204*3e6baeffSAndreas Gohr} 205