xref: /dokuwiki/_test/tests/inc/parser/lexer.test.php (revision be906b566b9bdfd92c032ee07c4fd077d820a8d1)
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
8*be906b56SAndreas Gohruse dokuwiki\Parsing\Lexer\Lexer;
9*be906b56SAndreas Gohruse dokuwiki\Parsing\Lexer\ParallelRegex;
10*be906b56SAndreas 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);
20f8369d7dSTobias Sarnowski        $this->assertFalse($regex->match("Hello", $match));
21f8369d7dSTobias Sarnowski        $this->assertEquals($match, "");
22f8369d7dSTobias Sarnowski    }
23f8369d7dSTobias Sarnowski    function testNoSubject() {
24de226116SAndreas Gohr        $regex = new ParallelRegex(false);
25f8369d7dSTobias Sarnowski        $regex->addPattern(".*");
26f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("", $match));
27f8369d7dSTobias Sarnowski        $this->assertEquals($match, "");
28f8369d7dSTobias Sarnowski    }
29f8369d7dSTobias Sarnowski    function testMatchAll() {
30de226116SAndreas Gohr        $regex = new ParallelRegex(false);
31f8369d7dSTobias Sarnowski        $regex->addPattern(".*");
32f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("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");
38f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("abcdef", $match));
39f8369d7dSTobias Sarnowski        $this->assertEquals($match, "abc");
40f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("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");
46f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("abcdef", $match));
47f8369d7dSTobias Sarnowski        $this->assertEquals($match, "abc");
48f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("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");
55f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("abcdef", $match));
56f8369d7dSTobias Sarnowski        $this->assertEquals($match, "abc");
57f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("AAABCabcdef", $match));
58f8369d7dSTobias Sarnowski        $this->assertEquals($match, "ABC");
59f8369d7dSTobias Sarnowski        $this->assertFalse($regex->match("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");
65f8369d7dSTobias Sarnowski        $this->assertEquals($regex->match("abcdef", $match), "letter");
66f8369d7dSTobias Sarnowski        $this->assertEquals($match, "abc");
67f8369d7dSTobias Sarnowski        $this->assertEquals($regex->match("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}");
75f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("abcdef", $match));
76f8369d7dSTobias Sarnowski        $this->assertEquals($match, "abc");
77f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("AAABCabcdef", $match));
78f8369d7dSTobias Sarnowski        $this->assertEquals($match, "ABC");
79f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("a\nab", $match));
80f8369d7dSTobias Sarnowski        $this->assertEquals($match, "ab");
81f8369d7dSTobias Sarnowski        $this->assertFalse($regex->match("Hello", $match));
82f8369d7dSTobias Sarnowski    }
83f8369d7dSTobias Sarnowski    function testMatchSetOptionCaseless() {
84de226116SAndreas Gohr        $regex = new ParallelRegex(true);
85f8369d7dSTobias Sarnowski        $regex->addPattern("a(?i)b(?i)c");
86f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("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+");
92f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("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)");
98f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("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)");
104f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("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");
110f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("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");
116f8369d7dSTobias Sarnowski        $this->assertTrue($regex->match("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() {
173db5867f1SAndreas Gohr        $handler = $this->createMock('TestParser');
174f8369d7dSTobias Sarnowski        $handler->expects($this->at(0))->method('accept')
175f8369d7dSTobias Sarnowski            ->with("aaa", DOKU_LEXER_MATCHED, 0)->will($this->returnValue(true));
176f8369d7dSTobias Sarnowski        $handler->expects($this->at(1))->method('accept')
177f8369d7dSTobias Sarnowski            ->with("x", DOKU_LEXER_UNMATCHED, 3)->will($this->returnValue(true));
178f8369d7dSTobias Sarnowski        $handler->expects($this->at(2))->method('accept')
179f8369d7dSTobias Sarnowski            ->with("a", DOKU_LEXER_MATCHED, 4)->will($this->returnValue(true));
180f8369d7dSTobias Sarnowski        $handler->expects($this->at(3))->method('accept')
181f8369d7dSTobias Sarnowski            ->with("yyy", DOKU_LEXER_UNMATCHED, 5)->will($this->returnValue(true));
182f8369d7dSTobias Sarnowski        $handler->expects($this->at(4))->method('accept')
183f8369d7dSTobias Sarnowski            ->with("a", DOKU_LEXER_MATCHED, 8)->will($this->returnValue(true));
184f8369d7dSTobias Sarnowski        $handler->expects($this->at(5))->method('accept')
185f8369d7dSTobias Sarnowski            ->with("x", DOKU_LEXER_UNMATCHED, 9)->will($this->returnValue(true));
186f8369d7dSTobias Sarnowski        $handler->expects($this->at(6))->method('accept')
187f8369d7dSTobias Sarnowski            ->with("aaa", DOKU_LEXER_MATCHED, 10)->will($this->returnValue(true));
188f8369d7dSTobias Sarnowski        $handler->expects($this->at(7))->method('accept')
189f8369d7dSTobias Sarnowski            ->with("z", DOKU_LEXER_UNMATCHED, 13)->will($this->returnValue(true));
190f8369d7dSTobias Sarnowski
191de226116SAndreas Gohr        $lexer = new Lexer($handler);
192f8369d7dSTobias Sarnowski        $lexer->addPattern("a+");
193f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse("aaaxayyyaxaaaz"));
194f8369d7dSTobias Sarnowski    }
195f8369d7dSTobias Sarnowski    function testMultiplePattern() {
196db5867f1SAndreas Gohr        $handler = $this->createPartialMock('TestParser', array('accept'));
197f8369d7dSTobias Sarnowski        $target = array("a", "b", "a", "bb", "x", "b", "a", "xxxxxx", "a", "x");
198f8369d7dSTobias Sarnowski        $positions = array(0, 1, 2, 3, 5, 6, 7, 8, 14, 15);
199f8369d7dSTobias Sarnowski        for ($i = 0; $i < count($target); $i++) {
200f8369d7dSTobias Sarnowski            $handler->expects($this->at($i))->method('accept')
201f8369d7dSTobias Sarnowski                ->with($target[$i], $this->anything(), $positions[$i])->will($this->returnValue(true));
202f8369d7dSTobias Sarnowski        }
203de226116SAndreas Gohr        $lexer = new Lexer($handler);
204f8369d7dSTobias Sarnowski        $lexer->addPattern("a+");
205f8369d7dSTobias Sarnowski        $lexer->addPattern("b+");
206f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse("ababbxbaxxxxxxax"));
207f8369d7dSTobias Sarnowski    }
208f8369d7dSTobias Sarnowski}
209f8369d7dSTobias Sarnowski
210f8369d7dSTobias Sarnowskiclass TestOfLexerModes extends DokuWikiTest {
211f8369d7dSTobias Sarnowski    function testIsolatedPattern() {
212db5867f1SAndreas Gohr        $handler = $this->createMock('TestParser');
213f8369d7dSTobias Sarnowski        $handler->expects($this->at(0))->method('a')
214f8369d7dSTobias Sarnowski            ->with("a", DOKU_LEXER_MATCHED,0)->will($this->returnValue(true));
215f8369d7dSTobias Sarnowski        $handler->expects($this->at(1))->method('a')
216f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_UNMATCHED,1)->will($this->returnValue(true));
217f8369d7dSTobias Sarnowski        $handler->expects($this->at(2))->method('a')
218f8369d7dSTobias Sarnowski            ->with("aa", DOKU_LEXER_MATCHED,2)->will($this->returnValue(true));
219f8369d7dSTobias Sarnowski        $handler->expects($this->at(3))->method('a')
220f8369d7dSTobias Sarnowski            ->with("bxb", DOKU_LEXER_UNMATCHED,4)->will($this->returnValue(true));
221f8369d7dSTobias Sarnowski        $handler->expects($this->at(4))->method('a')
222f8369d7dSTobias Sarnowski            ->with("aaa", DOKU_LEXER_MATCHED,7)->will($this->returnValue(true));
223f8369d7dSTobias Sarnowski        $handler->expects($this->at(5))->method('a')
224f8369d7dSTobias Sarnowski            ->with("x", DOKU_LEXER_UNMATCHED,10)->will($this->returnValue(true));
225f8369d7dSTobias Sarnowski        $handler->expects($this->at(6))->method('a')
226f8369d7dSTobias Sarnowski            ->with("aaaa", DOKU_LEXER_MATCHED,11)->will($this->returnValue(true));
227f8369d7dSTobias Sarnowski        $handler->expects($this->at(7))->method('a')
228f8369d7dSTobias Sarnowski            ->with("x", DOKU_LEXER_UNMATCHED,15)->will($this->returnValue(true));
229de226116SAndreas Gohr        $lexer = new Lexer($handler, "a");
230f8369d7dSTobias Sarnowski        $lexer->addPattern("a+", "a");
231f8369d7dSTobias Sarnowski        $lexer->addPattern("b+", "b");
232f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse("abaabxbaaaxaaaax"));
233f8369d7dSTobias Sarnowski    }
234f8369d7dSTobias Sarnowski    function testModeChange() {
235db5867f1SAndreas Gohr        $handler = $this->createMock('TestParser');
236f8369d7dSTobias Sarnowski        $handler->expects($this->at(0))->method('a')
237f8369d7dSTobias Sarnowski            ->with("a", DOKU_LEXER_MATCHED,0)->will($this->returnValue(true));
238f8369d7dSTobias Sarnowski        $handler->expects($this->at(1))->method('a')
239f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_UNMATCHED,1)->will($this->returnValue(true));
240f8369d7dSTobias Sarnowski        $handler->expects($this->at(2))->method('a')
241f8369d7dSTobias Sarnowski            ->with("aa", DOKU_LEXER_MATCHED,2)->will($this->returnValue(true));
242f8369d7dSTobias Sarnowski        $handler->expects($this->at(3))->method('a')
243f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_UNMATCHED,4)->will($this->returnValue(true));
244f8369d7dSTobias Sarnowski        $handler->expects($this->at(4))->method('a')
245f8369d7dSTobias Sarnowski            ->with("aaa", DOKU_LEXER_MATCHED,5)->will($this->returnValue(true));
246f8369d7dSTobias Sarnowski        $handler->expects($this->at(5))->method('b')
247f8369d7dSTobias Sarnowski            ->with(":", DOKU_LEXER_ENTER,8)->will($this->returnValue(true));
248f8369d7dSTobias Sarnowski        $handler->expects($this->at(6))->method('b')
249f8369d7dSTobias Sarnowski            ->with("a", DOKU_LEXER_UNMATCHED,9)->will($this->returnValue(true));
250f8369d7dSTobias Sarnowski        $handler->expects($this->at(7))->method('b')
251f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_MATCHED, 10)->will($this->returnValue(true));
252f8369d7dSTobias Sarnowski        $handler->expects($this->at(8))->method('b')
253f8369d7dSTobias Sarnowski            ->with("a", DOKU_LEXER_UNMATCHED,11)->will($this->returnValue(true));
254f8369d7dSTobias Sarnowski        $handler->expects($this->at(9))->method('b')
255f8369d7dSTobias Sarnowski            ->with("bb", DOKU_LEXER_MATCHED,12)->will($this->returnValue(true));
256f8369d7dSTobias Sarnowski        $handler->expects($this->at(10))->method('b')
257f8369d7dSTobias Sarnowski            ->with("a", DOKU_LEXER_UNMATCHED,14)->will($this->returnValue(true));
258f8369d7dSTobias Sarnowski        $handler->expects($this->at(11))->method('b')
259f8369d7dSTobias Sarnowski            ->with("bbb", DOKU_LEXER_MATCHED,15)->will($this->returnValue(true));
260f8369d7dSTobias Sarnowski        $handler->expects($this->at(12))->method('b')
261f8369d7dSTobias Sarnowski            ->with("a", DOKU_LEXER_UNMATCHED,18)->will($this->returnValue(true));
262f8369d7dSTobias Sarnowski
263de226116SAndreas Gohr        $lexer = new Lexer($handler, "a");
264f8369d7dSTobias Sarnowski        $lexer->addPattern("a+", "a");
265f8369d7dSTobias Sarnowski        $lexer->addEntryPattern(":", "a", "b");
266f8369d7dSTobias Sarnowski        $lexer->addPattern("b+", "b");
267f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse("abaabaaa:ababbabbba"));
268f8369d7dSTobias Sarnowski    }
269f8369d7dSTobias Sarnowski    function testNesting() {
270db5867f1SAndreas Gohr        $handler = $this->createMock('TestParser');
271f8369d7dSTobias Sarnowski        $handler->expects($this->at(0))->method('a')
272f8369d7dSTobias Sarnowski            ->with("aa", DOKU_LEXER_MATCHED,0)->will($this->returnValue(true));
273f8369d7dSTobias Sarnowski        $handler->expects($this->at(1))->method('a')
274f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_UNMATCHED,2)->will($this->returnValue(true));
275f8369d7dSTobias Sarnowski        $handler->expects($this->at(2))->method('a')
276f8369d7dSTobias Sarnowski            ->with("aa", DOKU_LEXER_MATCHED,3)->will($this->returnValue(true));
277f8369d7dSTobias Sarnowski        $handler->expects($this->at(3))->method('a')
278f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_UNMATCHED,5)->will($this->returnValue(true));
279f8369d7dSTobias Sarnowski        $handler->expects($this->at(4))->method('b')
280f8369d7dSTobias Sarnowski            ->with("(", DOKU_LEXER_ENTER,6)->will($this->returnValue(true));
281f8369d7dSTobias Sarnowski        $handler->expects($this->at(5))->method('b')
282f8369d7dSTobias Sarnowski            ->with("bb", DOKU_LEXER_MATCHED,7)->will($this->returnValue(true));
283f8369d7dSTobias Sarnowski        $handler->expects($this->at(6))->method('b')
284f8369d7dSTobias Sarnowski            ->with("a", DOKU_LEXER_UNMATCHED,9)->will($this->returnValue(true));
285f8369d7dSTobias Sarnowski        $handler->expects($this->at(7))->method('b')
286f8369d7dSTobias Sarnowski            ->with("bb", DOKU_LEXER_MATCHED,10)->will($this->returnValue(true));
287f8369d7dSTobias Sarnowski        $handler->expects($this->at(8))->method('b')
288f8369d7dSTobias Sarnowski            ->with(")", DOKU_LEXER_EXIT,12)->will($this->returnValue(true));
289f8369d7dSTobias Sarnowski        $handler->expects($this->at(9))->method('a')
290f8369d7dSTobias Sarnowski            ->with("aa", DOKU_LEXER_MATCHED,13)->will($this->returnValue(true));
291f8369d7dSTobias Sarnowski        $handler->expects($this->at(10))->method('a')
292f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_UNMATCHED,15)->will($this->returnValue(true));
293f8369d7dSTobias Sarnowski
294f8369d7dSTobias Sarnowski
295de226116SAndreas Gohr        $lexer = new Lexer($handler, "a");
296f8369d7dSTobias Sarnowski        $lexer->addPattern("a+", "a");
297f8369d7dSTobias Sarnowski        $lexer->addEntryPattern("(", "a", "b");
298f8369d7dSTobias Sarnowski        $lexer->addPattern("b+", "b");
299f8369d7dSTobias Sarnowski        $lexer->addExitPattern(")", "b");
300f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse("aabaab(bbabb)aab"));
301f8369d7dSTobias Sarnowski    }
302f8369d7dSTobias Sarnowski    function testSingular() {
303db5867f1SAndreas Gohr        $handler = $this->createMock('TestParser');
304f8369d7dSTobias Sarnowski        $handler->expects($this->at(0))->method('a')
305f8369d7dSTobias Sarnowski            ->with("aa", DOKU_LEXER_MATCHED,0)->will($this->returnValue(true));
306f8369d7dSTobias Sarnowski        $handler->expects($this->at(1))->method('b')
307f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_SPECIAL,2)->will($this->returnValue(true));
308f8369d7dSTobias Sarnowski        $handler->expects($this->at(2))->method('a')
309f8369d7dSTobias Sarnowski            ->with("aa", DOKU_LEXER_MATCHED,3)->will($this->returnValue(true));
310f8369d7dSTobias Sarnowski        $handler->expects($this->at(3))->method('a')
311f8369d7dSTobias Sarnowski            ->with("xx", DOKU_LEXER_UNMATCHED,5)->will($this->returnValue(true));
312f8369d7dSTobias Sarnowski        $handler->expects($this->at(4))->method('b')
313f8369d7dSTobias Sarnowski            ->with("bbb", DOKU_LEXER_SPECIAL,7)->will($this->returnValue(true));
314f8369d7dSTobias Sarnowski        $handler->expects($this->at(5))->method('a')
315f8369d7dSTobias Sarnowski            ->with("xx", DOKU_LEXER_UNMATCHED,10)->will($this->returnValue(true));
316de226116SAndreas Gohr        $lexer = new Lexer($handler, "a");
317f8369d7dSTobias Sarnowski        $lexer->addPattern("a+", "a");
318f8369d7dSTobias Sarnowski        $lexer->addSpecialPattern("b+", "a", "b");
319f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse("aabaaxxbbbxx"));
320f8369d7dSTobias Sarnowski    }
321f8369d7dSTobias Sarnowski    function testUnwindTooFar() {
322db5867f1SAndreas Gohr        $handler = $this->createMock('TestParser');
323f8369d7dSTobias Sarnowski        $handler->expects($this->at(0))->method('a')
324f8369d7dSTobias Sarnowski            ->with("aa", DOKU_LEXER_MATCHED,0)->will($this->returnValue(true));
325f8369d7dSTobias Sarnowski        $handler->expects($this->at(1))->method('a')
326f8369d7dSTobias Sarnowski            ->with(")", DOKU_LEXER_EXIT,2)->will($this->returnValue(true));
327f8369d7dSTobias Sarnowski
328de226116SAndreas Gohr        $lexer = new Lexer($handler, "a");
329f8369d7dSTobias Sarnowski        $lexer->addPattern("a+", "a");
330f8369d7dSTobias Sarnowski        $lexer->addExitPattern(")", "a");
331f8369d7dSTobias Sarnowski        $this->assertFalse($lexer->parse("aa)aa"));
332f8369d7dSTobias Sarnowski    }
333f8369d7dSTobias Sarnowski}
334f8369d7dSTobias Sarnowski
335f8369d7dSTobias Sarnowskiclass TestOfLexerHandlers extends DokuWikiTest {
336f8369d7dSTobias Sarnowski    function testModeMapping() {
337db5867f1SAndreas Gohr        $handler = $this->createMock('TestParser');
338f8369d7dSTobias Sarnowski        $handler->expects($this->at(0))->method('a')
339f8369d7dSTobias Sarnowski            ->with("aa", DOKU_LEXER_MATCHED,0)->will($this->returnValue(true));
340f8369d7dSTobias Sarnowski        $handler->expects($this->at(1))->method('a')
341f8369d7dSTobias Sarnowski            ->with("(", DOKU_LEXER_ENTER,2)->will($this->returnValue(true));
342f8369d7dSTobias Sarnowski        $handler->expects($this->at(2))->method('a')
343f8369d7dSTobias Sarnowski            ->with("bb", DOKU_LEXER_MATCHED,3)->will($this->returnValue(true));
344f8369d7dSTobias Sarnowski        $handler->expects($this->at(3))->method('a')
345f8369d7dSTobias Sarnowski            ->with("a", DOKU_LEXER_UNMATCHED,5)->will($this->returnValue(true));
346f8369d7dSTobias Sarnowski        $handler->expects($this->at(4))->method('a')
347f8369d7dSTobias Sarnowski            ->with("bb", DOKU_LEXER_MATCHED,6)->will($this->returnValue(true));
348f8369d7dSTobias Sarnowski        $handler->expects($this->at(5))->method('a')
349f8369d7dSTobias Sarnowski            ->with(")", DOKU_LEXER_EXIT,8)->will($this->returnValue(true));
350f8369d7dSTobias Sarnowski        $handler->expects($this->at(6))->method('a')
351f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_UNMATCHED,9)->will($this->returnValue(true));
352f8369d7dSTobias Sarnowski
353de226116SAndreas Gohr        $lexer = new Lexer($handler, "mode_a");
354f8369d7dSTobias Sarnowski        $lexer->addPattern("a+", "mode_a");
355f8369d7dSTobias Sarnowski        $lexer->addEntryPattern("(", "mode_a", "mode_b");
356f8369d7dSTobias Sarnowski        $lexer->addPattern("b+", "mode_b");
357f8369d7dSTobias Sarnowski        $lexer->addExitPattern(")", "mode_b");
358f8369d7dSTobias Sarnowski        $lexer->mapHandler("mode_a", "a");
359f8369d7dSTobias Sarnowski        $lexer->mapHandler("mode_b", "a");
360f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse("aa(bbabb)b"));
361f8369d7dSTobias Sarnowski    }
362f8369d7dSTobias Sarnowski}
363f8369d7dSTobias Sarnowski
364f8369d7dSTobias Sarnowskiclass TestParserByteIndex {
365f8369d7dSTobias Sarnowski
36626e22ab8SChristopher Smith    function __construct() {}
367f8369d7dSTobias Sarnowski
368f8369d7dSTobias Sarnowski    function ignore() {}
369f8369d7dSTobias Sarnowski
370f8369d7dSTobias Sarnowski    function caught() {}
371f8369d7dSTobias Sarnowski}
372f8369d7dSTobias Sarnowski
373f8369d7dSTobias Sarnowskiclass TestOfLexerByteIndices extends DokuWikiTest {
374f8369d7dSTobias Sarnowski
375f8369d7dSTobias Sarnowski    function testIndex() {
376f8369d7dSTobias Sarnowski        $doc = "aaa<file>bcd</file>eee";
377f8369d7dSTobias Sarnowski
378db5867f1SAndreas Gohr        $handler = $this->createMock('TestParserByteIndex');
379f8369d7dSTobias Sarnowski        $handler->expects($this->any())->method('ignore')->will($this->returnValue(true));
380f8369d7dSTobias Sarnowski        $handler->expects($this->at(1))->method('caught')
381f8369d7dSTobias Sarnowski            ->with("<file>", DOKU_LEXER_ENTER, strpos($doc,'<file>'))->will($this->returnValue(true));
382f8369d7dSTobias Sarnowski        $handler->expects($this->at(2))->method('caught')
383f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_SPECIAL, strpos($doc,'b'))->will($this->returnValue(true));
384f8369d7dSTobias Sarnowski        $handler->expects($this->at(3))->method('caught')
385f8369d7dSTobias Sarnowski            ->with("c", DOKU_LEXER_MATCHED, strpos($doc,'c'))->will($this->returnValue(true));
386f8369d7dSTobias Sarnowski        $handler->expects($this->at(4))->method('caught')
387f8369d7dSTobias Sarnowski            ->with("d", DOKU_LEXER_UNMATCHED, strpos($doc,'d'))->will($this->returnValue(true));
388f8369d7dSTobias Sarnowski        $handler->expects($this->at(5))->method('caught')
389f8369d7dSTobias Sarnowski            ->with("</file>", DOKU_LEXER_EXIT, strpos($doc,'</file>'))->will($this->returnValue(true));
390f8369d7dSTobias Sarnowski
391de226116SAndreas Gohr        $lexer = new Lexer($handler, "ignore");
392f8369d7dSTobias Sarnowski        $lexer->addEntryPattern("<file>", "ignore", "caught");
393f8369d7dSTobias Sarnowski        $lexer->addExitPattern("</file>", "caught");
394f8369d7dSTobias Sarnowski        $lexer->addSpecialPattern('b','caught','special');
395f8369d7dSTobias Sarnowski        $lexer->mapHandler('special','caught');
396f8369d7dSTobias Sarnowski        $lexer->addPattern('c','caught');
397f8369d7dSTobias Sarnowski
398f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse($doc));
399f8369d7dSTobias Sarnowski    }
400f8369d7dSTobias Sarnowski
401f8369d7dSTobias Sarnowski    function testIndexLookaheadEqual() {
402f8369d7dSTobias Sarnowski        $doc = "aaa<file>bcd</file>eee";
403f8369d7dSTobias Sarnowski
404db5867f1SAndreas Gohr        $handler = $this->createMock('TestParserByteIndex');
405f8369d7dSTobias Sarnowski        $handler->expects($this->any())->method('ignore')->will($this->returnValue(true));
406f8369d7dSTobias Sarnowski        $handler->expects($this->at(1))->method('caught')
407f8369d7dSTobias Sarnowski            ->with("<file>", DOKU_LEXER_ENTER, strpos($doc,'<file>'))->will($this->returnValue(true));
408f8369d7dSTobias Sarnowski        $handler->expects($this->at(2))->method('caught')
409f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_SPECIAL, strpos($doc,'b'))->will($this->returnValue(true));
410f8369d7dSTobias Sarnowski        $handler->expects($this->at(3))->method('caught')
411f8369d7dSTobias Sarnowski            ->with("c", DOKU_LEXER_MATCHED, strpos($doc,'c'))->will($this->returnValue(true));
412f8369d7dSTobias Sarnowski        $handler->expects($this->at(4))->method('caught')
413f8369d7dSTobias Sarnowski            ->with("d", DOKU_LEXER_UNMATCHED, strpos($doc,'d'))->will($this->returnValue(true));
414f8369d7dSTobias Sarnowski        $handler->expects($this->at(5))->method('caught')
415f8369d7dSTobias Sarnowski            ->with("</file>", DOKU_LEXER_EXIT, strpos($doc,'</file>'))->will($this->returnValue(true));
416f8369d7dSTobias Sarnowski
417de226116SAndreas Gohr        $lexer = new Lexer($handler, "ignore");
418f8369d7dSTobias Sarnowski        $lexer->addEntryPattern('<file>(?=.*</file>)', "ignore", "caught");
419f8369d7dSTobias Sarnowski        $lexer->addExitPattern("</file>", "caught");
420f8369d7dSTobias Sarnowski        $lexer->addSpecialPattern('b','caught','special');
421f8369d7dSTobias Sarnowski        $lexer->mapHandler('special','caught');
422f8369d7dSTobias Sarnowski        $lexer->addPattern('c','caught');
423f8369d7dSTobias Sarnowski
424f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse($doc));
425f8369d7dSTobias Sarnowski    }
426f8369d7dSTobias Sarnowski
427f8369d7dSTobias Sarnowski    function testIndexLookaheadNotEqual() {
428f8369d7dSTobias Sarnowski        $doc = "aaa<file>bcd</file>eee";
429f8369d7dSTobias Sarnowski
430db5867f1SAndreas Gohr        $handler = $this->createMock('TestParserByteIndex');
431f8369d7dSTobias Sarnowski        $handler->expects($this->any())->method('ignore')->will($this->returnValue(true));
432f8369d7dSTobias Sarnowski        $handler->expects($this->at(1))->method('caught')
433f8369d7dSTobias Sarnowski            ->with("<file>", DOKU_LEXER_ENTER, strpos($doc,'<file>'))->will($this->returnValue(true));
434f8369d7dSTobias Sarnowski        $handler->expects($this->at(2))->method('caught')
435f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_SPECIAL, strpos($doc,'b'))->will($this->returnValue(true));
436f8369d7dSTobias Sarnowski        $handler->expects($this->at(3))->method('caught')
437f8369d7dSTobias Sarnowski            ->with("c", DOKU_LEXER_MATCHED, strpos($doc,'c'))->will($this->returnValue(true));
438f8369d7dSTobias Sarnowski        $handler->expects($this->at(4))->method('caught')
439f8369d7dSTobias Sarnowski            ->with("d", DOKU_LEXER_UNMATCHED, strpos($doc,'d'))->will($this->returnValue(true));
440f8369d7dSTobias Sarnowski        $handler->expects($this->at(5))->method('caught')
441f8369d7dSTobias Sarnowski            ->with("</file>", DOKU_LEXER_EXIT, strpos($doc,'</file>'))->will($this->returnValue(true));
442f8369d7dSTobias Sarnowski
443de226116SAndreas Gohr        $lexer = new Lexer($handler, "ignore");
444f8369d7dSTobias Sarnowski        $lexer->addEntryPattern('<file>(?!foo)', "ignore", "caught");
445f8369d7dSTobias Sarnowski        $lexer->addExitPattern("</file>", "caught");
446f8369d7dSTobias Sarnowski        $lexer->addSpecialPattern('b','caught','special');
447f8369d7dSTobias Sarnowski        $lexer->mapHandler('special','caught');
448f8369d7dSTobias Sarnowski        $lexer->addPattern('c','caught');
449f8369d7dSTobias Sarnowski
450f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse($doc));
451f8369d7dSTobias Sarnowski    }
452f8369d7dSTobias Sarnowski
453f8369d7dSTobias Sarnowski    function testIndexLookbehindEqual() {
454f8369d7dSTobias Sarnowski        $doc = "aaa<file>bcd</file>eee";
455f8369d7dSTobias Sarnowski
456db5867f1SAndreas Gohr        $handler = $this->createMock('TestParserByteIndex');
457f8369d7dSTobias Sarnowski        $handler->expects($this->any())->method('ignore')->will($this->returnValue(true));
458f8369d7dSTobias Sarnowski        $handler->expects($this->at(1))->method('caught')
459f8369d7dSTobias Sarnowski            ->with("<file>", DOKU_LEXER_ENTER, strpos($doc,'<file>'))->will($this->returnValue(true));
460f8369d7dSTobias Sarnowski        $handler->expects($this->at(2))->method('caught')
461f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_SPECIAL, strpos($doc,'b'))->will($this->returnValue(true));
462f8369d7dSTobias Sarnowski        $handler->expects($this->at(3))->method('caught')
463f8369d7dSTobias Sarnowski            ->with("c", DOKU_LEXER_MATCHED, strpos($doc,'c'))->will($this->returnValue(true));
464f8369d7dSTobias Sarnowski        $handler->expects($this->at(4))->method('caught')
465f8369d7dSTobias Sarnowski            ->with("d", DOKU_LEXER_UNMATCHED, strpos($doc,'d'))->will($this->returnValue(true));
466f8369d7dSTobias Sarnowski        $handler->expects($this->at(5))->method('caught')
467f8369d7dSTobias Sarnowski            ->with("</file>", DOKU_LEXER_EXIT, strpos($doc,'</file>'))->will($this->returnValue(true));
468f8369d7dSTobias Sarnowski
469de226116SAndreas Gohr        $lexer = new Lexer($handler, "ignore");
470f8369d7dSTobias Sarnowski        $lexer->addEntryPattern('<file>', "ignore", "caught");
471f8369d7dSTobias Sarnowski        $lexer->addExitPattern("(?<=d)</file>", "caught");
472f8369d7dSTobias Sarnowski        $lexer->addSpecialPattern('b','caught','special');
473f8369d7dSTobias Sarnowski        $lexer->mapHandler('special','caught');
474f8369d7dSTobias Sarnowski        $lexer->addPattern('c','caught');
475f8369d7dSTobias Sarnowski
476f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse($doc));
477f8369d7dSTobias Sarnowski    }
478f8369d7dSTobias Sarnowski
479f8369d7dSTobias Sarnowski    function testIndexLookbehindNotEqual() {
480f8369d7dSTobias Sarnowski        $doc = "aaa<file>bcd</file>eee";
481f8369d7dSTobias Sarnowski
482db5867f1SAndreas Gohr        $handler = $this->createMock('TestParserByteIndex');
483f8369d7dSTobias Sarnowski        $handler->expects($this->any())->method('ignore')->will($this->returnValue(true));
484f8369d7dSTobias Sarnowski        $handler->expects($this->at(1))->method('caught')
485f8369d7dSTobias Sarnowski            ->with("<file>", DOKU_LEXER_ENTER, strpos($doc,'<file>'))->will($this->returnValue(true));
486f8369d7dSTobias Sarnowski        $handler->expects($this->at(2))->method('caught')
487f8369d7dSTobias Sarnowski            ->with("b", DOKU_LEXER_SPECIAL, strpos($doc,'b'))->will($this->returnValue(true));
488f8369d7dSTobias Sarnowski        $handler->expects($this->at(3))->method('caught')
489f8369d7dSTobias Sarnowski            ->with("c", DOKU_LEXER_MATCHED, strpos($doc,'c'))->will($this->returnValue(true));
490f8369d7dSTobias Sarnowski        $handler->expects($this->at(4))->method('caught')
491f8369d7dSTobias Sarnowski            ->with("d", DOKU_LEXER_UNMATCHED, strpos($doc,'d'))->will($this->returnValue(true));
492f8369d7dSTobias Sarnowski        $handler->expects($this->at(5))->method('caught')
493f8369d7dSTobias Sarnowski            ->with("</file>", DOKU_LEXER_EXIT, strpos($doc,'</file>'))->will($this->returnValue(true));
494f8369d7dSTobias Sarnowski
495de226116SAndreas Gohr        $lexer = new Lexer($handler, 'ignore');
496f8369d7dSTobias Sarnowski        $lexer->addEntryPattern('<file>', 'ignore', 'caught');
497f8369d7dSTobias Sarnowski        $lexer->addExitPattern('(?<!c)</file>', 'caught');
498f8369d7dSTobias Sarnowski        $lexer->addSpecialPattern('b','caught','special');
499f8369d7dSTobias Sarnowski        $lexer->mapHandler('special','caught');
500f8369d7dSTobias Sarnowski        $lexer->addPattern('c','caught');
501f8369d7dSTobias Sarnowski
502f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse($doc));
503f8369d7dSTobias Sarnowski    }
504f8369d7dSTobias Sarnowski
505f8369d7dSTobias Sarnowski    /**
506f8369d7dSTobias Sarnowski     * This test is primarily to ensure the correct match is chosen
507f8369d7dSTobias Sarnowski     * when there are non-captured elements in the pattern.
508f8369d7dSTobias Sarnowski     */
509f8369d7dSTobias Sarnowski    function testIndexSelectCorrectMatch() {
510f8369d7dSTobias Sarnowski        $doc = "ALL FOOLS ARE FOO";
511f8369d7dSTobias Sarnowski        $pattern = '\bFOO\b';
512f8369d7dSTobias Sarnowski
513db5867f1SAndreas Gohr        $handler = $this->createMock('TestParserByteIndex');
514f8369d7dSTobias Sarnowski        $handler->expects($this->any())->method('ignore')->will($this->returnValue(true));
515f8369d7dSTobias Sarnowski
516f8369d7dSTobias Sarnowski        $matches = array();
517f8369d7dSTobias Sarnowski        preg_match('/'.$pattern.'/',$doc,$matches,PREG_OFFSET_CAPTURE);
518f8369d7dSTobias Sarnowski
519f8369d7dSTobias Sarnowski        $handler->expects($this->once())->method('caught')
520f8369d7dSTobias Sarnowski            ->with("FOO", DOKU_LEXER_SPECIAL, $matches[0][1])->will($this->returnValue(true));
521f8369d7dSTobias Sarnowski
522de226116SAndreas Gohr        $lexer = new Lexer($handler, "ignore");
523f8369d7dSTobias Sarnowski        $lexer->addSpecialPattern($pattern,'ignore','caught');
524f8369d7dSTobias Sarnowski
525f8369d7dSTobias Sarnowski        $this->assertTrue($lexer->parse($doc));
526f8369d7dSTobias Sarnowski    }
527f8369d7dSTobias Sarnowski
528f8369d7dSTobias Sarnowski}
529