1 ;;; test-org-element.el --- Tests for org-element.el
3 ;; Copyright (C) 2012, 2013 Nicolas Goaziou
5 ;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
7 ;; This program is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
12 ;; This program is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
22 (unless (featurep 'org-element
)
23 (signal 'missing-test-dependency
"org-element"))
25 (defun org-test-parse-and-interpret (text)
26 "Parse TEXT as Org syntax and interpret it.
27 Return interpreted string."
31 (org-element-interpret-data (org-element-parse-buffer))))
35 ;;; Test `org-element-map'
37 (ert-deftest test-org-element
/map
()
38 "Test `org-element-map'."
39 ;; Can map to `plain-text' objects.
42 (org-test-with-temp-text "Some text \alpha
48 (org-element-parse-buffer) 'plain-text
49 (lambda (s) (when (string-match "text" s
) (incf count
))))
51 ;; Applies to secondary strings
53 (org-element-map '("some " (bold nil
"bold") "text") 'bold
'identity
))
54 ;; Enter secondary strings before entering contents.
60 (org-test-with-temp-text "* Some \\alpha headline\n\\beta entity."
61 (org-element-map (org-element-parse-buffer) 'entity
'identity nil t
)))))
62 ;; Apply NO-RECURSION argument.
64 (org-test-with-temp-text "#+BEGIN_CENTER\n\\alpha\n#+END_CENTER"
66 (org-element-parse-buffer) 'entity
'identity nil nil
'center-block
)))
67 ;; Use WITH-AFFILIATED argument.
71 (org-test-with-temp-text "#+CAPTION[a]: 1\n#+CAPTION[b]: 2\nParagraph"
73 (org-element-at-point) 'plain-text
'identity nil nil nil t
)))))
79 (ert-deftest test-org-element
/put-property
()
80 "Test `org-element-put-property' specifications."
82 (org-test-with-temp-text "* Headline\n *a*"
83 (let ((tree (org-element-parse-buffer)))
84 (org-element-put-property
85 (org-element-map tree
'bold
'identity nil t
) :test
1)
86 (should (org-element-property
87 :test
(org-element-map tree
'bold
'identity nil t
)))))
88 ;; Put property on a string.
90 (org-element-property :test
(org-element-put-property "Paragraph" :test t
))))
92 (ert-deftest test-org-element
/set-contents
()
93 "Test `org-element-set-contents' specifications."
94 ;; Accept multiple entries.
96 (equal '("b" (italic nil
"a"))
97 (org-test-with-temp-text "* Headline\n *a*"
98 (let ((tree (org-element-parse-buffer)))
99 (org-element-set-contents
100 (org-element-map tree
'bold
'identity nil t
) "b" '(italic nil
"a"))
101 (org-element-contents
102 (org-element-map tree
'bold
'identity nil t
))))))
103 ;; Accept atoms and elements.
106 (org-test-with-temp-text "* Headline\n *a*"
107 (let ((tree (org-element-parse-buffer)))
108 (org-element-set-contents
109 (org-element-map tree
'bold
'identity nil t
) "b")
110 (org-element-contents
111 (org-element-map tree
'bold
'identity nil t
))))))
113 (equal '((italic nil
"b"))
114 (org-test-with-temp-text "* Headline\n *a*"
115 (let ((tree (org-element-parse-buffer)))
116 (org-element-set-contents
117 (org-element-map tree
'bold
'identity nil t
) '(italic nil
"b"))
118 (org-element-contents
119 (org-element-map tree
'bold
'identity nil t
))))))
120 ;; Allow nil contents.
122 (org-test-with-temp-text "* Headline\n *a*"
123 (let ((tree (org-element-parse-buffer)))
124 (org-element-set-contents (org-element-map tree
'bold
'identity nil t
))
125 (org-element-contents (org-element-map tree
'bold
'identity nil t
))))))
127 (ert-deftest test-org-element
/set-element
()
128 "Test `org-element-set-element' specifications."
129 (org-test-with-temp-text "* Headline\n*a*"
130 (let ((tree (org-element-parse-buffer)))
131 (org-element-set-element
132 (org-element-map tree
'bold
'identity nil t
)
134 ;; Check if object is correctly replaced.
135 (should (org-element-map tree
'italic
'identity
))
136 (should-not (org-element-map tree
'bold
'identity
))
137 ;; Check if new object's parent is correctly set.
140 (org-element-property :parent
141 (org-element-map tree
'italic
'identity nil t
))
142 (org-element-map tree
'paragraph
'identity nil t
))))))
144 (ert-deftest test-org-element
/adopt-elements
()
145 "Test `org-element-adopt-elements' specifications."
148 (equal '(plain-text italic
)
149 (org-test-with-temp-text "* Headline\n *a*"
150 (let ((tree (org-element-parse-buffer)))
151 (org-element-adopt-elements
152 (org-element-map tree
'bold
'identity nil t
) '(italic nil
"a"))
153 (mapcar (lambda (blob) (org-element-type blob
))
154 (org-element-contents
155 (org-element-map tree
'bold
'identity nil t
)))))))
159 (org-test-with-temp-text "* Headline\n *a*"
160 (let ((tree (org-element-parse-buffer)))
161 (org-element-adopt-elements
162 (org-element-map tree
'bold
'identity nil t
) "b")
163 (org-element-contents
164 (org-element-map tree
'bold
'identity nil t
)))))))
170 ;;;; Affiliated Keywords
172 (ert-deftest test-org-element
/affiliated-keywords-parser
()
173 "Test affiliated keywords parsing."
174 ;; Read simple keywords.
177 (org-element-property
179 (org-test-with-temp-text "#+NAME: para\nParagraph"
180 (org-element-at-point)))))
183 (org-element-property
185 (org-test-with-temp-text "#+NAME: para\nParagraph"
186 (org-element-at-point)))))
187 ;; Parse multiple keywords.
191 (org-element-property
193 (org-test-with-temp-text
194 "#+ATTR_ASCII: line1\n#+ATTR_ASCII: line2\nParagraph"
195 (org-element-at-point)))))
196 ;; Parse "parsed" keywords.
200 (org-test-with-temp-text "#+CAPTION: caption\nParagraph"
201 (car (org-element-property :caption
(org-element-at-point))))))
202 ;; Parse dual keywords.
205 '((("long") "short"))
206 (org-test-with-temp-text "#+CAPTION[short]: long\nParagraph"
207 (org-element-property :caption
(org-element-at-point)))))
208 ;; Allow multiple caption keywords.
211 '((("l2") "s2") (("l1") "s1"))
212 (org-test-with-temp-text "#+CAPTION[s1]: l1\n#+CAPTION[s2]: l2\nParagraph"
213 (org-element-property :caption
(org-element-at-point)))))
216 '((("l1")) (nil "s1"))
217 (org-test-with-temp-text "#+CAPTION[s1]:\n#+CAPTION: l1\nParagraph"
218 (org-element-property :caption
(org-element-at-point)))))
219 ;; Corner case: orphaned keyword at the end of an element.
222 (org-test-with-temp-text "- item\n #+name: name\nSome paragraph"
223 (progn (search-forward "name")
224 (org-element-type (org-element-at-point))))))
226 (org-test-with-temp-text "- item\n #+name: name\nSome paragraph"
227 (progn (search-forward "Some")
228 (org-element-property :name
(org-element-at-point))))))
233 (ert-deftest test-org-element
/babel-call-parser
()
234 "Test `babel-call' parsing."
237 (org-test-with-temp-text "#+CALL: test()"
238 (org-element-map (org-element-parse-buffer) 'babel-call
'identity
)))
241 (org-test-with-temp-text "#+call: test()"
242 (org-element-map (org-element-parse-buffer) 'babel-call
'identity
))))
247 (ert-deftest test-org-element
/bold-parser
()
248 "Test `bold' parser."
251 (let ((org-emph-re "\\([ ('\"{]\\|^\\)\\(\\([+*/_=~]\\)\\([^
\n,\"']\\|[^
\n,\"'].*?\\(?:\n.*?\\)\\{0,1\\}[^
\n,\"']\\)\\3\\)\\([- .,:!?;'\")}\\]\\|$\\)"))
252 (org-test-with-temp-text "*bold*"
253 (org-element-map (org-element-parse-buffer) 'bold
'identity nil t
))))
254 ;; Multi-line markup.
257 (org-element-contents
258 (let ((org-emph-re "\\([ ('\"{]\\|^\\)\\(\\([+*/_=~]\\)\\([^
\n,\"']\\|[^
\n,\"'].*?\\(?:\n.*?\\)\\{0,1\\}[^
\n,\"']\\)\\3\\)\\([- .,:!?;'\")}\\]\\|$\\)"))
259 (org-test-with-temp-text "*first line\nsecond line*"
260 (org-element-map (org-element-parse-buffer) 'bold
'identity nil t
))))
261 '("first line\nsecond line"))))
266 (ert-deftest test-org-element
/center-block-parser
()
267 "Test `center-block' parser."
270 (org-test-with-temp-text "#+BEGIN_CENTER\nText\n#+END_CENTER"
271 (org-element-map (org-element-parse-buffer) 'center-block
'identity
)))
274 (org-test-with-temp-text "#+begin_center\nText\n#+end_center"
275 (org-element-map (org-element-parse-buffer) 'center-block
'identity
)))
276 ;; Test folded block.
277 (org-test-with-temp-text "#+BEGIN_CENTER\nText\n#+END_CENTER"
280 (org-element-property
283 (org-element-parse-buffer) 'center-block
'identity nil t
))))
284 ;; Ignore incomplete block.
286 (org-test-with-temp-text "#+BEGIN_CENTER"
288 (org-element-parse-buffer) 'center-block
'identity nil t
))))
293 (ert-deftest test-org-element
/clock-parser
()
294 "Test `clock' parser."
296 (let* ((org-clock-string "CLOCK:")
297 (clock (org-test-with-temp-text "CLOCK: [2012-01-01 sun. 00:01]"
298 (org-element-at-point))))
299 (should (eq (org-element-property :status clock
) 'running
))
301 (equal (org-element-property :raw-value
302 (org-element-property :value clock
))
303 "[2012-01-01 sun. 00:01]"))
304 (should-not (org-element-property :duration clock
)))
306 (let* ((org-clock-string "CLOCK:")
308 (org-test-with-temp-text
309 "CLOCK: [2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02] => 0:01"
310 (org-element-at-point))))
311 (should (eq (org-element-property :status clock
) 'closed
))
312 (should (equal (org-element-property :raw-value
313 (org-element-property :value clock
))
314 "[2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02]"))
315 (should (equal (org-element-property :duration clock
) "0:01"))))
320 (ert-deftest test-org-element
/code-parser
()
321 "Test `code' parser."
324 (let ((org-emph-re "\\([ ('\"{]\\|^\\)\\(\\([+*/_=~]\\)\\([^
\n,\"']\\|[^
\n,\"'].*?\\(?:\n.*?\\)\\{0,1\\}[^
\n,\"']\\)\\3\\)\\([- .,:!?;'\")}\\]\\|$\\)"))
325 (org-test-with-temp-text "~code~"
326 (org-element-map (org-element-parse-buffer) 'code
'identity
))))
327 ;; Multi-line markup.
330 (org-element-property
332 (let ((org-emph-re "\\([ ('\"{]\\|^\\)\\(\\([+*/_=~]\\)\\([^
\n,\"']\\|[^
\n,\"'].*?\\(?:\n.*?\\)\\{0,1\\}[^
\n,\"']\\)\\3\\)\\([- .,:!?;'\")}\\]\\|$\\)"))
333 (org-test-with-temp-text "~first line\nsecond line~"
335 (org-element-parse-buffer) 'code
'identity nil t
))))
336 "first line\nsecond line")))
341 (ert-deftest test-org-element
/comment-parser
()
342 "Test `comment' parser."
345 (org-test-with-temp-text "# Comment"
346 (org-element-map (org-element-parse-buffer) 'comment
'identity
)))
349 (org-test-with-temp-text " # Comment"
350 (org-element-map (org-element-parse-buffer) 'comment
'identity
)))
351 ;; Preserve indentation.
354 (org-element-property
356 (org-test-with-temp-text "# No blank\n# One blank"
357 (org-element-map (org-element-parse-buffer) 'comment
'identity nil t
)))
358 "No blank\n One blank"))
359 ;; Comment with blank lines.
362 (org-element-property
364 (org-test-with-temp-text "# First part\n# \n#\n# Second part"
365 (org-element-map (org-element-parse-buffer) 'comment
'identity nil t
)))
366 "First part\n\n\nSecond part"))
367 ;; Do not mix comments and keywords.
370 (org-test-with-temp-text "#+keyword: value\n# comment\n#+keyword: value"
371 (length (org-element-map
372 (org-element-parse-buffer) 'comment
'identity
)))))
375 (org-test-with-temp-text "#+keyword: value\n# comment\n#+keyword: value"
376 (org-element-property
379 (org-element-parse-buffer) 'comment
'identity nil t
))))))
384 (ert-deftest test-org-element
/comment-block-parser
()
385 "Test `comment-block' parser."
388 (org-test-with-temp-text "#+BEGIN_COMMENT\nText\n#+END_COMMENT"
390 (org-element-parse-buffer) 'comment-block
'identity
)))
393 (org-test-with-temp-text "#+begin_comment\nText\n#+end_comment"
395 (org-element-parse-buffer) 'comment-block
'identity
)))
396 ;; Test folded block.
397 (org-test-with-temp-text "#+BEGIN_COMMENT\nText\n#+END_COMMENT"
400 (org-element-property
403 (org-element-parse-buffer) 'comment-block
'identity nil t
))))
404 ;; Ignore incomplete block.
406 (org-test-with-temp-text "#+BEGIN_COMMENT"
408 (org-element-parse-buffer) 'comment-block
'identity nil t
))))
413 (ert-deftest test-org-element
/diary-sexp-parser
()
414 "Test `diary-sexp' parser."
418 (org-test-with-temp-text
419 "%%(org-anniversary 1956 5 14)(2) Arthur Dent is %d years old"
420 (org-element-type (org-element-at-point)))))
421 ;; Diary sexp must live at beginning of line
424 (org-test-with-temp-text " %%(org-bbdb-anniversaries)"
425 (org-element-type (org-element-at-point))))))
430 (ert-deftest test-org-element
/drawer-parser
()
431 "Test `drawer' parser."
434 (let ((org-drawers '("TEST")))
435 (org-test-with-temp-text ":TEST:\nText\n:END:"
436 (org-element-map (org-element-parse-buffer) 'drawer
'identity
))))
437 ;; Do not mix regular drawers and property drawers.
439 (let ((org-drawers '("PROPERTIES")))
440 (org-test-with-temp-text ":PROPERTIES:\n:prop: value\n:END:"
442 (org-element-parse-buffer) 'drawer
'identity nil t
))))
443 ;; Ignore incomplete drawer.
445 (let ((org-drawers '("TEST")))
446 (org-test-with-temp-text ":TEST:"
448 (org-element-parse-buffer) 'drawer
'identity nil t
)))))
453 (ert-deftest test-org-element
/dynamic-block-parser
()
454 "Test `dynamic-block' parser."
457 (org-test-with-temp-text
458 "#+BEGIN: myblock :param1 val1 :param2 val2\nText\n#+END:"
459 (org-element-map (org-element-parse-buffer) 'dynamic-block
'identity
)))
461 (org-test-with-temp-text
462 "#+BEGIN: myblock :param1 val1 :param2 val2\nText\n#+END:"
465 (org-element-property
468 (org-element-parse-buffer) 'dynamic-block
'identity nil t
))))
471 (org-test-with-temp-text
472 "#+begin: myblock :param1 val1 :param2 val2\nText\n#+end:"
473 (org-element-map (org-element-parse-buffer) 'dynamic-block
'identity
)))
474 ;; Ignore incomplete block.
476 (org-test-with-temp-text "#+BEGIN: myblock :param1 val1 :param2 val2"
478 (org-element-parse-buffer) 'dynamic-block
'identity nil t
))))
483 (ert-deftest test-org-element
/entity-parser
()
484 "Test `entity' parser."
487 (org-test-with-temp-text "\\sin"
488 (org-element-map (org-element-parse-buffer) 'entity
'identity
)))
491 (org-element-property
493 (org-test-with-temp-text "\\alpha{}text"
494 (org-element-map (org-element-parse-buffer) 'entity
'identity nil t
))))
495 ;; User-defined entity.
498 (org-element-property
500 (let ((org-entities-user
501 '(("test" "test" nil
"test" "test" "test" "test"))))
502 (org-test-with-temp-text "\\test"
503 (org-element-map (org-element-parse-buffer) 'entity
'identity nil t
))))
505 ;; Special case: entity at the end of a container.
508 (org-test-with-temp-text "*\\alpha \\beta*"
509 (search-forward "be")
510 (org-element-type (org-element-context))))))
515 (ert-deftest test-org-element
/example-block-parser
()
516 "Test `example-block' parser."
519 (org-test-with-temp-text "#+BEGIN_EXAMPLE\nText\n#+END_EXAMPLE"
520 (org-element-map (org-element-parse-buffer) 'example-block
'identity
)))
521 ;; Test folded block.
523 (org-test-with-temp-text "#+BEGIN_EXAMPLE\nText\n#+END_EXAMPLE"
525 (org-element-property :hiddenp
(org-element-at-point))))
526 ;; Ignore incomplete block.
529 (org-test-with-temp-text "#+BEGIN_EXAMPLE"
530 (org-element-type (org-element-at-point)))))
531 ;; Properly un-escape code.
533 (equal "* Headline\n #+keyword\nText\n"
534 (org-test-with-temp-text
535 "#+BEGIN_EXAMPLE\n,* Headline\n ,#+keyword\nText\n#+END_EXAMPLE"
536 (org-element-property :value
(org-element-at-point)))))
537 ;; Nil `org-src-preserve-indentation': Remove maximum common
541 (org-test-with-temp-text "#+BEGIN_EXAMPLE\n L1\n L2\n#+END_EXAMPLE"
542 (let ((org-src-preserve-indentation nil
))
543 (org-element-property :value
(org-element-at-point))))))
544 ;; Non-nil `org-src-preserve-indentation': Remove block indentation
545 ;; only, unless block contents are less indented than block
549 (org-test-with-temp-text " #+BEGIN_EXAMPLE\n L1\n L2\n #+END_EXAMPLE"
550 (let ((org-src-preserve-indentation t
))
551 (org-element-property :value
(org-element-at-point))))))
555 (org-test-with-temp-text " #+BEGIN_EXAMPLE\n L1\n L2\n #+END_EXAMPLE"
556 (let ((org-src-preserve-indentation t
))
557 (org-element-property :value
(org-element-at-point)))))))
559 (ert-deftest test-org-element
/block-switches
()
560 "Test `example-block' and `src-block' switches parsing."
561 (let ((org-coderef-label-format "(ref:%s)"))
562 ;; 1. Test "-i" switch.
564 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n(+ 1 1)\n#+END_SRC"
565 (org-element-property :preserve-indent
(org-element-at-point))))
567 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp -i\n(+ 1 1)\n#+END_SRC"
568 (org-element-property :preserve-indent
(org-element-at-point))))
570 (org-test-with-temp-text "#+BEGIN_EXAMPLE\nText.\n#+END_EXAMPLE"
571 (org-element-property :preserve-indent
(org-element-at-point))))
573 (org-test-with-temp-text "#+BEGIN_EXAMPLE -i\nText.\n#+END_EXAMPLE"
574 (org-element-property :preserve-indent
(org-element-at-point))))
575 ;; 2. "-n -r -k" combination should number lines, retain labels but
576 ;; not use them in coderefs.
578 (org-test-with-temp-text "#+BEGIN_EXAMPLE -n -r -k\nText.\n#+END_EXAMPLE"
579 (let ((element (org-element-at-point)))
580 (and (org-element-property :number-lines element
)
581 (org-element-property :retain-labels element
)
582 (not (org-element-property :use-labels element
))))))
584 (org-test-with-temp-text
585 "#+BEGIN_SRC emacs-lisp -n -r -k\n(+ 1 1)\n#+END_SRC"
586 (let ((element (org-element-at-point)))
587 (and (org-element-property :number-lines element
)
588 (org-element-property :retain-labels element
)
589 (not (org-element-property :use-labels element
))))))
590 ;; 3. "-n -r" combination should number-lines remove labels and not
591 ;; use them in coderefs.
593 (org-test-with-temp-text "#+BEGIN_EXAMPLE -n -r\nText.\n#+END_EXAMPLE"
594 (let ((element (org-element-at-point)))
595 (and (org-element-property :number-lines element
)
596 (not (org-element-property :retain-labels element
))
597 (not (org-element-property :use-labels element
))))))
599 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp -n -r\n(+ 1 1)\n#+END_SRC"
600 (let ((element (org-element-at-point)))
601 (and (org-element-property :number-lines element
)
602 (not (org-element-property :retain-labels element
))
603 (not (org-element-property :use-labels element
))))))
604 ;; 4. "-n" or "+n" should number lines, retain labels and use them
607 (org-test-with-temp-text "#+BEGIN_EXAMPLE -n\nText.\n#+END_EXAMPLE"
608 (let ((element (org-element-at-point)))
609 (and (org-element-property :number-lines element
)
610 (org-element-property :retain-labels element
)
611 (org-element-property :use-labels element
)))))
613 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp -n\n(+ 1 1)\n#+END_SRC"
614 (let ((element (org-element-at-point)))
615 (and (org-element-property :number-lines element
)
616 (org-element-property :retain-labels element
)
617 (org-element-property :use-labels element
)))))
619 (org-test-with-temp-text "#+BEGIN_EXAMPLE +n\nText.\n#+END_EXAMPLE"
620 (let ((element (org-element-at-point)))
621 (and (org-element-property :number-lines element
)
622 (org-element-property :retain-labels element
)
623 (org-element-property :use-labels element
)))))
625 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp +n\n(+ 1 1)\n#+END_SRC"
626 (let ((element (org-element-at-point)))
627 (and (org-element-property :number-lines element
)
628 (org-element-property :retain-labels element
)
629 (org-element-property :use-labels element
)))))
630 ;; 5. No switch should not number lines, but retain labels and use
633 (org-test-with-temp-text "#+BEGIN_EXAMPLE\nText.\n#+END_EXAMPLE"
634 (let ((element (org-element-at-point)))
635 (and (not (org-element-property :number-lines element
))
636 (org-element-property :retain-labels element
)
637 (org-element-property :use-labels element
)))))
639 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n(+ 1 1)\n#+END_SRC"
640 (let ((element (org-element-at-point)))
641 (and (not (org-element-property :number-lines element
))
642 (org-element-property :retain-labels element
)
643 (org-element-property :use-labels element
)))))
644 ;; 6. "-r" switch only: do not number lines, remove labels, and
645 ;; don't use labels in coderefs.
647 (org-test-with-temp-text "#+BEGIN_EXAMPLE -r\nText.\n#+END_EXAMPLE"
648 (let ((element (org-element-at-point)))
649 (and (not (org-element-property :number-lines element
))
650 (not (org-element-property :retain-labels element
))
651 (not (org-element-property :use-labels element
))))))
653 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp -r\n(+ 1 1)\n#+END_SRC"
654 (let ((element (org-element-at-point)))
655 (and (not (org-element-property :number-lines element
))
656 (not (org-element-property :retain-labels element
))
657 (not (org-element-property :use-labels element
))))))
658 ;; 7. Recognize coderefs with user-defined syntax.
662 (org-test-with-temp-text
663 "#+BEGIN_EXAMPLE -l \"[ref:%s]\"\nText [ref:text]\n#+END_EXAMPLE"
664 (org-element-property :label-fmt
(org-element-at-point)))))
668 (org-test-with-temp-text
669 "#+BEGIN_SRC emacs-lisp -l \"[ref:%s]\"\n(+ 1 1) [ref:text]\n#+END_SRC"
670 (org-element-property :label-fmt
(org-element-at-point)))))))
675 (ert-deftest test-org-element
/export-block-parser
()
676 "Test `export-block' parser."
679 (org-test-with-temp-text "#+BEGIN_LATEX\nText\n#+END_LATEX"
681 (let ((org-element-block-name-alist
682 '(("LATEX" . org-element-export-block-parser
))))
683 (org-element-parse-buffer))
684 'export-block
'identity
)))
685 ;; Test folded block.
686 (org-test-with-temp-text "#+BEGIN_LATEX\nText\n#+END_LATEX"
689 (org-element-property
692 (let ((org-element-block-name-alist
693 '(("LATEX" . org-element-export-block-parser
))))
694 (org-element-parse-buffer))
695 'export-block
'identity nil t
))))
698 (org-test-with-temp-text "#+begin_latex\nText\n#+end_latex"
700 (let ((org-element-block-name-alist
701 '(("LATEX" . org-element-export-block-parser
))))
702 (org-element-parse-buffer))
703 'export-block
'identity
)))
704 ;; Ignore incomplete block.
706 (org-test-with-temp-text "#+BEGIN_LATEX"
708 (let ((org-element-block-name-alist
709 '(("LATEX" . org-element-export-block-parser
))))
710 (org-element-parse-buffer))
711 'export-block
'identity nil t
))))
716 (ert-deftest test-org-element
/export-snippet-parser
()
717 "Test `export-snippet' parser."
720 '("back-end" .
"contents")
721 (org-test-with-temp-text "@@back-end:contents@@"
723 (org-element-parse-buffer) 'export-snippet
724 (lambda (snippet) (cons (org-element-property :back-end snippet
)
725 (org-element-property :value snippet
)))
731 (ert-deftest test-org-element
/fixed-width
()
732 "Test fixed-width area parsing."
733 ;; Preserve indentation.
735 (org-test-with-temp-text ": no blank\n: one blank"
736 (org-element-map (org-element-parse-buffer) 'fixed-width
'identity
)))
737 ;; Fixed-width with empty lines.
739 (org-test-with-temp-text ": first part\n:\n: \n: second part"
740 (org-element-map (org-element-parse-buffer) 'fixed-width
'identity
)))
741 ;; Parse indented fixed-width markers.
743 (org-test-with-temp-text "Text\n : no blank\n : one blank"
744 (org-element-map (org-element-parse-buffer) 'fixed-width
'identity
)))
745 ;; Distinguish fixed-width areas within a list and outside of it.
749 (org-test-with-temp-text "
752 : fixed-width outside"
754 (org-element-parse-buffer) 'fixed-width
'identity
))))))
757 ;;;; Footnote Definition
759 (ert-deftest test-org-element
/footnote-definition-parser
()
760 "Test `footnote-definition' parser."
762 (org-test-with-temp-text "[fn:1] Definition"
764 (org-element-parse-buffer) 'footnote-definition
'identity nil t
)))
765 ;; Footnote with more contents
768 (org-element-property
770 (org-test-with-temp-text "[fn:1] Definition\n\n| a | b |"
772 (org-element-parse-buffer)
773 'footnote-definition
'identity nil t
)))))
774 ;; Footnote starting with special syntax.
776 (org-test-with-temp-text "[fn:1] - no item"
777 (org-element-map (org-element-parse-buffer) 'item
'identity
))))
780 ;;;; Footnotes Reference.
782 (ert-deftest test-org-element
/footnote-reference-parser
()
783 "Test `footnote-reference' parser."
784 ;; 1. Parse a standard reference.
785 (org-test-with-temp-text "Text[fn:label]"
788 (org-element-parse-buffer) 'footnote-reference
'identity
)))
789 ;; 2. Parse a normalized reference.
790 (org-test-with-temp-text "Text[1]"
793 (org-element-parse-buffer) 'footnote-reference
'identity
)))
794 ;; 3. Parse an inline reference.
795 (org-test-with-temp-text "Text[fn:test:def]"
798 (org-element-parse-buffer) 'footnote-reference
'identity
)))
799 ;; 4. Parse an anonymous reference.
800 (org-test-with-temp-text "Text[fn::def]"
803 (org-element-parse-buffer) 'footnote-reference
'identity
)))
804 ;; 5. Parse nested footnotes.
805 (org-test-with-temp-text "Text[fn::def [fn:label]]"
810 (org-element-parse-buffer) 'footnote-reference
'identity
)))))
811 ;; 6. Parse adjacent footnotes.
812 (org-test-with-temp-text "Text[fn:label1][fn:label2]"
817 (org-element-parse-buffer) 'footnote-reference
'identity
)))))
818 ;; 7. Only properly closed footnotes are recognized as such.
819 (org-test-with-temp-text "Text[fn:label"
822 (org-element-parse-buffer) 'footnote-reference
'identity
))))
827 (ert-deftest test-org-element
/headline-quote-keyword
()
828 "Test QUOTE keyword recognition."
830 (org-test-with-temp-text "* Headline"
831 (let ((org-quote-string "QUOTE"))
832 (should-not (org-element-property :quotedp
(org-element-at-point)))))
833 ;; Standard position.
834 (org-test-with-temp-text "* QUOTE Headline"
835 (let* ((org-quote-string "QUOTE")
836 (headline (org-element-at-point)))
837 (should (org-element-property :quotedp headline
))
838 ;; Test removal from raw value.
839 (should (equal (org-element-property :raw-value headline
) "Headline"))))
841 (org-test-with-temp-text "* QUOTE Headline"
842 (let* ((org-quote-string "Quote")
843 (headline (org-element-at-point)))
844 (should-not (org-element-property :quotedp headline
))
845 (should (equal (org-element-property :raw-value headline
)
847 ;; With another keyword.
848 (org-test-with-temp-text "* TODO QUOTE Headline"
849 (let* ((org-quote-string "QUOTE")
850 (org-todo-keywords '((sequence "TODO" "DONE")))
851 (headline (org-element-at-point)))
852 (should (org-element-property :quotedp headline
))
853 (should (equal (org-element-property :raw-value headline
) "Headline"))))
854 ;; With the keyword only.
855 (org-test-with-temp-text "* QUOTE"
856 (let* ((org-quote-string "QUOTE")
857 (headline (org-element-at-point)))
858 (should (org-element-property :quotedp headline
))
859 (should (equal (org-element-property :raw-value headline
) "")))))
861 (ert-deftest test-org-element
/headline-comment-keyword
()
862 "Test COMMENT keyword recognition."
864 (org-test-with-temp-text "* Headline"
865 (let ((org-comment-string "COMMENT"))
866 (should-not (org-element-property :commentedp
(org-element-at-point)))))
867 ;; Standard position.
868 (org-test-with-temp-text "* COMMENT Headline"
869 (let ((org-comment-string "COMMENT")
870 (headline (org-element-at-point)))
871 (should (org-element-property :commentedp headline
))
872 (should (equal (org-element-property :raw-value headline
) "Headline"))))
874 (org-test-with-temp-text "* COMMENT Headline"
875 (let* ((org-comment-string "Comment")
876 (headline (org-element-at-point)))
877 (should-not (org-element-property :commentedp headline
))
878 (should (equal (org-element-property :raw-value headline
)
879 "COMMENT Headline"))))
880 ;; With another keyword.
881 (org-test-with-temp-text "* TODO COMMENT Headline"
882 (let* ((org-comment-string "COMMENT")
883 (org-todo-keywords '((sequence "TODO" "DONE")))
884 (headline (org-element-at-point)))
885 (should (org-element-property :commentedp headline
))
886 (should (equal (org-element-property :raw-value headline
) "Headline"))))
887 ;; With the keyword only.
888 (org-test-with-temp-text "* COMMENT"
889 (let* ((org-comment-string "COMMENT")
890 (headline (org-element-at-point)))
891 (should (org-element-property :commentedp headline
))
892 (should (equal (org-element-property :raw-value headline
) "")))))
894 (ert-deftest test-org-element
/headline-archive-tag
()
895 "Test ARCHIVE tag recognition."
897 (org-test-with-temp-text "* Headline"
898 (let ((org-archive-tag "ARCHIVE"))
899 (should-not (org-element-property :archivedp
(org-element-at-point)))))
901 (org-test-with-temp-text "* Headline :ARCHIVE:"
902 (let ((org-archive-tag "ARCHIVE"))
903 (let ((headline (org-element-at-point)))
904 (should (org-element-property :archivedp headline
))
906 (should-not (org-element-property :tags headline
))))
907 (let ((org-archive-tag "Archive"))
908 (should-not (org-element-property :archivedp
(org-element-at-point)))))
910 (org-test-with-temp-text "* Headline :test:ARCHIVE:"
911 (let ((org-archive-tag "ARCHIVE"))
912 (let ((headline (org-element-at-point)))
913 (should (org-element-property :archivedp headline
))
915 (should (equal (org-element-property :tags headline
) '("test")))))))
917 (ert-deftest test-org-element
/headline-properties
()
918 "Test properties from property drawer."
919 ;; All properties from property drawer have their symbol upper
922 (org-test-with-temp-text "* Headline\n:PROPERTIES:\n:foo: bar\n:END:"
923 (org-element-property :FOO
(org-element-at-point))))
925 (org-test-with-temp-text "* Headline\n:PROPERTIES:\n:foo: bar\n:END:"
926 (org-element-property :foo
(org-element-at-point)))))
931 (ert-deftest test-org-element
/horizontal-rule-parser
()
932 "Test `horizontal-rule' parser."
935 (org-test-with-temp-text "-----"
936 (org-element-map (org-element-parse-buffer) 'horizontal-rule
'identity
)))
939 (org-test-with-temp-text " -----"
940 (org-element-map (org-element-parse-buffer) 'horizontal-rule
'identity
)))
941 ;; Hyphen must be alone on the line.
943 (org-test-with-temp-text "-----wrong"
944 (org-element-map (org-element-parse-buffer) 'horizontal-rule
'identity
)))
945 ;; 4 hyphens is too small.
947 (org-test-with-temp-text "----"
948 (org-element-map (org-element-parse-buffer) 'horizontal-rule
'identity
))))
951 ;;;; Inline Babel Call
953 (ert-deftest test-org-element
/inline-babel-call-parser
()
954 "Test `inline-babel-call' parser."
956 (org-test-with-temp-text "call_test()"
958 (org-element-parse-buffer) 'inline-babel-call
'identity
))))
961 ;;;; Inline Src Block
963 (ert-deftest test-org-element
/inline-src-block-parser
()
964 "Test `inline-src-block' parser."
966 (org-test-with-temp-text "src_emacs-lisp{(+ 1 1)}"
967 (org-element-map (org-element-parse-buffer) 'inline-src-block
'identity
)))
968 ;; Test parsing at the beginning of an item.
970 (org-test-with-temp-text "- src_emacs-lisp{(+ 1 1)}"
971 (org-element-map (org-element-parse-buffer) 'inline-src-block
'identity
))))
976 (ert-deftest test-org-element
/inlinetask-parser
()
977 "Test `inlinetask' parser."
978 (when (featurep 'org-inlinetask
)
979 (let ((org-inlinetask-min-level 15))
980 ;; 1. Regular inlinetask.
982 (org-test-with-temp-text
983 "*************** Task\nTest\n*************** END"
984 (org-element-map (org-element-parse-buffer) 'inlinetask
'identity
)))
985 ;; 2. Degenerate inlinetask.
987 (org-test-with-temp-text "*************** Task"
988 (org-element-map (org-element-parse-buffer) 'inlinetask
'identity
)))
993 (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
994 (org-test-with-temp-text "*************** TODO Task"
995 (org-element-property
997 (org-element-map (org-element-parse-buffer) 'inlinetask
998 'identity nil t
))))))
1003 (org-test-with-temp-text "
1004 *************** Task
1005 DEADLINE: <2012-03-29 thu.>"
1006 (org-element-property
1008 (org-element-map (org-element-parse-buffer) 'inlinetask
'identity nil t
)))))
1013 (org-test-with-temp-text "
1014 *************** [#A] Task"
1015 (org-element-property
1018 (org-element-parse-buffer) 'inlinetask
'identity nil t
)))))
1023 (org-test-with-temp-text "
1024 *************** Task :test:"
1025 (org-element-property
1028 (org-element-parse-buffer) 'inlinetask
'identity nil t
)))))
1029 ;; Regular properties are accessed through upper case keywords.
1031 (org-test-with-temp-text "
1032 *************** Task
1036 *************** END"
1038 (org-element-property :FOO
(org-element-at-point))))
1040 (org-test-with-temp-text "
1041 *************** Task
1045 *************** END"
1047 (org-element-property :foo
(org-element-at-point)))))))
1052 (ert-deftest test-org-element
/italic-parser
()
1053 "Test `italic' parser."
1056 (let ((org-emph-re "\\([ ('\"{]\\|^\\)\\(\\([+*/_=~]\\)\\([^
\n,\"']\\|[^
\n,\"'].*?\\(?:\n.*?\\)\\{0,1\\}[^
\n,\"']\\)\\3\\)\\([- .,:!?;'\")}\\]\\|$\\)"))
1057 (org-test-with-temp-text "/italic/"
1058 (org-element-map (org-element-parse-buffer) 'italic
'identity nil t
))))
1059 ;; Multi-line markup.
1062 (org-element-contents
1063 (let ((org-emph-re "\\([ ('\"{]\\|^\\)\\(\\([+*/_=~]\\)\\([^
\n,\"']\\|[^
\n,\"'].*?\\(?:\n.*?\\)\\{0,1\\}[^
\n,\"']\\)\\3\\)\\([- .,:!?;'\")}\\]\\|$\\)"))
1064 (org-test-with-temp-text "/first line\nsecond line/"
1065 (org-element-map (org-element-parse-buffer) 'italic
'identity nil t
))))
1066 '("first line\nsecond line"))))
1071 (ert-deftest test-org-element
/item-parser
()
1072 "Test `item' parser."
1075 (org-test-with-temp-text "- item"
1076 (org-element-map (org-element-parse-buffer) 'item
'identity
)))
1080 (org-element-property
1082 (org-test-with-temp-text "6. [@6] item"
1083 (org-element-map (org-element-parse-buffer) 'item
'identity nil t
)))))
1088 (org-element-property
1090 (org-test-with-temp-text "- tag :: description"
1091 (org-element-map (org-element-parse-buffer) 'item
'identity nil t
)))))
1092 ;; No tags in ordered lists.
1094 (org-element-property
1096 (org-test-with-temp-text "1. tag :: description"
1097 (org-element-map (org-element-parse-buffer) 'item
'identity nil t
))))
1102 (org-test-with-temp-text "
1107 (org-element-parse-buffer) 'item
1108 (lambda (item) (org-element-property :checkbox item
))))))
1110 (org-test-with-temp-text "* Headline
1115 (let ((org-cycle-include-plain-lists t
)) (org-cycle))
1117 (org-element-property
1119 (org-element-map (org-element-parse-buffer) 'item
'identity nil t
))))
1120 ;; Item starting with special syntax.
1122 (equal '(("- item"))
1123 (org-test-with-temp-text "- - item"
1125 (org-element-parse-buffer) 'paragraph
'org-element-contents
)))))
1130 (ert-deftest test-org-element
/keyword-parser
()
1131 "Test `keyword' parser."
1134 (org-test-with-temp-text "#+KEYWORD: value"
1135 (org-element-map (org-element-parse-buffer) 'keyword
'identity
)))
1136 ;; Keywords are case-insensitive.
1138 (org-test-with-temp-text "#+keyword: value"
1139 (org-element-map (org-element-parse-buffer) 'keyword
'identity
)))
1140 ;; Affiliated keywords are not keywords.
1142 (org-test-with-temp-text "#+NAME: value
1144 (org-element-map (org-element-parse-buffer) 'keyword
'identity
)))
1145 ;; Do not mix keywords with Babel calls and dynamic blocks.
1147 (org-test-with-temp-text "#+CALL: fun()"
1148 (org-element-map (org-element-parse-buffer) 'keyword
'identity
)))
1150 (org-test-with-temp-text "#+BEGIN: my-fun\nBody\n#+END:"
1151 (org-element-map (org-element-parse-buffer) 'keyword
'identity
))))
1154 ;;;; Latex Environment
1156 (ert-deftest test-org-element
/latex-environment-parser
()
1157 "Test `latex-environment' parser."
1159 (org-test-with-temp-text "\\begin{equation}\ne^{i\\pi}+1=0\n\\end{equation}"
1160 (org-element-map (org-element-parse-buffer) 'latex-environment
'identity
)))
1161 ;; Allow nested environments.
1169 (org-test-with-temp-text "
1175 (org-element-property
1178 (org-element-parse-buffer) 'latex-environment
'identity nil t
)))))
1179 ;; Allow environments with options and arguments.
1181 (eq 'latex-environment
1182 (org-test-with-temp-text
1183 "\\begin{theorem}[Euler]\ne^{i\\pi}+1=0\n\\end{theorem}"
1184 (org-element-type (org-element-at-point)))))
1186 (eq 'latex-environment
1187 (org-test-with-temp-text "\\begin{env}{arg}\nvalue\n\\end{env}"
1188 (org-element-type (org-element-at-point)))))
1190 (eq 'latex-environment
1191 (org-test-with-temp-text "\\begin{env}{arg} something\nvalue\n\\end{env}"
1192 (org-element-type (org-element-at-point))))))
1197 (ert-deftest test-org-element
/latex-fragment-parser
()
1198 "Test `latex-fragment' parser."
1199 (let ((org-latex-regexps
1200 '(("begin" "^[ ]*\\(\\\\begin{\\([a-zA-Z0-9\\*]+\\)[^