test-org-src.el 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. ;;; test-org-src.el --- tests for org-src.el -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2012-2015, 2019 Le Wang
  3. ;; Author: Le Wang <l26wang at gmail dot com>
  4. ;; This file is not part of GNU Emacs.
  5. ;; This program is free software; you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; This program is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
  15. ;;; Code:
  16. (require 'org-test "../testing/org-test")
  17. (ert-deftest test-org-src/basic ()
  18. "Editing regular block works, with point on source block."
  19. (org-test-with-temp-text
  20. "
  21. <point>#+begin_src emacs-lisp
  22. (message hello)
  23. #+end_src
  24. "
  25. (let ((org-edit-src-content-indentation 2)
  26. (org-src-preserve-indentation nil))
  27. (org-edit-special)
  28. (insert "blah")
  29. (org-edit-src-exit)
  30. (should (equal (buffer-string) "
  31. #+begin_src emacs-lisp
  32. blah(message hello)
  33. #+end_src
  34. "))
  35. (should (looking-at-p "(message hello)")))))
  36. (ert-deftest test-org-src/point-outside-block ()
  37. "Editing with point before/after block signals expected error."
  38. (org-test-with-temp-text
  39. "
  40. #+begin_src emacs-lisp
  41. (message hello)
  42. #+end_src
  43. "
  44. (goto-line 1)
  45. (should-error (org-edit-special))
  46. (goto-char (point-max))
  47. (should-error (org-edit-special))))
  48. (ert-deftest test-org-src/undo ()
  49. "Undo-ing an edit buffer should not go back to empty state."
  50. (org-test-with-temp-text "
  51. #+begin_src emacs-lisp<point>
  52. (message hello)
  53. #+end_src
  54. "
  55. (org-edit-special)
  56. (should-error (undo))
  57. (org-edit-src-exit)))
  58. (ert-deftest test-org-src/empty-block ()
  59. "Editing empty block."
  60. (org-test-with-temp-text
  61. "
  62. <point>#+begin_src emacs-lisp
  63. #+end_src
  64. "
  65. (let ((org-edit-src-content-indentation 0)
  66. (org-src-preserve-indentation nil))
  67. (org-edit-special)
  68. (insert "blah")
  69. (org-edit-src-exit)
  70. (should (equal (buffer-string) "
  71. #+begin_src emacs-lisp
  72. blah
  73. #+end_src
  74. "))
  75. (should
  76. (equal (buffer-substring (line-beginning-position) (point)) "blah")))))
  77. (ert-deftest test-org-src/blank-line-block ()
  78. "Editing block with just a blank line."
  79. (org-test-with-temp-text-in-file
  80. "
  81. #+begin_src emacs-lisp
  82. #+end_src
  83. "
  84. (let ((org-edit-src-content-indentation 2)
  85. (org-src-preserve-indentation nil))
  86. (goto-line 2)
  87. (org-edit-special)
  88. (insert "blah")
  89. (org-edit-src-exit)
  90. (should (equal (buffer-string) "
  91. #+begin_src emacs-lisp
  92. blah
  93. #+end_src
  94. ")))))
  95. (ert-deftest test-org-src/preserve-tabs ()
  96. "Editing block preserve tab characters."
  97. ;; With `org-src-preserve-indentation' set to nil.
  98. (should
  99. (equal "
  100. #+begin_src emacs-lisp
  101. This is a tab:\t.
  102. #+end_src"
  103. (org-test-with-temp-text
  104. "
  105. #+begin_src emacs-lisp
  106. <point>This is a tab:\t.
  107. #+end_src"
  108. (let ((org-edit-src-content-indentation 2)
  109. (org-src-preserve-indentation nil))
  110. (org-edit-special)
  111. (org-edit-src-exit)
  112. (buffer-string)))))
  113. ;; With `org-src-preserve-indentation' set to t.
  114. (should
  115. (equal "
  116. #+begin_src emacs-lisp
  117. This is a tab:\t.
  118. #+end_src"
  119. (org-test-with-temp-text
  120. "
  121. #+begin_src emacs-lisp
  122. <point>This is a tab:\t.
  123. #+end_src"
  124. (let ((org-edit-src-content-indentation 2)
  125. (org-src-preserve-indentation t))
  126. (org-edit-special)
  127. (org-edit-src-exit)
  128. (buffer-string))))))
  129. (ert-deftest test-org-src/coderef-format ()
  130. "Test `org-src-coderef-format' specifications."
  131. ;; Regular tests in a src block, an example block and an edit
  132. ;; buffer.
  133. (should
  134. (equal "foo"
  135. (let ((org-coderef-label-format "foo"))
  136. (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n0\n#+END_SRC"
  137. (org-src-coderef-format)))))
  138. (should
  139. (equal "foo"
  140. (let ((org-coderef-label-format "foo"))
  141. (org-test-with-temp-text "#+BEGIN_EXAMPLE\n0\n#+END_EXAMPLE"
  142. (org-src-coderef-format)))))
  143. (should
  144. (equal "foo"
  145. (let ((org-coderef-label-format "foo") result)
  146. (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n0\n#+END_SRC"
  147. (org-edit-special)
  148. (setq result (org-src-coderef-format))
  149. (org-edit-src-exit)
  150. result))))
  151. ;; When a local variable in the source buffer is available, use it.
  152. (should
  153. (equal "bar"
  154. (let ((org-coderef-label-format "foo"))
  155. (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n0\n#+END_SRC"
  156. (setq-local org-coderef-label-format "bar")
  157. (org-src-coderef-format)))))
  158. (should
  159. (equal "bar"
  160. (let ((org-coderef-label-format "foo") result)
  161. (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n0\n#+END_SRC"
  162. (setq-local org-coderef-label-format "bar")
  163. (org-edit-special)
  164. (setq result (org-src-coderef-format))
  165. (org-edit-src-exit)
  166. result))))
  167. ;; Use provided local format even if in an edit buffer.
  168. (should
  169. (equal "bar"
  170. (let ((org-coderef-label-format "foo"))
  171. (org-test-with-temp-text
  172. "#+BEGIN_SRC emacs-lisp -l \"bar\"\n0\n#+END_SRC"
  173. (org-src-coderef-format)))))
  174. (should
  175. (equal "bar"
  176. (let ((org-coderef-label-format "foo") result)
  177. (org-test-with-temp-text
  178. "#+BEGIN_SRC emacs-lisp -l \"bar\"\n0\n#+END_SRC"
  179. (org-edit-special)
  180. (setq result (org-src-coderef-format))
  181. (org-edit-src-exit)
  182. result))))
  183. ;; Local format has precedence over local variables.
  184. (should
  185. (equal "bar"
  186. (let ((org-coderef-label-format "foo"))
  187. (org-test-with-temp-text
  188. "#+BEGIN_SRC emacs-lisp -l \"bar\"\n0\n#+END_SRC"
  189. (setq-local org-coderef-label-format "foo")
  190. (org-src-coderef-format)))))
  191. (should
  192. (equal "bar"
  193. (let ((org-coderef-label-format "foo") result)
  194. (org-test-with-temp-text
  195. "#+BEGIN_SRC emacs-lisp -l \"bar\"\n0\n#+END_SRC"
  196. (setq-local org-coderef-label-format "foo")
  197. (org-edit-special)
  198. (setq result (org-src-coderef-format))
  199. (org-edit-src-exit)
  200. result))))
  201. ;; When optional argument provides a coderef format string, use it.
  202. (should
  203. (equal "bar"
  204. (let ((org-coderef-label-format "foo")
  205. (element (org-element-create 'src-block '(:label-fmt "bar"))))
  206. (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n0\n#+END_SRC"
  207. (org-src-coderef-format element)))))
  208. (should
  209. (equal "baz"
  210. (let ((org-coderef-label-format "foo")
  211. (element (org-element-create 'src-block '(:label-fmt "baz"))))
  212. (org-test-with-temp-text
  213. "#+BEGIN_SRC emacs-lisp -l \"bar\"\n0\n#+END_SRC"
  214. (setq-local org-coderef-label-format "foo")
  215. (org-src-coderef-format element)))))
  216. ;; If it doesn't provide any label format string, fall back to
  217. ;; regular checks.
  218. (should
  219. (equal "foo"
  220. (let ((org-coderef-label-format "foo")
  221. (element (org-element-create 'src-block)))
  222. (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n0\n#+END_SRC"
  223. (org-src-coderef-format element)))))
  224. (should
  225. (equal "bar"
  226. (let ((org-coderef-label-format "foo")
  227. (element (org-element-create 'src-block)))
  228. (org-test-with-temp-text
  229. "#+BEGIN_SRC emacs-lisp -l \"bar\"\n0\n#+END_SRC"
  230. (setq-local org-coderef-label-format "foo")
  231. (org-src-coderef-format element))))))
  232. (ert-deftest test-org-src/coderef-regexp ()
  233. "Test `org-src-coderef-regexp' specifications."
  234. ;; Regular test.
  235. (should
  236. (string-match-p (org-src-coderef-regexp "; ref:%s")
  237. "#+BEGIN_SRC emacs-lisp\n0; ref:label\n#+END_SRC"))
  238. ;; Ignore white space around the coderef.
  239. (should
  240. (string-match-p (org-src-coderef-regexp "; ref:%s")
  241. "#+BEGIN_SRC emacs-lisp\n0 ; ref:label\n#+END_SRC"))
  242. (should
  243. (string-match-p (org-src-coderef-regexp "; ref:%s")
  244. "#+BEGIN_SRC emacs-lisp\n0 ; ref:label \n#+END_SRC"))
  245. ;; Only match regexp at the end of the line.
  246. (should-not
  247. (string-match-p (org-src-coderef-regexp "; ref:%s")
  248. "#+BEGIN_SRC emacs-lisp\n0; ref:label (+ 1 2)\n#+END_SRC"))
  249. ;; Do not match an empty label.
  250. (should-not
  251. (string-match-p (org-src-coderef-regexp "; ref:%s")
  252. "#+BEGIN_SRC emacs-lisp\n0; ref:\n#+END_SRC"))
  253. ;; When optional argument LABEL is provided, match given label only.
  254. (should
  255. (string-match-p (org-src-coderef-regexp "; ref:%s" "label")
  256. "#+BEGIN_SRC emacs-lisp\n0; ref:label\n#+END_SRC"))
  257. (should-not
  258. (string-match-p (org-src-coderef-regexp "; ref:%s" "label2")
  259. "#+BEGIN_SRC emacs-lisp\n0; ref:label\n#+END_SRC")))
  260. (ert-deftest test-org-src/indented-blocks ()
  261. "Test editing indented blocks."
  262. ;; Editing a block should preserve its global indentation, unless
  263. ;; `org-src-preserve-indentation' is non-nil.
  264. (should
  265. (equal
  266. "- Item\n #+BEGIN_SRC emacs-lisp\n Foo\n #+END_SRC"
  267. (org-test-with-temp-text
  268. "- Item\n<point> #+BEGIN_SRC emacs-lisp\n (+ 1 1)\n #+END_SRC"
  269. (let ((org-edit-src-content-indentation 2)
  270. (org-src-preserve-indentation nil))
  271. (org-edit-special)
  272. (erase-buffer)
  273. (insert "Foo")
  274. (org-edit-src-exit)
  275. (buffer-string)))))
  276. (should
  277. (equal
  278. "- Item\n #+BEGIN_SRC emacs-lisp\n Foo\n #+END_SRC"
  279. (org-test-with-temp-text
  280. "- Item\n<point> #+BEGIN_SRC emacs-lisp\n (+ 1 1)\n #+END_SRC"
  281. (let ((org-src-preserve-indentation t))
  282. (org-edit-special)
  283. (erase-buffer)
  284. (insert " Foo")
  285. (org-edit-src-exit)
  286. (buffer-string)))))
  287. ;; Global indentation obeys `indent-tabs-mode' from the original
  288. ;; buffer.
  289. (should
  290. (string-match-p
  291. "^\t+\s*argument2"
  292. (org-test-with-temp-text
  293. "
  294. - Item
  295. #+BEGIN_SRC emacs-lisp<point>
  296. (progn
  297. (function argument1
  298. argument2))
  299. #+END_SRC"
  300. (setq-local indent-tabs-mode t)
  301. (let ((org-edit-src-content-indentation 2)
  302. (org-src-preserve-indentation nil))
  303. (org-edit-special)
  304. (org-edit-src-exit)
  305. (buffer-string)))))
  306. (should
  307. (string-match-p
  308. "^\s+argument2"
  309. (org-test-with-temp-text
  310. "
  311. - Item
  312. #+BEGIN_SRC emacs-lisp<point>
  313. (progn\n (function argument1\n\t\targument2))
  314. #+END_SRC"
  315. (setq-local indent-tabs-mode nil)
  316. (let ((org-edit-src-content-indentation 2)
  317. (org-src-preserve-indentation nil))
  318. (org-edit-special)
  319. (org-edit-src-exit)
  320. (buffer-string)))))
  321. ;; Global indentation also obeys `tab-width' from original buffer.
  322. (should
  323. (string-match-p
  324. "^\t\\{3\\}\s\\{2\\}argument2"
  325. (org-test-with-temp-text
  326. "
  327. - Item
  328. #+BEGIN_SRC emacs-lisp<point>
  329. (progn
  330. (function argument1
  331. argument2))
  332. #+END_SRC"
  333. (setq-local indent-tabs-mode t)
  334. (setq-local tab-width 4)
  335. (let ((org-edit-src-content-indentation 0)
  336. (org-src-preserve-indentation nil))
  337. (org-edit-special)
  338. (org-edit-src-exit)
  339. (buffer-string)))))
  340. (should
  341. (string-match-p
  342. "^\t\s\\{6\\}argument2"
  343. (org-test-with-temp-text
  344. "
  345. - Item
  346. #+BEGIN_SRC emacs-lisp<point>
  347. (progn
  348. (function argument1
  349. argument2))
  350. #+END_SRC"
  351. (setq-local indent-tabs-mode t)
  352. (setq-local tab-width 8)
  353. (let ((org-edit-src-content-indentation 0)
  354. (org-src-preserve-indentation nil))
  355. (org-edit-special)
  356. (org-edit-src-exit)
  357. (buffer-string))))))
  358. (ert-deftest test-org-src/footnote-references ()
  359. "Test editing footnote references."
  360. ;; Error when there is no definition to edit.
  361. (should-error
  362. (org-test-with-temp-text "A footnote<point>[fn:1]"
  363. (org-edit-special)))
  364. ;; Error when trying to edit an anonymous footnote.
  365. (should-error
  366. (org-test-with-temp-text "A footnote[fn::<point>edit me!]"
  367. (org-edit-special)))
  368. ;; Edit a regular definition.
  369. (should
  370. (equal "[fn:1] Definition"
  371. (org-test-with-temp-text "A footnote<point>[fn:1]\n[fn:1] Definition"
  372. (org-edit-special)
  373. (prog1 (buffer-string) (org-edit-src-exit)))))
  374. ;; Label should be protected against editing.
  375. (should
  376. (org-test-with-temp-text "A footnote<point>[fn:1]\n[fn:1] Definition"
  377. (org-edit-special)
  378. (prog1 (get-text-property 0 'read-only (buffer-string))
  379. (org-edit-src-exit))))
  380. (should
  381. (org-test-with-temp-text "A footnote<point>[fn:1]\n[fn:1] Definition"
  382. (org-edit-special)
  383. (prog1 (get-text-property 5 'read-only (buffer-string))
  384. (org-edit-src-exit))))
  385. ;; Edit a regular definition.
  386. (should
  387. (equal
  388. "A footnote[fn:1][fn:2]\n[fn:1] D1\n\n[fn:2] D2"
  389. (org-test-with-temp-text
  390. "A footnote<point>[fn:1][fn:2]\n[fn:1] D1\n\n[fn:2] D2"
  391. (org-edit-special)
  392. (org-edit-src-exit)
  393. (buffer-string))))
  394. ;; Edit an inline definition.
  395. (should
  396. (equal
  397. "[fn:1:definition]"
  398. (org-test-with-temp-text
  399. "An inline<point>[fn:1] footnote[fn:1:definition]"
  400. (org-edit-special)
  401. (prog1 (buffer-string) (org-edit-src-exit)))))
  402. ;; Label and closing square bracket should be protected against
  403. ;; editing.
  404. (should
  405. (org-test-with-temp-text "An inline<point>[fn:1] footnote[fn:1:definition]"
  406. (org-edit-special)
  407. (prog1 (get-text-property 0 'read-only (buffer-string))
  408. (org-edit-src-exit))))
  409. (should
  410. (org-test-with-temp-text "An inline<point>[fn:1] footnote[fn:1:definition]"
  411. (org-edit-special)
  412. (prog1 (get-text-property 5 'read-only (buffer-string))
  413. (org-edit-src-exit))))
  414. (should
  415. (org-test-with-temp-text "An inline<point>[fn:1] footnote[fn:1:definition]"
  416. (org-edit-special)
  417. (prog1 (get-text-property 16 'read-only (buffer-string))
  418. (org-edit-src-exit))))
  419. ;; Do not include trailing white spaces when displaying the inline
  420. ;; footnote definition.
  421. (should
  422. (equal
  423. "[fn:1:definition]"
  424. (org-test-with-temp-text
  425. "An inline<point>[fn:1] footnote[fn:1:definition] and some text"
  426. (org-edit-special)
  427. (prog1 (buffer-string) (org-edit-src-exit)))))
  428. ;; Preserve local variables when editing a footnote definition.
  429. (should
  430. (eq 'bar
  431. (org-test-with-temp-text "A footnote<point>[fn:1]\n[fn:1] Definition"
  432. (setq-local foo 'bar)
  433. (org-edit-special)
  434. (prog1 foo (org-edit-src-exit))))))
  435. ;;; Code escaping
  436. (ert-deftest test-org-src/escape-code-in-string ()
  437. "Test `org-escape-code-in-string' specifications."
  438. ;; Escape lines starting with "*" or "#+".
  439. (should (equal ",*" (org-escape-code-in-string "*")))
  440. (should (equal ",#+" (org-escape-code-in-string "#+")))
  441. ;; Escape lines starting with ",*" and ",#+". Number of leading
  442. ;; commas does not matter.
  443. (should (equal ",,*" (org-escape-code-in-string ",*")))
  444. (should (equal ",,#+" (org-escape-code-in-string ",#+")))
  445. (should (equal ",,,*" (org-escape-code-in-string ",,*")))
  446. (should (equal ",,,#+" (org-escape-code-in-string ",,#+")))
  447. ;; Indentation does not matter.
  448. (should (equal " ,*" (org-escape-code-in-string " *")))
  449. (should (equal " ,#+" (org-escape-code-in-string " #+")))
  450. ;; Do nothing on other cases.
  451. (should (equal "a" (org-escape-code-in-string "a")))
  452. (should (equal "#" (org-escape-code-in-string "#")))
  453. (should (equal "," (org-escape-code-in-string ","))))
  454. (ert-deftest test-org-src/unescape-code-in-string ()
  455. "Test `org-unescape-code-in-string' specifications."
  456. ;; Unescape lines starting with ",*" or ",#+". Number of leading
  457. ;; commas does not matter.
  458. (should (equal "*" (org-unescape-code-in-string ",*")))
  459. (should (equal "#+" (org-unescape-code-in-string ",#+")))
  460. (should (equal ",*" (org-unescape-code-in-string ",,*")))
  461. (should (equal ",#+" (org-unescape-code-in-string ",,#+")))
  462. ;; Indentation does not matter.
  463. (should (equal " *" (org-unescape-code-in-string " ,*")))
  464. (should (equal " #+" (org-unescape-code-in-string " ,#+")))
  465. ;; Do nothing on other cases.
  466. (should (equal "a" (org-unescape-code-in-string "a")))
  467. (should (equal "#" (org-unescape-code-in-string "#")))
  468. (should (equal "," (org-unescape-code-in-string ","))))
  469. (provide 'test-org-src)
  470. ;;; test-org-src.el ends here