Tiny refactoring
[org-mode.git] / testing / lisp / test-org-list.el
blob1fc1b4de4d2d680a19c84586592946491cac68c3
1 ;;; test-org-list.el --- Tests for org-list.el
3 ;; Copyright (C) 2012, 2013, 2014 Nicolas Goaziou
5 ;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
7 ;; This program is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
12 ;; This program is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ;;; Code:
22 (ert-deftest test-org-list/list-ending ()
23 "Test if lists end at the right place."
24 ;; With two blank lines.
25 (org-test-with-temp-text "- item\n\n\n Text"
26 (goto-line 4)
27 (should-not (org-in-item-p)))
28 ;; With text less indented than top items.
29 (org-test-with-temp-text "- item\nText"
30 (goto-line 2)
31 (should-not (org-in-item-p)))
32 ;; Though, blank lines and text indentation is ignored in blocks.
33 (org-test-with-temp-text
34 "- item\n #+begin_quote\n\n\nText at column 0\n #+end_quote\n Text"
35 (goto-line 7)
36 (should (org-in-item-p))))
38 (ert-deftest test-org-list/list-navigation ()
39 "Test list navigation specifications."
40 (org-test-with-temp-text "
41 - item A
42 - item B
45 - item 1
46 - item 1.1
47 - item 1.2
48 - item 1.3
49 - item 2
52 - item X
53 - item Y"
54 (let ((org-list-use-circular-motion nil))
55 ;; 1. Test `org-next-item'.
57 ;; 1.1. Should return an error if at last item in
58 ;; a list/sub-list, unless `org-list-use-circular-motion'
59 ;; is non-nil.
60 (goto-line 9)
61 (should-error (org-next-item))
62 (let ((org-list-use-circular-motion t))
63 (should (progn (org-next-item) t)))
64 (goto-line 14)
65 (should-error (org-next-item))
66 (let ((org-list-use-circular-motion t))
67 (should (progn (org-next-item) t)))
68 ;; 1.2. Should jump over sub-lists.
69 (goto-line 6)
70 (org-next-item)
71 (should (looking-at "- item 2"))
72 ;; 1.3. Shouldn't move to another list.
73 (goto-line 3)
74 (should-error (org-next-item))
75 (should-not (looking-at "- item 1"))
76 ;; 1.4. Should move to the list/sub-list first item when
77 ;; `org-list-use-circular-motion' is non-nil.
78 (let ((org-list-use-circular-motion t))
79 (goto-line 10)
80 (org-next-item)
81 (should (looking-at "- item 1"))
82 (goto-line 9)
83 (org-next-item)
84 (should (looking-at " - item 1.1")))
85 ;; 2. Test `org-previous-item'.
87 ;; 2.1. Should return an error if at first item in
88 ;; a list/sub-list, unless `org-list-use-circular-motion is
89 ;; non-nil.
90 (goto-line 7)
91 (should-error (org-previous-item))
92 (let ((org-list-use-circular-motion t))
93 (should (progn (org-previous-item) t)))
94 (goto-line 13)
95 (should-error (org-previous-item))
96 (let ((org-list-use-circular-motion t))
97 (should (progn (org-previous-item) t)))
98 ;; 2.2. Should ignore sub-lists.
99 (goto-line 10)
100 (org-previous-item)
101 (should (looking-at "- item 1"))
102 ;; 2.3. Shouldn't move to another list.
103 (goto-line 6)
104 (should-error (org-previous-item))
105 (should-not (looking-at "- item B"))
106 ;; 2.4. Should move to the list/sub-list last item when
107 ;; `org-list-use-circular-motion' is non-nil.
108 (let ((org-list-use-circular-motion t))
109 (goto-line 6)
110 (org-previous-item)
111 (should (looking-at "- item 2"))
112 (goto-line 7)
113 (org-previous-item)
114 (should (looking-at " - item 1.3"))))))
116 (ert-deftest test-org-list/cycle-bullet ()
117 "Test `org-cycle-list-bullet' specifications."
118 ;; Error when not at an item.
119 (should-error
120 (org-test-with-temp-text "Paragraph"
121 (org-cycle-list-bullet)))
122 ;; Cycle through "-", "+", "*", "1.", "1)".
123 (org-test-with-temp-text " - item"
124 (org-cycle-list-bullet)
125 (should (looking-at "[ \t]+\\+"))
126 (org-cycle-list-bullet)
127 (should (looking-at "[ \t]+\\*"))
128 (let ((org-plain-list-ordered-item-terminator t))
129 (org-cycle-list-bullet))
130 (should (looking-at "[ \t]+1\\."))
131 (let ((org-plain-list-ordered-item-terminator t))
132 (org-cycle-list-bullet))
133 (should (looking-at "[ \t]+1)")))
134 ;; Argument is a valid bullet: cycle to that bullet directly.
135 (should
136 (equal "1. item"
137 (org-test-with-temp-text "- item"
138 (let ((org-plain-list-ordered-item-terminator t))
139 (org-cycle-list-bullet "1.")
140 (buffer-string)))))
141 ;; Argument is an integer N: cycle to the Nth allowed bullet.
142 (should
143 (equal "+ item"
144 (org-test-with-temp-text "1. item"
145 (let ((org-plain-list-ordered-item-terminator t))
146 (org-cycle-list-bullet 1)
147 (buffer-string)))))
148 ;; Argument is `previous': cycle backwards.
149 (should
150 (equal "- item"
151 (org-test-with-temp-text "+ item"
152 (let ((org-plain-list-ordered-item-terminator t))
153 (org-cycle-list-bullet 'previous)
154 (buffer-string)))))
155 ;; Do not cycle to "*" bullets when item is at column 0.
156 (should
157 (equal "1. item"
158 (org-test-with-temp-text "+ item"
159 (let ((org-plain-list-ordered-item-terminator t))
160 (org-cycle-list-bullet)
161 (buffer-string)))))
162 ;; Do not cycle to numbered bullets in a description list.
163 (should-not
164 (equal "1. tag :: item"
165 (org-test-with-temp-text "+ tag :: item"
166 (let ((org-plain-list-ordered-item-terminator t))
167 (org-cycle-list-bullet)
168 (buffer-string)))))
169 ;; Do not cycle to ordered item terminators if they are not allowed
170 ;; in `org-plain-list-ordered-item-terminator'.
171 (should
172 (equal " 1) item"
173 (org-test-with-temp-text " * item"
174 (let ((org-plain-list-ordered-item-terminator 41))
175 (org-cycle-list-bullet)
176 (buffer-string)))))
177 ;; When `org-list-allow-alphabetical' is non-nil, cycle to alpha bullets.
178 (should
179 (equal "a. item"
180 (org-test-with-temp-text "1) item"
181 (let ((org-plain-list-ordered-item-terminator t)
182 (org-list-allow-alphabetical t))
183 (org-cycle-list-bullet)
184 (buffer-string)))))
185 ;; Do not cycle to alpha bullets when list has more than 26
186 ;; elements.
187 (should-not
188 (equal "a. item 1"
189 (org-test-with-temp-text "1) item 1
190 2) item 2
191 3) item 3
192 4) item 4
193 5) item 5
194 6) item 6
195 7) item 7
196 8) item 8
197 9) item 9
198 10) item 10
199 11) item 11
200 12) item 12
201 13) item 13
202 14) item 14
203 15) item 15
204 16) item 16
205 17) item 17
206 18) item 18
207 19) item 19
208 20) item 20
209 21) item 21
210 22) item 22
211 23) item 23
212 24) item 24
213 25) item 25
214 26) item 26
215 27) item 27"
216 (let ((org-plain-list-ordered-item-terminator t)
217 (org-list-allow-alphabetical t))
218 (org-cycle-list-bullet)
219 (buffer-substring (point) (line-end-position)))))))
221 (ert-deftest test-org-list/indent-item ()
222 "Test `org-indent-item' specifications."
223 ;; 1. Error when not at an item.
224 (org-test-with-temp-text "Paragraph."
225 (should-error (org-indent-item)))
226 ;; 2. Error when trying to move first item of a list.
227 (org-test-with-temp-text "
228 - Item 1
229 - Item 2"
230 (forward-line)
231 (should-error (org-indent-item)))
232 ;; 3. Indent a single item, not its children.
233 (org-test-with-temp-text "
234 - Item 1
235 - Item 2
236 - Item 2.1"
237 (search-forward "- Item 2")
238 (let (org-list-demote-modify-bullet) (org-indent-item))
239 (should (equal (buffer-string)
241 - Item 1
242 - Item 2
243 - Item 2.1")))
244 ;; 4. Follow `org-list-demote-modify-bullet' specifications.
246 ;; 4.1. With unordered lists.
247 (org-test-with-temp-text "
248 - Item 1
249 - Item 2"
250 (search-forward "- Item 2")
251 (let ((org-list-demote-modify-bullet '(("-" . "+")))) (org-indent-item))
252 (should (equal (buffer-string)
254 - Item 1
255 + Item 2")))
256 ;; 4.2. and ordered lists.
257 (org-test-with-temp-text "
258 1. Item 1
259 2. Item 2"
260 (search-forward "2. Item 2")
261 (let ((org-plain-list-ordered-item-terminator t)
262 (org-list-demote-modify-bullet '(("1." . "+"))))
263 (org-indent-item))
264 (should (equal (buffer-string)
266 1. Item 1
267 + Item 2")))
268 ;; 5. When a region is selected, indent every item within.
269 (org-test-with-temp-text "
270 - Item 1
271 - Item 2
272 - Item 3
274 (search-forward "- Item 2")
275 (beginning-of-line)
276 (transient-mark-mode 1)
277 (push-mark (point) t t)
278 (goto-char (point-max))
279 (let (org-list-demote-modify-bullet) (org-indent-item))
280 (should (equal (buffer-string)
282 - Item 1
283 - Item 2
284 - Item 3
285 "))))
287 (ert-deftest test-org-list/indent-item-tree ()
288 "Test `org-indent-item-tree' specifications."
289 ;; 1. Error when not at an item.
290 (org-test-with-temp-text "Paragraph."
291 (should-error (org-indent-item-tree)))
292 ;; 2. Indent item along with its children.
293 (org-test-with-temp-text "
294 - Item 1
295 - Item 2
296 - Item 2.1"
297 (search-forward "- Item 2")
298 (let (org-list-demote-modify-bullet) (org-indent-item-tree))
299 (should (equal (buffer-string)
301 - Item 1
302 - Item 2
303 - Item 2.1")))
304 ;; 3. Special case: When indenting top item, move the whole list.
305 (org-test-with-temp-text "
306 - Item 1
307 - Item 2"
308 (search-forward "- Item 1")
309 (let (org-list-demote-modify-bullet org-odd-levels-only)
310 (org-indent-item-tree))
311 (should (equal (buffer-string)
313 - Item 1
314 - Item 2")))
315 ;; 4. Follow `org-list-demote-modify-bullet' specifications.
317 ;; 4.1. With unordered lists.
318 (org-test-with-temp-text "
319 - Item 1
320 - Item 2
321 + Item 2.1"
322 (search-forward "- Item 2")
323 (let ((org-list-demote-modify-bullet '(("-" . "+") ("+" . "-"))))
324 (org-indent-item-tree))
325 (should (equal (buffer-string)
327 - Item 1
328 + Item 2
329 - Item 2.1")))
330 ;; 4.2. and ordered lists.
331 (org-test-with-temp-text "
332 1. Item 1
333 2. Item 2
334 + Item 2.1"
335 (search-forward "2. Item 2")
336 (let ((org-plain-list-ordered-item-terminator t)
337 (org-list-demote-modify-bullet '(("1." . "+") ("+" . "1."))))
338 (org-indent-item-tree))
339 (should (equal (buffer-string)
341 1. Item 1
342 + Item 2
343 1. Item 2.1")))
344 ;; 5. When a region is selected, indent every item within.
345 (org-test-with-temp-text "
346 - Item 1
347 - Item 2
348 - Item 2.1
349 - Item 3
350 - Item 3.1
352 (search-forward "- Item 2")
353 (beginning-of-line)
354 (transient-mark-mode 1)
355 (push-mark (point) t t)
356 (goto-char (point-max))
357 (let (org-list-demote-modify-bullet) (org-indent-item-tree))
358 (should (equal (buffer-string)
360 - Item 1
361 - Item 2
362 - Item 2.1
363 - Item 3
364 - Item 3.1
365 "))))
367 (ert-deftest test-org-list/outdent-item ()
368 "Test `org-outdent-item' specifications."
369 ;; 1. Error when not at an item.
370 (org-test-with-temp-text "Paragraph."
371 (should-error (org-outdent-item)))
372 ;; 2. Error when trying to move first item of a list.
373 (org-test-with-temp-text "
374 - Item 1
375 - Item 2"
376 (forward-line)
377 (should-error (org-outdent-item)))
378 ;; 3. Error when trying to outdent an item without its children.
379 (org-test-with-temp-text "
380 - Item 1
381 - Item 1.1
382 - Item 1.1.1"
383 (search-forward "- Item 1.1")
384 (should-error (org-outdent-item)))
385 ;; 4. Error when trying to outdent before top item.
386 (org-test-with-temp-text "
387 - Item 1
388 - Item 2"
389 (search-forward "- Item 2")
390 (should-error (org-outdent-item)))
391 ;; 5. When a region is selected, outdent every item within.
392 (org-test-with-temp-text "
393 - Item 1
394 - Item 2
395 - Item 3
397 (search-forward "- Item 2")
398 (beginning-of-line)
399 (transient-mark-mode 1)
400 (push-mark (point) t t)
401 (goto-char (point-max))
402 (let (org-list-demote-modify-bullet) (org-outdent-item))
403 (should (equal (buffer-string)
405 - Item 1
406 - Item 2
407 - Item 3
408 "))))
410 (ert-deftest test-org-list/outdent-item-tree ()
411 "Test `org-outdent-item-tree' specifications."
412 ;; 1. Error when not at an item.
413 (org-test-with-temp-text "Paragraph."
414 (should-error (org-outdent-item-tree)))
415 ;; 2. Error when trying to outdent before top item.
416 (org-test-with-temp-text "
417 - Item 1
418 - Item 2"
419 (search-forward "- Item 2")
420 (should-error (org-outdent-item-tree)))
421 ;; 3. Outdent item along with its children.
422 (org-test-with-temp-text "
423 - Item 1
424 - Item 2
425 - Item 2.1"
426 (search-forward "- Item 2")
427 (org-outdent-item-tree)
428 (should (equal (buffer-string)
430 - Item 1
431 - Item 2
432 - Item 2.1")))
433 ;; 3. Special case: When outdenting top item, move the whole list.
434 (org-test-with-temp-text "
435 - Item 1
436 - Item 2"
437 (search-forward "- Item 1")
438 (let (org-odd-levels-only) (org-outdent-item-tree))
439 (should (equal (buffer-string)
441 - Item 1
442 - Item 2")))
443 ;; 5. When a region is selected, outdent every item within.
444 (org-test-with-temp-text "
445 - Item 1
446 - Item 2
447 - Item 2.1
448 - Item 3
449 - Item 3.1
451 (search-forward "- Item 2")
452 (beginning-of-line)
453 (transient-mark-mode 1)
454 (push-mark (point) t t)
455 (goto-char (point-max))
456 (org-outdent-item-tree)
457 (should (equal (buffer-string)
459 - Item 1
460 - Item 2
461 - Item 2.1
462 - Item 3
463 - Item 3.1
464 "))))
466 (ert-deftest test-org-list/move-item-down ()
467 "Test `org-move-item-down' specifications."
468 ;; Standard test.
469 (org-test-with-temp-text "- item 1\n- item 2"
470 (org-move-item-down)
471 (should (equal (buffer-string)
472 "- item 2\n- item 1")))
473 ;; Keep same column in item.
474 (org-test-with-temp-text "- item 1\n- item 2"
475 (forward-char 4)
476 (org-move-item-down)
477 (should (looking-at "em 1")))
478 ;; Move sub-items.
479 (org-test-with-temp-text "- item 1\n - sub-item 1\n- item 2"
480 (org-move-item-down)
481 (should (equal (buffer-string)
482 "- item 2\n- item 1\n - sub-item 1")))
483 ;; Preserve blank lines.
484 (should
485 (equal
486 "- item 2\n\n- item 1"
487 (org-test-with-temp-text "- item 1\n\n- item 2"
488 (org-move-item-down)
489 (buffer-string))))
490 ;; Error when trying to move the last item...
491 (org-test-with-temp-text "- item 1\n- item 2"
492 (forward-line)
493 (should-error (org-move-item-down)))
494 ;; ... unless `org-list-use-circular-motion' is non-nil. In this
495 ;; case, move to the first item.
496 (org-test-with-temp-text "- item 1\n- item 2\n- item 3"
497 (forward-line 2)
498 (let ((org-list-use-circular-motion t)) (org-move-item-down))
499 (should (equal (buffer-string) "- item 3\n- item 1\n- item 2\n")))
500 ;; Preserve item visibility.
501 (org-test-with-temp-text "* Headline\n- item 1\n body 1\n- item 2\n body 2"
502 (let ((org-cycle-include-plain-lists t))
503 (search-forward "- item 1")
504 (org-cycle)
505 (search-forward "- item 2")
506 (org-cycle))
507 (search-backward "- item 1")
508 (org-move-item-down)
509 (forward-line)
510 (should (org-invisible-p2))
511 (search-backward " body 2")
512 (should (org-invisible-p2)))
513 ;; Preserve children visibility.
514 (org-test-with-temp-text "* Headline
515 - item 1
516 - sub-item 1
517 sub-body 1
518 - item 2
519 - sub-item 2
520 sub-body 2"
521 (let ((org-cycle-include-plain-lists t))
522 (search-forward "- sub-item 1")
523 (org-cycle)
524 (search-forward "- sub-item 2")
525 (org-cycle))
526 (search-backward "- item 1")
527 (org-move-item-down)
528 (search-forward "sub-body 1")
529 (should (org-invisible-p2))
530 (search-backward "sub-body 2")
531 (should (org-invisible-p2)))
532 ;; Preserve contents visibility.
533 (org-test-with-temp-text "
534 - item 1
535 #+BEGIN_CENTER
536 Text1
537 #+END_CENTER
538 - item 2
539 #+BEGIN_CENTER
540 Text2
541 #+END_CENTER"
542 (org-hide-block-all)
543 (search-forward "- item 1")
544 (org-move-item-down)
545 (search-forward "Text1")
546 (should (org-invisible-p2))
547 (search-backward "Text2")
548 (should (org-invisible-p2))))
550 (ert-deftest test-org-list/move-item-up ()
551 "Test `org-move-item-up' specifications."
552 ;; Standard test.
553 (org-test-with-temp-text "- item 1\n- item 2"
554 (forward-line)
555 (org-move-item-up)
556 (should (equal (buffer-string)
557 "- item 2\n- item 1")))
558 ;; Keep same column in item.
559 (org-test-with-temp-text "- item 1\n- item 2"
560 (forward-line)
561 (forward-char 4)
562 (org-move-item-up)
563 (should (looking-at "em 2")))
564 ;; Move sub-items.
565 (org-test-with-temp-text "- item 1\n- item 2\n - sub-item 2"
566 (forward-line)
567 (org-move-item-up)
568 (should (equal (buffer-string)
569 "- item 2\n - sub-item 2\n- item 1")))
570 ;; Preserve blank lines.
571 (should
572 (equal
573 "- item 2\n\n- item 1"
574 (org-test-with-temp-text "- item 1\n\n- item 2"
575 (search-forward "- item 2")
576 (org-move-item-up)
577 (buffer-string))))
578 ;; Error when trying to move the first item...
579 (org-test-with-temp-text "- item 1\n- item 2"
580 (should-error (org-move-item-up)))
581 ;; ... unless `org-list-use-circular-motion' is non-nil. In this
582 ;; case, move to the first item.
583 (org-test-with-temp-text "- item 1\n- item 2\n- item 3"
584 (let ((org-list-use-circular-motion t)) (org-move-item-up))
585 (should (equal (buffer-string) "- item 2\n- item 3\n- item 1")))
586 ;; Preserve item visibility.
587 (org-test-with-temp-text "* Headline\n- item 1\n body 1\n- item 2\n body 2"
588 (let ((org-cycle-include-plain-lists t))
589 (search-forward "- item 1")
590 (org-cycle)
591 (search-forward "- item 2")
592 (org-cycle))
593 (org-move-item-up)
594 (forward-line)
595 (should (org-invisible-p2))
596 (search-forward " body 1")
597 (should (org-invisible-p2)))
598 ;; Preserve children visibility.
599 (org-test-with-temp-text "* Headline
600 - item 1
601 - sub-item 1
602 sub-body 1
603 - item 2
604 - sub-item 2
605 sub-body 2"
606 (let ((org-cycle-include-plain-lists t))
607 (search-forward "- sub-item 1")
608 (org-cycle)
609 (search-forward "- sub-item 2")
610 (org-cycle))
611 (search-backward "- item 2")
612 (org-move-item-up)
613 (search-forward "sub-body 2")
614 (should (org-invisible-p2))
615 (search-forward "sub-body 1")
616 (should (org-invisible-p2)))
617 ;; Preserve contents visibility.
618 (org-test-with-temp-text "
619 - item 1
620 #+BEGIN_CENTER
621 Text1
622 #+END_CENTER
623 - item 2
624 #+BEGIN_CENTER
625 Text2
626 #+END_CENTER"
627 (org-hide-block-all)
628 (search-forward "- item 2")
629 (org-move-item-up)
630 (search-forward "Text2")
631 (should (org-invisible-p2))
632 (search-forward "Text1")
633 (should (org-invisible-p2))))
635 (ert-deftest test-org-list/insert-item ()
636 "Test item insertion."
637 ;; Blank lines specifications.
639 ;; Non-nil `org-blank-before-new-entry': insert a blank line.
640 (should
641 (org-test-with-temp-text "- a"
642 (let ((org-blank-before-new-entry '((plain-list-item . t))))
643 (end-of-line)
644 (org-insert-item)
645 (forward-line -1)
646 (looking-at "$"))))
647 ;; Nil `org-blank-before-new-entry': do not insert a blank line.
648 (should-not
649 (org-test-with-temp-text "- a"
650 (let ((org-blank-before-new-entry '((plain-list-item . nil))))
651 (end-of-line)
652 (org-insert-item)
653 (forward-line -1)
654 (looking-at "$"))))
655 ;; `org-blank-before-new-entry' set to auto: if there's no blank
656 ;; line already in the sole item, do not insert one.
657 (should-not
658 (org-test-with-temp-text "- a"
659 (let ((org-blank-before-new-entry '((plain-list-item . auto))))
660 (end-of-line)
661 (org-insert-item)
662 (forward-line -1)
663 (looking-at "$"))))
664 ;; `org-blank-before-new-entry' set to `auto': if there's a blank
665 ;; line in the sole item, insert another one.
666 (should
667 (org-test-with-temp-text "- a\n\n b<point>"
668 (let ((org-blank-before-new-entry '((plain-list-item . auto))))
669 (org-insert-item)
670 (forward-line -1)
671 (looking-at "$"))))
672 ;; `org-blank-before-new-entry' set to `auto': if the user specified
673 ;; a blank line, preserve it.
674 (should
675 (org-test-with-temp-text "- a\n\n<point>"
676 (let ((org-blank-before-new-entry '((plain-list-item . auto))))
677 (org-insert-item)
678 (forward-line -1)
679 (looking-at "$"))))
680 ;; `org-blank-before-new-entry' set to `auto': if some items in list
681 ;; are already separated by blank lines, insert one.
682 (should
683 (org-test-with-temp-text "- a\n\n- b<point>"
684 (let ((org-blank-before-new-entry '((plain-list-item . auto))))
685 (org-insert-item)
686 (forward-line -1)
687 (looking-at "$"))))
688 (should
689 (org-test-with-temp-text "- a\n\n- b"
690 (let ((org-blank-before-new-entry '((plain-list-item . auto))))
691 (org-insert-item)
692 (forward-line)
693 (looking-at "$"))))
694 (should
695 (org-test-with-temp-text
696 "- a\n #+BEGIN_EXAMPLE\n\n x\n #+END_EXAMPLE<point>"
697 (let ((org-blank-before-new-entry '((plain-list-item . auto))))
698 (org-insert-item)
699 (forward-line -1)
700 (looking-at "$"))))
701 ;; When called before or on the bullet, insert new item before
702 ;; current one.
703 (should
704 (equal "- \n- item"
705 (org-test-with-temp-text "- item"
706 (org-insert-item)
707 (buffer-string))))
708 (should
709 (equal "- \n- item"
710 (org-test-with-temp-text "- <point>item"
711 (org-insert-item)
712 (buffer-string))))
713 ;; When called on tag in a descriptive list, insert new item before
714 ;; current one too.
715 (should
716 (equal "- :: \n- tag :: item"
717 (org-test-with-temp-text "- tag <point>:: item"
718 (org-insert-item)
719 (buffer-string))))
720 (should
721 (equal "- :: \n- tag :: item"
722 (org-test-with-temp-text "- ta<point>g :: item"
723 (org-insert-item)
724 (buffer-string))))
725 ;; Further, it splits the line or add a blank new item after it,
726 ;; according to `org-M-RET-may-split-line'.
727 (should
728 (equal "- it\n- em"
729 (org-test-with-temp-text "- it<point>em"
730 (let ((org-M-RET-may-split-line '((default . t))))
731 (org-insert-item))
732 (buffer-string))))
733 (should
734 (equal "- item\n- "
735 (org-test-with-temp-text "- it<point>em"
736 (let ((org-M-RET-may-split-line '((default . nil))))
737 (org-insert-item))
738 (buffer-string)))))
740 (ert-deftest test-org-list/repair ()
741 "Test `org-list-repair' specifications."
742 ;; Repair indentation.
743 (should
744 (equal "- item\n - child"
745 (org-test-with-temp-text "- item\n - child"
746 (let ((org-list-indent-offset 0)) (org-list-repair))
747 (buffer-string))))
748 ;; Repair bullets and numbering.
749 (should
750 (equal "- a\n- b"
751 (org-test-with-temp-text "- a\n+ b"
752 (let ((org-list-indent-offset 0))
753 (org-list-repair))
754 (buffer-string))))
755 (should
756 (equal "1. a\n2. b"
757 (org-test-with-temp-text "1. a\n1. b"
758 (let ((org-list-indent-offset 0)
759 (org-plain-list-ordered-item-terminator t))
760 (org-list-repair))
761 (buffer-string))))
762 ;; Repair check-boxes.
763 (should
764 (equal "- [X] item\n - [X] child"
765 (org-test-with-temp-text "- [ ] item\n - [X] child"
766 (let ((org-list-indent-offset 0))
767 (org-list-repair))
768 (buffer-string))))
769 ;; Special case: do not move contents of an item within its child.
770 ;; Yet, preserve indentation differences within contents.
771 (should
772 (equal "- item\n - child\n within item"
773 (org-test-with-temp-text "- item\n - child\n within item"
774 (let ((org-list-indent-offset 0)) (org-list-repair))
775 (buffer-string))))
776 (should
777 (equal
778 "- item\n - child\n within item\n indented"
779 (org-test-with-temp-text
780 "- item\n - child\n within item\n indented"
781 (let ((org-list-indent-offset 0)) (org-list-repair))
782 (buffer-string)))))
784 (ert-deftest test-org-list/update-checkbox-count ()
785 "Test `org-update-checkbox-count' specifications."
786 ;; From a headline.
787 (should
788 (string-match "\\[0/1\\]"
789 (org-test-with-temp-text "* [/]\n- [ ] item"
790 (org-update-checkbox-count)
791 (buffer-string))))
792 (should
793 (string-match "\\[1/1\\]"
794 (org-test-with-temp-text "* [/]\n- [X] item"
795 (org-update-checkbox-count)
796 (buffer-string))))
797 (should
798 (string-match "\\[100%\\]"
799 (org-test-with-temp-text "* [%]\n- [X] item"
800 (org-update-checkbox-count)
801 (buffer-string))))
802 ;; From a list or a sub-list.
803 (should
804 (string-match "\\[0/1\\]"
805 (org-test-with-temp-text "- [/]\n - [ ] item"
806 (org-update-checkbox-count)
807 (buffer-string))))
808 (should
809 (string-match "\\[1/1\\]"
810 (org-test-with-temp-text "- [/]\n - [X] item"
811 (org-update-checkbox-count)
812 (buffer-string))))
813 (should
814 (string-match "\\[100%\\]"
815 (org-test-with-temp-text "- [%]\n - [X] item"
816 (org-update-checkbox-count)
817 (buffer-string))))
818 (should
819 (string-match
820 "\\[1/1\\]"
821 (org-test-with-temp-text "- [ ] item 1\n- [ ] item 2 [/]\n - [X] sub 1"
822 (org-update-checkbox-count)
823 (buffer-string))))
824 ;; Count do not apply to sub-lists unless count is not hierarchical.
825 ;; This state can be achieved with COOKIE_DATA node property set to
826 ;; "recursive".
827 (should
828 (string-match "\\[1/1\\]"
829 (org-test-with-temp-text "- [/]\n - item\n - [X] sub-item"
830 (let ((org-checkbox-hierarchical-statistics nil))
831 (org-update-checkbox-count))
832 (buffer-string))))
833 (should
834 (string-match "\\[1/1\\]"
835 (org-test-with-temp-text "
836 <point>* H
837 :PROPERTIES:
838 :COOKIE_DATA: recursive
839 :END:
840 - [/]
841 - item
842 - [X] sub-item"
843 (org-update-checkbox-count)
844 (buffer-string))))
845 (should
846 (string-match "\\[0/0\\]"
847 (org-test-with-temp-text "- [/]\n - item\n - [ ] sub-item"
848 (org-update-checkbox-count)
849 (buffer-string))))
850 ;; With optional argument ALL, update all buffer.
851 (should
852 (= 2
853 (org-test-with-temp-text "* [/]\n- [X] item\n* [/]\n- [X] item"
854 (org-update-checkbox-count t)
855 (count-matches "\\[1/1\\]"))))
856 ;; Ignore boxes in drawers, blocks or inlinetasks when counting from
857 ;; outside.
858 (should
859 (string-match "\\[2/2\\]"
860 (org-test-with-temp-text "
861 - [/]
862 - [X] item1
863 :DRAWER:
864 - [X] item
865 :END:
866 - [X] item2"
867 (let ((org-checkbox-hierarchical-statistics nil))
868 (org-update-checkbox-count))
869 (buffer-string)))))
873 ;;; Miscellaneous
875 (ert-deftest test-org-list/toggle-item ()
876 "Test `org-toggle-item' specifications."
877 ;; Convert normal lines to items.
878 (should
879 (equal "- line"
880 (org-test-with-temp-text "line"
881 (org-toggle-item nil)
882 (buffer-string))))
883 ;; Convert items to normal lines.
884 (should
885 (equal "line"
886 (org-test-with-temp-text "- line"
887 (org-toggle-item nil)
888 (buffer-string))))
889 ;; Convert headlines to items.
890 (should
891 (equal "- line"
892 (org-test-with-temp-text "* line"
893 (org-toggle-item nil)
894 (buffer-string))))
895 ;; When converting a headline to a list item, TODO keywords become
896 ;; checkboxes.
897 (should
898 (equal "- [X] line"
899 (org-test-with-temp-text "* DONE line"
900 (org-toggle-item nil)
901 (buffer-string))))
902 (should
903 (equal "- [ ] line"
904 (org-test-with-temp-text "* TODO line"
905 (org-toggle-item nil)
906 (buffer-string))))
907 ;; When a region is marked and first line is a headline, all
908 ;; headlines are turned into items.
909 (should
910 (equal "- H1\n - H2"
911 (org-test-with-temp-text "* H1\n** H2"
912 (transient-mark-mode 1)
913 (push-mark (point) t t)
914 (goto-char (point-max))
915 (org-toggle-item nil)
916 (buffer-string))))
917 (should
918 (equal "- [ ] H1\n - [ ] H2"
919 (org-test-with-temp-text "* TODO H1\n** TODO H2"
920 (transient-mark-mode 1)
921 (push-mark (point) t t)
922 (goto-char (point-max))
923 (org-toggle-item nil)
924 (buffer-string))))
925 ;; When turning headlines into items, make sure headings contents
926 ;; are kept within items.
927 (should
928 (equal "- H1\n Text"
929 (org-test-with-temp-text "* H1\nText"
930 (transient-mark-mode 1)
931 (push-mark (point) t t)
932 (goto-char (point-max))
933 (org-toggle-item nil)
934 (buffer-string))))
935 ;; When a region is marked and first line is an item, all items are
936 ;; turned into normal lines.
937 (should
938 (equal "1\n 2"
939 (org-test-with-temp-text "- 1\n - 2"
940 (transient-mark-mode 1)
941 (push-mark (point) t t)
942 (goto-char (point-max))
943 (org-toggle-item nil)
944 (buffer-string))))
945 (should
946 (equal "1\n2"
947 (org-test-with-temp-text "- 1\n2"
948 (transient-mark-mode 1)
949 (push-mark (point) t t)
950 (goto-char (point-max))
951 (org-toggle-item nil)
952 (buffer-string))))
953 ;; When a region is marked and first line is an item, all normal
954 ;; lines are turned into items.
955 (should
956 (equal "- line 1\n- line 2"
957 (org-test-with-temp-text "line 1\nline 2"
958 (transient-mark-mode 1)
959 (push-mark (point) t t)
960 (goto-char (point-max))
961 (org-toggle-item nil)
962 (buffer-string))))
963 (should
964 (equal "- line 1\n- line 2"
965 (org-test-with-temp-text "line 1\n- line 2"
966 (transient-mark-mode 1)
967 (push-mark (point) t t)
968 (goto-char (point-max))
969 (org-toggle-item nil)
970 (buffer-string))))
971 ;; When argument ARG is non-nil, change the whole region into
972 ;; a single item.
973 (should
974 (equal "- line 1\n line 2"
975 (org-test-with-temp-text "line 1\nline 2"
976 (transient-mark-mode 1)
977 (push-mark (point) t t)
978 (goto-char (point-max))
979 (org-toggle-item t)
980 (buffer-string)))))
983 ;;; Radio Lists
985 (ert-deftest test-org-list/send-list ()
986 "Test various checks for `org-list-send-list'."
987 ;; Error when not at a list item.
988 (should-error
989 (org-test-with-temp-text "Not a list item"
990 (org-list-send-list)))
991 ;; Error when ORGLST line is not provided.
992 (should-error
993 (org-test-with-temp-text "- item"
994 (org-list-send-list)))
995 ;; Error when transformation function is unknown.
996 (should-error
997 (org-test-with-temp-text "@ignore
998 #+ORGLST: SEND list unknown-function
999 - item
1000 @end ignore"
1001 (forward-line 2)
1002 (org-list-send-list)))
1003 ;; Error when receiving location is not defined.
1004 (should-error
1005 (org-test-with-temp-text "@ignore
1006 #+ORGLST: SEND list org-list-to-texinfo
1007 - item
1008 @end ignore"
1009 (forward-line 2)
1010 (org-list-send-list)))
1011 ;; Error when insertion region is ill-formed.
1012 (should-error
1013 (org-test-with-temp-text "@c BEGIN RECEIVE ORGLST list
1014 @ignore
1015 #+ORGLST: SEND list org-list-to-texinfo
1016 - item
1017 @end ignore"
1018 (forward-line 3)
1019 (org-list-send-list)))
1020 ;; Allow multiple receiver locations.
1021 (should
1022 (org-test-with-temp-text "
1023 @c BEGIN RECEIVE ORGLST list
1024 @c END RECEIVE ORGLST list
1026 @ignore
1027 #+ORGLST: SEND list org-list-to-texinfo
1028 <point>- item contents
1029 @end ignore
1031 @c BEGIN RECEIVE ORGLST list
1032 @c END RECEIVE ORGLST list"
1033 (org-list-send-list)
1034 (goto-char (point-min))
1035 (search-forward "item contents" nil t 3))))
1037 (ert-deftest test-org-list/to-generic ()
1038 "Test `org-list-to-generic' specifications."
1039 ;; Test `:ustart' and `:uend' parameters.
1040 (should
1041 (equal
1042 "begin\na"
1043 (org-test-with-temp-text "- a"
1044 (org-list-to-generic (org-list-to-lisp) '(:ustart "begin")))))
1045 (should-not
1046 (equal
1047 "begin\na"
1048 (org-test-with-temp-text "1. a"
1049 (org-list-to-generic (org-list-to-lisp) '(:ustart "begin")))))
1050 (should
1051 (equal
1052 "a\nend"
1053 (org-test-with-temp-text "- a"
1054 (org-list-to-generic (org-list-to-lisp) '(:uend "end")))))
1055 (should-not
1056 (equal
1057 "a\nend"
1058 (org-test-with-temp-text "1. a"
1059 (org-list-to-generic (org-list-to-lisp) '(:uend "end")))))
1060 (should
1061 (equal
1062 "begin l1\na\nbegin l2\nb\nend l2\nend l1"
1063 (org-test-with-temp-text "- a\n - b"
1064 (org-list-to-generic
1065 (org-list-to-lisp)
1066 (list :ustart (lambda (l) (format "begin l%d" l))
1067 :uend (lambda (l) (format "end l%d" l)))))))
1068 ;; Test `:ostart' and `:oend' parameters.
1069 (should
1070 (equal
1071 "begin\na"
1072 (org-test-with-temp-text "1. a"
1073 (org-list-to-generic (org-list-to-lisp) '(:ostart "begin")))))
1074 (should-not
1075 (equal
1076 "begin\na"
1077 (org-test-with-temp-text "- a"
1078 (org-list-to-generic (org-list-to-lisp) '(:ostart "begin")))))
1079 (should
1080 (equal
1081 "a\nend"
1082 (org-test-with-temp-text "1. a"
1083 (org-list-to-generic (org-list-to-lisp) '(:oend "end")))))
1084 (should-not
1085 (equal
1086 "a\nend"
1087 (org-test-with-temp-text "- a"
1088 (org-list-to-generic (org-list-to-lisp) '(:oend "end")))))
1089 (should
1090 (equal
1091 "begin l1\na\nbegin l2\nb\nend l2\nend l1"
1092 (org-test-with-temp-text "1. a\n 1. b"
1093 (org-list-to-generic
1094 (org-list-to-lisp)
1095 (list :ostart (lambda (l) (format "begin l%d" l))
1096 :oend (lambda (l) (format "end l%d" l)))))))
1097 ;; Test `:dstart' and `:dend' parameters.
1098 (should
1099 (equal
1100 "begin\ntaga"
1101 (org-test-with-temp-text "- tag :: a"
1102 (org-list-to-generic (org-list-to-lisp) '(:dstart "begin")))))
1103 (should-not
1104 (equal
1105 "begin\na"
1106 (org-test-with-temp-text "- a"
1107 (org-list-to-generic (org-list-to-lisp) '(:dstart "begin")))))
1108 (should
1109 (equal
1110 "taga\nend"
1111 (org-test-with-temp-text "- tag :: a"
1112 (org-list-to-generic (org-list-to-lisp) '(:dend "end")))))
1113 (should-not
1114 (equal
1115 "a\nend"
1116 (org-test-with-temp-text "- a"
1117 (org-list-to-generic (org-list-to-lisp) '(:dend "end")))))
1118 (should
1119 (equal
1120 "begin l1\ntag1a\nbegin l2\ntag2b\nend l2\nend l1"
1121 (org-test-with-temp-text "- tag1 :: a\n - tag2 :: b"
1122 (org-list-to-generic
1123 (org-list-to-lisp)
1124 (list :dstart (lambda (l) (format "begin l%d" l))
1125 :dend (lambda (l) (format "end l%d" l)))))))
1126 ;; Test `:dtstart', `:dtend', `:ddstart' and `:ddend' parameters.
1127 (should
1128 (equal
1129 ">tag<a"
1130 (org-test-with-temp-text "- tag :: a"
1131 (org-list-to-generic (org-list-to-lisp) '(:dtstart ">" :dtend "<")))))
1132 (should
1133 (equal
1134 "tag>a<"
1135 (org-test-with-temp-text "- tag :: a"
1136 (org-list-to-generic (org-list-to-lisp) '(:ddstart ">" :ddend "<")))))
1137 ;; Test `:istart' and `:iend' parameters.
1138 (should
1139 (equal
1140 "starta"
1141 (org-test-with-temp-text "- a"
1142 (org-list-to-generic (org-list-to-lisp) '(:istart "start")))))
1143 (should
1144 (equal
1145 "level1 a\nlevel2 b"
1146 (org-test-with-temp-text "- a\n - b"
1147 (org-list-to-generic (org-list-to-lisp)
1148 '(:istart (lambda (l) (format "level%d "l)))))))
1149 (should
1150 (equal
1151 "a\nblevel2level1"
1152 (org-test-with-temp-text "- a\n - b"
1153 (org-list-to-generic (org-list-to-lisp)
1154 '(:iend (lambda (l) (format "level%d" l)))))))
1155 ;; Test `:icount' parameter.
1156 (should
1157 (equal
1158 "counta"
1159 (org-test-with-temp-text "1. [@3] a"
1160 (org-list-to-generic (org-list-to-lisp) '(:icount "count")))))
1161 (should-not
1162 (equal
1163 "counta"
1164 (org-test-with-temp-text "1. a"
1165 (org-list-to-generic (org-list-to-lisp) '(:icount "count")))))
1166 (should
1167 (equal
1168 "counta"
1169 (org-test-with-temp-text "1. [@3] a"
1170 (org-list-to-generic (org-list-to-lisp)
1171 '(:icount "count" :istart "start")))))
1172 (should
1173 (equal
1174 "level:1, counter:3 a"
1175 (org-test-with-temp-text "1. [@3] a"
1176 (org-list-to-generic
1177 (org-list-to-lisp)
1178 '(:icount (lambda (l c) (format "level:%d, counter:%d " l c)))))))
1179 ;; Test `:isep' parameter.
1180 (should
1181 (equal
1182 "a\n--\nb"
1183 (org-test-with-temp-text "- a\n- b"
1184 (org-list-to-generic (org-list-to-lisp) '(:isep "--")))))
1185 (should-not
1186 (equal
1187 "a\n--\nb"
1188 (org-test-with-temp-text "- a\n - b"
1189 (org-list-to-generic (org-list-to-lisp) '(:isep "--")))))
1190 (should
1191 (equal
1192 "a\n- 1 -\nb"
1193 (org-test-with-temp-text "- a\n- b"
1194 (org-list-to-generic (org-list-to-lisp)
1195 '(:isep (lambda (l) (format "- %d -" l)))))))
1196 ;; Test `:cbon', `:cboff', `:cbtrans'
1197 (should
1198 (equal
1199 "!a"
1200 (org-test-with-temp-text "- [X] a"
1201 (org-list-to-generic (org-list-to-lisp) '(:cbon "!")))))
1202 (should-not
1203 (equal
1204 "!a"
1205 (org-test-with-temp-text "- [X] a"
1206 (org-list-to-generic (org-list-to-lisp) '(:cboff "!" :cbtrans "!")))))
1207 (should
1208 (equal
1209 "!a"
1210 (org-test-with-temp-text "- [ ] a"
1211 (org-list-to-generic (org-list-to-lisp) '(:cboff "!")))))
1212 (should-not
1213 (equal
1214 "!a"
1215 (org-test-with-temp-text "- [ ] a"
1216 (org-list-to-generic (org-list-to-lisp) '(:cbon "!" :cbtrans "!")))))
1217 (should
1218 (equal
1219 "!a"
1220 (org-test-with-temp-text "- [-] a"
1221 (org-list-to-generic (org-list-to-lisp) '(:cbtrans "!")))))
1222 (should-not
1223 (equal
1224 "!a"
1225 (org-test-with-temp-text "- [-] a"
1226 (org-list-to-generic (org-list-to-lisp) '(:cbon "!" :cboff "!")))))
1227 ;; Test `:splice' parameter.
1228 (should
1229 (equal
1231 (org-test-with-temp-text "- a"
1232 (org-list-to-generic (org-list-to-lisp)
1233 '(:ustart "begin" :uend "end" :splice t)))))
1234 ;; No error on empty lists.
1235 (should
1236 (org-test-with-temp-text "-" (org-list-to-generic (org-list-to-lisp) nil))))
1238 (ert-deftest test-org-list/to-html ()
1239 "Test `org-list-to-html' specifications."
1240 (should
1241 (equal "<ul class=\"org-ul\">\n<li>a</li>\n</ul>"
1242 (let (org-html-indent)
1243 (with-temp-buffer
1244 (insert "<!-- BEGIN RECEIVE ORGLST name -->
1245 <!-- END RECEIVE ORGLST name -->
1246 <!--
1247 #+ORGLST: SEND name org-list-to-html
1249 -->")
1250 (goto-char (point-min))
1251 (re-search-forward "^- a" nil t)
1252 (beginning-of-line)
1253 (org-list-send-list)
1254 (goto-line 2)
1255 (buffer-substring-no-properties
1256 (point)
1257 (progn (re-search-forward "^<!-- END" nil t)
1258 (beginning-of-line)
1259 (skip-chars-backward " \r\t\n")
1260 (point))))))))
1262 (ert-deftest test-org-list/to-latex ()
1263 "Test `org-list-to-latex' specifications."
1264 (should
1265 (equal "\\begin{itemize}\n\\item a\n\\end{itemize}"
1266 (with-temp-buffer
1267 (insert "% BEGIN RECEIVE ORGLST name
1268 % END RECEIVE ORGLST name
1269 \\begin{comment}
1270 #+ORGLST: SEND name org-list-to-latex
1272 \\end{comment}")
1273 (goto-char (point-min))
1274 (re-search-forward "^- a" nil t)
1275 (beginning-of-line)
1276 (org-list-send-list)
1277 (goto-line 2)
1278 (buffer-substring-no-properties
1279 (point)
1280 (progn (re-search-forward "^% END" nil t)
1281 (beginning-of-line)
1282 (skip-chars-backward " \r\t\n")
1283 (point)))))))
1285 (ert-deftest test-org-list/to-texinfo ()
1286 "Test `org-list-to-texinfo' specifications."
1287 (should
1288 (equal "@itemize\n@item\na\n@end itemize"
1289 (with-temp-buffer
1290 (insert "@c BEGIN RECEIVE ORGLST name
1291 @c END RECEIVE ORGLST name
1292 @ignore
1293 #+ORGLST: SEND name org-list-to-texinfo
1295 @end ignore")
1296 (goto-char (point-min))
1297 (re-search-forward "^- a" nil t)
1298 (beginning-of-line)
1299 (org-list-send-list)
1300 (goto-line 2)
1301 (buffer-substring-no-properties
1302 (point)
1303 (progn (re-search-forward "^@c END" nil t)
1304 (beginning-of-line)
1305 (skip-chars-backward " \r\t\n")
1306 (point)))))))
1309 (provide 'test-org-list)
1310 ;;; test-org-list.el ends here