xref: /dokuwiki/_test/tests/Parsing/ParserMode/InternallinkTest.php (revision 2e43b79909f3bc04928779d886f68c1242b5d436)
1<?php
2
3namespace dokuwiki\test\Parsing\ParserMode;
4
5use dokuwiki\Parsing\ParserMode\Internallink;
6
7/**
8 * Tests for the {@see Internallink} parser mode: `[[target|title]]` dispatch.
9 *
10 * Covers internal pages, namespaces, section refs, interwiki labels, and the cases where the target
11 * dispatches to externallink (URL inside [[ ]]), emaillink (email inside [[ ]]), windowssharelink, or
12 * a media payload as the link title.
13 *
14 * @group parser_links
15 */
16class InternallinkTest extends ParserTestBase
17{
18    function testOneChar() {
19        $this->P->addMode('internallink', new Internallink());
20        $this->P->parse("Foo [[l]] Bar");
21        $calls = [
22            ['document_start', []],
23            ['p_open', []],
24            ['cdata', ["\n" . 'Foo ']],
25            ['internallink', ['l', null]],
26            ['cdata', [' Bar']],
27            ['p_close', []],
28            ['document_end', []],
29        ];
30        $this->assertCalls($calls, $this->H->calls);
31    }
32
33    function testNoChar() {
34        $this->P->addMode('internallink', new Internallink());
35        $this->P->parse("Foo [[]] Bar");
36        $calls = [
37            ['document_start', []],
38            ['p_open', []],
39            ['cdata', ["\n" . 'Foo ']],
40            ['internallink', ['', null]],
41            ['cdata', [' Bar']],
42            ['p_close', []],
43            ['document_end', []],
44        ];
45        $this->assertCalls($calls, $this->H->calls);
46    }
47
48    function testNamespaceNoTitle() {
49        $this->P->addMode('internallink', new Internallink());
50        $this->P->parse("Foo [[foo:bar]] Bar");
51        $calls = [
52            ['document_start', []],
53            ['p_open', []],
54            ['cdata', ["\n" . 'Foo ']],
55            ['internallink', ['foo:bar', null]],
56            ['cdata', [' Bar']],
57            ['p_close', []],
58            ['document_end', []],
59        ];
60        $this->assertCalls($calls, $this->H->calls);
61    }
62
63    function testNamespace() {
64        $this->P->addMode('internallink', new Internallink());
65        $this->P->parse("Foo [[x:1:y:foo_bar:z|Test]] Bar");
66        $calls = [
67            ['document_start', []],
68            ['p_open', []],
69            ['cdata', ["\n" . 'Foo ']],
70            ['internallink', ['x:1:y:foo_bar:z', 'Test']],
71            ['cdata', [' Bar']],
72            ['p_close', []],
73            ['document_end', []],
74        ];
75        $this->assertCalls($calls, $this->H->calls);
76    }
77
78    function testSectionRef() {
79        $this->P->addMode('internallink', new Internallink());
80        $this->P->parse("Foo [[wiki:syntax#internal|Syntax]] Bar");
81        $calls = [
82            ['document_start', []],
83            ['p_open', []],
84            ['cdata', ["\n" . 'Foo ']],
85            ['internallink', ['wiki:syntax#internal', 'Syntax']],
86            ['cdata', [' Bar']],
87            ['p_close', []],
88            ['document_end', []],
89        ];
90        $this->assertCalls($calls, $this->H->calls);
91    }
92
93    function testCodeFollows() {
94        $this->P->addMode('internallink', new Internallink());
95        $this->P->parse("Foo [[wiki:internal:link|Test]] Bar <code>command [arg1 [arg2 [arg3]]]</code>");
96        $calls = [
97            ['document_start', []],
98            ['p_open', []],
99            ['cdata', ["\n" . 'Foo ']],
100            ['internallink', ['wiki:internal:link', 'Test']],
101            ['cdata', [' Bar <code>command [arg1 [arg2 [arg3]]]</code>']],
102            ['p_close', []],
103            ['document_end', []],
104        ];
105        $this->assertCalls($calls, $this->H->calls);
106    }
107
108    function testCodeFollows2() {
109        $this->P->addMode('internallink', new Internallink());
110        $this->P->parse("Foo [[wiki:internal:link|[Square brackets in title] Test]] Bar <code>command [arg1 [arg2 [arg3]]]</code>");
111        $calls = [
112            ['document_start', []],
113            ['p_open', []],
114            ['cdata', ["\n" . 'Foo ']],
115            ['internallink', ['wiki:internal:link', '[Square brackets in title] Test']],
116            ['cdata', [' Bar <code>command [arg1 [arg2 [arg3]]]</code>']],
117            ['p_close', []],
118            ['document_end', []],
119        ];
120        $this->assertCalls($calls, $this->H->calls);
121    }
122
123    function testTwoLinks() {
124        $this->P->addMode('internallink', new Internallink());
125        $this->P->parse("Foo [[foo:bar|one]] and [[bar:foo|two]] Bar");
126        $calls = [
127            ['document_start', []],
128            ['p_open', []],
129            ['cdata', ["\n" . 'Foo ']],
130            ['internallink', ['foo:bar', 'one']],
131            ['cdata', [' and ']],
132            ['internallink', ['bar:foo', 'two']],
133            ['cdata', [' Bar']],
134            ['p_close', []],
135            ['document_end', []],
136        ];
137        $this->assertCalls($calls, $this->H->calls);
138    }
139
140    // ----- dispatch to externallink -----
141
142    function testExternalUrlInside() {
143        $this->P->addMode('internallink', new Internallink());
144        $this->P->parse("Foo [[http://www.google.com|Google]] Bar");
145        $calls = [
146            ['document_start', []],
147            ['p_open', []],
148            ['cdata', ["\n" . 'Foo ']],
149            ['externallink', ['http://www.google.com', 'Google']],
150            ['cdata', [' Bar']],
151            ['p_close', []],
152            ['document_end', []],
153        ];
154        $this->assertCalls($calls, $this->H->calls);
155    }
156
157    function testExternalUrlWithBracketsInside() {
158        $this->P->addMode('internallink', new Internallink());
159        $this->P->parse("Foo [[http://www.google.com?test[]=squarebracketsinurl|Google]] Bar");
160        $calls = [
161            ['document_start', []],
162            ['p_open', []],
163            ['cdata', ["\n" . 'Foo ']],
164            ['externallink', ['http://www.google.com?test[]=squarebracketsinurl', 'Google']],
165            ['cdata', [' Bar']],
166            ['p_close', []],
167            ['document_end', []],
168        ];
169        $this->assertCalls($calls, $this->H->calls);
170    }
171
172    function testExternalUrlWithBracketsInsideCodeFollows() {
173        $this->P->addMode('internallink', new Internallink());
174        $this->P->parse("Foo [[http://www.google.com?test[]=squarebracketsinurl|Google]] Bar <code>command [arg1 [arg2 [arg3]]]</code>");
175        $calls = [
176            ['document_start', []],
177            ['p_open', []],
178            ['cdata', ["\n" . 'Foo ']],
179            ['externallink', ['http://www.google.com?test[]=squarebracketsinurl', 'Google']],
180            ['cdata', [' Bar <code>command [arg1 [arg2 [arg3]]]</code>']],
181            ['p_close', []],
182            ['document_end', []],
183        ];
184        $this->assertCalls($calls, $this->H->calls);
185    }
186
187    function testFileSchemeInside() {
188        $this->P->addMode('internallink', new Internallink());
189        $this->P->parse('Foo [[file://temp/file.txt|Some File]] Bar');
190        $calls = [
191            ['document_start', []],
192            ['p_open', []],
193            ['cdata', ["\n" . 'Foo ']],
194            ['externallink', ['file://temp/file.txt', 'Some File']],
195            ['cdata', [' Bar']],
196            ['p_close', []],
197            ['document_end', []],
198        ];
199        $this->assertCalls($calls, $this->H->calls);
200    }
201
202    // ----- dispatch to interwikilink -----
203
204    function testInterwikiLink() {
205        $this->P->addMode('internallink', new Internallink());
206        $this->P->parse("Foo [[iw>somepage|Some Page]] Bar");
207        $calls = [
208            ['document_start', []],
209            ['p_open', []],
210            ['cdata', ["\n" . 'Foo ']],
211            ['interwikilink', ['iw>somepage', 'Some Page', 'iw', 'somepage']],
212            ['cdata', [' Bar']],
213            ['p_close', []],
214            ['document_end', []],
215        ];
216        $this->assertCalls($calls, $this->H->calls);
217    }
218
219    function testInterwikiLinkCase() {
220        $this->P->addMode('internallink', new Internallink());
221        $this->P->parse("Foo [[IW>somepage|Some Page]] Bar");
222        $calls = [
223            ['document_start', []],
224            ['p_open', []],
225            ['cdata', ["\n" . 'Foo ']],
226            ['interwikilink', ['IW>somepage', 'Some Page', 'iw', 'somepage']],
227            ['cdata', [' Bar']],
228            ['p_close', []],
229            ['document_end', []],
230        ];
231        $this->assertCalls($calls, $this->H->calls);
232    }
233
234    function testInterwikiPedia() {
235        $this->P->addMode('internallink', new Internallink());
236        $this->P->parse("Foo [[wp>Callback_(computer_science)|callbacks]] Bar");
237        $calls = [
238            ['document_start', []],
239            ['p_open', []],
240            ['cdata', ["\n" . 'Foo ']],
241            ['interwikilink', ['wp>Callback_(computer_science)', 'callbacks', 'wp', 'Callback_(computer_science)']],
242            ['cdata', [' Bar']],
243            ['p_close', []],
244            ['document_end', []],
245        ];
246        $this->assertCalls($calls, $this->H->calls);
247    }
248
249    // ----- media payload as link title -----
250
251    function testMediaImageAsTitle() {
252        $this->P->addMode('internallink', new Internallink());
253        $this->P->parse("Foo [[x:1:y:foo_bar:z|{{img.gif?10x20nocache|Some Image}}]] Bar");
254
255        $image = [
256            'type'    => 'internalmedia',
257            'src'     => 'img.gif',
258            'title'   => 'Some Image',
259            'align'   => null,
260            'width'   => 10,
261            'height'  => 20,
262            'cache'   => 'nocache',
263            'linking' => 'details',
264        ];
265
266        $calls = [
267            ['document_start', []],
268            ['p_open', []],
269            ['cdata', ["\n" . 'Foo ']],
270            ['internallink', ['x:1:y:foo_bar:z', $image]],
271            ['cdata', [' Bar']],
272            ['p_close', []],
273            ['document_end', []],
274        ];
275        $this->assertCalls($calls, $this->H->calls);
276    }
277
278    function testMediaNonImageAsTitle() {
279        $this->P->addMode('internallink', new Internallink());
280        $this->P->parse("Foo [[x:1:y:foo_bar:z|{{foo.txt?10x20nocache|Some Image}}]] Bar");
281
282        $image = [
283            'type'    => 'internalmedia',
284            'src'     => 'foo.txt',
285            'title'   => 'Some Image',
286            'align'   => null,
287            'width'   => 10,
288            'height'  => 20,
289            'cache'   => 'nocache',
290            'linking' => 'details',
291        ];
292
293        $calls = [
294            ['document_start', []],
295            ['p_open', []],
296            ['cdata', ["\n" . 'Foo ']],
297            ['internallink', ['x:1:y:foo_bar:z', $image]],
298            ['cdata', [' Bar']],
299            ['p_close', []],
300            ['document_end', []],
301        ];
302        $this->assertCalls($calls, $this->H->calls);
303    }
304
305    function testMediaAsEmailLinkTitle() {
306        $this->P->addMode('internallink', new Internallink());
307        $this->P->parse("Foo [[foo@example.com|{{img.gif?10x20nocache|Some Image}}]] Bar");
308
309        $image = [
310            'type'    => 'internalmedia',
311            'src'     => 'img.gif',
312            'title'   => 'Some Image',
313            'align'   => null,
314            'width'   => 10,
315            'height'  => 20,
316            'cache'   => 'nocache',
317            'linking' => 'details',
318        ];
319
320        $calls = [
321            ['document_start', []],
322            ['p_open', []],
323            ['cdata', ["\n" . 'Foo ']],
324            ['emaillink', ['foo@example.com', $image]],
325            ['cdata', [' Bar']],
326            ['p_close', []],
327            ['document_end', []],
328        ];
329        $this->assertCalls($calls, $this->H->calls);
330    }
331}
332