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