1<?php 2 3namespace dokuwiki\test\Parsing\ParserMode; 4 5use dokuwiki\Parsing\ParserMode\GfmStrongUnderscore; 6 7/** 8 * Tests for GFM strong emphasis via double underscores (`__text__`). 9 */ 10class GfmStrongUnderscoreTest extends ParserTestBase 11{ 12 public function setUp(): void 13 { 14 parent::setUp(); 15 $this->setSyntax('md'); 16 } 17 18 function testBasic() 19 { 20 $this->P->addMode('gfm_strong_underscore', new GfmStrongUnderscore()); 21 $this->P->parse('Foo __Bar__ Baz'); 22 $calls = [ 23 ['document_start', []], 24 ['p_open', []], 25 ['cdata', ["\nFoo "]], 26 ['strong_open', []], 27 ['cdata', ['Bar']], 28 ['strong_close', []], 29 ['cdata', [' Baz']], 30 ['p_close', []], 31 ['document_end', []], 32 ]; 33 $this->assertCalls($calls, $this->H->calls); 34 } 35 36 function testSingleCharacter() 37 { 38 $this->P->addMode('gfm_strong_underscore', new GfmStrongUnderscore()); 39 $this->P->parse('__x__'); 40 $modes = array_column($this->H->calls, 0); 41 $this->assertContains('strong_open', $modes); 42 $this->assertContains('strong_close', $modes); 43 } 44 45 function testMultipleWords() 46 { 47 $this->P->addMode('gfm_strong_underscore', new GfmStrongUnderscore()); 48 $this->P->parse('__one two three__'); 49 $modes = array_column($this->H->calls, 0); 50 $this->assertContains('strong_open', $modes); 51 } 52 53 function testIntrawordDoesNotOpen() 54 { 55 // `foo__bar__` — opening `__` intraword (preceded by `o`). 56 $this->P->addMode('gfm_strong_underscore', new GfmStrongUnderscore()); 57 $this->P->parse('foo__bar__'); 58 $this->assertNotContains('strong_open', array_column($this->H->calls, 0)); 59 } 60 61 function testLeadingWhitespaceDoesNotOpen() 62 { 63 $this->P->addMode('gfm_strong_underscore', new GfmStrongUnderscore()); 64 $this->P->parse('__ foo bar__'); 65 $this->assertNotContains('strong_open', array_column($this->H->calls, 0)); 66 } 67 68 function testTrailingWhitespaceDoesNotClose() 69 { 70 $this->P->addMode('gfm_strong_underscore', new GfmStrongUnderscore()); 71 $this->P->parse('__foo bar __'); 72 $this->assertNotContains('strong_open', array_column($this->H->calls, 0)); 73 } 74 75 function testEmptyDelimiterDoesNotMatch() 76 { 77 $this->P->addMode('gfm_strong_underscore', new GfmStrongUnderscore()); 78 $this->P->parse('____'); 79 $this->assertNotContains('strong_open', array_column($this->H->calls, 0)); 80 } 81 82 function testMultibyteIntrawordDoesNotMatch() 83 { 84 // Cyrillic spec example: `пристаням__стремятся__` — intraword, literal. 85 $this->P->addMode('gfm_strong_underscore', new GfmStrongUnderscore()); 86 $this->P->parse('пристаням__стремятся__'); 87 $this->assertNotContains('strong_open', array_column($this->H->calls, 0)); 88 } 89 90 function testMultibyteContentInsideStrongWorks() 91 { 92 $this->P->addMode('gfm_strong_underscore', new GfmStrongUnderscore()); 93 $this->P->parse('foo __für etwas__ bar'); 94 $this->assertContains('strong_open', array_column($this->H->calls, 0)); 95 $this->assertContains('strong_close', array_column($this->H->calls, 0)); 96 } 97 98 function testDoesNotSpanParagraphBoundary() 99 { 100 $this->P->addMode('gfm_strong_underscore', new GfmStrongUnderscore()); 101 $this->P->parse("__open\n\nclose__"); 102 $this->assertNotContains('strong_open', array_column($this->H->calls, 0)); 103 } 104 105 function testSortValue() 106 { 107 $this->assertSame(70, (new GfmStrongUnderscore())->getSort()); 108 } 109 110 function testInstructionNameIsStrong() 111 { 112 // The mode name is distinct (so it coexists with DW Strong in the 113 // lexer) but it must emit the same `strong_open`/`strong_close` 114 // instructions so the XHTML renderer outputs <strong>. 115 $this->P->addMode('gfm_strong_underscore', new GfmStrongUnderscore()); 116 $this->P->parse('__x__'); 117 $modes = array_column($this->H->calls, 0); 118 $this->assertContains('strong_open', $modes); 119 $this->assertNotContains('gfm_strong_underscore_open', $modes); 120 } 121} 122