test-org-capture.el 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. ;;; test-org-capture.el --- Tests for org-capture.el -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2015, 2017, 2019 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. Also try possibly problematic
  66. ;; prefixes such as "\\".
  67. (should
  68. (equal "> line 1\n> line 2\n"
  69. (let ((org-store-link-plist nil))
  70. (org-capture-fill-template "> %i" "line 1\nline 2"))))
  71. (should
  72. (equal "\\ line 1\n\\ line 2\n"
  73. (let ((org-store-link-plist nil))
  74. (org-capture-fill-template "\\ %i" "line 1\nline 2"))))
  75. ;; Test %-escaping with \ character.
  76. (should
  77. (equal "%i\n"
  78. (let ((org-store-link-plist nil))
  79. (org-capture-fill-template "\\%i" "success!"))))
  80. (should
  81. (equal "\\success!\n"
  82. (let ((org-store-link-plist nil))
  83. (org-capture-fill-template "\\\\%i" "success!"))))
  84. (should
  85. (equal "\\%i\n"
  86. (let ((org-store-link-plist nil))
  87. (org-capture-fill-template "\\\\\\%i" "success!"))))
  88. ;; More than one placeholder in the same template.
  89. (should
  90. (equal "success! success! success! success!\n"
  91. (let ((org-store-link-plist nil))
  92. (org-capture-fill-template "%i %i %i %i" "success!"))))
  93. ;; %(sexp) placeholder with an input containing the traps %, " and )
  94. ;; all at once which is complicated to parse.
  95. (should
  96. (equal "5 % Less (See Item \"3)\" Somewhere)\n"
  97. (let ((org-store-link-plist nil))
  98. (org-capture-fill-template
  99. "%(capitalize \"%i\")"
  100. "5 % less (see item \"3)\" somewhere)")))))
  101. (ert-deftest test-org-capture/refile ()
  102. "Test `org-capture-refile' specifications."
  103. ;; When refiling, make sure the headline being refiled is the one
  104. ;; being captured. In particular, empty lines after the entry may
  105. ;; be removed, and we don't want to shift onto the next heading.
  106. (should
  107. (string-prefix-p
  108. "** H1"
  109. (org-test-with-temp-text-in-file "* A\n* B\n"
  110. (let* ((file (buffer-file-name))
  111. (org-capture-templates
  112. `(("t" "Todo" entry (file+headline ,file "A") "** H1 %?"))))
  113. (org-capture nil "t")
  114. (insert "\n")
  115. (cl-letf (((symbol-function 'org-refile)
  116. (lambda ()
  117. (interactive)
  118. (throw :return
  119. (buffer-substring-no-properties
  120. (line-beginning-position)
  121. (line-end-position))))))
  122. (catch :return (org-capture-refile)))))))
  123. ;; When the entry is refiled, `:jump-to-captured' moves point to the
  124. ;; refile location, not the initial capture target.
  125. (should
  126. (org-test-with-temp-text-in-file "* Refile target"
  127. (let ((file1 (buffer-file-name)))
  128. (org-test-with-temp-text-in-file "* A"
  129. (let* ((file2 (buffer-file-name))
  130. (org-capture-templates
  131. `(("t" "Todo" entry (file+headline ,file2 "A")
  132. "** H1 %?" :jump-to-captured t))))
  133. (org-capture nil "t")
  134. (cl-letf (((symbol-function 'org-refile-get-location)
  135. (lambda (&rest args)
  136. (list (file-name-nondirectory file1) file1 nil nil))))
  137. (org-capture-refile)
  138. (list file1 file2 (buffer-file-name)))))))))
  139. (ert-deftest test-org-capture/abort ()
  140. "Test aborting a capture process."
  141. ;; Test that capture can be aborted after inserting at end of
  142. ;; capture buffer.
  143. (should
  144. (equal
  145. "* A\n* B\n"
  146. (org-test-with-temp-text-in-file "* A\n* B\n"
  147. (let* ((file (buffer-file-name))
  148. (org-capture-templates
  149. `(("t" "Todo" entry (file+headline ,file "A") "** H1 %?"))))
  150. (org-capture nil "t")
  151. (goto-char (point-max))
  152. (insert "Capture text")
  153. (org-capture-kill))
  154. (buffer-string))))
  155. (should
  156. (equal "- A\n - B\n"
  157. (org-test-with-temp-text-in-file "- A\n - B"
  158. (let* ((file (buffer-file-name))
  159. (org-capture-templates
  160. `(("t" "Item" item (file ,file) "- X"))))
  161. (org-capture nil "t")
  162. (org-capture-kill))
  163. (buffer-string))))
  164. (should
  165. (equal "| a |\n| b |\n"
  166. (org-test-with-temp-text-in-file "| a |\n| b |"
  167. (let* ((file (buffer-file-name))
  168. (org-capture-templates
  169. `(("t" "Table" table-line (file ,file) "| x |"))))
  170. (org-capture nil "t")
  171. (org-capture-kill))
  172. (buffer-string))))
  173. ;; Test aborting a capture that split the line.
  174. (should
  175. (equal
  176. "* AB\n"
  177. (org-test-with-temp-text-in-file "* AB\n"
  178. (let* ((file (buffer-file-name))
  179. (org-capture-templates
  180. `(("t" "Todo" entry
  181. (file+function ,file (lambda () (goto-char 4))) "** H1 %?"))))
  182. (org-capture nil "t")
  183. (org-capture-kill))
  184. (buffer-string)))))
  185. (ert-deftest test-org-capture/entry ()
  186. "Test `entry' type in capture template."
  187. ;; Do not break next headline.
  188. (should
  189. (equal
  190. "* A\n** H1 Capture text\n* B\n"
  191. (org-test-with-temp-text-in-file "* A\n* B\n"
  192. (let* ((file (buffer-file-name))
  193. (org-capture-templates
  194. `(("t" "Todo" entry (file+headline ,file "A") "** H1 %?"))))
  195. (org-capture nil "t")
  196. (goto-char (point-max))
  197. (insert "Capture text")
  198. (org-capture-finalize))
  199. (buffer-string))))
  200. ;; Correctly save position of inserted entry.
  201. (should
  202. (equal
  203. "** H"
  204. (org-test-with-temp-text-in-file "* A"
  205. (let* ((file (buffer-file-name))
  206. (org-capture-templates
  207. `(("t" "Test" entry (file+headline ,file "A") "** H\nFoo"
  208. :immediate-finish t))))
  209. (org-capture nil "t")
  210. (org-capture '(16))
  211. (buffer-substring (point) (line-end-position))))))
  212. ;; Do not raise an error on empty entries.
  213. (should
  214. (org-test-with-temp-text-in-file ""
  215. (let* ((file (buffer-file-name))
  216. (org-capture-templates
  217. `(("t" "Test" entry (file+headline ,file "A") "** "
  218. :immediate-finish t))))
  219. (org-capture nil "t")
  220. (buffer-string))))
  221. ;; With a 0 prefix argument, ignore surrounding lists.
  222. (should
  223. (equal "Foo\n* X\nBar\n"
  224. (org-test-with-temp-text-in-file "Foo\nBar"
  225. (forward-line)
  226. (let* ((file (buffer-file-name))
  227. (org-capture-templates
  228. `(("t" "Test" entry (file ,file) "* X"
  229. :immediate-finish t))))
  230. (org-capture 0 "t")
  231. (buffer-string)))))
  232. ;; With a 0 prefix argument, also obey to :empty-lines.
  233. (should
  234. (equal "Foo\n\n* X\n\nBar\n"
  235. (org-test-with-temp-text-in-file "Foo\nBar"
  236. (forward-line)
  237. (let* ((file (buffer-file-name))
  238. (org-capture-templates
  239. `(("t" "Test" entry (file ,file) "* X"
  240. :immediate-finish t :empty-lines 1))))
  241. (org-capture 0 "t")
  242. (buffer-string))))))
  243. (ert-deftest test-org-capture/item ()
  244. "Test `item' type in capture template."
  245. ;; Insert item in the first plain list found at the target location.
  246. (should
  247. (equal
  248. "* A\n- list 1\n- X\n\n\n1. list 2\n"
  249. (org-test-with-temp-text-in-file "* A\n- list 1\n\n\n1. list 2"
  250. (let* ((file (buffer-file-name))
  251. (org-capture-templates
  252. `(("t" "Item" item (file+headline ,file "A") "- X"))))
  253. (org-capture nil "t")
  254. (org-capture-finalize))
  255. (buffer-string))))
  256. (should
  257. (equal
  258. "Text\n- list 1\n- X\n\n\n1. list 2\n"
  259. (org-test-with-temp-text-in-file "Text\n- list 1\n\n\n1. list 2"
  260. (let* ((file (buffer-file-name))
  261. (org-capture-templates
  262. `(("t" "Item" item (file ,file) "- X"))))
  263. (org-capture nil "t")
  264. (org-capture-finalize))
  265. (buffer-string))))
  266. ;; When targeting a specific location, start looking for plain lists
  267. ;; from there.
  268. (should
  269. (equal
  270. "* A\n- skip\n\n\n1. here\n2. X\n"
  271. (org-test-with-temp-text-in-file "* A\n- skip\n\n\n1. here"
  272. (let* ((file (buffer-file-name))
  273. (org-capture-templates
  274. `(("t" "Item" item (file+regexp ,file "here") "1. X"))))
  275. (org-capture nil "t")
  276. (org-capture-finalize))
  277. (buffer-string))))
  278. ;; If there is no such list, create it.
  279. (should
  280. (equal
  281. "* A\n- X\n"
  282. (org-test-with-temp-text-in-file "* A"
  283. (let* ((file (buffer-file-name))
  284. (org-capture-templates
  285. `(("t" "Item" item (file+headline ,file "A") "- X"))))
  286. (org-capture nil "t")
  287. (org-capture-finalize))
  288. (buffer-string))))
  289. ;; When `:prepend' is non-nil, insert new item as the first item.
  290. (should
  291. (equal
  292. "* A\n- X\n- 1\n- 2\n"
  293. (org-test-with-temp-text-in-file "* A\n- 1\n- 2"
  294. (let* ((file (buffer-file-name))
  295. (org-capture-templates
  296. `(("t" "Item" item (file+headline ,file "A") "- X"
  297. :prepend t))))
  298. (org-capture nil "t")
  299. (org-capture-finalize))
  300. (buffer-string))))
  301. ;; If there is no list and `:prepend' is non-nil, insert list at the
  302. ;; beginning of the entry, or the beginning of the buffer. However,
  303. ;; preserve properties drawer and planning info, if any.
  304. (should
  305. (equal
  306. "* A\n- X\nSome text\n"
  307. (org-test-with-temp-text-in-file "* A\nSome text"
  308. (let* ((file (buffer-file-name))
  309. (org-capture-templates
  310. `(("t" "Item" item (file+headline ,file "A") "- X"
  311. :prepend t))))
  312. (org-capture nil "t")
  313. (org-capture-finalize))
  314. (buffer-string))))
  315. (should
  316. (equal
  317. "- X\nText\n"
  318. (org-test-with-temp-text-in-file "Text"
  319. (let* ((file (buffer-file-name))
  320. (org-capture-templates
  321. `(("t" "Item" item (file ,file) "- X" :prepend t))))
  322. (org-capture nil "t")
  323. (org-capture-finalize))
  324. (buffer-string))))
  325. (should
  326. (equal
  327. "* A\nSCHEDULED: <2012-03-29 Thu>\n- X\nText\n"
  328. (org-test-with-temp-text-in-file "* A\nSCHEDULED: <2012-03-29 Thu>\nText"
  329. (let* ((file (buffer-file-name))
  330. (org-capture-templates
  331. `(("t" "Item" item (file+headline ,file "A") "- X"
  332. :prepend t))))
  333. (org-capture nil "t")
  334. (org-capture-finalize))
  335. (buffer-string))))
  336. ;; When `:prepend' is nil, insert new item as the last top-level
  337. ;; item.
  338. (should
  339. (equal
  340. "* A\n- 1\n - 2\n- X\n"
  341. (org-test-with-temp-text-in-file "* A\n- 1\n - 2"
  342. (let* ((file (buffer-file-name))
  343. (org-capture-templates
  344. `(("t" "Item" item (file+headline ,file "A") "- X"))))
  345. (org-capture nil "t")
  346. (org-capture-finalize))
  347. (buffer-string))))
  348. ;; When targeting a specific location, one can insert in a sub-list.
  349. (should
  350. (equal
  351. "* A\n- skip\n - here\n - X\n- skip\n"
  352. (org-test-with-temp-text-in-file "* A\n- skip\n - here\n- skip"
  353. (let* ((file (buffer-file-name))
  354. (org-capture-templates
  355. `(("t" "Item" item (file+regexp ,file "here") "- X"))))
  356. (org-capture nil "t")
  357. (org-capture-finalize))
  358. (buffer-string))))
  359. ;; Obey `:empty-lines' when creating a new list.
  360. (should
  361. (equal
  362. "\n- X\n\n\n* H\n"
  363. (org-test-with-temp-text-in-file "\n* H"
  364. (let* ((file (buffer-file-name))
  365. (org-capture-templates
  366. `(("t" "Item" item (file ,file) "- X"
  367. :empty-lines-before 1 :empty-lines-after 2 :prepend t))))
  368. (org-capture nil "t")
  369. (org-capture-finalize))
  370. (buffer-string))))
  371. ;; Obey `:empty-lines' in an existing list only between items, and
  372. ;; only if the value doesn't break the list.
  373. (should
  374. (equal
  375. "- A\n\n- X\nText\n"
  376. (org-test-with-temp-text-in-file "- A\nText"
  377. (let* ((file (buffer-file-name))
  378. (org-capture-templates
  379. `(("t" "Item" item (file ,file) "- X" :empty-lines 1))))
  380. (org-capture nil "t")
  381. (org-capture-finalize))
  382. (buffer-string))))
  383. (should
  384. (equal
  385. "Text\n- X\n\n- A\n"
  386. (org-test-with-temp-text-in-file "Text\n- A"
  387. (let* ((file (buffer-file-name))
  388. (org-capture-templates
  389. `(("t" "Item" item (file ,file) "- X"
  390. :prepend t :empty-lines 1))))
  391. (org-capture nil "t")
  392. (org-capture-finalize))
  393. (buffer-string))))
  394. (should-not
  395. (equal
  396. "- A\n\n\n- X\n"
  397. (org-test-with-temp-text-in-file "- A"
  398. (let* ((file (buffer-file-name))
  399. (org-capture-templates
  400. `(("t" "Item" item (file ,file) "- X" :empty-lines 2))))
  401. (org-capture nil "t")
  402. (org-capture-finalize))
  403. (buffer-string))))
  404. ;; Preserve list type when pre-pending.
  405. (should
  406. (equal
  407. "1. X\n2. A\n"
  408. (org-test-with-temp-text-in-file "1. A"
  409. (let* ((file (buffer-file-name))
  410. (org-capture-templates
  411. `(("t" "Item" item (file ,file) "- X" :prepend t))))
  412. (org-capture nil "t")
  413. (org-capture-finalize))
  414. (buffer-string))))
  415. ;; Handle indentation. Handle multi-lines templates.
  416. (should
  417. (equal
  418. " - A\n - X\n"
  419. (org-test-with-temp-text-in-file " - A"
  420. (let* ((file (buffer-file-name))
  421. (org-capture-templates
  422. `(("t" "Item" item (file ,file) "- X"))))
  423. (org-capture nil "t")
  424. (org-capture-finalize))
  425. (buffer-string))))
  426. (should
  427. (equal
  428. " - A\n - X\n Line 2\n"
  429. (org-test-with-temp-text-in-file " - A"
  430. (let* ((file (buffer-file-name))
  431. (org-capture-templates
  432. `(("t" "Item" item (file ,file) "- X\n Line 2"))))
  433. (org-capture nil "t")
  434. (org-capture-finalize))
  435. (buffer-string))))
  436. ;; Handle incomplete templates.
  437. (should
  438. (equal
  439. "- A\n- X\n"
  440. (org-test-with-temp-text-in-file "- A"
  441. (let* ((file (buffer-file-name))
  442. (org-capture-templates
  443. `(("t" "Item" item (file ,file) "X"))))
  444. (org-capture nil "t")
  445. (org-capture-finalize))
  446. (buffer-string))))
  447. ;; Do not break next headline.
  448. (should-not
  449. (equal
  450. "- A\n- X\nFoo* H"
  451. (org-test-with-temp-text-in-file "- A\n* H"
  452. (let* ((file (buffer-file-name))
  453. (org-capture-templates
  454. `(("t" "Item" item (file ,file) "- X"))))
  455. (org-capture nil "t")
  456. (goto-char (point-max))
  457. (insert "Foo")
  458. (org-capture-finalize))
  459. (buffer-string))))
  460. ;; With a 0 prefix argument, ignore surrounding lists.
  461. (should
  462. (equal "- X\nFoo\n\n- A\n"
  463. (org-test-with-temp-text-in-file "Foo\n\n- A"
  464. (let* ((file (buffer-file-name))
  465. (org-capture-templates
  466. `(("t" "Test" item (file ,file) "- X"
  467. :immediate-finish t))))
  468. (org-capture 0 "t")
  469. (buffer-string)))))
  470. ;; With a 0 prefix argument, also obey to `:empty-lines'.
  471. (should
  472. (equal "\n- X\n\nFoo\n\n- A\n"
  473. (org-test-with-temp-text-in-file "Foo\n\n- A"
  474. (let* ((file (buffer-file-name))
  475. (org-capture-templates
  476. `(("t" "Test" item (file ,file) "- X"
  477. :immediate-finish t :empty-lines 1))))
  478. (org-capture 0 "t")
  479. (buffer-string))))))
  480. (ert-deftest test-org-capture/table-line ()
  481. "Test `table-line' type in capture template."
  482. ;; When a only file is specified, use the first table available.
  483. (should
  484. (equal "Text
  485. | a |
  486. | x |
  487. | b |
  488. "
  489. (org-test-with-temp-text-in-file "Text\n\n| a |\n\n| b |"
  490. (let* ((file (buffer-file-name))
  491. (org-capture-templates
  492. `(("t" "Table" table-line (file ,file) "| x |"
  493. :immediate-finish t))))
  494. (org-capture nil "t"))
  495. (buffer-string))))
  496. ;; When an entry is specified, find the first table in the
  497. ;; corresponding section.
  498. (should
  499. (equal "* Foo
  500. | a |
  501. * Inbox
  502. | b |
  503. | x |
  504. "
  505. (org-test-with-temp-text-in-file "* Foo\n| a |\n* Inbox\n| b |\n"
  506. (let* ((file (buffer-file-name))
  507. (org-capture-templates
  508. `(("t" "Table" table-line (file+headline ,file "Inbox")
  509. "| x |" :immediate-finish t))))
  510. (org-capture nil "t"))
  511. (buffer-string))))
  512. (should
  513. (equal "* Inbox
  514. | a |
  515. | x |
  516. | b |
  517. "
  518. (org-test-with-temp-text-in-file "* Inbox\n| a |\n\n| b |\n"
  519. (let* ((file (buffer-file-name))
  520. (org-capture-templates
  521. `(("t" "Table" table-line (file+headline ,file "Inbox")
  522. "| x |" :immediate-finish t))))
  523. (org-capture nil "t"))
  524. (buffer-string))))
  525. ;; When a precise location is specified, find the first table after
  526. ;; point, down to the end of the section.
  527. (should
  528. (equal "| a |
  529. | b |
  530. | x |
  531. "
  532. (org-test-with-temp-text-in-file "| a |\n\n\n| b |\n"
  533. (let* ((file (buffer-file-name))
  534. (org-capture-templates
  535. `(("t" "Table" table-line (file+function ,file forward-line)
  536. "| x |" :immediate-finish t))))
  537. (org-capture nil "t"))
  538. (buffer-string))))
  539. ;; Create a new table with an empty header when none can be found.
  540. (should
  541. (equal "| | |\n|---+---|\n| a | b |\n"
  542. (org-test-with-temp-text-in-file ""
  543. (let* ((file (buffer-file-name))
  544. (org-capture-templates
  545. `(("t" "Table" table-line (file ,file) "| a | b |"
  546. :immediate-finish t))))
  547. (org-capture nil "t"))
  548. (buffer-string))))
  549. ;; Properly insert row with formulas.
  550. (should
  551. (equal "| 1 |\n| 2 |\n#+TBLFM: \n"
  552. (org-test-with-temp-text-in-file "| 1 |\n#+TBLFM: "
  553. (let* ((file (buffer-file-name))
  554. (org-capture-templates
  555. `(("t" "Table" table-line (file ,file)
  556. "| 2 |" :immediate-finish t))))
  557. (org-capture nil "t"))
  558. (buffer-string))))
  559. ;; When `:prepend' is nil, add the row at the end of the table.
  560. (should
  561. (equal "| a |\n| x |\n"
  562. (org-test-with-temp-text-in-file "| a |"
  563. (let* ((file (buffer-file-name))
  564. (org-capture-templates
  565. `(("t" "Table" table-line (file ,file)
  566. "| x |" :immediate-finish t))))
  567. (org-capture nil "t"))
  568. (buffer-string))))
  569. ;; When `:prepend' is non-nil, add it as the first row after the
  570. ;; header, if there is one, or the first row otherwise.
  571. (should
  572. (equal "| a |\n|---|\n| x |\n| b |\n"
  573. (org-test-with-temp-text-in-file "| a |\n|---|\n| b |"
  574. (let* ((file (buffer-file-name))
  575. (org-capture-templates
  576. `(("t" "Table" table-line (file ,file)
  577. "| x |" :immediate-finish t :prepend t))))
  578. (org-capture nil "t"))
  579. (buffer-string))))
  580. (should
  581. (equal "| x |\n| a |\n"
  582. (org-test-with-temp-text-in-file "| a |"
  583. (let* ((file (buffer-file-name))
  584. (org-capture-templates
  585. `(("t" "Table" table-line (file ,file)
  586. "| x |" :immediate-finish t :prepend t))))
  587. (org-capture nil "t"))
  588. (buffer-string))))
  589. ;; When `:table-line-pos' is set and is meaningful, obey it.
  590. (should
  591. (equal "| a |\n|---|\n| b |\n| x |\n|---|\n| c |\n"
  592. (org-test-with-temp-text-in-file "| a |\n|---|\n| b |\n|---|\n| c |"
  593. (let* ((file (buffer-file-name))
  594. (org-capture-templates
  595. `(("t" "Table" table-line (file ,file)
  596. "| x |" :immediate-finish t :table-line-pos "II-1"))))
  597. (org-capture nil "t"))
  598. (buffer-string))))
  599. (should
  600. (equal "| a |\n|---|\n| x |\n| b |\n|---|\n| c |\n"
  601. (org-test-with-temp-text-in-file "| a |\n|---|\n| b |\n|---|\n| c |"
  602. (let* ((file (buffer-file-name))
  603. (org-capture-templates
  604. `(("t" "Table" table-line (file ,file)
  605. "| x |" :immediate-finish t :table-line-pos "I+1"))))
  606. (org-capture nil "t"))
  607. (buffer-string))))
  608. ;; Throw an error on invalid `:table-line-pos' specifications.
  609. (should-error
  610. (org-test-with-temp-text-in-file "| a |"
  611. (let* ((file (buffer-file-name))
  612. (org-capture-templates
  613. `(("t" "Table" table-line (file ,file)
  614. "| x |" :immediate-finish t :table-line-pos "II+99"))))
  615. (org-capture nil "t")
  616. t)))
  617. ;; Update formula when capturing one or more rows.
  618. (should
  619. (equal
  620. '(("@3$1" . "9"))
  621. (org-test-with-temp-text-in-file "| 1 |\n|---|\n| 9 |\n#+tblfm: @2$1=9"
  622. (let* ((file (buffer-file-name))
  623. (org-capture-templates
  624. `(("t" "Table" table-line (file ,file)
  625. "| 2 |" :immediate-finish t :table-line-pos "I-1"))))
  626. (org-capture nil "t")
  627. (org-table-get-stored-formulas)))))
  628. (should
  629. (equal
  630. '(("@4$1" . "9"))
  631. (org-test-with-temp-text-in-file "| 1 |\n|---|\n| 9 |\n#+tblfm: @2$1=9"
  632. (let* ((file (buffer-file-name))
  633. (org-capture-templates
  634. `(("t" "Table" table-line (file ,file)
  635. "| 2 |\n| 3 |" :immediate-finish t :table-line-pos "I-1"))))
  636. (org-capture nil "t")
  637. (org-table-get-stored-formulas)))))
  638. ;; Do not update formula when cell in inserted below affected row.
  639. (should-not
  640. (equal
  641. '(("@3$1" . "9"))
  642. (org-test-with-temp-text-in-file "| 1 |\n|---|\n| 9 |\n#+tblfm: @2$1=9"
  643. (let* ((file (buffer-file-name))
  644. (org-capture-templates
  645. `(("t" "Table" table-line (file ,file)
  646. "| 2 |" :immediate-finish t))))
  647. (org-capture nil "t")
  648. (org-table-get-stored-formulas)))))
  649. ;; With a 0 prefix argument, ignore surrounding tables.
  650. (should
  651. (equal "| |\n|---|\n| B |\nFoo\n\n| A |\n"
  652. (org-test-with-temp-text-in-file "Foo\n\n| A |"
  653. (let* ((file (buffer-file-name))
  654. (org-capture-templates
  655. `(("t" "Test" table-line (file ,file) "| B |"
  656. :immediate-finish t))))
  657. (org-capture 0 "t")
  658. (buffer-string))))))
  659. (ert-deftest test-org-capture/plain ()
  660. "Test `plain' type in capture template."
  661. ;; Insert at end of the file, unless `:prepend' is non-nil.
  662. (should
  663. (equal "Some text.\nFoo\n"
  664. (org-test-with-temp-text-in-file "Some text."
  665. (let* ((file (buffer-file-name))
  666. (org-capture-templates
  667. `(("t" "Text" plain (file ,file) "Foo"
  668. :immediate-finish t))))
  669. (org-capture nil "t")
  670. (buffer-string)))))
  671. (should
  672. (equal "Foo\nSome text.\n"
  673. (org-test-with-temp-text-in-file "Some text."
  674. (let* ((file (buffer-file-name))
  675. (org-capture-templates
  676. `(("t" "Text" plain (file ,file) "Foo"
  677. :immediate-finish t :prepend t))))
  678. (org-capture nil "t")
  679. (buffer-string)))))
  680. ;; When a headline is specified, add it at the beginning of the
  681. ;; entry, past any meta-data, or at its end, depending on
  682. ;; `:prepend'.
  683. (should
  684. (equal "* A\nSCHEDULED: <2012-03-29 Thu>\nSome text.\nFoo\n* B\n"
  685. (org-test-with-temp-text-in-file
  686. "* A\nSCHEDULED: <2012-03-29 Thu>\nSome text.\n* B"
  687. (let* ((file (buffer-file-name))
  688. (org-capture-templates
  689. `(("t" "Text" plain (file+headline ,file "A") "Foo"
  690. :immediate-finish t))))
  691. (org-capture nil "t")
  692. (buffer-string)))))
  693. (should
  694. (equal "* A\nSCHEDULED: <2012-03-29 Thu>\nFoo\nSome text.\n* B\n"
  695. (org-test-with-temp-text-in-file
  696. "* A\nSCHEDULED: <2012-03-29 Thu>\nSome text.\n* B"
  697. (let* ((file (buffer-file-name))
  698. (org-capture-templates
  699. `(("t" "Text" plain (file+headline ,file "A") "Foo"
  700. :immediate-finish t :prepend t))))
  701. (org-capture nil "t")
  702. (buffer-string)))))
  703. ;; At an exact position, in the middle of a line, make sure to
  704. ;; insert text on a line on its own.
  705. (should
  706. (equal "A\nX\nB\n"
  707. (org-test-with-temp-text-in-file "AB"
  708. (let* ((file (buffer-file-name))
  709. (org-capture-templates
  710. `(("t" "Text" plain (file+function ,file forward-char) "X"
  711. :immediate-finish t))))
  712. (org-capture nil "t")
  713. (buffer-string)))))
  714. ;; Pathological case: insert an empty template in an empty file.
  715. (should
  716. (equal ""
  717. (org-test-with-temp-text-in-file ""
  718. (let* ((file (buffer-file-name))
  719. (org-capture-templates
  720. `(("t" "Text" plain (file ,file) ""
  721. :immediate-finish t))))
  722. (org-capture nil "t")
  723. (buffer-string))))))
  724. (provide 'test-org-capture)
  725. ;;; test-org-capture.el ends here