1<?php 2 3namespace dokuwiki\test\Parsing\ParserMode; 4 5use dokuwiki\Parsing\Handler\Lists; 6use dokuwiki\Parsing\ParserMode\Eol; 7use dokuwiki\Parsing\ParserMode\Footnote; 8use dokuwiki\Parsing\ParserMode\Strong; 9use dokuwiki\Parsing\ParserMode\Linebreak; 10use dokuwiki\Parsing\ParserMode\Listblock; 11use dokuwiki\Parsing\ParserMode\Unformatted; 12 13class ListsTest extends ParserTestBase 14{ 15 16 function testUnorderedList() { 17 $this->P->addMode('listblock',new Listblock()); 18 $this->P->parse(' 19 *A 20 * B 21 * C 22'); 23 $calls = [ 24 ['document_start',[]], 25 ['listu_open',[]], 26 ['listitem_open',[1,Lists::NODE]], 27 ['listcontent_open',[]], 28 ['cdata',["A"]], 29 ['listcontent_close',[]], 30 ['listu_open',[]], 31 ['listitem_open',[2]], 32 ['listcontent_open',[]], 33 ['cdata',[' B']], 34 ['listcontent_close',[]], 35 ['listitem_close',[]], 36 ['listu_close',[]], 37 ['listitem_close',[]], 38 ['listitem_open',[1]], 39 ['listcontent_open',[]], 40 ['cdata',[' C']], 41 ['listcontent_close',[]], 42 ['listitem_close',[]], 43 ['listu_close',[]], 44 ['document_end',[]], 45 ]; 46 $this->assertCalls($calls, $this->H->calls); 47 } 48 49 function testOrderedList() { 50 $this->P->addMode('listblock',new Listblock()); 51 $this->P->parse(' 52 -A 53 - B 54 - C 55'); 56 $calls = [ 57 ['document_start',[]], 58 ['listo_open',[]], 59 ['listitem_open',[1,Lists::NODE]], 60 ['listcontent_open',[]], 61 ['cdata',["A"]], 62 ['listcontent_close',[]], 63 ['listo_open',[]], 64 ['listitem_open',[2]], 65 ['listcontent_open',[]], 66 ['cdata',[' B']], 67 ['listcontent_close',[]], 68 ['listitem_close',[]], 69 ['listo_close',[]], 70 ['listitem_close',[]], 71 ['listitem_open',[1]], 72 ['listcontent_open',[]], 73 ['cdata',[' C']], 74 ['listcontent_close',[]], 75 ['listitem_close',[]], 76 ['listo_close',[]], 77 ['document_end',[]], 78 ]; 79 $this->assertCalls($calls, $this->H->calls); 80 } 81 82 83 function testMixedList() { 84 $this->P->addMode('listblock',new Listblock()); 85 $this->P->parse(' 86 -A 87 * B 88 - C 89'); 90 $calls = [ 91 ['document_start',[]], 92 ['listo_open',[]], 93 ['listitem_open',[1,Lists::NODE]], 94 ['listcontent_open',[]], 95 ['cdata',["A"]], 96 ['listcontent_close',[]], 97 ['listu_open',[]], 98 ['listitem_open',[2]], 99 ['listcontent_open',[]], 100 ['cdata',[' B']], 101 ['listcontent_close',[]], 102 ['listitem_close',[]], 103 ['listu_close',[]], 104 ['listitem_close',[]], 105 ['listitem_open',[1]], 106 ['listcontent_open',[]], 107 ['cdata',[' C']], 108 ['listcontent_close',[]], 109 ['listitem_close',[]], 110 ['listo_close',[]], 111 ['document_end',[]], 112 ]; 113 $this->assertCalls($calls, $this->H->calls); 114 } 115 116 function testUnorderedListWinEOL() { 117 $this->P->addMode('listblock',new Listblock()); 118 $this->P->parse("\r\n *A\r\n * B\r\n * C\r\n"); 119 $calls = [ 120 ['document_start',[]], 121 ['listu_open',[]], 122 ['listitem_open',[1,Lists::NODE]], 123 ['listcontent_open',[]], 124 ['cdata',["A"]], 125 ['listcontent_close',[]], 126 ['listu_open',[]], 127 ['listitem_open',[2]], 128 ['listcontent_open',[]], 129 ['cdata',[' B']], 130 ['listcontent_close',[]], 131 ['listitem_close',[]], 132 ['listu_close',[]], 133 ['listitem_close',[]], 134 ['listitem_open',[1]], 135 ['listcontent_open',[]], 136 ['cdata',[' C']], 137 ['listcontent_close',[]], 138 ['listitem_close',[]], 139 ['listu_close',[]], 140 ['document_end',[]], 141 ]; 142 $this->assertCalls($calls, $this->H->calls); 143 } 144 145 function testOrderedListWinEOL() { 146 $this->P->addMode('listblock',new Listblock()); 147 $this->P->parse("\r\n -A\r\n - B\r\n - C\r\n"); 148 $calls = [ 149 ['document_start',[]], 150 ['listo_open',[]], 151 ['listitem_open',[1,Lists::NODE]], 152 ['listcontent_open',[]], 153 ['cdata',["A"]], 154 ['listcontent_close',[]], 155 ['listo_open',[]], 156 ['listitem_open',[2]], 157 ['listcontent_open',[]], 158 ['cdata',[' B']], 159 ['listcontent_close',[]], 160 ['listitem_close',[]], 161 ['listo_close',[]], 162 ['listitem_close',[]], 163 ['listitem_open',[1]], 164 ['listcontent_open',[]], 165 ['cdata',[' C']], 166 ['listcontent_close',[]], 167 ['listitem_close',[]], 168 ['listo_close',[]], 169 ['document_end',[]], 170 ]; 171 $this->assertCalls($calls, $this->H->calls); 172 } 173 174 function testNotAList() { 175 $this->P->addMode('listblock',new Listblock()); 176 $this->P->parse("Foo -bar *foo Bar"); 177 $calls = [ 178 ['document_start',[]], 179 ['p_open',[]], 180 ['cdata',["\nFoo -bar *foo Bar"]], 181 ['p_close',[]], 182 ['document_end',[]], 183 ]; 184 $this->assertCalls($calls, $this->H->calls); 185 } 186 187 function testUnorderedListParagraph() { 188 $this->P->addMode('listblock',new Listblock()); 189 $this->P->addMode('eol',new Eol()); 190 $this->P->parse('Foo 191 *A 192 * B 193 * C 194Bar'); 195 $calls = [ 196 ['document_start',[]], 197 ['p_open',[]], 198 ['cdata',["Foo"]], 199 ['p_close',[]], 200 ['listu_open',[]], 201 ['listitem_open',[1,Lists::NODE]], 202 ['listcontent_open',[]], 203 ['cdata',["A"]], 204 ['listcontent_close',[]], 205 ['listu_open',[]], 206 ['listitem_open',[2]], 207 ['listcontent_open',[]], 208 ['cdata',[' B']], 209 ['listcontent_close',[]], 210 ['listitem_close',[]], 211 ['listu_close',[]], 212 ['listitem_close',[]], 213 ['listitem_open',[1]], 214 ['listcontent_open',[]], 215 ['cdata',[' C']], 216 ['listcontent_close',[]], 217 ['listitem_close',[]], 218 ['listu_close',[]], 219 ['p_open',[]], 220 ['cdata',["Bar"]], 221 ['p_close',[]], 222 ['document_end',[]], 223 ]; 224 $this->assertCalls($calls, $this->H->calls); 225 } 226 227 // Bold must not spread across list items. Each item's `**` opener has 228 // to find its own closer within the item (flanking rules: non-whitespace 229 // before the closing `**`); otherwise the `**` stays literal. 230 function testUnorderedListStrong() { 231 $this->P->addMode('listblock',new Listblock()); 232 $this->P->addMode('strong',new Strong()); 233 $this->P->parse(' 234 ***A** 235 *** B 236 * C** 237'); 238 $calls = [ 239 ['document_start',[]], 240 ['listu_open',[]], 241 ['listitem_open',[1,Lists::NODE]], 242 ['listcontent_open',[]], 243 ['strong_open',[]], 244 ['cdata',["A"]], 245 ['strong_close',[]], 246 ['listcontent_close',[]], 247 ['listu_open',[]], 248 ['listitem_open',[2]], 249 ['listcontent_open',[]], 250 ['cdata',["** B"]], 251 ['listcontent_close',[]], 252 ['listitem_close',[]], 253 ['listu_close',[]], 254 ['listitem_close',[]], 255 ['listitem_open',[1]], 256 ['listcontent_open',[]], 257 ['cdata',[" C**"]], 258 ['listcontent_close',[]], 259 ['listitem_close',[]], 260 ['listu_close',[]], 261 ['document_end',[]], 262 ]; 263 $this->assertCalls($calls, $this->H->calls); 264 } 265 266 // This is really a failing test - unformatted able to spread across list items 267 // Problem is fixing it would mean a major rewrite of lists 268 function testUnorderedListUnformatted() { 269 $this->P->addMode('listblock',new Listblock()); 270 $this->P->addMode('unformatted',new Unformatted()); 271 $this->P->parse(' 272 *%%A%% 273 *%% B 274 * C%% 275'); 276 $calls = [ 277 ['document_start',[]], 278 ['listu_open',[]], 279 ['listitem_open',[1,Lists::NODE]], 280 ['listcontent_open',[]], 281 ['unformatted',["A"]], 282 ['listcontent_close',[]], 283 ['listu_open',[]], 284 ['listitem_open',[2]], 285 ['listcontent_open',[]], 286 ['unformatted',[" B\n * C"]], 287 ['listcontent_close',[]], 288 ['listitem_close',[]], 289 ['listu_close',[]], 290 ['listitem_close',[]], 291 ['listu_close',[]], 292 ['document_end',[]], 293 ]; 294 $this->assertCalls($calls, $this->H->calls); 295 } 296 297 function testUnorderedListLinebreak() { 298 $this->P->addMode('listblock',new Listblock()); 299 $this->P->addMode('linebreak',new Linebreak()); 300 $this->P->parse(' 301 *A\\\\ D 302 * B 303 * C 304'); 305 $calls = [ 306 ['document_start',[]], 307 ['listu_open',[]], 308 ['listitem_open',[1,Lists::NODE]], 309 ['listcontent_open',[]], 310 ['cdata',["A"]], 311 ['linebreak',[]], 312 ['cdata',["D"]], 313 ['listcontent_close',[]], 314 ['listu_open',[]], 315 ['listitem_open',[2]], 316 ['listcontent_open',[]], 317 ['cdata',[' B']], 318 ['listcontent_close',[]], 319 ['listitem_close',[]], 320 ['listu_close',[]], 321 ['listitem_close',[]], 322 ['listitem_open',[1]], 323 ['listcontent_open',[]], 324 ['cdata',[' C']], 325 ['listcontent_close',[]], 326 ['listitem_close',[]], 327 ['listu_close',[]], 328 ['document_end',[]], 329 ]; 330 $this->assertCalls($calls, $this->H->calls); 331 } 332 333 function testUnorderedListLinebreak2() { 334 $this->P->addMode('listblock',new Listblock()); 335 $this->P->addMode('linebreak',new Linebreak()); 336 $this->P->parse(' 337 *A\\\\ 338 * B 339'); 340 $calls = [ 341 ['document_start',[]], 342 ['listu_open',[]], 343 ['listitem_open',[1]], 344 ['listcontent_open',[]], 345 ['cdata',["A"]], 346 ['linebreak',[]], 347 ['listcontent_close',[]], 348 ['listitem_close',[]], 349 ['listitem_open',[1]], 350 ['listcontent_open',[]], 351 ['cdata',[' B']], 352 ['listcontent_close',[]], 353 ['listitem_close',[]], 354 ['listu_close',[]], 355 ['document_end',[]], 356 ]; 357 $this->assertCalls($calls, $this->H->calls); 358 } 359 360 function testUnorderedListFootnote() { 361 $this->P->addMode('listblock',new Listblock()); 362 $this->P->addMode('footnote',new Footnote()); 363 $this->P->parse("\n *((A))\n *(( B\n * C )) \n\n"); 364 $calls = [ 365 ['document_start',[]], 366 ['listu_open',[]], 367 ['listitem_open',[1,Lists::NODE]], 368 ['listcontent_open',[]], 369 ['nest', [ [ 370 ['footnote_open',[]], 371 ['cdata',["A"]], 372 ['footnote_close',[]] 373 ]]], 374 ['listcontent_close',[]], 375 ['listu_open',[]], 376 ['listitem_open',[2]], 377 ['listcontent_open',[]], 378 ['nest', [ [ 379 ['footnote_open',[]], 380 ['cdata',[" B"]], 381 ['listu_open',[]], 382 ['listitem_open',[1]], 383 ['listcontent_open',[]], 384 ['cdata',[" C )) "]], 385 ['listcontent_close',[]], 386 ['listitem_close',[]], 387 ['listu_close',[]], 388 ['cdata',["\n\n"]], 389 ['footnote_close',[]] 390 ]]], 391 ['listcontent_close',[]], 392 ['listitem_close',[]], 393 ['listu_close',[]], 394 ['listitem_close',[]], 395 ['listu_close',[]], 396 ['document_end',[]] 397 ]; 398 399 $this->assertCalls($calls, $this->H->calls); 400 } 401} 402