xref: /dokuwiki/_test/tests/Parsing/ParserMode/ListsTest.php (revision 75364f13219a5af44f52c564ea0a62df64c3a17f)
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