PageRenderTime 2762ms CodeModel.GetById 16ms RepoModel.GetById 2ms app.codeStats 0ms

/test/lisp/so-long-tests/so-long-tests.el

https://gitlab.com/RobertCochran/emacs
Emacs Lisp | 448 lines | 316 code | 42 blank | 90 comment | 3 complexity | 695bbd279e35e1907288b7e60def21ba MD5 | raw file
  1. ;;; so-long-tests.el --- Test suite for so-long.el -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2019 Free Software Foundation, Inc.
  3. ;; Author: Phil Sainty <psainty@orcon.net.nz>
  4. ;; Keywords: convenience
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;; Most of these tests use the shebang #!emacs to get `normal-mode' to
  18. ;; select `emacs-lisp-mode', as using a file-local mode variable would
  19. ;; usually trigger `so-long-file-local-mode-function'. In cases where
  20. ;; we need to `hack-local-variables', we instead set `buffer-file-name'.
  21. ;; (We could consistently use the latter, but the mixture of approaches
  22. ;; means that we're testing more things.)
  23. ;; Running the tests with "make lisp/so-long-tests" is like:
  24. ;;
  25. ;; HOME=/nonexistent EMACSLOADPATH= LC_ALL=C \
  26. ;; EMACS_TEST_DIRECTORY=/home/phil/emacs/trunk/repository/test \
  27. ;; "../src/emacs" --no-init-file --no-site-file --no-site-lisp \
  28. ;; -L ":." -l ert -l lisp/so-long-tests.el --batch --eval \
  29. ;; '(ert-run-tests-batch-and-exit (quote (not (tag :unstable))))'
  30. ;;
  31. ;; See also `ert-run-tests-batch-and-exit'.
  32. ;;; Code:
  33. (require 'ert)
  34. (require 'so-long)
  35. (load (expand-file-name "so-long-tests-helpers"
  36. (file-name-directory (or load-file-name
  37. default-directory))))
  38. (declare-function so-long-tests-remember "so-long-tests-helpers")
  39. (declare-function so-long-tests-assert-active "so-long-tests-helpers")
  40. (declare-function so-long-tests-assert-reverted "so-long-tests-helpers")
  41. (declare-function so-long-tests-assert-and-revert "so-long-tests-helpers")
  42. ;; Enable the automated behaviour for all tests.
  43. (global-so-long-mode 1)
  44. (ert-deftest so-long-tests-threshold-under ()
  45. "Under line length threshold."
  46. (with-temp-buffer
  47. (insert "#!emacs\n")
  48. (insert (make-string (1- so-long-threshold) ?x))
  49. (normal-mode)
  50. (should (eq major-mode 'emacs-lisp-mode))))
  51. (ert-deftest so-long-tests-threshold-at ()
  52. "At line length threshold."
  53. (with-temp-buffer
  54. (insert "#!emacs\n")
  55. (insert (make-string (1- so-long-threshold) ?x))
  56. (normal-mode)
  57. (should (eq major-mode 'emacs-lisp-mode))))
  58. (ert-deftest so-long-tests-threshold-over ()
  59. "Over line length threshold."
  60. (with-temp-buffer
  61. (insert "#!emacs\n")
  62. (normal-mode)
  63. (so-long-tests-remember)
  64. (insert (make-string (1+ so-long-threshold) ?x))
  65. (normal-mode)
  66. (so-long-tests-assert-and-revert 'so-long-mode)))
  67. (ert-deftest so-long-tests-skip-comments ()
  68. "Skip leading shebang, whitespace, and comments."
  69. ;; Long comment, no newline.
  70. (with-temp-buffer
  71. (insert "#!emacs\n")
  72. (insert (make-string (1+ so-long-threshold) ?\;))
  73. (normal-mode)
  74. (should (eq major-mode 'emacs-lisp-mode)))
  75. ;; Long comment, with newline.
  76. (with-temp-buffer
  77. (insert "#!emacs\n")
  78. (insert (make-string (1+ so-long-threshold) ?\;))
  79. (insert "\n")
  80. (normal-mode)
  81. (should (eq major-mode 'emacs-lisp-mode)))
  82. ;; Long comment, with short text following.
  83. (with-temp-buffer
  84. (insert "#!emacs\n")
  85. (insert (make-string (1+ so-long-threshold) ?\;))
  86. (insert "\n")
  87. (insert (make-string so-long-threshold ?x))
  88. (normal-mode)
  89. (should (eq major-mode 'emacs-lisp-mode)))
  90. ;; Long comment, with long text following.
  91. (with-temp-buffer
  92. (insert "#!emacs\n")
  93. (insert (make-string (1+ so-long-threshold) ?\;))
  94. (insert "\n")
  95. (insert (make-string (1+ so-long-threshold) ?x))
  96. (normal-mode)
  97. (should (eq major-mode 'so-long-mode))))
  98. (ert-deftest so-long-tests-max-lines ()
  99. "Give up after `so-long-max-lines'."
  100. (with-temp-buffer
  101. (insert "#!emacs\n")
  102. ;; Insert exactly `so-long-max-lines' non-comment lines, followed
  103. ;; by a long line.
  104. (dotimes (_ so-long-max-lines)
  105. (insert "x\n"))
  106. (insert (make-string (1+ so-long-threshold) ?x))
  107. (normal-mode)
  108. (should (eq major-mode 'emacs-lisp-mode))
  109. ;; If `so-long-max-lines' is nil, don't give up the search.
  110. (let ((so-long-max-lines nil))
  111. (normal-mode)
  112. (should (eq major-mode 'so-long-mode)))
  113. ;; If `so-long-skip-leading-comments' is nil, all lines are
  114. ;; counted, and so the shebang line counts, which makes the
  115. ;; long line one line further away.
  116. (let ((so-long-skip-leading-comments nil)
  117. (so-long-max-lines (1+ so-long-max-lines)))
  118. (normal-mode)
  119. (should (eq major-mode 'emacs-lisp-mode))
  120. (let ((so-long-max-lines (1+ so-long-max-lines)))
  121. (normal-mode)
  122. (should (eq major-mode 'so-long-mode))))))
  123. (ert-deftest so-long-tests-actions ()
  124. "Test each of the standard actions."
  125. (dolist (action (mapcar #'car so-long-action-alist))
  126. (with-temp-buffer
  127. (insert "#!emacs\n")
  128. (normal-mode)
  129. (so-long-tests-remember)
  130. (insert (make-string (1+ so-long-threshold) ?x))
  131. (let ((so-long-action action))
  132. (normal-mode)
  133. (so-long-tests-assert-and-revert action)))))
  134. (ert-deftest so-long-tests-command-so-long ()
  135. "Test the `so-long' command."
  136. ;; Includes argument of nil, meaning the default `so-long-mode' action.
  137. (dolist (action (cons nil (mapcar #'car so-long-action-alist)))
  138. (with-temp-buffer
  139. (insert "#!emacs\n")
  140. (normal-mode)
  141. (so-long-tests-remember)
  142. (insert (make-string (1+ so-long-threshold) ?x))
  143. (so-long action)
  144. (so-long-tests-assert-and-revert (or action 'so-long-mode)))))
  145. (ert-deftest so-long-tests-so-long-menu-item-replace-action ()
  146. "Test using the `so-long-menu-item-replace-action' menu item."
  147. (with-temp-buffer
  148. ;; Due to (with-selected-window (so-long-menu-click-window) ...)
  149. ;; (used by `so-long-menu-item-replace-action'), our temp buffer
  150. ;; must be in the selected window.
  151. (set-window-buffer nil (current-buffer))
  152. (insert "#!emacs\n")
  153. (normal-mode)
  154. (so-long-tests-remember)
  155. (insert (make-string (1+ so-long-threshold) ?x))
  156. (let (action)
  157. (dolist (item so-long-action-alist)
  158. ;; n.b. Any existing action is first reverted.
  159. (so-long-menu-item-replace-action item)
  160. (setq action (car item))
  161. (so-long-tests-assert-active action))
  162. ;; After all actions have been used, revert to normal and assert
  163. ;; that the most recent action to have been applied is the one
  164. ;; we have just reverted.
  165. (so-long-menu-item-revert)
  166. (so-long-tests-assert-reverted action))))
  167. (ert-deftest so-long-tests-major-mode ()
  168. "Test calling `so-long-mode' directly."
  169. (with-temp-buffer
  170. (insert "#!emacs\n")
  171. (normal-mode)
  172. (so-long-tests-remember)
  173. (so-long-mode)
  174. (so-long-tests-assert-and-revert 'so-long-mode)))
  175. (ert-deftest so-long-tests-minor-mode ()
  176. "Test calling `so-long-minor-mode' directly."
  177. (with-temp-buffer
  178. (insert "#!emacs\n")
  179. (normal-mode)
  180. (so-long-tests-remember)
  181. (so-long-minor-mode 1)
  182. (so-long-tests-assert-active 'so-long-minor-mode)
  183. (so-long-minor-mode 0)
  184. (so-long-tests-assert-reverted 'so-long-minor-mode)))
  185. (ert-deftest so-long-tests-target-modes ()
  186. "Targeted major modes."
  187. ;; Test the `so-long-target-modes' user option.
  188. (with-temp-buffer
  189. (insert "#!emacs\n")
  190. (insert (make-string (1+ so-long-threshold) ?x))
  191. ;; Nil target modes.
  192. (let ((so-long-target-modes nil))
  193. (normal-mode)
  194. (should (eq major-mode 'emacs-lisp-mode)))
  195. ;; Non-matching target modes.
  196. (let ((so-long-target-modes '(text-mode)))
  197. (normal-mode)
  198. (should (eq major-mode 'emacs-lisp-mode)))
  199. ;; Matching mode (direct).
  200. (let ((so-long-target-modes '(emacs-lisp-mode)))
  201. (normal-mode)
  202. (should (eq major-mode 'so-long-mode)))
  203. ;; Matching mode (indirect).
  204. (let ((so-long-target-modes '(prog-mode)))
  205. (normal-mode)
  206. (should (eq major-mode 'so-long-mode)))))
  207. (ert-deftest so-long-tests-predicate ()
  208. "Custom predicate function."
  209. ;; Test the `so-long-predicate' user option.
  210. (with-temp-buffer
  211. (insert "#!emacs\n")
  212. ;; Always false.
  213. (let ((so-long-predicate #'ignore))
  214. (normal-mode)
  215. (should (eq major-mode 'emacs-lisp-mode)))
  216. ;; Always true.
  217. (let ((so-long-predicate (lambda () t)))
  218. (normal-mode)
  219. (should (eq major-mode 'so-long-mode)))))
  220. (ert-deftest so-long-tests-file-local-action ()
  221. "File-local action."
  222. ;; Test `so-long-action' as a file-local variable.
  223. ;; Only valid in Emacs26+. Refer to "Caveats" in the so-long.el Commentary.
  224. (unless (version< emacs-version "26")
  225. (with-temp-buffer
  226. (insert "#!emacs\n")
  227. (normal-mode)
  228. (so-long-tests-remember))
  229. ;; n.b. `run-mode-hooks' *only* runs `hack-local-variables' when there's a
  230. ;; (buffer-file-name), so the #!emacs approach is insufficient here. It's
  231. ;; valid for the file-locals to be on the second line after the shebang,
  232. ;; but with the *.el filename we no longer need the shebang.
  233. (with-temp-buffer
  234. (setq buffer-file-name (expand-file-name "so-long-tests-data.el"))
  235. (insert ";; -*- so-long-action:so-long-minor-mode; -*-\n")
  236. (put 'so-long-action 'safe-local-variable #'symbolp)
  237. (insert (make-string (1+ so-long-threshold) ?x))
  238. (normal-mode)
  239. (so-long-tests-assert-and-revert 'so-long-minor-mode))))
  240. (ert-deftest so-long-tests-file-local-action-eval-so-long ()
  241. "File-local action and eval:(so-long)."
  242. ;; As per previous test, but using file-local `eval' to call `so-long'.
  243. ;; Only valid in Emacs26+. Refer to "Caveats" in the so-long.el Commentary.
  244. ;; See also `so-long-tests-file-local-action' above.
  245. (unless (version< emacs-version "26")
  246. (with-temp-buffer
  247. (insert "#!emacs\n")
  248. (normal-mode)
  249. (so-long-tests-remember))
  250. (with-temp-buffer
  251. (setq buffer-file-name (concat (make-temp-name "so-long-tests-") ".el"))
  252. (insert ";; -*- so-long-action:so-long-minor-mode; eval:(so-long) -*-\n")
  253. (put 'so-long-action 'safe-local-variable #'symbolp)
  254. (push '(eval . (so-long)) safe-local-variable-values)
  255. (normal-mode)
  256. (so-long-tests-assert-and-revert 'so-long-minor-mode))))
  257. (defvar so-long-tests-local-mode 'unset
  258. "Set by `so-long-tests-file-local-mode-function'.")
  259. (defun so-long-tests-file-local-mode-function (mode)
  260. "A custom value for `so-long-file-local-mode-function'."
  261. (setq so-long-tests-local-mode mode))
  262. ;; Test `so-long-file-local-mode-function' when the file-local major
  263. ;; mode is `emacs-lisp-mode'.
  264. (defmacro so-long-tests-deftest-file-local-emacs-lisp-mode
  265. (sym docstring prop-line &optional local-vars)
  266. "Generate tests for using `emacs-lisp-mode' as a file-local mode."
  267. (setq prop-line (or prop-line "")
  268. local-vars (or local-vars ""))
  269. `(ert-deftest ,sym ()
  270. ,docstring
  271. (let ((orig so-long-file-local-mode-function))
  272. ;; Do nothing at all when a file-local mode is used.
  273. (setq-default so-long-file-local-mode-function 'so-long-inhibit)
  274. (with-temp-buffer
  275. (insert ,prop-line)
  276. (insert (make-string (1+ so-long-threshold) ?x))
  277. (insert ,local-vars)
  278. (normal-mode)
  279. ;; Remember the `emacs-lisp-mode' state. The other cases
  280. ;; will validate the 'reverted' state against this.
  281. (so-long-tests-remember)
  282. (should (eq major-mode 'emacs-lisp-mode)))
  283. ;; Downgrade the action from major mode to minor mode.
  284. (setq-default so-long-file-local-mode-function 'so-long-mode-downgrade)
  285. (with-temp-buffer
  286. (insert ,prop-line)
  287. (insert (make-string (1+ so-long-threshold) ?x))
  288. (insert ,local-vars)
  289. (normal-mode)
  290. (so-long-tests-assert-and-revert 'so-long-minor-mode))
  291. ;; Do not treat the file-local mode specially.
  292. (setq-default so-long-file-local-mode-function nil)
  293. (with-temp-buffer
  294. (insert ,prop-line)
  295. (insert (make-string (1+ so-long-threshold) ?x))
  296. (insert ,local-vars)
  297. (normal-mode)
  298. (so-long-tests-assert-and-revert 'so-long-mode))
  299. ;; Custom function
  300. (setq-default so-long-file-local-mode-function
  301. #'so-long-tests-file-local-mode-function)
  302. (with-temp-buffer
  303. (insert ,prop-line)
  304. (insert (make-string (1+ so-long-threshold) ?x))
  305. (insert ,local-vars)
  306. (let (so-long-tests-local-mode)
  307. (normal-mode)
  308. (should (eq so-long-tests-local-mode 'emacs-lisp-mode))
  309. (so-long-tests-assert-active 'so-long-mode)))
  310. ;; end
  311. (setq-default so-long-file-local-mode-function orig))))
  312. (so-long-tests-deftest-file-local-emacs-lisp-mode
  313. so-long-tests-file-local-emacs-lisp-mode-short-form
  314. "File-local mode (short form). -*- emacs-lisp -*-"
  315. ";; -*- emacs-lisp -*-\n")
  316. (so-long-tests-deftest-file-local-emacs-lisp-mode
  317. so-long-tests-file-local-emacs-lisp-mode-long-form
  318. "File-local mode (long form). -*- emacs-lisp -*-"
  319. ";; -*- mode: emacs-lisp -*-\n")
  320. (so-long-tests-deftest-file-local-emacs-lisp-mode
  321. so-long-tests-file-local-emacs-lisp-mode-long-form2
  322. "File-local mode (long form). -*- emacs-lisp -*-"
  323. nil "\n;; Local Variables:\n;; mode: emacs-lisp\n;; End:\n")
  324. ;; Test `so-long-file-local-mode-function' when the file-local major
  325. ;; mode is `so-long-mode'. In this case we should always end up with
  326. ;; the major mode being `so-long-mode'.
  327. (defmacro so-long-tests-deftest-file-local-so-long-mode
  328. (sym docstring prop-line &optional local-vars)
  329. "Generate tests for using `so-long-mode' as a file-local mode."
  330. (setq prop-line (or prop-line "")
  331. local-vars (or local-vars ""))
  332. `(ert-deftest ,sym ()
  333. ,docstring
  334. (let ((orig so-long-file-local-mode-function))
  335. ;; Do nothing at all when a file-local mode is used.
  336. (setq-default so-long-file-local-mode-function 'so-long-inhibit)
  337. (with-temp-buffer
  338. ;; Remember the new-buffer state. The other cases will
  339. ;; validate the 'reverted' state against this.
  340. (so-long-tests-remember)
  341. (insert ,prop-line)
  342. (insert (make-string (1+ so-long-threshold) ?x))
  343. (insert ,local-vars)
  344. (normal-mode)
  345. (so-long-tests-assert-and-revert 'so-long-mode))
  346. ;; Downgrade from major mode to minor mode.
  347. (setq-default so-long-file-local-mode-function 'so-long-mode-downgrade)
  348. (with-temp-buffer
  349. (insert ,prop-line)
  350. (insert (make-string (1+ so-long-threshold) ?x))
  351. (insert ,local-vars)
  352. (normal-mode)
  353. (so-long-tests-assert-and-revert 'so-long-mode))
  354. ;; Do not treat the file-local mode specially.
  355. (setq-default so-long-file-local-mode-function nil)
  356. (with-temp-buffer
  357. (insert ,prop-line)
  358. (insert (make-string (1+ so-long-threshold) ?x))
  359. (insert ,local-vars)
  360. (normal-mode)
  361. (so-long-tests-assert-and-revert 'so-long-mode))
  362. ;; Custom function.
  363. (setq-default so-long-file-local-mode-function
  364. #'so-long-tests-file-local-mode-function)
  365. (with-temp-buffer
  366. (insert ,prop-line)
  367. (insert (make-string (1+ so-long-threshold) ?x))
  368. (insert ,local-vars)
  369. (let (so-long-tests-local-mode)
  370. (normal-mode)
  371. (should (eq so-long--inhibited t))
  372. (should (eq so-long-tests-local-mode 'so-long-mode))
  373. (so-long-tests-assert-active 'so-long-mode)))
  374. ;; end
  375. (setq-default so-long-file-local-mode-function orig))))
  376. (so-long-tests-deftest-file-local-so-long-mode
  377. so-long-tests-file-local-so-long-mode-short-form
  378. "File-local mode (short form). -*- so-long -*-"
  379. ";; -*- so-long -*-\n")
  380. (so-long-tests-deftest-file-local-so-long-mode
  381. so-long-tests-file-local-so-long-mode-long-form
  382. "File-local mode (long form). -*- mode: so-long -*-"
  383. ";; -*- mode: so-long -*-\n")
  384. (so-long-tests-deftest-file-local-so-long-mode
  385. so-long-tests-file-local-so-long-mode-long-form2
  386. "File-local mode (long form). -*- mode: so-long -*-"
  387. nil "\n;; Local Variables:\n;; mode: so-long\n;; End:\n")
  388. (ert-deftest so-long-tests-commentary ()
  389. "Test the `so-long-commentary' command."
  390. (so-long-commentary)
  391. (should (string= (buffer-name) "*So Long: Commentary*"))
  392. (should (eq major-mode 'outline-mode))
  393. (should (eq view-mode t))
  394. (should (looking-at "^\\* Introduction$"))
  395. (goto-char (point-min))
  396. (should (looking-at "^so-long\\.el$"))
  397. (should (re-search-forward "^\\* Change Log:$")))
  398. (ert-deftest so-long-tests-customize ()
  399. "Test the `so-long-customize' command."
  400. (so-long-customize)
  401. (should (string= (buffer-name) "*Customize Group: So Long*"))
  402. (should (eq major-mode 'Custom-mode)))
  403. ;; Page break to prevent the local vars strings above from
  404. ;; being misinterpreted as actual local vars declarations.
  405. ;;; so-long-tests.el ends here