test-org-capture.el 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. ;;; test-org-capture.el --- Tests for org-capture.el -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2015, 2017 Nicolas Goaziou
  3. ;; Author: Nicolas Goaziou <mail@nicolasgoaziou.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. ;;; Commentary:
  15. ;; Unit tests for Org Capture library.
  16. ;;; Code:
  17. (require 'org-capture)
  18. (ert-deftest test-org-capture/fill-template ()
  19. "Test `org-capture-fill-template' specifications."
  20. ;; When working on these tests consider to also change
  21. ;; `test-org-feed/fill-template'.
  22. ;; %(sexp) placeholder.
  23. (should
  24. (equal "success!\n"
  25. (org-capture-fill-template "%(concat \"success\" \"!\")")))
  26. ;; It is possible to include other place holders in %(sexp). In
  27. ;; that case properly escape \ and " characters.
  28. (should
  29. (equal "Nested string \"\\\"\\\"\"\n"
  30. (let ((org-store-link-plist nil))
  31. (org-capture-fill-template "%(concat \"%i\")"
  32. "Nested string \"\\\"\\\"\""))))
  33. ;; %<...> placeholder.
  34. (should
  35. (equal (concat (format-time-string "%Y") "\n")
  36. (org-capture-fill-template "%<%Y>")))
  37. ;; %t and %T placeholders.
  38. (should
  39. (equal (concat (format-time-string (org-time-stamp-format nil nil)) "\n")
  40. (org-capture-fill-template "%t")))
  41. (should
  42. (equal (concat (format-time-string (org-time-stamp-format t nil)) "\n")
  43. (org-capture-fill-template "%T")))
  44. ;; %u and %U placeholders.
  45. (should
  46. (equal
  47. (concat (format-time-string (org-time-stamp-format nil t)) "\n")
  48. (org-capture-fill-template "%u")))
  49. (should
  50. (equal
  51. (concat (format-time-string (org-time-stamp-format t t)) "\n")
  52. (org-capture-fill-template "%U")))
  53. ;; %i placeholder. Make sure sexp placeholders are not expanded
  54. ;; when they are inserted through this one.
  55. (should
  56. (equal "success!\n"
  57. (let ((org-store-link-plist nil))
  58. (org-capture-fill-template "%i" "success!"))))
  59. (should
  60. (equal "%(concat \"no \" \"evaluation\")\n"
  61. (let ((org-store-link-plist nil))
  62. (org-capture-fill-template
  63. "%i" "%(concat \"no \" \"evaluation\")"))))
  64. ;; When %i contents span over multiple line, repeat initial leading
  65. ;; characters over each line.
  66. (should
  67. (equal "> line 1\n> line 2\n"
  68. (let ((org-store-link-plist nil))
  69. (org-capture-fill-template "> %i" "line 1\nline 2"))))
  70. ;; Test %-escaping with \ character.
  71. (should
  72. (equal "%i\n"
  73. (let ((org-store-link-plist nil))
  74. (org-capture-fill-template "\\%i" "success!"))))
  75. (should
  76. (equal "\\success!\n"
  77. (let ((org-store-link-plist nil))
  78. (org-capture-fill-template "\\\\%i" "success!"))))
  79. (should
  80. (equal "\\%i\n"
  81. (let ((org-store-link-plist nil))
  82. (org-capture-fill-template "\\\\\\%i" "success!"))))
  83. ;; More than one placeholder in the same template.
  84. (should
  85. (equal "success! success! success! success!\n"
  86. (let ((org-store-link-plist nil))
  87. (org-capture-fill-template "%i %i %i %i" "success!"))))
  88. ;; %(sexp) placeholder with an input containing the traps %, " and )
  89. ;; all at once which is complicated to parse.
  90. (should
  91. (equal "5 % Less (See Item \"3)\" Somewhere)\n"
  92. (let ((org-store-link-plist nil))
  93. (org-capture-fill-template
  94. "%(capitalize \"%i\")"
  95. "5 % less (see item \"3)\" somewhere)")))))
  96. (ert-deftest test-org-capture/refile ()
  97. "Test `org-capture-refile' specifications."
  98. ;; When refiling, make sure the headline being refiled is the one
  99. ;; being captured. In particular, empty lines after the entry may
  100. ;; be removed, and we don't want to shift onto the next heading.
  101. (should
  102. (string-prefix-p
  103. "** H1"
  104. (org-test-with-temp-text-in-file "* A\n* B\n"
  105. (let* ((file (buffer-file-name))
  106. (org-capture-templates
  107. `(("t" "Todo" entry (file+headline ,file "A") "** H1 %?"))))
  108. (org-capture nil "t")
  109. (insert "\n")
  110. (cl-letf (((symbol-function 'org-refile)
  111. (lambda ()
  112. (interactive)
  113. (throw :return
  114. (buffer-substring-no-properties
  115. (line-beginning-position)
  116. (line-end-position))))))
  117. (catch :return (org-capture-refile)))))))
  118. ;; When the entry is refiled, `:jump-to-captured' moves point to the
  119. ;; refile location, not the initial capture target.
  120. (should
  121. (org-test-with-temp-text-in-file "* Refile target"
  122. (let ((file1 (buffer-file-name)))
  123. (org-test-with-temp-text-in-file "* A"
  124. (let* ((file2 (buffer-file-name))
  125. (org-capture-templates
  126. `(("t" "Todo" entry (file+headline ,file2 "A")
  127. "** H1 %?" :jump-to-captured t))))
  128. (org-capture nil "t")
  129. (cl-letf (((symbol-function 'org-refile-get-location)
  130. (lambda (&rest args)
  131. (list (file-name-nondirectory file1) file1 nil nil))))
  132. (org-capture-refile)
  133. (list file1 file2 (buffer-file-name)))))))))
  134. (ert-deftest test-org-capture/abort ()
  135. "Test aborting a capture process."
  136. ;; Test that capture can be aborted after inserting at end of
  137. ;; capture buffer.
  138. (should
  139. (equal
  140. "* A\n* B\n"
  141. (org-test-with-temp-text-in-file "* A\n* B\n"
  142. (let* ((file (buffer-file-name))
  143. (org-capture-templates
  144. `(("t" "Todo" entry (file+headline ,file "A") "** H1 %?"))))
  145. (org-capture nil "t")
  146. (goto-char (point-max))
  147. (insert "Capture text")
  148. (org-capture-kill))
  149. (buffer-string))))
  150. ;; Test aborting a capture that split the line.
  151. (should
  152. (equal
  153. "* AB\n"
  154. (org-test-with-temp-text-in-file "* AB\n"
  155. (let* ((file (buffer-file-name))
  156. (org-capture-templates
  157. `(("t" "Todo" entry
  158. (file+function ,file (lambda () (goto-char 4))) "** H1 %?"))))
  159. (org-capture nil "t")
  160. (org-capture-kill))
  161. (buffer-string)))))
  162. (ert-deftest test-org-caputre/entry ()
  163. "Test `entry' type in capture template."
  164. ;; Do not break next headline.
  165. (should
  166. (equal
  167. "* A\n** H1 Capture text\n* B\n"
  168. (org-test-with-temp-text-in-file "* A\n* B\n"
  169. (let* ((file (buffer-file-name))
  170. (org-capture-templates
  171. `(("t" "Todo" entry (file+headline ,file "A") "** H1 %?"))))
  172. (org-capture nil "t")
  173. (goto-char (point-max))
  174. (insert "Capture text")
  175. (org-capture-finalize))
  176. (buffer-string)))))
  177. (ert-deftest test-org-capture/table-line ()
  178. "Test `table-line' type in capture template."
  179. ;; When a only file is specified, use the first table available.
  180. (should
  181. (equal "Text
  182. | a |
  183. | x |
  184. | b |"
  185. (org-test-with-temp-text-in-file "Text\n\n| a |\n\n| b |"
  186. (let* ((file (buffer-file-name))
  187. (org-capture-templates
  188. `(("t" "Table" table-line (file ,file) "| x |"
  189. :immediate-finish t))))
  190. (org-capture nil "t"))
  191. (buffer-string))))
  192. ;; When an entry is specified, find the first table in the
  193. ;; corresponding section.
  194. (should
  195. (equal "* Foo
  196. | a |
  197. * Inbox
  198. | b |
  199. | x |
  200. "
  201. (org-test-with-temp-text-in-file "* Foo\n| a |\n* Inbox\n| b |\n"
  202. (let* ((file (buffer-file-name))
  203. (org-capture-templates
  204. `(("t" "Table" table-line (file+headline ,file "Inbox")
  205. "| x |" :immediate-finish t))))
  206. (org-capture nil "t"))
  207. (buffer-string))))
  208. (should
  209. (equal "* Inbox
  210. | a |
  211. | x |
  212. | b |
  213. "
  214. (org-test-with-temp-text-in-file "* Inbox\n| a |\n\n| b |\n"
  215. (let* ((file (buffer-file-name))
  216. (org-capture-templates
  217. `(("t" "Table" table-line (file+headline ,file "Inbox")
  218. "| x |" :immediate-finish t))))
  219. (org-capture nil "t"))
  220. (buffer-string))))
  221. ;; When a precise location is specified, find the first table after
  222. ;; point, down to the end of the section.
  223. (should
  224. (equal "| a |
  225. | b |
  226. | x |
  227. "
  228. (org-test-with-temp-text-in-file "| a |\n\n\n| b |\n"
  229. (let* ((file (buffer-file-name))
  230. (org-capture-templates
  231. `(("t" "Table" table-line (file+function ,file forward-line)
  232. "| x |" :immediate-finish t))))
  233. (org-capture nil "t"))
  234. (buffer-string))))
  235. ;; Create a new table with an empty header when none can be found.
  236. (should
  237. (equal "| | |\n|---+---|\n| a | b |\n"
  238. (org-test-with-temp-text-in-file ""
  239. (let* ((file (buffer-file-name))
  240. (org-capture-templates
  241. `(("t" "Table" table-line (file ,file) "| a | b |"
  242. :immediate-finish t))))
  243. (org-capture nil "t"))
  244. (buffer-string))))
  245. ;; Properly insert row with formulas.
  246. (should
  247. (equal "| 1 |\n| 2 |\n#+TBLFM: "
  248. (org-test-with-temp-text-in-file "| 1 |\n#+TBLFM: "
  249. (let* ((file (buffer-file-name))
  250. (org-capture-templates
  251. `(("t" "Table" table-line (file ,file)
  252. "| 2 |" :immediate-finish t))))
  253. (org-capture nil "t"))
  254. (buffer-string))))
  255. ;; When `:prepend' is nil, add the row at the end of the table.
  256. (should
  257. (equal "| a |\n| x |\n"
  258. (org-test-with-temp-text-in-file "| a |"
  259. (let* ((file (buffer-file-name))
  260. (org-capture-templates
  261. `(("t" "Table" table-line (file ,file)
  262. "| x |" :immediate-finish t))))
  263. (org-capture nil "t"))
  264. (buffer-string))))
  265. ;; When `:prepend' is non-nil, add it as the first row after the
  266. ;; header, if there is one, or the first row otherwise.
  267. (should
  268. (equal "| a |\n|---|\n| x |\n| b |"
  269. (org-test-with-temp-text-in-file "| a |\n|---|\n| b |"
  270. (let* ((file (buffer-file-name))
  271. (org-capture-templates
  272. `(("t" "Table" table-line (file ,file)
  273. "| x |" :immediate-finish t :prepend t))))
  274. (org-capture nil "t"))
  275. (buffer-string))))
  276. (should
  277. (equal "| x |\n| a |"
  278. (org-test-with-temp-text-in-file "| a |"
  279. (let* ((file (buffer-file-name))
  280. (org-capture-templates
  281. `(("t" "Table" table-line (file ,file)
  282. "| x |" :immediate-finish t :prepend t))))
  283. (org-capture nil "t"))
  284. (buffer-string))))
  285. ;; When `:table-line-pos' is set and is meaningful, obey it.
  286. (should
  287. (equal "| a |\n|---|\n| b |\n| x |\n|---|\n| c |"
  288. (org-test-with-temp-text-in-file "| a |\n|---|\n| b |\n|---|\n| c |"
  289. (let* ((file (buffer-file-name))
  290. (org-capture-templates
  291. `(("t" "Table" table-line (file ,file)
  292. "| x |" :immediate-finish t :table-line-pos "II-1"))))
  293. (org-capture nil "t"))
  294. (buffer-string))))
  295. (should
  296. (equal "| a |\n|---|\n| x |\n| b |\n|---|\n| c |"
  297. (org-test-with-temp-text-in-file "| a |\n|---|\n| b |\n|---|\n| c |"
  298. (let* ((file (buffer-file-name))
  299. (org-capture-templates
  300. `(("t" "Table" table-line (file ,file)
  301. "| x |" :immediate-finish t :table-line-pos "I+1"))))
  302. (org-capture nil "t"))
  303. (buffer-string))))
  304. ;; Throw an error on invalid `:table-line-pos' specifications.
  305. (should-error
  306. (org-test-with-temp-text-in-file "| a |"
  307. (let* ((file (buffer-file-name))
  308. (org-capture-templates
  309. `(("t" "Table" table-line (file ,file)
  310. "| x |" :immediate-finish t :table-line-pos "II+99"))))
  311. (org-capture nil "t")
  312. t)))
  313. ;; Update formula when capturing one or more rows.
  314. (should
  315. (equal
  316. '(("@3$1" . "9"))
  317. (org-test-with-temp-text-in-file "| 1 |\n|---|\n| 9 |\n#+tblfm: @2$1=9"
  318. (let* ((file (buffer-file-name))
  319. (org-capture-templates
  320. `(("t" "Table" table-line (file ,file)
  321. "| 2 |" :immediate-finish t :table-line-pos "I-1"))))
  322. (org-capture nil "t")
  323. (org-table-get-stored-formulas)))))
  324. (should
  325. (equal
  326. '(("@4$1" . "9"))
  327. (org-test-with-temp-text-in-file "| 1 |\n|---|\n| 9 |\n#+tblfm: @2$1=9"
  328. (let* ((file (buffer-file-name))
  329. (org-capture-templates
  330. `(("t" "Table" table-line (file ,file)
  331. "| 2 |\n| 3 |" :immediate-finish t :table-line-pos "I-1"))))
  332. (org-capture nil "t")
  333. (org-table-get-stored-formulas)))))
  334. ;; Do not update formula when cell in inserted below affected row.
  335. (should-not
  336. (equal
  337. '(("@3$1" . "9"))
  338. (org-test-with-temp-text-in-file "| 1 |\n|---|\n| 9 |\n#+tblfm: @2$1=9"
  339. (let* ((file (buffer-file-name))
  340. (org-capture-templates
  341. `(("t" "Table" table-line (file ,file)
  342. "| 2 |" :immediate-finish t))))
  343. (org-capture nil "t")
  344. (org-table-get-stored-formulas))))))
  345. (provide 'test-org-capture)
  346. ;;; test-org-capture.el ends here