test-org-footnote.el 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. ;;; test-org-footnote.el --- Tests for org-footnote.el
  2. ;; Copyright (C) 2012-2015 Nicolas Goaziou
  3. ;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
  4. ;; This program is free software; you can redistribute it and/or modify
  5. ;; it under the terms of the GNU General Public License as published by
  6. ;; the Free Software Foundation, either version 3 of the License, or
  7. ;; (at your option) any later version.
  8. ;; This program is distributed in the hope that it will be useful,
  9. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. ;; GNU General Public License for more details.
  12. ;; You should have received a copy of the GNU General Public License
  13. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. ;;; Code:
  15. (ert-deftest test-org-footnote/new ()
  16. "Test `org-footnote-new' specifications."
  17. ;; `org-footnote-auto-label' is t.
  18. (should
  19. (string-match-p
  20. "Test\\[fn:1\\]\n+\\[fn:1\\]"
  21. (org-test-with-temp-text "Test<point>"
  22. (let ((org-footnote-auto-label t)
  23. (org-footnote-section nil))
  24. (org-footnote-new))
  25. (buffer-string))))
  26. ;; `org-footnote-auto-label' is `plain'.
  27. (should
  28. (string-match-p
  29. "Test\\[1\\]\n+\\[1\\]"
  30. (org-test-with-temp-text "Test<point>"
  31. (let ((org-footnote-auto-label 'plain)
  32. (org-footnote-section nil))
  33. (org-footnote-new))
  34. (buffer-string))))
  35. ;; `org-footnote-auto-label' is `random'.
  36. (should
  37. (string-match-p
  38. "Test\\[fn:\\(.+?\\)\\]\n+\\[fn:\\1\\]"
  39. (org-test-with-temp-text "Test<point>"
  40. (let ((org-footnote-auto-label 'random)
  41. (org-footnote-section nil))
  42. (org-footnote-new))
  43. (buffer-string))))
  44. ;; Error at beginning of line.
  45. (should-error
  46. (org-test-with-temp-text "<point>Test"
  47. (org-footnote-new)))
  48. ;; Error at keywords.
  49. (should-error
  50. (org-test-with-temp-text "#+TIT<point>LE: value"
  51. (org-footnote-new)))
  52. (should-error
  53. (org-test-with-temp-text "#+CAPTION: <point>\nParagraph"
  54. (org-footnote-new)))
  55. ;; Allow new footnotes in blank lines at the beginning of the
  56. ;; document.
  57. (should
  58. (string-match-p
  59. " \\[fn:1\\]"
  60. (org-test-with-temp-text " <point>"
  61. (let ((org-footnote-auto-label t)) (org-footnote-new))
  62. (buffer-string))))
  63. ;; In an headline or inlinetask, point must be either on the
  64. ;; heading itself or on the blank lines below.
  65. (should (org-test-with-temp-text "* H<point>" (org-footnote-new) t))
  66. (should
  67. (org-test-with-temp-text "* H\n <point>\nParagraph" (org-footnote-new) t))
  68. (should-error (org-test-with-temp-text "*<point> H" (org-footnote-new) t))
  69. (should-error
  70. (org-test-with-temp-text "* H <point>:tag:" (org-footnote-new) t))
  71. ;; Allow new footnotes within recursive objects, but not in links.
  72. (should
  73. (string-match-p
  74. " \\*bold\\[fn:1\\]\\*"
  75. (org-test-with-temp-text " *bold<point>*"
  76. (let ((org-footnote-auto-label t)) (org-footnote-new))
  77. (buffer-string))))
  78. (should-error
  79. (org-test-with-temp-text " [[http://orgmode.org][Org mode<point>]]"
  80. (org-footnote-new)))
  81. ;; Allow new footnotes in blank lines after an element or white
  82. ;; spaces after an object.
  83. (should
  84. (string-match-p
  85. " \\[fn:1\\]"
  86. (org-test-with-temp-text "#+BEGIN_EXAMPLE\nA\n#+END_EXAMPLE\n <point>"
  87. (let ((org-footnote-auto-label t)) (org-footnote-new))
  88. (buffer-string))))
  89. (should
  90. (string-match-p
  91. " \\*bold\\*\\[fn:1\\]"
  92. (org-test-with-temp-text " *bold*<point>"
  93. (let ((org-footnote-auto-label t)) (org-footnote-new))
  94. (buffer-string))))
  95. ;; When creating a new footnote, move to its definition.
  96. (should
  97. (string=
  98. "[fn:1] "
  99. (org-test-with-temp-text "Text<point>"
  100. (let ((org-footnote-auto-label t)
  101. (org-footnote-auto-adjust nil))
  102. (org-footnote-new))
  103. (buffer-substring-no-properties (line-beginning-position) (point)))))
  104. ;; Re-order and re-label footnotes properly when
  105. ;; `org-footnote-auto-adjust' is non-nil.
  106. (should
  107. (string=
  108. "[fn:1] 1\n\n[fn:2] \n\n[fn:3] 2\n"
  109. (org-test-with-temp-text
  110. "Text[fn:1]Text<point>Text[fn:2]\n\n[fn:1] 1\n\n[fn:2] 2"
  111. (let ((org-footnote-auto-label t)
  112. (org-footnote-auto-adjust t)
  113. (org-footnote-section nil))
  114. (org-footnote-new))
  115. (buffer-substring-no-properties
  116. (line-beginning-position -1)
  117. (line-beginning-position 4))))))
  118. (ert-deftest test-org-footnote/delete ()
  119. "Test `org-footnote-delete' specifications."
  120. ;; Regular test.
  121. (should
  122. (equal "Paragraph"
  123. (org-test-with-temp-text "Paragraph[1]\n\n[1] Definition"
  124. (search-forward "[")
  125. (org-footnote-delete)
  126. (org-trim (buffer-string)))))
  127. ;; Remove multiple definitions and references.
  128. (should
  129. (equal "Paragraph and another"
  130. (org-test-with-temp-text
  131. "Paragraph[1] and another[1]\n\n[1] def\n\n[1] def"
  132. (search-forward "[")
  133. (org-footnote-delete)
  134. (org-trim (buffer-string)))))
  135. ;; Delete inline footnotes and all references.
  136. (should
  137. (equal "Para and"
  138. (org-test-with-temp-text "Para[fn:label:def] and[fn:label]"
  139. (search-forward "[")
  140. (org-footnote-delete)
  141. (org-trim (buffer-string)))))
  142. ;; Delete anonymous footnotes.
  143. (should
  144. (equal "Para"
  145. (org-test-with-temp-text "Para[fn::def]"
  146. (search-forward "[")
  147. (org-footnote-delete)
  148. (org-trim (buffer-string)))))
  149. ;; With an argument, delete footnote with specified label.
  150. (should
  151. (equal "Paragraph[1] and another\n\n[1] def"
  152. (let ((org-footnote-section nil))
  153. (org-test-with-temp-text
  154. "Paragraph[1] and another[2]\n\n[1] def\n\n[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[1]\n\n[1] Def"
  161. (org-footnote-delete)))
  162. ;; Correctly delete footnotes with multiple paragraphs.
  163. (should
  164. (equal "Para\n\n\nOutside footnote."
  165. (org-test-with-temp-text
  166. "Para[1]\n\n[1] para1\n\npara2\n\n\nOutside footnote."
  167. (org-footnote-delete "1")
  168. (org-trim (buffer-string))))))
  169. (ert-deftest test-org-footnote/goto-definition ()
  170. "Test `org-footnote-goto-definition' specifications."
  171. ;; Error on unknown definitions.
  172. (should-error
  173. (org-test-with-temp-text "No footnote definition"
  174. (org-footnote-goto-definition "fn:1")))
  175. ;; Error when trying to reach a definition outside narrowed part of
  176. ;; buffer.
  177. (should-error
  178. (org-test-with-temp-text "Some text<point>\n[fn:1] Definition."
  179. (narrow-to-region (point-min) (point))
  180. (org-footnote-goto-definition "fn:1")))
  181. (should-error
  182. (org-test-with-temp-text "[fn:1] Definition.\n<point>Some text"
  183. (narrow-to-region (point) (point-max))
  184. (org-footnote-goto-definition "fn:1")))
  185. ;; Otherwise, move at the beginning of the definition, including
  186. ;; anonymous footnotes.
  187. (should
  188. (equal
  189. "Definition."
  190. (org-test-with-temp-text "Some text\n[fn:1] Definition."
  191. (org-footnote-goto-definition "fn:1")
  192. (buffer-substring (point) (point-max)))))
  193. (should
  194. (equal
  195. "definition]"
  196. (org-test-with-temp-text "Some text[fn:label:definition]"
  197. (org-footnote-goto-definition "fn:label")
  198. (buffer-substring (point) (point-max))))))
  199. (ert-deftest test-org-footnote/normalize-in-org ()
  200. "Test specifications for `org-footnote-normalize' in an Org buffer."
  201. ;; With a non-nil `org-footnote-section', normalize each type of
  202. ;; footnote: standard, labelled, numbered, inline, anonymous.
  203. (should
  204. (equal "Paragraph[1][2][3][4][5]
  205. * Footnotes
  206. \[1] Standard
  207. \[2] Labelled
  208. \[3] Numbered
  209. \[4] Inline
  210. \[5] Anonymous
  211. "
  212. (let ((org-footnote-section "Footnotes")
  213. (org-blank-before-new-entry '((heading . auto))))
  214. (org-test-with-temp-text
  215. "Paragraph[fn:1][fn:label][1][fn:inline:Inline][fn::Anonymous]
  216. * Footnotes
  217. \[fn:1] Standard
  218. \[fn:label] Labelled
  219. \[1] Numbered"
  220. (org-footnote-normalize)
  221. (buffer-string)))))
  222. ;; When no footnote section is present, create it. Follow
  223. ;; `org-blank-before-new-entry' specifications when doing so.
  224. (should
  225. (equal "Paragraph[1]\n\n* Footnotes\n\n[1] Definition"
  226. (let ((org-footnote-section "Footnotes")
  227. (org-blank-before-new-entry '((heading . auto))))
  228. (org-test-with-temp-text "Paragraph[fn:1]\n\n[fn:1] Definition"
  229. (org-footnote-normalize)
  230. (buffer-string)))))
  231. (should
  232. (equal
  233. "Paragraph[1]\n* Head1\n* Footnotes\n\n[1] Definition"
  234. (let ((org-footnote-section "Footnotes")
  235. (org-blank-before-new-entry '((heading))))
  236. (org-test-with-temp-text "Paragraph[fn:1]\n* Head1\n[fn:1] Definition"
  237. (org-footnote-normalize)
  238. (buffer-string)))))
  239. ;; When the footnote section is misplaced, move it at the end of
  240. ;; the buffer.
  241. (should
  242. (equal
  243. "* Head1
  244. Body[1]
  245. * Head2
  246. * Footnotes
  247. \[1] Definition 1"
  248. (let ((org-footnote-section "Footnotes")
  249. (org-blank-before-new-entry '((heading . auto))))
  250. (org-test-with-temp-text "* Head1
  251. Body[fn:1]
  252. * Footnotes
  253. \[fn:1] Definition 1
  254. * Head2"
  255. (org-footnote-normalize)
  256. (buffer-string)))))
  257. ;; With a nil `org-footnote-section', normalize each type of
  258. ;; footnote: standard, labelled, numbered, inline, anonymous.
  259. (should
  260. (equal "Paragraph[1][2][3][4][5]
  261. \[1] Standard
  262. \[2] Labelled
  263. \[3] Numbered
  264. \[4] Inline
  265. \[5] Anonymous
  266. "
  267. (let ((org-footnote-section nil))
  268. (org-test-with-temp-text
  269. "Paragraph[fn:1][fn:label][1][fn:inline:Inline][fn::Anonymous]
  270. \[fn:1] Standard
  271. \[fn:label] Labelled
  272. \[1] Numbered"
  273. (org-footnote-normalize)
  274. (buffer-string)))))
  275. ;; Also put each footnote definition at the end of the section
  276. ;; containing its first reference.
  277. (should
  278. (equal "* Head 1
  279. Text[1]
  280. \[1] Def1
  281. * Head 2
  282. Text[1]
  283. * Head 3
  284. Text[2]
  285. \[2] Def2
  286. "
  287. (let ((org-footnote-section nil))
  288. (org-test-with-temp-text
  289. "* Head 1
  290. Text[fn:1:Def1]
  291. * Head 2
  292. Text[fn:1]
  293. * Head 3
  294. Text[fn:2:Def2]"
  295. (org-footnote-normalize)
  296. (buffer-string))))))
  297. (ert-deftest test-org-footnote/normalize-outside-org ()
  298. "Test `org-footnote-normalize' specifications for buffers not in Org mode."
  299. ;; 1. In a non-Org buffer, footnotes definitions are always put at
  300. ;; its end.
  301. (should
  302. (equal
  303. "Paragraph[1][2][3][4][5]
  304. Some additional text.
  305. \[1] Standard
  306. \[2] Labelled
  307. \[3] Numbered
  308. \[4] Inline
  309. \[5] Anonymous"
  310. (let ((org-footnote-tag-for-non-org-mode-files nil))
  311. (with-temp-buffer
  312. (insert "Paragraph[fn:1][fn:label][1][fn:inline:Inline][fn::Anonymous]
  313. \[fn:1] Standard
  314. \[fn:label] Labelled
  315. \[1] Numbered
  316. Some additional text.")
  317. (org-footnote-normalize)
  318. (buffer-string)))))
  319. ;; 2. With a special tag.
  320. (let ((org-footnote-tag-for-non-org-mode-files "Footnotes:"))
  321. ;; 2.1. The tag must be inserted before the footnotes, separated
  322. ;; from the rest of the text with a blank line.
  323. (with-temp-buffer
  324. (insert "Paragraph[fn:1][fn::Anonymous]
  325. \[fn:1] Standard
  326. Some additional text.")
  327. (org-footnote-normalize)
  328. (should
  329. (equal (buffer-string)
  330. "Paragraph[1][2]
  331. Some additional text.
  332. Footnotes:
  333. \[1] Standard
  334. \[2] Anonymous")))
  335. ;; 2.2. Any tag already inserted in the buffer should be removed
  336. ;; prior to footnotes insertion.
  337. (with-temp-buffer
  338. (insert "Text[fn:1]
  339. Footnotes:
  340. Additional text.
  341. Footnotes:
  342. \[fn:1] Definition")
  343. (org-footnote-normalize)
  344. (should
  345. (equal (buffer-string)
  346. "Text[1]
  347. Additional text.
  348. Footnotes:
  349. \[1] Definition"))))
  350. ;; 3. As an exception, in `message-mode' buffer, if a signature is
  351. ;; present, insert footnotes before it.n
  352. (let ((org-footnote-tag-for-non-org-mode-files nil))
  353. (with-temp-buffer
  354. (insert "Body[fn::def]
  355. --
  356. Fake signature
  357. --
  358. Signature")
  359. ;; Mimic `message-mode'.
  360. (let ((major-mode 'message-mode)
  361. (message-cite-prefix-regexp "\\([ ]*[_.[:word:]]+>+\\|[ ]*[]>|]\\)+")
  362. (message-signature-separator "^-- $"))
  363. (flet ((message-point-in-header-p nil nil))
  364. (org-footnote-normalize)))
  365. (should
  366. (equal (buffer-string)
  367. "Body[1]
  368. --
  369. Fake signature
  370. \[1] def
  371. --
  372. Signature")))))
  373. (ert-deftest test-org-footnote/sort ()
  374. "Test footnotes definitions sorting."
  375. (let ((org-footnote-section nil))
  376. (org-test-with-temp-text
  377. "Text[fn:1][fn::inline][fn:2][fn:label]
  378. \[fn:label] C
  379. \[fn:1] A
  380. \[fn:2] B"
  381. (org-footnote-normalize 'sort)
  382. (should
  383. (equal (buffer-string)
  384. "Text[fn:1][fn::inline][fn:2][fn:label]
  385. \[fn:1] A
  386. \[fn:2] B
  387. \[fn:label] C
  388. ")))))
  389. (provide 'test-org-footnote)
  390. ;;; test-org-footnote.el ends here