[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/_test/tests/inc/parser/ -> lexer.test.php (source)

   1  <?php
   2  /**
   3  * @version $Id: lexer.todo.php,v 1.2 2005/03/25 21:00:22 harryf Exp $
   4  * @package Doku
   5  * @subpackage Tests
   6  */
   7  
   8  use dokuwiki\Parsing\Lexer\Lexer;
   9  use dokuwiki\Parsing\Lexer\ParallelRegex;
  10  use dokuwiki\Parsing\Lexer\StateStack;
  11  
  12  /**
  13  * @package Doku
  14  * @subpackage Tests
  15  */
  16  class TestOfLexerParallelRegex extends DokuWikiTest {
  17  
  18      function testNoPatterns() {
  19          $regex = new ParallelRegex(false);
  20          $this->assertFalse($regex->apply("Hello", $match));
  21          $this->assertEquals($match, "");
  22      }
  23      function testNoSubject() {
  24          $regex = new ParallelRegex(false);
  25          $regex->addPattern(".*");
  26          $this->assertTrue($regex->apply("", $match));
  27          $this->assertEquals($match, "");
  28      }
  29      function testMatchAll() {
  30          $regex = new ParallelRegex(false);
  31          $regex->addPattern(".*");
  32          $this->assertTrue($regex->apply("Hello", $match));
  33          $this->assertEquals($match, "Hello");
  34      }
  35      function testCaseSensitive() {
  36          $regex = new ParallelRegex(true);
  37          $regex->addPattern("abc");
  38          $this->assertTrue($regex->apply("abcdef", $match));
  39          $this->assertEquals($match, "abc");
  40          $this->assertTrue($regex->apply("AAABCabcdef", $match));
  41          $this->assertEquals($match, "abc");
  42      }
  43      function testCaseInsensitive() {
  44          $regex = new ParallelRegex(false);
  45          $regex->addPattern("abc");
  46          $this->assertTrue($regex->apply("abcdef", $match));
  47          $this->assertEquals($match, "abc");
  48          $this->assertTrue($regex->apply("AAABCabcdef", $match));
  49          $this->assertEquals($match, "ABC");
  50      }
  51      function testMatchMultiple() {
  52          $regex = new ParallelRegex(true);
  53          $regex->addPattern("abc");
  54          $regex->addPattern("ABC");
  55          $this->assertTrue($regex->apply("abcdef", $match));
  56          $this->assertEquals($match, "abc");
  57          $this->assertTrue($regex->apply("AAABCabcdef", $match));
  58          $this->assertEquals($match, "ABC");
  59          $this->assertFalse($regex->apply("Hello", $match));
  60      }
  61      function testPatternLabels() {
  62          $regex = new ParallelRegex(false);
  63          $regex->addPattern("abc", "letter");
  64          $regex->addPattern("123", "number");
  65          $this->assertEquals($regex->apply("abcdef", $match), "letter");
  66          $this->assertEquals($match, "abc");
  67          $this->assertEquals($regex->apply("0123456789", $match), "number");
  68          $this->assertEquals($match, "123");
  69      }
  70      function testMatchMultipleWithLookaheadNot() {
  71          $regex = new ParallelRegex(true);
  72          $regex->addPattern("abc");
  73          $regex->addPattern("ABC");
  74          $regex->addPattern("a(?!\n).{1}");
  75          $this->assertTrue($regex->apply("abcdef", $match));
  76          $this->assertEquals($match, "abc");
  77          $this->assertTrue($regex->apply("AAABCabcdef", $match));
  78          $this->assertEquals($match, "ABC");
  79          $this->assertTrue($regex->apply("a\nab", $match));
  80          $this->assertEquals($match, "ab");
  81          $this->assertFalse($regex->apply("Hello", $match));
  82      }
  83      function testMatchSetOptionCaseless() {
  84          $regex = new ParallelRegex(true);
  85          $regex->addPattern("a(?i)b(?i)c");
  86          $this->assertTrue($regex->apply("aBc", $match));
  87          $this->assertEquals($match, "aBc");
  88      }
  89      function testMatchSetOptionUngreedy() {
  90          $regex = new ParallelRegex(true);
  91          $regex->addPattern("(?U)\w+");
  92          $this->assertTrue($regex->apply("aaaaaa", $match));
  93          $this->assertEquals($match, "a");
  94      }
  95      function testMatchLookaheadEqual() {
  96          $regex = new ParallelRegex(true);
  97          $regex->addPattern("\w(?=c)");
  98          $this->assertTrue($regex->apply("xbyczd", $match));
  99          $this->assertEquals($match, "y");
 100      }
 101      function testMatchLookaheadNot() {
 102          $regex = new ParallelRegex(true);
 103          $regex->addPattern("\w(?!b|c)");
 104          $this->assertTrue($regex->apply("xbyczd", $match));
 105          $this->assertEquals($match, "b");
 106      }
 107      function testMatchLookbehindEqual() {
 108          $regex = new ParallelRegex(true);
 109          $regex->addPattern("(?<=c)\w");
 110          $this->assertTrue($regex->apply("xbyczd", $match));
 111          $this->assertEquals($match, "z");
 112      }
 113      function testMatchLookbehindNot() {
 114          $regex = new ParallelRegex(true);
 115          $regex->addPattern("(?<!\A|x|b)\w");
 116          $this->assertTrue($regex->apply("xbyczd", $match));
 117          $this->assertEquals($match, "c");
 118      }
 119  }
 120  
 121  
 122  class TestOfLexerStateStack extends DokuWikiTest {
 123      function testStartState() {
 124          $stack = new StateStack("one");
 125          $this->assertEquals($stack->getCurrent(), "one");
 126      }
 127      function testExhaustion() {
 128          $stack = new StateStack("one");
 129          $this->assertFalse($stack->leave());
 130      }
 131      function testStateMoves() {
 132          $stack = new StateStack("one");
 133          $stack->enter("two");
 134          $this->assertEquals($stack->getCurrent(), "two");
 135          $stack->enter("three");
 136          $this->assertEquals($stack->getCurrent(), "three");
 137          $this->assertTrue($stack->leave());
 138          $this->assertEquals($stack->getCurrent(), "two");
 139          $stack->enter("third");
 140          $this->assertEquals($stack->getCurrent(), "third");
 141          $this->assertTrue($stack->leave());
 142          $this->assertTrue($stack->leave());
 143          $this->assertEquals($stack->getCurrent(), "one");
 144      }
 145  }
 146  
 147  class TestParser {
 148      function __construct() {
 149      }
 150      function accept() {
 151      }
 152      function a() {
 153      }
 154      function b() {
 155      }
 156  }
 157  
 158  class TestOfLexer extends DokuWikiTest {
 159      function testNoPatterns() {
 160          $handler = $this->createMock('TestParser');
 161          $handler->expects($this->never())->method('accept');
 162          $lexer = new Lexer($handler);
 163          $this->assertFalse($lexer->parse("abcdef"));
 164      }
 165      function testEmptyPage() {
 166          $handler = $this->createMock('TestParser');
 167          $handler->expects($this->never())->method('accept');
 168          $lexer = new Lexer($handler);
 169          $lexer->addPattern("a+");
 170          $this->assertTrue($lexer->parse(""));
 171      }
 172      function testSinglePattern() {
 173          $acceptArguments = [
 174              ["aaa", DOKU_LEXER_MATCHED, 0],
 175              ["x", DOKU_LEXER_UNMATCHED, 3],
 176              ["a", DOKU_LEXER_MATCHED, 4],
 177              ["yyy", DOKU_LEXER_UNMATCHED, 5],
 178              ["a", DOKU_LEXER_MATCHED, 8],
 179              ["x", DOKU_LEXER_UNMATCHED, 9],
 180              ["aaa", DOKU_LEXER_MATCHED, 10],
 181              ["z", DOKU_LEXER_UNMATCHED, 13],
 182          ];
 183          $acceptArgumentCount = count($acceptArguments);
 184  
 185          $handler = $this->createMock('TestParser');
 186          $handler
 187              ->expects($this->exactly($acceptArgumentCount))
 188              ->method('accept')
 189              ->withConsecutive(...$acceptArguments)
 190              ->willReturnOnConsecutiveCalls(...array_fill(0, $acceptArgumentCount, true));
 191  
 192          $lexer = new Lexer($handler);
 193          $lexer->addPattern("a+");
 194          $this->assertTrue($lexer->parse("aaaxayyyaxaaaz"));
 195      }
 196      function testMultiplePattern() {
 197          $acceptArguments = [
 198              ["a", $this->anything(), 0],
 199              ["b", $this->anything(), 1],
 200              ["a", $this->anything(), 2],
 201              ["bb", $this->anything(), 3],
 202              ["x", $this->anything(), 5],
 203              ["b", $this->anything(), 6],
 204              ["a", $this->anything(), 7],
 205              ["xxxxxx", $this->anything(), 8],
 206              ["a", $this->anything(), 14],
 207              ["x", $this->anything(), 15],
 208          ];
 209          $acceptArgumentCount = count($acceptArguments);
 210  
 211          $handler = $this->createPartialMock('TestParser', ['accept']);
 212          $handler
 213              ->expects($this->exactly($acceptArgumentCount))
 214              ->method('accept')
 215              ->withConsecutive(...$acceptArguments)
 216              ->willReturnOnConsecutiveCalls(...array_fill(0, $acceptArgumentCount, true));
 217  
 218          $lexer = new Lexer($handler);
 219          $lexer->addPattern("a+");
 220          $lexer->addPattern("b+");
 221          $this->assertTrue($lexer->parse("ababbxbaxxxxxxax"));
 222      }
 223  }
 224  
 225  class TestOfLexerModes extends DokuWikiTest {
 226      function testIsolatedPattern() {
 227          $aArguments = [
 228              ["a", DOKU_LEXER_MATCHED, 0],
 229              ["b", DOKU_LEXER_UNMATCHED, 1],
 230              ["aa", DOKU_LEXER_MATCHED, 2],
 231              ["bxb", DOKU_LEXER_UNMATCHED, 4],
 232              ["aaa", DOKU_LEXER_MATCHED, 7],
 233              ["x", DOKU_LEXER_UNMATCHED, 10],
 234              ["aaaa", DOKU_LEXER_MATCHED, 11],
 235              ["x", DOKU_LEXER_UNMATCHED, 15],
 236          ];
 237          $aArgumentCount = count($aArguments);
 238  
 239          $handler = $this->createMock('TestParser');
 240          $handler
 241              ->expects($this->exactly($aArgumentCount))
 242              ->method('a')
 243              ->withConsecutive(...$aArguments)
 244              ->willReturnOnConsecutiveCalls(...array_fill(0, $aArgumentCount, true));
 245  
 246          $lexer = new Lexer($handler, "a");
 247          $lexer->addPattern("a+", "a");
 248          $lexer->addPattern("b+", "b");
 249          $this->assertTrue($lexer->parse("abaabxbaaaxaaaax"));
 250      }
 251      function testModeChange() {
 252          $methodArguments = [
 253              'a' => [
 254                  ["a", DOKU_LEXER_MATCHED, 0],
 255                  ["b", DOKU_LEXER_UNMATCHED, 1],
 256                  ["aa", DOKU_LEXER_MATCHED, 2],
 257                  ["b", DOKU_LEXER_UNMATCHED, 4],
 258                  ["aaa", DOKU_LEXER_MATCHED, 5],
 259              ],
 260              'b' => [
 261                  [":", DOKU_LEXER_ENTER, 8],
 262                  ["a", DOKU_LEXER_UNMATCHED, 9],
 263                  ["b", DOKU_LEXER_MATCHED, 10],
 264                  ["a", DOKU_LEXER_UNMATCHED, 11],
 265                  ["bb", DOKU_LEXER_MATCHED, 12],
 266                  ["a", DOKU_LEXER_UNMATCHED, 14],
 267                  ["bbb", DOKU_LEXER_MATCHED, 15],
 268                  ["a", DOKU_LEXER_UNMATCHED, 18],
 269              ],
 270          ];
 271  
 272          $handler = $this->createMock('TestParser');
 273          foreach ($methodArguments as $method => $arguments) {
 274              $count = count($arguments);
 275              $handler
 276                  ->expects($this->exactly($count))
 277                  ->method($method)
 278                  ->withConsecutive(...$arguments)
 279                  ->willReturnOnConsecutiveCalls(...array_fill(0, $count, true));
 280          }
 281  
 282          $lexer = new Lexer($handler, "a");
 283          $lexer->addPattern("a+", "a");
 284          $lexer->addEntryPattern(":", "a", "b");
 285          $lexer->addPattern("b+", "b");
 286          $this->assertTrue($lexer->parse("abaabaaa:ababbabbba"));
 287      }
 288      function testNesting() {
 289          $methodArguments = [
 290              'a' => [
 291                  ["aa", DOKU_LEXER_MATCHED, 0],
 292                  ["b", DOKU_LEXER_UNMATCHED, 2],
 293                  ["aa", DOKU_LEXER_MATCHED, 3],
 294                  ["b", DOKU_LEXER_UNMATCHED, 5],
 295                  // some b calls in between here
 296                  ["aa", DOKU_LEXER_MATCHED, 13],
 297                  ["b", DOKU_LEXER_UNMATCHED, 15],
 298              ],
 299              'b' => [
 300                  ["(", DOKU_LEXER_ENTER, 6],
 301                  ["bb", DOKU_LEXER_MATCHED, 7],
 302                  ["a", DOKU_LEXER_UNMATCHED, 9],
 303                  ["bb", DOKU_LEXER_MATCHED, 10],
 304                  [")", DOKU_LEXER_EXIT, 12],
 305              ],
 306          ];
 307  
 308          $handler = $this->createMock('TestParser');
 309          foreach ($methodArguments as $method => $arguments) {
 310              $count = count($arguments);
 311              $handler
 312                  ->expects($this->exactly($count))
 313                  ->method($method)
 314                  ->withConsecutive(...$arguments)
 315                  ->willReturnOnConsecutiveCalls(...array_fill(0, $count, true));
 316          }
 317  
 318          $lexer = new Lexer($handler, "a");
 319          $lexer->addPattern("a+", "a");
 320          $lexer->addEntryPattern("(", "a", "b");
 321          $lexer->addPattern("b+", "b");
 322          $lexer->addExitPattern(")", "b");
 323          $this->assertTrue($lexer->parse("aabaab(bbabb)aab"));
 324      }
 325      function testSingular() {
 326          $methodArguments = [
 327              'a' => [
 328                  ["aa", DOKU_LEXER_MATCHED, 0],
 329                  ["aa", DOKU_LEXER_MATCHED, 3],
 330                  ["xx", DOKU_LEXER_UNMATCHED, 5],
 331                  ["xx", DOKU_LEXER_UNMATCHED, 10],
 332              ],
 333              'b' => [
 334                  ["b", DOKU_LEXER_SPECIAL, 2],
 335                  ["bbb", DOKU_LEXER_SPECIAL, 7],
 336              ],
 337          ];
 338  
 339          $handler = $this->createMock('TestParser');
 340          foreach ($methodArguments as $method => $arguments) {
 341              $count = count($arguments);
 342              $handler
 343                  ->expects($this->exactly($count))
 344                  ->method($method)
 345                  ->withConsecutive(...$arguments)
 346                  ->willReturnOnConsecutiveCalls(...array_fill(0, $count, true));
 347          }
 348  
 349          $lexer = new Lexer($handler, "a");
 350          $lexer->addPattern("a+", "a");
 351          $lexer->addSpecialPattern("b+", "a", "b");
 352          $this->assertTrue($lexer->parse("aabaaxxbbbxx"));
 353      }
 354      function testUnwindTooFar() {
 355          $aArguments = [
 356              ["aa", DOKU_LEXER_MATCHED,0],
 357              [")", DOKU_LEXER_EXIT,2],
 358          ];
 359          $aArgumentCount = count($aArguments);
 360  
 361          $handler = $this->createMock('TestParser');
 362          $handler
 363              ->expects($this->exactly($aArgumentCount))
 364              ->method('a')
 365              ->withConsecutive(...$aArguments)
 366              ->willReturnOnConsecutiveCalls(...array_fill(0, $aArgumentCount, true));
 367  
 368          $lexer = new Lexer($handler, "a");
 369          $lexer->addPattern("a+", "a");
 370          $lexer->addExitPattern(")", "a");
 371          $this->assertFalse($lexer->parse("aa)aa"));
 372      }
 373  }
 374  
 375  class TestOfLexerHandlers extends DokuWikiTest {
 376      function testModeMapping() {
 377          $aArguments = [
 378              ["aa", DOKU_LEXER_MATCHED, 0],
 379              ["(", DOKU_LEXER_ENTER, 2],
 380              ["bb", DOKU_LEXER_MATCHED, 3],
 381              ["a", DOKU_LEXER_UNMATCHED, 5],
 382              ["bb", DOKU_LEXER_MATCHED, 6],
 383              [")", DOKU_LEXER_EXIT, 8],
 384              ["b", DOKU_LEXER_UNMATCHED, 9],
 385          ];
 386          $aArgumentCount = count($aArguments);
 387  
 388          $handler = $this->createMock('TestParser');
 389          $handler
 390              ->expects($this->exactly($aArgumentCount))
 391              ->method('a')
 392              ->withConsecutive(...$aArguments)
 393              ->willReturnOnConsecutiveCalls(...array_fill(0, $aArgumentCount, true));
 394  
 395          $lexer = new Lexer($handler, "mode_a");
 396          $lexer->addPattern("a+", "mode_a");
 397          $lexer->addEntryPattern("(", "mode_a", "mode_b");
 398          $lexer->addPattern("b+", "mode_b");
 399          $lexer->addExitPattern(")", "mode_b");
 400          $lexer->mapHandler("mode_a", "a");
 401          $lexer->mapHandler("mode_b", "a");
 402          $this->assertTrue($lexer->parse("aa(bbabb)b"));
 403      }
 404  }
 405  
 406  class TestParserByteIndex {
 407  
 408      function __construct() {}
 409  
 410      function ignore() {}
 411  
 412      function caught() {}
 413  }
 414  
 415  class TestOfLexerByteIndices extends DokuWikiTest {
 416  
 417      function testIndex() {
 418          $doc = "aaa<file>bcd</file>eee";
 419  
 420          $caughtArguments = [
 421              ["<file>", DOKU_LEXER_ENTER, strpos($doc, '<file>')],
 422              ["b", DOKU_LEXER_SPECIAL, strpos($doc, 'b')],
 423              ["c", DOKU_LEXER_MATCHED, strpos($doc, 'c')],
 424              ["d", DOKU_LEXER_UNMATCHED, strpos($doc, 'd')],
 425              ["</file>", DOKU_LEXER_EXIT, strpos($doc, '</file>')],
 426          ];
 427          $caughtArgumentCount = count($caughtArguments);
 428  
 429          $handler = $this->createMock('TestParserByteIndex');
 430          $handler->expects($this->any())->method('ignore')->will($this->returnValue(true));
 431          $handler
 432              ->expects($this->exactly($caughtArgumentCount))
 433              ->method('caught')
 434              ->withConsecutive(...$caughtArguments)
 435              ->willReturnOnConsecutiveCalls(...array_fill(0, $caughtArgumentCount, true));
 436  
 437          $lexer = new Lexer($handler, "ignore");
 438          $lexer->addEntryPattern("<file>", "ignore", "caught");
 439          $lexer->addExitPattern("</file>", "caught");
 440          $lexer->addSpecialPattern('b','caught','special');
 441          $lexer->mapHandler('special','caught');
 442          $lexer->addPattern('c','caught');
 443  
 444          $this->assertTrue($lexer->parse($doc));
 445      }
 446  
 447      function testIndexLookaheadEqual() {
 448          $doc = "aaa<file>bcd</file>eee";
 449  
 450          $caughtArguments = [
 451              ["<file>", DOKU_LEXER_ENTER, strpos($doc, '<file>')],
 452              ["b", DOKU_LEXER_SPECIAL, strpos($doc, 'b')],
 453              ["c", DOKU_LEXER_MATCHED, strpos($doc, 'c')],
 454              ["d", DOKU_LEXER_UNMATCHED, strpos($doc, 'd')],
 455              ["</file>", DOKU_LEXER_EXIT, strpos($doc, '</file>')],
 456          ];
 457          $caughtArgumentCount = count($caughtArguments);
 458  
 459          $handler = $this->createMock('TestParserByteIndex');
 460          $handler->expects($this->any())->method('ignore')->will($this->returnValue(true));
 461          $handler
 462              ->expects($this->exactly($caughtArgumentCount))
 463              ->method('caught')
 464              ->withConsecutive(...$caughtArguments)
 465              ->willReturnOnConsecutiveCalls(...array_fill(0, $caughtArgumentCount, true));
 466  
 467          $lexer = new Lexer($handler, "ignore");
 468          $lexer->addEntryPattern('<file>(?=.*</file>)', "ignore", "caught");
 469          $lexer->addExitPattern("</file>", "caught");
 470          $lexer->addSpecialPattern('b','caught','special');
 471          $lexer->mapHandler('special','caught');
 472          $lexer->addPattern('c','caught');
 473  
 474          $this->assertTrue($lexer->parse($doc));
 475      }
 476  
 477      function testIndexLookaheadNotEqual() {
 478          $doc = "aaa<file>bcd</file>eee";
 479  
 480          $caughtArguments = [
 481              ["<file>", DOKU_LEXER_ENTER, strpos($doc, '<file>')],
 482              ["b", DOKU_LEXER_SPECIAL, strpos($doc, 'b')],
 483              ["c", DOKU_LEXER_MATCHED, strpos($doc, 'c')],
 484              ["d", DOKU_LEXER_UNMATCHED, strpos($doc, 'd')],
 485              ["</file>", DOKU_LEXER_EXIT, strpos($doc, '</file>')],
 486          ];
 487          $caughtArgumentCount = count($caughtArguments);
 488  
 489          $handler = $this->createMock('TestParserByteIndex');
 490          $handler->expects($this->any())->method('ignore')->will($this->returnValue(true));
 491          $handler
 492              ->expects($this->exactly($caughtArgumentCount))
 493              ->method('caught')
 494              ->withConsecutive(...$caughtArguments)
 495              ->willReturnOnConsecutiveCalls(...array_fill(0, $caughtArgumentCount, true));
 496  
 497          $lexer = new Lexer($handler, "ignore");
 498          $lexer->addEntryPattern('<file>(?!foo)', "ignore", "caught");
 499          $lexer->addExitPattern("</file>", "caught");
 500          $lexer->addSpecialPattern('b','caught','special');
 501          $lexer->mapHandler('special','caught');
 502          $lexer->addPattern('c','caught');
 503  
 504          $this->assertTrue($lexer->parse($doc));
 505      }
 506  
 507      function testIndexLookbehindEqual() {
 508          $doc = "aaa<file>bcd</file>eee";
 509  
 510          $caughtArguments = [
 511              ["<file>", DOKU_LEXER_ENTER, strpos($doc, '<file>')],
 512              ["b", DOKU_LEXER_SPECIAL, strpos($doc, 'b')],
 513              ["c", DOKU_LEXER_MATCHED, strpos($doc, 'c')],
 514              ["d", DOKU_LEXER_UNMATCHED, strpos($doc, 'd')],
 515              ["</file>", DOKU_LEXER_EXIT, strpos($doc, '</file>')],
 516          ];
 517          $caughtArgumentCount = count($caughtArguments);
 518  
 519          $handler = $this->createMock('TestParserByteIndex');
 520          $handler->expects($this->any())->method('ignore')->will($this->returnValue(true));
 521          $handler
 522              ->expects($this->exactly($caughtArgumentCount))
 523              ->method('caught')
 524              ->withConsecutive(...$caughtArguments)
 525              ->willReturnOnConsecutiveCalls(...array_fill(0, $caughtArgumentCount, true));
 526  
 527          $lexer = new Lexer($handler, "ignore");
 528          $lexer->addEntryPattern('<file>', "ignore", "caught");
 529          $lexer->addExitPattern("(?<=d)</file>", "caught");
 530          $lexer->addSpecialPattern('b','caught','special');
 531          $lexer->mapHandler('special','caught');
 532          $lexer->addPattern('c','caught');
 533  
 534          $this->assertTrue($lexer->parse($doc));
 535      }
 536  
 537      function testIndexLookbehindNotEqual() {
 538          $doc = "aaa<file>bcd</file>eee";
 539  
 540          $caughtArguments = [
 541              ["<file>", DOKU_LEXER_ENTER, strpos($doc, '<file>')],
 542              ["b", DOKU_LEXER_SPECIAL, strpos($doc, 'b')],
 543              ["c", DOKU_LEXER_MATCHED, strpos($doc, 'c')],
 544              ["d", DOKU_LEXER_UNMATCHED, strpos($doc, 'd')],
 545              ["</file>", DOKU_LEXER_EXIT, strpos($doc, '</file>')],
 546          ];
 547          $caughtArgumentCount = count($caughtArguments);
 548  
 549          $handler = $this->createMock('TestParserByteIndex');
 550          $handler->expects($this->any())->method('ignore')->will($this->returnValue(true));
 551          $handler
 552              ->expects($this->exactly($caughtArgumentCount))
 553              ->method('caught')
 554              ->withConsecutive(...$caughtArguments)
 555              ->willReturnOnConsecutiveCalls(...array_fill(0, $caughtArgumentCount, true));
 556  
 557          $lexer = new Lexer($handler, 'ignore');
 558          $lexer->addEntryPattern('<file>', 'ignore', 'caught');
 559          $lexer->addExitPattern('(?<!c)</file>', 'caught');
 560          $lexer->addSpecialPattern('b','caught','special');
 561          $lexer->mapHandler('special','caught');
 562          $lexer->addPattern('c','caught');
 563  
 564          $this->assertTrue($lexer->parse($doc));
 565      }
 566  
 567      /**
 568       * This test is primarily to ensure the correct match is chosen
 569       * when there are non-captured elements in the pattern.
 570       */
 571      function testIndexSelectCorrectMatch() {
 572          $doc = "ALL FOOLS ARE FOO";
 573          $pattern = '\bFOO\b';
 574  
 575          $handler = $this->createMock('TestParserByteIndex');
 576          $handler->expects($this->any())->method('ignore')->will($this->returnValue(true));
 577  
 578          $matches = [];
 579          preg_match('/'.$pattern.'/',$doc,$matches,PREG_OFFSET_CAPTURE);
 580  
 581          $handler->expects($this->once())->method('caught')
 582              ->with("FOO", DOKU_LEXER_SPECIAL, $matches[0][1])->will($this->returnValue(true));
 583  
 584          $lexer = new Lexer($handler, "ignore");
 585          $lexer->addSpecialPattern($pattern,'ignore','caught');
 586  
 587          $this->assertTrue($lexer->parse($doc));
 588      }
 589  
 590  }