xref: /dokuwiki/_test/tests/inc/parser/lexer.test.php (revision 2a113f46634a3d04c5413c5b6916ea6c8fd0809d)
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