171096e46SAndreas Gohr<?php 271096e46SAndreas Gohr 371096e46SAndreas Gohrnamespace dokuwiki\test\Parsing; 471096e46SAndreas Gohr 571096e46SAndreas Gohruse dokuwiki\Parsing\Handler; 671096e46SAndreas Gohruse dokuwiki\Parsing\ParserMode\ModeInterface; 771096e46SAndreas Gohr 871096e46SAndreas Gohrclass HandlerTest extends \DokuWikiTest 971096e46SAndreas Gohr{ 1071096e46SAndreas Gohr function testGetModeNameReturnsOriginalName() 1171096e46SAndreas Gohr { 1271096e46SAndreas Gohr $handler = new Handler(); 1371096e46SAndreas Gohr 1471096e46SAndreas Gohr // create a simple mode that records what getModeName() returns 1571096e46SAndreas Gohr $mode = new class extends \dokuwiki\Parsing\ParserMode\AbstractMode { 1671096e46SAndreas Gohr public $receivedModeName = ''; 1771096e46SAndreas Gohr public function getSort() { return 0; } 1871096e46SAndreas Gohr public function handle($match, $state, $pos, Handler $handler) 1971096e46SAndreas Gohr { 2071096e46SAndreas Gohr $this->receivedModeName = $handler->getModeName(); 2171096e46SAndreas Gohr return true; 2271096e46SAndreas Gohr } 2371096e46SAndreas Gohr }; 2471096e46SAndreas Gohr 2571096e46SAndreas Gohr $handler->registerModeObject('resolved', $mode); 2671096e46SAndreas Gohr 2771096e46SAndreas Gohr // simulate dispatch with a remapped name (original differs from resolved) 2871096e46SAndreas Gohr $handler->handleToken('resolved', 'test', DOKU_LEXER_SPECIAL, 0, 'original'); 2971096e46SAndreas Gohr 3071096e46SAndreas Gohr $this->assertSame('original', $mode->receivedModeName); 3171096e46SAndreas Gohr } 3271096e46SAndreas Gohr 3371096e46SAndreas Gohr function testGetModeNameFallsBackToModeName() 3471096e46SAndreas Gohr { 3571096e46SAndreas Gohr $handler = new Handler(); 3671096e46SAndreas Gohr 3771096e46SAndreas Gohr $mode = new class extends \dokuwiki\Parsing\ParserMode\AbstractMode { 3871096e46SAndreas Gohr public $receivedModeName = ''; 3971096e46SAndreas Gohr public function getSort() { return 0; } 4071096e46SAndreas Gohr public function handle($match, $state, $pos, Handler $handler) 4171096e46SAndreas Gohr { 4271096e46SAndreas Gohr $this->receivedModeName = $handler->getModeName(); 4371096e46SAndreas Gohr return true; 4471096e46SAndreas Gohr } 4571096e46SAndreas Gohr }; 4671096e46SAndreas Gohr 4771096e46SAndreas Gohr $handler->registerModeObject('mymode', $mode); 4871096e46SAndreas Gohr 4971096e46SAndreas Gohr // no original name passed — should fall back to the resolved name 5071096e46SAndreas Gohr $handler->handleToken('mymode', 'test', DOKU_LEXER_SPECIAL, 0); 5171096e46SAndreas Gohr 5271096e46SAndreas Gohr $this->assertSame('mymode', $mode->receivedModeName); 5371096e46SAndreas Gohr } 54*36ba8eadSAndreas Gohr 55*36ba8eadSAndreas Gohr /** 56*36ba8eadSAndreas Gohr * Regression test for #4637 57*36ba8eadSAndreas Gohr * 58*36ba8eadSAndreas Gohr * handleToken() must route plugin_* modes through plugin() even when 59*36ba8eadSAndreas Gohr * the same name is also registered as a mode object. 60*36ba8eadSAndreas Gohr * 61*36ba8eadSAndreas Gohr * Before the fix, modeObjects was consulted first, which called 62*36ba8eadSAndreas Gohr * SyntaxPlugin::handle() directly. That returns data but never 63*36ba8eadSAndreas Gohr * emits an instruction via addPluginCall(), so the plugin's rendered 64*36ba8eadSAndreas Gohr * output silently disappeared. 65*36ba8eadSAndreas Gohr */ 66*36ba8eadSAndreas Gohr function testPluginModeIsRoutedThroughPluginHandler() 67*36ba8eadSAndreas Gohr { 68*36ba8eadSAndreas Gohr $handler = new Handler(); 69*36ba8eadSAndreas Gohr 70*36ba8eadSAndreas Gohr // Plugins register themselves as mode objects under their plugin_* name. 71*36ba8eadSAndreas Gohr // This reproduces the conflict the bug depended on. 72*36ba8eadSAndreas Gohr $info = plugin_load('syntax', 'info'); 73*36ba8eadSAndreas Gohr $this->assertNotNull($info, 'info plugin must be available for this test'); 74*36ba8eadSAndreas Gohr $handler->registerModeObject('plugin_info', $info); 75*36ba8eadSAndreas Gohr 76*36ba8eadSAndreas Gohr $handler->handleToken('plugin_info', '~~INFO:datetime~~', DOKU_LEXER_SPECIAL, 0); 77*36ba8eadSAndreas Gohr 78*36ba8eadSAndreas Gohr // After the fix, plugin() runs and emits a plugin instruction. 79*36ba8eadSAndreas Gohr // With the bug, modeObjects['plugin_info']->handle() ran and emitted nothing. 80*36ba8eadSAndreas Gohr $this->assertCount(1, $handler->calls, 'plugin mode must emit exactly one instruction'); 81*36ba8eadSAndreas Gohr [$name, $args] = $handler->calls[0]; 82*36ba8eadSAndreas Gohr $this->assertSame('plugin', $name); 83*36ba8eadSAndreas Gohr $this->assertSame('info', $args[0]); 84*36ba8eadSAndreas Gohr $this->assertSame(['datetime'], $args[1]); 85*36ba8eadSAndreas Gohr $this->assertSame('~~INFO:datetime~~', $args[3]); 86*36ba8eadSAndreas Gohr } 8771096e46SAndreas Gohr} 88