Merge branch 'maint'
[org-mode/org-tableheadings.git] / testing / lisp / test-org-footnote.el
blobb2347cb97785fe1afb59d7feed4e465a6c2471a2
1 ;;; test-org-footnote.el --- Tests for org-footnote.el
3 ;; Copyright (C) 2012-2015 Nicolas Goaziou
5 ;; Author: Nicolas Goaziou <mail at nicolasgoaziou dot fr>
7 ;; This program is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
12 ;; This program is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ;;; Code:
22 (ert-deftest test-org-footnote/new ()
23 "Test `org-footnote-new' specifications."
24 ;; `org-footnote-auto-label' is t.
25 (should
26 (string-match-p
27 "Test\\[fn:1\\]\n+\\[fn:1\\]"
28 (org-test-with-temp-text "Test<point>"
29 (let ((org-footnote-auto-label t)
30 (org-footnote-section nil))
31 (org-footnote-new))
32 (buffer-string))))
33 ;; `org-footnote-auto-label' is `random'.
34 (should
35 (string-match-p
36 "Test\\[fn:\\(.+?\\)\\]\n+\\[fn:\\1\\]"
37 (org-test-with-temp-text "Test<point>"
38 (let ((org-footnote-auto-label 'random)
39 (org-footnote-section nil))
40 (org-footnote-new))
41 (buffer-string))))
42 ;; Error at beginning of line.
43 (should-error
44 (org-test-with-temp-text "<point>Test"
45 (org-footnote-new)))
46 ;; Error at keywords.
47 (should-error
48 (org-test-with-temp-text "#+TIT<point>LE: value"
49 (org-footnote-new)))
50 (should-error
51 (org-test-with-temp-text "#+CAPTION: <point>\nParagraph"
52 (org-footnote-new)))
53 ;; Allow new footnotes in blank lines at the beginning of the
54 ;; document.
55 (should
56 (string-match-p
57 " \\[fn:1\\]"
58 (org-test-with-temp-text " <point>"
59 (let ((org-footnote-auto-label t)) (org-footnote-new))
60 (buffer-string))))
61 ;; In an headline or inlinetask, point must be either on the
62 ;; heading itself or on the blank lines below.
63 (should (org-test-with-temp-text "* H<point>" (org-footnote-new) t))
64 (should
65 (org-test-with-temp-text "* H\n <point>\nParagraph" (org-footnote-new) t))
66 (should-error (org-test-with-temp-text "*<point> H" (org-footnote-new) t))
67 (should-error
68 (org-test-with-temp-text "* H <point>:tag:" (org-footnote-new) t))
69 ;; Allow new footnotes within recursive objects, but not in links.
70 (should
71 (string-match-p
72 " \\*bold\\[fn:1\\]\\*"
73 (org-test-with-temp-text " *bold<point>*"
74 (let ((org-footnote-auto-label t)) (org-footnote-new))
75 (buffer-string))))
76 (should-error
77 (org-test-with-temp-text " [[http://orgmode.org][Org mode<point>]]"
78 (org-footnote-new)))
79 ;; Allow new footnotes in blank lines after an element or white
80 ;; spaces after an object.
81 (should
82 (string-match-p
83 " \\[fn:1\\]"
84 (org-test-with-temp-text "#+BEGIN_EXAMPLE\nA\n#+END_EXAMPLE\n <point>"
85 (let ((org-footnote-auto-label t)) (org-footnote-new))
86 (buffer-string))))
87 (should
88 (string-match-p
89 " \\*bold\\*\\[fn:1\\]"
90 (org-test-with-temp-text " *bold*<point>"
91 (let ((org-footnote-auto-label t)) (org-footnote-new))
92 (buffer-string))))
93 ;; When creating a new footnote, move to its definition.
94 (should
95 (string=
96 "[fn:1] "
97 (org-test-with-temp-text "Text<point>"
98 (let ((org-footnote-auto-label t)
99 (org-footnote-auto-adjust nil))
100 (org-footnote-new))
101 (buffer-substring-no-properties (line-beginning-position) (point)))))
102 ;; Re-order and re-label footnotes properly when
103 ;; `org-footnote-auto-adjust' is non-nil.
104 (should
105 (string=
106 "[fn:1] 1\n\n[fn:2] \n\n[fn:3] 2\n"
107 (org-test-with-temp-text
108 "Text[fn:1]Text<point>Text[fn:2]\n\n[fn:1] 1\n\n[fn:2] 2"
109 (let ((org-footnote-auto-label t)
110 (org-footnote-auto-adjust t)
111 (org-footnote-section nil))
112 (org-footnote-new))
113 (buffer-substring-no-properties
114 (line-beginning-position -1)
115 (line-beginning-position 4))))))
117 (ert-deftest test-org-footnote/delete ()
118 "Test `org-footnote-delete' specifications."
119 ;; Regular test.
120 (should
121 (equal "Paragraph"
122 (org-test-with-temp-text "Paragraph<point>[fn:1]\n\n[fn:1] Definition"
123 (org-footnote-delete)
124 (org-trim (buffer-string)))))
125 ;; Remove multiple definitions and references.
126 (should
127 (equal "Paragraph and another"
128 (org-test-with-temp-text
129 "Paragraph<point>[fn:1] and another[fn:1]
131 \[fn:1] def
133 \[fn:1] def"
134 (org-footnote-delete)
135 (org-trim (buffer-string)))))
136 ;; Delete inline footnotes and all references.
137 (should
138 (equal "Para and"
139 (org-test-with-temp-text "Para<point>[fn:label:def] and[fn:label]"
140 (org-footnote-delete)
141 (org-trim (buffer-string)))))
142 ;; Delete anonymous footnotes.
143 (should
144 (equal "Para"
145 (let ((org-footnote-section nil))
146 (org-test-with-temp-text "Para<point>[fn::def]"
147 (org-footnote-delete)
148 (org-trim (buffer-string))))))
149 ;; With an argument, delete footnote with specified label.
150 (should
151 (equal "Paragraph[fn:1] and another\n\n[fn:1] def"
152 (let ((org-footnote-section nil))
153 (org-test-with-temp-text
154 "Paragraph[fn:1] and another[fn:2]\n\n[fn:1] def\n\n[fn:2] def2"
155 (org-footnote-delete "2")
156 (org-trim (buffer-string))))))
157 ;; Error when no argument is specified at point is not at a footnote
158 ;; reference.
159 (should-error
160 (org-test-with-temp-text "Para[fn:1]\n\n[fn:1] Def"
161 (org-footnote-delete)))
162 ;; Correctly delete footnotes with multiple paragraphs.
163 (should
164 (equal "Para\n\n\nOutside footnote."
165 (let ((org-footnote-section nil))
166 (org-test-with-temp-text
167 "Para[fn:1]\n\n[fn:1] para1\n\npara2\n\n\nOutside footnote."
168 (org-footnote-delete "1")
169 (org-trim (buffer-string))))))
170 ;; Remove blank lines above the footnote but preserve those after
171 ;; it.
172 (should
173 (equal "Text\n\n\nOther text."
174 (let ((org-footnote-section nil))
175 (org-test-with-temp-text
176 "Text[fn:1]\n\n[fn:1] Definition.\n\n\nOther text."
177 (org-footnote-delete "1")
178 (buffer-string))))))
180 (ert-deftest test-org-footnote/goto-definition ()
181 "Test `org-footnote-goto-definition' specifications."
182 ;; Error on unknown definitions.
183 (should-error
184 (org-test-with-temp-text "No footnote definition"
185 (org-footnote-goto-definition "1")))
186 ;; Error when trying to reach a definition outside narrowed part of
187 ;; buffer.
188 (should-error
189 (org-test-with-temp-text "Some text<point>\n[fn:1] Definition."
190 (narrow-to-region (point-min) (point))
191 (org-footnote-goto-definition "1")))
192 (should-error
193 (org-test-with-temp-text "[fn:1] Definition.\n<point>Some text"
194 (narrow-to-region (point) (point-max))
195 (org-footnote-goto-definition "1")))
196 ;; Otherwise, move at the beginning of the definition, including
197 ;; anonymous footnotes.
198 (should
199 (equal
200 "Definition."
201 (org-test-with-temp-text "Some text\n[fn:1] Definition."
202 (org-footnote-goto-definition "1")
203 (buffer-substring (point) (point-max)))))
204 (should
205 (equal
206 "definition]"
207 (org-test-with-temp-text "Some text[fn:label:definition]"
208 (org-footnote-goto-definition "label")
209 (buffer-substring (point) (point-max))))))
211 (ert-deftest test-org-footnote/sort ()
212 "Test `org-footnote-sort' specifications."
213 ;; Reorder definitions with a nil `org-footnote-section'. In this
214 ;; case each definition is written at the end of the section
215 ;; containing its first reference.
216 (should
217 (equal
219 Text[fn:1][fn:2]
221 \[fn:1] Def 1
223 \[fn:2] Def 2
225 (org-test-with-temp-text "
226 Text[fn:1][fn:2]
228 \[fn:2] Def 2
230 \[fn:1] Def 1"
231 (let ((org-footnote-section nil)) (org-footnote-sort))
232 (buffer-string))))
233 (should
234 (equal
236 * H1
237 Text[fn:1]
239 \[fn:1] Def 1
240 * H2
241 Text[fn:2]
243 \[fn:2] Def 2
245 (org-test-with-temp-text "
246 * H1
247 Text[fn:1]
248 * H2
249 Text[fn:2]
251 \[fn:1] Def 1
253 \[fn:2] Def 2
255 (let ((org-footnote-section nil)) (org-footnote-sort))
256 (buffer-string))))
257 ;; Reorder definitions with a non-nil `org-footnote-section'.
258 (should
259 (equal
261 Text[fn:1][fn:2]
263 * Footnotes
265 \[fn:1] Def 1
267 \[fn:2] Def 2
269 (org-test-with-temp-text "
270 Text[fn:1][fn:2]
272 \[fn:2] Def 2
274 \[fn:1] Def 1"
275 (let ((org-footnote-section "Footnotes")) (org-footnote-sort))
276 (buffer-string))))
277 ;; When `org-footnote-section' is non-nil, clear previous footnote
278 ;; sections.
279 (should
280 (equal
282 Text[fn:1]
284 * Headline
286 * Other headline
288 * Footnotes
290 \[fn:1] Def 1
292 (org-test-with-temp-text "
293 Text[fn:1]
295 * Footnotes
297 \[fn:1] Def 1
299 * Headline
301 ** Footnotes
303 * Other headline"
304 (let ((org-footnote-section "Footnotes")) (org-footnote-sort))
305 (buffer-string))))
306 ;; Ignore anonymous footnotes.
307 (should
308 (equal
310 Text[fn:1][fn::inline][fn:2]
312 \[fn:1] Def 1
314 \[fn:2] Def 2
316 (org-test-with-temp-text
318 Text[fn:1][fn::inline][fn:2]
320 \[fn:2] Def 2
322 \[fn:1] Def 1"
323 (let ((org-footnote-section nil)) (org-footnote-sort))
324 (buffer-string))))
325 ;; Ignore inline footnotes.
326 (should
327 (equal
329 Text[fn:1][fn:label:inline][fn:2]
331 \[fn:1] Def 1
333 \[fn:2] Def 2
335 (org-test-with-temp-text
337 Text[fn:1][fn:label:inline][fn:2]
339 \[fn:2] Def 2
341 \[fn:1] Def 1"
342 (let ((org-footnote-section nil)) (org-footnote-sort))
343 (buffer-string))))
344 ;; Handle (deeply) nested footnotes.
345 (should
346 (equal
348 Text[fn:1][fn:3]
350 \[fn:1] Def 1[fn:2]
352 \[fn:2] Def 2
354 \[fn:3] Def 3
356 (org-test-with-temp-text "
357 Text[fn:1][fn:3]
359 \[fn:1] Def 1[fn:2]
361 \[fn:3] Def 3
363 \[fn:2] Def 2
365 (let ((org-footnote-section nil)) (org-footnote-sort))
366 (buffer-string))))
367 (should
368 (equal
370 Text[fn:1][fn:4]
372 \[fn:1] Def 1[fn:2]
374 \[fn:2] Def 2[fn:3]
376 \[fn:3] Def 3
378 \[fn:4] Def 4
380 (org-test-with-temp-text "
381 Text[fn:1][fn:4]
383 \[fn:1] Def 1[fn:2]
385 \[fn:3] Def 3
387 \[fn:2] Def 2[fn:3]
389 \[fn:4] Def 4
391 (let ((org-footnote-section nil)) (org-footnote-sort))
392 (buffer-string))))
393 ;; When multiple (nested) references are used, make sure to insert
394 ;; definition only once.
395 (should
396 (equal
398 * Section 1
400 Text[fn:1]
402 \[fn:1] Def 1
404 * Section 2
406 Text[fn:1]"
407 (org-test-with-temp-text
409 * Section 1
411 Text[fn:1]
413 \[fn:1] Def 1
415 * Section 2
417 Text[fn:1]"
418 (let ((org-footnote-section nil)) (org-footnote-sort))
419 (buffer-string))))
420 (should
421 (equal
423 Text[fn:1][fn:4]
425 \[fn:1] Def 1[fn:2][fn:3]
427 \[fn:2] Def 2[fn:3]
429 \[fn:3] Def 3
431 \[fn:4] Def 4
433 (org-test-with-temp-text "
434 Text[fn:1][fn:4]
436 \[fn:1] Def 1[fn:2][fn:3]
438 \[fn:3] Def 3
440 \[fn:2] Def 2[fn:3]
442 \[fn:4] Def 4
444 (let ((org-footnote-section nil)) (org-footnote-sort))
445 (buffer-string))))
446 ;; Insert un-referenced definitions at the end.
447 (should
448 (equal
449 "Text[fn:9]
451 \[fn:9] B
453 \[fn:1] A
455 (org-test-with-temp-text "Text[fn:9]\n\n[fn:1] A\n[fn:9] B"
456 (let ((org-footnote-section nil)) (org-footnote-sort))
457 (buffer-string)))))
459 (ert-deftest test-org-footnote/renumber-fn:N ()
460 "Test `org-footnote-renumber-fn:N' specifications."
461 ;; Renumber (inline) references and definitions.
462 (should
463 (equal
464 "Test[fn:1]"
465 (org-test-with-temp-text "Test[fn:99]"
466 (org-footnote-renumber-fn:N)
467 (buffer-string))))
468 (should
469 (equal
470 "Test[fn:1]\n\n[fn:1] 99"
471 (org-test-with-temp-text "Test[fn:99]\n\n[fn:99] 99"
472 (org-footnote-renumber-fn:N)
473 (buffer-string))))
474 (should
475 (equal
476 "Test[fn:1:99]"
477 (org-test-with-temp-text "Test[fn:99:99]"
478 (org-footnote-renumber-fn:N)
479 (buffer-string))))
480 ;; No-op if there's no numbered footnote.
481 (should
482 (equal
483 "Test[fn:label]\n\n[fn:label] Def"
484 (org-test-with-temp-text "Test[fn:label]\n\n[fn:label] Def"
485 (org-footnote-renumber-fn:N)
486 (buffer-string))))
487 ;; Definitions without a reference get the highest numbers.
488 (should
489 (equal
490 "Test[fn:1]\n[fn:1] 1\n[fn:2] 99"
491 (org-test-with-temp-text "Test[fn:1]\n[fn:1] 1\n[fn:99] 99"
492 (org-footnote-renumber-fn:N)
493 (buffer-string))))
494 ;; Sort labels in sequence. Anonymous footnotes are ignored.
495 (should
496 (equal
497 "Test[fn:1][fn:2:def][fn:3]"
498 (org-test-with-temp-text "Test[fn:4][fn:3:def][fn:2]"
499 (org-footnote-renumber-fn:N)
500 (buffer-string))))
501 (should
502 (equal
503 "Test[fn:1][fn::def][fn:2]"
504 (org-test-with-temp-text "Test[fn:4][fn::def][fn:2]"
505 (org-footnote-renumber-fn:N)
506 (buffer-string)))))
508 (ert-deftest test-org-footnote/normalize ()
509 "Test `org-footnote-normalize' specifications."
510 ;; Normalize regular, inline and anonymous references.
511 (should
512 (equal
513 "Test[fn:1]\n\n[fn:1] def\n"
514 (org-test-with-temp-text "Test[fn:label]\n[fn:label] def"
515 (let ((org-footnote-section nil)) (org-footnote-normalize))
516 (buffer-string))))
517 (should
518 (equal
519 "Test[fn:1]\n\n[fn:1] def\n"
520 (org-test-with-temp-text "Test[fn:label:def]"
521 (let ((org-footnote-section nil)) (org-footnote-normalize))
522 (buffer-string))))
523 (should
524 (equal
525 "Test[fn:1]\n\n[fn:1] def\n"
526 (org-test-with-temp-text "Test[fn::def]"
527 (let ((org-footnote-section nil)) (org-footnote-normalize))
528 (buffer-string))))
529 ;; Normalization includes sorting.
530 (should
531 (equal
532 "Test[fn:1][fn:2]\n\n[fn:1] def2\n\n[fn:2] def\n"
533 (org-test-with-temp-text "Test[fn:2][fn:1]\n\n[fn:2] def2\n[fn:1] def"
534 (let ((org-footnote-section nil)) (org-footnote-normalize))
535 (buffer-string))))
536 (should
537 (equal
538 "Test[fn:1][fn:2]\n\n[fn:1] def\n\n[fn:2] inline\n"
539 (org-test-with-temp-text "Test[fn:2][fn::inline]\n[fn:2] def\n"
540 (let ((org-footnote-section nil)) (org-footnote-normalize))
541 (buffer-string))))
542 (should
543 (equal
544 "Test[fn:1][fn:3]
546 \[fn:1] def[fn:2]
548 \[fn:2] inline
550 \[fn:3] last
552 (org-test-with-temp-text
553 "Test[fn:lab1][fn:lab2]\n[fn:lab1] def[fn::inline]\n[fn:lab2] last"
554 (let ((org-footnote-section nil)) (org-footnote-normalize))
555 (buffer-string))))
556 ;; When normalizing an inline reference, fill paragraph whenever the
557 ;; `org-footnote-fill-after-inline-note-extraction' is non-nil.
558 (should
559 (equal
560 "Test[fn:1] Next\n\n[fn:1] def\n"
561 (org-test-with-temp-text "Test[fn::def]\nNext"
562 (let ((org-footnote-section nil)
563 (org-footnote-fill-after-inline-note-extraction t))
564 (org-footnote-normalize))
565 (buffer-string))))
566 ;; Insert un-referenced definitions at the end.
567 (should
568 (equal
569 "Test[fn:1]\nNext\n\n[fn:1] def\n\n[fn:2] A\n"
570 (org-test-with-temp-text "Test[fn::def]\nNext\n[fn:unref] A"
571 (let ((org-footnote-section nil)) (org-footnote-normalize))
572 (buffer-string)))))
575 (provide 'test-org-footnote)
576 ;;; test-org-footnote.el ends here