1<?php 2 3namespace dokuwiki\test\Parsing\ParserMode; 4 5use dokuwiki\Parsing\ModeRegistry; 6use dokuwiki\Parsing\ParserMode\GfmEmphasisStrong; 7 8/** 9 * Tests for the GFM em-wrapping-strong mode (`***text***`). 10 * 11 * Only the exact 3+3 symmetric variant is handled. Longer symmetric runs 12 * (4+4, 6+6, ...) and asymmetric variants fall through to other modes or 13 * stay literal. 14 */ 15class GfmEmphasisStrongTest extends ParserTestBase 16{ 17 public function setUp(): void 18 { 19 parent::setUp(); 20 global $conf; 21 $conf['syntax'] = 'markdown'; 22 ModeRegistry::reset(); 23 } 24 25 public function tearDown(): void 26 { 27 ModeRegistry::reset(); 28 parent::tearDown(); 29 } 30 31 function testBasic() 32 { 33 $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong()); 34 $this->P->parse('Foo ***Bar*** Baz'); 35 $calls = [ 36 ['document_start', []], 37 ['p_open', []], 38 ['cdata', ["\nFoo "]], 39 ['emphasis_open', []], 40 ['strong_open', []], 41 ['cdata', ['Bar']], 42 ['strong_close', []], 43 ['emphasis_close', []], 44 ['cdata', [' Baz']], 45 ['p_close', []], 46 ['document_end', []], 47 ]; 48 $this->assertCalls($calls, $this->H->calls); 49 } 50 51 function testSingleCharacter() 52 { 53 $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong()); 54 $this->P->parse('***a***'); 55 $modes = array_column($this->H->calls, 0); 56 $this->assertContains('emphasis_open', $modes); 57 $this->assertContains('strong_open', $modes); 58 $this->assertContains('strong_close', $modes); 59 $this->assertContains('emphasis_close', $modes); 60 } 61 62 function testLeadingWhitespaceDoesNotMatch() 63 { 64 $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong()); 65 $this->P->parse('*** foo***'); 66 $this->assertNotContains('emphasis_open', array_column($this->H->calls, 0)); 67 } 68 69 function testTrailingWhitespaceDoesNotMatch() 70 { 71 $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong()); 72 $this->P->parse('***foo ***'); 73 $this->assertNotContains('emphasis_open', array_column($this->H->calls, 0)); 74 } 75 76 function testDoesNotSpanParagraphBoundary() 77 { 78 $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong()); 79 $this->P->parse("***foo\n\nbar***"); 80 $this->assertNotContains('emphasis_open', array_column($this->H->calls, 0)); 81 } 82 83 function testLongerSymmetricRunDoesNotMatch() 84 { 85 // `****foo****` has 4 asterisks each side. The entry pattern requires 86 // the opener run to be exactly 3 (via `(?<!\*)` and `(?!\*)` on the 87 // closer), so this mode doesn't fire. It falls through to other 88 // modes (which is tested via the full spec suite). 89 $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong()); 90 $this->P->parse('****foo****'); 91 $this->assertNotContains('emphasis_open', array_column($this->H->calls, 0)); 92 } 93 94 function testAsymmetricDoesNotMatch() 95 { 96 // `***foo**` has 3 asterisks on the left but only 2 on the right. 97 // The entry's closing-delimiter lookahead requires exactly 3 `*`s 98 // not followed by another `*`, so there's no valid closer. 99 $this->P->addMode('gfm_emphasis_strong', new GfmEmphasisStrong()); 100 $this->P->parse('***foo**'); 101 $this->assertNotContains('emphasis_open', array_column($this->H->calls, 0)); 102 } 103 104 function testSortValue() 105 { 106 $this->assertSame(65, (new GfmEmphasisStrong())->getSort()); 107 } 108} 109