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