test-org-capture.el 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  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 <https://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. (insert "Capture text")
  197. (org-capture-finalize))
  198. (buffer-string))))
  199. ;; Correctly save position of inserted entry.
  200. (should
  201. (equal
  202. "** H"
  203. (org-test-with-temp-text-in-file "* A"
  204. (let* ((file (buffer-file-name))
  205. (org-capture-templates
  206. `(("t" "Test" entry (file+headline ,file "A") "** H\nFoo"
  207. :immediate-finish t))))
  208. (org-capture nil "t")
  209. (org-capture '(16))
  210. (buffer-substring (point) (line-end-position))))))
  211. ;; Do not raise an error on empty entries.
  212. (should
  213. (org-test-with-temp-text-in-file ""
  214. (let* ((file (buffer-file-name))
  215. (org-capture-templates
  216. `(("t" "Test" entry (file+headline ,file "A") "** "
  217. :immediate-finish t))))
  218. (org-capture nil "t")
  219. (buffer-string))))
  220. ;; With a 0 prefix argument, ignore surrounding lists.
  221. (should
  222. (equal "Foo\n* X\nBar\n"
  223. (org-test-with-temp-text-in-file "Foo\nBar"
  224. (forward-line)
  225. (let* ((file (buffer-file-name))
  226. (org-capture-templates
  227. `(("t" "Test" entry (file ,file) "* X"
  228. :immediate-finish t))))
  229. (org-capture 0 "t")
  230. (buffer-string)))))
  231. ;; With a 0 prefix argument, also obey to :empty-lines.
  232. (should
  233. (equal "Foo\n\n* X\n\nBar\n"
  234. (org-test-with-temp-text-in-file "Foo\nBar"
  235. (forward-line)
  236. (let* ((file (buffer-file-name))
  237. (org-capture-templates
  238. `(("t" "Test" entry (file ,file) "* X"
  239. :immediate-finish t :empty-lines 1))))
  240. (org-capture 0 "t")
  241. (buffer-string))))))
  242. (ert-deftest test-org-capture/item ()
  243. "Test `item' type in capture template."
  244. ;; Insert item in the first plain list found at the target location.
  245. (should
  246. (equal
  247. "* A\n- list 1\n- X\n\n\n1. list 2\n"
  248. (org-test-with-temp-text-in-file "* A\n- list 1\n\n\n1. list 2"
  249. (let* ((file (buffer-file-name))
  250. (org-capture-templates
  251. `(("t" "Item" item (file+headline ,file "A") "- X"))))
  252. (org-capture nil "t")
  253. (org-capture-finalize))
  254. (buffer-string))))
  255. (should
  256. (equal
  257. "Text\n- list 1\n- X\n\n\n1. list 2\n"
  258. (org-test-with-temp-text-in-file "Text\n- list 1\n\n\n1. list 2"
  259. (let* ((file (buffer-file-name))
  260. (org-capture-templates
  261. `(("t" "Item" item (file ,file) "- X"))))
  262. (org-capture nil "t")
  263. (org-capture-finalize))
  264. (buffer-string))))
  265. ;; When targeting a specific location, start looking for plain lists
  266. ;; from there.
  267. (should
  268. (equal
  269. "* A\n- skip\n\n\n1. here\n2. X\n"
  270. (org-test-with-temp-text-in-file "* A\n- skip\n\n\n1. here"
  271. (let* ((file (buffer-file-name))
  272. (org-capture-templates
  273. `(("t" "Item" item (file+regexp ,file "here") "1. X"))))
  274. (org-capture nil "t")
  275. (org-capture-finalize))
  276. (buffer-string))))
  277. ;; If there is no such list, create it.
  278. (should
  279. (equal
  280. "* A\n- X\n"
  281. (org-test-with-temp-text-in-file "* A"
  282. (let* ((file (buffer-file-name))
  283. (org-capture-templates
  284. `(("t" "Item" item (file+headline ,file "A") "- X"))))
  285. (org-capture nil "t")
  286. (org-capture-finalize))
  287. (buffer-string))))
  288. ;; When `:prepend' is non-nil, insert new item as the first item.
  289. (should
  290. (equal
  291. "* A\n- X\n- 1\n- 2\n"
  292. (org-test-with-temp-text-in-file "* A\n- 1\n- 2"
  293. (let* ((file (buffer-file-name))
  294. (org-capture-templates
  295. `(("t" "Item" item (file+headline ,file "A") "- X"
  296. :prepend t))))
  297. (org-capture nil "t")
  298. (org-capture-finalize))
  299. (buffer-string))))
  300. ;; If there is no list and `:prepend' is non-nil, insert list at the
  301. ;; beginning of the entry, or the beginning of the buffer. However,
  302. ;; preserve properties drawer and planning info, if any.
  303. (should
  304. (equal
  305. "* A\n- X\nSome text\n"
  306. (org-test-with-temp-text-in-file "* A\nSome text"
  307. (let* ((file (buffer-file-name))
  308. (org-capture-templates
  309. `(("t" "Item" item (file+headline ,file "A") "- X"
  310. :prepend t))))
  311. (org-capture nil "t")
  312. (org-capture-finalize))
  313. (buffer-string))))
  314. (should
  315. (equal
  316. "- X\nText\n"
  317. (org-test-with-temp-text-in-file "Text"
  318. (let* ((file (buffer-file-name))
  319. (org-capture-templates
  320. `(("t" "Item" item (file ,file) "- X" :prepend t))))
  321. (org-capture nil "t")
  322. (org-capture-finalize))
  323. (buffer-string))))
  324. (should
  325. (equal
  326. "* A\nSCHEDULED: <2012-03-29 Thu>\n- X\nText\n"
  327. (org-test-with-temp-text-in-file "* A\nSCHEDULED: <2012-03-29 Thu>\nText"
  328. (let* ((file (buffer-file-name))
  329. (org-capture-templates
  330. `(("t" "Item" item (file+headline ,file "A") "- X"
  331. :prepend t))))
  332. (org-capture nil "t")
  333. (org-capture-finalize))
  334. (buffer-string))))
  335. ;; When `:prepend' is nil, insert new item as the last top-level
  336. ;; item.
  337. (should
  338. (equal
  339. "* A\n- 1\n - 2\n- X\n"
  340. (org-test-with-temp-text-in-file "* A\n- 1\n - 2"
  341. (let* ((file (buffer-file-name))
  342. (org-capture-templates
  343. `(("t" "Item" item (file+headline ,file "A") "- X"))))
  344. (org-capture nil "t")
  345. (org-capture-finalize))
  346. (buffer-string))))
  347. ;; When targeting a specific location, one can insert in a sub-list.
  348. (should
  349. (equal
  350. "* A\n- skip\n - here\n - X\n- skip\n"
  351. (org-test-with-temp-text-in-file "* A\n- skip\n - here\n- skip"
  352. (let* ((file (buffer-file-name))
  353. (org-capture-templates
  354. `(("t" "Item" item (file+regexp ,file "here") "- X"))))
  355. (org-capture nil "t")
  356. (org-capture-finalize))
  357. (buffer-string))))
  358. ;; Obey `:empty-lines' when creating a new list.
  359. (should
  360. (equal
  361. "\n- X\n\n\n* H\n"
  362. (org-test-with-temp-text-in-file "\n* H"
  363. (let* ((file (buffer-file-name))
  364. (org-capture-templates
  365. `(("t" "Item" item (file ,file) "- X"
  366. :empty-lines-before 1 :empty-lines-after 2 :prepend t))))
  367. (org-capture nil "t")
  368. (org-capture-finalize))
  369. (buffer-string))))
  370. ;; Obey `:empty-lines' in an existing list only between items, and
  371. ;; only if the value doesn't break the list.
  372. (should
  373. (equal
  374. "- A\n\n- X\nText\n"
  375. (org-test-with-temp-text-in-file "- A\nText"
  376. (let* ((file (buffer-file-name))
  377. (org-capture-templates
  378. `(("t" "Item" item (file ,file) "- X" :empty-lines 1))))
  379. (org-capture nil "t")
  380. (org-capture-finalize))
  381. (buffer-string))))
  382. (should
  383. (equal
  384. "Text\n- X\n\n- A\n"
  385. (org-test-with-temp-text-in-file "Text\n- A"
  386. (let* ((file (buffer-file-name))
  387. (org-capture-templates
  388. `(("t" "Item" item (file ,file) "- X"
  389. :prepend t :empty-lines 1))))
  390. (org-capture nil "t")
  391. (org-capture-finalize))
  392. (buffer-string))))
  393. (should-not
  394. (equal
  395. "- A\n\n\n- X\n"
  396. (org-test-with-temp-text-in-file "- A"
  397. (let* ((file (buffer-file-name))
  398. (org-capture-templates
  399. `(("t" "Item" item (file ,file) "- X" :empty-lines 2))))
  400. (org-capture nil "t")
  401. (org-capture-finalize))
  402. (buffer-string))))
  403. ;; Preserve list type when pre-pending.
  404. (should
  405. (equal
  406. "1. X\n2. A\n"
  407. (org-test-with-temp-text-in-file "1. A"
  408. (let* ((file (buffer-file-name))
  409. (org-capture-templates
  410. `(("t" "Item" item (file ,file) "- X" :prepend t))))
  411. (org-capture nil "t")
  412. (org-capture-finalize))
  413. (buffer-string))))
  414. ;; Handle indentation. Handle multi-lines templates.
  415. (should
  416. (equal
  417. " - A\n - X\n"
  418. (org-test-with-temp-text-in-file " - A"
  419. (let* ((file (buffer-file-name))
  420. (org-capture-templates
  421. `(("t" "Item" item (file ,file) "- X"))))
  422. (org-capture nil "t")
  423. (org-capture-finalize))
  424. (buffer-string))))
  425. (should
  426. (equal
  427. " - A\n - X\n Line 2\n"
  428. (org-test-with-temp-text-in-file " - A"
  429. (let* ((file (buffer-file-name))
  430. (org-capture-templates
  431. `(("t" "Item" item (file ,file) "- X\n Line 2"))))
  432. (org-capture nil "t")
  433. (org-capture-finalize))
  434. (buffer-string))))
  435. ;; Handle incomplete templates.
  436. (should
  437. (equal
  438. "- A\n- X\n"
  439. (org-test-with-temp-text-in-file "- A"
  440. (let* ((file (buffer-file-name))
  441. (org-capture-templates
  442. `(("t" "Item" item (file ,file) "X"))))
  443. (org-capture nil "t")
  444. (org-capture-finalize))
  445. (buffer-string))))
  446. ;; Do not break next headline.
  447. (should-not
  448. (equal
  449. "- A\n- X\nFoo* H"
  450. (org-test-with-temp-text-in-file "- A\n* H"
  451. (let* ((file (buffer-file-name))
  452. (org-capture-templates
  453. `(("t" "Item" item (file ,file) "- X"))))
  454. (org-capture nil "t")
  455. (goto-char (point-max))
  456. (insert "Foo")
  457. (org-capture-finalize))
  458. (buffer-string))))
  459. ;; With a 0 prefix argument, ignore surrounding lists.
  460. (should
  461. (equal "- X\nFoo\n\n- A\n"
  462. (org-test-with-temp-text-in-file "Foo\n\n- A"
  463. (let* ((file (buffer-file-name))
  464. (org-capture-templates
  465. `(("t" "Test" item (file ,file) "- X"
  466. :immediate-finish t))))
  467. (org-capture 0 "t")
  468. (buffer-string)))))
  469. ;; With a 0 prefix argument, also obey to `:empty-lines'.
  470. (should
  471. (equal "\n- X\n\nFoo\n\n- A\n"
  472. (org-test-with-temp-text-in-file "Foo\n\n- A"
  473. (let* ((file (buffer-file-name))
  474. (org-capture-templates
  475. `(("t" "Test" item (file ,file) "- X"
  476. :immediate-finish t :empty-lines 1))))
  477. (org-capture 0 "t")
  478. (buffer-string))))))
  479. (ert-deftest test-org-capture/table-line ()
  480. "Test `table-line' type in capture template."
  481. ;; When a only file is specified, use the first table available.
  482. (should
  483. (equal "Text
  484. | a |
  485. | x |
  486. | b |
  487. "
  488. (org-test-with-temp-text-in-file "Text\n\n| a |\n\n| b |"
  489. (let* ((file (buffer-file-name))
  490. (org-capture-templates
  491. `(("t" "Table" table-line (file ,file) "| x |"
  492. :immediate-finish t))))
  493. (org-capture nil "t"))
  494. (buffer-string))))
  495. ;; When an entry is specified, find the first table in the
  496. ;; corresponding section.
  497. (should
  498. (equal "* Foo
  499. | a |
  500. * Inbox
  501. | b |
  502. | x |
  503. "
  504. (org-test-with-temp-text-in-file "* Foo\n| a |\n* Inbox\n| b |\n"
  505. (let* ((file (buffer-file-name))
  506. (org-capture-templates
  507. `(("t" "Table" table-line (file+headline ,file "Inbox")
  508. "| x |" :immediate-finish t))))
  509. (org-capture nil "t"))
  510. (buffer-string))))
  511. (should
  512. (equal "* Inbox
  513. | a |
  514. | x |
  515. | b |
  516. "
  517. (org-test-with-temp-text-in-file "* Inbox\n| a |\n\n| b |\n"
  518. (let* ((file (buffer-file-name))
  519. (org-capture-templates
  520. `(("t" "Table" table-line (file+headline ,file "Inbox")
  521. "| x |" :immediate-finish t))))
  522. (org-capture nil "t"))
  523. (buffer-string))))
  524. ;; When a precise location is specified, find the first table after
  525. ;; point, down to the end of the section.
  526. (should
  527. (equal "| a |
  528. | b |
  529. | x |
  530. "
  531. (org-test-with-temp-text-in-file "| a |\n\n\n| b |\n"
  532. (let* ((file (buffer-file-name))
  533. (org-capture-templates
  534. `(("t" "Table" table-line (file+function ,file forward-line)
  535. "| x |" :immediate-finish t))))
  536. (org-capture nil "t"))
  537. (buffer-string))))
  538. ;; Create a new table with an empty header when none can be found.
  539. (should
  540. (equal "| | |\n|---+---|\n| a | b |\n"
  541. (org-test-with-temp-text-in-file ""
  542. (let* ((file (buffer-file-name))
  543. (org-capture-templates
  544. `(("t" "Table" table-line (file ,file) "| a | b |"
  545. :immediate-finish t))))
  546. (org-capture nil "t"))
  547. (buffer-string))))
  548. ;; Properly insert row with formulas.
  549. (should
  550. (equal "| 1 |\n| 2 |\n#+TBLFM: \n"
  551. (org-test-with-temp-text-in-file "| 1 |\n#+TBLFM: "
  552. (let* ((file (buffer-file-name))
  553. (org-capture-templates
  554. `(("t" "Table" table-line (file ,file)
  555. "| 2 |" :immediate-finish t))))
  556. (org-capture nil "t"))
  557. (buffer-string))))
  558. ;; When `:prepend' is nil, add the row at the end of the table.
  559. (should
  560. (equal "| a |\n| x |\n"
  561. (org-test-with-temp-text-in-file "| a |"
  562. (let* ((file (buffer-file-name))
  563. (org-capture-templates
  564. `(("t" "Table" table-line (file ,file)
  565. "| x |" :immediate-finish t))))
  566. (org-capture nil "t"))
  567. (buffer-string))))
  568. ;; When `:prepend' is non-nil, add it as the first row after the
  569. ;; header, if there is one, or the first row otherwise.
  570. (should
  571. (equal "| a |\n|---|\n| x |\n| b |\n"
  572. (org-test-with-temp-text-in-file "| a |\n|---|\n| b |"
  573. (let* ((file (buffer-file-name))
  574. (org-capture-templates
  575. `(("t" "Table" table-line (file ,file)
  576. "| x |" :immediate-finish t :prepend t))))
  577. (org-capture nil "t"))
  578. (buffer-string))))
  579. (should
  580. (equal "| x |\n| a |\n"
  581. (org-test-with-temp-text-in-file "| a |"
  582. (let* ((file (buffer-file-name))
  583. (org-capture-templates
  584. `(("t" "Table" table-line (file ,file)
  585. "| x |" :immediate-finish t :prepend t))))
  586. (org-capture nil "t"))
  587. (buffer-string))))
  588. ;; When `:table-line-pos' is set and is meaningful, obey it.
  589. (should
  590. (equal "| a |\n|---|\n| b |\n| x |\n|---|\n| c |\n"
  591. (org-test-with-temp-text-in-file "| a |\n|---|\n| b |\n|---|\n| c |"
  592. (let* ((file (buffer-file-name))
  593. (org-capture-templates
  594. `(("t" "Table" table-line (file ,file)
  595. "| x |" :immediate-finish t :table-line-pos "II-1"))))
  596. (org-capture nil "t"))
  597. (buffer-string))))
  598. (should
  599. (equal "| a |\n|---|\n| x |\n| b |\n|---|\n| c |\n"
  600. (org-test-with-temp-text-in-file "| a |\n|---|\n| b |\n|---|\n| c |"
  601. (let* ((file (buffer-file-name))
  602. (org-capture-templates
  603. `(("t" "Table" table-line (file ,file)
  604. "| x |" :immediate-finish t :table-line-pos "I+1"))))
  605. (org-capture nil "t"))
  606. (buffer-string))))
  607. ;; Throw an error on invalid `:table-line-pos' specifications.
  608. (should-error
  609. (org-test-with-temp-text-in-file "| a |"
  610. (let* ((file (buffer-file-name))
  611. (org-capture-templates
  612. `(("t" "Table" table-line (file ,file)
  613. "| x |" :immediate-finish t :table-line-pos "II+99"))))
  614. (org-capture nil "t")
  615. t)))
  616. ;; Update formula when capturing one or more rows.
  617. (should
  618. (equal
  619. '(("@3$1" . "9"))
  620. (org-test-with-temp-text-in-file "| 1 |\n|---|\n| 9 |\n#+tblfm: @2$1=9"
  621. (let* ((file (buffer-file-name))
  622. (org-capture-templates
  623. `(("t" "Table" table-line (file ,file)
  624. "| 2 |" :immediate-finish t :table-line-pos "I-1"))))
  625. (org-capture nil "t")
  626. (org-table-get-stored-formulas)))))
  627. (should
  628. (equal
  629. '(("@4$1" . "9"))
  630. (org-test-with-temp-text-in-file "| 1 |\n|---|\n| 9 |\n#+tblfm: @2$1=9"
  631. (let* ((file (buffer-file-name))
  632. (org-capture-templates
  633. `(("t" "Table" table-line (file ,file)
  634. "| 2 |\n| 3 |" :immediate-finish t :table-line-pos "I-1"))))
  635. (org-capture nil "t")
  636. (org-table-get-stored-formulas)))))
  637. ;; Do not update formula when cell in inserted below affected row.
  638. (should-not
  639. (equal
  640. '(("@3$1" . "9"))
  641. (org-test-with-temp-text-in-file "| 1 |\n|---|\n| 9 |\n#+tblfm: @2$1=9"
  642. (let* ((file (buffer-file-name))
  643. (org-capture-templates
  644. `(("t" "Table" table-line (file ,file)
  645. "| 2 |" :immediate-finish t))))
  646. (org-capture nil "t")
  647. (org-table-get-stored-formulas)))))
  648. ;; With a 0 prefix argument, ignore surrounding tables.
  649. (should
  650. (equal "| |\n|---|\n| B |\nFoo\n\n| A |\n"
  651. (org-test-with-temp-text-in-file "Foo\n\n| A |"
  652. (let* ((file (buffer-file-name))
  653. (org-capture-templates
  654. `(("t" "Test" table-line (file ,file) "| B |"
  655. :immediate-finish t))))
  656. (org-capture 0 "t")
  657. (buffer-string))))))
  658. (ert-deftest test-org-capture/plain ()
  659. "Test `plain' type in capture template."
  660. ;; Insert at end of the file, unless `:prepend' is non-nil.
  661. (should
  662. (equal "Some text.\nFoo\n"
  663. (org-test-with-temp-text-in-file "Some text."
  664. (let* ((file (buffer-file-name))
  665. (org-capture-templates
  666. `(("t" "Text" plain (file ,file) "Foo"
  667. :immediate-finish t))))
  668. (org-capture nil "t")
  669. (buffer-string)))))
  670. (should
  671. (equal "Foo\nSome text.\n"
  672. (org-test-with-temp-text-in-file "Some text."
  673. (let* ((file (buffer-file-name))
  674. (org-capture-templates
  675. `(("t" "Text" plain (file ,file) "Foo"
  676. :immediate-finish t :prepend t))))
  677. (org-capture nil "t")
  678. (buffer-string)))))
  679. ;; When a headline is specified, add it at the beginning of the
  680. ;; entry, past any meta-data, or at its end, depending on
  681. ;; `:prepend'.
  682. (should
  683. (equal "* A\nSCHEDULED: <2012-03-29 Thu>\nSome text.\nFoo\n* B\n"
  684. (org-test-with-temp-text-in-file
  685. "* A\nSCHEDULED: <2012-03-29 Thu>\nSome text.\n* B"
  686. (let* ((file (buffer-file-name))
  687. (org-capture-templates
  688. `(("t" "Text" plain (file+headline ,file "A") "Foo"
  689. :immediate-finish t))))
  690. (org-capture nil "t")
  691. (buffer-string)))))
  692. (should
  693. (equal "* A\nSCHEDULED: <2012-03-29 Thu>\nFoo\nSome text.\n* B\n"
  694. (org-test-with-temp-text-in-file
  695. "* A\nSCHEDULED: <2012-03-29 Thu>\nSome text.\n* B"
  696. (let* ((file (buffer-file-name))
  697. (org-capture-templates
  698. `(("t" "Text" plain (file+headline ,file "A") "Foo"
  699. :immediate-finish t :prepend t))))
  700. (org-capture nil "t")
  701. (buffer-string)))))
  702. ;; At an exact position, in the middle of a line, make sure to
  703. ;; insert text on a line on its own.
  704. (should
  705. (equal "A\nX\nB\n"
  706. (org-test-with-temp-text-in-file "AB"
  707. (let* ((file (buffer-file-name))
  708. (org-capture-templates
  709. `(("t" "Text" plain (file+function ,file forward-char) "X"
  710. :immediate-finish t))))
  711. (org-capture nil "t")
  712. (buffer-string)))))
  713. ;; Pathological case: insert an empty template in an empty file.
  714. (should
  715. (equal ""
  716. (org-test-with-temp-text-in-file ""
  717. (let* ((file (buffer-file-name))
  718. (org-capture-templates
  719. `(("t" "Text" plain (file ,file) ""
  720. :immediate-finish t))))
  721. (org-capture nil "t")
  722. (buffer-string)))))
  723. ;; Test :unnarrowed property without a "%?" marker.
  724. (should
  725. (equal "SUCCESS\n"
  726. (org-test-with-temp-text-in-file ""
  727. (let* ((file (buffer-file-name))
  728. (org-capture-templates
  729. `(("t" "Text" plain (file ,file) "SUCCESS"
  730. :unnarrowed t :immediate-finish t))))
  731. (org-capture nil "t")
  732. (buffer-string))))))
  733. (provide 'test-org-capture)
  734. ;;; test-org-capture.el ends here