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