Fix opening custom ID links with percent escaped syntax
[org-mode/org-tableheadings.git] / testing / lisp / test-org.el
blob6e1abc827a32b3e4fd67e49656221530f66888ab
1 ;;; test-org.el --- tests for org.el
3 ;; Copyright (c) David Maus
4 ;; Authors: David Maus
6 ;; This file is not part of GNU Emacs.
8 ;; This program is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation, either version 3 of the License, or
11 ;; (at your option) any later version.
13 ;; This program is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ;; Template test file for Org tests
23 ;;; Code:
25 (eval-and-compile (require 'cl-lib))
28 ;;; Comments
30 (ert-deftest test-org/toggle-comment ()
31 "Test `org-toggle-comment' specifications."
32 ;; Simple headline.
33 (should
34 (equal "* Test"
35 (org-test-with-temp-text "* COMMENT Test"
36 (org-toggle-comment)
37 (buffer-string))))
38 (should
39 (equal "* COMMENT Test"
40 (org-test-with-temp-text "* Test"
41 (org-toggle-comment)
42 (buffer-string))))
43 ;; Headline with a regular keyword.
44 (should
45 (equal "* TODO Test"
46 (org-test-with-temp-text "* TODO COMMENT Test"
47 (org-toggle-comment)
48 (buffer-string))))
49 (should
50 (equal "* TODO COMMENT Test"
51 (org-test-with-temp-text "* TODO Test"
52 (org-toggle-comment)
53 (buffer-string))))
54 ;; Empty headline.
55 (should
56 (equal "* "
57 (org-test-with-temp-text "* COMMENT"
58 (org-toggle-comment)
59 (buffer-string))))
60 (should
61 (equal "* COMMENT"
62 (org-test-with-temp-text "* "
63 (org-toggle-comment)
64 (buffer-string))))
65 ;; Headline with a single keyword.
66 (should
67 (equal "* TODO "
68 (org-test-with-temp-text "* TODO COMMENT"
69 (org-toggle-comment)
70 (buffer-string))))
71 (should
72 (equal "* TODO COMMENT"
73 (org-test-with-temp-text "* TODO"
74 (org-toggle-comment)
75 (buffer-string))))
76 ;; Headline with a keyword, a priority cookie and contents.
77 (should
78 (equal "* TODO [#A] Headline"
79 (org-test-with-temp-text "* TODO [#A] COMMENT Headline"
80 (org-toggle-comment)
81 (buffer-string))))
82 (should
83 (equal "* TODO [#A] COMMENT Headline"
84 (org-test-with-temp-text "* TODO [#A] Headline"
85 (org-toggle-comment)
86 (buffer-string)))))
88 (ert-deftest test-org/comment-dwim ()
89 "Test `comment-dwim' behaviour in an Org buffer."
90 ;; No region selected, no comment on current line and line not
91 ;; empty: insert comment on line above.
92 (should
93 (equal "# \nComment"
94 (org-test-with-temp-text "Comment"
95 (call-interactively #'org-comment-dwim)
96 (buffer-string))))
97 ;; No region selected, no comment on current line and line empty:
98 ;; insert comment on this line.
99 (should
100 (equal "# \nParagraph"
101 (org-test-with-temp-text "\nParagraph"
102 (call-interactively #'org-comment-dwim)
103 (buffer-string))))
104 ;; No region selected, and a comment on this line: indent it.
105 (should
106 (equal "* Headline\n # Comment"
107 (org-test-with-temp-text "* Headline\n# <point>Comment"
108 (let ((org-adapt-indentation t))
109 (call-interactively #'org-comment-dwim))
110 (buffer-string))))
111 ;; Also recognize single # at column 0 as comments.
112 (should
113 (equal "# Comment"
114 (org-test-with-temp-text "# Comment"
115 (call-interactively #'org-comment-dwim)
116 (buffer-string))))
117 ;; Region selected and only comments and blank lines within it:
118 ;; un-comment all commented lines.
119 (should
120 (equal "Comment 1\n\nComment 2"
121 (org-test-with-temp-text "# Comment 1\n\n# Comment 2"
122 (transient-mark-mode 1)
123 (push-mark (point) t t)
124 (goto-char (point-max))
125 (call-interactively #'org-comment-dwim)
126 (buffer-string))))
127 ;; Region selected without comments: comment all lines if
128 ;; `comment-empty-lines' is non-nil, only non-blank lines otherwise.
129 (should
130 (equal "# Comment 1\n\n# Comment 2"
131 (org-test-with-temp-text "Comment 1\n\nComment 2"
132 (transient-mark-mode 1)
133 (push-mark (point) t t)
134 (goto-char (point-max))
135 (let ((comment-empty-lines nil))
136 (call-interactively #'org-comment-dwim))
137 (buffer-string))))
138 (should
139 (equal "# Comment 1\n# \n# Comment 2"
140 (org-test-with-temp-text "Comment 1\n\nComment 2"
141 (transient-mark-mode 1)
142 (push-mark (point) t t)
143 (goto-char (point-max))
144 (let ((comment-empty-lines t))
145 (call-interactively #'org-comment-dwim))
146 (buffer-string))))
147 ;; In front of a keyword without region, insert a new comment.
148 (should
149 (equal "# \n#+KEYWORD: value"
150 (org-test-with-temp-text "#+KEYWORD: value"
151 (call-interactively #'org-comment-dwim)
152 (buffer-string))))
153 ;; Comment a heading
154 (should
155 (equal "* COMMENT Test"
156 (org-test-with-temp-text "* Test"
157 (call-interactively #'org-comment-dwim)
158 (buffer-string))))
159 ;; In a source block, use appropriate syntax.
160 (should
161 (equal " ;; "
162 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n<point>\n#+END_SRC"
163 (let ((org-edit-src-content-indentation 2))
164 (call-interactively #'org-comment-dwim))
165 (buffer-substring-no-properties (line-beginning-position)
166 (point)))))
167 (should
168 (equal "#+BEGIN_SRC emacs-lisp\n ;; a\n ;; b\n#+END_SRC"
169 (org-test-with-temp-text
170 "#+BEGIN_SRC emacs-lisp\n<point>a\nb\n#+END_SRC"
171 (transient-mark-mode 1)
172 (push-mark (point) t t)
173 (forward-line 2)
174 (let ((org-edit-src-content-indentation 2))
175 (call-interactively #'org-comment-dwim))
176 (buffer-string)))))
180 ;;; Date and time analysis
182 (ert-deftest test-org/org-read-date ()
183 "Test `org-read-date' specifications."
184 ;; Parse ISO date with abbreviated year and month.
185 (should (equal "2012-03-29 16:40"
186 (let ((org-time-was-given t))
187 (org-read-date t nil "12-3-29 16:40"))))
188 ;; Parse Europeans dates.
189 (should (equal "2012-03-29 16:40"
190 (let ((org-time-was-given t))
191 (org-read-date t nil "29.03.2012 16:40"))))
192 ;; Parse Europeans dates without year.
193 (should (string-match "2[0-9]\\{3\\}-03-29 16:40"
194 (let ((org-time-was-given t))
195 (org-read-date t nil "29.03. 16:40"))))
196 ;; Relative date applied to current time if there is single
197 ;; plus/minus, or to default date when there are two of them.
198 (should
199 (equal
200 "2015-03-04"
201 (cl-letf (((symbol-function 'current-time)
202 (lambda ()
203 (apply #'encode-time (org-parse-time-string "2014-03-04")))))
204 (org-read-date
205 t nil "+1y" nil
206 (apply #'encode-time (org-parse-time-string "2012-03-29"))))))
207 (should
208 (equal
209 "2013-03-29"
210 (cl-letf (((symbol-function 'current-time)
211 (lambda ()
212 (apply #'encode-time (org-parse-time-string "2014-03-04")))))
213 (org-read-date
214 t nil "++1y" nil
215 (apply #'encode-time (org-parse-time-string "2012-03-29"))))))
216 ;; When `org-read-date-prefer-future' is non-nil, prefer future
217 ;; dates (relatively to now) when incomplete. Otherwise, use
218 ;; default date.
219 (should
220 (equal
221 "2014-04-01"
222 (cl-letf (((symbol-function 'current-time)
223 (lambda ()
224 (apply #'encode-time (org-parse-time-string "2014-03-04")))))
225 (let ((org-read-date-prefer-future t))
226 (org-read-date t nil "1")))))
227 (should
228 (equal
229 "2013-03-04"
230 (cl-letf (((symbol-function 'current-time)
231 (lambda ()
232 (apply #'encode-time (org-parse-time-string "2012-03-29")))))
233 (let ((org-read-date-prefer-future t))
234 (org-read-date t nil "3-4")))))
235 (should
236 (equal
237 "2012-03-04"
238 (cl-letf (((symbol-function 'current-time)
239 (lambda ()
240 (apply #'encode-time (org-parse-time-string "2012-03-29")))))
241 (let ((org-read-date-prefer-future nil))
242 (org-read-date t nil "3-4")))))
243 ;; When set to `org-read-date-prefer-future' is set to `time', read
244 ;; day is moved to tomorrow if specified hour is before current
245 ;; time. However, it only happens in no other part of the date is
246 ;; specified.
247 (should
248 (equal
249 "2012-03-30"
250 (cl-letf (((symbol-function 'current-time)
251 (lambda ()
252 (apply #'encode-time (org-parse-time-string "2012-03-29 16:40")))))
253 (let ((org-read-date-prefer-future 'time))
254 (org-read-date t nil "00:40" nil)))))
255 (should-not
256 (equal
257 "2012-03-30"
258 (cl-letf (((symbol-function 'current-time)
259 (lambda ()
260 (apply #'encode-time (org-parse-time-string "2012-03-29 16:40")))))
261 (let ((org-read-date-prefer-future 'time))
262 (org-read-date t nil "29 00:40" nil)))))
263 ;; Caveat: `org-read-date-prefer-future' always refers to current
264 ;; time, not default time, when they differ.
265 (should
266 (equal
267 "2014-04-01"
268 (cl-letf (((symbol-function 'current-time)
269 (lambda ()
270 (apply #'encode-time (org-parse-time-string "2014-03-04")))))
271 (let ((org-read-date-prefer-future t))
272 (org-read-date
273 t nil "1" nil
274 (apply #'encode-time (org-parse-time-string "2012-03-29")))))))
275 (should
276 (equal
277 "2014-03-25"
278 (cl-letf (((symbol-function 'current-time)
279 (lambda ()
280 (apply #'encode-time (org-parse-time-string "2014-03-04")))))
281 (let ((org-read-date-prefer-future t))
282 (org-read-date
283 t nil "25" nil
284 (apply #'encode-time (org-parse-time-string "2012-03-29"))))))))
286 (ert-deftest test-org/org-parse-time-string ()
287 "Test `org-parse-time-string'."
288 (should (equal (org-parse-time-string "2012-03-29 16:40")
289 '(0 40 16 29 3 2012 nil nil nil)))
290 (should (equal (org-parse-time-string "[2012-03-29 16:40]")
291 '(0 40 16 29 3 2012 nil nil nil)))
292 (should (equal (org-parse-time-string "<2012-03-29 16:40>")
293 '(0 40 16 29 3 2012 nil nil nil)))
294 (should (equal (org-parse-time-string "<2012-03-29>")
295 '(0 0 0 29 3 2012 nil nil nil)))
296 (should (equal (org-parse-time-string "<2012-03-29>" t)
297 '(0 nil nil 29 3 2012 nil nil nil))))
299 (ert-deftest test-org/closest-date ()
300 "Test `org-closest-date' specifications."
301 (require 'calendar)
302 ;; Time stamps without a repeater are returned unchanged.
303 (should
304 (equal
305 '(3 29 2012)
306 (calendar-gregorian-from-absolute
307 (org-closest-date "<2012-03-29>" "<2014-03-04>" nil))))
308 ;; Time stamps with a null repeater are returned unchanged.
309 (should
310 (equal
311 '(3 29 2012)
312 (calendar-gregorian-from-absolute
313 (org-closest-date "<2012-03-29 +0d>" "<2014-03-04>" nil))))
314 ;; if PREFER is set to `past' always return a date before, or equal
315 ;; to CURRENT.
316 (should
317 (equal
318 '(3 1 2014)
319 (calendar-gregorian-from-absolute
320 (org-closest-date "<2012-03-29 +1m>" "<2014-03-04>" 'past))))
321 (should
322 (equal
323 '(3 4 2014)
324 (calendar-gregorian-from-absolute
325 (org-closest-date "<2012-03-04 +1m>" "<2014-03-04>" 'past))))
326 ;; if PREFER is set to `future' always return a date before, or equal
327 ;; to CURRENT.
328 (should
329 (equal
330 '(3 29 2014)
331 (calendar-gregorian-from-absolute
332 (org-closest-date "<2012-03-29 +1m>" "<2014-03-04>" 'future))))
333 (should
334 (equal
335 '(3 4 2014)
336 (calendar-gregorian-from-absolute
337 (org-closest-date "<2012-03-04 +1m>" "<2014-03-04>" 'future))))
338 ;; If PREFER is neither `past' nor `future', select closest date.
339 (should
340 (equal
341 '(3 1 2014)
342 (calendar-gregorian-from-absolute
343 (org-closest-date "<2012-03-29 +1m>" "<2014-03-04>" nil))))
344 (should
345 (equal
346 '(5 4 2014)
347 (calendar-gregorian-from-absolute
348 (org-closest-date "<2012-03-04 +1m>" "<2014-04-28>" nil))))
349 ;; Test "day" repeater.
350 (should
351 (equal '(3 8 2014)
352 (calendar-gregorian-from-absolute
353 (org-closest-date "<2014-03-04 +2d>" "<2014-03-09>" 'past))))
354 (should
355 (equal '(3 10 2014)
356 (calendar-gregorian-from-absolute
357 (org-closest-date "<2014-03-04 +2d>" "<2014-03-09>" 'future))))
358 ;; Test "month" repeater.
359 (should
360 (equal '(1 5 2015)
361 (calendar-gregorian-from-absolute
362 (org-closest-date "<2014-03-05 +2m>" "<2015-02-04>" 'past))))
363 (should
364 (equal '(3 29 2014)
365 (calendar-gregorian-from-absolute
366 (org-closest-date "<2012-03-29 +2m>" "<2014-03-04>" 'future))))
367 ;; Test "year" repeater.
368 (should
369 (equal '(3 5 2014)
370 (calendar-gregorian-from-absolute
371 (org-closest-date "<2014-03-05 +2y>" "<2015-02-04>" 'past))))
372 (should
373 (equal '(3 29 2014)
374 (calendar-gregorian-from-absolute
375 (org-closest-date "<2012-03-29 +2y>" "<2014-03-04>" 'future)))))
377 (ert-deftest test-org/deadline-close-p ()
378 "Test `org-deadline-close-p' specifications."
379 ;; Pretend that the current time is 2016-06-03 Fri 01:43
380 (cl-letf (((symbol-function 'current-time)
381 (lambda ()
382 (apply #'encode-time
383 (org-parse-time-string "2016-06-03 Fri 01:43")))))
384 ;; Timestamps are close if they are within `ndays' of lead time.
385 (org-test-with-temp-text "* Heading"
386 (should (org-deadline-close-p "2016-06-03 Fri" 0))
387 (should (org-deadline-close-p "2016-06-02 Thu" 0))
388 (should-not (org-deadline-close-p "2016-06-04 Sat" 0))
389 (should (org-deadline-close-p "2016-06-04 Sat" 1))
390 (should (org-deadline-close-p "2016-06-03 Fri 12:00" 0)))
391 ;; Read `ndays' from timestamp if argument not given.
392 (org-test-with-temp-text "* H"
393 (should (org-deadline-close-p "2016-06-04 Sat -1d"))
394 (should-not (org-deadline-close-p "2016-06-04 Sat -0d"))
395 (should (org-deadline-close-p "2016-06-10 Fri -1w"))
396 (should-not (org-deadline-close-p "2016-06-11 Sat -1w")))
397 ;; Prefer `ndays' argument over lead time in timestamp.
398 (org-test-with-temp-text "* H"
399 (should (org-deadline-close-p "2016-06-04 Sat -0d" 1))
400 (should-not (org-deadline-close-p "2016-06-04 Sat -0d" 0)))
401 ;; Completed tasks are never close.
402 (let ((org-todo-keywords '(("TODO" "|" "DONE"))))
403 (org-test-with-temp-text "* TODO Heading"
404 (should (org-deadline-close-p "2016-06-03")))
405 (org-test-with-temp-text "* DONE Heading"
406 (should-not (org-deadline-close-p "2016-06-03"))))))
409 ;;; Drawers
411 (ert-deftest test-org/insert-property-drawer ()
412 "Test `org-insert-property-drawer' specifications."
413 ;; Error before first headline.
414 (should-error (org-test-with-temp-text "" (org-insert-property-drawer)))
415 ;; Insert drawer right after headline if there is no planning line,
416 ;; or after it otherwise.
417 (should
418 (equal "* H\n:PROPERTIES:\n:END:\nParagraph"
419 (org-test-with-temp-text "* H\nParagraph<point>"
420 (let ((org-adapt-indentation nil)) (org-insert-property-drawer))
421 (buffer-string))))
422 (should
423 (equal "* H\nDEADLINE: <2014-03-04 tue.>\n:PROPERTIES:\n:END:\nParagraph"
424 (org-test-with-temp-text
425 "* H\nDEADLINE: <2014-03-04 tue.>\nParagraph<point>"
426 (let ((org-adapt-indentation nil)) (org-insert-property-drawer))
427 (buffer-string))))
428 ;; Indent inserted drawer.
429 (should
430 (equal "* H\n :PROPERTIES:\n :END:\nParagraph"
431 (org-test-with-temp-text "* H\nParagraph<point>"
432 (let ((org-adapt-indentation t)) (org-insert-property-drawer))
433 (buffer-string))))
434 ;; Handle insertion at eob.
435 (should
436 (equal "* H\n:PROPERTIES:\n:END:\n"
437 (org-test-with-temp-text "* H"
438 (let ((org-adapt-indentation nil)) (org-insert-property-drawer))
439 (buffer-string))))
440 ;; Skip inlinetasks before point.
441 (when (featurep 'org-inlinetask)
442 (should
443 (equal "* H\n:PROPERTIES:\n:END:\n*************** I\n*************** END\nP"
444 (org-test-with-temp-text
445 "* H\n*************** I\n*************** END\nP<point>"
446 (let ((org-adapt-indentation nil)
447 (org-inlinetask-min-level 15))
448 (org-insert-property-drawer))
449 (buffer-string)))))
450 ;; Correctly set drawer in an inlinetask.
451 (when (featurep 'org-inlinetask)
452 (should
453 (equal "* H\n*************** I\n:PROPERTIES:\n:END:\nP\n*************** END"
454 (org-test-with-temp-text
455 "* H\n*************** I\nP<point>\n*************** END"
456 (let ((org-adapt-indentation nil)
457 (org-inlinetask-min-level 15))
458 (org-insert-property-drawer))
459 (buffer-string))))))
462 ;;; Filling
464 (ert-deftest test-org/fill-element ()
465 "Test `org-fill-element' specifications."
466 ;; At an Org table, align it.
467 (should
468 (equal "| a |\n"
469 (org-test-with-temp-text "|a|"
470 (org-fill-element)
471 (buffer-string))))
472 (should
473 (equal "#+name: table\n| a |\n"
474 (org-test-with-temp-text "#+name: table\n| a |\n"
475 (org-fill-element)
476 (buffer-string))))
477 ;; At a paragraph, preserve line breaks.
478 (org-test-with-temp-text "some \\\\\nlong\ntext"
479 (let ((fill-column 20))
480 (org-fill-element)
481 (should (equal (buffer-string) "some \\\\\nlong text"))))
482 ;; Correctly fill a paragraph when point is at its very end.
483 (should
484 (equal "A B"
485 (org-test-with-temp-text "A\nB"
486 (let ((fill-column 20))
487 (goto-char (point-max))
488 (org-fill-element)
489 (buffer-string)))))
490 ;; Correctly fill the last paragraph of a greater element.
491 (should
492 (equal "#+BEGIN_CENTER\n- 012345\n 789\n#+END_CENTER"
493 (org-test-with-temp-text "#+BEGIN_CENTER\n- 012345 789\n#+END_CENTER"
494 (let ((fill-column 8))
495 (forward-line)
496 (end-of-line)
497 (org-fill-element)
498 (buffer-string)))))
499 ;; Correctly fill an element in a narrowed buffer.
500 (should
501 (equal "01234\n6"
502 (org-test-with-temp-text "01234 6789"
503 (let ((fill-column 5))
504 (narrow-to-region 1 8)
505 (org-fill-element)
506 (buffer-string)))))
507 ;; Handle `adaptive-fill-regexp' in paragraphs.
508 (should
509 (equal "> a b"
510 (org-test-with-temp-text "> a\n> b"
511 (let ((fill-column 5)
512 (adaptive-fill-regexp "[ \t]*>+[ \t]*"))
513 (org-fill-element)
514 (buffer-string)))))
515 ;; Special case: Fill first paragraph when point is at an item or
516 ;; a plain-list or a footnote reference.
517 (should
518 (equal "- A B"
519 (org-test-with-temp-text "- A\n B"
520 (let ((fill-column 20))
521 (org-fill-element)
522 (buffer-string)))))
523 (should
524 (equal "[fn:1] A B"
525 (org-test-with-temp-text "[fn:1] A\nB"
526 (let ((fill-column 20))
527 (org-fill-element)
528 (buffer-string)))))
529 (org-test-with-temp-text "#+BEGIN_VERSE\nSome \\\\\nlong\ntext\n#+END_VERSE"
530 (let ((fill-column 20))
531 (org-fill-element)
532 (should (equal (buffer-string)
533 "#+BEGIN_VERSE\nSome \\\\\nlong\ntext\n#+END_VERSE"))))
534 ;; Fill contents of `comment-block' elements.
535 (should
536 (equal
537 (org-test-with-temp-text "#+BEGIN_COMMENT\nSome\ntext\n#+END_COMMENT"
538 (let ((fill-column 20))
539 (forward-line)
540 (org-fill-element)
541 (buffer-string)))
542 "#+BEGIN_COMMENT\nSome text\n#+END_COMMENT"))
543 ;; Fill `comment' elements.
544 (should
545 (equal " # A B"
546 (org-test-with-temp-text " # A\n # B"
547 (let ((fill-column 20))
548 (org-fill-element)
549 (buffer-string)))))
550 ;; Do not mix consecutive comments when filling one of them.
551 (should
552 (equal "# A B\n\n# C"
553 (org-test-with-temp-text "# A\n# B\n\n# C"
554 (let ((fill-column 20))
555 (org-fill-element)
556 (buffer-string)))))
557 ;; Use commented empty lines as separators when filling comments.
558 (should
559 (equal "# A B\n#\n# C"
560 (org-test-with-temp-text "# A\n# B\n#\n# C"
561 (let ((fill-column 20))
562 (org-fill-element)
563 (buffer-string)))))
564 ;; Handle `adaptive-fill-regexp' in comments.
565 (should
566 (equal "# > a b"
567 (org-test-with-temp-text "# > a\n# > b"
568 (let ((fill-column 20)
569 (adaptive-fill-regexp "[ \t]*>+[ \t]*"))
570 (org-fill-element)
571 (buffer-string)))))
572 ;; Do nothing at affiliated keywords.
573 (should
574 (equal "#+NAME: para\nSome\ntext."
575 (org-test-with-temp-text "#+NAME: para\nSome\ntext."
576 (let ((fill-column 20))
577 (org-fill-element)
578 (buffer-string)))))
579 ;; Do not move point after table when filling a table.
580 (should-not
581 (org-test-with-temp-text "| a | b |\n| c | d |\n"
582 (forward-char)
583 (org-fill-element)
584 (eobp)))
585 ;; Do not fill "n" macro, with or without arguments, followed by
586 ;; a dot or a closing parenthesis since it could be confused with
587 ;; a numbered bullet.
588 (should-not
589 (equal "123456789\n{{{n}}}."
590 (org-test-with-temp-text "123456789 {{{n}}}."
591 (let ((fill-column 10))
592 (org-fill-element)
593 (buffer-string)))))
594 (should-not
595 (equal "123456789\n{{{n}}}\)"
596 (org-test-with-temp-text "123456789 {{{n}}}\)"
597 (let ((fill-column 10))
598 (org-fill-element)
599 (buffer-string)))))
600 (should-not
601 (equal "123456789\n{{{n()}}}."
602 (org-test-with-temp-text "123456789 {{{n()}}}."
603 (let ((fill-column 10))
604 (org-fill-element)
605 (buffer-string)))))
606 (should-not
607 (equal "123456789\n{{{n(counter)}}}."
608 (org-test-with-temp-text "123456789 {{{n(counter)}}}."
609 (let ((fill-column 10))
610 (org-fill-element)
611 (buffer-string))))))
613 (ert-deftest test-org/auto-fill-function ()
614 "Test auto-filling features."
615 ;; Auto fill paragraph.
616 (should
617 (equal "12345\n7890"
618 (org-test-with-temp-text "12345 7890"
619 (let ((fill-column 5))
620 (end-of-line)
621 (org-auto-fill-function)
622 (buffer-string)))))
623 ;; Auto fill first paragraph in an item.
624 (should
625 (equal "- 12345\n 7890"
626 (org-test-with-temp-text "- 12345 7890"
627 (let ((fill-column 7))
628 (end-of-line)
629 (org-auto-fill-function)
630 (buffer-string)))))
631 ;; Auto fill paragraph when `adaptive-fill-regexp' matches.
632 (should
633 (equal "> 12345\n 7890"
634 (org-test-with-temp-text "> 12345 7890"
635 (let ((fill-column 10)
636 (adaptive-fill-regexp "[ \t]*>+[ \t]*")
637 (adaptive-fill-first-line-regexp "\\`[ ]*\\'"))
638 (end-of-line)
639 (org-auto-fill-function)
640 (buffer-string)))))
641 (should
642 (equal "> 12345\n> 12345\n> 7890"
643 (org-test-with-temp-text "> 12345\n> 12345 7890"
644 (let ((fill-column 10)
645 (adaptive-fill-regexp "[ \t]*>+[ \t]*"))
646 (goto-char (point-max))
647 (org-auto-fill-function)
648 (buffer-string)))))
649 (should-not
650 (equal " 12345\n *12345\n *12345"
651 (org-test-with-temp-text " 12345\n *12345 12345"
652 (let ((fill-column 10)
653 (adaptive-fill-regexp "[ \t]*>+[ \t]*"))
654 (goto-char (point-max))
655 (org-auto-fill-function)
656 (buffer-string)))))
657 ;; Auto fill comments.
658 (should
659 (equal " # 12345\n # 7890"
660 (org-test-with-temp-text " # 12345 7890"
661 (let ((fill-column 10))
662 (end-of-line)
663 (org-auto-fill-function)
664 (buffer-string)))))
665 ;; A hash within a line isn't a comment.
666 (should-not
667 (equal "12345 # 7890\n# 1"
668 (org-test-with-temp-text "12345 # 7890 1"
669 (let ((fill-column 12))
670 (end-of-line)
671 (org-auto-fill-function)
672 (buffer-string)))))
673 ;; Correctly interpret empty prefix.
674 (should-not
675 (equal "# a\n# b\nRegular\n# paragraph"
676 (org-test-with-temp-text "# a\n# b\nRegular paragraph"
677 (let ((fill-column 12))
678 (end-of-line 3)
679 (org-auto-fill-function)
680 (buffer-string)))))
681 ;; Comment block: auto fill contents.
682 (should
683 (equal "#+BEGIN_COMMENT\n12345\n7890\n#+END_COMMENT"
684 (org-test-with-temp-text "#+BEGIN_COMMENT\n12345 7890\n#+END_COMMENT"
685 (let ((fill-column 5))
686 (forward-line)
687 (end-of-line)
688 (org-auto-fill-function)
689 (buffer-string)))))
690 (should
691 (equal "#+BEGIN_COMMENT\n12345\n7890\n#+END_COMMENT"
692 (org-test-with-temp-text "#+BEGIN_COMMENT\n12345 7890\n#+END_COMMENT"
693 (let ((fill-column 5))
694 (forward-line)
695 (end-of-line)
696 (org-auto-fill-function)
697 (buffer-string)))))
698 ;; Do not fill if a new item could be created.
699 (should-not
700 (equal "12345\n- 90"
701 (org-test-with-temp-text "12345 - 90"
702 (let ((fill-column 5))
703 (end-of-line)
704 (org-auto-fill-function)
705 (buffer-string)))))
706 ;; Do not fill if a line break could be introduced.
707 (should-not
708 (equal "123\\\\\n7890"
709 (org-test-with-temp-text "123\\\\ 7890"
710 (let ((fill-column 6))
711 (end-of-line)
712 (org-auto-fill-function)
713 (buffer-string)))))
714 ;; Do not fill affiliated keywords.
715 (should-not
716 (equal "#+ATTR_LATEX: ABC\nDEFGHIJKL"
717 (org-test-with-temp-text "#+ATTR_LATEX: ABC DEFGHIJKL"
718 (let ((fill-column 20))
719 (end-of-line)
720 (org-auto-fill-function)
721 (buffer-string))))))
725 ;;; Indentation
727 (ert-deftest test-org/indent-line ()
728 "Test `org-indent-line' specifications."
729 ;; Do not indent diary sexps, footnote definitions or headlines.
730 (should
731 (zerop
732 (org-test-with-temp-text "%%(org-calendar-holiday)"
733 (org-indent-line)
734 (org-get-indentation))))
735 (should
736 (zerop
737 (org-test-with-temp-text "[fn:1] fn"
738 (let ((org-adapt-indentation t)) (org-indent-line))
739 (org-get-indentation))))
740 (should
741 (zerop
742 (org-test-with-temp-text "* H"
743 (org-indent-line)
744 (org-get-indentation))))
745 ;; Do not indent before first headline.
746 (should
747 (zerop
748 (org-test-with-temp-text ""
749 (org-indent-line)
750 (org-get-indentation))))
751 ;; Indent according to headline level otherwise, unless
752 ;; `org-adapt-indentation' is nil.
753 (should
754 (= 2
755 (org-test-with-temp-text "* H\n<point>A"
756 (let ((org-adapt-indentation t)) (org-indent-line))
757 (org-get-indentation))))
758 (should
759 (= 2
760 (org-test-with-temp-text "* H\n<point>\nA"
761 (let ((org-adapt-indentation t)) (org-indent-line))
762 (org-get-indentation))))
763 (should
764 (zerop
765 (org-test-with-temp-text "* H\n<point>A"
766 (let ((org-adapt-indentation nil)) (org-indent-line))
767 (org-get-indentation))))
768 ;; Indenting preserves point position.
769 (should
770 (org-test-with-temp-text "* H\nA<point>B"
771 (let ((org-adapt-indentation t)) (org-indent-line))
772 (looking-at "B")))
773 ;; Do not change indentation at an item or a LaTeX environment.
774 (should
775 (= 1
776 (org-test-with-temp-text "* H\n<point> - A"
777 (let ((org-adapt-indentation t)) (org-indent-line))
778 (org-get-indentation))))
779 (should
780 (= 1
781 (org-test-with-temp-text
782 "\\begin{equation}\n <point>1+1=2\n\\end{equation}"
783 (org-indent-line)
784 (org-get-indentation))))
785 ;; On blank lines at the end of a list, indent like last element
786 ;; within it if the line is still in the list. If the last element
787 ;; is an item, indent like its contents. Otherwise, indent like the
788 ;; whole list.
789 (should
790 (= 4
791 (org-test-with-temp-text "* H\n- A\n - AA\n<point>"
792 (let ((org-adapt-indentation t)) (org-indent-line))
793 (org-get-indentation))))
794 (should
795 (= 4
796 (org-test-with-temp-text "* H\n- A\n -\n\n<point>"
797 (let ((org-adapt-indentation t)) (org-indent-line))
798 (org-get-indentation))))
799 (should
800 (zerop
801 (org-test-with-temp-text "* H\n- A\n - AA\n\n\n\n<point>"
802 (let ((org-adapt-indentation t)) (org-indent-line))
803 (org-get-indentation))))
804 (should
805 (= 4
806 (org-test-with-temp-text "* H\n- A\n - \n<point>"
807 (let ((org-adapt-indentation t)) (org-indent-line))
808 (org-get-indentation))))
809 (should
810 (= 4
811 (org-test-with-temp-text
812 "* H\n - \n #+BEGIN_SRC emacs-lisp\n t\n #+END_SRC\n<point>"
813 (let ((org-adapt-indentation t)) (org-indent-line))
814 (org-get-indentation))))
815 (should
816 (= 2
817 (org-test-with-temp-text "- A\n B\n\n<point>"
818 (let ((org-adapt-indentation nil)) (org-indent-line))
819 (org-get-indentation))))
820 (should
821 (= 2
822 (org-test-with-temp-text
823 "- A\n \begin{cases} 1 + 1\n \end{cases}\n\n<point>"
824 (let ((org-adapt-indentation nil)) (org-indent-line))
825 (org-get-indentation))))
826 ;; Likewise, on a blank line at the end of a footnote definition,
827 ;; indent at column 0 if line belongs to the definition. Otherwise,
828 ;; indent like the definition itself.
829 (should
830 (zerop
831 (org-test-with-temp-text "* H\n[fn:1] Definition\n<point>"
832 (let ((org-adapt-indentation t)) (org-indent-line))
833 (org-get-indentation))))
834 (should
835 (zerop
836 (org-test-with-temp-text "* H\n[fn:1] Definition\n\n\n\n<point>"
837 (let ((org-adapt-indentation t)) (org-indent-line))
838 (org-get-indentation))))
839 ;; After the end of the contents of a greater element, indent like
840 ;; the beginning of the element.
841 (should
842 (= 1
843 (org-test-with-temp-text
844 " #+BEGIN_CENTER\n Contents\n<point>#+END_CENTER"
845 (org-indent-line)
846 (org-get-indentation))))
847 ;; On blank lines after a paragraph, indent like its last non-empty
848 ;; line.
849 (should
850 (= 1
851 (org-test-with-temp-text " Paragraph\n\n<point>"
852 (org-indent-line)
853 (org-get-indentation))))
854 ;; At the first line of an element, indent like previous element's
855 ;; first line, ignoring footnotes definitions and inline tasks, or
856 ;; according to parent.
857 (should
858 (= 2
859 (org-test-with-temp-text "A\n\n B\n\nC<point>"
860 (org-indent-line)
861 (org-get-indentation))))
862 (should
863 (= 1
864 (org-test-with-temp-text " A\n\n[fn:1] B\n\n\nC<point>"
865 (org-indent-line)
866 (org-get-indentation))))
867 (should
868 (= 1
869 (org-test-with-temp-text
870 " #+BEGIN_CENTER\n<point> Contents\n#+END_CENTER"
871 (org-indent-line)
872 (org-get-indentation))))
873 ;; Within code part of a source block, use language major mode if
874 ;; `org-src-tab-acts-natively' is non-nil. Otherwise, indent
875 ;; according to line above.
876 (should
877 (= 6
878 (org-test-with-temp-text
879 "#+BEGIN_SRC emacs-lisp\n (and A\n<point>B)\n#+END_SRC"
880 (let ((org-src-tab-acts-natively t)
881 (org-edit-src-content-indentation 0))
882 (org-indent-line))
883 (org-get-indentation))))
884 (should
885 (= 1
886 (org-test-with-temp-text
887 "#+BEGIN_SRC emacs-lisp\n (and A\n<point>B)\n#+END_SRC"
888 (let ((org-src-tab-acts-natively nil)
889 (org-edit-src-content-indentation 0))
890 (org-indent-line))
891 (org-get-indentation))))
892 ;; Otherwise, indent like the first non-blank line above.
893 (should
894 (zerop
895 (org-test-with-temp-text
896 "#+BEGIN_CENTER\nline1\n\n<point> line2\n#+END_CENTER"
897 (org-indent-line)
898 (org-get-indentation))))
899 ;; Align node properties according to `org-property-format'. Handle
900 ;; nicely empty values.
901 (should
902 (equal "* H\n:PROPERTIES:\n:key: value\n:END:"
903 (org-test-with-temp-text
904 "* H\n:PROPERTIES:\n<point>:key: value\n:END:"
905 (let ((org-property-format "%-10s %s")) (org-indent-line))
906 (buffer-string))))
907 (should
908 (equal "* H\n:PROPERTIES:\n:key:\n:END:"
909 (org-test-with-temp-text "* H\n:PROPERTIES:\n<point>:key:\n:END:"
910 (let ((org-property-format "%-10s %s")) (org-indent-line))
911 (buffer-string)))))
913 (ert-deftest test-org/indent-region ()
914 "Test `org-indent-region' specifications."
915 ;; Indent paragraph.
916 (should
917 (equal "A\nB\nC"
918 (org-test-with-temp-text " A\nB\n C"
919 (org-indent-region (point-min) (point-max))
920 (buffer-string))))
921 ;; Indent greater elements along with their contents.
922 (should
923 (equal "#+BEGIN_CENTER\nA\nB\n#+END_CENTER"
924 (org-test-with-temp-text "#+BEGIN_CENTER\n A\n B\n#+END_CENTER"
925 (org-indent-region (point-min) (point-max))
926 (buffer-string))))
927 ;; Ignore contents of verse blocks. Only indent block delimiters.
928 (should
929 (equal "#+BEGIN_VERSE\n A\n B\n#+END_VERSE"
930 (org-test-with-temp-text "#+BEGIN_VERSE\n A\n B\n#+END_VERSE"
931 (org-indent-region (point-min) (point-max))
932 (buffer-string))))
933 (should
934 (equal "#+BEGIN_VERSE\n A\n B\n#+END_VERSE"
935 (org-test-with-temp-text " #+BEGIN_VERSE\n A\n B\n #+END_VERSE"
936 (org-indent-region (point-min) (point-max))
937 (buffer-string))))
938 ;; Indent example blocks as a single block, unless indentation
939 ;; should be preserved. In this case only indent the block markers.
940 (should
941 (equal "#+BEGIN_EXAMPLE\n A\n B\n#+END_EXAMPLE"
942 (org-test-with-temp-text "#+BEGIN_EXAMPLE\n A\n B\n#+END_EXAMPLE"
943 (org-indent-region (point-min) (point-max))
944 (buffer-string))))
945 (should
946 (equal "#+BEGIN_EXAMPLE\n A\n B\n#+END_EXAMPLE"
947 (org-test-with-temp-text " #+BEGIN_EXAMPLE\n A\n B\n #+END_EXAMPLE"
948 (org-indent-region (point-min) (point-max))
949 (buffer-string))))
950 (should
951 (equal "#+BEGIN_EXAMPLE -i\n A\n B\n#+END_EXAMPLE"
952 (org-test-with-temp-text
953 " #+BEGIN_EXAMPLE -i\n A\n B\n #+END_EXAMPLE"
954 (org-indent-region (point-min) (point-max))
955 (buffer-string))))
956 (should
957 (equal "#+BEGIN_EXAMPLE\n A\n B\n#+END_EXAMPLE"
958 (org-test-with-temp-text
959 " #+BEGIN_EXAMPLE\n A\n B\n #+END_EXAMPLE"
960 (let ((org-src-preserve-indentation t))
961 (org-indent-region (point-min) (point-max)))
962 (buffer-string))))
963 ;; Treat export blocks as a whole.
964 (should
965 (equal "#+BEGIN_EXPORT latex\n A\n B\n#+END_EXPORT"
966 (org-test-with-temp-text "#+BEGIN_EXPORT latex\n A\n B\n#+END_EXPORT"
967 (org-indent-region (point-min) (point-max))
968 (buffer-string))))
969 (should
970 (equal "#+BEGIN_EXPORT latex\n A\n B\n#+END_EXPORT"
971 (org-test-with-temp-text
972 " #+BEGIN_EXPORT latex\n A\n B\n #+END_EXPORT"
973 (org-indent-region (point-min) (point-max))
974 (buffer-string))))
975 ;; Indent according to mode if `org-src-tab-acts-natively' is
976 ;; non-nil. Otherwise, do not indent code at all.
977 (should
978 (equal "#+BEGIN_SRC emacs-lisp\n(and A\n B)\n#+END_SRC"
979 (org-test-with-temp-text
980 "#+BEGIN_SRC emacs-lisp\n (and A\nB)\n#+END_SRC"
981 (let ((org-src-tab-acts-natively t)
982 (org-edit-src-content-indentation 0))
983 (org-indent-region (point-min) (point-max)))
984 (buffer-string))))
985 (should
986 (equal "#+BEGIN_SRC emacs-lisp\n (and A\nB)\n#+END_SRC"
987 (org-test-with-temp-text
988 "#+BEGIN_SRC emacs-lisp\n (and A\nB)\n#+END_SRC"
989 (let ((org-src-tab-acts-natively nil)
990 (org-edit-src-content-indentation 0))
991 (org-indent-region (point-min) (point-max)))
992 (buffer-string))))
993 ;; Align node properties according to `org-property-format'. Handle
994 ;; nicely empty values.
995 (should
996 (equal "* H\n:PROPERTIES:\n:key: value\n:END:"
997 (org-test-with-temp-text "* H\n<point>:PROPERTIES:\n:key: value\n:END:"
998 (let ((org-property-format "%-10s %s")
999 (org-adapt-indentation nil))
1000 (org-indent-region (point) (point-max)))
1001 (buffer-string))))
1002 (should
1003 (equal "* H\n:PROPERTIES:\n:key:\n:END:"
1004 (org-test-with-temp-text "* H\n<point>:PROPERTIES:\n:key:\n:END:"
1005 (let ((org-property-format "%-10s %s")
1006 (org-adapt-indentation nil))
1007 (org-indent-region (point) (point-max)))
1008 (buffer-string))))
1009 ;; Indent plain lists.
1010 (should
1011 (equal "- A\n B\n - C\n\n D"
1012 (org-test-with-temp-text "- A\n B\n - C\n\n D"
1013 (org-indent-region (point-min) (point-max))
1014 (buffer-string))))
1015 (should
1016 (equal "- A\n\n- B"
1017 (org-test-with-temp-text " - A\n\n - B"
1018 (org-indent-region (point-min) (point-max))
1019 (buffer-string))))
1020 ;; Indent footnote definitions.
1021 (should
1022 (equal "[fn:1] Definition\n\nDefinition"
1023 (org-test-with-temp-text "[fn:1] Definition\n\n Definition"
1024 (org-indent-region (point-min) (point-max))
1025 (buffer-string))))
1026 ;; Special case: Start indenting on a blank line.
1027 (should
1028 (equal "\nParagraph"
1029 (org-test-with-temp-text "\n Paragraph"
1030 (org-indent-region (point-min) (point-max))
1031 (buffer-string)))))
1035 ;;; Editing
1037 (ert-deftest test-org/delete-indentation ()
1038 "Test `org-delete-indentation' specifications."
1039 ;; Regular test.
1040 (should (equal "foo bar"
1041 (org-test-with-temp-text
1042 "foo \n bar<point>"
1043 (org-delete-indentation)
1044 (buffer-string))))
1045 ;; With optional argument.
1046 (should (equal "foo bar"
1047 (org-test-with-temp-text
1048 "foo<point> \n bar"
1049 (org-delete-indentation t)
1050 (buffer-string))))
1051 ;; At headline text should be appended to the headline text.
1052 (should
1053 (equal"* foo bar :tag:"
1054 (let (org-auto-align-tags)
1055 (org-test-with-temp-text
1056 "* foo :tag:\n bar<point>"
1057 (org-delete-indentation)
1058 (buffer-string)))))
1059 (should
1060 (equal "* foo bar :tag:"
1061 (let (org-auto-align-tags)
1062 (org-test-with-temp-text
1063 "* foo <point>:tag:\n bar"
1064 (org-delete-indentation t)
1065 (buffer-string))))))
1067 (ert-deftest test-org/return ()
1068 "Test `org-return' specifications."
1069 ;; Regular test.
1070 (should
1071 (equal "Para\ngraph"
1072 (org-test-with-temp-text "Para<point>graph"
1073 (org-return)
1074 (buffer-string))))
1075 ;; With optional argument, indent line.
1076 (should
1077 (equal " Para\n graph"
1078 (org-test-with-temp-text " Para<point>graph"
1079 (org-return t)
1080 (buffer-string))))
1081 ;; On a table, call `org-table-next-row'.
1082 (should
1083 (org-test-with-temp-text "| <point>a |\n| b |"
1084 (org-return)
1085 (looking-at-p "b")))
1086 ;; Open link or timestamp under point when `org-return-follows-link'
1087 ;; is non-nil.
1088 (should
1089 (org-test-with-temp-text "Link [[target<point>]] <<target>>"
1090 (let ((org-return-follows-link t)
1091 (org-link-search-must-match-exact-headline nil))
1092 (org-return))
1093 (looking-at-p "<<target>>")))
1094 (should-not
1095 (org-test-with-temp-text "Link [[target<point>]] <<target>>"
1096 (let ((org-return-follows-link nil)) (org-return))
1097 (looking-at-p "<<target>>")))
1098 (should
1099 (org-test-with-temp-text "* [[b][a<point>]]\n* b"
1100 (let ((org-return-follows-link t)) (org-return))
1101 (looking-at-p "* b")))
1102 (should
1103 (org-test-with-temp-text "Link [[target][/descipt<point>ion/]] <<target>>"
1104 (let ((org-return-follows-link t)
1105 (org-link-search-must-match-exact-headline nil))
1106 (org-return))
1107 (looking-at-p "<<target>>")))
1108 (should-not
1109 (org-test-with-temp-text "Link [[target]]<point> <<target>>"
1110 (let ((org-return-follows-link t)
1111 (org-link-search-must-match-exact-headline nil))
1112 (org-return))
1113 (looking-at-p "<<target>>")))
1114 ;; When `org-return-follows-link' is non-nil, tolerate links and
1115 ;; timestamps in comments, node properties, etc.
1116 (should
1117 (org-test-with-temp-text "# Comment [[target<point>]]\n <<target>>"
1118 (let ((org-return-follows-link t)
1119 (org-link-search-must-match-exact-headline nil))
1120 (org-return))
1121 (looking-at-p "<<target>>")))
1122 (should-not
1123 (org-test-with-temp-text "# Comment [[target<point>]]\n <<target>>"
1124 (let ((org-return-follows-link nil)) (org-return))
1125 (looking-at-p "<<target>>")))
1126 (should-not
1127 (org-test-with-temp-text "# Comment [[target]]<point>\n <<target>>"
1128 (let ((org-return-follows-link t)
1129 (org-link-search-must-match-exact-headline nil))
1130 (org-return))
1131 (looking-at-p "<<target>>")))
1132 ;; `org-return-follows-link' handle multi-line lines.
1133 (should
1134 (org-test-with-temp-text
1135 "[[target][This is a very\n long description<point>]]\n <<target>>"
1136 (let ((org-return-follows-link t)
1137 (org-link-search-must-match-exact-headline nil))
1138 (org-return))
1139 (looking-at-p "<<target>>")))
1140 (should-not
1141 (org-test-with-temp-text
1142 "[[target][This is a very\n long description]]<point>\n <<target>>"
1143 (let ((org-return-follows-link t)
1144 (org-link-search-must-match-exact-headline nil))
1145 (org-return))
1146 (looking-at-p "<<target>>")))
1147 ;; However, do not open link when point is in a table.
1148 (should
1149 (org-test-with-temp-text "| [[target<point>]] |\n| between |\n| <<target>> |"
1150 (let ((org-return-follows-link t)) (org-return))
1151 (looking-at-p "between")))
1152 ;; Special case: in a list, when indenting, do not break structure.
1153 (should
1154 (equal "- A\n B"
1155 (org-test-with-temp-text "- A <point>B"
1156 (org-return t)
1157 (buffer-string))))
1158 (should
1159 (equal "- A\n\n- B"
1160 (org-test-with-temp-text "- A\n<point>- B"
1161 (org-return t)
1162 (buffer-string))))
1163 ;; On tags part of a headline, add a newline below it instead of
1164 ;; breaking it.
1165 (should
1166 (equal "* H :tag:\n"
1167 (org-test-with-temp-text "* H :<point>tag:"
1168 (org-return)
1169 (buffer-string))))
1170 ;; Before headline text, add a newline below it instead of breaking
1171 ;; it.
1172 (should
1173 (equal "* TODO H :tag:\n"
1174 (org-test-with-temp-text "* <point>TODO H :tag:"
1175 (org-return)
1176 (buffer-string))))
1177 (should
1178 (equal "* TODO [#B] H :tag:\n"
1179 (org-test-with-temp-text "* TODO<point> [#B] H :tag:"
1180 (org-return)
1181 (buffer-string))))
1182 (should ;TODO are case-sensitive
1183 (equal "* \nTodo"
1184 (org-test-with-temp-text "* <point>Todo"
1185 (org-return)
1186 (buffer-string))))
1187 ;; At headline text, break headline text but preserve tags.
1188 (should
1189 (equal "* TODO [#B] foo :tag:\nbar"
1190 (let (org-auto-align-tags)
1191 (org-test-with-temp-text "* TODO [#B] foo<point>bar :tag:"
1192 (org-return)
1193 (buffer-string)))))
1194 ;; At bol of headline insert newline.
1195 (should
1196 (equal "\n* h"
1197 (org-test-with-temp-text "<point>* h"
1198 (org-return)
1199 (buffer-string))))
1200 ;; Refuse to leave invalid headline in buffer.
1201 (should
1202 (equal "* h\n"
1203 (org-test-with-temp-text "*<point> h"
1204 (org-return)
1205 (buffer-string))))
1206 ;; Before first column or after last one in a table, split the
1207 ;; table.
1208 (should
1209 (equal "| a |\n\n| b |"
1210 (org-test-with-temp-text "| a |\n<point>| b |"
1211 (org-return)
1212 (buffer-string))))
1213 (should
1214 (equal "| a |\n\n| b |"
1215 (org-test-with-temp-text "| a |<point>\n| b |"
1216 (org-return)
1217 (buffer-string))))
1218 ;; Do not auto-fill on hitting <RET> inside a property drawer.
1219 (should
1220 (equal "* Heading\n:PROPERTIES:\n:SOME_PROP: This is a very long property value that goes beyond the fill-column. But this is inside a property drawer, so the auto-filling should be disabled.\n\n:END:"
1221 (org-test-with-temp-text "* Heading\n:PROPERTIES:\n:SOME_PROP: This is a very long property value that goes beyond the fill-column. But this is inside a property drawer, so the auto-filling should be disabled.<point>\n:END:"
1222 (setq-local fill-column 10)
1223 (auto-fill-mode 1)
1224 (org-return)
1225 (buffer-string)))))
1227 (ert-deftest test-org/meta-return ()
1228 "Test M-RET (`org-meta-return') specifications."
1229 ;; In a table field insert a row above.
1230 (should
1231 (org-test-with-temp-text "| a |"
1232 (forward-char)
1233 (org-meta-return)
1234 (forward-line -1)
1235 (looking-at "| |$")))
1236 ;; In a paragraph change current line into a header.
1237 (should
1238 (org-test-with-temp-text "a"
1239 (org-meta-return)
1240 (beginning-of-line)
1241 (looking-at "\* a$")))
1242 ;; In an item insert an item, in this case above.
1243 (should
1244 (org-test-with-temp-text "- a"
1245 (org-meta-return)
1246 (beginning-of-line)
1247 (looking-at "- $")))
1248 ;; In a drawer and item insert an item, in this case above.
1249 (should
1250 (org-test-with-temp-text ":MYDRAWER:\n- a\n:END:"
1251 (forward-line)
1252 (org-meta-return)
1253 (beginning-of-line)
1254 (looking-at "- $"))))
1256 (ert-deftest test-org/insert-heading ()
1257 "Test `org-insert-heading' specifications."
1258 ;; In an empty buffer, insert a new headline.
1259 (should
1260 (equal "* "
1261 (org-test-with-temp-text ""
1262 (org-insert-heading)
1263 (buffer-string))))
1264 ;; At the beginning of a line, turn it into a headline.
1265 (should
1266 (equal "* P"
1267 (org-test-with-temp-text "<point>P"
1268 (org-insert-heading)
1269 (buffer-string))))
1270 ;; In the middle of a line, split the line if allowed, otherwise,
1271 ;; insert the headline at its end.
1272 (should
1273 (equal "Para\n* graph"
1274 (org-test-with-temp-text "Para<point>graph"
1275 (let ((org-M-RET-may-split-line '((default . t))))
1276 (org-insert-heading))
1277 (buffer-string))))
1278 (should
1279 (equal "Paragraph\n* "
1280 (org-test-with-temp-text "Para<point>graph"
1281 (let ((org-M-RET-may-split-line '((default . nil))))
1282 (org-insert-heading))
1283 (buffer-string))))
1284 ;; At the beginning of a headline, create one above.
1285 (should
1286 (equal "* \n* H"
1287 (org-test-with-temp-text "* H"
1288 (org-insert-heading)
1289 (buffer-string))))
1290 ;; In the middle of a headline, split it if allowed.
1291 (should
1292 (equal "* H\n* 1\n"
1293 (org-test-with-temp-text "* H<point>1"
1294 (let ((org-M-RET-may-split-line '((headline . t))))
1295 (org-insert-heading))
1296 (buffer-string))))
1297 (should
1298 (equal "* H1\n* \n"
1299 (org-test-with-temp-text "* H<point>1"
1300 (let ((org-M-RET-may-split-line '((headline . nil))))
1301 (org-insert-heading))
1302 (buffer-string))))
1303 ;; However, splitting cannot happen on TODO keywords, priorities or
1304 ;; tags.
1305 (should
1306 (equal "* TODO H1\n* \n"
1307 (org-test-with-temp-text "* TO<point>DO H1"
1308 (let ((org-M-RET-may-split-line '((headline . t))))
1309 (org-insert-heading))
1310 (buffer-string))))
1311 (should
1312 (equal "* [#A] H1\n* \n"
1313 (org-test-with-temp-text "* [#<point>A] H1"
1314 (let ((org-M-RET-may-split-line '((headline . t))))
1315 (org-insert-heading))
1316 (buffer-string))))
1317 (should
1318 (equal "* H1 :tag:\n* \n"
1319 (org-test-with-temp-text "* H1 :ta<point>g:"
1320 (let ((org-M-RET-may-split-line '((headline . t))))
1321 (org-insert-heading))
1322 (buffer-string))))
1323 ;; New headline level depends on the level of the headline above.
1324 (should
1325 (equal "** H\n** P"
1326 (org-test-with-temp-text "** H\n<point>P"
1327 (org-insert-heading)
1328 (buffer-string))))
1329 (should
1330 (equal "** H\nPara\n** graph"
1331 (org-test-with-temp-text "** H\nPara<point>graph"
1332 (let ((org-M-RET-may-split-line '((default . t))))
1333 (org-insert-heading))
1334 (buffer-string))))
1335 (should
1336 (equal "** \n** H"
1337 (org-test-with-temp-text "** H"
1338 (org-insert-heading)
1339 (buffer-string))))
1340 ;; When called with one universal argument, insert a new headline at
1341 ;; the end of the current subtree, independently on the position of
1342 ;; point.
1343 (should
1344 (equal
1345 "* H1\n** H2\n* \n"
1346 (org-test-with-temp-text "* H1\n** H2"
1347 (let ((org-insert-heading-respect-content nil))
1348 (org-insert-heading '(4)))
1349 (buffer-string))))
1350 (should
1351 (equal
1352 "* H1\n** H2\n* \n"
1353 (org-test-with-temp-text "* H<point>1\n** H2"
1354 (let ((org-insert-heading-respect-content nil))
1355 (org-insert-heading '(4)))
1356 (buffer-string))))
1357 ;; When called with two universal arguments, insert a new headline
1358 ;; at the end of the grandparent subtree.
1359 (should
1360 (equal "* H1\n** H3\n- item\n** H2\n** \n"
1361 (org-test-with-temp-text "* H1\n** H3\n- item<point>\n** H2"
1362 (let ((org-insert-heading-respect-content nil))
1363 (org-insert-heading '(16)))
1364 (buffer-string))))
1365 ;; When optional TOP-LEVEL argument is non-nil, always insert
1366 ;; a level 1 heading.
1367 (should
1368 (equal "* H1\n** H2\n* \n"
1369 (org-test-with-temp-text "* H1\n** H2<point>"
1370 (org-insert-heading nil nil t)
1371 (buffer-string))))
1372 (should
1373 (equal "* H1\n- item\n* "
1374 (org-test-with-temp-text "* H1\n- item<point>"
1375 (org-insert-heading nil nil t)
1376 (buffer-string))))
1377 ;; Obey `org-blank-before-new-entry'.
1378 (should
1379 (equal "* H1\n\n* \n"
1380 (org-test-with-temp-text "* H1<point>"
1381 (let ((org-blank-before-new-entry '((heading . t))))
1382 (org-insert-heading))
1383 (buffer-string))))
1384 (should
1385 (equal "* H1\n* \n"
1386 (org-test-with-temp-text "* H1<point>"
1387 (let ((org-blank-before-new-entry '((heading . nil))))
1388 (org-insert-heading))
1389 (buffer-string))))
1390 (should
1391 (equal "* H1\n* H2\n* \n"
1392 (org-test-with-temp-text "* H1\n* H2<point>"
1393 (let ((org-blank-before-new-entry '((heading . auto))))
1394 (org-insert-heading))
1395 (buffer-string))))
1396 (should
1397 (equal "* H1\n\n* H2\n\n* \n"
1398 (org-test-with-temp-text "* H1\n\n* H2<point>"
1399 (let ((org-blank-before-new-entry '((heading . auto))))
1400 (org-insert-heading))
1401 (buffer-string))))
1402 ;; Corner case: correctly insert a headline after an empty one.
1403 (should
1404 (equal "* \n* \n"
1405 (org-test-with-temp-text "* <point>"
1406 (org-insert-heading)
1407 (buffer-string))))
1408 (should
1409 (org-test-with-temp-text "* <point>\n"
1410 (org-insert-heading)
1411 (looking-at-p "\n\\'")))
1412 ;; Do not insert spurious headlines when inserting a new headline.
1413 (should
1414 (equal "* H1\n* H2\n* \n"
1415 (org-test-with-temp-text "* H1\n* H2<point>\n"
1416 (org-insert-heading)
1417 (buffer-string))))
1418 ;; Preserve visibility at beginning of line. In particular, when
1419 ;; removing spurious blank lines, do not visually merge heading with
1420 ;; the line visible above.
1421 (should-not
1422 (org-test-with-temp-text "* H1<point>\nContents\n\n* H2\n"
1423 (org-overview)
1424 (let ((org-blank-before-new-entry '((heading . nil))))
1425 (org-insert-heading '(4)))
1426 (invisible-p (line-end-position 0))))
1427 ;; Properly handle empty lines when forcing a headline below current
1428 ;; one.
1429 (should
1430 (equal "* H1\n\n* H\n\n* \n"
1431 (org-test-with-temp-text "* H1\n\n* H<point>"
1432 (let ((org-blank-before-new-entry '((heading . t))))
1433 (org-insert-heading '(4))
1434 (buffer-string))))))
1436 (ert-deftest test-org/insert-todo-heading-respect-content ()
1437 "Test `org-insert-todo-heading-respect-content' specifications."
1438 ;; Create a TODO heading.
1439 (should
1440 (org-test-with-temp-text "* H1\n Body"
1441 (org-insert-todo-heading-respect-content)
1442 (nth 2 (org-heading-components))))
1443 ;; Add headline at the end of the first subtree
1444 (should
1445 (equal
1446 "* TODO \n"
1447 (org-test-with-temp-text "* H1\nH1Body<point>\n** H2\nH2Body"
1448 (org-insert-todo-heading-respect-content)
1449 (buffer-substring-no-properties (line-beginning-position) (point-max)))))
1450 ;; In a list, do not create a new item.
1451 (should
1452 (equal
1453 "* TODO \n"
1454 (org-test-with-temp-text "* H\n- an item\n- another one"
1455 (search-forward "an ")
1456 (org-insert-todo-heading-respect-content)
1457 (buffer-substring-no-properties (line-beginning-position) (point-max)))))
1458 ;; Use the same TODO keyword as current heading.
1459 (should
1460 (equal
1461 "* TODO \n"
1462 (org-test-with-temp-text "* TODO\n** WAITING\n"
1463 (org-insert-todo-heading-respect-content)
1464 (buffer-substring-no-properties (line-beginning-position) (point-max))))))
1466 (ert-deftest test-org/clone-with-time-shift ()
1467 "Test `org-clone-subtree-with-time-shift'."
1468 ;; Raise an error before first heading.
1469 (should-error
1470 (org-test-with-temp-text ""
1471 (org-clone-subtree-with-time-shift 1)))
1472 ;; Raise an error on invalid number of clones.
1473 (should-error
1474 (org-test-with-temp-text "* Clone me"
1475 (org-clone-subtree-with-time-shift -1)))
1476 ;; Clone non-repeating once.
1477 (should
1478 (equal "\
1479 * H1\n<2015-06-21>
1480 * H1\n<2015-06-23>
1482 (org-test-with-temp-text "* H1\n<2015-06-21 Sun>"
1483 (org-clone-subtree-with-time-shift 1 "+2d")
1484 (replace-regexp-in-string
1485 "\\( [.A-Za-z]+\\)\\( \\+[0-9][hdmwy]\\)?>" "" (buffer-string)
1486 nil nil 1))))
1487 ;; Clone repeating once.
1488 (should
1489 (equal "\
1490 * H1\n<2015-06-21>
1491 * H1\n<2015-06-23>
1492 * H1\n<2015-06-25 +1w>
1494 (org-test-with-temp-text "* H1\n<2015-06-21 Sun +1w>"
1495 (org-clone-subtree-with-time-shift 1 "+2d")
1496 (replace-regexp-in-string
1497 "\\( [.A-Za-z]+\\)\\( \\+[0-9][hdmwy]\\)?>" "" (buffer-string)
1498 nil nil 1))))
1499 ;; Clone non-repeating zero times.
1500 (should
1501 (equal "\
1502 * H1\n<2015-06-21>
1504 (org-test-with-temp-text "* H1\n<2015-06-21 Sun>"
1505 (org-clone-subtree-with-time-shift 0 "+2d")
1506 (replace-regexp-in-string
1507 "\\( [.A-Za-z]+\\)\\( \\+[0-9][hdmwy]\\)?>" "" (buffer-string)
1508 nil nil 1))))
1509 ;; Clone repeating "zero" times.
1510 (should
1511 (equal "\
1512 * H1\n<2015-06-21>
1513 * H1\n<2015-06-23 +1w>
1515 (org-test-with-temp-text "* H1\n<2015-06-21 Sun +1w>"
1516 (org-clone-subtree-with-time-shift 0 "+2d")
1517 (replace-regexp-in-string
1518 "\\( [.A-Za-z]+\\)\\( \\+[0-9][hdmwy]\\)?>" "" (buffer-string)
1519 nil nil 1))))
1520 ;; Clone with blank SHIFT argument.
1521 (should
1522 (string-prefix-p
1523 "* H <2012-03-29"
1524 (org-test-with-temp-text "* H <2012-03-29 Thu><point>"
1525 (org-clone-subtree-with-time-shift 1 "")
1526 (buffer-substring-no-properties (line-beginning-position 2)
1527 (line-end-position 2)))))
1528 ;; Find time stamps before point. If SHIFT is not specified, ask
1529 ;; for a time shift.
1530 (should
1531 (string-prefix-p
1532 "* H <2012-03-30"
1533 (org-test-with-temp-text "* H <2012-03-29 Thu><point>"
1534 (org-clone-subtree-with-time-shift 1 "+1d")
1535 (buffer-substring-no-properties (line-beginning-position 2)
1536 (line-end-position 2)))))
1537 (should
1538 (string-prefix-p
1539 "* H <2014-03-05"
1540 (org-test-with-temp-text "* H <2014-03-04 Tue><point>"
1541 (cl-letf (((symbol-function 'read-from-minibuffer)
1542 (lambda (&rest args) "+1d")))
1543 (org-clone-subtree-with-time-shift 1))
1544 (buffer-substring-no-properties (line-beginning-position 2)
1545 (line-end-position 2))))))
1548 ;;; Fixed-Width Areas
1550 (ert-deftest test-org/toggle-fixed-width ()
1551 "Test `org-toggle-fixed-width' specifications."
1552 ;; No region: Toggle on fixed-width marker in paragraphs.
1553 (should
1554 (equal ": A"
1555 (org-test-with-temp-text "A"
1556 (org-toggle-fixed-width)
1557 (buffer-string))))
1558 ;; No region: Toggle off fixed-width markers in fixed-width areas.
1559 (should
1560 (equal "A"
1561 (org-test-with-temp-text ": A"
1562 (org-toggle-fixed-width)
1563 (buffer-string))))
1564 ;; No region: Toggle on marker in blank lines after elements or just
1565 ;; after a headline.
1566 (should
1567 (equal "* H\n: "
1568 (org-test-with-temp-text "* H\n"
1569 (forward-line)
1570 (org-toggle-fixed-width)
1571 (buffer-string))))
1572 (should
1573 (equal "#+BEGIN_EXAMPLE\nContents\n#+END_EXAMPLE\n: "
1574 (org-test-with-temp-text "#+BEGIN_EXAMPLE\nContents\n#+END_EXAMPLE\n"
1575 (goto-char (point-max))
1576 (org-toggle-fixed-width)
1577 (buffer-string))))
1578 ;; No region: Toggle on marker in front of one line elements (e.g.,
1579 ;; headlines, clocks)
1580 (should
1581 (equal ": * Headline"
1582 (org-test-with-temp-text "* Headline"
1583 (org-toggle-fixed-width)
1584 (buffer-string))))
1585 (should
1586 (equal ": #+KEYWORD: value"
1587 (org-test-with-temp-text "#+KEYWORD: value"
1588 (org-toggle-fixed-width)
1589 (buffer-string))))
1590 ;; No region: error in other situations.
1591 (should-error
1592 (org-test-with-temp-text "#+BEGIN_EXAMPLE\n: A\n#+END_EXAMPLE"
1593 (forward-line)
1594 (org-toggle-fixed-width)
1595 (buffer-string)))
1596 ;; No region: Indentation is preserved.
1597 (should
1598 (equal "- A\n : B"
1599 (org-test-with-temp-text "- A\n B"
1600 (forward-line)
1601 (org-toggle-fixed-width)
1602 (buffer-string))))
1603 ;; Region: If it contains only fixed-width elements and blank lines,
1604 ;; toggle off fixed-width markup.
1605 (should
1606 (equal "A\n\nB"
1607 (org-test-with-temp-text ": A\n\n: B"
1608 (transient-mark-mode 1)
1609 (push-mark (point) t t)
1610 (goto-char (point-max))
1611 (org-toggle-fixed-width)
1612 (buffer-string))))
1613 ;; Region: If it contains anything else, toggle on fixed-width but
1614 ;; not on fixed-width areas.
1615 (should
1616 (equal ": A\n: \n: B\n: \n: C"
1617 (org-test-with-temp-text "A\n\n: B\n\nC"
1618 (transient-mark-mode 1)
1619 (push-mark (point) t t)
1620 (goto-char (point-max))
1621 (org-toggle-fixed-width)
1622 (buffer-string))))
1623 ;; Region: Ignore blank lines at its end, unless it contains only
1624 ;; such lines.
1625 (should
1626 (equal ": A\n\n"
1627 (org-test-with-temp-text "A\n\n"
1628 (transient-mark-mode 1)
1629 (push-mark (point) t t)
1630 (goto-char (point-max))
1631 (org-toggle-fixed-width)
1632 (buffer-string))))
1633 (should
1634 (equal ": \n: \n"
1635 (org-test-with-temp-text "\n\n"
1636 (transient-mark-mode 1)
1637 (push-mark (point) t t)
1638 (goto-char (point-max))
1639 (org-toggle-fixed-width)
1640 (buffer-string)))))
1642 (ert-deftest test-org/kill-line ()
1643 "Test `org-kill-line' specifications."
1644 ;; At the beginning of a line, kill whole line.
1645 (should
1646 (equal ""
1647 (org-test-with-temp-text "abc"
1648 (org-kill-line)
1649 (buffer-string))))
1650 ;; In the middle of a line, kill line until its end.
1651 (should
1652 (equal "a"
1653 (org-test-with-temp-text "a<point>bc"
1654 (org-kill-line)
1655 (buffer-string))))
1656 ;; Do not kill newline character.
1657 (should
1658 (equal "\n123"
1659 (org-test-with-temp-text "abc\n123"
1660 (org-kill-line)
1661 (buffer-string))))
1662 (should
1663 (equal "a\n123"
1664 (org-test-with-temp-text "a<point>bc\n123"
1665 (org-kill-line)
1666 (buffer-string))))
1667 ;; When `org-special-ctrl-k' is non-nil and point is at a headline,
1668 ;; kill until tags.
1669 (should
1670 (equal "* A :tag:"
1671 (org-test-with-temp-text "* A<point>B :tag:"
1672 (let ((org-special-ctrl-k t)
1673 (org-tags-column 0))
1674 (org-kill-line))
1675 (buffer-string))))
1676 ;; If point is on tags, only kill part left until the end of line.
1677 (should
1678 (equal "* A :tag:"
1679 (org-test-with-temp-text "* A :tag:<point>tag2:"
1680 (let ((org-special-ctrl-k t)
1681 (org-tags-column 0))
1682 (org-kill-line))
1683 (buffer-string))))
1684 ;; However, if point is at the beginning of the line, kill whole
1685 ;; headline.
1686 (should
1687 (equal ""
1688 (org-test-with-temp-text "* AB :tag:"
1689 (let ((org-special-ctrl-k t)
1690 (org-tags-column 0))
1691 (org-kill-line))
1692 (buffer-string))))
1693 ;; When `org-ctrl-k-protect-subtree' is non-nil, and point is in
1694 ;; invisible text, ask before removing it. When set to `error',
1695 ;; throw an error.
1696 (should-error
1697 (org-test-with-temp-text "* H\n** <point>H2\nContents\n* H3"
1698 (org-overview)
1699 (let ((org-special-ctrl-k nil)
1700 (org-ctrl-k-protect-subtree t))
1701 (cl-letf (((symbol-function 'y-or-n-p) 'ignore))
1702 (org-kill-line)))))
1703 (should-error
1704 (org-test-with-temp-text "* H\n** <point>H2\nContents\n* H3"
1705 (org-overview)
1706 (let ((org-special-ctrl-k nil)
1707 (org-ctrl-k-protect-subtree 'error))
1708 (org-kill-line)))))
1712 ;;; Headline
1714 (ert-deftest test-org/get-heading ()
1715 "Test `org-get-heading' specifications."
1716 ;; Return current heading, even if point is not on it.
1717 (should
1718 (equal "H"
1719 (org-test-with-temp-text "* H"
1720 (org-get-heading))))
1721 (should
1722 (equal "H"
1723 (org-test-with-temp-text "* H\nText<point>"
1724 (org-get-heading))))
1725 ;; Without any optional argument, return TODO keyword, priority
1726 ;; cookie, COMMENT keyword and tags.
1727 (should
1728 (equal "TODO H"
1729 (org-test-with-temp-text "#+TODO: TODO | DONE\n* TODO H<point>"
1730 (org-get-heading))))
1731 (should
1732 (equal "[#A] H"
1733 (org-test-with-temp-text "* [#A] H"
1734 (org-get-heading))))
1735 (should
1736 (equal "COMMENT H"
1737 (org-test-with-temp-text "* COMMENT H"
1738 (org-get-heading))))
1739 (should
1740 (equal "H :tag:"
1741 (org-test-with-temp-text "* H :tag:"
1742 (org-get-heading))))
1743 ;; With NO-TAGS argument, ignore tags.
1744 (should
1745 (equal "TODO H"
1746 (org-test-with-temp-text "#+TODO: TODO | DONE\n* TODO H<point>"
1747 (org-get-heading t))))
1748 (should
1749 (equal "H"
1750 (org-test-with-temp-text "* H :tag:"
1751 (org-get-heading t))))
1752 ;; With NO-TODO, ignore TODO keyword.
1753 (should
1754 (equal "H"
1755 (org-test-with-temp-text "#+TODO: TODO | DONE\n* TODO H<point>"
1756 (org-get-heading nil t))))
1757 (should
1758 (equal "H :tag:"
1759 (org-test-with-temp-text "* H :tag:"
1760 (org-get-heading nil t))))
1761 ;; TODO keywords are case-sensitive.
1762 (should
1763 (equal "Todo H"
1764 (org-test-with-temp-text "#+TODO: TODO | DONE\n* Todo H<point>"
1765 (org-get-heading nil t))))
1766 ;; With NO-PRIORITY, ignore priority.
1767 (should
1768 (equal "H"
1769 (org-test-with-temp-text "* [#A] H"
1770 (org-get-heading nil nil t))))
1771 (should
1772 (equal "H"
1773 (org-test-with-temp-text "* H"
1774 (org-get-heading nil nil t))))
1775 (should
1776 (equal "TODO H"
1777 (org-test-with-temp-text "* TODO [#A] H"
1778 (org-get-heading nil nil t))))
1779 ;; With NO-COMMENT, ignore COMMENT keyword.
1780 (should
1781 (equal "H"
1782 (org-test-with-temp-text "* COMMENT H"
1783 (org-get-heading nil nil nil t))))
1784 (should
1785 (equal "H"
1786 (org-test-with-temp-text "* H"
1787 (org-get-heading nil nil nil t))))
1788 (should
1789 (equal "TODO [#A] H"
1790 (org-test-with-temp-text "* TODO [#A] COMMENT H"
1791 (org-get-heading nil nil nil t))))
1792 ;; On an empty headline, return value is consistent.
1793 (should (equal "" (org-test-with-temp-text "* " (org-get-heading))))
1794 (should (equal "" (org-test-with-temp-text "* " (org-get-heading t))))
1795 (should (equal "" (org-test-with-temp-text "* " (org-get-heading nil t))))
1796 (should (equal "" (org-test-with-temp-text "* " (org-get-heading nil nil t))))
1797 (should
1798 (equal "" (org-test-with-temp-text "* " (org-get-heading nil nil nil t)))))
1800 (ert-deftest test-org/in-commented-heading-p ()
1801 "Test `org-in-commented-heading-p' specifications."
1802 ;; Commented headline.
1803 (should
1804 (org-test-with-temp-text "* COMMENT Headline\nBody"
1805 (goto-char (point-max))
1806 (org-in-commented-heading-p)))
1807 ;; Commented ancestor.
1808 (should
1809 (org-test-with-temp-text "* COMMENT Headline\n** Level 2\nBody"
1810 (goto-char (point-max))
1811 (org-in-commented-heading-p)))
1812 ;; Comment keyword is case-sensitive.
1813 (should-not
1814 (org-test-with-temp-text "* Comment Headline\nBody"
1815 (goto-char (point-max))
1816 (org-in-commented-heading-p)))
1817 ;; Keyword is standalone.
1818 (should-not
1819 (org-test-with-temp-text "* COMMENTHeadline\nBody"
1820 (goto-char (point-max))
1821 (org-in-commented-heading-p)))
1822 ;; Optional argument.
1823 (should-not
1824 (org-test-with-temp-text "* COMMENT Headline\n** Level 2\nBody"
1825 (goto-char (point-max))
1826 (org-in-commented-heading-p t))))
1828 (ert-deftest test-org/entry-blocked-p ()
1829 ;; Check other dependencies.
1830 (should
1831 (org-test-with-temp-text "* TODO Blocked\n** DONE one\n** TODO two"
1832 (let ((org-enforce-todo-dependencies t)
1833 (org-blocker-hook
1834 '(org-block-todo-from-children-or-siblings-or-parent)))
1835 (org-entry-blocked-p))))
1836 (should-not
1837 (org-test-with-temp-text "* TODO Blocked\n** DONE one\n** DONE two"
1838 (let ((org-enforce-todo-dependencies t)
1839 (org-blocker-hook
1840 '(org-block-todo-from-children-or-siblings-or-parent)))
1841 (org-entry-blocked-p))))
1842 ;; Entry without a TODO keyword or with a DONE keyword cannot be
1843 ;; blocked.
1844 (should-not
1845 (org-test-with-temp-text "* Blocked\n** TODO one"
1846 (let ((org-enforce-todo-dependencies t)
1847 (org-blocker-hook
1848 '(org-block-todo-from-children-or-siblings-or-parent)))
1849 (org-entry-blocked-p))))
1850 (should-not
1851 (org-test-with-temp-text "* DONE Blocked\n** TODO one"
1852 (let ((org-enforce-todo-dependencies t)
1853 (org-blocker-hook
1854 '(org-block-todo-from-children-or-siblings-or-parent)))
1855 (org-entry-blocked-p))))
1856 ;; Follow :ORDERED: specifications.
1857 (should
1858 (org-test-with-temp-text
1859 "* H\n:PROPERTIES:\n:ORDERED: t\n:END:\n** TODO one\n** <point>TODO two"
1860 (let ((org-enforce-todo-dependencies t)
1861 (org-blocker-hook
1862 '(org-block-todo-from-children-or-siblings-or-parent)))
1863 (org-entry-blocked-p))))
1864 (should-not
1865 (org-test-with-temp-text
1866 "* H\n:PROPERTIES:\n:ORDERED: t\n:END:\n** <point>TODO one\n** DONE two"
1867 (let ((org-enforce-todo-dependencies t)
1868 (org-blocker-hook
1869 '(org-block-todo-from-children-or-siblings-or-parent)))
1870 (org-entry-blocked-p)))))
1872 (ert-deftest test-org/get-outline-path ()
1873 "Test `org-get-outline-path' specifications."
1874 ;; Top-level headlines have no outline path.
1875 (should-not
1876 (org-test-with-temp-text "* H"
1877 (org-get-outline-path)))
1878 ;; Otherwise, outline path is the path leading to the headline.
1879 (should
1880 (equal '("H")
1881 (org-test-with-temp-text "* H\n** S<point>"
1882 (org-get-outline-path))))
1883 ;; Find path even when point is not on a headline.
1884 (should
1885 (equal '("H")
1886 (org-test-with-temp-text "* H\n** S\nText<point>"
1887 (org-get-outline-path))))
1888 ;; TODO keywords, tags and statistics cookies are ignored.
1889 (should
1890 (equal '("H")
1891 (org-test-with-temp-text "* TODO H [0/1] :tag:\n** S<point>"
1892 (org-get-outline-path))))
1893 ;; Links are replaced with their description or their path.
1894 (should
1895 (equal '("Org")
1896 (org-test-with-temp-text
1897 "* [[https://orgmode.org][Org]]\n** S<point>"
1898 (org-get-outline-path))))
1899 (should
1900 (equal '("https://orgmode.org")
1901 (org-test-with-temp-text
1902 "* [[https://orgmode.org]]\n** S<point>"
1903 (org-get-outline-path))))
1904 ;; When WITH-SELF is non-nil, include current heading.
1905 (should
1906 (equal '("H")
1907 (org-test-with-temp-text "* H"
1908 (org-get-outline-path t))))
1909 (should
1910 (equal '("H" "S")
1911 (org-test-with-temp-text "* H\n** S\nText<point>"
1912 (org-get-outline-path t))))
1913 ;; Using cache is transparent to the user.
1914 (should
1915 (equal '("H")
1916 (org-test-with-temp-text "* H\n** S<point>"
1917 (setq org-outline-path-cache nil)
1918 (org-get-outline-path nil t))))
1919 ;; Do not corrupt cache when finding outline path in distant part of
1920 ;; the buffer.
1921 (should
1922 (equal '("H2")
1923 (org-test-with-temp-text "* H\n** S<point>\n* H2\n** S2"
1924 (setq org-outline-path-cache nil)
1925 (org-get-outline-path nil t)
1926 (search-forward "S2")
1927 (org-get-outline-path nil t))))
1928 ;; Do not choke on empty headlines.
1929 (should
1930 (org-test-with-temp-text "* H\n** <point>"
1931 (org-get-outline-path)))
1932 (should
1933 (org-test-with-temp-text "* \n** H<point>"
1934 (org-get-outline-path))))
1936 (ert-deftest test-org/format-outline-path ()
1937 "Test `org-format-outline-path' specifications."
1938 (should
1939 (string= (org-format-outline-path (list "one" "two" "three"))
1940 "one/two/three"))
1941 ;; Empty path.
1942 (should
1943 (string= (org-format-outline-path '())
1944 ""))
1945 (should
1946 (string= (org-format-outline-path '(nil))
1947 ""))
1948 ;; Empty path and prefix.
1949 (should
1950 (string= (org-format-outline-path '() nil ">>")
1951 ">>"))
1952 ;; Trailing whitespace in headings.
1953 (should
1954 (string= (org-format-outline-path (list "one\t" "tw o " "three "))
1955 "one/tw o/three"))
1956 ;; Non-default prefix and separators.
1957 (should
1958 (string= (org-format-outline-path (list "one" "two" "three") nil ">>" "|")
1959 ">>|one|two|three"))
1960 ;; Truncate.
1961 (should
1962 (string= (org-format-outline-path (list "one" "two" "three" "four") 10)
1963 "one/two/.."))
1964 ;; Give a very narrow width.
1965 (should
1966 (string= (org-format-outline-path (list "one" "two" "three" "four") 2)
1967 "on"))
1968 ;; Give a prefix that extends beyond the width.
1969 (should
1970 (string= (org-format-outline-path (list "one" "two" "three" "four") 10
1971 ">>>>>>>>>>")
1972 ">>>>>>>>..")))
1974 (ert-deftest test-org/map-entries ()
1975 "Test `org-map-entries' specifications."
1976 ;; Full match.
1977 (should
1978 (equal '(1 11)
1979 (org-test-with-temp-text "* Level 1\n** Level 2"
1980 (org-map-entries #'point))))
1981 ;; Level match.
1982 (should
1983 (equal '(1)
1984 (org-test-with-temp-text "* Level 1\n** Level 2"
1985 (let (org-odd-levels-only) (org-map-entries #'point "LEVEL=1")))))
1986 (should
1987 (equal '(11)
1988 (org-test-with-temp-text "* Level 1\n** Level 2"
1989 (let (org-odd-levels-only) (org-map-entries #'point "LEVEL>1")))))
1990 ;; Tag match.
1991 (should
1992 (equal '(11)
1993 (org-test-with-temp-text "* H1 :no:\n* H2 :yes:"
1994 (org-map-entries #'point "yes"))))
1995 (should
1996 (equal '(14)
1997 (org-test-with-temp-text "* H1 :yes:a:\n* H2 :yes:b:"
1998 (org-map-entries #'point "+yes-a"))))
1999 (should
2000 (equal '(11 23)
2001 (org-test-with-temp-text "* H1 :no:\n* H2 :yes1:\n* H3 :yes2:"
2002 (org-map-entries #'point "{yes?}"))))
2003 ;; Priority match.
2004 (should
2005 (equal '(1)
2006 (org-test-with-temp-text "* [#A] H1\n* [#B] H2"
2007 (org-map-entries #'point "PRIORITY=\"A\""))))
2008 ;; Date match.
2009 (should
2010 (equal '(36)
2011 (org-test-with-temp-text "
2012 * H1
2013 SCHEDULED: <2012-03-29 thu.>
2014 * H2
2015 SCHEDULED: <2014-03-04 tue.>"
2016 (org-map-entries #'point "SCHEDULED=\"<2014-03-04 tue.>\""))))
2017 (should
2018 (equal '(2)
2019 (org-test-with-temp-text "
2020 * H1
2021 SCHEDULED: <2012-03-29 thu.>
2022 * H2
2023 SCHEDULED: <2014-03-04 tue.>"
2024 (org-map-entries #'point "SCHEDULED<\"<2013-01-01>\""))))
2025 ;; Regular property match.
2026 (should
2027 (equal '(2)
2028 (org-test-with-temp-text "
2029 * H1
2030 :PROPERTIES:
2031 :TEST: 1
2032 :END:
2033 * H2
2034 :PROPERTIES:
2035 :TEST: 2
2036 :END:"
2037 (org-map-entries #'point "TEST=1"))))
2038 ;; Multiple criteria.
2039 (should
2040 (equal '(23)
2041 (org-test-with-temp-text "* H1 :no:\n** H2 :yes:\n* H3 :yes:"
2042 (let (org-odd-levels-only
2043 (org-use-tag-inheritance nil))
2044 (org-map-entries #'point "yes+LEVEL=1")))))
2045 ;; "or" criteria.
2046 (should
2047 (equal '(12 24)
2048 (org-test-with-temp-text "* H1 :yes:\n** H2 :yes:\n** H3 :no:"
2049 (let (org-odd-levels-only)
2050 (org-map-entries #'point "LEVEL=2|no")))))
2051 (should
2052 (equal '(1 12)
2053 (org-test-with-temp-text "* H1 :yes:\n* H2 :no:\n* H3 :maybe:"
2054 (let (org-odd-levels-only)
2055 (org-map-entries #'point "yes|no")))))
2056 ;; "and" criteria.
2057 (should
2058 (equal '(22)
2059 (org-test-with-temp-text "* H1 :yes:\n* H2 :no:\n* H3 :yes:no:"
2060 (let (org-odd-levels-only)
2061 (org-map-entries #'point "yes&no"))))))
2063 (ert-deftest test-org/edit-headline ()
2064 "Test `org-edit-headline' specifications."
2065 (should
2066 (equal "* B"
2067 (org-test-with-temp-text "* A"
2068 (org-edit-headline "B")
2069 (buffer-string))))
2070 ;; Handle empty headings.
2071 (should
2072 (equal "* "
2073 (org-test-with-temp-text "* A"
2074 (org-edit-headline "")
2075 (buffer-string))))
2076 (should
2077 (equal "* A"
2078 (org-test-with-temp-text "* "
2079 (org-edit-headline "A")
2080 (buffer-string))))
2081 ;; Handle TODO keywords and priority cookies.
2082 (should
2083 (equal "* TODO B"
2084 (org-test-with-temp-text "* TODO A"
2085 (org-edit-headline "B")
2086 (buffer-string))))
2087 (should
2088 (equal "* [#A] B"
2089 (org-test-with-temp-text "* [#A] A"
2090 (org-edit-headline "B")
2091 (buffer-string))))
2092 (should
2093 (equal "* TODO [#A] B"
2094 (org-test-with-temp-text "* TODO [#A] A"
2095 (org-edit-headline "B")
2096 (buffer-string))))
2097 ;; Handle tags.
2098 (equal "* B :tag:"
2099 (org-test-with-temp-text "* A :tag:"
2100 (let ((org-tags-column 4)) (org-edit-headline "B"))
2101 (buffer-string))))
2105 ;;; Keywords
2107 (ert-deftest test-org/set-regexps-and-options ()
2108 "Test `org-set-regexps-and-options' specifications."
2109 ;; TAGS keyword.
2110 (should
2111 (equal '(("A"))
2112 (let ((org-tag-alist '(("A")))
2113 (org-tag-persistent-alist nil))
2114 (org-test-with-temp-text ""
2115 (org-mode-restart)
2116 org-current-tag-alist))))
2117 (should
2118 (equal '(("B"))
2119 (let ((org-tag-alist '(("A")))
2120 (org-tag-persistent-alist nil))
2121 (org-test-with-temp-text "#+TAGS: B"
2122 (org-mode-restart)
2123 org-current-tag-alist))))
2124 (should
2125 (equal '(("C") ("B"))
2126 (let ((org-tag-alist '(("A")))
2127 (org-tag-persistent-alist '(("C"))))
2128 (org-test-with-temp-text "#+TAGS: B"
2129 (org-mode-restart)
2130 org-current-tag-alist))))
2131 (should
2132 (equal '(("B"))
2133 (let ((org-tag-alist '(("A")))
2134 (org-tag-persistent-alist '(("C"))))
2135 (org-test-with-temp-text "#+STARTUP: noptag\n#+TAGS: B"
2136 (org-mode-restart)
2137 org-current-tag-alist))))
2138 (should
2139 (equal '(("A" . ?a) ("B") ("C"))
2140 (let ((org-tag-persistant-alist nil))
2141 (org-test-with-temp-text "#+TAGS: A(a) B C"
2142 (org-mode-restart)
2143 org-current-tag-alist))))
2144 (should
2145 (equal '(("A") (:newline) ("B"))
2146 (let ((org-tag-persistent-alist nil))
2147 (org-test-with-temp-text "#+TAGS: A\n#+TAGS: B"
2148 (org-mode-restart)
2149 org-current-tag-alist))))
2150 (should
2151 (equal '((:startgroup) ("A") ("B") (:endgroup) ("C"))
2152 (let ((org-tag-persistent-alist nil))
2153 (org-test-with-temp-text "#+TAGS: { A B } C"
2154 (org-mode-restart)
2155 org-current-tag-alist))))
2156 (should
2157 (equal '((:startgroup) ("A") (:grouptags) ("B") ("C") (:endgroup))
2158 (let ((org-tag-persistent-alist nil))
2159 (org-test-with-temp-text "#+TAGS: { A : B C }"
2160 (org-mode-restart)
2161 org-current-tag-alist))))
2162 (should
2163 (equal '(("A" "B" "C"))
2164 (let ((org-tag-persistent-alist nil))
2165 (org-test-with-temp-text "#+TAGS: { A : B C }"
2166 (org-mode-restart)
2167 org-tag-groups-alist))))
2168 (should
2169 (equal '((:startgrouptag) ("A") (:grouptags) ("B") ("C") (:endgrouptag))
2170 (let ((org-tag-persistent-alist nil))
2171 (org-test-with-temp-text "#+TAGS: [ A : B C ]"
2172 (org-mode-restart)
2173 org-current-tag-alist))))
2174 (should
2175 (equal '(("A" "B" "C"))
2176 (let ((org-tag-persistent-alist nil))
2177 (org-test-with-temp-text "#+TAGS: [ A : B C ]"
2178 (org-mode-restart)
2179 org-tag-groups-alist))))
2180 ;; FILETAGS keyword.
2181 (should
2182 (equal '("A" "B" "C")
2183 (org-test-with-temp-text "#+FILETAGS: :A:B:C:"
2184 (org-mode-restart)
2185 org-file-tags)))
2186 ;; PROPERTY keyword. Property names are case-insensitive.
2187 (should
2188 (equal "foo=1"
2189 (org-test-with-temp-text "#+PROPERTY: var foo=1"
2190 (org-mode-restart)
2191 (cdr (assoc "var" org-file-properties)))))
2192 (should
2193 (equal
2194 "foo=1 bar=2"
2195 (org-test-with-temp-text "#+PROPERTY: var foo=1\n#+PROPERTY: var+ bar=2"
2196 (org-mode-restart)
2197 (cdr (assoc "var" org-file-properties)))))
2198 (should
2199 (equal
2200 "foo=1 bar=2"
2201 (org-test-with-temp-text "#+PROPERTY: var foo=1\n#+PROPERTY: VAR+ bar=2"
2202 (org-mode-restart)
2203 (cdr (assoc "var" org-file-properties)))))
2204 ;; ARCHIVE keyword.
2205 (should
2206 (equal "%s_done::"
2207 (org-test-with-temp-text "#+ARCHIVE: %s_done::"
2208 (org-mode-restart)
2209 org-archive-location)))
2210 ;; CATEGORY keyword.
2211 (should
2212 (eq 'test
2213 (org-test-with-temp-text "#+CATEGORY: test"
2214 (org-mode-restart)
2215 org-category)))
2216 (should
2217 (equal "test"
2218 (org-test-with-temp-text "#+CATEGORY: test"
2219 (org-mode-restart)
2220 (cdr (assoc "CATEGORY" org-file-properties)))))
2221 ;; COLUMNS keyword.
2222 (should
2223 (equal "%25ITEM %TAGS %PRIORITY %TODO"
2224 (org-test-with-temp-text "#+COLUMNS: %25ITEM %TAGS %PRIORITY %TODO"
2225 (org-mode-restart)
2226 org-columns-default-format)))
2227 ;; CONSTANTS keyword. Constants names are case sensitive.
2228 (should
2229 (equal '("299792458." "3.14")
2230 (org-test-with-temp-text "#+CONSTANTS: c=299792458. pi=3.14"
2231 (org-mode-restart)
2232 (mapcar
2233 (lambda (n) (cdr (assoc n org-table-formula-constants-local)))
2234 '("c" "pi")))))
2235 (should
2236 (equal "3.14"
2237 (org-test-with-temp-text "#+CONSTANTS: pi=22/7 pi=3.14"
2238 (org-mode-restart)
2239 (cdr (assoc "pi" org-table-formula-constants-local)))))
2240 (should
2241 (equal "22/7"
2242 (org-test-with-temp-text "#+CONSTANTS: PI=22/7 pi=3.14"
2243 (org-mode-restart)
2244 (cdr (assoc "PI" org-table-formula-constants-local)))))
2245 ;; LINK keyword.
2246 (should
2247 (equal
2248 '("url1" "url2")
2249 (org-test-with-temp-text "#+LINK: a url1\n#+LINK: b url2"
2250 (org-mode-restart)
2251 (mapcar (lambda (abbrev) (cdr (assoc abbrev org-link-abbrev-alist-local)))
2252 '("a" "b")))))
2253 ;; PRIORITIES keyword. Incomplete priorities sets are ignored.
2254 (should
2255 (equal
2256 '(?X ?Z ?Y)
2257 (org-test-with-temp-text "#+PRIORITIES: X Z Y"
2258 (org-mode-restart)
2259 (list org-highest-priority org-lowest-priority org-default-priority))))
2260 (should
2261 (equal
2262 '(?A ?C ?B)
2263 (org-test-with-temp-text "#+PRIORITIES: X Z"
2264 (org-mode-restart)
2265 (list org-highest-priority org-lowest-priority org-default-priority))))
2266 ;; STARTUP keyword.
2267 (should
2268 (equal '(t t)
2269 (org-test-with-temp-text "#+STARTUP: fold odd"
2270 (org-mode-restart)
2271 (list org-startup-folded org-odd-levels-only))))
2272 ;; TODO keywords.
2273 (should
2274 (equal '(("A" "B") ("C"))
2275 (org-test-with-temp-text "#+TODO: A B | C"
2276 (org-mode-restart)
2277 (list org-not-done-keywords org-done-keywords))))
2278 (should
2279 (equal '(("A" "C") ("B" "D"))
2280 (org-test-with-temp-text "#+TODO: A | B\n#+TODO: C | D"
2281 (org-mode-restart)
2282 (list org-not-done-keywords org-done-keywords))))
2283 (should
2284 (equal '(("A" "B") ("C"))
2285 (org-test-with-temp-text "#+TYP_TODO: A B | C"
2286 (org-mode-restart)
2287 (list org-not-done-keywords org-done-keywords))))
2288 (should
2289 (equal '((:startgroup) ("A" . ?a) (:endgroup))
2290 (org-test-with-temp-text "#+TODO: A(a)"
2291 (org-mode-restart)
2292 org-todo-key-alist)))
2293 (should
2294 (equal '(("D" note nil) ("C" time nil) ("B" note time))
2295 (org-test-with-temp-text "#+TODO: A(a) B(b@/!) | C(c!) D(d@)"
2296 (org-mode-restart)
2297 org-todo-log-states)))
2298 ;; Enter SETUPFILE keyword.
2299 (should
2300 (equal "1"
2301 (org-test-with-temp-text
2302 (format "#+SETUPFILE: \"%s/examples/setupfile.org\"" org-test-dir)
2303 (org-mode-restart)
2304 (cdr (assoc "a" org-file-properties))))))
2308 ;;; Links
2310 ;;;; Coderefs
2312 (ert-deftest test-org/coderef ()
2313 "Test coderef links specifications."
2314 (should
2315 (org-test-with-temp-text "
2316 #+BEGIN_SRC emacs-lisp
2317 \(+ 1 1) (ref:sc)
2318 #+END_SRC
2319 \[[(sc)<point>]]"
2320 (org-open-at-point)
2321 (looking-at "(ref:sc)")))
2322 ;; Find coderef even with alternate label format.
2323 (should
2324 (org-test-with-temp-text "
2325 #+BEGIN_SRC emacs-lisp -l \"{ref:%s}\"
2326 \(+ 1 1) {ref:sc}
2327 #+END_SRC
2328 \[[(sc)<point>]]"
2329 (org-open-at-point)
2330 (looking-at "{ref:sc}"))))
2332 ;;;; Custom ID
2334 (ert-deftest test-org/custom-id ()
2335 "Test custom ID links specifications."
2336 (should
2337 (org-test-with-temp-text
2338 "* H1\n:PROPERTIES:\n:CUSTOM_ID: custom\n:END:\n* H2\n[[#custom<point>]]"
2339 (org-open-at-point)
2340 (looking-at-p "\\* H1")))
2341 ;; Handle escape characters.
2342 (should
2343 (org-test-with-temp-text
2344 "* H1\n:PROPERTIES:\n:CUSTOM_ID: [%]\n:END:\n* H2\n[[#%5B%25%5D<point>]]"
2345 (org-open-at-point)
2346 (looking-at-p "\\* H1")))
2347 ;; Throw an error on false positives.
2348 (should-error
2349 (org-test-with-temp-text
2350 "* H1\n:DRAWER:\n:CUSTOM_ID: custom\n:END:\n* H2\n[[#custom<point>]]"
2351 (org-open-at-point)
2352 (looking-at-p "\\* H1"))))
2354 ;;;; Fuzzy Links
2356 ;; Fuzzy links [[text]] encompass links to a target (<<text>>), to
2357 ;; a named element (#+name: text) and to headlines (* Text).
2359 (ert-deftest test-org/fuzzy-links ()
2360 "Test fuzzy links specifications."
2361 ;; Fuzzy link goes in priority to a matching target.
2362 (should
2363 (org-test-with-temp-text
2364 "#+NAME: Test\n|a|b|\n<<Test>>\n* Test\n<point>[[Test]]"
2365 (let ((org-link-search-must-match-exact-headline nil)) (org-open-at-point))
2366 (looking-at "<<Test>>")))
2367 ;; Then fuzzy link points to an element with a given name.
2368 (should
2369 (org-test-with-temp-text "Test\n#+NAME: Test\n|a|b|\n* Test\n<point>[[Test]]"
2370 (let ((org-link-search-must-match-exact-headline nil)) (org-open-at-point))
2371 (looking-at "#\\+NAME: Test")))
2372 ;; A target still lead to a matching headline otherwise.
2373 (should
2374 (org-test-with-temp-text "* Head1\n* Head2\n*Head3\n<point>[[Head2]]"
2375 (let ((org-link-search-must-match-exact-headline nil)) (org-open-at-point))
2376 (looking-at "\\* Head2")))
2377 ;; With a leading star in link, enforce heading match.
2378 (should
2379 (org-test-with-temp-text "* Test\n<<Test>>\n<point>[[*Test]]"
2380 (let ((org-link-search-must-match-exact-headline nil)) (org-open-at-point))
2381 (looking-at "\\* Test")))
2382 ;; With a leading star in link, enforce exact heading match, even
2383 ;; with `org-link-search-must-match-exact-headline' set to nil.
2384 (should-error
2385 (org-test-with-temp-text "* Test 1\nFoo Bar\n<point>[[*Test]]"
2386 (let ((org-link-search-must-match-exact-headline nil))
2387 (org-open-at-point))))
2388 ;; Handle non-nil `org-link-search-must-match-exact-headline'.
2389 (should
2390 (org-test-with-temp-text "* Test\nFoo Bar\n<point>[[Test]]"
2391 (let ((org-link-search-must-match-exact-headline t)) (org-open-at-point))
2392 (looking-at "\\* Test")))
2393 (should
2394 (org-test-with-temp-text "* Test\nFoo Bar\n<point>[[*Test]]"
2395 (let ((org-link-search-must-match-exact-headline t)) (org-open-at-point))
2396 (looking-at "\\* Test")))
2397 ;; Heading match should not care about spaces, cookies, TODO
2398 ;; keywords, priorities, and tags. However, TODO keywords are
2399 ;; case-sensitive.
2400 (should
2401 (let ((first-line
2402 "** TODO [#A] [/] Test [1/2] [33%] 1 \t 2 [%] :work:urgent: "))
2403 (org-test-with-temp-text
2404 (concat first-line "\nFoo Bar\n<point>[[*Test 1 2]]")
2405 (let ((org-link-search-must-match-exact-headline nil)
2406 (org-todo-regexp "TODO"))
2407 (org-open-at-point))
2408 (looking-at (regexp-quote first-line)))))
2409 (should-error
2410 (org-test-with-temp-text "** todo Test 1 2\nFoo Bar\n<point>[[*Test 1 2]]"
2411 (let ((org-link-search-must-match-exact-headline nil)
2412 (org-todo-regexp "TODO"))
2413 (org-open-at-point))))
2414 ;; Heading match should still be exact.
2415 (should-error
2416 (org-test-with-temp-text "
2417 ** TODO [#A] [/] Test [1/2] [33%] 1 \t 2 [%] :work:urgent:
2418 Foo Bar
2419 <point>[[*Test 1]]"
2420 (let ((org-link-search-must-match-exact-headline nil)
2421 (org-todo-regexp "TODO"))
2422 (org-open-at-point))))
2423 (should
2424 (org-test-with-temp-text "* Test 1 2 3\n** Test 1 2\n<point>[[*Test 1 2]]"
2425 (let ((org-link-search-must-match-exact-headline nil)
2426 (org-todo-regexp "TODO"))
2427 (org-open-at-point))
2428 (looking-at-p (regexp-quote "** Test 1 2"))))
2429 ;; Heading match ignores COMMENT keyword.
2430 (should
2431 (org-test-with-temp-text "[[*Test]]\n* COMMENT Test"
2432 (org-open-at-point)
2433 (looking-at "\\* COMMENT Test")))
2434 (should
2435 (org-test-with-temp-text "[[*Test]]\n* TODO COMMENT Test"
2436 (org-open-at-point)
2437 (looking-at "\\* TODO COMMENT Test")))
2438 ;; Correctly un-hexify fuzzy links.
2439 (should
2440 (org-test-with-temp-text "* With space\n[[*With%20space][With space<point>]]"
2441 (org-open-at-point)
2442 (bobp)))
2443 (should
2444 (org-test-with-temp-text "* [1]\n[[*%5B1%5D<point>]]"
2445 (org-open-at-point)
2446 (bobp)))
2447 ;; Match search strings containing newline characters, including
2448 ;; blank lines.
2449 (should
2450 (org-test-with-temp-text-in-file "Paragraph\n\nline1\nline2\n\n"
2451 (let ((file (buffer-file-name)))
2452 (goto-char (point-max))
2453 (insert (format "[[file:%s::line1 line2]]" file))
2454 (beginning-of-line)
2455 (let ((org-link-search-must-match-exact-headline nil))
2456 (org-open-at-point 0))
2457 (looking-at-p "line1"))))
2458 (should
2459 (org-test-with-temp-text-in-file "Paragraph\n\nline1\n\nline2\n\n"
2460 (let ((file (buffer-file-name)))
2461 (goto-char (point-max))
2462 (insert (format "[[file:%s::line1 line2]]" file))
2463 (beginning-of-line)
2464 (let ((org-link-search-must-match-exact-headline nil))
2465 (org-open-at-point 0))
2466 (looking-at-p "line1")))))
2468 ;;;; Link Escaping
2470 (ert-deftest test-org/org-link-escape-ascii-character ()
2471 "Escape an ascii character."
2472 (should
2473 (string=
2474 "%5B"
2475 (org-link-escape "["))))
2477 (ert-deftest test-org/org-link-escape-ascii-ctrl-character ()
2478 "Escape an ascii control character."
2479 (should
2480 (string=
2481 "%09"
2482 (org-link-escape "\t"))))
2484 (ert-deftest test-org/org-link-escape-multibyte-character ()
2485 "Escape an unicode multibyte character."
2486 (should
2487 (string=
2488 "%E2%82%AC"
2489 (org-link-escape "€"))))
2491 (ert-deftest test-org/org-link-escape-custom-table ()
2492 "Escape string with custom character table."
2493 (should
2494 (string=
2495 "Foo%3A%42ar%0A"
2496 (org-link-escape "Foo:Bar\n" '(?\: ?\B)))))
2498 (ert-deftest test-org/org-link-escape-custom-table-merge ()
2499 "Escape string with custom table merged with default table."
2500 (should
2501 (string=
2502 "%5BF%6F%6F%3A%42ar%0A%5D"
2503 (org-link-escape "[Foo:Bar\n]" '(?\: ?\B ?\o) t))))
2505 (ert-deftest test-org/org-link-unescape-ascii-character ()
2506 "Unescape an ascii character."
2507 (should
2508 (string=
2510 (org-link-unescape "%5B"))))
2512 (ert-deftest test-org/org-link-unescape-ascii-ctrl-character ()
2513 "Unescpae an ascii control character."
2514 (should
2515 (string=
2516 "\n"
2517 (org-link-unescape "%0A"))))
2519 (ert-deftest test-org/org-link-unescape-multibyte-character ()
2520 "Unescape unicode multibyte character."
2521 (should
2522 (string=
2523 "€"
2524 (org-link-unescape "%E2%82%AC"))))
2526 (ert-deftest test-org/org-link-unescape-ascii-extended-char ()
2527 "Unescape old style percent escaped character."
2528 (should
2529 (string=
2530 "àâçèéêîôùû"
2531 (decode-coding-string
2532 (org-link-unescape "%E0%E2%E7%E8%E9%EA%EE%F4%F9%FB") 'latin-1))))
2534 (ert-deftest test-org/org-link-escape-url-with-escaped-char ()
2535 "Escape and unescape a URL that includes an escaped char.
2536 http://article.gmane.org/gmane.emacs.orgmode/21459/"
2537 (should
2538 (string=
2539 "http://some.host.com/form?&id=blah%2Bblah25"
2540 (org-link-unescape
2541 (org-link-escape "http://some.host.com/form?&id=blah%2Bblah25")))))
2543 ;;;; Open at point
2545 (ert-deftest test-org/open-at-point/keyword ()
2546 "Does `org-open-at-point' open link in a keyword line?"
2547 (should
2548 (org-test-with-temp-text
2549 "<<top>>\n#+KEYWORD: <point>[[top]]"
2550 (org-open-at-point) t))
2551 (should
2552 (org-test-with-temp-text
2553 "* H\n<<top>>\n#+KEYWORD: <point>[[top]]"
2554 (org-open-at-point) t)))
2556 (ert-deftest test-org/open-at-point/property ()
2557 "Does `org-open-at-point' open link in property drawer?"
2558 (should
2559 (org-test-with-temp-text
2560 "* Headline
2561 :PROPERTIES:
2562 :URL: <point>[[*Headline]]
2563 :END:"
2564 (org-open-at-point) t)))
2566 (ert-deftest test-org/open-at-point/comment ()
2567 "Does `org-open-at-point' open link in a commented line?"
2568 (should
2569 (org-test-with-temp-text
2570 "<<top>>\n# <point>[[top]]"
2571 (org-open-at-point) t))
2572 (should
2573 (org-test-with-temp-text
2574 "* H\n<<top>>\n# <point>[[top]]"
2575 (org-open-at-point) t)))
2577 (ert-deftest test-org/open-at-point/inline-image ()
2578 "Test `org-open-at-point' on nested links."
2579 (should
2580 (org-test-with-temp-text "<<top>>\n[[top][file:<point>unicorn.jpg]]"
2581 (org-open-at-point)
2582 (bobp))))
2584 (ert-deftest test-org/open-at-point/radio-target ()
2585 "Test `org-open-at-point' on radio targets."
2586 (should
2587 (org-test-with-temp-text "<<<target>>> <point>target"
2588 (org-update-radio-target-regexp)
2589 (org-open-at-point)
2590 (eq (org-element-type (org-element-context)) 'radio-target))))
2592 (ert-deftest test-org/open-at-point/tag ()
2593 "Test `org-open-at-point' on tags."
2594 (should
2595 (org-test-with-temp-text "* H :<point>tag:"
2596 (catch :result
2597 (cl-letf (((symbol-function 'org-tags-view)
2598 (lambda (&rest args) (throw :result t))))
2599 (org-open-at-point)
2600 nil))))
2601 (should-not
2602 (org-test-with-temp-text-in-file "* H<point> :tag:"
2603 (catch :result
2604 (cl-letf (((symbol-function 'org-tags-view)
2605 (lambda (&rest args) (throw :result t))))
2606 (org-open-at-point)
2607 nil)))))
2609 ;;;; Stored links
2611 (ert-deftest test-org/store-link ()
2612 "Test `org-store-link' specifications."
2613 ;; On a headline, link to that headline. Use heading as the
2614 ;; description of the link.
2615 (should
2616 (let (org-store-link-props org-stored-links)
2617 (org-test-with-temp-text-in-file "* H1"
2618 (let ((file (buffer-file-name)))
2619 (equal (format "[[file:%s::*H1][H1]]" file)
2620 (org-store-link nil))))))
2621 ;; On a headline, remove any link from description.
2622 (should
2623 (let (org-store-link-props org-stored-links)
2624 (org-test-with-temp-text-in-file "* [[#l][d]]"
2625 (let ((file (buffer-file-name)))
2626 (equal (format "[[file:%s::*%s][d]]"
2627 file
2628 (org-link-escape "[[#l][d]]"))
2629 (org-store-link nil))))))
2630 (should
2631 (let (org-store-link-props org-stored-links)
2632 (org-test-with-temp-text-in-file "* [[l]]"
2633 (let ((file (buffer-file-name)))
2634 (equal (format "[[file:%s::*%s][l]]" file (org-link-escape "[[l]]"))
2635 (org-store-link nil))))))
2636 (should
2637 (let (org-store-link-props org-stored-links)
2638 (org-test-with-temp-text-in-file "* [[l1][d1]] [[l2][d2]]"
2639 (let ((file (buffer-file-name)))
2640 (equal (format "[[file:%s::*%s][d1 d2]]"
2641 file
2642 (org-link-escape "[[l1][d1]] [[l2][d2]]"))
2643 (org-store-link nil))))))
2644 ;; On a named element, link to that element.
2645 (should
2646 (let (org-store-link-props org-stored-links)
2647 (org-test-with-temp-text-in-file "#+NAME: foo\nParagraph"
2648 (let ((file (buffer-file-name)))
2649 (equal (format "[[file:%s::foo][foo]]" file)
2650 (org-store-link nil))))))
2651 ;; Store link to Org buffer, with context.
2652 (should
2653 (let ((org-stored-links nil)
2654 (org-id-link-to-org-use-id nil)
2655 (org-context-in-file-links t))
2656 (org-test-with-temp-text-in-file "* h1"
2657 (let ((file (buffer-file-name)))
2658 (equal (format "[[file:%s::*h1][h1]]" file)
2659 (org-store-link nil))))))
2660 ;; Store link to Org buffer, without context.
2661 (should
2662 (let ((org-stored-links nil)
2663 (org-id-link-to-org-use-id nil)
2664 (org-context-in-file-links nil))
2665 (org-test-with-temp-text-in-file "* h1"
2666 (let ((file (buffer-file-name)))
2667 (equal (format "[[file:%s][file:%s]]" file file)
2668 (org-store-link nil))))))
2669 ;; C-u prefix reverses `org-context-in-file-links' in Org buffer.
2670 (should
2671 (let ((org-stored-links nil)
2672 (org-id-link-to-org-use-id nil)
2673 (org-context-in-file-links nil))
2674 (org-test-with-temp-text-in-file "* h1"
2675 (let ((file (buffer-file-name)))
2676 (equal (format "[[file:%s::*h1][h1]]" file)
2677 (org-store-link '(4)))))))
2678 ;; A C-u C-u does *not* reverse `org-context-in-file-links' in Org
2679 ;; buffer.
2680 (should
2681 (let ((org-stored-links nil)
2682 (org-id-link-to-org-use-id nil)
2683 (org-context-in-file-links nil))
2684 (org-test-with-temp-text-in-file "* h1"
2685 (let ((file (buffer-file-name)))
2686 (equal (format "[[file:%s][file:%s]]" file file)
2687 (org-store-link '(16)))))))
2688 ;; Store file link to non-Org buffer, with context.
2689 (should
2690 (let ((org-stored-links nil)
2691 (org-context-in-file-links t))
2692 (org-test-with-temp-text-in-file "one\n<point>two"
2693 (fundamental-mode)
2694 (let ((file (buffer-file-name)))
2695 (equal (format "[[file:%s::one]]" file)
2696 (org-store-link nil))))))
2697 ;; Store file link to non-Org buffer, without context.
2698 (should
2699 (let ((org-stored-links nil)
2700 (org-context-in-file-links nil))
2701 (org-test-with-temp-text-in-file "one\n<point>two"
2702 (fundamental-mode)
2703 (let ((file (buffer-file-name)))
2704 (equal (format "[[file:%s][file:%s]]" file file)
2705 (org-store-link nil))))))
2706 ;; C-u prefix reverses `org-context-in-file-links' in non-Org
2707 ;; buffer.
2708 (should
2709 (let ((org-stored-links nil)
2710 (org-context-in-file-links nil))
2711 (org-test-with-temp-text-in-file "one\n<point>two"
2712 (fundamental-mode)
2713 (let ((file (buffer-file-name)))
2714 (equal (format "[[file:%s::one]]" file)
2715 (org-store-link '(4)))))))
2716 ;; A C-u C-u does *not* reverse `org-context-in-file-links' in
2717 ;; non-Org buffer.
2718 (should
2719 (let ((org-stored-links nil)
2720 (org-context-in-file-links nil))
2721 (org-test-with-temp-text-in-file "one\n<point>two"
2722 (fundamental-mode)
2723 (let ((file (buffer-file-name)))
2724 (equal (format "[[file:%s][file:%s]]" file file)
2725 (org-store-link '(16))))))))
2728 ;;; Node Properties
2730 (ert-deftest test-org/accumulated-properties-in-drawers ()
2731 "Ensure properties accumulate in subtree drawers."
2732 (org-test-at-id "75282ba2-f77a-4309-a970-e87c149fe125"
2733 (org-babel-next-src-block)
2734 (should (equal '(2 1) (org-babel-execute-src-block)))))
2736 (ert-deftest test-org/custom-properties ()
2737 "Test custom properties specifications."
2738 ;; Standard test.
2739 (should
2740 (let ((org-custom-properties '("FOO")))
2741 (org-test-with-temp-text "* H\n:PROPERTIES:\n<point>:FOO: val\n:END:\n"
2742 (org-toggle-custom-properties-visibility)
2743 (org-invisible-p2))))
2744 ;; Properties are case-insensitive.
2745 (should
2746 (let ((org-custom-properties '("FOO")))
2747 (org-test-with-temp-text "* H\n:PROPERTIES:\n<point>:foo: val\n:END:\n"
2748 (org-toggle-custom-properties-visibility)
2749 (org-invisible-p2))))
2750 (should
2751 (let ((org-custom-properties '("foo")))
2752 (org-test-with-temp-text "* H\n:PROPERTIES:\n<point>:FOO: val\n:END:\n"
2753 (org-toggle-custom-properties-visibility)
2754 (org-invisible-p2))))
2755 ;; Multiple custom properties in the same drawer.
2756 (should
2757 (let ((org-custom-properties '("FOO" "BAR")))
2758 (org-test-with-temp-text
2759 "* H\n:PROPERTIES:\n<point>:FOO: val\n:P: 1\n:BAR: baz\n:END:\n"
2760 (org-toggle-custom-properties-visibility)
2761 (and (org-invisible-p2)
2762 (not (progn (forward-line) (org-invisible-p2)))
2763 (progn (forward-line) (org-invisible-p2))))))
2764 ;; Hide custom properties with an empty value.
2765 (should
2766 (let ((org-custom-properties '("FOO")))
2767 (org-test-with-temp-text "* H\n:PROPERTIES:\n<point>:FOO:\n:END:\n"
2768 (org-toggle-custom-properties-visibility)
2769 (org-invisible-p2))))
2770 ;; Do not hide fake properties.
2771 (should-not
2772 (let ((org-custom-properties '("FOO")))
2773 (org-test-with-temp-text ":FOO: val\n"
2774 (org-toggle-custom-properties-visibility)
2775 (org-invisible-p2))))
2776 (should-not
2777 (let ((org-custom-properties '("A")))
2778 (org-test-with-temp-text
2779 "* H\n:PROPERTIES:\n:A: 1\n:END:\n\n:PROPERTIES:\n<point>:A: 2\n:END:"
2780 (org-toggle-custom-properties-visibility)
2781 (org-invisible-p2)))))
2785 ;;; Mark Region
2787 (ert-deftest test-org/mark-subtree ()
2788 "Test `org-mark-subtree' specifications."
2789 ;; Error when point is before first headline.
2790 (should-error
2791 (org-test-with-temp-text "Paragraph\n* Headline\nBody"
2792 (progn (transient-mark-mode 1)
2793 (org-mark-subtree))))
2794 ;; Without argument, mark current subtree.
2795 (should
2796 (equal
2797 '(12 32)
2798 (org-test-with-temp-text "* Headline\n** Sub-headline\nBody"
2799 (progn (transient-mark-mode 1)
2800 (forward-line 2)
2801 (org-mark-subtree)
2802 (list (region-beginning) (region-end))))))
2803 ;; With an argument, move ARG up.
2804 (should
2805 (equal
2806 '(1 32)
2807 (org-test-with-temp-text "* Headline\n** Sub-headline\nBody"
2808 (progn (transient-mark-mode 1)
2809 (forward-line 2)
2810 (org-mark-subtree 1)
2811 (list (region-beginning) (region-end))))))
2812 ;; Do not get fooled by inlinetasks.
2813 (when (featurep 'org-inlinetask)
2814 (should
2815 (= 1
2816 (org-test-with-temp-text "* Headline\n*************** Task\nContents"
2817 (progn (transient-mark-mode 1)
2818 (forward-line 1)
2819 (let ((org-inlinetask-min-level 15)) (org-mark-subtree))
2820 (region-beginning)))))))
2824 ;;; Miscellaneous
2826 (ert-deftest test-org/sort-entries ()
2827 "Test `org-sort-entries'."
2828 ;; Sort alphabetically.
2829 (should
2830 (equal "\n* abc\n* def\n* xyz\n"
2831 (org-test-with-temp-text "\n* def\n* xyz\n* abc\n"
2832 (org-sort-entries nil ?a)
2833 (buffer-string))))
2834 (should
2835 (equal "\n* xyz\n* def\n* abc\n"
2836 (org-test-with-temp-text "\n* def\n* xyz\n* abc\n"
2837 (org-sort-entries nil ?A)
2838 (buffer-string))))
2839 (should
2840 (equal "\n* \n* klm\n* xyz\n"
2841 (org-test-with-temp-text "\n* xyz\n* \n* klm\n"
2842 (org-sort-entries nil ?a)
2843 (buffer-string))))
2844 ;; Sort numerically.
2845 (should
2846 (equal "\n* 1\n* 2\n* 10\n"
2847 (org-test-with-temp-text "\n* 10\n* 1\n* 2\n"
2848 (org-sort-entries nil ?n)
2849 (buffer-string))))
2850 (should
2851 (equal "\n* 10\n* 2\n* 1\n"
2852 (org-test-with-temp-text "\n* 10\n* 1\n* 2\n"
2853 (org-sort-entries nil ?N)
2854 (buffer-string))))
2855 (should
2856 (equal "\n* \n* 1\n* 2\n"
2857 (org-test-with-temp-text "\n* 1\n* \n* 2\n"
2858 (org-sort-entries nil ?n)
2859 (buffer-string))))
2860 ;; Sort by custom function.
2861 (should
2862 (equal "\n* b\n* aa\n* ccc\n"
2863 (org-test-with-temp-text "\n* ccc\n* b\n* aa\n"
2864 (org-sort-entries nil ?f
2865 (lambda ()
2866 (length (buffer-substring (point-at-bol)
2867 (point-at-eol))))
2868 #'<)
2869 (buffer-string))))
2870 (should
2871 (equal "\n* ccc\n* aa\n* b\n"
2872 (org-test-with-temp-text "\n* ccc\n* b\n* aa\n"
2873 (org-sort-entries nil ?F
2874 (lambda ()
2875 (length (buffer-substring (point-at-bol)
2876 (point-at-eol))))
2877 #'<)
2878 (buffer-string))))
2879 ;; Sort by TODO keyword.
2880 (should
2881 (equal "\n* TODO h1\n* TODO h3\n* DONE h2\n"
2882 (org-test-with-temp-text
2883 "\n* TODO h1\n* DONE h2\n* TODO h3\n"
2884 (org-sort-entries nil ?o)
2885 (buffer-string))))
2886 (should
2887 (equal "\n* DONE h2\n* TODO h1\n* TODO h3\n"
2888 (org-test-with-temp-text
2889 "\n* TODO h1\n* DONE h2\n* TODO h3\n"
2890 (org-sort-entries nil ?O)
2891 (buffer-string))))
2892 ;; Sort by priority.
2893 (should
2894 (equal "\n* [#A] h2\n* [#B] h3\n* [#C] h1\n"
2895 (org-test-with-temp-text
2896 "\n* [#C] h1\n* [#A] h2\n* [#B] h3\n"
2897 (org-sort-entries nil ?p)
2898 (buffer-string))))
2899 (should
2900 (equal "\n* [#C] h1\n* [#B] h3\n* [#A] h2\n"
2901 (org-test-with-temp-text
2902 "\n* [#C] h1\n* [#A] h2\n* [#B] h3\n"
2903 (org-sort-entries nil ?P)
2904 (buffer-string))))
2905 ;; Sort by creation time.
2906 (should
2907 (equal "
2908 * h3
2909 [2017-05-08 Mon]
2910 * h2
2911 [2017-05-09 Tue]
2912 * h1
2913 [2018-05-09 Wed]
2915 (org-test-with-temp-text
2917 * h1
2918 [2018-05-09 Wed]
2919 * h2
2920 [2017-05-09 Tue]
2921 * h3
2922 [2017-05-08 Mon]
2924 (org-sort-entries nil ?c)
2925 (buffer-string))))
2927 ;; Sort by scheduled date.
2928 (should
2929 (equal "
2930 * TODO h4
2931 SCHEDULED: <2017-05-06 Sat>
2932 * TODO h3
2933 SCHEDULED: <2017-05-08 Mon>
2934 * TODO h2
2935 DEADLINE: <2017-05-09 Tue>
2936 * TODO h1
2937 DEADLINE: <2017-05-07 Sun>
2939 (org-test-with-temp-text
2941 * TODO h2
2942 DEADLINE: <2017-05-09 Tue>
2943 * TODO h1
2944 DEADLINE: <2017-05-07 Sun>
2945 * TODO h3
2946 SCHEDULED: <2017-05-08 Mon>
2947 * TODO h4
2948 SCHEDULED: <2017-05-06 Sat>
2950 (org-sort-entries nil ?s)
2951 (buffer-string))))
2952 ;; Sort by deadline date.
2953 (should
2954 (equal "
2955 * TODO h1
2956 DEADLINE: <2017-05-07 Sun>
2957 * TODO h2
2958 DEADLINE: <2017-05-09 Tue>
2959 * TODO h3
2960 SCHEDULED: <2017-05-08 Mon>
2961 * TODO h4
2962 SCHEDULED: <2017-05-06 Sat>
2964 (org-test-with-temp-text
2966 * TODO h2
2967 DEADLINE: <2017-05-09 Tue>
2968 * TODO h1
2969 DEADLINE: <2017-05-07 Sun>
2970 * TODO h3
2971 SCHEDULED: <2017-05-08 Mon>
2972 * TODO h4
2973 SCHEDULED: <2017-05-06 Sat>
2975 (org-sort-entries nil ?d)
2976 (buffer-string))))
2977 ;; Sort by any date/time
2978 (should
2979 (equal "
2980 * TODO h4
2981 SCHEDULED: <2017-05-06 Sat>
2982 * TODO h1
2983 DEADLINE: <2017-05-07 Sun>
2984 * TODO h3
2985 SCHEDULED: <2017-05-08 Mon>
2986 * TODO h2
2987 DEADLINE: <2017-05-09 Tue>
2989 (org-test-with-temp-text
2991 * TODO h2
2992 DEADLINE: <2017-05-09 Tue>
2993 * TODO h1
2994 DEADLINE: <2017-05-07 Sun>
2995 * TODO h3
2996 SCHEDULED: <2017-05-08 Mon>
2997 * TODO h4
2998 SCHEDULED: <2017-05-06 Sat>
3000 (org-sort-entries nil ?t)
3001 (buffer-string))))
3002 ;; Sort by clocking time.
3003 (should
3004 (equal "
3005 * clocked h2
3006 :LOGBOOK:
3007 CLOCK: [2017-05-09 Tue 00:15]--[2017-05-09 Tue 00:22] => 0:07
3008 CLOCK: [2017-05-09 Tue 00:00]--[2017-05-09 Tue 00:10] => 0:10
3009 :END:
3010 * clocked h1
3011 :LOGBOOK:
3012 CLOCK: [2017-05-09 Tue 00:15]--[2017-05-09 Tue 00:22] => 0:07
3013 CLOCK: [2017-05-09 Tue 00:00]--[2017-05-09 Tue 00:12] => 0:12
3014 :END:
3016 (org-test-with-temp-text
3018 * clocked h1
3019 :LOGBOOK:
3020 CLOCK: [2017-05-09 Tue 00:15]--[2017-05-09 Tue 00:22] => 0:07
3021 CLOCK: [2017-05-09 Tue 00:00]--[2017-05-09 Tue 00:12] => 0:12
3022 :END:
3023 * clocked h2
3024 :LOGBOOK:
3025 CLOCK: [2017-05-09 Tue 00:15]--[2017-05-09 Tue 00:22] => 0:07
3026 CLOCK: [2017-05-09 Tue 00:00]--[2017-05-09 Tue 00:10] => 0:10
3027 :END:
3029 (org-sort-entries nil ?k)
3030 (buffer-string))))
3031 ;; Preserve file local variables when sorting.
3032 (should
3033 (equal "\n* A\n* B\n# Local Variables:\n# foo: t\n# End:\n"
3034 (org-test-with-temp-text
3035 "\n* B\n* A\n# Local Variables:\n# foo: t\n# End:"
3036 (org-sort-entries nil ?a)
3037 (buffer-string)))))
3039 (ert-deftest test-org/string-collate-greaterp ()
3040 "Test `org-string-collate-greaterp' specifications."
3041 (should (org-string-collate-greaterp "def" "abc"))
3042 (should-not (org-string-collate-greaterp "abc" "def")))
3044 (ert-deftest test-org/file-contents ()
3045 "Test `org-file-contents' specifications."
3046 ;; Open files.
3047 (should
3048 (string= "#+BIND: variable value
3049 #+DESCRIPTION: l2
3050 #+LANGUAGE: en
3051 #+SELECT_TAGS: b
3052 #+TITLE: b
3053 #+PROPERTY: a 1
3054 " (org-file-contents (expand-file-name "setupfile3.org"
3055 (concat org-test-dir "examples/")))))
3056 ;; Throw error when trying to access an invalid file.
3057 (should-error (org-file-contents "this-file-must-not-exist"))
3058 ;; Try to access an invalid file, but do not throw an error.
3059 (should
3060 (progn (org-file-contents "this-file-must-not-exist" :noerror) t))
3061 ;; Open URL.
3062 (should
3063 (string= "foo"
3064 (let ((buffer (generate-new-buffer "url-retrieve-output")))
3065 (unwind-protect
3066 ;; Simulate successful retrieval of a URL.
3067 (cl-letf (((symbol-function 'url-retrieve-synchronously)
3068 (lambda (&rest_)
3069 (with-current-buffer buffer
3070 (insert "HTTP/1.1 200 OK\n\nfoo"))
3071 buffer)))
3072 (org-file-contents "http://some-valid-url"))
3073 (kill-buffer buffer)))))
3074 ;; Throw error when trying to access an invalid URL.
3075 (should-error
3076 (let ((buffer (generate-new-buffer "url-retrieve-output")))
3077 (unwind-protect
3078 ;; Simulate unsuccessful retrieval of a URL.
3079 (cl-letf (((symbol-function 'url-retrieve-synchronously)
3080 (lambda (&rest_)
3081 (with-current-buffer buffer
3082 (insert "HTTP/1.1 404 Not found\n\ndoes not matter"))
3083 buffer)))
3084 (org-file-contents "http://this-url-must-not-exist"))
3085 (kill-buffer buffer))))
3086 ;; Try to access an invalid URL, but do not throw an error.
3087 (should-error
3088 (let ((buffer (generate-new-buffer "url-retrieve-output")))
3089 (unwind-protect
3090 ;; Simulate unsuccessful retrieval of a URL.
3091 (cl-letf (((symbol-function 'url-retrieve-synchronously)
3092 (lambda (&rest_)
3093 (with-current-buffer buffer
3094 (insert "HTTP/1.1 404 Not found\n\ndoes not matter"))
3095 buffer)))
3096 (org-file-contents "http://this-url-must-not-exist"))
3097 (kill-buffer buffer))))
3098 (should
3099 (let ((buffer (generate-new-buffer "url-retrieve-output")))
3100 (unwind-protect
3101 ;; Simulate unsuccessful retrieval of a URL.
3102 (cl-letf (((symbol-function 'url-retrieve-synchronously)
3103 (lambda (&rest_)
3104 (with-current-buffer buffer
3105 (insert "HTTP/1.1 404 Not found\n\ndoes not matter"))
3106 buffer)))
3107 (org-file-contents "http://this-url-must-not-exist" :noerror))
3108 (kill-buffer buffer))
3109 t)))
3112 ;;; Navigation
3114 (ert-deftest test-org/forward-heading-same-level ()
3115 "Test `org-forward-heading-same-level' specifications."
3116 ;; Test navigation at top level, forward and backward.
3117 (should
3118 (equal "* H2"
3119 (org-test-with-temp-text "* H1\n* H2"
3120 (org-forward-heading-same-level 1)
3121 (buffer-substring-no-properties (point) (line-end-position)))))
3122 (should
3123 (equal "* H1"
3124 (org-test-with-temp-text "* H1\n<point>* H2"
3125 (org-forward-heading-same-level -1)
3126 (buffer-substring-no-properties (point) (line-end-position)))))
3127 ;; Test navigation in a sub-tree, forward and backward.
3128 (should
3129 (equal "* H2"
3130 (org-test-with-temp-text "* H1\n** H11\n** H12\n* H2"
3131 (org-forward-heading-same-level 1)
3132 (buffer-substring-no-properties (point) (line-end-position)))))
3133 (should
3134 (equal "* H1"
3135 (org-test-with-temp-text "* H1\n** H11\n** H12\n<point>* H2"
3136 (org-forward-heading-same-level -1)
3137 (buffer-substring-no-properties (point) (line-end-position)))))
3138 ;; Stop at first or last sub-heading.
3139 (should-not
3140 (equal "* H2"
3141 (org-test-with-temp-text "* H1\n** H11\n<point>** H12\n* H2"
3142 (org-forward-heading-same-level 1)
3143 (buffer-substring-no-properties (point) (line-end-position)))))
3144 (should-not
3145 (equal "* H2"
3146 (org-test-with-temp-text "* H1\n<point>** H11\n** H12\n* H2"
3147 (org-forward-heading-same-level -1)
3148 (buffer-substring-no-properties (point) (line-end-position)))))
3149 ;; Allow multiple moves.
3150 (should
3151 (equal "* H3"
3152 (org-test-with-temp-text "* H1\n* H2\n* H3"
3153 (org-forward-heading-same-level 2)
3154 (buffer-substring-no-properties (point) (line-end-position)))))
3155 (should
3156 (equal "* H1"
3157 (org-test-with-temp-text "* H1\n* H2\n<point>* H3"
3158 (org-forward-heading-same-level -2)
3159 (buffer-substring-no-properties (point) (line-end-position)))))
3160 ;; Ignore spurious moves when first (or last) sibling is reached.
3161 (should
3162 (equal "** H3"
3163 (org-test-with-temp-text "* First\n<point>** H1\n** H2\n** H3\n* Last"
3164 (org-forward-heading-same-level 100)
3165 (buffer-substring-no-properties (point) (line-end-position)))))
3166 (should
3167 (equal "** H1"
3168 (org-test-with-temp-text "* First\n** H1\n** H2\n<point>** H3\n* Last"
3169 (org-forward-heading-same-level -100)
3170 (buffer-substring-no-properties (point) (line-end-position))))))
3172 (ert-deftest test-org/end-of-meta-data ()
3173 "Test `org-end-of-meta-data' specifications."
3174 ;; Skip planning line.
3175 (should
3176 (org-test-with-temp-text "* Headline\nSCHEDULED: <2014-03-04 tue.>"
3177 (org-end-of-meta-data)
3178 (eobp)))
3179 ;; Skip properties drawer.
3180 (should
3181 (org-test-with-temp-text
3182 "* Headline\nSCHEDULED: <2014-03-04 tue.>\n:PROPERTIES:\n:A: 1\n:END:"
3183 (org-end-of-meta-data)
3184 (eobp)))
3185 ;; Skip both.
3186 (should
3187 (org-test-with-temp-text "* Headline\n:PROPERTIES:\n:A: 1\n:END:"
3188 (org-end-of-meta-data)
3189 (eobp)))
3190 ;; Nothing to skip, go to first line.
3191 (should
3192 (org-test-with-temp-text "* Headline\nContents"
3193 (org-end-of-meta-data)
3194 (looking-at "Contents")))
3195 ;; With option argument, skip empty lines, regular drawers and
3196 ;; clocking lines.
3197 (should
3198 (org-test-with-temp-text "* Headline\n\nContents"
3199 (org-end-of-meta-data t)
3200 (looking-at "Contents")))
3201 (should
3202 (org-test-with-temp-text "* Headline\nCLOCK:\nContents"
3203 (org-end-of-meta-data t)
3204 (looking-at "Contents")))
3205 (should
3206 (org-test-with-temp-text "* Headline\n:LOGBOOK:\nlogging\n:END:\nContents"
3207 (org-end-of-meta-data t)
3208 (looking-at "Contents")))
3209 ;; Special case: do not skip incomplete drawers.
3210 (should
3211 (org-test-with-temp-text "* Headline\n:LOGBOOK:\nlogging\nContents"
3212 (org-end-of-meta-data t)
3213 (looking-at ":LOGBOOK:")))
3214 ;; Special case: Be careful about consecutive headlines.
3215 (should-not
3216 (org-test-with-temp-text "* H1\n*H2\nContents"
3217 (org-end-of-meta-data t)
3218 (looking-at "Contents"))))
3220 (ert-deftest test-org/beginning-of-line ()
3221 "Test `org-beginning-of-line' specifications."
3222 ;; Move to beginning of line. If current line in invisible, move to
3223 ;; beginning of visible line instead.
3224 (should
3225 (org-test-with-temp-text "Some text\nSome other text<point>"
3226 (org-beginning-of-line)
3227 (bolp)))
3228 (should
3229 (org-test-with-temp-text "* H1\n** H2<point>"
3230 (org-overview)
3231 (org-beginning-of-line)
3232 (= (line-beginning-position) 1)))
3233 ;; With `visual-line-mode' active, move to beginning of visual line.
3234 (should-not
3235 (org-test-with-temp-text "A <point>long line of text\nSome other text"
3236 (visual-line-mode)
3237 (dotimes (i 1000) (insert "very "))
3238 (org-beginning-of-line)
3239 (bolp)))
3240 ;; In a wide headline, with `visual-line-mode', prefer going to the
3241 ;; beginning of a visual line than to the logical beginning of line,
3242 ;; even if special movement is active.
3243 (should-not
3244 (org-test-with-temp-text "* A <point>long headline"
3245 (visual-line-mode)
3246 (dotimes (i 1000) (insert "very "))
3247 (goto-char (point-max))
3248 (org-beginning-of-line)
3249 (bobp)))
3250 (should-not
3251 (org-test-with-temp-text "* A <point>long headline"
3252 (visual-line-mode)
3253 (dotimes (i 1000) (insert "very "))
3254 (goto-char (point-max))
3255 (let ((org-special-ctrl-a/e t)) (org-beginning-of-line))
3256 (bobp)))
3257 ;; At an headline with special movement, first move at beginning of
3258 ;; title, then at the beginning of line, rinse, repeat.
3259 (should
3260 (org-test-with-temp-text "* TODO Headline<point>"
3261 (let ((org-special-ctrl-a/e t))
3262 (and (progn (org-beginning-of-line) (looking-at-p "Headline"))
3263 (progn (org-beginning-of-line) (bolp))
3264 (progn (org-beginning-of-line) (looking-at-p "Headline"))))))
3265 (should
3266 (org-test-with-temp-text "* TODO [#A] Headline<point>"
3267 (let ((org-special-ctrl-a/e t))
3268 (org-beginning-of-line)
3269 (looking-at "Headline"))))
3270 (should
3271 (org-test-with-temp-text "* TODO [#A] Headline<point>"
3272 (let ((org-special-ctrl-a/e '(t . nil)))
3273 (org-beginning-of-line)
3274 (looking-at "Headline"))))
3275 (should-not
3276 (org-test-with-temp-text "* TODO [#A] Headline<point>"
3277 (let ((org-special-ctrl-a/e '(nil . nil)))
3278 (org-beginning-of-line)
3279 (looking-at "Headline"))))
3280 ;; At an headline with reversed movement, first move to beginning of
3281 ;; line, then to the beginning of title.
3282 (should
3283 (org-test-with-temp-text "* TODO Headline<point>"
3284 (let ((org-special-ctrl-a/e 'reversed)
3285 (this-command last-command))
3286 (and (progn (org-beginning-of-line) (bolp))
3287 (progn (org-beginning-of-line) (looking-at-p "Headline"))))))
3288 (should
3289 (org-test-with-temp-text "* TODO Headline<point>"
3290 (let ((org-special-ctrl-a/e '(reversed . nil))
3291 (this-command last-command))
3292 (and (progn (org-beginning-of-line) (bolp))
3293 (progn (org-beginning-of-line) (looking-at-p "Headline"))))))
3294 (should-not
3295 (org-test-with-temp-text "* TODO Headline<point>"
3296 (let ((org-special-ctrl-a/e '(t . nil))
3297 (this-command last-command))
3298 (and (progn (org-beginning-of-line) (bolp))
3299 (progn (org-beginning-of-line) (looking-at-p "Headline"))))))
3300 ;; At an item with special movement, first move after to beginning
3301 ;; of title, then to the beginning of line, rinse, repeat.
3302 (should
3303 (org-test-with-temp-text "- [ ] Item<point>"
3304 (let ((org-special-ctrl-a/e t))
3305 (and (progn (org-beginning-of-line) (looking-at-p "Item"))
3306 (progn (org-beginning-of-line) (bolp))
3307 (progn (org-beginning-of-line) (looking-at-p "Item"))))))
3308 ;; At an item with reversed movement, first move to beginning of
3309 ;; line, then to the beginning of title.
3310 (should
3311 (org-test-with-temp-text "- [X] Item<point>"
3312 (let ((org-special-ctrl-a/e 'reversed)
3313 (this-command last-command))
3314 (and (progn (org-beginning-of-line) (bolp))
3315 (progn (org-beginning-of-line) (looking-at-p "Item"))))))
3316 ;; Leave point before invisible characters at column 0.
3317 (should
3318 (org-test-with-temp-text "[[https://orgmode.org]]<point>"
3319 (let ((org-special-ctrl-a/e nil))
3320 (org-beginning-of-line)
3321 (bolp))))
3322 (should
3323 (org-test-with-temp-text "[[https://orgmode.org]]<point>"
3324 (let ((org-special-ctrl-a/e t))
3325 (org-beginning-of-line)
3326 (bolp))))
3327 (should
3328 (org-test-with-temp-text "[[http<point>://orgmode.org]]"
3329 (visual-line-mode)
3330 (org-beginning-of-line)
3331 (bolp)))
3332 ;; Special case: Do not error when the buffer contains only a single
3333 ;; asterisk.
3334 (should
3335 (org-test-with-temp-text "*<point>"
3336 (let ((org-special-ctrl-a/e t)) (org-beginning-of-line) t)))
3337 (should
3338 (org-test-with-temp-text "*<point>"
3339 (let ((org-special-ctrl-a/e nil)) (org-beginning-of-line) t))))
3341 (ert-deftest test-org/end-of-line ()
3342 "Test `org-end-of-line' specifications."
3343 ;; Standard test.
3344 (should
3345 (org-test-with-temp-text "Some text\nSome other text"
3346 (org-end-of-line)
3347 (eolp)))
3348 ;; With `visual-line-mode' active, move to end of visible line.
3349 ;; However, never go past ellipsis.
3350 (should-not
3351 (org-test-with-temp-text "A <point>long line of text\nSome other text"
3352 (visual-line-mode)
3353 (dotimes (i 1000) (insert "very "))
3354 (goto-char (point-min))
3355 (org-end-of-line)
3356 (eolp)))
3357 (should-not
3358 (org-test-with-temp-text "* A short headline\nSome contents"
3359 (visual-line-mode)
3360 (org-overview)
3361 (org-end-of-line)
3362 (eobp)))
3363 ;; In a wide headline, with `visual-line-mode', prefer going to end
3364 ;; of visible line if tags, or end of line, are farther.
3365 (should-not
3366 (org-test-with-temp-text "* A <point>long headline"
3367 (visual-line-mode)
3368 (dotimes (i 1000) (insert "very "))
3369 (goto-char (point-min))
3370 (org-end-of-line)
3371 (eolp)))
3372 (should-not
3373 (org-test-with-temp-text "* A <point>long headline :tag:"
3374 (visual-line-mode)
3375 (dotimes (i 1000) (insert "very "))
3376 (goto-char (point-min))
3377 (org-end-of-line)
3378 (eolp)))
3379 ;; At an headline without special movement, go to end of line.
3380 ;; However, never go past ellipsis.
3381 (should
3382 (org-test-with-temp-text "* Headline2b :tag:\n"
3383 (let ((org-special-ctrl-a/e nil))
3384 (and (progn (org-end-of-line) (eolp))
3385 (progn (org-end-of-line) (eolp))))))
3386 (should
3387 (org-test-with-temp-text "* Headline2b :tag:\n"
3388 (let ((org-special-ctrl-a/e '(t . nil)))
3389 (and (progn (org-end-of-line) (eolp))
3390 (progn (org-end-of-line) (eolp))))))
3391 (should
3392 (org-test-with-temp-text "* Headline2a :tag:\n** Sub"
3393 (org-overview)
3394 (let ((org-special-ctrl-a/e nil))
3395 (org-end-of-line)
3396 (= 1 (line-beginning-position)))))
3397 ;; At an headline with special movement, first move before tags,
3398 ;; then at the end of line, rinse, repeat. However, never go past
3399 ;; ellipsis.
3400 (should
3401 (org-test-with-temp-text "* Headline1 :tag:\n"
3402 (let ((org-special-ctrl-a/e t))
3403 (and (progn (org-end-of-line) (looking-at-p " :tag:"))
3404 (progn (org-end-of-line) (eolp))
3405 (progn (org-end-of-line) (looking-at-p " :tag:"))))))
3406 (should
3407 (org-test-with-temp-text "* Headline1 :tag:\n"
3408 (let ((org-special-ctrl-a/e '(nil . t)))
3409 (and (progn (org-end-of-line) (looking-at-p " :tag:"))
3410 (progn (org-end-of-line) (eolp))
3411 (progn (org-end-of-line) (looking-at-p " :tag:"))))))
3412 (should-not
3413 (org-test-with-temp-text "* Headline1 :tag:\n"
3414 (let ((org-special-ctrl-a/e '(nil . nil)))
3415 (and (progn (org-end-of-line) (looking-at-p " :tag:"))
3416 (progn (org-end-of-line) (eolp))
3417 (progn (org-end-of-line) (looking-at-p " :tag:"))))))
3418 (should
3419 (org-test-with-temp-text "* Headline2a :tag:\n** Sub"
3420 (org-overview)
3421 (let ((org-special-ctrl-a/e t))
3422 (org-end-of-line)
3423 (org-end-of-line)
3424 (= 1 (line-beginning-position)))))
3425 ;; At an headline, with reversed movement, first go to end of line,
3426 ;; then before tags. However, never go past ellipsis.
3427 (should
3428 (org-test-with-temp-text "* Headline3 :tag:\n"
3429 (let ((org-special-ctrl-a/e 'reversed)
3430 (this-command last-command))
3431 (and (progn (org-end-of-line) (eolp))
3432 (progn (org-end-of-line) (looking-at-p " :tag:"))))))
3433 (should
3434 (org-test-with-temp-text "* Headline3 :tag:\n"
3435 (let ((org-special-ctrl-a/e '(nil . reversed))
3436 (this-command last-command))
3437 (and (progn (org-end-of-line) (eolp))
3438 (progn (org-end-of-line) (looking-at-p " :tag:"))))))
3439 (should-not
3440 (org-test-with-temp-text "* Headline3 :tag:\n"
3441 (let ((org-special-ctrl-a/e '(nil . t))
3442 (this-command last-command))
3443 (and (progn (org-end-of-line) (eolp))
3444 (progn (org-end-of-line) (looking-at-p " :tag:"))))))
3445 (should
3446 (org-test-with-temp-text "* Headline2a :tag:\n** Sub"
3447 (org-overview)
3448 (let ((org-special-ctrl-a/e 'reversed))
3449 (org-end-of-line)
3450 (= 1 (line-beginning-position)))))
3451 ;; At a block without hidden contents.
3452 (should
3453 (org-test-with-temp-text "#+BEGIN_CENTER\nContents\n#+END_CENTER"
3454 (progn (org-end-of-line) (eolp))))
3455 ;; At a block with hidden contents.
3456 (should-not
3457 (org-test-with-temp-text "#+BEGIN_CENTER\nContents\n#+END_CENTER"
3458 (let ((org-special-ctrl-a/e t))
3459 (org-hide-block-toggle)
3460 (org-end-of-line)
3461 (eobp))))
3462 ;; Get past invisible characters at the end of line.
3463 (should
3464 (org-test-with-temp-text "[[https://orgmode.org]]"
3465 (org-end-of-line)
3466 (eolp))))
3468 (ert-deftest test-org/open-line ()
3469 "Test `org-open-line' specifications."
3470 ;; Call `open-line' outside of tables.
3471 (should
3472 (equal "\nText"
3473 (org-test-with-temp-text "Text"
3474 (org-open-line 1)
3475 (buffer-string))))
3476 ;; At a table, create a row above.
3477 (should
3478 (equal "\n| |\n| a |"
3479 (org-test-with-temp-text "\n<point>| a |"
3480 (org-open-line 1)
3481 (buffer-string))))
3482 ;; At the very first character of the buffer, also call `open-line'.
3483 (should
3484 (equal "\n| a |"
3485 (org-test-with-temp-text "| a |"
3486 (org-open-line 1)
3487 (buffer-string))))
3488 ;; Narrowing does not count.
3489 (should
3490 (equal "Text\n| |\n| a |"
3491 (org-test-with-temp-text "Text\n<point>| a |"
3492 (narrow-to-region (point) (point-max))
3493 (org-open-line 1)
3494 (widen)
3495 (buffer-string)))))
3497 (ert-deftest test-org/forward-sentence ()
3498 "Test `org-forward-sentence' specifications."
3499 ;; At the end of a table cell, move to the end of the next one.
3500 (should
3501 (org-test-with-temp-text "| a<point> | b |"
3502 (org-forward-sentence)
3503 (looking-at " |$")))
3504 ;; Elsewhere in a cell, move to its end.
3505 (should
3506 (org-test-with-temp-text "| a<point>c | b |"
3507 (org-forward-sentence)
3508 (looking-at " | b |$")))
3509 ;; Otherwise, simply call `forward-sentence'.
3510 (should
3511 (org-test-with-temp-text "Sentence<point> 1. Sentence 2."
3512 (org-forward-sentence)
3513 (looking-at " Sentence 2.")))
3514 (should
3515 (org-test-with-temp-text "Sentence<point> 1. Sentence 2."
3516 (org-forward-sentence)
3517 (org-forward-sentence)
3518 (eobp)))
3519 ;; At the end of an element, jump to the next one, without stopping
3520 ;; on blank lines in-between.
3521 (should
3522 (org-test-with-temp-text "Paragraph 1.<point>\n\nParagraph 2."
3523 (org-forward-sentence)
3524 (eobp)))
3525 ;; Headlines are considered to be sentences by themselves, even if
3526 ;; they do not end with a full stop.
3527 (should
3528 (equal
3529 "* Headline"
3530 (org-test-with-temp-text "* <point>Headline\nSentence."
3531 (org-forward-sentence)
3532 (buffer-substring-no-properties (line-beginning-position) (point)))))
3533 (should
3534 (org-test-with-temp-text "* Headline<point>\nSentence."
3535 (org-forward-sentence)
3536 (eobp)))
3537 (should
3538 (org-test-with-temp-text "Sentence.<point>\n\n* Headline\n\nSentence 2."
3539 (org-forward-sentence)
3540 (and (org-at-heading-p) (eolp)))))
3542 (ert-deftest test-org/backward-sentence ()
3543 "Test `org-backward-sentence' specifications."
3544 ;; At the beginning of a table cell, move to the beginning of the
3545 ;; previous one.
3546 (should
3547 (org-test-with-temp-text "| a | <point>b |"
3548 (org-backward-sentence)
3549 (looking-at "a | b |$")))
3550 ;; Elsewhere in a cell, move to its beginning.
3551 (should
3552 (org-test-with-temp-text "| a | b<point>c |"
3553 (org-backward-sentence)
3554 (looking-at "bc |$")))
3555 ;; Otherwise, simply call `backward-sentence'.
3556 (should
3557 (org-test-with-temp-text "Sentence 1. Sentence<point> 2."
3558 (org-backward-sentence)
3559 (looking-at "Sentence 2.")))
3560 (should
3561 (org-test-with-temp-text "Sentence 1. Sentence<point> 2."
3562 (org-backward-sentence)
3563 (org-backward-sentence)
3564 (bobp)))
3565 ;; Make sure to hit the beginning of a sentence on the same line as
3566 ;; an item.
3567 (should
3568 (org-test-with-temp-text "- Line 1\n line <point>2."
3569 (org-backward-sentence)
3570 (looking-at "Line 1"))))
3572 (ert-deftest test-org/forward-paragraph ()
3573 "Test `org-forward-paragraph' specifications."
3574 ;; At end of buffer, do not return an error.
3575 (should
3576 (org-test-with-temp-text "Paragraph"
3577 (goto-char (point-max))
3578 (org-forward-paragraph)
3580 ;; Standard test.
3581 (should
3582 (org-test-with-temp-text "P1\n\nP2\n\nP3"
3583 (org-forward-paragraph)
3584 (looking-at "P2")))
3585 ;; Ignore depth.
3586 (should
3587 (org-test-with-temp-text "#+BEGIN_CENTER\nP1\n#+END_CENTER\nP2"
3588 (org-forward-paragraph)
3589 (looking-at "P1")))
3590 ;; Do not enter elements with invisible contents.
3591 (should
3592 (org-test-with-temp-text "#+BEGIN_CENTER\nP1\n\nP2\n#+END_CENTER\nP3"
3593 (org-hide-block-toggle)
3594 (org-forward-paragraph)
3595 (looking-at "P3")))
3596 ;; On an affiliated keyword, jump to the beginning of the element.
3597 (should
3598 (org-test-with-temp-text "#+name: para\n#+caption: caption\nPara"
3599 (org-forward-paragraph)
3600 (looking-at "Para")))
3601 ;; On an item or a footnote definition, move to the second element
3602 ;; inside, if any.
3603 (should
3604 (org-test-with-temp-text "- Item1\n\n Paragraph\n- Item2"
3605 (org-forward-paragraph)
3606 (looking-at " Paragraph")))
3607 (should
3608 (org-test-with-temp-text "[fn:1] Def1\n\nParagraph\n\n[fn:2] Def2"
3609 (org-forward-paragraph)
3610 (looking-at "Paragraph")))
3611 ;; On an item, or a footnote definition, when the first line is
3612 ;; empty, move to the first item.
3613 (should
3614 (org-test-with-temp-text "- \n\n Paragraph\n- Item2"
3615 (org-forward-paragraph)
3616 (looking-at " Paragraph")))
3617 (should
3618 (org-test-with-temp-text "[fn:1]\n\nParagraph\n\n[fn:2] Def2"
3619 (org-forward-paragraph)
3620 (looking-at "Paragraph")))
3621 ;; On a table (resp. a property drawer) do not move through table
3622 ;; rows (resp. node properties).
3623 (should
3624 (org-test-with-temp-text "| a | b |\n| c | d |\nParagraph"
3625 (org-forward-paragraph)
3626 (looking-at "Paragraph")))
3627 (should
3628 (org-test-with-temp-text
3629 "* H\n<point>:PROPERTIES:\n:prop: value\n:END:\nParagraph"
3630 (org-forward-paragraph)
3631 (looking-at "Paragraph")))
3632 ;; On a verse or source block, stop after blank lines.
3633 (should
3634 (org-test-with-temp-text "#+BEGIN_VERSE\nL1\n\nL2\n#+END_VERSE"
3635 (org-forward-paragraph)
3636 (looking-at "L2")))
3637 (should
3638 (org-test-with-temp-text "#+BEGIN_SRC\nL1\n\nL2\n#+END_SRC"
3639 (org-forward-paragraph)
3640 (looking-at "L2"))))
3642 (ert-deftest test-org/backward-paragraph ()
3643 "Test `org-backward-paragraph' specifications."
3644 ;; Do not error at beginning of buffer.
3645 (should
3646 (org-test-with-temp-text "Paragraph"
3647 (org-backward-paragraph)
3649 ;; Regular test.
3650 (should
3651 (org-test-with-temp-text "P1\n\nP2\n\nP3<point>"
3652 (org-backward-paragraph)
3653 (looking-at "P3")))
3654 (should
3655 (org-test-with-temp-text "P1\n\nP2\n\n<point>P3"
3656 (org-backward-paragraph)
3657 (looking-at-p "P2")))
3658 ;; Ignore depth.
3659 (should
3660 (org-test-with-temp-text "P1\n\n#+BEGIN_CENTER\nP2\n#+END_CENTER\n<point>P3"
3661 (org-backward-paragraph)
3662 (looking-at-p "P2")))
3663 ;; Ignore invisible elements.
3664 (should
3665 (org-test-with-temp-text "* H1\n P1\n* H2"
3666 (org-cycle)
3667 (goto-char (point-max))
3668 (beginning-of-line)
3669 (org-backward-paragraph)
3670 (bobp)))
3671 ;; On an affiliated keyword, jump to the first one.
3672 (should
3673 (org-test-with-temp-text
3674 "P1\n#+name: n\n#+caption: c1\n#+caption: <point>c2\nP2"
3675 (org-backward-paragraph)
3676 (looking-at-p "#\\+name")))
3677 ;; On the second element in an item or a footnote definition, jump
3678 ;; to item or the definition.
3679 (should
3680 (org-test-with-temp-text "- line1\n\n<point> line2"
3681 (org-backward-paragraph)
3682 (looking-at-p "- line1")))
3683 (should
3684 (org-test-with-temp-text "[fn:1] line1\n\n<point> line2"
3685 (org-backward-paragraph)
3686 (looking-at-p "\\[fn:1\\] line1")))
3687 ;; On a table (resp. a property drawer), ignore table rows
3688 ;; (resp. node properties).
3689 (should
3690 (org-test-with-temp-text "| a | b |\n| c | d |\n<point>P1"
3691 (org-backward-paragraph)
3692 (bobp)))
3693 (should
3694 (org-test-with-temp-text "* H\n:PROPERTIES:\n:prop: value\n:END:\n<point>P1"
3695 (org-backward-paragraph)
3696 (looking-at-p ":PROPERTIES:")))
3697 ;; On a comment, example, src and verse blocks, stop before blank
3698 ;; lines.
3699 (should
3700 (org-test-with-temp-text "#+BEGIN_VERSE\nL1\n\nL2\n\n<point>L3\n#+END_VERSE"
3701 (org-backward-paragraph)
3702 (looking-at-p "L2")))
3703 (should
3704 (org-test-with-temp-text "#+BEGIN_SRC\nL1\n\nL2\n\n<point>L3#+END_SRC"
3705 (org-backward-paragraph)
3706 (looking-at-p "L2")))
3707 ;; In comment, example, export, src and verse blocks, stop below
3708 ;; opening line when called from within the block.
3709 (should
3710 (org-test-with-temp-text "#+BEGIN_VERSE\nL1\nL2<point>\n#+END_VERSE"
3711 (org-backward-paragraph)
3712 (looking-at-p "L1")))
3713 (should
3714 (org-test-with-temp-text "#+BEGIN_EXAMPLE\nL1\nL2<point>\n#+END_EXAMPLE"
3715 (org-backward-paragraph)
3716 (looking-at-p "L1")))
3717 ;; When called from the opening line itself, however, move to
3718 ;; beginning of block.
3719 (should
3720 (org-test-with-temp-text "#+BEGIN_<point>EXAMPLE\nL1\n#+END_EXAMPLE"
3721 (org-backward-paragraph)
3722 (bobp)))
3723 ;; Pathological case: on an empty heading, move to its beginning.
3724 (should
3725 (org-test-with-temp-text "* <point>H"
3726 (org-backward-paragraph)
3727 (bobp))))
3729 (ert-deftest test-org/forward-element ()
3730 "Test `org-forward-element' specifications."
3731 ;; 1. At EOB: should error.
3732 (org-test-with-temp-text "Some text\n"
3733 (goto-char (point-max))
3734 (should-error (org-forward-element)))
3735 ;; 2. Standard move: expected to ignore blank lines.
3736 (org-test-with-temp-text "First paragraph.\n\n\nSecond paragraph."
3737 (org-forward-element)
3738 (should (looking-at (regexp-quote "Second paragraph."))))
3739 ;; 3. Headline tests.
3740 (org-test-with-temp-text "
3741 * Head 1
3742 ** Head 1.1
3743 *** Head 1.1.1
3744 ** Head 1.2"
3745 ;; 3.1. At an headline beginning: move to next headline at the
3746 ;; same level.
3747 (goto-line 3)
3748 (org-forward-element)
3749 (should (looking-at (regexp-quote "** Head 1.2")))
3750 ;; 3.2. At an headline beginning: move to parent headline if no
3751 ;; headline at the same level.
3752 (goto-line 3)
3753 (org-forward-element)
3754 (should (looking-at (regexp-quote "** Head 1.2"))))
3755 ;; 4. Greater element tests.
3756 (org-test-with-temp-text
3757 "#+BEGIN_CENTER\nInside.\n#+END_CENTER\n\nOutside."
3758 ;; 4.1. At a greater element: expected to skip contents.
3759 (org-forward-element)
3760 (should (looking-at (regexp-quote "Outside.")))
3761 ;; 4.2. At the end of greater element contents: expected to skip
3762 ;; to the end of the greater element.
3763 (goto-line 2)
3764 (org-forward-element)
3765 (should (looking-at (regexp-quote "Outside."))))
3766 ;; 5. List tests.
3767 (org-test-with-temp-text "
3768 - item1
3770 - sub1
3772 - sub2
3774 - sub3
3776 Inner paragraph.
3778 - item2
3780 Outside."
3781 ;; 5.1. At list top point: expected to move to the element after
3782 ;; the list.
3783 (goto-line 2)
3784 (org-forward-element)
3785 (should (looking-at (regexp-quote "Outside.")))
3786 ;; 5.2. Special case: at the first line of a sub-list, but not at
3787 ;; beginning of line, move to next item.
3788 (goto-line 2)
3789 (forward-char)
3790 (org-forward-element)
3791 (should (looking-at "- item2"))
3792 (goto-line 4)
3793 (forward-char)
3794 (org-forward-element)
3795 (should (looking-at " - sub2"))
3796 ;; 5.3 At sub-list beginning: expected to move after the sub-list.
3797 (goto-line 4)
3798 (org-forward-element)
3799 (should (looking-at (regexp-quote " Inner paragraph.")))
3800 ;; 5.4. At sub-list end: expected to move outside the sub-list.
3801 (goto-line 8)
3802 (org-forward-element)
3803 (should (looking-at (regexp-quote " Inner paragraph.")))
3804 ;; 5.5. At an item: expected to move to next item, if any.
3805 (goto-line 6)
3806 (org-forward-element)
3807 (should (looking-at " - sub3"))))
3809 (ert-deftest test-org/backward-element ()
3810 "Test `org-backward-element' specifications."
3811 ;; 1. Should error at BOB.
3812 (org-test-with-temp-text " \nParagraph."
3813 (should-error (org-backward-element)))
3814 ;; 2. Should move at BOB when called on the first element in buffer.
3815 (should
3816 (org-test-with-temp-text "\n#+TITLE: test"
3817 (progn (forward-line)
3818 (org-backward-element)
3819 (bobp))))
3820 ;; 3. Not at the beginning of an element: move at its beginning.
3821 (org-test-with-temp-text "Paragraph1.\n\nParagraph2."
3822 (goto-line 3)
3823 (end-of-line)
3824 (org-backward-element)
3825 (should (looking-at (regexp-quote "Paragraph2."))))
3826 ;; 4. Headline tests.
3827 (org-test-with-temp-text "
3828 * Head 1
3829 ** Head 1.1
3830 *** Head 1.1.1
3831 ** Head 1.2"
3832 ;; 4.1. At an headline beginning: move to previous headline at the
3833 ;; same level.
3834 (goto-line 5)
3835 (org-backward-element)
3836 (should (looking-at (regexp-quote "** Head 1.1")))
3837 ;; 4.2. At an headline beginning: move to parent headline if no
3838 ;; headline at the same level.
3839 (goto-line 3)
3840 (org-backward-element)
3841 (should (looking-at (regexp-quote "* Head 1")))
3842 ;; 4.3. At the first top-level headline: should error.
3843 (goto-line 2)
3844 (should-error (org-backward-element)))
3845 ;; 5. At beginning of first element inside a greater element:
3846 ;; expected to move to greater element's beginning.
3847 (org-test-with-temp-text "Before.\n#+BEGIN_CENTER\nInside.\n#+END_CENTER"
3848 (goto-line 3)
3849 (org-backward-element)
3850 (should (looking-at "#\\+BEGIN_CENTER")))
3851 ;; 6. At the beginning of the first element in a section: should
3852 ;; move back to headline, if any.
3853 (should
3854 (org-test-with-temp-text "#+TITLE: test\n* Headline\n\nParagraph"
3855 (progn (goto-char (point-max))
3856 (beginning-of-line)
3857 (org-backward-element)
3858 (org-at-heading-p))))
3859 ;; 7. List tests.
3860 (org-test-with-temp-text "
3861 - item1
3863 - sub1
3865 - sub2
3867 - sub3
3869 Inner paragraph.
3871 - item2
3874 Outside."
3875 ;; 7.1. At beginning of sub-list: expected to move to the
3876 ;; paragraph before it.
3877 (goto-line 4)
3878 (org-backward-element)
3879 (should (looking-at "item1"))
3880 ;; 7.2. At an item in a list: expected to move at previous item.
3881 (goto-line 8)
3882 (org-backward-element)
3883 (should (looking-at " - sub2"))
3884 (goto-line 12)
3885 (org-backward-element)
3886 (should (looking-at "- item1"))
3887 ;; 7.3. At end of list/sub-list: expected to move to list/sub-list
3888 ;; beginning.
3889 (goto-line 10)
3890 (org-backward-element)
3891 (should (looking-at " - sub1"))
3892 (goto-line 15)
3893 (org-backward-element)
3894 (should (looking-at "- item1"))
3895 ;; 7.4. At blank-lines before list end: expected to move to top
3896 ;; item.
3897 (goto-line 14)
3898 (org-backward-element)
3899 (should (looking-at "- item1"))))
3901 (ert-deftest test-org/up-element ()
3902 "Test `org-up-element' specifications."
3903 ;; 1. At BOB or with no surrounding element: should error.
3904 (org-test-with-temp-text "Paragraph."
3905 (should-error (org-up-element)))
3906 (org-test-with-temp-text "* Head1\n* Head2"
3907 (goto-line 2)
3908 (should-error (org-up-element)))
3909 (org-test-with-temp-text "Paragraph1.\n\nParagraph2."
3910 (goto-line 3)
3911 (should-error (org-up-element)))
3912 ;; 2. At an headline: move to parent headline.
3913 (org-test-with-temp-text "* Head1\n** Sub-Head1\n** Sub-Head2"
3914 (goto-line 3)
3915 (org-up-element)
3916 (should (looking-at "\\* Head1")))
3917 ;; 3. Inside a greater element: move to greater element beginning.
3918 (org-test-with-temp-text
3919 "Before.\n#+BEGIN_CENTER\nParagraph1\nParagraph2\n#+END_CENTER\n"
3920 (goto-line 3)
3921 (org-up-element)
3922 (should (looking-at "#\\+BEGIN_CENTER")))
3923 ;; 4. List tests.
3924 (org-test-with-temp-text "* Top
3925 - item1
3927 - sub1
3929 - sub2
3931 Paragraph within sub2.
3933 - item2"
3934 ;; 4.1. Within an item: move to the item beginning.
3935 (goto-line 8)
3936 (org-up-element)
3937 (should (looking-at " - sub2"))
3938 ;; 4.2. At an item in a sub-list: move to parent item.
3939 (goto-line 4)
3940 (org-up-element)
3941 (should (looking-at "- item1"))
3942 ;; 4.3. At an item in top list: move to beginning of whole list.
3943 (goto-line 10)
3944 (org-up-element)
3945 (should (looking-at "- item1"))
3946 ;; 4.4. Special case. At very top point: should move to parent of
3947 ;; list.
3948 (goto-line 2)
3949 (org-up-element)
3950 (should (looking-at "\\* Top"))))
3952 (ert-deftest test-org/down-element ()
3953 "Test `org-down-element' specifications."
3954 ;; Error when the element hasn't got a recursive type.
3955 (org-test-with-temp-text "Paragraph."
3956 (should-error (org-down-element)))
3957 ;; Error when the element has no contents
3958 (org-test-with-temp-text "* Headline"
3959 (should-error (org-down-element)))
3960 ;; When at a plain-list, move to first item.
3961 (org-test-with-temp-text "- Item 1\n - Item 1.1\n - Item 2.2"
3962 (goto-line 2)
3963 (org-down-element)
3964 (should (looking-at " - Item 1.1")))
3965 (org-test-with-temp-text "#+NAME: list\n- Item 1"
3966 (org-down-element)
3967 (should (looking-at " Item 1")))
3968 ;; When at a table, move to first row
3969 (org-test-with-temp-text "#+NAME: table\n| a | b |"
3970 (org-down-element)
3971 (should (looking-at " a | b |")))
3972 ;; Otherwise, move inside the greater element.
3973 (org-test-with-temp-text "#+BEGIN_CENTER\nParagraph.\n#+END_CENTER"
3974 (org-down-element)
3975 (should (looking-at "Paragraph"))))
3977 (ert-deftest test-org/drag-element-backward ()
3978 "Test `org-drag-element-backward' specifications."
3979 ;; Standard test.
3980 (should
3981 (equal
3982 "#+key2: val2\n#+key1: val1\n#+key3: val3"
3983 (org-test-with-temp-text "#+key1: val1\n<point>#+key2: val2\n#+key3: val3"
3984 (org-drag-element-backward)
3985 (buffer-string))))
3986 (should
3987 (equal
3988 "#+BEGIN_CENTER\n#+B: 2\n#+A: 1\n#+END_CENTER"
3989 (org-test-with-temp-text
3990 "#+BEGIN_CENTER\n#+A: 1\n<point>#+B: 2\n#+END_CENTER"
3991 (org-drag-element-backward)
3992 (buffer-string))))
3993 ;; Preserve blank lines.
3994 (should
3995 (equal "Paragraph 2\n\n\nPara1\n\nPara3"
3996 (org-test-with-temp-text "Para1\n\n\n<point>Paragraph 2\n\nPara3"
3997 (org-drag-element-backward)
3998 (buffer-string))))
3999 ;; Preserve column.
4000 (should
4001 (org-test-with-temp-text "#+key1: v\n#+key<point>2: v\n#+key3: v"
4002 (org-drag-element-backward)
4003 (looking-at-p "2")))
4004 ;; Error when trying to move first element of buffer.
4005 (should-error
4006 (org-test-with-temp-text "Paragraph 1.\n\nParagraph 2."
4007 (org-drag-element-backward))
4008 :type 'user-error)
4009 ;; Error when trying to swap nested elements.
4010 (should-error
4011 (org-test-with-temp-text "#+BEGIN_CENTER\n<point>Test.\n#+END_CENTER"
4012 (org-drag-element-backward))
4013 :type 'user-error)
4014 ;; Error when trying to swap an headline element and a non-headline
4015 ;; element.
4016 (should-error
4017 (org-test-with-temp-text "Test.\n<point>* Head 1"
4018 (org-drag-element-backward))
4019 :type 'error)
4020 ;; Error when called before first element.
4021 (should-error
4022 (org-test-with-temp-text "\n<point>"
4023 (org-drag-element-backward))
4024 :type 'user-error)
4025 ;; Preserve visibility of elements and their contents.
4026 (should
4027 (equal '((63 . 82) (26 . 48))
4028 (org-test-with-temp-text "
4029 #+BEGIN_CENTER
4030 Text.
4031 #+END_CENTER
4032 - item 1
4033 #+BEGIN_QUOTE
4034 Text.
4035 #+END_QUOTE"
4036 (while (search-forward "BEGIN_" nil t) (org-cycle))
4037 (search-backward "- item 1")
4038 (org-drag-element-backward)
4039 (mapcar (lambda (ov) (cons (overlay-start ov) (overlay-end ov)))
4040 (overlays-in (point-min) (point-max))))))
4041 ;; Pathological case: handle call with point in blank lines right
4042 ;; after a headline.
4043 (should
4044 (equal "* H2\n\n* H1\nText\n"
4045 (org-test-with-temp-text "* H1\nText\n* H2\n\n<point>"
4046 (org-drag-element-backward)
4047 (buffer-string)))))
4049 (ert-deftest test-org/drag-element-forward ()
4050 "Test `org-drag-element-forward' specifications."
4051 ;; 1. Error when trying to move first element of buffer.
4052 (org-test-with-temp-text "Paragraph 1.\n\nParagraph 2."
4053 (goto-line 3)
4054 (should-error (org-drag-element-forward)))
4055 ;; 2. Error when trying to swap nested elements.
4056 (org-test-with-temp-text "#+BEGIN_CENTER\nTest.\n#+END_CENTER"
4057 (forward-line)
4058 (should-error (org-drag-element-forward)))
4059 ;; 3. Error when trying to swap a non-headline element and an
4060 ;; headline.
4061 (org-test-with-temp-text "Test.\n* Head 1"
4062 (should-error (org-drag-element-forward)))
4063 ;; 4. Error when called before first element.
4064 (should-error
4065 (org-test-with-temp-text "\n"
4066 (forward-line)
4067 (org-drag-element-backward))
4068 :type 'user-error)
4069 ;; 5. Otherwise, swap elements, preserving column and blank lines
4070 ;; between elements.
4071 (org-test-with-temp-text "Paragraph 1\n\n\nPara2\n\nPara3"
4072 (search-forward "graph")
4073 (org-drag-element-forward)
4074 (should (equal (buffer-string) "Para2\n\n\nParagraph 1\n\nPara3"))
4075 (should (looking-at " 1")))
4076 ;; 5. Preserve visibility of elements and their contents.
4077 (org-test-with-temp-text "
4078 #+BEGIN_CENTER
4079 Text.
4080 #+END_CENTER
4081 - item 1
4082 #+BEGIN_QUOTE
4083 Text.
4084 #+END_QUOTE"
4085 (while (search-forward "BEGIN_" nil t) (org-cycle))
4086 (search-backward "#+BEGIN_CENTER")
4087 (org-drag-element-forward)
4088 (should
4089 (equal
4090 '((63 . 82) (26 . 48))
4091 (mapcar (lambda (ov) (cons (overlay-start ov) (overlay-end ov)))
4092 (overlays-in (point-min) (point-max)))))))
4094 (ert-deftest test-org/next-block ()
4095 "Test `org-next-block' specifications."
4096 ;; Regular test.
4097 (should
4098 (org-test-with-temp-text "Paragraph\n#+BEGIN_CENTER\ncontents\n#+END_CENTER"
4099 (org-next-block 1)
4100 (looking-at "#\\+BEGIN_CENTER")))
4101 ;; Ignore case.
4102 (should
4103 (org-test-with-temp-text "Paragraph\n#+begin_center\ncontents\n#+end_center"
4104 (let ((case-fold-search nil))
4105 (org-next-block 1)
4106 (looking-at "#\\+begin_center"))))
4107 ;; Ignore current line.
4108 (should
4109 (org-test-with-temp-text
4110 "#+BEGIN_QUOTE\n#+END_QUOTE\n#+BEGIN_CENTER\n#+END_CENTER"
4111 (org-next-block 1)
4112 (looking-at "#\\+BEGIN_CENTER")))
4113 ;; Throw an error when no block is found.
4114 (should-error
4115 (org-test-with-temp-text "Paragraph"
4116 (org-next-block 1)))
4117 ;; With an argument, skip many blocks at once.
4118 (should
4119 (org-test-with-temp-text
4120 "Start\n#+BEGIN_CENTER\nA\n#+END_CENTER\n#+BEGIN_QUOTE\nB\n#+END_QUOTE"
4121 (org-next-block 2)
4122 (looking-at "#\\+BEGIN_QUOTE")))
4123 ;; With optional argument BLOCK-REGEXP, filter matched blocks.
4124 (should
4125 (org-test-with-temp-text
4126 "Start\n#+BEGIN_CENTER\nA\n#+END_CENTER\n#+BEGIN_QUOTE\nB\n#+END_QUOTE"
4127 (org-next-block 1 nil "^[ \t]*#\\+BEGIN_QUOTE")
4128 (looking-at "#\\+BEGIN_QUOTE")))
4129 ;; Optional argument is also case-insensitive.
4130 (should
4131 (org-test-with-temp-text
4132 "Start\n#+BEGIN_CENTER\nA\n#+END_CENTER\n#+begin_quote\nB\n#+end_quote"
4133 (let ((case-fold-search nil))
4134 (org-next-block 1 nil "^[ \t]*#\\+BEGIN_QUOTE")
4135 (looking-at "#\\+begin_quote")))))
4137 (ert-deftest test-org/insert-structure-template ()
4138 "Test `org-insert-structure-template'."
4139 ;; Test in empty buffer.
4140 (should
4141 (string= "#+begin_foo\n#+end_foo\n"
4142 (org-test-with-temp-text ""
4143 (org-insert-structure-template "foo")
4144 (buffer-string))))
4145 ;; Test with multiple lines in buffer.
4146 (should
4147 (string= "#+begin_foo\nI'm a paragraph\n#+end_foo\n\nI'm a second paragraph"
4148 (org-test-with-temp-text "I'm a paragraph\n\nI'm a second paragraph"
4149 (transient-mark-mode 1)
4150 (org-mark-element)
4151 (org-insert-structure-template "foo")
4152 (buffer-string))))
4153 ;; Mark only the current line.
4154 (should
4155 (string= "#+begin_foo\nI'm a paragraph\n#+end_foo\n\nI'm a second paragraph"
4156 (org-test-with-temp-text "I'm a paragraph\n\nI'm a second paragraph"
4157 (transient-mark-mode 1)
4158 (set-mark (point-min))
4159 (end-of-line)
4160 (org-insert-structure-template "foo")
4161 (buffer-string))))
4162 ;; Middle of paragraph.
4163 (should
4164 (string= "p1\n#+begin_foo\np2\n#+end_foo\np3"
4165 (org-test-with-temp-text "p1\n<point>p2\np3"
4166 (set-mark (line-beginning-position))
4167 (end-of-line)
4168 (activate-mark)
4169 (org-insert-structure-template "foo")
4170 (buffer-string))))
4171 ;; Test with text in buffer, no region, no final newline.
4172 (should
4173 (string= "#+begin_foo\nI'm a paragraph.\n#+end_foo\n"
4174 (org-test-with-temp-text "I'm a paragraph."
4175 (org-mark-element)
4176 (org-insert-structure-template "foo")
4177 (buffer-string))))
4178 ;; Test with text in buffer and region set.
4179 (should
4180 (string= "#+begin_foo\nI'm a paragraph\n\nI'm a second paragrah\n#+end_foo\n"
4181 (org-test-with-temp-text "I'm a paragraph\n\nI'm a second paragrah"
4182 (set-mark (point))
4183 (goto-char (point-max))
4184 (org-insert-structure-template "foo")
4185 (buffer-string))))
4186 ;; Test with example escaping.
4187 (should
4188 (string= "#+begin_example\n,* Heading\n#+end_example\n"
4189 (org-test-with-temp-text "* Heading"
4190 (org-mark-element)
4191 (org-insert-structure-template "example")
4192 (buffer-string))))
4193 ;; Test with indentation.
4194 (should
4195 (string= " #+begin_foo\n This is a paragraph\n #+end_foo\n"
4196 (org-test-with-temp-text " This is a paragraph"
4197 (org-mark-element)
4198 (org-insert-structure-template "foo")
4199 (buffer-string))))
4200 (should
4201 (string= " #+begin_foo\n Line 1\n Line2\n #+end_foo\n"
4202 (org-test-with-temp-text " Line 1\n Line2"
4203 (org-mark-element)
4204 (org-insert-structure-template "foo")
4205 (buffer-string))))
4206 ;; Test point location.
4207 (should
4208 (string= "#+begin_foo\n"
4209 (org-test-with-temp-text ""
4210 (org-insert-structure-template "foo")
4211 (buffer-substring (point-min) (point)))))
4212 (should
4213 (string= "#+begin_src "
4214 (org-test-with-temp-text ""
4215 (org-insert-structure-template "src")
4216 (buffer-substring (point-min) (point))))))
4218 (ert-deftest test-org/previous-block ()
4219 "Test `org-previous-block' specifications."
4220 ;; Regular test.
4221 (should
4222 (org-test-with-temp-text "#+BEGIN_CENTER\ncontents\n#+END_CENTER\n<point>"
4223 (org-previous-block 1)
4224 (looking-at "#\\+BEGIN_CENTER")))
4225 ;; Ignore case.
4226 (should
4227 (org-test-with-temp-text "#+begin_center\ncontents\n#+end_center\n<point>"
4228 (let ((case-fold-search nil))
4229 (org-previous-block 1)
4230 (looking-at "#\\+begin_center"))))
4231 ;; Ignore current line.
4232 (should
4233 (org-test-with-temp-text
4234 "#+BEGIN_QUOTE\n#+END_QUOTE\n#+BEGIN_CENTER<point>\n#+END_CENTER"
4235 (org-previous-block 1)
4236 (looking-at "#\\+BEGIN_QUOTE")))
4237 ;; Throw an error when no block is found.
4238 (should-error
4239 (org-test-with-temp-text "Paragraph<point>"
4240 (org-previous-block 1)))
4241 ;; With an argument, skip many blocks at once.
4242 (should
4243 (org-test-with-temp-text
4244 "#+BEGIN_CENTER\nA\n#+END_CENTER\n#+BEGIN_QUOTE\nB\n#+END_QUOTE\n<point>"
4245 (org-previous-block 2)
4246 (looking-at "#\\+BEGIN_CENTER")))
4247 ;; With optional argument BLOCK-REGEXP, filter matched blocks.
4248 (should
4249 (org-test-with-temp-text
4250 "#+BEGIN_CENTER\nA\n#+END_CENTER\n#+BEGIN_QUOTE\nB\n#+END_QUOTE\n<point>"
4251 (org-previous-block 1 "^[ \t]*#\\+BEGIN_QUOTE")
4252 (looking-at "#\\+BEGIN_QUOTE")))
4253 ;; Optional argument is also case-insensitive.
4254 (should
4255 (org-test-with-temp-text
4256 "#+BEGIN_CENTER\nA\n#+END_CENTER\n#+begin_quote\nB\n#+end_quote\n<point>"
4257 (let ((case-fold-search nil))
4258 (org-next-block 1 "^[ \t]*#\\+BEGIN_QUOTE")
4259 (looking-at "#\\+begin_quote")))))
4262 ;;; Outline structure
4264 (ert-deftest test-org/demote ()
4265 "Test `org-demote' specifications."
4266 ;; Add correct number of stars according to `org-odd-levels-only'.
4267 (should
4268 (= 2
4269 (org-test-with-temp-text "* H"
4270 (let ((org-odd-levels-only nil)) (org-demote))
4271 (org-current-level))))
4272 (should
4273 (= 3
4274 (org-test-with-temp-text "* H"
4275 (let ((org-odd-levels-only t)) (org-demote))
4276 (org-current-level))))
4277 ;; When `org-auto-align-tags' is non-nil, move tags accordingly.
4278 (should
4279 (org-test-with-temp-text "* H :tag:"
4280 (let ((org-tags-column 10)
4281 (org-auto-align-tags t)
4282 (org-odd-levels-only nil))
4283 (org-demote))
4284 (org-move-to-column 10)
4285 (looking-at-p ":tag:$")))
4286 (should-not
4287 (org-test-with-temp-text "* H :tag:"
4288 (let ((org-tags-column 10)
4289 (org-auto-align-tags nil)
4290 (org-odd-levels-only nil))
4291 (org-demote))
4292 (org-move-to-column 10)
4293 (looking-at-p ":tag:$")))
4294 ;; When `org-adapt-indentation' is non-nil, always indent planning
4295 ;; info and property drawers accordingly.
4296 (should
4297 (= 3
4298 (org-test-with-temp-text "* H\n SCHEDULED: <2014-03-04 tue.>"
4299 (let ((org-odd-levels-only nil)
4300 (org-adapt-indentation t))
4301 (org-demote))
4302 (forward-line)
4303 (org-get-indentation))))
4304 (should
4305 (= 3
4306 (org-test-with-temp-text "* H\n :PROPERTIES:\n :FOO: Bar\n :END:"
4307 (let ((org-odd-levels-only nil)
4308 (org-adapt-indentation t))
4309 (org-demote))
4310 (forward-line)
4311 (org-get-indentation))))
4312 (should-not
4313 (= 3
4314 (org-test-with-temp-text "* H\n SCHEDULED: <2014-03-04 tue.>"
4315 (let ((org-odd-levels-only nil)
4316 (org-adapt-indentation nil))
4317 (org-demote))
4318 (forward-line)
4319 (org-get-indentation))))
4320 ;; When `org-adapt-indentation' is non-nil, shift all lines in
4321 ;; section accordingly. Ignore, however, footnote definitions and
4322 ;; inlinetasks boundaries.
4323 (should
4324 (= 3
4325 (org-test-with-temp-text "* H\n Paragraph"
4326 (let ((org-odd-levels-only nil)
4327 (org-adapt-indentation t))
4328 (org-demote))
4329 (forward-line)
4330 (org-get-indentation))))
4331 (should
4332 (= 2
4333 (org-test-with-temp-text "* H\n Paragraph"
4334 (let ((org-odd-levels-only nil)
4335 (org-adapt-indentation nil))
4336 (org-demote))
4337 (forward-line)
4338 (org-get-indentation))))
4339 (should
4340 (zerop
4341 (org-test-with-temp-text "* H\n[fn:1] def line 1\ndef line 2"
4342 (let ((org-odd-levels-only nil)
4343 (org-adapt-indentation t))
4344 (org-demote))
4345 (goto-char (point-max))
4346 (org-get-indentation))))
4347 (should
4348 (= 3
4349 (org-test-with-temp-text "* H\n[fn:1] Def.\n\n\n After def."
4350 (let ((org-odd-levels-only nil)
4351 (org-adapt-indentation t))
4352 (org-demote))
4353 (goto-char (point-max))
4354 (org-get-indentation))))
4355 (when (featurep 'org-inlinetask)
4356 (should
4357 (zerop
4358 (let ((org-inlinetask-min-level 5)
4359 (org-adapt-indentation t))
4360 (org-test-with-temp-text "* H\n***** I\n***** END"
4361 (org-demote)
4362 (forward-line)
4363 (org-get-indentation))))))
4364 (when (featurep 'org-inlinetask)
4365 (should
4366 (= 3
4367 (let ((org-inlinetask-min-level 5)
4368 (org-adapt-indentation t))
4369 (org-test-with-temp-text "* H\n***** I\n Contents\n***** END"
4370 (org-demote)
4371 (forward-line 2)
4372 (org-get-indentation))))))
4373 ;; Ignore contents of source blocks or example blocks when
4374 ;; indentation should be preserved (through
4375 ;; `org-src-preserve-indentation' or "-i" flag).
4376 (should-not
4377 (zerop
4378 (org-test-with-temp-text "* H\n#+BEGIN_SRC emacs-lisp\n(+ 1 1)\n#+END_SRC"
4379 (let ((org-adapt-indentation t)
4380 (org-src-preserve-indentation nil))
4381 (org-demote))
4382 (forward-line 2)
4383 (org-get-indentation))))
4384 (should
4385 (zerop
4386 (org-test-with-temp-text "* H\n#+BEGIN_EXAMPLE\n(+ 1 1)\n#+END_EXAMPLE"
4387 (let ((org-adapt-indentation t)
4388 (org-src-preserve-indentation t))
4389 (org-demote))
4390 (forward-line 2)
4391 (org-get-indentation))))
4392 (should
4393 (zerop
4394 (org-test-with-temp-text "* H\n#+BEGIN_SRC emacs-lisp\n(+ 1 1)\n#+END_SRC"
4395 (let ((org-adapt-indentation t)
4396 (org-src-preserve-indentation t))
4397 (org-demote))
4398 (forward-line 2)
4399 (org-get-indentation))))
4400 (should
4401 (zerop
4402 (org-test-with-temp-text
4403 "* H\n#+BEGIN_SRC emacs-lisp -i\n(+ 1 1)\n#+END_SRC"
4404 (let ((org-adapt-indentation t)
4405 (org-src-preserve-indentation nil))
4406 (org-demote))
4407 (forward-line 2)
4408 (org-get-indentation)))))
4410 (ert-deftest test-org/promote ()
4411 "Test `org-promote' specifications."
4412 ;; Return an error if headline is to be promoted to level 0, unless
4413 ;; `org-allow-promoting-top-level-subtree' is non-nil, in which case
4414 ;; headline becomes a comment.
4415 (should-error
4416 (org-test-with-temp-text "* H"
4417 (let ((org-allow-promoting-top-level-subtree nil)) (org-promote))))
4418 (should
4419 (equal "# H"
4420 (org-test-with-temp-text "* H"
4421 (let ((org-allow-promoting-top-level-subtree t)) (org-promote))
4422 (buffer-string))))
4423 ;; Remove correct number of stars according to
4424 ;; `org-odd-levels-only'.
4425 (should
4426 (= 2
4427 (org-test-with-temp-text "*** H"
4428 (let ((org-odd-levels-only nil)) (org-promote))
4429 (org-current-level))))
4430 (should
4431 (= 1
4432 (org-test-with-temp-text "*** H"
4433 (let ((org-odd-levels-only t)) (org-promote))
4434 (org-current-level))))
4435 ;; When `org-auto-align-tags' is non-nil, move tags accordingly.
4436 (should
4437 (org-test-with-temp-text "** H :tag:"
4438 (let ((org-tags-column 10)
4439 (org-auto-align-tags t)
4440 (org-odd-levels-only nil))
4441 (org-promote))
4442 (org-move-to-column 10)
4443 (looking-at-p ":tag:$")))
4444 (should-not
4445 (org-test-with-temp-text "** H :tag:"
4446 (let ((org-tags-column 10)
4447 (org-auto-align-tags nil)
4448 (org-odd-levels-only nil))
4449 (org-promote))
4450 (org-move-to-column 10)
4451 (looking-at-p ":tag:$")))
4452 ;; When `org-adapt-indentation' is non-nil, always indent planning
4453 ;; info and property drawers.
4454 (should
4455 (= 2
4456 (org-test-with-temp-text "** H\n SCHEDULED: <2014-03-04 tue.>"
4457 (let ((org-odd-levels-only nil)
4458 (org-adapt-indentation t))
4459 (org-promote))
4460 (forward-line)
4461 (org-get-indentation))))
4462 (should
4463 (= 2
4464 (org-test-with-temp-text "** H\n :PROPERTIES:\n :FOO: Bar\n :END:"
4465 (let ((org-odd-levels-only nil)
4466 (org-adapt-indentation t))
4467 (org-promote))
4468 (forward-line)
4469 (org-get-indentation))))
4470 (should-not
4471 (= 2
4472 (org-test-with-temp-text "** H\n SCHEDULED: <2014-03-04 tue.>"
4473 (let ((org-odd-levels-only nil)
4474 (org-adapt-indentation nil))
4475 (org-promote))
4476 (forward-line)
4477 (org-get-indentation))))
4478 ;; When `org-adapt-indentation' is non-nil, shift all lines in
4479 ;; section accordingly. Ignore, however, footnote definitions and
4480 ;; inlinetasks boundaries.
4481 (should
4482 (= 2
4483 (org-test-with-temp-text "** H\n Paragraph"
4484 (let ((org-odd-levels-only nil)
4485 (org-adapt-indentation t))
4486 (org-promote))
4487 (forward-line)
4488 (org-get-indentation))))
4489 (should-not
4490 (= 2
4491 (org-test-with-temp-text "** H\n Paragraph"
4492 (let ((org-odd-levels-only nil)
4493 (org-adapt-indentation nil))
4494 (org-promote))
4495 (forward-line)
4496 (org-get-indentation))))
4497 (should
4498 (= 2
4499 (org-test-with-temp-text "** H\n Paragraph\n[fn:1] line1\nline2"
4500 (let ((org-odd-levels-only nil)
4501 (org-adapt-indentation t))
4502 (org-promote))
4503 (forward-line)
4504 (org-get-indentation))))
4505 (when (featurep 'org-inlinetask)
4506 (should
4507 (zerop
4508 (let ((org-inlinetask-min-level 5)
4509 (org-adapt-indentation t))
4510 (org-test-with-temp-text "** H\n***** I\n***** END"
4511 (org-promote)
4512 (forward-line)
4513 (org-get-indentation))))))
4514 (when (featurep 'org-inlinetask)
4515 (should
4516 (= 2
4517 (let ((org-inlinetask-min-level 5)
4518 (org-adapt-indentation t))
4519 (org-test-with-temp-text "** H\n***** I\n Contents\n***** END"
4520 (org-promote)
4521 (forward-line 2)
4522 (org-get-indentation))))))
4523 ;; Give up shifting if it would break document's structure
4524 ;; otherwise.
4525 (should
4526 (= 3
4527 (org-test-with-temp-text "** H\n Paragraph\n [fn:1] Def."
4528 (let ((org-odd-levels-only nil)
4529 (org-adapt-indentation t))
4530 (org-promote))
4531 (forward-line)
4532 (org-get-indentation))))
4533 (should
4534 (= 3
4535 (org-test-with-temp-text "** H\n Paragraph\n * list."
4536 (let ((org-odd-levels-only nil)
4537 (org-adapt-indentation t))
4538 (org-promote))
4539 (forward-line)
4540 (org-get-indentation))))
4541 ;; Ignore contents of source blocks or example blocks when
4542 ;; indentation should be preserved (through
4543 ;; `org-src-preserve-indentation' or "-i" flag).
4544 (should-not
4545 (zerop
4546 (org-test-with-temp-text
4547 "** H\n #+BEGIN_SRC emacs-lisp\n(+ 1 1)\n #+END_SRC"
4548 (let ((org-adapt-indentation t)
4549 (org-src-preserve-indentation nil)
4550 (org-odd-levels-only nil))
4551 (org-promote))
4552 (forward-line)
4553 (org-get-indentation))))
4554 (should
4555 (zerop
4556 (org-test-with-temp-text
4557 "** H\n #+BEGIN_EXAMPLE\nContents\n #+END_EXAMPLE"
4558 (let ((org-adapt-indentation t)
4559 (org-src-preserve-indentation t)
4560 (org-odd-levels-only nil))
4561 (org-promote))
4562 (forward-line)
4563 (org-get-indentation))))
4564 (should
4565 (zerop
4566 (org-test-with-temp-text
4567 "** H\n #+BEGIN_SRC emacs-lisp\n(+ 1 1)\n #+END_SRC"
4568 (let ((org-adapt-indentation t)
4569 (org-src-preserve-indentation t)
4570 (org-odd-levels-only nil))
4571 (org-promote))
4572 (forward-line)
4573 (org-get-indentation))))
4574 (should
4575 (zerop
4576 (org-test-with-temp-text
4577 "** H\n #+BEGIN_SRC emacs-lisp -i\n(+ 1 1)\n #+END_SRC"
4578 (let ((org-adapt-indentation t)
4579 (org-src-preserve-indentation nil)
4580 (org-odd-levels-only nil))
4581 (org-promote))
4582 (forward-line)
4583 (org-get-indentation)))))
4585 (ert-deftest test-org/org-get-valid-level ()
4586 "Test function `org-get-valid-level' specifications."
4587 (let ((org-odd-levels-only nil))
4588 (should (equal 1 (org-get-valid-level 0 0)))
4589 (should (equal 1 (org-get-valid-level 0 1)))
4590 (should (equal 2 (org-get-valid-level 0 2)))
4591 (should (equal 3 (org-get-valid-level 0 3)))
4592 (should (equal 1 (org-get-valid-level 1 0)))
4593 (should (equal 2 (org-get-valid-level 1 1)))
4594 (should (equal 23 (org-get-valid-level 1 22)))
4595 (should (equal 1 (org-get-valid-level 1 -1)))
4596 (should (equal 1 (org-get-valid-level 2 -1))))
4597 (let ((org-odd-levels-only t))
4598 (should (equal 1 (org-get-valid-level 0 0)))
4599 (should (equal 1 (org-get-valid-level 0 1)))
4600 (should (equal 3 (org-get-valid-level 0 2)))
4601 (should (equal 5 (org-get-valid-level 0 3)))
4602 (should (equal 1 (org-get-valid-level 1 0)))
4603 (should (equal 3 (org-get-valid-level 1 1)))
4604 (should (equal 3 (org-get-valid-level 2 1)))
4605 (should (equal 5 (org-get-valid-level 3 1)))
4606 (should (equal 5 (org-get-valid-level 4 1)))
4607 (should (equal 43 (org-get-valid-level 1 21)))
4608 (should (equal 1 (org-get-valid-level 1 -1)))
4609 (should (equal 1 (org-get-valid-level 2 -1)))
4610 (should (equal 1 (org-get-valid-level 3 -1)))
4611 (should (equal 3 (org-get-valid-level 4 -1)))
4612 (should (equal 3 (org-get-valid-level 5 -1)))))
4615 ;;; Planning
4617 (ert-deftest test-org/at-planning-p ()
4618 "Test `org-at-planning-p' specifications."
4619 ;; Regular test.
4620 (should
4621 (org-test-with-temp-text "* Headline\n<point>DEADLINE: <2014-03-04 tue.>"
4622 (org-at-planning-p)))
4623 (should-not
4624 (org-test-with-temp-text "DEADLINE: <2014-03-04 tue.>"
4625 (org-at-planning-p)))
4626 ;; Correctly find planning attached to inlinetasks.
4627 (when (featurep 'org-inlinetask)
4628 (should
4629 (org-test-with-temp-text
4630 "*** Inlinetask\n<point>DEADLINE: <2014-03-04 tue.>\n*** END"
4631 (let ((org-inlinetask-min-level 3)) (org-at-planning-p))))
4632 (should-not
4633 (org-test-with-temp-text
4634 "*** Inlinetask\n<point>DEADLINE: <2014-03-04 tue.>"
4635 (let ((org-inlinetask-min-level 3)) (org-at-planning-p))))
4636 (should-not
4637 (org-test-with-temp-text
4638 "* Headline\n*** Inlinetask\n<point>DEADLINE: <2014-03-04 tue.>"
4639 (let ((org-inlinetask-min-level 3)) (org-at-planning-p))))
4640 (should-not
4641 (org-test-with-temp-text
4642 "* Headline\n*** Inlinetask\n*** END\n<point>DEADLINE: <2014-03-04 tue.>"
4643 (let ((org-inlinetask-min-level 3)) (org-at-planning-p))))))
4645 (ert-deftest test-org/add-planning-info ()
4646 "Test `org-add-planning-info'."
4647 ;; Create deadline when `org-adapt-indentation' is non-nil.
4648 (should
4649 (equal "* H\n DEADLINE: <2015-06-25>\nParagraph"
4650 (org-test-with-temp-text "* H\nParagraph<point>"
4651 (let ((org-adapt-indentation t))
4652 (org-add-planning-info 'deadline "<2015-06-25 Thu>"))
4653 (replace-regexp-in-string
4654 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4655 nil nil 1))))
4656 ;; Create deadline when `org-adapt-indentation' is nil.
4657 (should
4658 (equal "* H\nDEADLINE: <2015-06-25>\nParagraph"
4659 (org-test-with-temp-text "* H\nParagraph<point>"
4660 (let ((org-adapt-indentation nil))
4661 (org-add-planning-info 'deadline "<2015-06-25 Thu>"))
4662 (replace-regexp-in-string
4663 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4664 nil nil 1))))
4665 ;; Update deadline when `org-adapt-indentation' is non-nil.
4666 (should
4667 (equal "* H\n DEADLINE: <2015-06-25>\nParagraph"
4668 (org-test-with-temp-text "\
4670 DEADLINE: <2015-06-24 Wed>
4671 Paragraph<point>"
4672 (let ((org-adapt-indentation t))
4673 (org-add-planning-info 'deadline "<2015-06-25 Thu>"))
4674 (replace-regexp-in-string
4675 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4676 nil nil 1))))
4677 ;; Update deadline when `org-adapt-indentation' is nil.
4678 (should
4679 (equal "* H\nDEADLINE: <2015-06-25>\nParagraph"
4680 (org-test-with-temp-text "\
4682 DEADLINE: <2015-06-24 Wed>
4683 Paragraph<point>"
4684 (let ((org-adapt-indentation nil))
4685 (org-add-planning-info 'deadline "<2015-06-25 Thu>"))
4686 (replace-regexp-in-string
4687 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4688 nil nil 1))))
4689 ;; Schedule when `org-adapt-indentation' is non-nil.
4690 (should
4691 (equal "* H\n SCHEDULED: <2015-06-25>\nParagraph"
4692 (org-test-with-temp-text "* H\nParagraph<point>"
4693 (let ((org-adapt-indentation t))
4694 (org-add-planning-info 'scheduled "<2015-06-25 Thu>"))
4695 (replace-regexp-in-string
4696 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4697 nil nil 1))))
4698 ;; Schedule when `org-adapt-indentation' is nil.
4699 (should
4700 (equal "* H\nSCHEDULED: <2015-06-25>\nParagraph"
4701 (org-test-with-temp-text "* H\nParagraph<point>"
4702 (let ((org-adapt-indentation nil))
4703 (org-add-planning-info 'scheduled "<2015-06-25 Thu>"))
4704 (replace-regexp-in-string
4705 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4706 nil nil 1))))
4707 ;; Add deadline when scheduled.
4708 (should
4709 (equal "\
4711 DEADLINE: <2015-06-25> SCHEDULED: <2015-06-24>
4712 Paragraph"
4713 (org-test-with-temp-text "\
4715 SCHEDULED: <2015-06-24 Wed>
4716 Paragraph<point>"
4717 (let ((org-adapt-indentation t))
4718 (org-add-planning-info 'deadline "<2015-06-25 Thu>"))
4719 (replace-regexp-in-string
4720 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4721 nil nil 1))))
4722 ;; Remove middle entry.
4723 (should
4724 (equal "\
4726 CLOSED: [2015-06-24] SCHEDULED: <2015-06-24>
4727 Paragraph"
4728 (org-test-with-temp-text "\
4730 CLOSED: [2015-06-24 Wed] DEADLINE: <2015-06-25 Thu> SCHEDULED: <2015-06-24 Wed>
4731 Paragraph<point>"
4732 (let ((org-adapt-indentation t))
4733 (org-add-planning-info nil nil 'deadline))
4734 (replace-regexp-in-string
4735 "\\( [.A-Za-z]+\\)[]>]" "" (buffer-string)
4736 nil nil 1))))
4737 ;; Remove last entry and then middle entry (order should not
4738 ;; matter).
4739 (should
4740 (equal "\
4742 CLOSED: [2015-06-24]
4743 Paragraph"
4744 (org-test-with-temp-text "\
4746 CLOSED: [2015-06-24 Wed] DEADLINE: <2015-06-25 Thu> SCHEDULED: <2015-06-24 Wed>
4747 Paragraph<point>"
4748 (let ((org-adapt-indentation t))
4749 (org-add-planning-info nil nil 'scheduled 'deadline))
4750 (replace-regexp-in-string
4751 "\\( [.A-Za-z]+\\)[]>]" "" (buffer-string)
4752 nil nil 1))))
4753 ;; Remove closed when `org-adapt-indentation' is non-nil.
4754 (should
4755 (equal "* H\n DEADLINE: <2015-06-25>\nParagraph"
4756 (org-test-with-temp-text "\
4758 CLOSED: [2015-06-25 Thu] DEADLINE: <2015-06-25 Thu>
4759 Paragraph<point>"
4760 (let ((org-adapt-indentation t))
4761 (org-add-planning-info nil nil 'closed))
4762 (replace-regexp-in-string
4763 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4764 nil nil 1))))
4765 (should
4766 (equal "* H\n Paragraph"
4767 (org-test-with-temp-text "\
4769 CLOSED: [2015-06-25 Thu]
4770 Paragraph<point>"
4771 (let ((org-adapt-indentation t))
4772 (org-add-planning-info nil nil 'closed))
4773 (replace-regexp-in-string
4774 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4775 nil nil 1))))
4776 ;; Remove closed when `org-adapt-indentation' is nil.
4777 (should
4778 (equal "* H\nDEADLINE: <2015-06-25>\nParagraph"
4779 (org-test-with-temp-text "\
4781 CLOSED: [2015-06-25 Thu] DEADLINE: <2015-06-25 Thu>
4782 Paragraph<point>"
4783 (let ((org-adapt-indentation nil))
4784 (org-add-planning-info nil nil 'closed))
4785 (replace-regexp-in-string
4786 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4787 nil nil 1))))
4788 (should
4789 (equal "* H\nParagraph"
4790 (org-test-with-temp-text "\
4792 CLOSED: [2015-06-25 Thu]
4793 Paragraph<point>"
4794 (let ((org-adapt-indentation nil))
4795 (org-add-planning-info nil nil 'closed))
4796 (replace-regexp-in-string
4797 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4798 nil nil 1))))
4799 ;; Remove closed entry and delete empty line.
4800 (should
4801 (equal "\
4803 Paragraph"
4804 (org-test-with-temp-text "\
4806 CLOSED: [2015-06-24 Wed]
4807 Paragraph<point>"
4808 (let ((org-adapt-indentation t))
4809 (org-add-planning-info nil nil 'closed))
4810 (replace-regexp-in-string
4811 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4812 nil nil 1))))
4813 ;; Remove one entry and update another.
4814 (should
4815 (equal "* H\n DEADLINE: <2015-06-25>\nParagraph"
4816 (org-test-with-temp-text "\
4818 SCHEDULED: <2015-06-23 Tue> DEADLINE: <2015-06-24 Wed>
4819 Paragraph<point>"
4820 (let ((org-adapt-indentation t))
4821 (org-add-planning-info 'deadline "<2015-06-25 Thu>" 'scheduled))
4822 (replace-regexp-in-string
4823 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4824 nil nil 1)))))
4826 (ert-deftest test-org/deadline ()
4827 "Test `org-deadline' specifications."
4828 ;; Insert a new value or replace existing one.
4829 (should
4830 (equal "* H\nDEADLINE: <2012-03-29>\n"
4831 (org-test-with-temp-text "* H"
4832 (let ((org-adapt-indentation nil)
4833 (org-last-inserted-timestamp nil))
4834 (org-deadline nil "<2012-03-29 Tue>"))
4835 (replace-regexp-in-string
4836 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4837 nil nil 1))))
4838 (should
4839 (equal "* H\nDEADLINE: <2014-03-04>"
4840 (org-test-with-temp-text "* H\nDEADLINE: <2012-03-29>"
4841 (let ((org-adapt-indentation nil)
4842 (org-last-inserted-timestamp nil))
4843 (org-deadline nil "<2014-03-04 Thu>"))
4844 (replace-regexp-in-string
4845 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4846 nil nil 1))))
4847 ;; Accept delta time, e.g., "+2d".
4848 (should
4849 (equal "* H\nDEADLINE: <2015-03-04>\n"
4850 (cl-letf (((symbol-function 'current-time)
4851 (lambda (&rest args)
4852 (apply #'encode-time
4853 (org-parse-time-string "2014-03-04")))))
4854 (org-test-with-temp-text "* H"
4855 (let ((org-adapt-indentation nil)
4856 (org-last-inserted-timestamp nil))
4857 (org-deadline nil "+1y"))
4858 (replace-regexp-in-string
4859 "\\( [.A-Za-z]+\\)>" "" (buffer-string) nil nil 1)))))
4860 ;; Preserve repeater.
4861 (should
4862 (equal "* H\nDEADLINE: <2012-03-29 +2y>\n"
4863 (org-test-with-temp-text "* H"
4864 (let ((org-adapt-indentation nil)
4865 (org-last-inserted-timestamp nil))
4866 (org-deadline nil "<2012-03-29 Tue +2y>"))
4867 (replace-regexp-in-string
4868 "\\( [.A-Za-z]+\\) " "" (buffer-string) nil nil 1))))
4869 ;; Remove CLOSED keyword, if any.
4870 (should
4871 (equal "* H\nDEADLINE: <2012-03-29>"
4872 (org-test-with-temp-text "* H\nCLOSED: [2017-01-25 Wed]"
4873 (let ((org-adapt-indentation nil)
4874 (org-last-inserted-timestamp nil))
4875 (org-deadline nil "<2012-03-29 Tue>"))
4876 (replace-regexp-in-string
4877 "\\( [.A-Za-z]+\\)>" "" (buffer-string) nil nil 1))))
4878 ;; With C-u argument, remove DEADLINE keyword.
4879 (should
4880 (equal "* H\n"
4881 (org-test-with-temp-text "* H\nDEADLINE: <2012-03-29>"
4882 (let ((org-adapt-indentation nil)
4883 (org-last-inserted-timestamp nil))
4884 (org-deadline '(4)))
4885 (buffer-string))))
4886 (should
4887 (equal "* H"
4888 (org-test-with-temp-text "* H"
4889 (let ((org-adapt-indentation nil)
4890 (org-last-inserted-timestamp nil))
4891 (org-deadline '(4)))
4892 (buffer-string))))
4893 ;; With C-u C-u argument, prompt for a delay cookie.
4894 (should
4895 (equal "* H\nDEADLINE: <2012-03-29 -705d>"
4896 (cl-letf (((symbol-function 'org-read-date)
4897 (lambda (&rest args)
4898 (apply #'encode-time
4899 (org-parse-time-string "2014-03-04")))))
4900 (org-test-with-temp-text "* H\nDEADLINE: <2012-03-29>"
4901 (let ((org-adapt-indentation nil)
4902 (org-last-inserted-timestamp nil))
4903 (org-deadline '(16)))
4904 (buffer-string)))))
4905 (should-error
4906 (cl-letf (((symbol-function 'org-read-date)
4907 (lambda (&rest args)
4908 (apply #'encode-time
4909 (org-parse-time-string "2014-03-04")))))
4910 (org-test-with-temp-text "* H"
4911 (let ((org-adapt-indentation nil)
4912 (org-last-inserted-timestamp nil))
4913 (org-deadline '(16)))
4914 (buffer-string))))
4915 ;; When a region is active and
4916 ;; `org-loop-over-headlines-in-active-region' is non-nil, insert the
4917 ;; same value in all headlines in region.
4918 (should
4919 (equal "* H1\nDEADLINE: <2012-03-29>\n* H2\nDEADLINE: <2012-03-29>\n"
4920 (org-test-with-temp-text "* H1\n* H2"
4921 (let ((org-adapt-indentation nil)
4922 (org-last-inserted-timestamp nil)
4923 (org-loop-over-headlines-in-active-region t))
4924 (transient-mark-mode 1)
4925 (push-mark (point) t t)
4926 (goto-char (point-max))
4927 (org-deadline nil "2012-03-29"))
4928 (replace-regexp-in-string
4929 "\\( [.A-Za-z]+\\)>" "" (buffer-string) nil nil 1))))
4930 (should-not
4931 (equal "* H1\nDEADLINE: <2012-03-29>\n* H2\nDEADLINE: <2012-03-29>\n"
4932 (org-test-with-temp-text "* H1\n* H2"
4933 (let ((org-adapt-indentation nil)
4934 (org-last-inserted-timestamp nil)
4935 (org-loop-over-headlines-in-active-region nil))
4936 (transient-mark-mode 1)
4937 (push-mark (point) t t)
4938 (goto-char (point-max))
4939 (org-deadline nil "2012-03-29"))
4940 (replace-regexp-in-string
4941 "\\( [.A-Za-z]+\\)>" "" (buffer-string) nil nil 1)))))
4943 (ert-deftest test-org/schedule ()
4944 "Test `org-schedule' specifications."
4945 ;; Insert a new value or replace existing one.
4946 (should
4947 (equal "* H\nSCHEDULED: <2012-03-29>\n"
4948 (org-test-with-temp-text "* H"
4949 (let ((org-adapt-indentation nil)
4950 (org-last-inserted-timestamp nil))
4951 (org-schedule nil "<2012-03-29 Tue>"))
4952 (replace-regexp-in-string
4953 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4954 nil nil 1))))
4955 (should
4956 (equal "* H\nSCHEDULED: <2014-03-04>"
4957 (org-test-with-temp-text "* H\nSCHEDULED: <2012-03-29>"
4958 (let ((org-adapt-indentation nil)
4959 (org-last-inserted-timestamp nil))
4960 (org-schedule nil "<2014-03-04 Thu>"))
4961 (replace-regexp-in-string
4962 "\\( [.A-Za-z]+\\)>" "" (buffer-string)
4963 nil nil 1))))
4964 ;; Accept delta time, e.g., "+2d".
4965 (should
4966 (equal "* H\nSCHEDULED: <2015-03-04>\n"
4967 (cl-letf (((symbol-function 'current-time)
4968 (lambda (&rest args)
4969 (apply #'encode-time
4970 (org-parse-time-string "2014-03-04")))))
4971 (org-test-with-temp-text "* H"
4972 (let ((org-adapt-indentation nil)
4973 (org-last-inserted-timestamp nil))
4974 (org-schedule nil "+1y"))
4975 (replace-regexp-in-string
4976 "\\( [.A-Za-z]+\\)>" "" (buffer-string) nil nil 1)))))
4977 ;; Preserve repeater.
4978 (should
4979 (equal "* H\nSCHEDULED: <2012-03-29 +2y>\n"
4980 (org-test-with-temp-text "* H"
4981 (let ((org-adapt-indentation nil)
4982 (org-last-inserted-timestamp nil))
4983 (org-schedule nil "<2012-03-29 Tue +2y>"))
4984 (replace-regexp-in-string
4985 "\\( [.A-Za-z]+\\) " "" (buffer-string) nil nil 1))))
4986 ;; Remove CLOSED keyword, if any.
4987 (should
4988 (equal "* H\nSCHEDULED: <2012-03-29>"
4989 (org-test-with-temp-text "* H\nCLOSED: [2017-01-25 Wed]"
4990 (let ((org-adapt-indentation nil)
4991 (org-last-inserted-timestamp nil))
4992 (org-schedule nil "<2012-03-29 Tue>"))
4993 (replace-regexp-in-string
4994 "\\( [.A-Za-z]+\\)>" "" (buffer-string) nil nil 1))))
4995 ;; With C-u argument, remove SCHEDULED keyword.
4996 (should
4997 (equal "* H\n"
4998 (org-test-with-temp-text "* H\nSCHEDULED: <2012-03-29>"
4999 (let ((org-adapt-indentation nil)
5000 (org-last-inserted-timestamp nil))
5001 (org-schedule '(4)))
5002 (buffer-string))))
5003 (should
5004 (equal "* H"
5005 (org-test-with-temp-text "* H"
5006 (let ((org-adapt-indentation nil)
5007 (org-last-inserted-timestamp nil))
5008 (org-schedule '(4)))
5009 (buffer-string))))
5010 ;; With C-u C-u argument, prompt for a delay cookie.
5011 (should
5012 (equal "* H\nSCHEDULED: <2012-03-29 -705d>"
5013 (cl-letf (((symbol-function 'org-read-date)
5014 (lambda (&rest args)
5015 (apply #'encode-time
5016 (org-parse-time-string "2014-03-04")))))
5017 (org-test-with-temp-text "* H\nSCHEDULED: <2012-03-29>"
5018 (let ((org-adapt-indentation nil)
5019 (org-last-inserted-timestamp nil))
5020 (org-schedule '(16)))
5021 (buffer-string)))))
5022 (should-error
5023 (cl-letf (((symbol-function 'org-read-date)
5024 (lambda (&rest args)
5025 (apply #'encode-time
5026 (org-parse-time-string "2014-03-04")))))
5027 (org-test-with-temp-text "* H"
5028 (let ((org-adapt-indentation nil)
5029 (org-last-inserted-timestamp nil))
5030 (org-schedule '(16)))
5031 (buffer-string))))
5032 ;; When a region is active and
5033 ;; `org-loop-over-headlines-in-active-region' is non-nil, insert the
5034 ;; same value in all headlines in region.
5035 (should
5036 (equal "* H1\nSCHEDULED: <2012-03-29>\n* H2\nSCHEDULED: <2012-03-29>\n"
5037 (org-test-with-temp-text "* H1\n* H2"
5038 (let ((org-adapt-indentation nil)
5039 (org-last-inserted-timestamp nil)
5040 (org-loop-over-headlines-in-active-region t))
5041 (transient-mark-mode 1)
5042 (push-mark (point) t t)
5043 (goto-char (point-max))
5044 (org-schedule nil "2012-03-29"))
5045 (replace-regexp-in-string
5046 "\\( [.A-Za-z]+\\)>" "" (buffer-string) nil nil 1))))
5047 (should-not
5048 (equal "* H1\nSCHEDULED: <2012-03-29>\n* H2\nSCHEDULED: <2012-03-29>\n"
5049 (org-test-with-temp-text "* H1\n* H2"
5050 (let ((org-adapt-indentation nil)
5051 (org-last-inserted-timestamp nil)
5052 (org-loop-over-headlines-in-active-region nil))
5053 (transient-mark-mode 1)
5054 (push-mark (point) t t)
5055 (goto-char (point-max))
5056 (org-schedule nil "2012-03-29"))
5057 (replace-regexp-in-string
5058 "\\( [.A-Za-z]+\\)>" "" (buffer-string) nil nil 1))))
5059 (should
5060 ;; check if a repeater survives re-scheduling.
5061 (string-match-p
5062 "\\* H\nSCHEDULED: <2017-02-01 [.A-Za-z]* \\+\\+7d>\n"
5063 (org-test-with-temp-text "* H\nSCHEDULED: <2017-01-19 ++7d>\n"
5064 (let ((org-adapt-indentation nil)
5065 (org-last-inserted-timestamp nil))
5066 (org-schedule nil "2017-02-01"))
5067 (buffer-string)))))
5070 ;;; Property API
5072 (ert-deftest test-org/buffer-property-keys ()
5073 "Test `org-buffer-property-keys' specifications."
5074 ;; Retrieve properties accross siblings.
5075 (should
5076 (equal '("A" "B")
5077 (org-test-with-temp-text "
5078 * H1
5079 :PROPERTIES:
5080 :A: 1
5081 :END:
5082 * H2
5083 :PROPERTIES:
5084 :B: 1
5085 :END:"
5086 (org-buffer-property-keys))))
5087 ;; Retrieve properties accross children.
5088 (should
5089 (equal '("A" "B")
5090 (org-test-with-temp-text "
5091 * H1
5092 :PROPERTIES:
5093 :A: 1
5094 :END:
5095 ** H2
5096 :PROPERTIES:
5097 :B: 1
5098 :END:"
5099 (org-buffer-property-keys))))
5100 ;; Retrieve muliple properties in the same drawer.
5101 (should
5102 (equal '("A" "B")
5103 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:B: 2\n:END:"
5104 (org-buffer-property-keys))))
5105 ;; Ignore extension symbol in property name.
5106 (should
5107 (equal '("A")
5108 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:A+: 2\n:END:"
5109 (org-buffer-property-keys))))
5110 ;; With non-nil COLUMNS, extract property names from columns.
5111 (should
5112 (equal '("A" "B")
5113 (org-test-with-temp-text "#+COLUMNS: %25ITEM %A %20B"
5114 (org-buffer-property-keys nil nil t))))
5115 (should
5116 (equal '("A" "B" "COLUMNS")
5117 (org-test-with-temp-text
5118 "* H\n:PROPERTIES:\n:COLUMNS: %25ITEM %A %20B\n:END:"
5119 (org-buffer-property-keys nil nil t))))
5120 ;; In COLUMNS, ignore title and summary-type.
5121 (should
5122 (equal '("A")
5123 (org-test-with-temp-text "#+COLUMNS: %A(Foo)"
5124 (org-buffer-property-keys nil nil t))))
5125 (should
5126 (equal '("A")
5127 (org-test-with-temp-text "#+COLUMNS: %A{Foo}"
5128 (org-buffer-property-keys nil nil t))))
5129 (should
5130 (equal '("A")
5131 (org-test-with-temp-text "#+COLUMNS: %A(Foo){Bar}"
5132 (org-buffer-property-keys nil nil t)))))
5134 (ert-deftest test-org/property-values ()
5135 "Test `org-property-values' specifications."
5136 ;; Regular test.
5137 (should
5138 (equal '("2" "1")
5139 (org-test-with-temp-text
5140 "* H\n:PROPERTIES:\n:A: 1\n:END:\n* H\n:PROPERTIES:\n:A: 2\n:END:"
5141 (org-property-values "A"))))
5142 ;; Ignore empty values.
5143 (should-not
5144 (org-test-with-temp-text
5145 "* H1\n:PROPERTIES:\n:A:\n:END:\n* H2\n:PROPERTIES:\n:A: \n:END:"
5146 (org-property-values "A")))
5147 ;; Take into consideration extended values.
5148 (should
5149 (equal '("1 2")
5150 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:A+: 2\n:END:"
5151 (org-property-values "A")))))
5153 (ert-deftest test-org/find-property ()
5154 "Test `org-find-property' specifications."
5155 ;; Regular test.
5156 (should
5157 (= 1
5158 (org-test-with-temp-text "* H\n:PROPERTIES:\n:PROP: value\n:END:"
5159 (org-find-property "prop"))))
5160 ;; Ignore false positives.
5161 (should
5162 (= 27
5163 (org-test-with-temp-text
5164 "* H1\n:DRAWER:\n:A: 1\n:END:\n* H2\n:PROPERTIES:\n:A: 1\n:END:"
5165 (org-find-property "A"))))
5166 ;; Return first entry found in buffer.
5167 (should
5168 (= 1
5169 (org-test-with-temp-text
5170 "* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2\n:PROPERTIES:\n:<point>A: 1\n:END:"
5171 (org-find-property "A"))))
5172 ;; Only search visible part of the buffer.
5173 (should
5174 (= 31
5175 (org-test-with-temp-text
5176 "* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2\n:PROPERTIES:\n:<point>A: 1\n:END:"
5177 (org-narrow-to-subtree)
5178 (org-find-property "A"))))
5179 ;; With optional argument, only find entries with a specific value.
5180 (should-not
5181 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:"
5182 (org-find-property "A" "2")))
5183 (should
5184 (= 31
5185 (org-test-with-temp-text
5186 "* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2\n:PROPERTIES:\n:A: 2\n:END:"
5187 (org-find-property "A" "2"))))
5188 ;; Use "nil" for explicit nil values.
5189 (should
5190 (= 31
5191 (org-test-with-temp-text
5192 "* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2\n:PROPERTIES:\n:A: nil\n:END:"
5193 (org-find-property "A" "nil")))))
5195 (ert-deftest test-org/entry-delete ()
5196 "Test `org-entry-delete' specifications."
5197 ;; Regular test.
5198 (should
5199 (string-match
5200 " *:PROPERTIES:\n *:B: +2\n *:END:"
5201 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:B: 2\n:END:"
5202 (org-entry-delete (point) "A")
5203 (buffer-string))))
5204 ;; Also remove accumulated properties.
5205 (should-not
5206 (string-match
5207 ":A"
5208 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:A+: 2\n:B: 3\n:END:"
5209 (org-entry-delete (point) "A")
5210 (buffer-string))))
5211 ;; When last property is removed, remove the property drawer.
5212 (should-not
5213 (string-match
5214 ":PROPERTIES:"
5215 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:\nParagraph"
5216 (org-entry-delete (point) "A")
5217 (buffer-string))))
5218 ;; Return a non-nil value when some property was removed.
5219 (should
5220 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:B: 2\n:END:"
5221 (org-entry-delete (point) "A")))
5222 (should-not
5223 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:B: 2\n:END:"
5224 (org-entry-delete (point) "C")))
5225 ;; Special properties cannot be located in a drawer. Allow to
5226 ;; remove them anyway, in case of user error.
5227 (should
5228 (org-test-with-temp-text "* H\n:PROPERTIES:\n:SCHEDULED: 1\n:END:"
5229 (org-entry-delete (point) "SCHEDULED"))))
5231 (ert-deftest test-org/entry-get ()
5232 "Test `org-entry-get' specifications."
5233 ;; Regular test.
5234 (should
5235 (equal "1"
5236 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:"
5237 (org-entry-get (point) "A"))))
5238 ;; Ignore case.
5239 (should
5240 (equal "1"
5241 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:"
5242 (org-entry-get (point) "a"))))
5243 ;; Handle extended values, both before and after base value.
5244 (should
5245 (equal "1 2 3"
5246 (org-test-with-temp-text
5247 "* H\n:PROPERTIES:\n:A+: 2\n:A: 1\n:A+: 3\n:END:"
5248 (org-entry-get (point) "A"))))
5249 ;; Empty values are returned as the empty string.
5250 (should
5251 (equal ""
5252 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A:\n:END:"
5253 (org-entry-get (point) "A"))))
5254 ;; Special nil value. If LITERAL-NIL is non-nil, return "nil",
5255 ;; otherwise, return nil.
5256 (should-not
5257 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: nil\n:END:"
5258 (org-entry-get (point) "A")))
5259 (should
5260 (equal "nil"
5261 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: nil\n:END:"
5262 (org-entry-get (point) "A" nil t))))
5263 ;; Return nil when no property is found, independently on the
5264 ;; LITERAL-NIL argument.
5265 (should-not
5266 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:"
5267 (org-entry-get (point) "B")))
5268 (should-not
5269 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:"
5270 (org-entry-get (point) "B" nil t)))
5271 ;; Handle inheritance, when allowed. Include extended values and
5272 ;; possibly global values.
5273 (should
5274 (equal
5276 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:\n** <point>H2"
5277 (org-entry-get (point) "A" t))))
5278 (should
5279 (equal
5281 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:\n** <point>H2"
5282 (let ((org-use-property-inheritance t))
5283 (org-entry-get (point) "A" 'selective)))))
5284 (should-not
5285 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:\n** <point>H2"
5286 (let ((org-use-property-inheritance nil))
5287 (org-entry-get (point) "A" 'selective))))
5288 (should
5289 (equal
5290 "1 2"
5291 (org-test-with-temp-text
5292 "* H\n:PROPERTIES:\n:A: 1\n:END:\n** H2\n:PROPERTIES:\n:A+: 2\n:END:"
5293 (org-entry-get (point-max) "A" t))))
5294 (should
5295 (equal "1"
5296 (org-test-with-temp-text
5297 "#+PROPERTY: A 0\n* H\n:PROPERTIES:\n:A: 1\n:END:"
5298 (org-mode-restart)
5299 (org-entry-get (point-max) "A" t))))
5300 (should
5301 (equal "0 1"
5302 (org-test-with-temp-text
5303 "#+PROPERTY: A 0\n* H\n:PROPERTIES:\n:A+: 1\n:END:"
5304 (org-mode-restart)
5305 (org-entry-get (point-max) "A" t)))))
5307 (ert-deftest test-org/entry-properties ()
5308 "Test `org-entry-properties' specifications."
5309 ;; Get "ITEM" property.
5310 (should
5311 (equal "H"
5312 (org-test-with-temp-text "* TODO H"
5313 (cdr (assoc "ITEM" (org-entry-properties nil "ITEM"))))))
5314 (should
5315 (equal "H"
5316 (org-test-with-temp-text "* TODO H"
5317 (cdr (assoc "ITEM" (org-entry-properties))))))
5318 ;; Get "TODO" property. TODO keywords are case sensitive.
5319 (should
5320 (equal "TODO"
5321 (org-test-with-temp-text "* TODO H"
5322 (cdr (assoc "TODO" (org-entry-properties nil "TODO"))))))
5323 (should
5324 (equal "TODO"
5325 (org-test-with-temp-text "* TODO H"
5326 (cdr (assoc "TODO" (org-entry-properties))))))
5327 (should-not
5328 (org-test-with-temp-text "* H"
5329 (assoc "TODO" (org-entry-properties nil "TODO"))))
5330 (should-not
5331 (org-test-with-temp-text "* todo H"
5332 (assoc "TODO" (org-entry-properties nil "TODO"))))
5333 ;; Get "PRIORITY" property.
5334 (should
5335 (equal "A"
5336 (org-test-with-temp-text "* [#A] H"
5337 (cdr (assoc "PRIORITY" (org-entry-properties nil "PRIORITY"))))))
5338 (should
5339 (equal "A"
5340 (org-test-with-temp-text "* [#A] H"
5341 (cdr (assoc "PRIORITY" (org-entry-properties))))))
5342 (should
5343 (equal (char-to-string org-default-priority)
5344 (org-test-with-temp-text "* H"
5345 (cdr (assoc "PRIORITY" (org-entry-properties nil "PRIORITY"))))))
5346 ;; Get "FILE" property.
5347 (should
5348 (org-test-with-temp-text-in-file "* H\nParagraph"
5349 (file-equal-p (cdr (assoc "FILE" (org-entry-properties nil "FILE")))
5350 (buffer-file-name))))
5351 (should
5352 (org-test-with-temp-text-in-file "* H\nParagraph"
5353 (file-equal-p (cdr (assoc "FILE" (org-entry-properties)))
5354 (buffer-file-name))))
5355 (should-not
5356 (org-test-with-temp-text "* H\nParagraph"
5357 (cdr (assoc "FILE" (org-entry-properties nil "FILE")))))
5358 ;; Get "TAGS" property.
5359 (should
5360 (equal ":tag1:tag2:"
5361 (org-test-with-temp-text "* H :tag1:tag2:"
5362 (cdr (assoc "TAGS" (org-entry-properties nil "TAGS"))))))
5363 (should
5364 (equal ":tag1:tag2:"
5365 (org-test-with-temp-text "* H :tag1:tag2:"
5366 (cdr (assoc "TAGS" (org-entry-properties))))))
5367 (should-not
5368 (org-test-with-temp-text "* H"
5369 (cdr (assoc "TAGS" (org-entry-properties nil "TAGS")))))
5370 ;; Get "ALLTAGS" property.
5371 (should
5372 (equal ":tag1:tag2:"
5373 (org-test-with-temp-text "* H :tag1:\n<point>** H2 :tag2:"
5374 (cdr (assoc "ALLTAGS" (org-entry-properties nil "ALLTAGS"))))))
5375 (should
5376 (equal ":tag1:tag2:"
5377 (org-test-with-temp-text "* H :tag1:\n<point>** H2 :tag2:"
5378 (cdr (assoc "ALLTAGS" (org-entry-properties))))))
5379 (should-not
5380 (org-test-with-temp-text "* H"
5381 (cdr (assoc "ALLTAGS" (org-entry-properties nil "ALLTAGS")))))
5382 ;; Get "BLOCKED" property.
5383 (should
5384 (equal "t"
5385 (org-test-with-temp-text "* TODO Blocked\n** DONE one\n** TODO two"
5386 (let ((org-enforce-todo-dependencies t)
5387 (org-blocker-hook
5388 '(org-block-todo-from-children-or-siblings-or-parent)))
5389 (cdr (assoc "BLOCKED" (org-entry-properties nil "BLOCKED")))))))
5390 (should
5391 (equal ""
5392 (org-test-with-temp-text "* TODO Blocked\n** DONE one\n** DONE two"
5393 (let ((org-enforce-todo-dependencies t)
5394 (org-blocker-hook
5395 '(org-block-todo-from-children-or-siblings-or-parent)))
5396 (cdr (assoc "BLOCKED" (org-entry-properties nil "BLOCKED")))))))
5397 ;; Get "CLOSED", "DEADLINE" and "SCHEDULED" properties.
5398 (should
5399 (equal
5400 "[2012-03-29 thu.]"
5401 (org-test-with-temp-text "* H\nCLOSED: [2012-03-29 thu.]"
5402 (cdr (assoc "CLOSED" (org-entry-properties nil "CLOSED"))))))
5403 (should
5404 (equal
5405 "[2012-03-29 thu.]"
5406 (org-test-with-temp-text "* H\nCLOSED: [2012-03-29 thu.]"
5407 (cdr (assoc "CLOSED" (org-entry-properties))))))
5408 (should-not
5409 (org-test-with-temp-text "* H"
5410 (cdr (assoc "CLOSED" (org-entry-properties nil "CLOSED")))))
5411 (should
5412 (equal
5413 "<2014-03-04 tue.>"
5414 (org-test-with-temp-text "* H\nDEADLINE: <2014-03-04 tue.>"
5415 (cdr (assoc "DEADLINE" (org-entry-properties nil "DEADLINE"))))))
5416 (should
5417 (equal
5418 "<2014-03-04 tue.>"
5419 (org-test-with-temp-text "* H\nDEADLINE: <2014-03-04 tue.>"
5420 (cdr (assoc "DEADLINE" (org-entry-properties))))))
5421 (should-not
5422 (org-test-with-temp-text "* H"
5423 (cdr (assoc "DEADLINE" (org-entry-properties nil "DEADLINE")))))
5424 (should
5425 (equal
5426 "<2014-03-04 tue.>"
5427 (org-test-with-temp-text "* H\nSCHEDULED: <2014-03-04 tue.>"
5428 (cdr (assoc "SCHEDULED" (org-entry-properties nil "SCHEDULED"))))))
5429 (should
5430 (equal
5431 "<2014-03-04 tue.>"
5432 (org-test-with-temp-text "* H\nSCHEDULED: <2014-03-04 tue.>"
5433 (cdr (assoc "SCHEDULED" (org-entry-properties))))))
5434 (should-not
5435 (org-test-with-temp-text "* H"
5436 (cdr (assoc "SCHEDULED" (org-entry-properties nil "SCHEDULED")))))
5437 ;; Get "CATEGORY"
5438 (should
5439 (equal "cat"
5440 (org-test-with-temp-text "#+CATEGORY: cat\n<point>* H"
5441 (cdr (assoc "CATEGORY" (org-entry-properties))))))
5442 (should
5443 (equal "cat"
5444 (org-test-with-temp-text "#+CATEGORY: cat\n<point>* H"
5445 (cdr (assoc "CATEGORY" (org-entry-properties nil "CATEGORY"))))))
5446 (should
5447 (equal "cat"
5448 (org-test-with-temp-text "* H\n:PROPERTIES:\n:CATEGORY: cat\n:END:"
5449 (cdr (assoc "CATEGORY" (org-entry-properties nil "CATEGORY"))))))
5450 (should
5451 (equal "cat2"
5452 (org-test-with-temp-text
5453 (concat "* H\n:PROPERTIES:\n:CATEGORY: cat1\n:END:"
5454 "\n"
5455 "** H2\n:PROPERTIES:\n:CATEGORY: cat2\n:END:<point>")
5456 (cdr (assoc "CATEGORY" (org-entry-properties nil "CATEGORY"))))))
5457 ;; Get "TIMESTAMP" and "TIMESTAMP_IA" properties.
5458 (should
5459 (equal "<2012-03-29 thu.>"
5460 (org-test-with-temp-text "* Entry\n<2012-03-29 thu.>"
5461 (cdr (assoc "TIMESTAMP" (org-entry-properties))))))
5462 (should
5463 (equal "[2012-03-29 thu.]"
5464 (org-test-with-temp-text "* Entry\n[2012-03-29 thu.]"
5465 (cdr (assoc "TIMESTAMP_IA" (org-entry-properties))))))
5466 (should
5467 (equal "<2012-03-29 thu.>"
5468 (org-test-with-temp-text "* Entry\n[2014-03-04 tue.]<2012-03-29 thu.>"
5469 (cdr (assoc "TIMESTAMP" (org-entry-properties nil "TIMESTAMP"))))))
5470 (should
5471 (equal "[2014-03-04 tue.]"
5472 (org-test-with-temp-text "* Entry\n<2012-03-29 thu.>[2014-03-04 tue.]"
5473 (cdr (assoc "TIMESTAMP_IA"
5474 (org-entry-properties nil "TIMESTAMP_IA"))))))
5475 (should-not
5476 (equal "<2012-03-29 thu.>"
5477 (org-test-with-temp-text "* Current\n* Next\n<2012-03-29 thu.>"
5478 (cdr (assoc "TIMESTAMP" (org-entry-properties))))))
5479 ;; Get standard properties.
5480 (should
5481 (equal "1"
5482 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:"
5483 (cdr (assoc "A" (org-entry-properties nil 'standard))))))
5484 ;; Handle extended properties.
5485 (should
5486 (equal "1 2 3"
5487 (org-test-with-temp-text
5488 "* H\n:PROPERTIES:\n:A+: 2\n:A: 1\n:A+: 3\n:END:"
5489 (cdr (assoc "A" (org-entry-properties nil 'standard))))))
5490 (should
5491 (equal "1 2 3"
5492 (org-test-with-temp-text
5493 "* H\n:PROPERTIES:\n:A+: 2\n:A: 1\n:a+: 3\n:END:"
5494 (cdr (assoc "A" (org-entry-properties nil 'standard))))))
5495 ;; Ignore forbidden (special) properties.
5496 (should-not
5497 (org-test-with-temp-text "* H\n:PROPERTIES:\n:TODO: foo\n:END:"
5498 (cdr (assoc "TODO" (org-entry-properties nil 'standard))))))
5500 (ert-deftest test-org/entry-put ()
5501 "Test `org-entry-put' specifications."
5502 ;; Error when not a string or nil.
5503 (should-error
5504 (org-test-with-temp-text "* H\n:PROPERTIES:\n:test: 1\n:END:"
5505 (org-entry-put 1 "test" 2)))
5506 ;; Error when property name is invalid.
5507 (should-error
5508 (org-test-with-temp-text "* H\n:PROPERTIES:\n:test: 1\n:END:"
5509 (org-entry-put 1 "no space" "value")))
5510 (should-error
5511 (org-test-with-temp-text "* H\n:PROPERTIES:\n:test: 1\n:END:"
5512 (org-entry-put 1 "" "value")))
5513 ;; Set "TODO" property.
5514 (should
5515 (string-match (regexp-quote " TODO H")
5516 (org-test-with-temp-text "#+TODO: TODO | DONE\n<point>* H"
5517 (org-entry-put (point) "TODO" "TODO")
5518 (buffer-string))))
5519 (should
5520 (string-match (regexp-quote "* H")
5521 (org-test-with-temp-text "#+TODO: TODO | DONE\n<point>* H"
5522 (org-entry-put (point) "TODO" nil)
5523 (buffer-string))))
5524 ;; Set "PRIORITY" property.
5525 (should
5526 (equal "* [#A] H"
5527 (org-test-with-temp-text "* [#B] H"
5528 (org-entry-put (point) "PRIORITY" "A")
5529 (buffer-string))))
5530 (should
5531 (equal "* H"
5532 (org-test-with-temp-text "* [#B] H"
5533 (org-entry-put (point) "PRIORITY" nil)
5534 (buffer-string))))
5535 ;; Set "SCHEDULED" property.
5536 (should
5537 (string-match "* H\n *SCHEDULED: <2014-03-04 .*?>"
5538 (org-test-with-temp-text "* H"
5539 (org-entry-put (point) "SCHEDULED" "2014-03-04")
5540 (buffer-string))))
5541 (should
5542 (string= "* H\n"
5543 (org-test-with-temp-text "* H\nSCHEDULED: <2014-03-04 tue.>"
5544 (org-entry-put (point) "SCHEDULED" nil)
5545 (buffer-string))))
5546 (should
5547 (string-match "* H\n *SCHEDULED: <2014-03-03 .*?>"
5548 (org-test-with-temp-text "* H\nSCHEDULED: <2014-03-04 tue.>"
5549 (org-entry-put (point) "SCHEDULED" "earlier")
5550 (buffer-string))))
5551 (should
5552 (string-match "^ *SCHEDULED: <2014-03-05 .*?>"
5553 (org-test-with-temp-text "* H\nSCHEDULED: <2014-03-04 tue.>"
5554 (org-entry-put (point) "SCHEDULED" "later")
5555 (buffer-string))))
5556 ;; Set "DEADLINE" property.
5557 (should
5558 (string-match "^ *DEADLINE: <2014-03-04 .*?>"
5559 (org-test-with-temp-text "* H"
5560 (org-entry-put (point) "DEADLINE" "2014-03-04")
5561 (buffer-string))))
5562 (should
5563 (string= "* H\n"
5564 (org-test-with-temp-text "* H\nDEADLINE: <2014-03-04 tue.>"
5565 (org-entry-put (point) "DEADLINE" nil)
5566 (buffer-string))))
5567 (should
5568 (string-match "^ *DEADLINE: <2014-03-03 .*?>"
5569 (org-test-with-temp-text "* H\nDEADLINE: <2014-03-04 tue.>"
5570 (org-entry-put (point) "DEADLINE" "earlier")
5571 (buffer-string))))
5572 (should
5573 (string-match "^ *DEADLINE: <2014-03-05 .*?>"
5574 (org-test-with-temp-text "* H\nDEADLINE: <2014-03-04 tue.>"
5575 (org-entry-put (point) "DEADLINE" "later")
5576 (buffer-string))))
5577 ;; Set "CATEGORY" property
5578 (should
5579 (string-match "^ *:CATEGORY: cat"
5580 (org-test-with-temp-text "* H"
5581 (org-entry-put (point) "CATEGORY" "cat")
5582 (buffer-string))))
5583 ;; Regular properties, with or without pre-existing drawer.
5584 (should
5585 (string-match "^ *:A: +2$"
5586 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:"
5587 (org-entry-put (point) "A" "2")
5588 (buffer-string))))
5589 (should
5590 (string-match "^ *:A: +1$"
5591 (org-test-with-temp-text "* H"
5592 (org-entry-put (point) "A" "1")
5593 (buffer-string))))
5594 ;; Special case: two consecutive headlines.
5595 (should
5596 (string-match "\\* A\n *:PROPERTIES:"
5597 (org-test-with-temp-text "* A\n** B"
5598 (org-entry-put (point) "A" "1")
5599 (buffer-string)))))
5601 (ert-deftest test-org/refresh-properties ()
5602 "Test `org-refresh-properties' specifications."
5603 (should
5604 (equal "1"
5605 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:"
5606 (org-refresh-properties "A" 'org-test)
5607 (get-text-property (point) 'org-test))))
5608 (should-not
5609 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:"
5610 (org-refresh-properties "B" 'org-test)
5611 (get-text-property (point) 'org-test)))
5612 ;; Handle properties only defined with extension syntax, i.e.,
5613 ;; "PROPERTY+".
5614 (should
5615 (equal "1"
5616 (org-test-with-temp-text "* H\n:PROPERTIES:\n:A+: 1\n:END:"
5617 (org-refresh-properties "A" 'org-test)
5618 (get-text-property (point) 'org-test))))
5619 ;; When property is inherited, add text property to the whole
5620 ;; sub-tree.
5621 (should
5622 (equal "1"
5623 (org-test-with-temp-text
5624 "* H1\n:PROPERTIES:\n:A: 1\n:END:\n<point>** H2"
5625 (let ((org-use-property-inheritance t))
5626 (org-refresh-properties "A" 'org-test))
5627 (get-text-property (point) 'org-test))))
5628 ;; When property is inherited, use global value across the whole
5629 ;; buffer. However local values have precedence.
5630 (should-not
5631 (equal "1"
5632 (org-test-with-temp-text "#+PROPERTY: A 1\n<point>* H1"
5633 (org-mode-restart)
5634 (let ((org-use-property-inheritance nil))
5635 (org-refresh-properties "A" 'org-test))
5636 (get-text-property (point) 'org-test))))
5637 (should
5638 (equal "1"
5639 (org-test-with-temp-text "#+PROPERTY: A 1\n<point>* H1"
5640 (org-mode-restart)
5641 (let ((org-use-property-inheritance t))
5642 (org-refresh-properties "A" 'org-test))
5643 (get-text-property (point) 'org-test))))
5644 (should
5645 (equal "2"
5646 (org-test-with-temp-text
5647 "#+PROPERTY: A 1\n<point>* H\n:PROPERTIES:\n:A: 2\n:END:"
5648 (org-mode-restart)
5649 (let ((org-use-property-inheritance t))
5650 (org-refresh-properties "A" 'org-test))
5651 (get-text-property (point) 'org-test)))))
5654 ;;; Radio Targets
5656 (ert-deftest test-org/update-radio-target-regexp ()
5657 "Test `org-update-radio-target-regexp' specifications."
5658 ;; Properly update cache with no previous radio target regexp.
5659 (should
5660 (eq 'link
5661 (org-test-with-temp-text "radio\n\nParagraph\n\nradio"
5662 (save-excursion (goto-char (point-max)) (org-element-context))
5663 (insert "<<<")
5664 (search-forward "o")
5665 (insert ">>>")
5666 (org-update-radio-target-regexp)
5667 (goto-char (point-max))
5668 (org-element-type (org-element-context)))))
5669 ;; Properly update cache with previous radio target regexp.
5670 (should
5671 (eq 'link
5672 (org-test-with-temp-text "radio\n\nParagraph\n\nradio"
5673 (save-excursion (goto-char (point-max)) (org-element-context))
5674 (insert "<<<")
5675 (search-forward "o")
5676 (insert ">>>")
5677 (org-update-radio-target-regexp)
5678 (search-backward "r")
5679 (delete-char 5)
5680 (insert "new")
5681 (org-update-radio-target-regexp)
5682 (goto-char (point-max))
5683 (delete-region (line-beginning-position) (point))
5684 (insert "new")
5685 (org-element-type (org-element-context))))))
5688 ;;; Refile
5690 (ert-deftest test-org/refile-get-targets ()
5691 "Test `org-refile-get-targets' specifications."
5692 ;; :maxlevel includes all headings above specified value.
5693 (should
5694 (equal '("H1" "H2" "H3")
5695 (org-test-with-temp-text "* H1\n** H2\n*** H3"
5696 (let ((org-refile-use-outline-path nil)
5697 (org-refile-targets `((nil :maxlevel . 3))))
5698 (mapcar #'car (org-refile-get-targets))))))
5699 (should
5700 (equal '("H1" "H2")
5701 (org-test-with-temp-text "* H1\n** H2\n*** H3"
5702 (let ((org-refile-use-outline-path nil)
5703 (org-refile-targets `((nil :maxlevel . 2))))
5704 (mapcar #'car (org-refile-get-targets))))))
5705 ;; :level limits targets to headlines with the specified level.
5706 (should
5707 (equal '("H2")
5708 (org-test-with-temp-text "* H1\n** H2\n*** H3"
5709 (let ((org-refile-use-outline-path nil)
5710 (org-refile-targets `((nil :level . 2))))
5711 (mapcar #'car (org-refile-get-targets))))))
5712 ;; :tag limits targets to headlines with specified tag.
5713 (should
5714 (equal '("H1")
5715 (org-test-with-temp-text "* H1 :foo:\n** H2\n*** H3 :bar:"
5716 (let ((org-refile-use-outline-path nil)
5717 (org-refile-targets `((nil :tag . "foo"))))
5718 (mapcar #'car (org-refile-get-targets))))))
5719 ;; :todo limits targets to headlines with specified TODO keyword.
5720 (should
5721 (equal '("H2")
5722 (org-test-with-temp-text "* H1\n** TODO H2\n*** DONE H3"
5723 (let ((org-refile-use-outline-path nil)
5724 (org-refile-targets `((nil :todo . "TODO"))))
5725 (mapcar #'car (org-refile-get-targets))))))
5726 ;; :regexp filters targets matching provided regexp.
5727 (should
5728 (equal '("F2" "F3")
5729 (org-test-with-temp-text "* H1\n** F2\n*** F3"
5730 (let ((org-refile-use-outline-path nil)
5731 (org-refile-targets `((nil :regexp . "F"))))
5732 (mapcar #'car (org-refile-get-targets))))))
5733 ;; A nil `org-refile-targets' includes only top level headlines in
5734 ;; current buffer.
5735 (should
5736 (equal '("H1" "H2")
5737 (org-test-with-temp-text "* H1\n** S1\n* H2"
5738 (let ((org-refile-use-outline-path nil)
5739 (org-refile-targets nil))
5740 (mapcar #'car (org-refile-get-targets))))))
5741 ;; Return value is the union of the targets according to all the
5742 ;; defined rules. However, prevent duplicates.
5743 (should
5744 (equal '("F2" "F3" "H1")
5745 (org-test-with-temp-text "* TODO H1\n** F2\n*** F3"
5746 (let ((org-refile-use-outline-path nil)
5747 (org-refile-targets `((nil :regexp . "F")
5748 (nil :todo . "TODO"))))
5749 (mapcar #'car (org-refile-get-targets))))))
5750 (should
5751 (equal '("F2" "F3" "H1")
5752 (org-test-with-temp-text "* TODO H1\n** TODO F2\n*** F3"
5753 (let ((org-refile-use-outline-path nil)
5754 (org-refile-targets `((nil :regexp . "F")
5755 (nil :todo . "TODO"))))
5756 (mapcar #'car (org-refile-get-targets))))))
5757 ;; When `org-refile-use-outline-path' is non-nil, provide targets as
5758 ;; paths.
5759 (should
5760 (equal '("H1" "H1/H2" "H1/H2/H3")
5761 (org-test-with-temp-text "* H1\n** H2\n*** H3"
5762 (let ((org-refile-use-outline-path t)
5763 (org-refile-targets `((nil :maxlevel . 3))))
5764 (mapcar #'car (org-refile-get-targets))))))
5765 ;; When providing targets as paths, escape forward slashes in
5766 ;; headings with backslashes.
5767 (should
5768 (equal '("H1\\/foo")
5769 (org-test-with-temp-text "* H1/foo"
5770 (let ((org-refile-use-outline-path t)
5771 (org-refile-targets `((nil :maxlevel . 1))))
5772 (mapcar #'car (org-refile-get-targets))))))
5773 ;; When `org-refile-use-outline-path' is `file', include file name
5774 ;; without directory in targets.
5775 (should
5776 (org-test-with-temp-text-in-file "* H1"
5777 (let* ((filename (buffer-file-name))
5778 (org-refile-use-outline-path 'file)
5779 (org-refile-targets `(((,filename) :level . 1))))
5780 (member (file-name-nondirectory filename)
5781 (mapcar #'car (org-refile-get-targets))))))
5782 ;; When `org-refile-use-outline-path' is `full-file-path', include
5783 ;; full file name.
5784 (should
5785 (org-test-with-temp-text-in-file "* H1"
5786 (let* ((filename (file-truename (buffer-file-name)))
5787 (org-refile-use-outline-path 'full-file-path)
5788 (org-refile-targets `(((,filename) :level . 1))))
5789 (member filename (mapcar #'car (org-refile-get-targets))))))
5790 ;; When `org-refile-use-outline-path' is `buffer-name', include
5791 ;; buffer name.
5792 (should
5793 (org-test-with-temp-text "* H1"
5794 (let* ((org-refile-use-outline-path 'buffer-name)
5795 (org-refile-targets `((nil :level . 1))))
5796 (member (buffer-name) (mapcar #'car (org-refile-get-targets)))))))
5800 ;;; Sparse trees
5802 (ert-deftest test-org/match-sparse-tree ()
5803 "Test `org-match-sparse-tree' specifications."
5804 ;; Match tags.
5805 (should-not
5806 (org-test-with-temp-text "* H\n** H1 :tag:"
5807 (org-match-sparse-tree nil "tag")
5808 (search-forward "H1")
5809 (org-invisible-p2)))
5810 (should
5811 (org-test-with-temp-text "* H\n** H1 :tag:\n** H2 :tag2:"
5812 (org-match-sparse-tree nil "tag")
5813 (search-forward "H2")
5814 (org-invisible-p2)))
5815 ;; "-" operator for tags.
5816 (should-not
5817 (org-test-with-temp-text "* H\n** H1 :tag1:\n** H2 :tag1:tag2:"
5818 (org-match-sparse-tree nil "tag1-tag2")
5819 (search-forward "H1")
5820 (org-invisible-p2)))
5821 (should
5822 (org-test-with-temp-text "* H\n** H1 :tag1:\n** H2 :tag1:tag2:"
5823 (org-match-sparse-tree nil "tag1-tag2")
5824 (search-forward "H2")
5825 (org-invisible-p2)))
5826 ;; "&" operator for tags.
5827 (should
5828 (org-test-with-temp-text "* H\n** H1 :tag1:\n** H2 :tag1:tag2:"
5829 (org-match-sparse-tree nil "tag1&tag2")
5830 (search-forward "H1")
5831 (org-invisible-p2)))
5832 (should-not
5833 (org-test-with-temp-text "* H\n** H1 :tag1:\n** H2 :tag1:tag2:"
5834 (org-match-sparse-tree nil "tag1&tag2")
5835 (search-forward "H2")
5836 (org-invisible-p2)))
5837 ;; "|" operator for tags.
5838 (should-not
5839 (org-test-with-temp-text "* H\n** H1 :tag1:\n** H2 :tag1:tag2:"
5840 (org-match-sparse-tree nil "tag1|tag2")
5841 (search-forward "H1")
5842 (org-invisible-p2)))
5843 (should-not
5844 (org-test-with-temp-text "* H\n** H1 :tag1:\n** H2 :tag1:tag2:"
5845 (org-match-sparse-tree nil "tag1|tag2")
5846 (search-forward "H2")
5847 (org-invisible-p2)))
5848 ;; Regexp match on tags.
5849 (should-not
5850 (org-test-with-temp-text "* H\n** H1 :tag1:\n** H2 :foo:"
5851 (org-match-sparse-tree nil "{^tag.*}")
5852 (search-forward "H1")
5853 (org-invisible-p2)))
5854 (should
5855 (org-test-with-temp-text "* H\n** H1 :tag1:\n** H2 :foo:"
5856 (org-match-sparse-tree nil "{^tag.*}")
5857 (search-forward "H2")
5858 (org-invisible-p2)))
5859 ;; Match group tags.
5860 (should-not
5861 (org-test-with-temp-text
5862 "#+TAGS: { work : lab }\n* H\n** H1 :work:\n** H2 :lab:"
5863 (org-match-sparse-tree nil "work")
5864 (search-forward "H1")
5865 (org-invisible-p2)))
5866 (should-not
5867 (org-test-with-temp-text
5868 "#+TAGS: { work : lab }\n* H\n** H1 :work:\n** H2 :lab:"
5869 (org-match-sparse-tree nil "work")
5870 (search-forward "H2")
5871 (org-invisible-p2)))
5872 ;; Match group tags with hard brackets.
5873 (should-not
5874 (org-test-with-temp-text
5875 "#+TAGS: [ work : lab ]\n* H\n** H1 :work:\n** H2 :lab:"
5876 (org-match-sparse-tree nil "work")
5877 (search-forward "H1")
5878 (org-invisible-p2)))
5879 (should-not
5880 (org-test-with-temp-text
5881 "#+TAGS: [ work : lab ]\n* H\n** H1 :work:\n** H2 :lab:"
5882 (org-match-sparse-tree nil "work")
5883 (search-forward "H2")
5884 (org-invisible-p2)))
5885 ;; Match tags in hierarchies
5886 (should-not
5887 (org-test-with-temp-text
5888 "#+TAGS: [ Lev_1 : Lev_2 ]\n
5889 #+TAGS: [ Lev_2 : Lev_3 ]\n
5890 #+TAGS: { Lev_3 : Lev_4 }\n
5891 * H\n** H1 :Lev_1:\n** H2 :Lev_2:\n** H3 :Lev_3:\n** H4 :Lev_4:"
5892 (org-match-sparse-tree nil "Lev_1")
5893 (search-forward "H4")
5894 (org-invisible-p2)))
5895 (should-not
5896 (org-test-with-temp-text
5897 "#+TAGS: [ Lev_1 : Lev_2 ]\n
5898 #+TAGS: [ Lev_2 : Lev_3 ]\n
5899 #+TAGS: { Lev_3 : Lev_4 }\n
5900 * H\n** H1 :Lev_1:\n** H2 :Lev_2:\n** H3 :Lev_3:\n** H4 :Lev_4:"
5901 (org-match-sparse-tree nil "Lev_1+Lev_3")
5902 (search-forward "H4")
5903 (org-invisible-p2)))
5904 ;; Match regular expressions in tags
5905 (should-not
5906 (org-test-with-temp-text
5907 "#+TAGS: [ Lev : {Lev_[0-9]} ]\n* H\n** H1 :Lev_1:"
5908 (org-match-sparse-tree nil "Lev")
5909 (search-forward "H1")
5910 (org-invisible-p2)))
5911 (should
5912 (org-test-with-temp-text
5913 "#+TAGS: [ Lev : {Lev_[0-9]} ]\n* H\n** H1 :Lev_n:"
5914 (org-match-sparse-tree nil "Lev")
5915 (search-forward "H1")
5916 (org-invisible-p2)))
5917 ;; Match properties.
5918 (should
5919 (org-test-with-temp-text
5920 "* H\n** H1\n:PROPERTIES:\n:A: 1\n:END:\n** H2\n:PROPERTIES:\n:A: 2\n:END:"
5921 (org-match-sparse-tree nil "A=\"1\"")
5922 (search-forward "H2")
5923 (org-invisible-p2)))
5924 (should-not
5925 (org-test-with-temp-text "* H1\n** H2\n:PROPERTIES:\n:A: 1\n:END:"
5926 (org-match-sparse-tree nil "A=\"1\"")
5927 (search-forward "H2")
5928 (org-invisible-p2)))
5929 ;; Case is not significant when matching properties.
5930 (should-not
5931 (org-test-with-temp-text "* H1\n** H2\n:PROPERTIES:\n:A: 1\n:END:"
5932 (org-match-sparse-tree nil "a=\"1\"")
5933 (search-forward "H2")
5934 (org-invisible-p2)))
5935 (should-not
5936 (org-test-with-temp-text "* H1\n** H2\n:PROPERTIES:\n:a: 1\n:END:"
5937 (org-match-sparse-tree nil "A=\"1\"")
5938 (search-forward "H2")
5939 (org-invisible-p2)))
5940 ;; Match special LEVEL property.
5941 (should-not
5942 (org-test-with-temp-text "* H\n** H1\n*** H2"
5943 (let ((org-odd-levels-only nil)) (org-match-sparse-tree nil "LEVEL=2"))
5944 (search-forward "H1")
5945 (org-invisible-p2)))
5946 (should
5947 (org-test-with-temp-text "* H\n** H1\n*** H2"
5948 (let ((org-odd-levels-only nil)) (org-match-sparse-tree nil "LEVEL=2"))
5949 (search-forward "H2")
5950 (org-invisible-p2)))
5951 ;; Comparison operators when matching properties.
5952 (should
5953 (org-test-with-temp-text
5954 "* H\n** H1\nSCHEDULED: <2014-03-04 tue.>\n** H2\nSCHEDULED: <2012-03-29 thu.>"
5955 (org-match-sparse-tree nil "SCHEDULED<=\"<2013-01-01>\"")
5956 (search-forward "H1")
5957 (org-invisible-p2)))
5958 (should-not
5959 (org-test-with-temp-text
5960 "* H\n** H1\nSCHEDULED: <2014-03-04 tue.>\n** H2\nSCHEDULED: <2012-03-29 thu.>"
5961 (org-match-sparse-tree nil "SCHEDULED<=\"<2013-01-01>\"")
5962 (search-forward "H2")
5963 (org-invisible-p2)))
5964 ;; Regexp match on properties values.
5965 (should-not
5966 (org-test-with-temp-text
5967 "* H\n** H1\n:PROPERTIES:\n:A: foo\n:END:\n** H2\n:PROPERTIES:\n:A: bar\n:END:"
5968 (org-match-sparse-tree nil "A={f.*}")
5969 (search-forward "H1")
5970 (org-invisible-p2)))
5971 (should
5972 (org-test-with-temp-text
5973 "* H\n** H1\n:PROPERTIES:\n:A: foo\n:END:\n** H2\n:PROPERTIES:\n:A: bar\n:END:"
5974 (org-match-sparse-tree nil "A={f.*}")
5975 (search-forward "H2")
5976 (org-invisible-p2)))
5977 ;; With an optional argument, limit match to TODO entries.
5978 (should-not
5979 (org-test-with-temp-text "* H\n** TODO H1 :tag:\n** H2 :tag:"
5980 (org-match-sparse-tree t "tag")
5981 (search-forward "H1")
5982 (org-invisible-p2)))
5983 (should
5984 (org-test-with-temp-text "* H\n** TODO H1 :tag:\n** H2 :tag:"
5985 (org-match-sparse-tree t "tag")
5986 (search-forward "H2")
5987 (org-invisible-p2))))
5989 (ert-deftest test-org/occur ()
5990 "Test `org-occur' specifications."
5991 ;; Count number of matches.
5992 (should
5993 (= 1
5994 (org-test-with-temp-text "* H\nA\n* H2"
5995 (org-occur "A"))))
5996 (should
5997 (= 2
5998 (org-test-with-temp-text "* H\nA\n* H2\nA"
5999 (org-occur "A"))))
6000 ;; Test CALLBACK optional argument.
6001 (should
6002 (= 0
6003 (org-test-with-temp-text "* H\nA\n* H2"
6004 (org-occur "A" nil (lambda () (equal (org-get-heading) "H2"))))))
6005 (should
6006 (= 1
6007 (org-test-with-temp-text "* H\nA\n* H2\nA"
6008 (org-occur "A" nil (lambda () (equal (org-get-heading) "H2"))))))
6009 ;; Case-fold searches according to `org-occur-case-fold-search'.
6010 (should
6011 (= 2
6012 (org-test-with-temp-text "Aa"
6013 (let ((org-occur-case-fold-search t)) (org-occur "A")))))
6014 (should
6015 (= 2
6016 (org-test-with-temp-text "Aa"
6017 (let ((org-occur-case-fold-search t)) (org-occur "a")))))
6018 (should
6019 (= 1
6020 (org-test-with-temp-text "Aa"
6021 (let ((org-occur-case-fold-search nil)) (org-occur "A")))))
6022 (should
6023 (= 1
6024 (org-test-with-temp-text "Aa"
6025 (let ((org-occur-case-fold-search nil)) (org-occur "a")))))
6026 (should
6027 (= 1
6028 (org-test-with-temp-text "Aa"
6029 (let ((org-occur-case-fold-search 'smart)) (org-occur "A")))))
6030 (should
6031 (= 2
6032 (org-test-with-temp-text "Aa"
6033 (let ((org-occur-case-fold-search 'smart)) (org-occur "a"))))))
6036 ;;; Tags
6038 (ert-deftest test-org/tag-string-to-alist ()
6039 "Test `org-tag-string-to-alist' specifications."
6040 ;; Tag without selection key.
6041 (should (equal (org-tag-string-to-alist "tag1") '(("tag1"))))
6042 ;; Tag with selection key.
6043 (should (equal (org-tag-string-to-alist "tag1(t)") '(("tag1" . ?t))))
6044 ;; Tag group.
6045 (should
6046 (equal
6047 (org-tag-string-to-alist "[ group : t1 t2 ]")
6048 '((:startgrouptag) ("group") (:grouptags) ("t1") ("t2") (:endgrouptag))))
6049 ;; Mutually exclusive tags.
6050 (should (equal (org-tag-string-to-alist "{ tag1 tag2 }")
6051 '((:startgroup) ("tag1") ("tag2") (:endgroup))))
6052 (should
6053 (equal
6054 (org-tag-string-to-alist "{ group : tag1 tag2 }")
6055 '((:startgroup) ("group") (:grouptags) ("tag1") ("tag2") (:endgroup)))))
6057 (ert-deftest test-org/tag-alist-to-string ()
6058 "Test `org-tag-alist-to-string' specifications."
6059 (should (equal (org-tag-alist-to-string '(("tag1"))) "tag1"))
6060 (should (equal (org-tag-alist-to-string '(("tag1" . ?t))) "tag1(t)"))
6061 (should
6062 (equal
6063 (org-tag-alist-to-string
6064 '((:startgrouptag) ("group") (:grouptags) ("t1") ("t2") (:endgrouptag)))
6065 "[ group : t1 t2 ]"))
6066 (should
6067 (equal (org-tag-alist-to-string
6068 '((:startgroup) ("tag1") ("tag2") (:endgroup)))
6069 "{ tag1 tag2 }"))
6070 (should
6071 (equal
6072 (org-tag-alist-to-string
6073 '((:startgroup) ("group") (:grouptags) ("tag1") ("tag2") (:endgroup)))
6074 "{ group : tag1 tag2 }")))
6076 (ert-deftest test-org/tag-alist-to-groups ()
6077 "Test `org-tag-alist-to-groups' specifications."
6078 (should
6079 (equal (org-tag-alist-to-groups
6080 '((:startgroup) ("group") (:grouptags) ("t1") ("t2") (:endgroup)))
6081 '(("group" "t1" "t2"))))
6082 (should
6083 (equal
6084 (org-tag-alist-to-groups
6085 '((:startgrouptag) ("group") (:grouptags) ("t1") ("t2") (:endgrouptag)))
6086 '(("group" "t1" "t2"))))
6087 (should-not
6088 (org-tag-alist-to-groups
6089 '((:startgroup) ("group") ("t1") ("t2") (:endgroup)))))
6091 (ert-deftest test-org/tag-align ()
6092 "Test tags alignment."
6093 ;; Test aligning tags with different display width.
6094 (should
6095 ;; 12345678901234567890
6096 (equal "* Test :abc:"
6097 (org-test-with-temp-text "* Test :abc:"
6098 (let ((org-tags-column -20)
6099 (indent-tabs-mode nil))
6100 (org-fix-tags-on-the-fly))
6101 (buffer-string))))
6102 (should
6103 ;; 12345678901234567890
6104 (equal "* Test :日本語:"
6105 (org-test-with-temp-text "* Test :日本語:"
6106 (let ((org-tags-column -20)
6107 (indent-tabs-mode nil))
6108 (org-fix-tags-on-the-fly))
6109 (buffer-string))))
6110 ;; Make sure aligning tags do not skip invisible text.
6111 (should
6112 (equal "* [[linkx]] :tag:"
6113 (org-test-with-temp-text "* [[link<point>]] :tag:"
6114 (let ((org-tags-column 0))
6115 (org-fix-tags-on-the-fly)
6116 (insert "x")
6117 (buffer-string)))))
6118 ;; Aligning tags preserve position.
6119 (should
6120 (= 6 (org-test-with-temp-text "* 345 <point> :tag:"
6121 (let ((org-tags-column 78)
6122 (indent-tabs-mode nil))
6123 (org-fix-tags-on-the-fly))
6124 (current-column)))))
6126 (ert-deftest test-org/get-tags ()
6127 "Test `org-get-tags' specifications."
6128 ;; Standard test.
6129 (should
6130 (equal '("foo")
6131 (org-test-with-temp-text "* Test :foo:" (org-get-tags))))
6132 (should
6133 (equal '("foo" "bar")
6134 (org-test-with-temp-text "* Test :foo:bar:" (org-get-tags))))
6135 ;; Return nil when there is no tag.
6136 (should-not
6137 (org-test-with-temp-text "* Test" (org-get-tags)))
6138 ;; Tags are inherited from parent headlines.
6139 (should
6140 (equal '("tag")
6141 (let ((org-use-tag-inheritance t))
6142 (org-test-with-temp-text "* H0 :foo:\n* H1 :tag:\n<point>** H2"
6143 (org-get-tags)))))
6144 ;; Tags are inherited from `org-file-tags'.
6145 (should
6146 (equal '("tag")
6147 (org-test-with-temp-text "* H1"
6148 (let ((org-file-tags '("tag"))
6149 (org-use-tag-inheritance t))
6150 (org-get-tags)))))
6151 ;; Only inherited tags have the `inherited' text property.
6152 (should
6153 (get-text-property 0 'inherited
6154 (org-test-with-temp-text "* H1 :foo:\n** <point>H2 :bar:"
6155 (let ((org-use-tag-inheritance t))
6156 (assoc-string "foo" (org-get-tags))))))
6157 (should-not
6158 (get-text-property 0 'inherited
6159 (org-test-with-temp-text "* H1 :foo:\n** <point>H2 :bar:"
6160 (let ((org-use-tag-inheritance t))
6161 (assoc-string "bar" (org-get-tags))))))
6162 ;; Obey to `org-use-tag-inheritance'.
6163 (should-not
6164 (org-test-with-temp-text "* H1 :foo:\n** <point>H2 :bar:"
6165 (let ((org-use-tag-inheritance nil))
6166 (assoc-string "foo" (org-get-tags)))))
6167 (should-not
6168 (org-test-with-temp-text "* H1 :foo:\n** <point>H2 :bar:"
6169 (let ((org-use-tag-inheritance nil)
6170 (org-file-tags '("foo")))
6171 (assoc-string "foo" (org-get-tags)))))
6172 (should-not
6173 (org-test-with-temp-text "* H1 :foo:bar:\n** <point>H2 :baz:"
6174 (let ((org-use-tag-inheritance '("bar")))
6175 (assoc-string "foo" (org-get-tags)))))
6176 (should
6177 (org-test-with-temp-text "* H1 :foo:bar:\n** <point>H2 :baz:"
6178 (let ((org-use-tag-inheritance '("bar")))
6179 (assoc-string "bar" (org-get-tags)))))
6180 (should-not
6181 (org-test-with-temp-text "* H1 :foo:bar:\n** <point>H2 :baz:"
6182 (let ((org-use-tag-inheritance "b.*"))
6183 (assoc-string "foo" (org-get-tags)))))
6184 (should
6185 (org-test-with-temp-text "* H1 :foo:bar:\n** <point>H2 :baz:"
6186 (let ((org-use-tag-inheritance "b.*"))
6187 (assoc-string "bar" (org-get-tags)))))
6188 ;; When optional argument LOCAL is non-nil, ignore tag inheritance.
6189 (should
6190 (equal '("baz")
6191 (org-test-with-temp-text "* H1 :foo:bar:\n** <point>H2 :baz:"
6192 (let ((org-use-tag-inheritance t))
6193 (org-get-tags nil t)))))
6194 ;; When optional argument POS is non-nil, get tags there instead.
6195 (should
6196 (equal '("foo")
6197 (org-test-with-temp-text "* H1 :foo:\n* <point>H2 :bar:"
6198 (org-get-tags 1))))
6199 ;; Make sure tags excluded from inheritance are returned if local
6200 (should
6201 (equal '("foo")
6202 (org-test-with-temp-text "* Test :foo:"
6203 (let ((org-use-tag-inheritance t)
6204 (org-tags-exclude-from-inheritance '("foo")))
6205 (org-get-tags)))))
6206 ;; Pathological case: tagged headline with an empty body.
6207 (should (org-test-with-temp-text "* :tag:" (org-get-tags))))
6209 (ert-deftest test-org/set-tags ()
6210 "Test `org-set-tags' specifications."
6211 ;; Throw an error on invalid data.
6212 (should-error
6213 (org-test-with-temp-text "* H"
6214 (org-set-tags 'foo)))
6215 ;; `nil', an empty, and a blank string remove all tags.
6216 (should
6217 (equal "* H"
6218 (org-test-with-temp-text "* H :tag1:tag2:"
6219 (org-set-tags nil)
6220 (buffer-string))))
6221 (should
6222 (equal "* H"
6223 (org-test-with-temp-text "* H :tag1:tag2:"
6224 (org-set-tags "")
6225 (buffer-string))))
6226 (should
6227 (equal "* H"
6228 (org-test-with-temp-text "* H :tag1:tag2:"
6229 (org-set-tags " ")
6230 (buffer-string))))
6231 ;; If there's nothing to remove, just bail out.
6232 (should
6233 (equal "* H"
6234 (org-test-with-temp-text "* H"
6235 (org-set-tags nil)
6236 (buffer-string))))
6237 (should
6238 (equal "* "
6239 (org-test-with-temp-text "* "
6240 (org-set-tags nil)
6241 (buffer-string))))
6242 ;; If DATA is a tag string, set current tags to it, even if it means
6243 ;; replacing old tags.
6244 (should
6245 (equal "* H :tag0:"
6246 (org-test-with-temp-text "* H :tag1:tag2:"
6247 (let ((org-tags-column 1)) (org-set-tags ":tag0:"))
6248 (buffer-string))))
6249 (should
6250 (equal "* H :tag0:"
6251 (org-test-with-temp-text "* H"
6252 (let ((org-tags-column 1)) (org-set-tags ":tag0:"))
6253 (buffer-string))))
6254 ;; If DATA is a list, set tags to this list, even if it means
6255 ;; replacing old tags.
6256 (should
6257 (equal "* H :tag0:"
6258 (org-test-with-temp-text "* H :tag1:tag2:"
6259 (let ((org-tags-column 1)) (org-set-tags '("tag0")))
6260 (buffer-string))))
6261 (should
6262 (equal "* H :tag0:"
6263 (org-test-with-temp-text "* H"
6264 (let ((org-tags-column 1)) (org-set-tags '("tag0")))
6265 (buffer-string))))
6266 ;; When set, apply `org-tags-sort-function'.
6267 (should
6268 (equal "* H :a:b:"
6269 (org-test-with-temp-text "* H"
6270 (let ((org-tags-column 1)
6271 (org-tags-sort-function #'string<))
6272 (org-set-tags '("b" "a"))
6273 (buffer-string)))))
6274 ;; When new tags are identical to the previous ones, still align.
6275 (should
6276 (equal "* H :foo:"
6277 (org-test-with-temp-text "* H :foo:"
6278 (let ((org-tags-column 1))
6279 (org-set-tags '("foo"))
6280 (buffer-string)))))
6281 ;; When tags have been changed, run `org-after-tags-change-hook'.
6282 (should
6283 (catch :return
6284 (org-test-with-temp-text "* H :foo:"
6285 (let ((org-after-tags-change-hook (lambda () (throw :return t))))
6286 (org-set-tags '("bar"))
6287 nil))))
6288 (should-not
6289 (catch :return
6290 (org-test-with-temp-text "* H :foo:"
6291 (let ((org-after-tags-change-hook (lambda () (throw :return t))))
6292 (org-set-tags '("foo"))
6293 nil))))
6294 ;; Special case: handle empty headlines.
6295 (should
6296 (equal "* :tag0:"
6297 (org-test-with-temp-text "* "
6298 (let ((org-tags-column 1)) (org-set-tags '("tag0")))
6299 (buffer-string))))
6300 ;; Modify buffer only when a tag change happens or alignment is
6301 ;; done.
6302 (should-not
6303 (org-test-with-temp-text "* H :foo:"
6304 (set-buffer-modified-p nil)
6305 (let ((org-tags-column 1)) (org-set-tags '("foo")))
6306 (buffer-modified-p)))
6307 (should
6308 (org-test-with-temp-text "* H :foo:"
6309 (set-buffer-modified-p nil)
6310 (let ((org-tags-column 10)) (org-set-tags '("foo")))
6311 (buffer-modified-p)))
6312 (should
6313 (org-test-with-temp-text "* H :foo:"
6314 (set-buffer-modified-p nil)
6315 (let ((org-tags-column 10)) (org-set-tags '("bar")))
6316 (buffer-modified-p)))
6317 ;; Pathological case: when setting tags of a folded headline, do not
6318 ;; let new tags being sucked into invisibility.
6319 (should-not
6320 (org-test-with-temp-text "* H1\nContent\n* H2\n\n Other Content"
6321 ;; Show only headlines
6322 (org-content)
6323 ;; Set NEXT tag on current entry
6324 (org-set-tags ":NEXT:")
6325 ;; Move point to that NEXT tag
6326 (search-forward "NEXT") (backward-word)
6327 ;; And it should be visible (i.e. no overlays)
6328 (overlays-at (point)))))
6330 (ert-deftest test-org/set-tags-command ()
6331 "Test `org-set-tags-command' specifications"
6332 ;; Set tags at current headline.
6333 (should
6334 (equal "* H1 :foo:"
6335 (org-test-with-temp-text "* H1"
6336 (cl-letf (((symbol-function 'completing-read)
6337 (lambda (&rest args) ":foo:")))
6338 (let ((org-use-fast-tag-selection nil)
6339 (org-tags-column 1))
6340 (org-set-tags-command)))
6341 (buffer-string))))
6342 ;; Preserve position when called from the section below.
6343 (should
6344 (equal "* H1 :foo:\nContents"
6345 (org-test-with-temp-text "* H1\n<point>Contents"
6346 (cl-letf (((symbol-function 'completing-read)
6347 (lambda (&rest args) ":foo:")))
6348 (let ((org-use-fast-tag-selection nil)
6349 (org-tags-column 1))
6350 (org-set-tags-command)))
6351 (buffer-string))))
6352 (should-not
6353 (equal "* H1 :foo:\nContents2"
6354 (org-test-with-temp-text "* H1\n<point>Contents2"
6355 (cl-letf (((symbol-function 'completing-read)
6356 (lambda (&rest args) ":foo:")))
6357 (let ((org-use-fast-tag-selection nil)
6358 (org-tags-column 1))
6359 (org-set-tags-command)))
6360 (org-at-heading-p))))
6361 ;; Strip all forbidden characters from user-entered tags.
6362 (should
6363 (equal "* H1 :foo:"
6364 (org-test-with-temp-text "* H1"
6365 (cl-letf (((symbol-function 'completing-read)
6366 (lambda (&rest args) ": foo *:")))
6367 (let ((org-use-fast-tag-selection nil)
6368 (org-tags-column 1))
6369 (org-set-tags-command)))
6370 (buffer-string))))
6371 ;; When a region is active and
6372 ;; `org-loop-over-headlines-in-active-region' is non-nil, insert the
6373 ;; same value in all headlines in region.
6374 (should
6375 (equal "* H1 :foo:\nContents\n* H2 :foo:"
6376 (org-test-with-temp-text "* H1\nContents\n* H2"
6377 (cl-letf (((symbol-function 'completing-read)
6378 (lambda (&rest args) ":foo:")))
6379 (let ((org-use-fast-tag-selection nil)
6380 (org-loop-over-headlines-in-active-region t)
6381 (org-tags-column 1))
6382 (transient-mark-mode 1)
6383 (push-mark (point) t t)
6384 (goto-char (point-max))
6385 (org-set-tags-command)))
6386 (buffer-string))))
6387 (should
6388 (equal "* H1\nContents\n* H2 :foo:"
6389 (org-test-with-temp-text "* H1\nContents\n* H2"
6390 (cl-letf (((symbol-function 'completing-read)
6391 (lambda (&rest args) ":foo:")))
6392 (let ((org-use-fast-tag-selection nil)
6393 (org-loop-over-headlines-in-active-region nil)
6394 (org-tags-column 1))
6395 (transient-mark-mode 1)
6396 (push-mark (point) t t)
6397 (goto-char (point-max))
6398 (org-set-tags-command)))
6399 (buffer-string))))
6400 ;; With a non-nil prefix argument, align all tags in the buffer.
6401 (should
6402 (equal "* H1 :foo:\n* H2 :bar:"
6403 (org-test-with-temp-text "* H1 :foo:\n* H2 :bar:"
6404 (let ((org-tags-column 1)) (org-set-tags-command t))
6405 (buffer-string)))))
6407 (ert-deftest test-org/toggle-tag ()
6408 "Test `org-toggle-tag' specifications."
6409 ;; Insert missing tag.
6410 (should
6411 (equal "* H :tag:"
6412 (org-test-with-temp-text "* H"
6413 (let ((org-tags-column 1)) (org-toggle-tag "tag"))
6414 (buffer-string))))
6415 (should
6416 (equal "* H :tag1:tag2:"
6417 (org-test-with-temp-text "* H :tag1:"
6418 (let ((org-tags-column 1)) (org-toggle-tag "tag2"))
6419 (buffer-string))))
6420 ;; Remove existing tag.
6421 (should
6422 (equal "* H"
6423 (org-test-with-temp-text "* H :tag:"
6424 (org-toggle-tag "tag")
6425 (buffer-string))))
6426 (should
6427 (equal "* H :tag1:"
6428 (org-test-with-temp-text "* H :tag1:tag2:"
6429 (let ((org-tags-column 1)) (org-toggle-tag "tag2"))
6430 (buffer-string))))
6431 (should
6432 (equal "* H :tag2:"
6433 (org-test-with-temp-text "* H :tag1:tag2:"
6434 (let ((org-tags-column 1)) (org-toggle-tag "tag1"))
6435 (buffer-string))))
6436 ;; With optional argument ONOFF set to `on', try to insert the tag,
6437 ;; even if its already there.
6438 (should
6439 (equal "* H :tag:"
6440 (org-test-with-temp-text "* H"
6441 (let ((org-tags-column 1)) (org-toggle-tag "tag" 'on))
6442 (buffer-string))))
6443 (should
6444 (equal "* H :tag:"
6445 (org-test-with-temp-text "* H :tag:"
6446 (let ((org-tags-column 1)) (org-toggle-tag "tag" 'on))
6447 (buffer-string))))
6448 ;; With optional argument ONOFF set to `off', try to remove the tag,
6449 ;; even if its not there.
6450 (should
6451 (equal "* H"
6452 (org-test-with-temp-text "* H :tag:"
6453 (org-toggle-tag "tag" 'off)
6454 (buffer-string))))
6455 (should
6456 (equal "* H :tag:"
6457 (org-test-with-temp-text "* H :tag:"
6458 (let ((org-tags-column 1)) (org-toggle-tag "foo" 'off))
6459 (buffer-string))))
6460 ;; Special case: Handle properly tag inheritance. In particular, do
6461 ;; not set inherited tags.
6462 (should
6463 (equal "* H1 :tag:\n** H2 :tag2:tag:"
6464 (org-test-with-temp-text "* H1 :tag:\n** <point>H2 :tag2:"
6465 (let ((org-use-tag-inheritance t)
6466 (org-tags-column 1))
6467 (org-toggle-tag "tag"))
6468 (buffer-string))))
6469 (should
6470 (equal "* H1 :tag1:tag2:\n** H2 :foo:"
6471 (org-test-with-temp-text "* H1 :tag1:tag2:\n** <point>H2"
6472 (let ((org-use-tag-inheritance t)
6473 (org-tags-column 1))
6474 (org-toggle-tag "foo"))
6475 (buffer-string)))))
6477 (ert-deftest test-org/tags-expand ()
6478 "Test `org-tags-expand' specifications."
6479 ;; Expand tag groups as a regexp enclosed withing curly brackets.
6480 (should
6481 (equal "{\\<[ABC]\\>}"
6482 (org-test-with-temp-text "#+TAGS: [ A : B C ]"
6483 (org-mode-restart)
6484 (let ((org-tag-alist-for-agenda nil)) (org-tags-expand "A")))))
6485 (should
6486 (equal "{\\<\\(?:Aa\\|Bb\\|Cc\\)\\>}"
6487 (org-test-with-temp-text "#+TAGS: [ Aa : Bb Cc ]"
6488 (org-mode-restart)
6489 (let ((org-tag-alist-for-agenda nil)) (org-tags-expand "Aa")))))
6490 ;; Preserve operator before the regexp.
6491 (should
6492 (equal "+{\\<[ABC]\\>}"
6493 (org-test-with-temp-text "#+TAGS: [ A : B C ]"
6494 (org-mode-restart)
6495 (let ((org-tag-alist-for-agenda nil)) (org-tags-expand "+A")))))
6496 (should
6497 (equal "-{\\<[ABC]\\>}"
6498 (org-test-with-temp-text "#+TAGS: [ A : B C ]"
6499 (org-mode-restart)
6500 (let ((org-tag-alist-for-agenda nil)) (org-tags-expand "-A")))))
6501 ;; Handle "|" syntax.
6502 (should
6503 (equal "{\\<[ABC]\\>}|D"
6504 (org-test-with-temp-text "#+TAGS: [ A : B C ]"
6505 (org-mode-restart)
6506 (let ((org-tag-alist-for-agenda nil)) (org-tags-expand "A|D")))))
6507 ;; Handle nested groups.
6508 (should
6509 (equal "{\\<[A-D]\\>}"
6510 (org-test-with-temp-text "#+TAGS: [ A : B C ]\n#+TAGS: [ B : D ]"
6511 (org-mode-restart)
6512 (let ((org-tag-alist-for-agenda nil)) (org-tags-expand "A")))))
6513 ;; Expand multiple occurrences of the same group.
6514 (should
6515 (equal "{\\<[ABC]\\>}|{\\<[ABC]\\>}"
6516 (org-test-with-temp-text "#+TAGS: [ A : B C ]"
6517 (org-mode-restart)
6518 (let ((org-tag-alist-for-agenda nil)) (org-tags-expand "A|A")))))
6519 ;; Preserve regexp matches.
6520 (should
6521 (equal "{A+}"
6522 (org-test-with-temp-text "#+TAGS: [ A : B C ]"
6523 (org-mode-restart)
6524 (let ((org-tag-alist-for-agenda nil)) (org-tags-expand "{A+}"))))))
6527 ;;; TODO keywords
6529 (ert-deftest test-org/auto-repeat-maybe ()
6530 "Test `org-auto-repeat-maybe' specifications."
6531 ;; Do not auto repeat when there is no valid time stamp with
6532 ;; a repeater in the entry.
6533 (should-not
6534 (string-prefix-p
6535 "* TODO H"
6536 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
6537 (org-test-with-temp-text "* TODO H\n<2012-03-29 Thu>"
6538 (org-todo "DONE")
6539 (buffer-string)))))
6540 (should-not
6541 (string-prefix-p
6542 "* TODO H"
6543 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
6544 (org-test-with-temp-text "* TODO H\n# <2012-03-29 Thu>"
6545 (org-todo "DONE")
6546 (buffer-string)))))
6547 ;; When switching to DONE state, switch back to first TODO keyword
6548 ;; in sequence, or the same keyword if they have different types.
6549 (should
6550 (string-prefix-p
6551 "* TODO H"
6552 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
6553 (org-test-with-temp-text "* TODO H\n<2012-03-29 Thu +2y>"
6554 (org-todo "DONE")
6555 (buffer-string)))))
6556 (should
6557 (string-prefix-p
6558 "* KWD1 H"
6559 (let ((org-todo-keywords '((sequence "KWD1" "KWD2" "DONE"))))
6560 (org-test-with-temp-text "* KWD2 H\n<2012-03-29 Thu +2y>"
6561 (org-todo "DONE")
6562 (buffer-string)))))
6563 (should
6564 (string-prefix-p
6565 "* KWD2 H"
6566 (let ((org-todo-keywords '((type "KWD1" "KWD2" "DONE"))))
6567 (org-test-with-temp-text "* KWD2 H\n<2012-03-29 Thu +2y>"
6568 (org-todo "DONE")
6569 (buffer-string)))))
6570 ;; If there was no TODO keyword in the first place, do not insert
6571 ;; any either.
6572 (should
6573 (string-prefix-p
6574 "* H"
6575 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
6576 (org-test-with-temp-text "* H\n<2012-03-29 Thu +2y>"
6577 (org-todo "DONE")
6578 (buffer-string)))))
6579 ;; Revert to REPEAT_TO_STATE, if set.
6580 (should
6581 (string-prefix-p
6582 "* KWD2 H"
6583 (let ((org-todo-keywords '((sequence "KWD1" "KWD2" "DONE"))))
6584 (org-test-with-temp-text
6585 "* KWD2 H
6586 :PROPERTIES:
6587 :REPEAT_TO_STATE: KWD2
6588 :END:
6589 <2012-03-29 Thu +2y>"
6590 (org-todo "DONE")
6591 (buffer-string)))))
6592 ;; When switching to DONE state, update base date. If there are
6593 ;; multiple repeated time stamps, update them all.
6594 (should
6595 (string-match-p
6596 "<2014-03-29 .* \\+2y>"
6597 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
6598 (org-test-with-temp-text "* TODO H\n<2012-03-29 Thu +2y>"
6599 (org-todo "DONE")
6600 (buffer-string)))))
6601 (should
6602 (string-match-p
6603 "<2015-03-04 .* \\+1y>"
6604 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
6605 (org-test-with-temp-text
6606 "* TODO H\n<2012-03-29 Thu. +2y>\n<2014-03-04 Tue +1y>"
6607 (org-todo "DONE")
6608 (buffer-string)))))
6609 ;; Throw an error if repeater unit is the hour and no time is
6610 ;; provided in the time-stamp.
6611 (should-error
6612 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
6613 (org-test-with-temp-text "* TODO H\n<2012-03-29 Thu +2h>"
6614 (org-todo "DONE")
6615 (buffer-string))))
6616 ;; Also repeat inactive time stamps with a repeater.
6617 (should
6618 (string-match-p
6619 "\\[2014-03-29 .* \\+2y\\]"
6620 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
6621 (org-test-with-temp-text
6622 "* TODO H\n[2012-03-29 Thu. +2y]"
6623 (org-todo "DONE")
6624 (buffer-string)))))
6625 ;; Do not repeat commented time stamps.
6626 (should-not
6627 (string-prefix-p
6628 "<2015-03-04 .* \\+1y>"
6629 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
6630 (org-test-with-temp-text
6631 "* TODO H\n<2012-03-29 Thu +2y>\n# <2014-03-04 Tue +1y>"
6632 (org-todo "DONE")
6633 (buffer-string)))))
6634 (should-not
6635 (string-prefix-p
6636 "<2015-03-04 .* \\+1y>"
6637 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
6638 (org-test-with-temp-text
6639 "* TODO H
6640 <2012-03-29 Thu. +2y>
6641 #+BEGIN_EXAMPLE
6642 <2014-03-04 Tue +1y>
6643 #+END_EXAMPLE"
6644 (org-todo "DONE")
6645 (buffer-string)))))
6646 ;; When `org-log-repeat' is non-nil or there is a CLOCK in the
6647 ;; entry, record time of last repeat.
6648 (should-not
6649 (string-match-p
6650 ":LAST_REPEAT:"
6651 (let ((org-todo-keywords '((sequence "TODO" "DONE")))
6652 (org-log-repeat nil))
6653 (cl-letf (((symbol-function 'org-add-log-setup)
6654 (lambda (&rest args) nil)))
6655 (org-test-with-temp-text "* TODO H\n<2012-03-29 Thu. +2y>"
6656 (org-todo "DONE")
6657 (buffer-string))))))
6658 (should
6659 (string-match-p
6660 ":LAST_REPEAT:"
6661 (let ((org-todo-keywords '((sequence "TODO" "DONE")))
6662 (org-log-repeat t))
6663 (cl-letf (((symbol-function 'org-add-log-setup)
6664 (lambda (&rest args) nil)))
6665 (org-test-with-temp-text "* TODO H\n<2012-03-29 Thu. +2y>"
6666 (org-todo "DONE")
6667 (buffer-string))))))
6668 (should
6669 (string-match-p
6670 ":LAST_REPEAT:"
6671 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
6672 (cl-letf (((symbol-function 'org-add-log-setup)
6673 (lambda (&rest args) nil)))
6674 (org-test-with-temp-text
6675 "* TODO H\n<2012-03-29 Thu +2y>\nCLOCK: [2012-03-29 Thu 16:40]"
6676 (org-todo "DONE")
6677 (buffer-string))))))
6678 ;; When a SCHEDULED entry has no repeater, remove it upon repeating
6679 ;; the entry as it is no longer relevant.
6680 (should-not
6681 (string-match-p
6682 "^SCHEDULED:"
6683 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
6684 (org-test-with-temp-text
6685 "* TODO H\nSCHEDULED: <2014-03-04 Tue>\n<2012-03-29 Thu +2y>"
6686 (org-todo "DONE")
6687 (buffer-string)))))
6688 ;; Properly advance repeater even when a clock entry is specified
6689 ;; and `org-log-repeat' is nil.
6690 (should
6691 (string-match-p
6692 "SCHEDULED: <2014-03-29"
6693 (let ((org-log-repeat nil)
6694 (org-todo-keywords '((sequence "TODO" "DONE"))))
6695 (org-test-with-temp-text
6696 "* TODO H
6697 SCHEDULED: <2012-03-29 Thu +2y>
6698 CLOCK: [2012-03-29 Thu 10:00]--[2012-03-29 Thu 16:40] => 6:40"
6699 (org-todo "DONE")
6700 (buffer-string))))))
6703 ;;; Timestamps API
6705 (ert-deftest test-org/at-timestamp-p ()
6706 "Test `org-at-timestamp-p' specifications."
6707 (should
6708 (org-test-with-temp-text "<2012-03-29 Thu>"
6709 (org-at-timestamp-p)))
6710 (should-not
6711 (org-test-with-temp-text "2012-03-29 Thu"
6712 (org-at-timestamp-p)))
6713 ;; Test return values.
6714 (should
6715 (eq 'bracket
6716 (org-test-with-temp-text "<2012-03-29 Thu>"
6717 (org-at-timestamp-p))))
6718 (should
6719 (eq 'year
6720 (org-test-with-temp-text "<<point>2012-03-29 Thu>"
6721 (org-at-timestamp-p))))
6722 (should
6723 (eq 'month
6724 (org-test-with-temp-text "<2012-<point>03-29 Thu>"
6725 (org-at-timestamp-p))))
6726 (should
6727 (eq 'day
6728 (org-test-with-temp-text "<2012-03-<point>29 Thu>"
6729 (org-at-timestamp-p))))
6730 (should
6731 (eq 'day
6732 (org-test-with-temp-text "<2012-03-29 T<point>hu>"
6733 (org-at-timestamp-p))))
6734 (should
6735 (wholenump
6736 (org-test-with-temp-text "<2012-03-29 Thu +2<point>y>"
6737 (org-at-timestamp-p))))
6738 (should
6739 (eq 'bracket
6740 (org-test-with-temp-text "<2012-03-29 Thu<point>>"
6741 (org-at-timestamp-p))))
6742 (should
6743 (eq 'after
6744 (org-test-with-temp-text "<2012-03-29 Thu><point>»"
6745 (org-at-timestamp-p))))
6746 ;; Test `inactive' optional argument.
6747 (should
6748 (org-test-with-temp-text "[2012-03-29 Thu]"
6749 (org-at-timestamp-p 'inactive)))
6750 (should-not
6751 (org-test-with-temp-text "[2012-03-29 Thu]"
6752 (org-at-timestamp-p)))
6753 ;; When optional argument is `agenda', recognize time-stamps in
6754 ;; planning info line, property drawers and clocks.
6755 (should
6756 (org-test-with-temp-text "* H\nSCHEDULED: <point><2012-03-29 Thu>"
6757 (org-at-timestamp-p 'agenda)))
6758 (should-not
6759 (org-test-with-temp-text "* H\nSCHEDULED: <point><2012-03-29 Thu>"
6760 (org-at-timestamp-p)))
6761 (should
6762 (org-test-with-temp-text
6763 "* H\n:PROPERTIES:\n:PROP: <point><2012-03-29 Thu>\n:END:"
6764 (org-at-timestamp-p 'agenda)))
6765 (should-not
6766 (org-test-with-temp-text
6767 "* H\n:PROPERTIES:\n:PROP: <point><2012-03-29 Thu>\n:END:"
6768 (org-at-timestamp-p)))
6769 (should
6770 (org-test-with-temp-text "CLOCK: <point>[2012-03-29 Thu]"
6771 (let ((org-agenda-include-inactive-timestamps t))
6772 (org-at-timestamp-p 'agenda))))
6773 (should-not
6774 (org-test-with-temp-text "CLOCK: <point>[2012-03-29 Thu]"
6775 (let ((org-agenda-include-inactive-timestamps t))
6776 (org-at-timestamp-p))))
6777 (should-not
6778 (org-test-with-temp-text "CLOCK: <point>[2012-03-29 Thu]"
6779 (let ((org-agenda-include-inactive-timestamps t))
6780 (org-at-timestamp-p 'inactive))))
6781 ;; When optional argument is `lax', match any part of the document
6782 ;; with Org timestamp syntax.
6783 (should
6784 (org-test-with-temp-text "# <2012-03-29 Thu><point>"
6785 (org-at-timestamp-p 'lax)))
6786 (should-not
6787 (org-test-with-temp-text "# <2012-03-29 Thu><point>"
6788 (org-at-timestamp-p)))
6789 (should
6790 (org-test-with-temp-text ": <2012-03-29 Thu><point>"
6791 (org-at-timestamp-p 'lax)))
6792 (should-not
6793 (org-test-with-temp-text ": <2012-03-29 Thu><point>"
6794 (org-at-timestamp-p)))
6795 (should
6796 (org-test-with-temp-text
6797 "#+BEGIN_EXAMPLE\n<2012-03-29 Thu><point>\n#+END_EXAMPLE"
6798 (org-at-timestamp-p 'lax)))
6799 (should-not
6800 (org-test-with-temp-text
6801 "#+BEGIN_EXAMPLE\n<2012-03-29 Thu><point>\n#+END_EXAMPLE"
6802 (org-at-timestamp-p)))
6803 ;; Optional argument `lax' also matches inactive timestamps.
6804 (should
6805 (org-test-with-temp-text "# [2012-03-29 Thu]<point>"
6806 (org-at-timestamp-p 'lax))))
6808 (ert-deftest test-org/time-stamp ()
6809 "Test `org-time-stamp' specifications."
6810 ;; Insert chosen time stamp at point.
6811 (should
6812 (string-match
6813 "Te<2014-03-04 .*?>xt"
6814 (org-test-with-temp-text "Te<point>xt"
6815 (cl-letf (((symbol-function 'org-read-date)
6816 (lambda (&rest args)
6817 (apply #'encode-time (org-parse-time-string "2014-03-04")))))
6818 (org-time-stamp nil)
6819 (buffer-string)))))
6820 ;; With a prefix argument, also insert time.
6821 (should
6822 (string-match
6823 "Te<2014-03-04 .*? 00:41>xt"
6824 (org-test-with-temp-text "Te<point>xt"
6825 (cl-letf (((symbol-function 'org-read-date)
6826 (lambda (&rest args)
6827 (apply #'encode-time
6828 (org-parse-time-string "2014-03-04 00:41")))))
6829 (org-time-stamp '(4))
6830 (buffer-string)))))
6831 ;; With two universal prefix arguments, insert an active timestamp
6832 ;; with the current time without prompting the user.
6833 (should
6834 (string-match
6835 "Te<2014-03-04 .*? 00:41>xt"
6836 (org-test-with-temp-text "Te<point>xt"
6837 (cl-letf (((symbol-function 'current-time)
6838 (lambda ()
6839 (apply #'encode-time
6840 (org-parse-time-string "2014-03-04 00:41")))))
6841 (org-time-stamp '(16))
6842 (buffer-string)))))
6843 ;; When optional argument is non-nil, insert an inactive timestamp.
6844 (should
6845 (string-match
6846 "Te\\[2014-03-04 .*?\\]xt"
6847 (org-test-with-temp-text "Te<point>xt"
6848 (cl-letf (((symbol-function 'org-read-date)
6849 (lambda (&rest args)
6850 (apply #'encode-time (org-parse-time-string "2014-03-04")))))
6851 (org-time-stamp nil t)
6852 (buffer-string)))))
6853 ;; When called from a timestamp, replace existing one.
6854 (should
6855 (string-match
6856 "<2014-03-04 .*?>"
6857 (org-test-with-temp-text "<2012-03-29<point> thu.>"
6858 (cl-letf (((symbol-function 'org-read-date)
6859 (lambda (&rest args)
6860 (apply #'encode-time (org-parse-time-string "2014-03-04")))))
6861 (org-time-stamp nil)
6862 (buffer-string)))))
6863 (should
6864 (string-match
6865 "<2014-03-04 .*?>--<2014-03-04 .*?>"
6866 (org-test-with-temp-text "<2012-03-29<point> thu.>--<2014-03-04 tue.>"
6867 (cl-letf (((symbol-function 'org-read-date)
6868 (lambda (&rest args)
6869 (apply #'encode-time (org-parse-time-string "2014-03-04")))))
6870 (org-time-stamp nil)
6871 (buffer-string)))))
6872 ;; When replacing a timestamp, preserve repeater, if any.
6873 (should
6874 (string-match
6875 "<2014-03-04 .*? \\+2y>"
6876 (org-test-with-temp-text "<2012-03-29<point> thu. +2y>"
6877 (cl-letf (((symbol-function 'org-read-date)
6878 (lambda (&rest args)
6879 (apply #'encode-time (org-parse-time-string "2014-03-04")))))
6880 (org-time-stamp nil)
6881 (buffer-string)))))
6882 ;; When called twice in a raw, build a date range.
6883 (should
6884 (string-match
6885 "<2012-03-29 .*?>--<2014-03-04 .*?>"
6886 (org-test-with-temp-text "<2012-03-29 thu.><point>"
6887 (cl-letf (((symbol-function 'org-read-date)
6888 (lambda (&rest args)
6889 (apply #'encode-time (org-parse-time-string "2014-03-04")))))
6890 (let ((last-command 'org-time-stamp)
6891 (this-command 'org-time-stamp))
6892 (org-time-stamp nil))
6893 (buffer-string))))))
6895 (ert-deftest test-org/timestamp-has-time-p ()
6896 "Test `org-timestamp-has-time-p' specifications."
6897 ;; With time.
6898 (should
6899 (org-test-with-temp-text "<2012-03-29 Thu 16:40>"
6900 (org-timestamp-has-time-p (org-element-context))))
6901 ;; Without time.
6902 (should-not
6903 (org-test-with-temp-text "<2012-03-29 Thu>"
6904 (org-timestamp-has-time-p (org-element-context)))))
6906 (ert-deftest test-org/get-repeat ()
6907 "Test `org-get-repeat' specifications."
6908 (should
6909 (org-test-with-temp-text "* H\n<2012-03-29 Thu 16:40 +2y>"
6910 (org-get-repeat)))
6911 (should-not
6912 (org-test-with-temp-text "* H\n<2012-03-29 Thu 16:40>"
6913 (org-get-repeat)))
6914 ;; Return proper repeat string.
6915 (should
6916 (equal "+2y"
6917 (org-test-with-temp-text "* H\n<2014-03-04 Tue 16:40 +2y>"
6918 (org-get-repeat))))
6919 ;; Prevent false positive (commented or verbatim time stamps)
6920 (should-not
6921 (org-test-with-temp-text "* H\n# <2012-03-29 Thu 16:40>"
6922 (org-get-repeat)))
6923 (should-not
6924 (org-test-with-temp-text
6925 "* H\n#+BEGIN_EXAMPLE\n<2012-03-29 Thu 16:40>\n#+END_EXAMPLE"
6926 (org-get-repeat)))
6927 ;; Return nil when called before first heading.
6928 (should-not
6929 (org-test-with-temp-text "<2012-03-29 Thu 16:40 +2y>"
6930 (org-get-repeat)))
6931 ;; When called with an optional argument, extract repeater from that
6932 ;; string instead.
6933 (should (equal "+2y" (org-get-repeat "<2012-03-29 Thu 16:40 +2y>")))
6934 (should-not (org-get-repeat "<2012-03-29 Thu 16:40>")))
6936 (ert-deftest test-org/timestamp-format ()
6937 "Test `org-timestamp-format' specifications."
6938 ;; Regular test.
6939 (should
6940 (equal
6941 "2012-03-29 16:40"
6942 (org-test-with-temp-text "<2012-03-29 Thu 16:40>"
6943 (org-timestamp-format (org-element-context) "%Y-%m-%d %R"))))
6944 ;; Range end.
6945 (should
6946 (equal
6947 "2012-03-29"
6948 (org-test-with-temp-text "[2011-07-14 Thu]--[2012-03-29 Thu]"
6949 (org-timestamp-format (org-element-context) "%Y-%m-%d" t)))))
6951 (ert-deftest test-org/timestamp-split-range ()
6952 "Test `org-timestamp-split-range' specifications."
6953 ;; Extract range start (active).
6954 (should
6955 (equal '(2012 3 29)
6956 (org-test-with-temp-text "<2012-03-29 Thu>--<2012-03-30 Fri>"
6957 (let ((ts (org-timestamp-split-range (org-element-context))))
6958 (mapcar (lambda (p) (org-element-property p ts))
6959 '(:year-end :month-end :day-end))))))
6960 ;; Extract range start (inactive)
6961 (should
6962 (equal '(2012 3 29)
6963 (org-test-with-temp-text "[2012-03-29 Thu]--[2012-03-30 Fri]"
6964 (let ((ts (org-timestamp-split-range (org-element-context))))
6965 (mapcar (lambda (p) (org-element-property p ts))
6966 '(:year-end :month-end :day-end))))))
6967 ;; Extract range end (active).
6968 (should
6969 (equal '(2012 3 30)
6970 (org-test-with-temp-text "<2012-03-29 Thu>--<2012-03-30 Fri>"
6971 (let ((ts (org-timestamp-split-range
6972 (org-element-context) t)))
6973 (mapcar (lambda (p) (org-element-property p ts))
6974 '(:year-end :month-end :day-end))))))
6975 ;; Extract range end (inactive)
6976 (should
6977 (equal '(2012 3 30)
6978 (org-test-with-temp-text "[2012-03-29 Thu]--[2012-03-30 Fri]"
6979 (let ((ts (org-timestamp-split-range
6980 (org-element-context) t)))
6981 (mapcar (lambda (p) (org-element-property p ts))
6982 '(:year-end :month-end :day-end))))))
6983 ;; Return the timestamp if not a range.
6984 (should
6985 (org-test-with-temp-text "[2012-03-29 Thu]"
6986 (let* ((ts-orig (org-element-context))
6987 (ts-copy (org-timestamp-split-range ts-orig)))
6988 (eq ts-orig ts-copy))))
6989 (should
6990 (org-test-with-temp-text "<%%(org-float t 4 2)>"
6991 (let* ((ts-orig (org-element-context))
6992 (ts-copy (org-timestamp-split-range ts-orig)))
6993 (eq ts-orig ts-copy)))))
6995 (ert-deftest test-org/timestamp-translate ()
6996 "Test `org-timestamp-translate' specifications."
6997 ;; Translate whole date range.
6998 (should
6999 (equal "<29>--<30>"
7000 (org-test-with-temp-text "<2012-03-29 Thu>--<2012-03-30 Fri>"
7001 (let ((org-display-custom-times t)
7002 (org-time-stamp-custom-formats '("<%d>" . "<%d>")))
7003 (org-timestamp-translate (org-element-context))))))
7004 ;; Translate date range start.
7005 (should
7006 (equal "<29>"
7007 (org-test-with-temp-text "<2012-03-29 Thu>--<2012-03-30 Fri>"
7008 (let ((org-display-custom-times t)
7009 (org-time-stamp-custom-formats '("<%d>" . "<%d>")))
7010 (org-timestamp-translate (org-element-context) 'start)))))
7011 ;; Translate date range end.
7012 (should
7013 (equal "<30>"
7014 (org-test-with-temp-text "<2012-03-29 Thu>--<2012-03-30 Fri>"
7015 (let ((org-display-custom-times t)
7016 (org-time-stamp-custom-formats '("<%d>" . "<%d>")))
7017 (org-timestamp-translate (org-element-context) 'end)))))
7018 ;; Translate time range.
7019 (should
7020 (equal "<08>--<16>"
7021 (org-test-with-temp-text "<2012-03-29 Thu 8:30-16:40>"
7022 (let ((org-display-custom-times t)
7023 (org-time-stamp-custom-formats '("<%d>" . "<%H>")))
7024 (org-timestamp-translate (org-element-context))))))
7025 ;; Translate non-range timestamp.
7026 (should
7027 (equal "<29>"
7028 (org-test-with-temp-text "<2012-03-29 Thu>"
7029 (let ((org-display-custom-times t)
7030 (org-time-stamp-custom-formats '("<%d>" . "<%d>")))
7031 (org-timestamp-translate (org-element-context))))))
7032 ;; Do not change `diary' timestamps.
7033 (should
7034 (equal "<%%(org-float t 4 2)>"
7035 (org-test-with-temp-text "<%%(org-float t 4 2)>"
7036 (let ((org-display-custom-times t)
7037 (org-time-stamp-custom-formats '("<%d>" . "<%d>")))
7038 (org-timestamp-translate (org-element-context)))))))
7040 (ert-deftest test-org/timestamp-from-string ()
7041 "Test `org-timestamp-from-string' specifications."
7042 ;; Return nil if argument is not a valid Org timestamp.
7043 (should-not (org-timestamp-from-string ""))
7044 (should-not (org-timestamp-from-string nil))
7045 (should-not (org-timestamp-from-string "<2012-03-29"))
7046 ;; Otherwise, return a valid Org timestamp object.
7047 (should
7048 (equal "<2012-03-29 Thu>"
7049 (let ((system-time-locale "en_US"))
7050 (org-element-interpret-data
7051 (org-timestamp-from-string "<2012-03-29 Thu>")))))
7052 (should
7053 (equal "[2014-03-04 Tue]"
7054 (let ((system-time-locale "en_US"))
7055 (org-element-interpret-data
7056 (org-timestamp-from-string "[2014-03-04 Tue]"))))))
7058 (ert-deftest test-org/timestamp-from-time ()
7059 "Test `org-timestamp-from-time' specifications."
7060 ;; Standard test.
7061 (should
7062 (equal "<2012-03-29 Thu>"
7063 (let ((system-time-locale "en_US"))
7064 (org-element-interpret-data
7065 (org-timestamp-from-time
7066 (apply #'encode-time
7067 (org-parse-time-string "<2012-03-29 Thu 16:40>")))))))
7068 ;; When optional argument WITH-TIME is non-nil, provide time
7069 ;; information.
7070 (should
7071 (equal "<2012-03-29 Thu 16:40>"
7072 (let ((system-time-locale "en_US"))
7073 (org-element-interpret-data
7074 (org-timestamp-from-time
7075 (apply #'encode-time
7076 (org-parse-time-string "<2012-03-29 Thu 16:40>"))
7077 t)))))
7078 ;; When optional argument INACTIVE is non-nil, return an inactive
7079 ;; timestamp.
7080 (should
7081 (equal "[2012-03-29 Thu]"
7082 (let ((system-time-locale "en_US"))
7083 (org-element-interpret-data
7084 (org-timestamp-from-time
7085 (apply #'encode-time
7086 (org-parse-time-string "<2012-03-29 Thu 16:40>"))
7087 nil t))))))
7089 (ert-deftest test-org/timestamp-to-time ()
7090 "Test `org-timestamp-to-time' specifications."
7091 (should
7092 (equal "2014-03-04"
7093 (format-time-string
7094 "%Y-%m-%d"
7095 (org-timestamp-to-time
7096 (org-timestamp-from-string "<2014-03-04 Tue>")))))
7097 (should
7098 (equal "2014-03-04"
7099 (format-time-string
7100 "%Y-%m-%d"
7101 (org-timestamp-to-time
7102 (org-timestamp-from-string "[2014-03-04 Tue]")))))
7103 (should
7104 (equal "2012-03-29 08:30"
7105 (format-time-string
7106 "%Y-%m-%d %H:%M"
7107 (org-timestamp-to-time
7108 (org-timestamp-from-string "<2012-03-29 Thu 08:30-16:40>")))))
7109 (should
7110 (equal "2012-03-29"
7111 (format-time-string
7112 "%Y-%m-%d"
7113 (org-timestamp-to-time
7114 (org-timestamp-from-string "<2012-03-29 Thu>--<2014-03-04 Tue>")))))
7115 (should
7116 (equal "2012-03-29"
7117 (format-time-string
7118 "%Y-%m-%d"
7119 (org-timestamp-to-time
7120 (org-timestamp-from-string "[2012-03-29 Thu]--[2014-03-04 Tue]")))))
7121 ;; When optional argument END is non-nil, use end of date range or
7122 ;; time range.
7123 (should
7124 (equal "2012-03-29 16:40"
7125 (format-time-string
7126 "%Y-%m-%d %H:%M"
7127 (org-timestamp-to-time
7128 (org-timestamp-from-string "<2012-03-29 Thu 08:30-16:40>")
7129 t))))
7130 (should
7131 (equal "2014-03-04"
7132 (format-time-string
7133 "%Y-%m-%d"
7134 (org-timestamp-to-time
7135 (org-timestamp-from-string "<2012-03-29 Thu>--<2014-03-04 Tue>")
7136 t))))
7137 (should
7138 (equal "2014-03-04"
7139 (format-time-string
7140 "%Y-%m-%d"
7141 (org-timestamp-to-time
7142 (org-timestamp-from-string "[2012-03-29 Thu]--[2014-03-04 Tue]")
7143 t)))))
7146 ;;; Visibility
7148 (ert-deftest test-org/flag-drawer ()
7149 "Test `org-flag-drawer' specifications."
7150 ;; Hide drawer.
7151 (should
7152 (org-test-with-temp-text ":DRAWER:\ncontents\n:END:"
7153 (org-flag-drawer t)
7154 (get-char-property (line-end-position) 'invisible)))
7155 ;; Show drawer.
7156 (should-not
7157 (org-test-with-temp-text ":DRAWER:\ncontents\n:END:"
7158 (org-flag-drawer t)
7159 (org-flag-drawer nil)
7160 (get-char-property (line-end-position) 'invisible)))
7161 ;; Test optional argument.
7162 (should
7163 (org-test-with-temp-text "Text\n:D1:\nc1\n:END:\n\n:D2:\nc2\n:END:"
7164 (let ((drawer (save-excursion (search-forward ":D2")
7165 (org-element-at-point))))
7166 (org-flag-drawer t drawer)
7167 (get-char-property (progn (search-forward ":D2") (line-end-position))
7168 'invisible))))
7169 (should-not
7170 (org-test-with-temp-text ":D1:\nc1\n:END:\n\n:D2:\nc2\n:END:"
7171 (let ((drawer (save-excursion (search-forward ":D2")
7172 (org-element-at-point))))
7173 (org-flag-drawer t drawer)
7174 (get-char-property (line-end-position) 'invisible))))
7175 ;; Do not hide fake drawers.
7176 (should-not
7177 (org-test-with-temp-text "#+begin_example\n:D:\nc\n:END:\n#+end_example"
7178 (forward-line 1)
7179 (org-flag-drawer t)
7180 (get-char-property (line-end-position) 'invisible)))
7181 ;; Do not hide incomplete drawers.
7182 (should-not
7183 (org-test-with-temp-text ":D:\nparagraph"
7184 (forward-line 1)
7185 (org-flag-drawer t)
7186 (get-char-property (line-end-position) 'invisible)))
7187 ;; Do not hide drawers when called from final blank lines.
7188 (should-not
7189 (org-test-with-temp-text ":DRAWER:\nA\n:END:\n\n"
7190 (goto-char (point-max))
7191 (org-flag-drawer t)
7192 (goto-char (point-min))
7193 (get-char-property (line-end-position) 'invisible)))
7194 ;; Don't leave point in an invisible part of the buffer when hiding
7195 ;; a drawer away.
7196 (should-not
7197 (org-test-with-temp-text ":DRAWER:\ncontents\n:END:"
7198 (goto-char (point-max))
7199 (org-flag-drawer t)
7200 (get-char-property (point) 'invisible))))
7202 (ert-deftest test-org/hide-block-toggle ()
7203 "Test `org-hide-block-toggle' specifications."
7204 ;; Error when not at a block.
7205 (should-error
7206 (org-test-with-temp-text "#+BEGIN_QUOTE\ncontents"
7207 (org-hide-block-toggle 'off)
7208 (get-char-property (line-end-position) 'invisible)))
7209 ;; Hide block.
7210 (should
7211 (org-test-with-temp-text "#+BEGIN_CENTER\ncontents\n#+END_CENTER"
7212 (org-hide-block-toggle)
7213 (get-char-property (line-end-position) 'invisible)))
7214 (should
7215 (org-test-with-temp-text "#+BEGIN_EXAMPLE\ncontents\n#+END_EXAMPLE"
7216 (org-hide-block-toggle)
7217 (get-char-property (line-end-position) 'invisible)))
7218 ;; Show block unconditionally when optional argument is `off'.
7219 (should-not
7220 (org-test-with-temp-text "#+BEGIN_QUOTE\ncontents\n#+END_QUOTE"
7221 (org-hide-block-toggle)
7222 (org-hide-block-toggle 'off)
7223 (get-char-property (line-end-position) 'invisible)))
7224 (should-not
7225 (org-test-with-temp-text "#+BEGIN_QUOTE\ncontents\n#+END_QUOTE"
7226 (org-hide-block-toggle 'off)
7227 (get-char-property (line-end-position) 'invisible)))
7228 ;; Hide block unconditionally when optional argument is non-nil.
7229 (should
7230 (org-test-with-temp-text "#+BEGIN_QUOTE\ncontents\n#+END_QUOTE"
7231 (org-hide-block-toggle t)
7232 (get-char-property (line-end-position) 'invisible)))
7233 (should
7234 (org-test-with-temp-text "#+BEGIN_QUOTE\ncontents\n#+END_QUOTE"
7235 (org-hide-block-toggle)
7236 (org-hide-block-toggle t)
7237 (get-char-property (line-end-position) 'invisible)))
7238 ;; Do not hide block when called from final blank lines.
7239 (should-not
7240 (org-test-with-temp-text "#+BEGIN_QUOTE\ncontents\n#+END_QUOTE\n\n<point>"
7241 (org-hide-block-toggle)
7242 (goto-char (point-min))
7243 (get-char-property (line-end-position) 'invisible)))
7244 ;; Don't leave point in an invisible part of the buffer when hiding
7245 ;; a block away.
7246 (should-not
7247 (org-test-with-temp-text "#+BEGIN_QUOTE\ncontents\n<point>#+END_QUOTE"
7248 (org-hide-block-toggle)
7249 (get-char-property (point) 'invisible))))
7251 (ert-deftest test-org/hide-block-toggle-maybe ()
7252 "Test `org-hide-block-toggle-maybe' specifications."
7253 (should
7254 (org-test-with-temp-text "#+BEGIN: dynamic\nContents\n#+END:"
7255 (org-hide-block-toggle-maybe)))
7256 (should-not
7257 (org-test-with-temp-text "Paragraph" (org-hide-block-toggle-maybe))))
7259 (ert-deftest test-org/show-set-visibility ()
7260 "Test `org-show-set-visibility' specifications."
7261 ;; Do not throw an error before first heading.
7262 (should
7263 (org-test-with-temp-text "Preamble\n* Headline"
7264 (org-show-set-visibility 'tree)
7266 ;; Test all visibility spans, both on headline and in entry.
7267 (let ((list-visible-lines
7268 (lambda (state headerp)
7269 (org-test-with-temp-text "* Grandmother (0)
7270 ** Uncle (1)
7271 *** Heir (2)
7272 ** Father (3)
7273 Ancestor text (4)
7274 *** Sister (5)
7275 Sibling text (6)
7276 *** Self (7)
7277 Match (8)
7278 **** First born (9)
7279 Child text (10)
7280 **** The other child (11)
7281 *** Brother (12)
7282 ** Aunt (13)
7284 (org-cycle t)
7285 (search-forward (if headerp "Self" "Match"))
7286 (org-show-set-visibility state)
7287 (goto-char (point-min))
7288 (let (result (line 0))
7289 (while (not (eobp))
7290 (unless (org-invisible-p2) (push line result))
7291 (cl-incf line)
7292 (forward-line))
7293 (nreverse result))))))
7294 (should (equal '(0 7) (funcall list-visible-lines 'minimal t)))
7295 (should (equal '(0 7 8) (funcall list-visible-lines 'minimal nil)))
7296 (should (equal '(0 7 8 9) (funcall list-visible-lines 'local t)))
7297 (should (equal '(0 7 8 9) (funcall list-visible-lines 'local nil)))
7298 (should (equal '(0 3 7) (funcall list-visible-lines 'ancestors t)))
7299 (should (equal '(0 3 7 8) (funcall list-visible-lines 'ancestors nil)))
7300 (should (equal '(0 3 5 7 12) (funcall list-visible-lines 'lineage t)))
7301 (should (equal '(0 3 5 7 8 9 12) (funcall list-visible-lines 'lineage nil)))
7302 (should (equal '(0 1 3 5 7 12 13) (funcall list-visible-lines 'tree t)))
7303 (should (equal '(0 1 3 5 7 8 9 11 12 13)
7304 (funcall list-visible-lines 'tree nil)))
7305 (should (equal '(0 1 3 4 5 7 12 13)
7306 (funcall list-visible-lines 'canonical t)))
7307 (should (equal '(0 1 3 4 5 7 8 9 11 12 13)
7308 (funcall list-visible-lines 'canonical nil))))
7309 ;; When point is hidden in a drawer or a block, make sure to make it
7310 ;; visible.
7311 (should-not
7312 (org-test-with-temp-text "#+BEGIN_QUOTE\nText\n#+END_QUOTE"
7313 (org-hide-block-toggle)
7314 (search-forward "Text")
7315 (org-show-set-visibility 'minimal)
7316 (org-invisible-p2)))
7317 (should-not
7318 (org-test-with-temp-text ":DRAWER:\nText\n:END:"
7319 (org-flag-drawer t)
7320 (search-forward "Text")
7321 (org-show-set-visibility 'minimal)
7322 (org-invisible-p2)))
7323 (should-not
7324 (org-test-with-temp-text
7325 "#+BEGIN_QUOTE\n<point>:DRAWER:\nText\n:END:\n#+END_QUOTE"
7326 (org-flag-drawer t)
7327 (forward-line -1)
7328 (org-hide-block-toggle)
7329 (search-forward "Text")
7330 (org-show-set-visibility 'minimal)
7331 (org-invisible-p2))))
7333 (defun test-org/copy-visible ()
7334 "Test `org-copy-visible' specifications."
7335 (should
7336 (equal "Foo"
7337 (org-test-with-temp-text "Foo"
7338 (let ((kill-ring nil))
7339 (org-copy-visible (point-min) (point-max))
7340 (current-kill 0 t)))))
7341 ;; Skip invisible characters by text property.
7342 (should
7343 (equal "Foo"
7344 (org-test-with-temp-text #("F<hidden>oo" 1 7 (invisible t))
7345 (let ((kill-ring nil))
7346 (org-copy-visible (point-min) (point-max))
7347 (current-kill 0 t)))))
7348 ;; Skip invisible characters by overlay.
7349 (should
7350 (equal "Foo"
7351 (org-test-with-temp-text "F<hidden>oo"
7352 (let ((o (make-overlay 2 10)))
7353 (overlay-put o 'invisible t))
7354 (let ((kill-ring nil))
7355 (org-copy-visible (point-min) (point-max))
7356 (current-kill 0 t)))))
7357 ;; Handle invisible characters at the beginning and the end of the
7358 ;; buffer.
7359 (should
7360 (equal "Foo"
7361 (org-test-with-temp-text #("<hidden>Foo" 0 8 (invisible t))
7362 (let ((kill-ring nil))
7363 (org-copy-visible (point-min) (point-max))
7364 (current-kill 0 t)))))
7365 (should
7366 (equal "Foo"
7367 (org-test-with-temp-text #("Foo<hidden>" 3 11 (invisible t))
7368 (let ((kill-ring nil))
7369 (org-copy-visible (point-min) (point-max))
7370 (current-kill 0 t)))))
7371 ;; Handle multiple visible parts.
7372 (should
7373 (equal "abc"
7374 (org-test-with-temp-text
7375 #("aXbXc" 1 2 (invisible t) 3 4 (invisible t))
7376 (let ((kill-ring nil))
7377 (org-copy-visible (point-min) (point-max))
7378 (current-kill 0 t))))))
7380 (ert-deftest test-org/set-visibility-according-to-property ()
7381 "Test `org-set-visibility-according-to-property' specifications."
7382 ;; "folded" state.
7383 (should
7384 (org-test-with-temp-text
7387 :PROPERTIES:
7388 :VISIBILITY: folded
7389 :END:
7390 ** <point>b"
7391 (org-set-visibility-according-to-property)
7392 (invisible-p (point))))
7393 ;; "children" state.
7394 (should
7395 (org-test-with-temp-text
7398 :PROPERTIES:
7399 :VISIBILITY: children
7400 :END:
7401 ** b
7402 <point>Contents
7403 ** c"
7404 (org-set-visibility-according-to-property)
7405 (invisible-p (point))))
7406 (should
7407 (org-test-with-temp-text
7410 :PROPERTIES:
7411 :VISIBILITY: children
7412 :END:
7413 ** b
7414 Contents
7415 *** <point>c"
7416 (org-set-visibility-according-to-property)
7417 (invisible-p (point))))
7418 ;; "content" state.
7419 (should
7420 (org-test-with-temp-text
7423 :PROPERTIES:
7424 :VISIBILITY: content
7425 :END:
7426 ** b
7427 <point>Contents
7428 *** c"
7429 (org-set-visibility-according-to-property)
7430 (invisible-p (point))))
7431 (should
7432 (org-test-with-temp-text
7435 :PROPERTIES:
7436 :VISIBILITY: content
7437 :END:
7438 ** b
7439 Contents
7440 *** <point>c"
7441 (org-set-visibility-according-to-property)
7442 (not (invisible-p (point)))))
7443 ;; "showall" state.
7444 (should
7445 (org-test-with-temp-text
7448 :PROPERTIES:
7449 :VISIBILITY: showall
7450 :END:
7451 ** b
7452 <point>Contents
7453 *** c"
7454 (org-set-visibility-according-to-property)
7455 (not (invisible-p (point)))))
7456 (should
7457 (org-test-with-temp-text
7460 :PROPERTIES:
7461 :VISIBILITY: showall
7462 :END:
7463 ** b
7464 Contents
7465 *** <point>c"
7466 (org-set-visibility-according-to-property)
7467 (not (invisible-p (point))))))
7470 ;;; Yank and Kill
7472 (ert-deftest test-org/paste-subtree ()
7473 "Test `org-paste-subtree' specifications."
7474 ;; Return an error if text to yank is not a set of subtrees.
7475 (should-error (org-paste-subtree nil "Text"))
7476 ;; Adjust level according to current one.
7477 (should
7478 (equal "* H\n* Text\n"
7479 (org-test-with-temp-text "* H\n<point>"
7480 (org-paste-subtree nil "* Text")
7481 (buffer-string))))
7482 (should
7483 (equal "* H1\n** H2\n** Text\n"
7484 (org-test-with-temp-text "* H1\n** H2\n<point>"
7485 (org-paste-subtree nil "* Text")
7486 (buffer-string))))
7487 ;; When not on a heading, move to next heading before yanking.
7488 (should
7489 (equal "* H1\nParagraph\n* Text\n* H2"
7490 (org-test-with-temp-text "* H1\n<point>Paragraph\n* H2"
7491 (org-paste-subtree nil "* Text")
7492 (buffer-string))))
7493 ;; If point is between two headings, use the deepest level.
7494 (should
7495 (equal "* H1\n\n* Text\n* H2"
7496 (org-test-with-temp-text "* H1\n<point>\n* H2"
7497 (org-paste-subtree nil "* Text")
7498 (buffer-string))))
7499 (should
7500 (equal "** H1\n\n** Text\n* H2"
7501 (org-test-with-temp-text "** H1\n<point>\n* H2"
7502 (org-paste-subtree nil "* Text")
7503 (buffer-string))))
7504 (should
7505 (equal "* H1\n\n** Text\n** H2"
7506 (org-test-with-temp-text "* H1\n<point>\n** H2"
7507 (org-paste-subtree nil "* Text")
7508 (buffer-string))))
7509 ;; When on an empty heading, after the stars, deduce the new level
7510 ;; from the number of stars.
7511 (should
7512 (equal "*** Text\n"
7513 (org-test-with-temp-text "*** <point>"
7514 (org-paste-subtree nil "* Text")
7515 (buffer-string))))
7516 ;; Optional argument LEVEL forces a level for the subtree.
7517 (should
7518 (equal "* H\n*** Text\n"
7519 (org-test-with-temp-text "* H<point>"
7520 (org-paste-subtree 3 "* Text")
7521 (buffer-string)))))
7523 (ert-deftest test-org/cut-and-paste-subtree ()
7524 "Test `org-cut-subtree' and `org-paste-subtree'."
7525 (should
7526 (equal
7527 "* Two
7529 * One
7531 (org-test-with-temp-text
7532 "* One
7533 <point>* Two
7536 (call-interactively #'org-cut-subtree)
7537 (goto-char (point-min))
7538 (call-interactively #'org-paste-subtree)
7539 (buffer-string))))
7540 (should
7541 (equal
7542 "* One
7543 * Two
7545 (org-test-with-temp-text
7546 "* One
7547 <point>* Two
7549 (call-interactively #'org-cut-subtree)
7550 (backward-char)
7551 (call-interactively #'org-paste-subtree)
7552 (buffer-string)))))
7554 (provide 'test-org)
7556 ;;; test-org.el ends here