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