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