1<?php
2
3use dokuwiki\Parsing\ParserMode\Camelcaselink;
4use dokuwiki\Parsing\ParserMode\Emaillink;
5use dokuwiki\Parsing\ParserMode\Externallink;
6use dokuwiki\Parsing\ParserMode\Filelink;
7use dokuwiki\Parsing\ParserMode\Internallink;
8use dokuwiki\Parsing\ParserMode\Media;
9use dokuwiki\Parsing\ParserMode\Windowssharelink;
10
11require_once 'parser.inc.php';
12
13/**
14 * Tests for the implementation of link syntax
15 *
16 * @group parser_links
17*/
18class TestOfDoku_Parser_Links extends TestOfDoku_Parser {
19
20    function testExternalLinkSimple() {
21        $this->P->addMode('externallink',new Externallink());
22        $this->P->parse("Foo http://www.google.com Bar");
23        $calls = array (
24            array('document_start',array()),
25            array('p_open',array()),
26            array('cdata',array("\n".'Foo ')),
27            array('externallink',array('http://www.google.com', NULL)),
28            array('cdata',array(' Bar')),
29            array('p_close',array()),
30            array('document_end',array()),
31        );
32        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
33    }
34
35    function testExternalLinkCase() {
36        $this->P->addMode('externallink',new Externallink());
37        $this->P->parse("Foo HTTP://WWW.GOOGLE.COM Bar");
38        $calls = array (
39            array('document_start',array()),
40            array('p_open',array()),
41            array('cdata',array("\n".'Foo ')),
42            array('externallink',array('HTTP://WWW.GOOGLE.COM', NULL)),
43            array('cdata',array(' Bar')),
44            array('p_close',array()),
45            array('document_end',array()),
46        );
47        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
48    }
49
50    function testExternalIPv4() {
51        $this->P->addMode('externallink',new Externallink());
52        $this->P->parse("Foo http://123.123.3.21/foo Bar");
53        $calls = array (
54            array('document_start',array()),
55            array('p_open',array()),
56            array('cdata',array("\n".'Foo ')),
57            array('externallink',array('http://123.123.3.21/foo', NULL)),
58            array('cdata',array(' Bar')),
59            array('p_close',array()),
60            array('document_end',array()),
61        );
62        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
63    }
64
65    function testExternalIPv6() {
66        $this->P->addMode('externallink',new Externallink());
67        $this->P->parse("Foo http://[3ffe:2a00:100:7031::1]/foo Bar");
68        $calls = array (
69            array('document_start',array()),
70            array('p_open',array()),
71            array('cdata',array("\n".'Foo ')),
72            array('externallink',array('http://[3ffe:2a00:100:7031::1]/foo', NULL)),
73            array('cdata',array(' Bar')),
74            array('p_close',array()),
75            array('document_end',array()),
76        );
77        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
78    }
79
80    function testExternalMulti(){
81        $this->teardown();
82
83        $links = array(
84            'http://www.google.com',
85            'HTTP://WWW.GOOGLE.COM',
86            'http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html',
87            'http://[1080:0:0:0:8:800:200C:417A]/index.html',
88            'http://[3ffe:2a00:100:7031::1]',
89            'http://[1080::8:800:200C:417A]/foo',
90            'http://[::192.9.5.5]/ipng',
91            'http://[::FFFF:129.144.52.38]:80/index.html',
92            'http://[2010:836B:4179::836B:4179]',
93        );
94        $titles = array(false,null,'foo bar');
95        foreach($links as $link){
96            foreach($titles as $title){
97                if($title === false){
98                    $source = $link;
99                    $name   = null;
100                }elseif($title === null){
101                    $source = "[[$link]]";
102                    $name   = null;
103                }else{
104                    $source = "[[$link|$title]]";
105                    $name   = $title;
106                }
107                $this->setup();
108                $this->P->addMode('internallink',new Internallink());
109                $this->P->addMode('externallink',new Externallink());
110                $this->P->parse("Foo $source Bar");
111                $calls = array (
112                    array('document_start',array()),
113                    array('p_open',array()),
114                    array('cdata',array("\n".'Foo ')),
115                    array('externallink',array($link, $name)),
116                    array('cdata',array(' Bar')),
117                    array('p_close',array()),
118                    array('document_end',array()),
119                );
120                $this->assertEquals(array_map('stripByteIndex',$this->H->calls), $calls, $source);
121                $this->teardown();
122            }
123        }
124
125        $this->setup();
126    }
127
128    function testExternalLinkJavascript() {
129        $this->P->addMode('externallink',new Externallink());
130        $this->P->parse("Foo javascript:alert('XSS'); Bar");
131        $calls = array (
132            array('document_start',array()),
133            array('p_open',array()),
134            array('cdata',array("\nFoo javascript:alert('XSS'); Bar")),
135            array('p_close',array()),
136            array('document_end',array()),
137        );
138        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
139    }
140
141    function testExternalWWWLink() {
142        $this->P->addMode('externallink',new Externallink());
143        $this->P->parse("Foo www.google.com Bar");
144        $calls = array (
145            array('document_start',array()),
146            array('p_open',array()),
147            array('cdata',array("\n".'Foo ')),
148            array('externallink',array('http://www.google.com', 'www.google.com')),
149            array('cdata',array(' Bar')),
150            array('p_close',array()),
151            array('document_end',array()),
152        );
153        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
154    }
155
156    function testExternalWWWLinkStartOfLine() {
157        // Regression test for issue #2399
158        $calls = array (
159            array('document_start',array()),
160            array('p_open',array()),
161            array('externallink',array('http://www.google.com', 'www.google.com')),
162            array('cdata',array(' Bar')),
163            array('p_close',array()),
164            array('document_end',array()),
165        );
166        $instructions = p_get_instructions("www.google.com Bar");
167        $this->assertEquals(array_map('stripByteIndex',$instructions),$calls);
168    }
169
170    function testExternalWWWLinkInRoundBrackets() {
171        $this->P->addMode('externallink',new ExternalLink());
172        $this->P->parse("Foo (www.google.com) Bar");
173        $calls = array (
174            array('document_start',array()),
175            array('p_open',array()),
176            array('cdata',array("\n".'Foo (')),
177            array('externallink',array('http://www.google.com', 'www.google.com')),
178            array('cdata',array(') Bar')),
179            array('p_close',array()),
180            array('document_end',array()),
181        );
182        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
183    }
184
185    function testExternalWWWLinkInPath() {
186        $this->P->addMode('externallink',new Externallink());
187        // See issue #936. Should NOT generate a link!
188        $this->P->parse("Foo /home/subdir/www/www.something.de/somedir/ Bar");
189        $calls = array (
190            array('document_start',array()),
191            array('p_open',array()),
192            array('cdata',array("\n".'Foo /home/subdir/www/www.something.de/somedir/ Bar')),
193            array('p_close',array()),
194            array('document_end',array()),
195        );
196        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
197    }
198
199    function testExternalWWWLinkFollowingPath() {
200        $this->P->addMode('externallink',new Externallink());
201        $this->P->parse("Foo /home/subdir/www/ www.something.de/somedir/ Bar");
202        $calls = array (
203            array('document_start',array()),
204            array('p_open',array()),
205            array('cdata',array("\n".'Foo /home/subdir/www/ ')),
206            array('externallink',array('http://www.something.de/somedir/', 'www.something.de/somedir/')),
207            array('cdata',array(' Bar')),
208            array('p_close',array()),
209            array('document_end',array()),
210        );
211        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
212    }
213
214    function testExternalFTPLink() {
215        $this->P->addMode('externallink',new Externallink());
216        $this->P->parse("Foo ftp.sunsite.com Bar");
217        $calls = array (
218            array('document_start',array()),
219            array('p_open',array()),
220            array('cdata',array("\n".'Foo ')),
221            array('externallink',array('ftp://ftp.sunsite.com', 'ftp.sunsite.com')),
222            array('cdata',array(' Bar')),
223            array('p_close',array()),
224            array('document_end',array()),
225        );
226        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
227    }
228
229    function testExternalFTPLinkInPath() {
230        $this->P->addMode('externallink',new Externallink());
231        // See issue #936. Should NOT generate a link!
232        $this->P->parse("Foo /home/subdir/www/ftp.something.de/somedir/ Bar");
233        $calls = array (
234            array('document_start',array()),
235            array('p_open',array()),
236            array('cdata',array("\n".'Foo /home/subdir/www/ftp.something.de/somedir/ Bar')),
237            array('p_close',array()),
238            array('document_end',array()),
239        );
240        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
241    }
242
243    function testExternalFTPLinkFollowingPath() {
244        $this->P->addMode('externallink',new Externallink());
245        $this->P->parse("Foo /home/subdir/www/ ftp.something.de/somedir/ Bar");
246        $calls = array (
247            array('document_start',array()),
248            array('p_open',array()),
249            array('cdata',array("\n".'Foo /home/subdir/www/ ')),
250            array('externallink',array('ftp://ftp.something.de/somedir/', 'ftp.something.de/somedir/')),
251            array('cdata',array(' Bar')),
252            array('p_close',array()),
253            array('document_end',array()),
254        );
255        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
256    }
257
258    function testEmail() {
259        $this->P->addMode('emaillink',new Emaillink());
260        $this->P->parse("Foo <bugs@php.net> Bar");
261        $calls = array (
262            array('document_start',array()),
263            array('p_open',array()),
264            array('cdata',array("\n".'Foo ')),
265            array('emaillink',array('bugs@php.net', NULL)),
266            array('cdata',array(' Bar')),
267            array('p_close',array()),
268            array('document_end',array()),
269        );
270        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
271    }
272
273    function testEmailRFC2822() {
274        $this->P->addMode('emaillink',new Emaillink());
275        $this->P->parse("Foo <~fix+bug's.for/ev{e}r@php.net> Bar");
276        $calls = array (
277            array('document_start',array()),
278            array('p_open',array()),
279            array('cdata',array("\n".'Foo ')),
280            array('emaillink',array("~fix+bug's.for/ev{e}r@php.net", NULL)),
281            array('cdata',array(' Bar')),
282            array('p_close',array()),
283            array('document_end',array()),
284        );
285        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
286    }
287
288    function testEmailCase() {
289        $this->P->addMode('emaillink',new Emaillink());
290        $this->P->parse("Foo <bugs@pHp.net> Bar");
291        $calls = array (
292            array('document_start',array()),
293            array('p_open',array()),
294            array('cdata',array("\n".'Foo ')),
295            array('emaillink',array('bugs@pHp.net', NULL)),
296            array('cdata',array(' Bar')),
297            array('p_close',array()),
298            array('document_end',array()),
299        );
300        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
301    }
302
303
304    function testInternalLinkOneChar() {
305        $this->P->addMode('internallink',new Internallink());
306        $this->P->parse("Foo [[l]] Bar");
307        $calls = array (
308            array('document_start',array()),
309            array('p_open',array()),
310            array('cdata',array("\n".'Foo ')),
311            array('internallink',array('l',NULL)),
312            array('cdata',array(' Bar')),
313            array('p_close',array()),
314            array('document_end',array()),
315        );
316        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
317    }
318
319    function testInternalLinkNoChar() {
320        $this->P->addMode('internallink',new Internallink());
321        $this->P->parse("Foo [[]] Bar");
322        $calls = array (
323            array('document_start',array()),
324            array('p_open',array()),
325            array('cdata',array("\n".'Foo ')),
326            array('internallink',array('',NULL)),
327            array('cdata',array(' Bar')),
328            array('p_close',array()),
329            array('document_end',array()),
330        );
331        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
332    }
333
334    function testInternalLinkNamespaceNoTitle() {
335        $this->P->addMode('internallink',new Internallink());
336        $this->P->parse("Foo [[foo:bar]] Bar");
337        $calls = array (
338            array('document_start',array()),
339            array('p_open',array()),
340            array('cdata',array("\n".'Foo ')),
341            array('internallink',array('foo:bar',NULL)),
342            array('cdata',array(' Bar')),
343            array('p_close',array()),
344            array('document_end',array()),
345        );
346        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
347    }
348
349    function testInternalLinkNamespace() {
350        $this->P->addMode('internallink',new Internallink());
351        $this->P->parse("Foo [[x:1:y:foo_bar:z|Test]] Bar");
352        $calls = array (
353            array('document_start',array()),
354            array('p_open',array()),
355            array('cdata',array("\n".'Foo ')),
356            array('internallink',array('x:1:y:foo_bar:z','Test')),
357            array('cdata',array(' Bar')),
358            array('p_close',array()),
359            array('document_end',array()),
360        );
361        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
362    }
363
364    function testInternalLinkSectionRef() {
365        $this->P->addMode('internallink',new Internallink());
366        $this->P->parse("Foo [[wiki:syntax#internal|Syntax]] Bar");
367        $calls = array (
368            array('document_start',array()),
369            array('p_open',array()),
370            array('cdata',array("\n".'Foo ')),
371            array('internallink',array('wiki:syntax#internal','Syntax')),
372            array('cdata',array(' Bar')),
373            array('p_close',array()),
374            array('document_end',array()),
375        );
376        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
377    }
378
379    function testInternalLinkCodeFollows() {
380        $this->P->addMode('internallink',new Internallink());
381        $this->P->parse("Foo [[wiki:internal:link|Test]] Bar <code>command [arg1 [arg2 [arg3]]]</code>");
382        $calls = array (
383            array('document_start',array()),
384            array('p_open',array()),
385            array('cdata',array("\n".'Foo ')),
386            array('internallink',array('wiki:internal:link','Test')),
387            array('cdata',array(' Bar <code>command [arg1 [arg2 [arg3]]]</code>')),
388            array('p_close',array()),
389            array('document_end',array()),
390        );
391        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
392    }
393
394    function testInternalLinkCodeFollows2() {
395        $this->P->addMode('internallink',new Internallink());
396        $this->P->parse("Foo [[wiki:internal:link|[Square brackets in title] Test]] Bar <code>command [arg1 [arg2 [arg3]]]</code>");
397        $calls = array (
398            array('document_start',array()),
399            array('p_open',array()),
400            array('cdata',array("\n".'Foo ')),
401            array('internallink',array('wiki:internal:link','[Square brackets in title] Test')),
402            array('cdata',array(' Bar <code>command [arg1 [arg2 [arg3]]]</code>')),
403            array('p_close',array()),
404            array('document_end',array()),
405        );
406        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
407    }
408
409    function testExternalInInternalLink() {
410        $this->P->addMode('internallink',new Internallink());
411        $this->P->parse("Foo [[http://www.google.com|Google]] Bar");
412        $calls = array (
413            array('document_start',array()),
414            array('p_open',array()),
415            array('cdata',array("\n".'Foo ')),
416            array('externallink',array('http://www.google.com','Google')),
417            array('cdata',array(' Bar')),
418            array('p_close',array()),
419            array('document_end',array()),
420        );
421        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
422    }
423
424    function testExternalInInternalLink2() {
425        $this->P->addMode('internallink',new Internallink());
426        $this->P->parse("Foo [[http://www.google.com?test[]=squarebracketsinurl|Google]] Bar");
427        $calls = array (
428            array('document_start',array()),
429            array('p_open',array()),
430            array('cdata',array("\n".'Foo ')),
431            array('externallink',array('http://www.google.com?test[]=squarebracketsinurl','Google')),
432            array('cdata',array(' Bar')),
433            array('p_close',array()),
434            array('document_end',array()),
435        );
436        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
437    }
438
439    function testExternalInInternalLink2CodeFollows() {
440        $this->P->addMode('internallink',new Internallink());
441        $this->P->parse("Foo [[http://www.google.com?test[]=squarebracketsinurl|Google]] Bar <code>command [arg1 [arg2 [arg3]]]</code>");
442        $calls = array (
443            array('document_start',array()),
444            array('p_open',array()),
445            array('cdata',array("\n".'Foo ')),
446            array('externallink',array('http://www.google.com?test[]=squarebracketsinurl','Google')),
447            array('cdata',array(' Bar <code>command [arg1 [arg2 [arg3]]]</code>')),
448            array('p_close',array()),
449            array('document_end',array()),
450        );
451        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
452    }
453
454    function testTwoInternalLinks() {
455        $this->P->addMode('internallink',new Internallink());
456        $this->P->parse("Foo [[foo:bar|one]] and [[bar:foo|two]] Bar");
457        $calls = array (
458            array('document_start',array()),
459            array('p_open',array()),
460            array('cdata',array("\n".'Foo ')),
461            array('internallink',array('foo:bar','one')),
462            array('cdata',array(' and ')),
463            array('internallink',array('bar:foo','two')),
464            array('cdata',array(' Bar')),
465            array('p_close',array()),
466            array('document_end',array()),
467        );
468        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
469    }
470
471
472    function testInterwikiLink() {
473        $this->P->addMode('internallink',new Internallink());
474        $this->P->parse("Foo [[iw>somepage|Some Page]] Bar");
475        $calls = array (
476            array('document_start',array()),
477            array('p_open',array()),
478            array('cdata',array("\n".'Foo ')),
479            array('interwikilink',array('iw>somepage','Some Page','iw','somepage')),
480            array('cdata',array(' Bar')),
481            array('p_close',array()),
482            array('document_end',array()),
483        );
484        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
485    }
486
487    function testInterwikiLinkCase() {
488        $this->P->addMode('internallink',new Internallink());
489        $this->P->parse("Foo [[IW>somepage|Some Page]] Bar");
490        $calls = array (
491            array('document_start',array()),
492            array('p_open',array()),
493            array('cdata',array("\n".'Foo ')),
494            array('interwikilink',array('IW>somepage','Some Page','iw','somepage')),
495            array('cdata',array(' Bar')),
496            array('p_close',array()),
497            array('document_end',array()),
498        );
499        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
500    }
501
502    function testInterwikiPedia() {
503        $this->P->addMode('internallink',new Internallink());
504        $this->P->parse("Foo [[wp>Callback_(computer_science)|callbacks]] Bar");
505        $calls = array (
506            array('document_start',array()),
507            array('p_open',array()),
508            array('cdata',array("\n".'Foo ')),
509            array('interwikilink',array('wp>Callback_(computer_science)','callbacks','wp','Callback_(computer_science)')),
510            array('cdata',array(' Bar')),
511            array('p_close',array()),
512            array('document_end',array()),
513        );
514        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
515    }
516
517    function testCamelCase() {
518        $this->P->addMode('camelcaselink',new Camelcaselink());
519        $this->P->parse("Foo FooBar Bar");
520        $calls = array (
521            array('document_start',array()),
522            array('p_open',array()),
523            array('cdata',array("\n".'Foo ')),
524            array('camelcaselink',array('FooBar')),
525            array('cdata',array(' Bar')),
526            array('p_close',array()),
527            array('document_end',array()),
528        );
529        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
530    }
531
532    function testFileLink() {
533        $this->P->addMode('filelink',new FileLink());
534        $this->P->parse('Foo file://temp/file.txt Bar');
535        $calls = array (
536            array('document_start',array()),
537            array('p_open',array()),
538            array('cdata',array("\n".'Foo ')),
539            array('filelink',array('file://temp/file.txt ',NULL)),
540            array('cdata',array('Bar')),
541            array('p_close',array()),
542            array('document_end',array()),
543        );
544        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
545    }
546
547    function testFileLinkInternal() {
548        $this->P->addMode('internallink',new Internallink());
549        $this->P->parse('Foo [[file://temp/file.txt|Some File]] Bar');
550        $calls = array (
551            array('document_start',array()),
552            array('p_open',array()),
553            array('cdata',array("\n".'Foo ')),
554            array('externallink',array('file://temp/file.txt','Some File')),
555            array('cdata',array(' Bar')),
556            array('p_close',array()),
557            array('document_end',array()),
558        );
559        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
560    }
561
562    function testWindowsShareLink() {
563        $this->P->addMode('windowssharelink',new Windowssharelink());
564        $this->P->parse('Foo \\\server\share Bar');
565        $calls = array (
566            array('document_start',array()),
567            array('p_open',array()),
568            array('cdata',array("\n".'Foo ')),
569            array('windowssharelink',array('\\\server\share',NULL)),
570            array('cdata',array(' Bar')),
571            array('p_close',array()),
572            array('document_end',array()),
573        );
574        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
575    }
576
577    function testWindowsShareLinkHyphen() {
578        $this->P->addMode('windowssharelink',new Windowssharelink());
579        $this->P->parse('Foo \\\server\share-hyphen Bar');
580        $calls = array (
581        array('document_start',array()),
582        array('p_open',array()),
583        array('cdata',array("\n".'Foo ')),
584        array('windowssharelink',array('\\\server\share-hyphen',NULL)),
585        array('cdata',array(' Bar')),
586        array('p_close',array()),
587        array('document_end',array()),
588        );
589        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
590    }
591
592    function testWindowsShareLinkInternal() {
593        $this->P->addMode('internallink',new Internallink());
594        $this->P->parse('Foo [[\\\server\share|My Documents]] Bar');
595        $calls = array (
596            array('document_start',array()),
597            array('p_open',array()),
598            array('cdata',array("\n".'Foo ')),
599            array('windowssharelink',array('\\\server\share','My Documents')),
600            array('cdata',array(' Bar')),
601            array('p_close',array()),
602            array('document_end',array()),
603        );
604        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
605    }
606
607    function testMediaInternal() {
608        $this->P->addMode('media',new Media());
609        $this->P->parse('Foo {{img.gif}} Bar');
610        $calls = array (
611            array('document_start',array()),
612            array('p_open',array()),
613            array('cdata',array("\n".'Foo ')),
614            array('internalmedia',array('img.gif',NULL,NULL,NULL,NULL,'cache','details')),
615            array('cdata',array(' Bar')),
616            array('p_close',array()),
617            array('document_end',array()),
618        );
619        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
620    }
621
622    function testMediaInternalLinkOnly() {
623        $this->P->addMode('media',new Media());
624        $this->P->parse('Foo {{img.gif?linkonly}} Bar');
625        $calls = array (
626            array('document_start',array()),
627            array('p_open',array()),
628            array('cdata',array("\n".'Foo ')),
629            array('internalmedia',array('img.gif',NULL,NULL,NULL,NULL,'cache','linkonly')),
630            array('cdata',array(' Bar')),
631            array('p_close',array()),
632            array('document_end',array()),
633        );
634        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
635    }
636
637    function testMediaNotImage() {
638        $this->P->addMode('media',new Media());
639        $this->P->parse('Foo {{foo.txt?10x10|Some File}} Bar');
640        $calls = array (
641            array('document_start',array()),
642            array('p_open',array()),
643            array('cdata',array("\n".'Foo ')),
644            array('internalmedia',array('foo.txt','Some File',null,10,10,'cache','details')),
645            array('cdata',array(' Bar')),
646            array('p_close',array()),
647            array('document_end',array()),
648        );
649        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
650    }
651
652    function testMediaInternalLAlign() {
653        $this->P->addMode('media',new Media());
654        $this->P->parse('Foo {{img.gif }} Bar');
655        $calls = array (
656            array('document_start',array()),
657            array('p_open',array()),
658            array('cdata',array("\n".'Foo ')),
659            array('internalmedia',array('img.gif',NULL,'left',NULL,NULL,'cache','details')),
660            array('cdata',array(' Bar')),
661            array('p_close',array()),
662            array('document_end',array()),
663        );
664        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
665    }
666
667    function testMediaInternalRAlign() {
668        $this->P->addMode('media',new Media());
669        $this->P->parse('Foo {{ img.gif}} Bar');
670        $calls = array (
671            array('document_start',array()),
672            array('p_open',array()),
673            array('cdata',array("\n".'Foo ')),
674            array('internalmedia',array('img.gif',NULL,'right',NULL,NULL,'cache','details')),
675            array('cdata',array(' Bar')),
676            array('p_close',array()),
677            array('document_end',array()),
678        );
679        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
680    }
681
682    function testMediaInternalCenter() {
683        $this->P->addMode('media',new Media());
684        $this->P->parse('Foo {{ img.gif }} Bar');
685        $calls = array (
686            array('document_start',array()),
687            array('p_open',array()),
688            array('cdata',array("\n".'Foo ')),
689            array('internalmedia',array('img.gif',NULL,'center',NULL,NULL,'cache','details')),
690            array('cdata',array(' Bar')),
691            array('p_close',array()),
692            array('document_end',array()),
693        );
694        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
695    }
696
697    function testMediaInternalParams() {
698        $this->P->addMode('media',new Media());
699        $this->P->parse('Foo {{img.gif?50x100nocache}} Bar');
700        $calls = array (
701            array('document_start',array()),
702            array('p_open',array()),
703            array('cdata',array("\n".'Foo ')),
704            array('internalmedia',array('img.gif',NULL,NULL,'50','100','nocache','details')),
705            array('cdata',array(' Bar')),
706            array('p_close',array()),
707            array('document_end',array()),
708        );
709        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
710    }
711
712    function testMediaInternalTitle() {
713        $this->P->addMode('media',new Media());
714        $this->P->parse('Foo {{img.gif?50x100|Some Image}} Bar');
715        $calls = array (
716            array('document_start',array()),
717            array('p_open',array()),
718            array('cdata',array("\n".'Foo ')),
719            array('internalmedia',array('img.gif','Some Image',NULL,'50','100','cache','details')),
720            array('cdata',array(' Bar')),
721            array('p_close',array()),
722            array('document_end',array()),
723        );
724        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
725    }
726
727    function testMediaExternal() {
728        $this->P->addMode('media',new Media());
729        $this->P->parse('Foo {{http://www.google.com/img.gif}} Bar');
730        $calls = array (
731            array('document_start',array()),
732            array('p_open',array()),
733            array('cdata',array("\n".'Foo ')),
734            array('externalmedia',array('http://www.google.com/img.gif',NULL,NULL,NULL,NULL,'cache','details')),
735            array('cdata',array(' Bar')),
736            array('p_close',array()),
737            array('document_end',array()),
738        );
739        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
740    }
741
742    function testMediaExternalParams() {
743        $this->P->addMode('media',new Media());
744        $this->P->parse('Foo {{http://www.google.com/img.gif?50x100nocache}} Bar');
745        $calls = array (
746            array('document_start',array()),
747            array('p_open',array()),
748            array('cdata',array("\n".'Foo ')),
749            array('externalmedia',array('http://www.google.com/img.gif',NULL,NULL,'50','100','nocache','details')),
750            array('cdata',array(' Bar')),
751            array('p_close',array()),
752            array('document_end',array()),
753        );
754        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
755    }
756
757    function testMediaExternalTitle() {
758        $this->P->addMode('media',new Media());
759        $this->P->parse('Foo {{http://www.google.com/img.gif?50x100|Some Image}} Bar');
760        $calls = array (
761            array('document_start',array()),
762            array('p_open',array()),
763            array('cdata',array("\n".'Foo ')),
764            array('externalmedia',
765            array('http://www.google.com/img.gif','Some Image',NULL,'50','100','cache','details')),
766            array('cdata',array(' Bar')),
767            array('p_close',array()),
768            array('document_end',array()),
769        );
770        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
771    }
772
773    function testMediaInInternalLink() {
774        $this->P->addMode('internallink',new Internallink());
775        $this->P->parse("Foo [[x:1:y:foo_bar:z|{{img.gif?10x20nocache|Some Image}}]] Bar");
776
777        $image = array(
778            'type'=>'internalmedia',
779            'src'=>'img.gif',
780            'title'=>'Some Image',
781            'align'=>NULL,
782            'width'=>10,
783            'height'=>20,
784            'cache'=>'nocache',
785            'linking'=>'details',
786        );
787
788        $calls = array (
789            array('document_start',array()),
790            array('p_open',array()),
791            array('cdata',array("\n".'Foo ')),
792            array('internallink',array('x:1:y:foo_bar:z',$image)),
793            array('cdata',array(' Bar')),
794            array('p_close',array()),
795            array('document_end',array()),
796        );
797        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
798    }
799
800    function testMediaNoImageInInternalLink() {
801        $this->P->addMode('internallink',new Internallink());
802        $this->P->parse("Foo [[x:1:y:foo_bar:z|{{foo.txt?10x20nocache|Some Image}}]] Bar");
803
804        $image = array(
805            'type'=>'internalmedia',
806            'src'=>'foo.txt',
807            'title'=>'Some Image',
808            'align'=>NULL,
809            'width'=>10,
810            'height'=>20,
811            'cache'=>'nocache',
812            'linking'=>'details',
813        );
814
815        $calls = array (
816            array('document_start',array()),
817            array('p_open',array()),
818            array('cdata',array("\n".'Foo ')),
819            array('internallink',array('x:1:y:foo_bar:z',$image)),
820            array('cdata',array(' Bar')),
821            array('p_close',array()),
822            array('document_end',array()),
823        );
824        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
825    }
826
827    function testMediaInEmailLink() {
828        $this->P->addMode('internallink',new Internallink());
829        $this->P->parse("Foo [[foo@example.com|{{img.gif?10x20nocache|Some Image}}]] Bar");
830
831        $image = array(
832            'type'=>'internalmedia',
833            'src'=>'img.gif',
834            'title'=>'Some Image',
835            'align'=>NULL,
836            'width'=>10,
837            'height'=>20,
838            'cache'=>'nocache',
839            'linking'=>'details',
840        );
841
842        $calls = array (
843            array('document_start',array()),
844            array('p_open',array()),
845            array('cdata',array("\n".'Foo ')),
846            array('emaillink',array('foo@example.com',$image)),
847            array('cdata',array(' Bar')),
848            array('p_close',array()),
849            array('document_end',array()),
850        );
851        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
852    }
853
854    function testNestedMedia() {
855        $this->P->addMode('media',new Media());
856        $this->P->parse('Foo {{img.gif|{{foo.gif|{{bar.gif|Bar}}}}}} Bar');
857        $calls = array (
858            array('document_start',array()),
859            array('p_open',array()),
860            array('cdata',array("\n".'Foo ')),
861            array('internalmedia',
862            array('img.gif','{{foo.gif|{{bar.gif|Bar',NULL,NULL,NULL,'cache','details')),
863            array('cdata',array('}}}} Bar')),
864            array('p_close',array()),
865            array('document_end',array()),
866        );
867        $this->assertEquals(array_map('stripByteIndex',$this->H->calls),$calls);
868    }
869
870}
871
872