test-org-footnote.el 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  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. ;; Allow new footnotes within recursive objects, but not in links.
  64. (should
  65. (string-match-p
  66. " \\*bold\\[fn:1\\]\\*"
  67. (org-test-with-temp-text " *bold<point>*"
  68. (let ((org-footnote-auto-label t)) (org-footnote-new))
  69. (buffer-string))))
  70. (should-error
  71. (org-test-with-temp-text " [[http://orgmode.org][Org mode<point>]]"
  72. (org-footnote-new)))
  73. ;; Allow new footnotes in blank lines after an element or white
  74. ;; spaces after an object.
  75. (should
  76. (string-match-p
  77. " \\[fn:1\\]"
  78. (org-test-with-temp-text "#+BEGIN_EXAMPLE\nA\n#+END_EXAMPLE\n <point>"
  79. (let ((org-footnote-auto-label t)) (org-footnote-new))
  80. (buffer-string))))
  81. (should
  82. (string-match-p
  83. " \\*bold\\*\\[fn:1\\]"
  84. (org-test-with-temp-text " *bold*<point>"
  85. (let ((org-footnote-auto-label t)) (org-footnote-new))
  86. (buffer-string)))))
  87. (ert-deftest test-org-footnote/delete ()
  88. "Test `org-footnote-delete' specifications."
  89. ;; Regular test.
  90. (should
  91. (equal "Paragraph"
  92. (org-test-with-temp-text "Paragraph[1]\n\n[1] Definition"
  93. (search-forward "[")
  94. (org-footnote-delete)
  95. (org-trim (buffer-string)))))
  96. ;; Remove multiple definitions and references.
  97. (should
  98. (equal "Paragraph and another"
  99. (org-test-with-temp-text
  100. "Paragraph[1] and another[1]\n\n[1] def\n\n[1] def"
  101. (search-forward "[")
  102. (org-footnote-delete)
  103. (org-trim (buffer-string)))))
  104. ;; Delete inline footnotes and all references.
  105. (should
  106. (equal "Para and"
  107. (org-test-with-temp-text "Para[fn:label:def] and[fn:label]"
  108. (search-forward "[")
  109. (org-footnote-delete)
  110. (org-trim (buffer-string)))))
  111. ;; Delete anonymous footnotes.
  112. (should
  113. (equal "Para"
  114. (org-test-with-temp-text "Para[fn::def]"
  115. (search-forward "[")
  116. (org-footnote-delete)
  117. (org-trim (buffer-string)))))
  118. ;; With an argument, delete footnote with specified label.
  119. (should
  120. (equal "Paragraph[1] and another\n\n[1] def"
  121. (let ((org-footnote-section nil))
  122. (org-test-with-temp-text
  123. "Paragraph[1] and another[2]\n\n[1] def\n\n[2] def2"
  124. (org-footnote-delete "2")
  125. (org-trim (buffer-string))))))
  126. ;; Error when no argument is specified at point is not at a footnote
  127. ;; reference.
  128. (should-error
  129. (org-test-with-temp-text "Para[1]\n\n[1] Def"
  130. (org-footnote-delete)))
  131. ;; Correctly delete footnotes with multiple paragraphs.
  132. (should
  133. (equal "Para\n\n\nOutside footnote."
  134. (org-test-with-temp-text
  135. "Para[1]\n\n[1] para1\n\npara2\n\n\nOutside footnote."
  136. (org-footnote-delete "1")
  137. (org-trim (buffer-string))))))
  138. (ert-deftest test-org-footnote/normalize-in-org ()
  139. "Test specifications for `org-footnote-normalize' in an Org buffer."
  140. ;; 1. With a non-nil `org-footnote-section'.
  141. (let ((org-footnote-section "Footnotes")
  142. (org-blank-before-new-entry '((heading . auto))))
  143. ;; 1.1. Normalize each type of footnote: standard, labelled,
  144. ;; numbered, inline, anonymous.
  145. (org-test-with-temp-text
  146. "Paragraph[fn:1][fn:label][1][fn:inline:Inline][fn::Anonymous]
  147. * Footnotes
  148. \[fn:1] Standard
  149. \[fn:label] Labelled
  150. \[1] Numbered"
  151. (org-footnote-normalize)
  152. (should
  153. (equal (buffer-string)
  154. "Paragraph[1][2][3][4][5]
  155. * Footnotes
  156. \[1] Standard
  157. \[2] Labelled
  158. \[3] Numbered
  159. \[4] Inline
  160. \[5] Anonymous
  161. ")))
  162. ;; 1.2. When no footnote section is present, create it. Follow
  163. ;; `org-blank-before-new-entry' specifications when doing so.
  164. (org-test-with-temp-text "Paragraph[fn:1]\n\n[fn:1] Definition"
  165. (org-footnote-normalize)
  166. (should (equal (buffer-string)
  167. "Paragraph[1]\n\n* Footnotes\n\n[1] Definition")))
  168. (org-test-with-temp-text "Paragraph[fn:1]\n* Head1\n[fn:1] Definition"
  169. (let ((org-blank-before-new-entry '((heading))))
  170. (org-footnote-normalize))
  171. (should (equal (buffer-string)
  172. "Paragraph[1]\n* Head1\n* Footnotes\n\n[1] Definition")))
  173. ;; 1.3. When the footnote section is misplaced, move it at the end
  174. ;; of the buffer.
  175. (org-test-with-temp-text "* Head1
  176. Body[fn:1]
  177. * Footnotes
  178. \[fn:1] Definition 1
  179. * Head2"
  180. (org-footnote-normalize)
  181. (should
  182. (equal (buffer-string)
  183. "* Head1
  184. Body[1]
  185. * Head2
  186. * Footnotes
  187. \[1] Definition 1"))))
  188. ;; 2. With a nil `org-footnote-section'.
  189. (let ((org-footnote-section nil))
  190. ;; 2.1. Normalize each type of footnote: standard, labelled,
  191. ;; numbered, inline, anonymous.
  192. (org-test-with-temp-text
  193. "Paragraph[fn:1][fn:label][1][fn:inline:Inline][fn::Anonymous]
  194. \[fn:1] Standard
  195. \[fn:label] Labelled
  196. \[1] Numbered"
  197. (org-footnote-normalize)
  198. (should
  199. (equal (buffer-string)
  200. "Paragraph[1][2][3][4][5]
  201. \[1] Standard
  202. \[2] Labelled
  203. \[3] Numbered
  204. \[4] Inline
  205. \[5] Anonymous
  206. ")))
  207. ;; 2.2. Put each footnote definition at the end of the section
  208. ;; containing its first reference.
  209. (org-test-with-temp-text
  210. "* Head 1
  211. Text[fn:1:Def1]
  212. * Head 2
  213. Text[fn:1]
  214. * Head 3
  215. Text[fn:2:Def2]"
  216. (org-footnote-normalize)
  217. (should
  218. (equal (buffer-string)
  219. "* Head 1
  220. Text[1]
  221. \[1] Def1
  222. * Head 2
  223. Text[1]
  224. * Head 3
  225. Text[2]
  226. \[2] Def2
  227. ")))))
  228. (ert-deftest test-org-footnote/normalize-outside-org ()
  229. "Test `org-footnote-normalize' specifications for buffers not in Org mode."
  230. ;; 1. In a non-Org buffer, footnotes definitions are always put at
  231. ;; its end.
  232. (should
  233. (equal
  234. "Paragraph[1][2][3][4][5]
  235. Some additional text.
  236. \[1] Standard
  237. \[2] Labelled
  238. \[3] Numbered
  239. \[4] Inline
  240. \[5] Anonymous"
  241. (let ((org-footnote-tag-for-non-org-mode-files nil))
  242. (with-temp-buffer
  243. (insert "Paragraph[fn:1][fn:label][1][fn:inline:Inline][fn::Anonymous]
  244. \[fn:1] Standard
  245. \[fn:label] Labelled
  246. \[1] Numbered
  247. Some additional text.")
  248. (org-footnote-normalize)
  249. (buffer-string)))))
  250. ;; 2. With a special tag.
  251. (let ((org-footnote-tag-for-non-org-mode-files "Footnotes:"))
  252. ;; 2.1. The tag must be inserted before the footnotes, separated
  253. ;; from the rest of the text with a blank line.
  254. (with-temp-buffer
  255. (insert "Paragraph[fn:1][fn::Anonymous]
  256. \[fn:1] Standard
  257. Some additional text.")
  258. (org-footnote-normalize)
  259. (should
  260. (equal (buffer-string)
  261. "Paragraph[1][2]
  262. Some additional text.
  263. Footnotes:
  264. \[1] Standard
  265. \[2] Anonymous")))
  266. ;; 2.2. Any tag already inserted in the buffer should be removed
  267. ;; prior to footnotes insertion.
  268. (with-temp-buffer
  269. (insert "Text[fn:1]
  270. Footnotes:
  271. Additional text.
  272. Footnotes:
  273. \[fn:1] Definition")
  274. (org-footnote-normalize)
  275. (should
  276. (equal (buffer-string)
  277. "Text[1]
  278. Additional text.
  279. Footnotes:
  280. \[1] Definition"))))
  281. ;; 3. As an exception, in `message-mode' buffer, if a signature is
  282. ;; present, insert footnotes before it.n
  283. (let ((org-footnote-tag-for-non-org-mode-files nil))
  284. (with-temp-buffer
  285. (insert "Body[fn::def]
  286. --
  287. Fake signature
  288. --
  289. Signature")
  290. ;; Mimic `message-mode'.
  291. (let ((major-mode 'message-mode)
  292. (message-cite-prefix-regexp "\\([ ]*[_.[:word:]]+>+\\|[ ]*[]>|]\\)+")
  293. (message-signature-separator "^-- $"))
  294. (flet ((message-point-in-header-p nil nil))
  295. (org-footnote-normalize)))
  296. (should
  297. (equal (buffer-string)
  298. "Body[1]
  299. --
  300. Fake signature
  301. \[1] def
  302. --
  303. Signature")))))
  304. (ert-deftest test-org-footnote/sort ()
  305. "Test footnotes definitions sorting."
  306. (let ((org-footnote-section nil))
  307. (org-test-with-temp-text
  308. "Text[fn:1][fn::inline][fn:2][fn:label]
  309. \[fn:label] C
  310. \[fn:1] A
  311. \[fn:2] B"
  312. (org-footnote-normalize 'sort)
  313. (should
  314. (equal (buffer-string)
  315. "Text[fn:1][fn::inline][fn:2][fn:label]
  316. \[fn:1] A
  317. \[fn:2] B
  318. \[fn:label] C
  319. ")))))
  320. (provide 'test-org-footnote)
  321. ;;; test-org-footnote.el ends here