org-element: Ignore blank lines when removing element indentation
[org-mode/org-mode-NeilSmithlineMods.git] / testing / lisp / test-org-element.el
blob4e184c98132c092f2094368852b6fa73aad82a61
1 ;;; test-org-element.el --- Tests for org-element.el
3 ;; Copyright (C) 2012 Nicolas Goaziou
5 ;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
7 ;; This program is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
12 ;; This program is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ;;; Commentary:
22 ;;; Code:
24 (unless (featurep 'org-element)
25 (signal 'missing-test-dependency "org-element"))
29 ;;; Tests:
33 ;;;; Headlines
35 (ert-deftest test-org-element/headline-quote-keyword ()
36 "Test QUOTE keyword recognition."
37 ;; Reference test.
38 (org-test-with-temp-text "* Headline"
39 (let ((org-quote-string "QUOTE"))
40 (should-not (org-element-property :quotedp (org-element-at-point)))))
41 ;; Standard position.
42 (org-test-with-temp-text "* QUOTE Headline"
43 (let ((org-quote-string "QUOTE"))
44 (let ((headline (org-element-at-point)))
45 (should (org-element-property :quotedp headline))
46 ;; Test removal from raw value.
47 (should (equal (org-element-property :raw-value headline) "Headline"))))
48 ;; Case sensitivity.
49 (let ((org-quote-string "Quote"))
50 (should-not (org-element-property :quotedp (org-element-at-point)))))
51 ;; With another keyword.
52 (org-test-with-temp-text "* TODO QUOTE Headline"
53 (let ((org-quote-string "QUOTE")
54 (org-todo-keywords '((sequence "TODO" "DONE"))))
55 (should (org-element-property :quotedp (org-element-at-point))))))
57 (ert-deftest test-org-element/headline-comment-keyword ()
58 "Test COMMENT keyword recognition."
59 ;; Reference test.
60 (org-test-with-temp-text "* Headline"
61 (let ((org-comment-string "COMMENT"))
62 (should-not (org-element-property :commentedp (org-element-at-point)))))
63 ;; Standard position.
64 (org-test-with-temp-text "* COMMENT Headline"
65 (let ((org-comment-string "COMMENT"))
66 (let ((headline (org-element-at-point)))
67 (should (org-element-property :commentedp headline))
68 ;; Test removal from raw value.
69 (should (equal (org-element-property :raw-value headline) "Headline"))))
70 ;; Case sensitivity.
71 (let ((org-comment-string "Comment"))
72 (should-not (org-element-property :commentedp (org-element-at-point)))))
73 ;; With another keyword.
74 (org-test-with-temp-text "* TODO COMMENT Headline"
75 (let ((org-comment-string "COMMENT")
76 (org-todo-keywords '((sequence "TODO" "DONE"))))
77 (should (org-element-property :commentedp (org-element-at-point))))))
79 (ert-deftest test-org-element/headline-archive-tag ()
80 "Test ARCHIVE tag recognition."
81 ;; Reference test.
82 (org-test-with-temp-text "* Headline"
83 (let ((org-archive-tag "ARCHIVE"))
84 (should-not (org-element-property :archivedp (org-element-at-point)))))
85 ;; Single tag.
86 (org-test-with-temp-text "* Headline :ARCHIVE:"
87 (let ((org-archive-tag "ARCHIVE"))
88 (let ((headline (org-element-at-point)))
89 (should (org-element-property :archivedp headline))
90 ;; Test tag removal.
91 (should-not (org-element-property :tags headline))))
92 (let ((org-archive-tag "Archive"))
93 (should-not (org-element-property :archivedp (org-element-at-point)))))
94 ;; Multiple tags.
95 (org-test-with-temp-text "* Headline :test:ARCHIVE:"
96 (let ((org-archive-tag "ARCHIVE"))
97 (let ((headline (org-element-at-point)))
98 (should (org-element-property :archivedp headline))
99 ;; Test tag removal.
100 (should (equal (org-element-property :tags headline) ":test:"))))))
104 ;;;; Example-blocks and Src-blocks
106 (ert-deftest test-org-element/block-switches ()
107 "Test `example-block' and `src-block' switches parsing."
108 (let ((org-coderef-label-format "(ref:%s)"))
109 ;; 1. Test "-i" switch.
110 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n(+ 1 1)\n#+END_SRC"
111 (let ((element (org-element-current-element)))
112 (should-not (org-element-property :preserve-indent element))))
113 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp -i\n(+ 1 1)\n#+END_SRC"
114 (let ((element (org-element-current-element)))
115 (should (org-element-property :preserve-indent element))))
116 (org-test-with-temp-text "#+BEGIN_EXAMPLE\nText.\n#+END_EXAMPLE"
117 (let ((element (org-element-current-element)))
118 (should-not (org-element-property :preserve-indent element))))
119 (org-test-with-temp-text "#+BEGIN_EXAMPLE -i\nText.\n#+END_EXAMPLE"
120 (let ((element (org-element-current-element)))
121 (should (org-element-property :preserve-indent element))))
122 ;; 2. "-n -r -k" combination should number lines, retain labels but
123 ;; not use them in coderefs.
124 (org-test-with-temp-text "#+BEGIN_EXAMPLE -n -r -k\nText.\N#+END_EXAMPLE"
125 (let ((element (org-element-current-element)))
126 (should (and (org-element-property :number-lines element)
127 (org-element-property :retain-labels element)
128 (not (org-element-property :use-labels element))))))
129 (org-test-with-temp-text
130 "#+BEGIN_SRC emacs-lisp -n -r -k\n(+ 1 1)\n#+END_SRC"
131 (let ((element (org-element-current-element)))
132 (should (and (org-element-property :number-lines element)
133 (org-element-property :retain-labels element)
134 (not (org-element-property :use-labels element))))))
135 ;; 3. "-n -r" combination should number-lines remove labels and not
136 ;; use them in coderefs.
137 (org-test-with-temp-text "#+BEGIN_EXAMPLE -n -r\nText.\n#+END_EXAMPLE"
138 (let ((element (org-element-current-element)))
139 (should (and (org-element-property :number-lines element)
140 (not (org-element-property :retain-labels element))
141 (not (org-element-property :use-labels element))))))
142 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp -n -r\n(+ 1 1)\n#+END_SRC"
143 (let ((element (org-element-current-element)))
144 (should (and (org-element-property :number-lines element)
145 (not (org-element-property :retain-labels element))
146 (not (org-element-property :use-labels element))))))
147 ;; 4. "-n" or "+n" should number lines, retain labels and use them
148 ;; in coderefs.
149 (org-test-with-temp-text "#+BEGIN_EXAMPLE -n\nText.\n#+END_EXAMPLE"
150 (let ((element (org-element-current-element)))
151 (should (and (org-element-property :number-lines element)
152 (org-element-property :retain-labels element)
153 (org-element-property :use-labels element)))))
154 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp -n\n(+ 1 1)\n#+END_SRC"
155 (let ((element (org-element-current-element)))
156 (should (and (org-element-property :number-lines element)
157 (org-element-property :retain-labels element)
158 (org-element-property :use-labels element)))))
159 (org-test-with-temp-text "#+BEGIN_EXAMPLE +n\nText.\n#+END_EXAMPLE"
160 (let ((element (org-element-current-element)))
161 (should (and (org-element-property :number-lines element)
162 (org-element-property :retain-labels element)
163 (org-element-property :use-labels element)))))
164 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp +n\n(+ 1 1)\n#+END_SRC"
165 (let ((element (org-element-current-element)))
166 (should (and (org-element-property :number-lines element)
167 (org-element-property :retain-labels element)
168 (org-element-property :use-labels element)))))
169 ;; 5. No switch should not number lines, but retain labels and use
170 ;; them in coderefs.
171 (org-test-with-temp-text "#+BEGIN_EXAMPLE\nText.\n#+END_EXAMPLE"
172 (let ((element (org-element-current-element)))
173 (should (and (not (org-element-property :number-lines element))
174 (org-element-property :retain-labels element)
175 (org-element-property :use-labels element)))))
176 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n(+ 1 1)\n#+END_SRC"
177 (let ((element (org-element-current-element)))
178 (should (and (not (org-element-property :number-lines element))
179 (org-element-property :retain-labels element)
180 (org-element-property :use-labels element)))))
181 ;; 6. "-r" switch only: do not number lines, remove labels, and
182 ;; don't use labels in coderefs.
183 (org-test-with-temp-text "#+BEGIN_EXAMPLE -r\nText.\n#+END_EXAMPLE"
184 (let ((element (org-element-current-element)))
185 (should (and (not (org-element-property :number-lines element))
186 (not (org-element-property :retain-labels element))
187 (not (org-element-property :use-labels element))))))
188 (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp -r\n(+ 1 1)\n#+END_SRC"
189 (let ((element (org-element-current-element)))
190 (should (and (not (org-element-property :number-lines element))
191 (not (org-element-property :retain-labels element))
192 (not (org-element-property :use-labels element))))))
193 ;; 7. Recognize coderefs with user-defined syntax.
194 (org-test-with-temp-text
195 "#+BEGIN_EXAMPLE -l \"[ref:%s]\"\nText [ref:text]\n#+END_EXAMPLE"
196 (let ((element (org-element-current-element)))
197 (should
198 (equal (org-element-property :label-fmt element) "[ref:%s]"))))
199 (org-test-with-temp-text
200 "#+BEGIN_SRC emacs-lisp -l \"[ref:%s]\"\n(+ 1 1) [ref:text]\n#+END_SRC"
201 (let ((element (org-element-current-element)))
202 (should
203 (equal (org-element-property :label-fmt element) "[ref:%s]"))))))
207 ;;;; Footnotes references and definitions
209 (ert-deftest test-org-element/footnote-reference ()
210 "Test footnote-reference parsing."
211 ;; 1. Parse a standard reference.
212 (org-test-with-temp-text "[fn:label]"
213 (should (equal (org-element-footnote-reference-parser)
214 '(footnote-reference
215 (:label "fn:label" :type standard :inline-definition nil
216 :begin 1 :end 11 :post-blank 0)))))
217 ;; 2. Parse a normalized reference.
218 (org-test-with-temp-text "[1]"
219 (should (equal (org-element-footnote-reference-parser)
220 '(footnote-reference
221 (:label "1" :type standard :inline-definition nil
222 :begin 1 :end 4 :post-blank 0)))))
223 ;; 3. Parse an inline reference.
224 (org-test-with-temp-text "[fn:test:def]"
225 (should (equal (org-element-footnote-reference-parser)
226 '(footnote-reference
227 (:label "fn:test" :type inline :inline-definition ("def")
228 :begin 1 :end 14 :post-blank 0)))))
229 ;; 4. Parse an anonymous reference.
230 (org-test-with-temp-text "[fn::def]"
231 (should (equal (org-element-footnote-reference-parser)
232 '(footnote-reference
233 (:label nil :type inline :inline-definition ("def")
234 :begin 1 :end 10 :post-blank 0)))))
235 ;; 5. Parse nested footnotes.
236 (org-test-with-temp-text "[fn::def [fn:label]]"
237 (should
238 (equal
239 (org-element-footnote-reference-parser)
240 '(footnote-reference
241 (:label nil :type inline
242 :inline-definition
243 ("def "
244 (footnote-reference
245 (:label "fn:label" :type standard :inline-definition nil
246 :begin 5 :end 15 :post-blank 0)))
247 :begin 1 :end 21 :post-blank 0)))))
248 ;; 6. Parse adjacent footnotes.
249 (org-test-with-temp-text "[fn:label1][fn:label2]"
250 (should
251 (equal
252 (org-element-footnote-reference-parser)
253 '(footnote-reference
254 (:label "fn:label1" :type standard :inline-definition nil :begin 1
255 :end 12 :post-blank 0)))))
256 ;; 7. Only properly closed footnotes are recognized as such.
257 (org-test-with-temp-text "Text [fn:label"
258 (should-not
259 (org-element-map
260 (org-element-parse-buffer) 'footnote-reference 'identity))))
264 ;;;; Granularity
266 (ert-deftest test-org-element/granularity ()
267 "Test granularity impact on buffer parsing."
268 (org-test-with-temp-text "
269 * Head 1
270 ** Head 2
271 #+BEGIN_CENTER
272 Centered paragraph.
273 #+END_CENTER
274 Paragraph \\alpha."
275 ;; 1.1. Granularity set to `headline' should parse every headline
276 ;; in buffer, and only them.
277 (let ((tree (org-element-parse-buffer 'headline)))
278 (should (= 2 (length (org-element-map tree 'headline 'identity))))
279 (should-not (org-element-map tree 'paragraph 'identity)))
280 ;; 1.2. Granularity set to `greater-element' should not enter
281 ;; greater elements excepted headlines and sections.
282 (let ((tree (org-element-parse-buffer 'greater-element)))
283 (should (= 1 (length (org-element-map tree 'center-block 'identity))))
284 (should (= 1 (length (org-element-map tree 'paragraph 'identity))))
285 (should-not (org-element-map tree 'entity 'identity)))
286 ;; 1.3. Granularity set to `element' should enter every
287 ;; greater-element.
288 (let ((tree (org-element-parse-buffer 'element)))
289 (should (= 2 (length (org-element-map tree 'paragraph 'identity))))
290 (should-not (org-element-map tree 'entity 'identity)))
291 ;; 1.4. Granularity set to `object' can see everything.
292 (let ((tree (org-element-parse-buffer 'object)))
293 (should (= 1 (length (org-element-map tree 'entity 'identity)))))))
295 (ert-deftest test-org-element/secondary-string-parsing ()
296 "Test if granularity correctly toggles secondary strings parsing."
297 ;; 1. With a granularity bigger than `object', no secondary string
298 ;; should be parsed.
300 ;; 1.1. Test with `headline' type.
301 (org-test-with-temp-text "* Headline"
302 (let ((headline
303 (org-element-map (org-element-parse-buffer 'headline) 'headline
304 'identity
306 'first-match)))
307 (should (stringp (org-element-property :title headline)))))
308 ;; 1.2. Test with `item' type.
309 (org-test-with-temp-text "* Headline\n- tag :: item"
310 (let ((item (org-element-map (org-element-parse-buffer 'element)
311 'item
312 'identity
314 'first-match)))
315 (should (stringp (org-element-property :tag item)))))
316 ;; 1.3. Test with `inlinetask' type, if avalaible.
317 (when (featurep 'org-inlinetask)
318 (let ((org-inlinetask-min-level 15))
319 (org-test-with-temp-text "*************** Inlinetask"
320 (let ((inlinetask (org-element-map (org-element-parse-buffer 'element)
321 'inlinetask
322 'identity
324 'first-match)))
325 (should (stringp (org-element-property :title inlinetask)))))))
326 ;; 2. With a default granularity, secondary strings should be
327 ;; parsed.
328 (org-test-with-temp-text "* Headline"
329 (let ((headline
330 (org-element-map (org-element-parse-buffer) 'headline
331 'identity
333 'first-match)))
334 (should (listp (org-element-property :title headline)))))
335 ;; 3. `org-element-at-point' should never parse a secondary string.
336 (org-test-with-temp-text "* Headline"
337 (should (stringp (org-element-property :title (org-element-at-point))))))
341 ;;;; Interpretation.
343 (ert-deftest test-org-element/interpret-affiliated-keywords ()
344 "Test if affiliated keywords are correctly interpreted."
345 ;; Interpret simple keywords.
346 (should
347 (equal
348 (org-element-interpret-data
349 '(org-data nil (paragraph (:name "para") "Paragraph")))
350 "#+NAME: para\nParagraph\n"))
351 ;; Interpret multiple keywords.
352 (should
353 (equal
354 (org-element-interpret-data
355 '(org-data nil (paragraph (:attr_ascii ("line1" "line2")) "Paragraph")))
356 "#+ATTR_ASCII: line1\n#+ATTR_ASCII: line2\nParagraph\n"))
357 ;; Interpret parsed keywords.
358 (should
359 (equal
360 (org-element-interpret-data
361 '(org-data nil (paragraph (:caption ("caption")) "Paragraph")))
362 "#+CAPTION: caption\nParagraph\n"))
363 ;; Interpret dual keywords.
364 (should
365 (equal
366 (org-element-interpret-data
367 '(org-data nil (paragraph (:caption (("long") "short")) "Paragraph")))
368 "#+CAPTION[short]: long\nParagraph\n")))
372 ;;;; Normalize contents
374 (ert-deftest test-org-element/normalize-contents ()
375 "Test `org-element-normalize-contents' specifications."
376 ;; 1. Remove maximum common indentation from element's contents.
377 (should
378 (equal
379 (org-element-normalize-contents
380 '(paragraph nil " Two spaces\n Three spaces"))
381 '(paragraph nil "Two spaces\n Three spaces")))
382 ;; 2. Ignore objects within contents when computing maximum common
383 ;; indentation.
384 (should
385 (equal
386 (org-element-normalize-contents
387 '(paragraph nil " One " (emphasis nil "space") "\n Two spaces"))
388 '(paragraph nil "One " (emphasis nil "space") "\n Two spaces")))
389 ;; 3. Ignore blank lines.
390 (should
391 (equal
392 (org-element-normalize-contents
393 '(paragraph nil " Two spaces\n\n \n Two spaces"))
394 '(paragraph nil "Two spaces\n\n \nTwo spaces")))
395 ;; 4. Recursively enter objects in order to compute common
396 ;; indentation.
397 (should
398 (equal
399 (org-element-normalize-contents
400 '(paragraph nil " Two spaces " (emphasis nil " and\n One space")))
401 '(paragraph nil " Two spaces " (emphasis nil " and\nOne space"))))
402 ;; 5. When optional argument is provided, ignore first line
403 ;; indentation.
404 (should
405 (equal
406 (org-element-normalize-contents
407 '(paragraph nil "No space\n Two spaces\n Three spaces") t)
408 '(paragraph nil "No space\nTwo spaces\n Three spaces"))))
411 ;;;; Navigation tools.
413 (ert-deftest test-org-element/forward-element ()
414 "Test `org-element-forward' specifications."
415 ;; 1. At EOB: should error.
416 (org-test-with-temp-text "Some text\n"
417 (goto-char (point-max))
418 (should-error (org-element-forward)))
419 ;; 2. Standard move: expected to ignore blank lines.
420 (org-test-with-temp-text "First paragraph.\n\n\nSecond paragraph."
421 (org-element-forward)
422 (should (looking-at "Second paragraph.")))
423 ;; 3. Headline tests.
424 (org-test-with-temp-text "
425 * Head 1
426 ** Head 1.1
427 *** Head 1.1.1
428 ** Head 1.2"
429 ;; 3.1. At an headline beginning: move to next headline at the
430 ;; same level.
431 (goto-line 3)
432 (org-element-forward)
433 (should (looking-at "** Head 1.2"))
434 ;; 3.2. At an headline beginning: move to parent headline if no
435 ;; headline at the same level.
436 (goto-line 3)
437 (org-element-forward)
438 (should (looking-at "** Head 1.2")))
439 ;; 4. Greater element tests.
440 (org-test-with-temp-text
441 "#+BEGIN_CENTER\nInside.\n#+END_CENTER\n\nOutside."
442 ;; 4.1. At a greater element: expected to skip contents.
443 (org-element-forward)
444 (should (looking-at "Outside."))
445 ;; 4.2. At the end of greater element contents: expected to skip
446 ;; to the end of the greater element.
447 (goto-line 2)
448 (org-element-forward)
449 (should (looking-at "Outside.")))
450 ;; 5. List tests.
451 (org-test-with-temp-text "
452 - item1
454 - sub1
456 - sub2
458 - sub3
460 Inner paragraph.
462 - item2
464 Outside."
465 ;; 5.1. At list top point: expected to move to the element after
466 ;; the list.
467 (goto-line 2)
468 (org-element-forward)
469 (should (looking-at "Outside."))
470 ;; 5.2. Special case: at the first line of a sub-list, but not at
471 ;; beginning of line, move to next item.
472 (goto-line 2)
473 (forward-char)
474 (org-element-forward)
475 (should (looking-at "- item2"))
476 (goto-line 4)
477 (forward-char)
478 (org-element-forward)
479 (should (looking-at " - sub2"))
480 ;; 5.3 At sub-list beginning: expected to move after the sub-list.
481 (goto-line 4)
482 (org-element-forward)
483 (should (looking-at " Inner paragraph."))
484 ;; 5.4. At sub-list end: expected to move outside the sub-list.
485 (goto-line 8)
486 (org-element-forward)
487 (should (looking-at " Inner paragraph."))
488 ;; 5.5. At an item: expected to move to next item, if any.
489 (goto-line 6)
490 (org-element-forward)
491 (should (looking-at " - sub3"))))
493 (ert-deftest test-org-element/backward-element ()
494 "Test `org-element-backward' specifications."
495 ;; 1. At BOB (modulo some white spaces): should error.
496 (org-test-with-temp-text " \nParagraph."
497 (org-skip-whitespace)
498 (should-error (org-element-backward)))
499 ;; 2. Not at the beginning of an element: move at its beginning.
500 (org-test-with-temp-text "Paragraph1.\n\nParagraph2."
501 (goto-line 3)
502 (end-of-line)
503 (org-element-backward)
504 (should (looking-at "Paragraph2.")))
505 ;; 3. Headline tests.
506 (org-test-with-temp-text "
507 * Head 1
508 ** Head 1.1
509 *** Head 1.1.1
510 ** Head 1.2"
511 ;; 3.1. At an headline beginning: move to previous headline at the
512 ;; same level.
513 (goto-line 5)
514 (org-element-backward)
515 (should (looking-at "** Head 1.1"))
516 ;; 3.2. At an headline beginning: move to parent headline if no
517 ;; headline at the same level.
518 (goto-line 3)
519 (org-element-backward)
520 (should (looking-at "* Head 1"))
521 ;; 3.3. At the first top-level headline: should error.
522 (goto-line 2)
523 (should-error (org-element-backward)))
524 ;; 4. At beginning of first element inside a greater element:
525 ;; expected to move to greater element's beginning.
526 (org-test-with-temp-text "Before.\n#+BEGIN_CENTER\nInside.\n#+END_CENTER."
527 (goto-line 3)
528 (org-element-backward)
529 (should (looking-at "#\\+BEGIN_CENTER")))
530 ;; 5. List tests.
531 (org-test-with-temp-text "
532 - item1
534 - sub1
536 - sub2
538 - sub3
540 Inner paragraph.
542 - item2
545 Outside."
546 ;; 5.1. At beginning of sub-list: expected to move to the
547 ;; paragraph before it.
548 (goto-line 4)
549 (org-element-backward)
550 (should (looking-at "item1"))
551 ;; 5.2. At an item in a list: expected to move at previous item.
552 (goto-line 8)
553 (org-element-backward)
554 (should (looking-at " - sub2"))
555 (goto-line 12)
556 (org-element-backward)
557 (should (looking-at "- item1"))
558 ;; 5.3. At end of list/sub-list: expected to move to list/sub-list
559 ;; beginning.
560 (goto-line 10)
561 (org-element-backward)
562 (should (looking-at " - sub1"))
563 (goto-line 15)
564 (org-element-backward)
565 (should (looking-at "- item1"))
566 ;; 5.4. At blank-lines before list end: expected to move to top
567 ;; item.
568 (goto-line 14)
569 (org-element-backward)
570 (should (looking-at "- item1"))))
572 (ert-deftest test-org-element/up-element ()
573 "Test `org-element-up' specifications."
574 ;; 1. At BOB or with no surrounding element: should error.
575 (org-test-with-temp-text "Paragraph."
576 (should-error (org-element-up)))
577 (org-test-with-temp-text "* Head1\n* Head2"
578 (goto-line 2)
579 (should-error (org-element-up)))
580 (org-test-with-temp-text "Paragraph1.\n\nParagraph2."
581 (goto-line 3)
582 (should-error (org-element-up)))
583 ;; 2. At an headline: move to parent headline.
584 (org-test-with-temp-text "* Head1\n** Sub-Head1\n** Sub-Head2"
585 (goto-line 3)
586 (org-element-up)
587 (should (looking-at "\\* Head1")))
588 ;; 3. Inside a greater element: move to greater element beginning.
589 (org-test-with-temp-text
590 "Before.\n#+BEGIN_CENTER\nParagraph1\nParagraph2\n#+END_CENTER\n"
591 (goto-line 3)
592 (org-element-up)
593 (should (looking-at "#\\+BEGIN_CENTER")))
594 ;; 4. List tests.
595 (org-test-with-temp-text "* Top
596 - item1
598 - sub1
600 - sub2
602 Paragraph within sub2.
604 - item2"
605 ;; 4.1. Within an item: move to the item beginning.
606 (goto-line 8)
607 (org-element-up)
608 (should (looking-at " - sub2"))
609 ;; 4.2. At an item in a sub-list: move to parent item.
610 (goto-line 4)
611 (org-element-up)
612 (should (looking-at "- item1"))
613 ;; 4.3. At an item in top list: move to beginning of whole list.
614 (goto-line 10)
615 (org-element-up)
616 (should (looking-at "- item1"))
617 ;; 4.4. Special case. At very top point: should move to parent of
618 ;; list.
619 (goto-line 2)
620 (org-element-up)
621 (should (looking-at "\\* Top"))))
623 (ert-deftest test-org-element/down-element ()
624 "Test `org-element-down' specifications."
625 ;; 1. Error when the element hasn't got a recursive type.
626 (org-test-with-temp-text "Paragraph."
627 (should-error (org-element-down)))
628 ;; 2. When at a plain-list, move to first item.
629 (org-test-with-temp-text "- Item 1\n - Item 1.1\n - Item 2.2"
630 (goto-line 2)
631 (org-element-down)
632 (should (looking-at " - Item 1.1")))
633 (org-test-with-temp-text "#+NAME: list\n- Item 1"
634 (org-element-down)
635 (should (looking-at " Item 1")))
636 ;; 3. When at a table, move to first row
637 (org-test-with-temp-text "#+NAME: table\n| a | b |"
638 (org-element-down)
639 (should (looking-at " a | b |")))
640 ;; 4. Otherwise, move inside the greater element.
641 (org-test-with-temp-text "#+BEGIN_CENTER\nParagraph.\n#+END_CENTER"
642 (org-element-down)
643 (should (looking-at "Paragraph"))))
645 (ert-deftest test-org-element/drag-backward ()
646 "Test `org-element-drag-backward' specifications."
647 ;; 1. Error when trying to move first element of buffer.
648 (org-test-with-temp-text "Paragraph 1.\n\nParagraph 2."
649 (should-error (org-element-drag-backward)))
650 ;; 2. Error when trying to swap nested elements.
651 (org-test-with-temp-text "#+BEGIN_CENTER\nTest.\n#+END_CENTER"
652 (forward-line)
653 (should-error (org-element-drag-backward)))
654 ;; 3. Error when trying to swap an headline element and
655 ;; a non-headline element.
656 (org-test-with-temp-text "Test.\n* Head 1"
657 (forward-line)
658 (should-error (org-element-drag-backward)))
659 ;; 4. Otherwise, swap elements, preserving column and blank lines
660 ;; between elements.
661 (org-test-with-temp-text "Para1\n\n\nParagraph 2\n\nPara3"
662 (search-forward "graph")
663 (org-element-drag-backward)
664 (should (equal (buffer-string) "Paragraph 2\n\n\nPara1\n\nPara3"))
665 (should (looking-at " 2"))))
667 (ert-deftest test-org-element/drag-forward ()
668 "Test `org-element-drag-forward' specifications."
669 ;; 1. Error when trying to move first element of buffer.
670 (org-test-with-temp-text "Paragraph 1.\n\nParagraph 2."
671 (goto-line 3)
672 (should-error (org-element-drag-forward)))
673 ;; 2. Error when trying to swap nested elements.
674 (org-test-with-temp-text "#+BEGIN_CENTER\nTest.\n#+END_CENTER"
675 (forward-line)
676 (should-error (org-element-drag-forward)))
677 ;; 3. Error when trying to swap a non-headline element and an
678 ;; headline.
679 (org-test-with-temp-text "Test.\n* Head 1"
680 (should-error (org-element-drag-forward)))
681 ;; 4. Otherwise, swap elements, preserving column and blank lines
682 ;; between elements.
683 (org-test-with-temp-text "Paragraph 1\n\n\nPara2\n\nPara3"
684 (search-forward "graph")
685 (org-element-drag-forward)
686 (should (equal (buffer-string) "Para2\n\n\nParagraph 1\n\nPara3"))
687 (should (looking-at " 1"))))
690 (provide 'test-org-element)
691 ;;; test-org-element.el ends here