test-org-footnote.el 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. ;;; test-org-footnote.el --- Tests for org-footnote.el
  2. ;; Copyright (C) 2012-2015 Nicolas Goaziou
  3. ;; Author: Nicolas Goaziou <mail at nicolasgoaziou dot fr>
  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 `random'.
  27. (should
  28. (string-match-p
  29. "Test\\[fn:\\(.+?\\)\\]\n+\\[fn:\\1\\]"
  30. (org-test-with-temp-text "Test<point>"
  31. (let ((org-footnote-auto-label 'random)
  32. (org-footnote-section nil))
  33. (org-footnote-new))
  34. (buffer-string))))
  35. ;; Error at beginning of line.
  36. (should-error
  37. (org-test-with-temp-text "<point>Test"
  38. (org-footnote-new)))
  39. ;; Error at keywords.
  40. (should-error
  41. (org-test-with-temp-text "#+TIT<point>LE: value"
  42. (org-footnote-new)))
  43. (should-error
  44. (org-test-with-temp-text "#+CAPTION: <point>\nParagraph"
  45. (org-footnote-new)))
  46. ;; Allow new footnotes in blank lines at the beginning of the
  47. ;; document.
  48. (should
  49. (string-match-p
  50. " \\[fn:1\\]"
  51. (org-test-with-temp-text " <point>"
  52. (let ((org-footnote-auto-label t)) (org-footnote-new))
  53. (buffer-string))))
  54. ;; In an headline or inlinetask, point must be either on the
  55. ;; heading itself or on the blank lines below.
  56. (should (org-test-with-temp-text "* H<point>" (org-footnote-new) t))
  57. (should
  58. (org-test-with-temp-text "* H\n <point>\nParagraph" (org-footnote-new) t))
  59. (should-error (org-test-with-temp-text "*<point> H" (org-footnote-new) t))
  60. (should-error
  61. (org-test-with-temp-text "* H <point>:tag:" (org-footnote-new) t))
  62. ;; Allow new footnotes within recursive objects, but not in links.
  63. (should
  64. (string-match-p
  65. " \\*bold\\[fn:1\\]\\*"
  66. (org-test-with-temp-text " *bold<point>*"
  67. (let ((org-footnote-auto-label t)) (org-footnote-new))
  68. (buffer-string))))
  69. (should-error
  70. (org-test-with-temp-text " [[http://orgmode.org][Org mode<point>]]"
  71. (org-footnote-new)))
  72. ;; Allow new footnotes in blank lines after an element or white
  73. ;; spaces after an object.
  74. (should
  75. (string-match-p
  76. " \\[fn:1\\]"
  77. (org-test-with-temp-text "#+BEGIN_EXAMPLE\nA\n#+END_EXAMPLE\n <point>"
  78. (let ((org-footnote-auto-label t)) (org-footnote-new))
  79. (buffer-string))))
  80. (should
  81. (string-match-p
  82. " \\*bold\\*\\[fn:1\\]"
  83. (org-test-with-temp-text " *bold*<point>"
  84. (let ((org-footnote-auto-label t)) (org-footnote-new))
  85. (buffer-string))))
  86. ;; When creating a new footnote, move to its definition.
  87. (should
  88. (string=
  89. "[fn:1] "
  90. (org-test-with-temp-text "Text<point>"
  91. (let ((org-footnote-auto-label t)
  92. (org-footnote-auto-adjust nil))
  93. (org-footnote-new))
  94. (buffer-substring-no-properties (line-beginning-position) (point)))))
  95. ;; Re-order and re-label footnotes properly when
  96. ;; `org-footnote-auto-adjust' is non-nil.
  97. (should
  98. (string=
  99. "[fn:1] 1\n\n[fn:2] \n\n[fn:3] 2\n"
  100. (org-test-with-temp-text
  101. "Text[fn:1]Text<point>Text[fn:2]\n\n[fn:1] 1\n\n[fn:2] 2"
  102. (let ((org-footnote-auto-label t)
  103. (org-footnote-auto-adjust t)
  104. (org-footnote-section nil))
  105. (org-footnote-new))
  106. (buffer-substring-no-properties
  107. (line-beginning-position -1)
  108. (line-beginning-position 4))))))
  109. (ert-deftest test-org-footnote/delete ()
  110. "Test `org-footnote-delete' specifications."
  111. ;; Regular test.
  112. (should
  113. (equal "Paragraph"
  114. (org-test-with-temp-text "Paragraph<point>[fn:1]\n\n[fn:1] Definition"
  115. (org-footnote-delete)
  116. (org-trim (buffer-string)))))
  117. ;; Remove multiple definitions and references.
  118. (should
  119. (equal "Paragraph and another"
  120. (org-test-with-temp-text
  121. "Paragraph<point>[fn:1] and another[fn:1]
  122. \[fn:1] def
  123. \[fn:1] def"
  124. (org-footnote-delete)
  125. (org-trim (buffer-string)))))
  126. ;; Delete inline footnotes and all references.
  127. (should
  128. (equal "Para and"
  129. (org-test-with-temp-text "Para<point>[fn:label:def] and[fn:label]"
  130. (org-footnote-delete)
  131. (org-trim (buffer-string)))))
  132. ;; Delete anonymous footnotes.
  133. (should
  134. (equal "Para"
  135. (let ((org-footnote-section nil))
  136. (org-test-with-temp-text "Para<point>[fn::def]"
  137. (org-footnote-delete)
  138. (org-trim (buffer-string))))))
  139. ;; With an argument, delete footnote with specified label.
  140. (should
  141. (equal "Paragraph[fn:1] and another\n\n[fn:1] def"
  142. (let ((org-footnote-section nil))
  143. (org-test-with-temp-text
  144. "Paragraph[fn:1] and another[fn:2]\n\n[fn:1] def\n\n[fn:2] def2"
  145. (org-footnote-delete "2")
  146. (org-trim (buffer-string))))))
  147. ;; Error when no argument is specified at point is not at a footnote
  148. ;; reference.
  149. (should-error
  150. (org-test-with-temp-text "Para[fn:1]\n\n[fn:1] Def"
  151. (org-footnote-delete)))
  152. ;; Correctly delete footnotes with multiple paragraphs.
  153. (should
  154. (equal "Para\n\n\nOutside footnote."
  155. (let ((org-footnote-section nil))
  156. (org-test-with-temp-text
  157. "Para[fn:1]\n\n[fn:1] para1\n\npara2\n\n\nOutside footnote."
  158. (org-footnote-delete "1")
  159. (org-trim (buffer-string)))))))
  160. (ert-deftest test-org-footnote/goto-definition ()
  161. "Test `org-footnote-goto-definition' specifications."
  162. ;; Error on unknown definitions.
  163. (should-error
  164. (org-test-with-temp-text "No footnote definition"
  165. (org-footnote-goto-definition "1")))
  166. ;; Error when trying to reach a definition outside narrowed part of
  167. ;; buffer.
  168. (should-error
  169. (org-test-with-temp-text "Some text<point>\n[fn:1] Definition."
  170. (narrow-to-region (point-min) (point))
  171. (org-footnote-goto-definition "1")))
  172. (should-error
  173. (org-test-with-temp-text "[fn:1] Definition.\n<point>Some text"
  174. (narrow-to-region (point) (point-max))
  175. (org-footnote-goto-definition "1")))
  176. ;; Otherwise, move at the beginning of the definition, including
  177. ;; anonymous footnotes.
  178. (should
  179. (equal
  180. "Definition."
  181. (org-test-with-temp-text "Some text\n[fn:1] Definition."
  182. (org-footnote-goto-definition "1")
  183. (buffer-substring (point) (point-max)))))
  184. (should
  185. (equal
  186. "definition]"
  187. (org-test-with-temp-text "Some text[fn:label:definition]"
  188. (org-footnote-goto-definition "label")
  189. (buffer-substring (point) (point-max))))))
  190. (ert-deftest test-org-footnote/sort ()
  191. "Test `org-footnote-sort' specifications."
  192. ;; Reorder definitions with a nil `org-footnote-section'. In this
  193. ;; case each definition is written at the end of the section
  194. ;; containing its first reference.
  195. (should
  196. (equal
  197. "
  198. Text[fn:1][fn:2]
  199. \[fn:1] Def 1
  200. \[fn:2] Def 2
  201. "
  202. (org-test-with-temp-text "
  203. Text[fn:1][fn:2]
  204. \[fn:2] Def 2
  205. \[fn:1] Def 1"
  206. (let ((org-footnote-section nil)) (org-footnote-sort))
  207. (buffer-string))))
  208. (should
  209. (equal
  210. "
  211. * H1
  212. Text[fn:1]
  213. \[fn:1] Def 1
  214. * H2
  215. Text[fn:2]
  216. \[fn:2] Def 2
  217. "
  218. (org-test-with-temp-text "
  219. * H1
  220. Text[fn:1]
  221. * H2
  222. Text[fn:2]
  223. \[fn:1] Def 1
  224. \[fn:2] Def 2
  225. "
  226. (let ((org-footnote-section nil)) (org-footnote-sort))
  227. (buffer-string))))
  228. ;; Reorder definitions with a non-nil `org-footnote-section'.
  229. (should
  230. (equal
  231. "
  232. Text[fn:1][fn:2]
  233. * Footnotes
  234. \[fn:1] Def 1
  235. \[fn:2] Def 2
  236. "
  237. (org-test-with-temp-text "
  238. Text[fn:1][fn:2]
  239. \[fn:2] Def 2
  240. \[fn:1] Def 1"
  241. (let ((org-footnote-section "Footnotes")) (org-footnote-sort))
  242. (buffer-string))))
  243. ;; When `org-footnote-section' is non-nil, clear previous footnote
  244. ;; sections.
  245. (should
  246. (equal
  247. "
  248. Text[fn:1]
  249. * Headline
  250. * Other headline
  251. * Footnotes
  252. \[fn:1] Def 1
  253. "
  254. (org-test-with-temp-text "
  255. Text[fn:1]
  256. * Footnotes
  257. \[fn:1] Def 1
  258. * Headline
  259. ** Footnotes
  260. * Other headline"
  261. (let ((org-footnote-section "Footnotes")) (org-footnote-sort))
  262. (buffer-string))))
  263. ;; Ignore anonymous footnotes.
  264. (should
  265. (equal
  266. "
  267. Text[fn:1][fn::inline][fn:2]
  268. \[fn:1] Def 1
  269. \[fn:2] Def 2
  270. "
  271. (org-test-with-temp-text
  272. "
  273. Text[fn:1][fn::inline][fn:2]
  274. \[fn:2] Def 2
  275. \[fn:1] Def 1"
  276. (let ((org-footnote-section nil)) (org-footnote-sort))
  277. (buffer-string))))
  278. ;; Ignore inline footnotes.
  279. (should
  280. (equal
  281. "
  282. Text[fn:1][fn:label:inline][fn:2]
  283. \[fn:1] Def 1
  284. \[fn:2] Def 2
  285. "
  286. (org-test-with-temp-text
  287. "
  288. Text[fn:1][fn:label:inline][fn:2]
  289. \[fn:2] Def 2
  290. \[fn:1] Def 1"
  291. (let ((org-footnote-section nil)) (org-footnote-sort))
  292. (buffer-string))))
  293. ;; Handle (deeply) nested footnotes.
  294. (should
  295. (equal
  296. "
  297. Text[fn:1][fn:3]
  298. \[fn:1] Def 1[fn:2]
  299. \[fn:2] Def 2
  300. \[fn:3] Def 3
  301. "
  302. (org-test-with-temp-text "
  303. Text[fn:1][fn:3]
  304. \[fn:1] Def 1[fn:2]
  305. \[fn:3] Def 3
  306. \[fn:2] Def 2
  307. "
  308. (let ((org-footnote-section nil)) (org-footnote-sort))
  309. (buffer-string))))
  310. (should
  311. (equal
  312. "
  313. Text[fn:1][fn:4]
  314. \[fn:1] Def 1[fn:2]
  315. \[fn:2] Def 2[fn:3]
  316. \[fn:3] Def 3
  317. \[fn:4] Def 4
  318. "
  319. (org-test-with-temp-text "
  320. Text[fn:1][fn:4]
  321. \[fn:1] Def 1[fn:2]
  322. \[fn:3] Def 3
  323. \[fn:2] Def 2[fn:3]
  324. \[fn:4] Def 4
  325. "
  326. (let ((org-footnote-section nil)) (org-footnote-sort))
  327. (buffer-string))))
  328. ;; When multiple (nested) references are used, make sure to insert
  329. ;; definition only once.
  330. (should
  331. (equal
  332. "
  333. * Section 1
  334. Text[fn:1]
  335. \[fn:1] Def 1
  336. * Section 2
  337. Text[fn:1]"
  338. (org-test-with-temp-text
  339. "
  340. * Section 1
  341. Text[fn:1]
  342. \[fn:1] Def 1
  343. * Section 2
  344. Text[fn:1]"
  345. (let ((org-footnote-section nil)) (org-footnote-sort))
  346. (buffer-string))))
  347. (should
  348. (equal
  349. "
  350. Text[fn:1][fn:4]
  351. \[fn:1] Def 1[fn:2][fn:3]
  352. \[fn:2] Def 2[fn:3]
  353. \[fn:3] Def 3
  354. \[fn:4] Def 4
  355. "
  356. (org-test-with-temp-text "
  357. Text[fn:1][fn:4]
  358. \[fn:1] Def 1[fn:2][fn:3]
  359. \[fn:3] Def 3
  360. \[fn:2] Def 2[fn:3]
  361. \[fn:4] Def 4
  362. "
  363. (let ((org-footnote-section nil)) (org-footnote-sort))
  364. (buffer-string)))))
  365. (ert-deftest test-org-footnote/renumber-fn:N ()
  366. "Test `org-footnote-renumber-fn:N' specifications."
  367. ;; Renumber (inline) references and definitions.
  368. (should
  369. (equal
  370. "Test[fn:1]"
  371. (org-test-with-temp-text "Test[fn:99]"
  372. (org-footnote-renumber-fn:N)
  373. (buffer-string))))
  374. (should
  375. (equal
  376. "Test[fn:1]\n\n[fn:1] 99"
  377. (org-test-with-temp-text "Test[fn:99]\n\n[fn:99] 99"
  378. (org-footnote-renumber-fn:N)
  379. (buffer-string))))
  380. (should
  381. (equal
  382. "Test[fn:1:99]"
  383. (org-test-with-temp-text "Test[fn:99:99]"
  384. (org-footnote-renumber-fn:N)
  385. (buffer-string))))
  386. ;; No-op if there's no numbered footnote.
  387. (should
  388. (equal
  389. "Test[fn:label]\n\n[fn:label] Def"
  390. (org-test-with-temp-text "Test[fn:label]\n\n[fn:label] Def"
  391. (org-footnote-renumber-fn:N)
  392. (buffer-string))))
  393. ;; Definitions without a reference get the highest numbers.
  394. (should
  395. (equal
  396. "Test[fn:1]\n[fn:1] 1\n[fn:2] 99"
  397. (org-test-with-temp-text "Test[fn:1]\n[fn:1] 1\n[fn:99] 99"
  398. (org-footnote-renumber-fn:N)
  399. (buffer-string))))
  400. ;; Sort labels in sequence. Anonymous footnotes are ignored.
  401. (should
  402. (equal
  403. "Test[fn:1][fn:2:def][fn:3]"
  404. (org-test-with-temp-text "Test[fn:4][fn:3:def][fn:2]"
  405. (org-footnote-renumber-fn:N)
  406. (buffer-string))))
  407. (should
  408. (equal
  409. "Test[fn:1][fn::def][fn:2]"
  410. (org-test-with-temp-text "Test[fn:4][fn::def][fn:2]"
  411. (org-footnote-renumber-fn:N)
  412. (buffer-string)))))
  413. (ert-deftest test-org-footnote/normalize ()
  414. "Test `org-footnote-normalize' specifications."
  415. ;; Normalize regular, inline and anonymous references.
  416. (should
  417. (equal
  418. "Test[fn:1]\n\n[fn:1] def\n"
  419. (org-test-with-temp-text "Test[fn:label]\n[fn:label] def"
  420. (let ((org-footnote-section nil)) (org-footnote-normalize))
  421. (buffer-string))))
  422. (should
  423. (equal
  424. "Test[fn:1]\n\n[fn:1] def\n"
  425. (org-test-with-temp-text "Test[fn:label:def]"
  426. (let ((org-footnote-section nil)) (org-footnote-normalize))
  427. (buffer-string))))
  428. (should
  429. (equal
  430. "Test[fn:1]\n\n[fn:1] def\n"
  431. (org-test-with-temp-text "Test[fn::def]"
  432. (let ((org-footnote-section nil)) (org-footnote-normalize))
  433. (buffer-string))))
  434. ;; Normalization includes sorting.
  435. (should
  436. (equal
  437. "Test[fn:1][fn:2]\n\n[fn:1] def2\n\n[fn:2] def\n"
  438. (org-test-with-temp-text "Test[fn:2][fn:1]\n\n[fn:2] def2\n[fn:1] def"
  439. (let ((org-footnote-section nil)) (org-footnote-normalize))
  440. (buffer-string))))
  441. (should
  442. (equal
  443. "Test[fn:1][fn:2]\n\n[fn:1] def\n\n[fn:2] inline\n"
  444. (org-test-with-temp-text "Test[fn:2][fn::inline]\n[fn:2] def\n"
  445. (let ((org-footnote-section nil)) (org-footnote-normalize))
  446. (buffer-string))))
  447. (should
  448. (equal
  449. "Test[fn:1][fn:3]
  450. \[fn:1] def[fn:2]
  451. \[fn:2] inline
  452. \[fn:3] last
  453. "
  454. (org-test-with-temp-text
  455. "Test[fn:lab1][fn:lab2]\n[fn:lab1] def[fn::inline]\n[fn:lab2] last"
  456. (let ((org-footnote-section nil)) (org-footnote-normalize))
  457. (buffer-string))))
  458. ;; When normalizing an inline reference, fill paragraph whenever the
  459. ;; `org-footnote-fill-after-inline-note-extraction' is non-nil.
  460. (should
  461. (equal
  462. "Test[fn:1] Next\n\n[fn:1] def\n"
  463. (org-test-with-temp-text "Test[fn::def]\nNext"
  464. (let ((org-footnote-section nil)
  465. (org-footnote-fill-after-inline-note-extraction t))
  466. (org-footnote-normalize))
  467. (buffer-string)))))
  468. (provide 'test-org-footnote)
  469. ;;; test-org-footnote.el ends here