1 ;;; simple-test.el --- Tests for simple.el -*- lexical-binding: t; -*-
3 ;; Copyright (C) 2015-2018 Free Software Foundation, Inc.
5 ;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
7 ;; This program is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
12 ;; This program is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
23 (eval-when-compile (require 'cl-lib
))
25 (defmacro simple-test--dummy-buffer
(&rest body
)
30 (setq indent-tabs-mode nil
)
32 (save-excursion (insert " c d)"))
35 (cons (buffer-substring (point-min) (point))
36 (buffer-substring (point) (point-max))))))
41 (defmacro simple-test--transpositions
(&rest body
)
46 (insert "(s1) (s2) (s3) (s4) (s5)")
49 (cons (buffer-substring (point-min) (point))
50 (buffer-substring (point) (point-max)))))
52 ;;; Transposition with negative args (bug#20698, bug#21885)
53 (ert-deftest simple-transpose-subr
()
54 (should (equal (simple-test--transpositions (transpose-sexps -
1))
55 '("(s1) (s2) (s4)" .
" (s3) (s5)")))
56 (should (equal (simple-test--transpositions (transpose-sexps -
2))
57 '("(s1) (s4)" .
" (s2) (s3) (s5)"))))
61 (ert-deftest newline
()
62 (should-error (newline -
1))
63 (should (equal (simple-test--dummy-buffer (newline 1))
64 '("(a b\n" .
" c d)")))
65 (should (equal (simple-test--dummy-buffer
66 (electric-indent-mode -
1)
67 (call-interactively #'newline
))
68 '("(a b\n" .
" c d)")))
69 (should (equal (simple-test--dummy-buffer
70 (let ((current-prefix-arg 5))
71 (call-interactively #'newline
)))
72 '("(a b\n\n\n\n\n" .
" c d)")))
73 (should (equal (simple-test--dummy-buffer (newline 5))
74 '("(a b\n\n\n\n\n" .
" c d)")))
75 (should (equal (simple-test--dummy-buffer
78 '("(a b \n" .
"c d)"))))
80 (ert-deftest newline-indent
()
81 (should (equal (simple-test--dummy-buffer
82 (electric-indent-local-mode 1)
84 '("(a b\n" .
" c d)")))
85 (should (equal (simple-test--dummy-buffer
86 (electric-indent-local-mode 1)
87 (newline 1 'interactive
))
88 '("(a b\n " .
"c d)")))
89 (should (equal (simple-test--dummy-buffer
90 (electric-indent-local-mode 1)
91 (let ((current-prefix-arg nil
))
92 (call-interactively #'newline
)
93 (call-interactively #'newline
)))
94 '("(a b\n\n " .
"c d)")))
95 (should (equal (simple-test--dummy-buffer
96 (electric-indent-local-mode 1)
97 (newline 5 'interactive
))
98 '("(a b\n\n\n\n\n " .
"c d)")))
99 (should (equal (simple-test--dummy-buffer
100 (electric-indent-local-mode 1)
101 (let ((current-prefix-arg 5))
102 (call-interactively #'newline
)))
103 '("(a b\n\n\n\n\n " .
"c d)")))
104 (should (equal (simple-test--dummy-buffer
106 (electric-indent-local-mode 1)
107 (newline 1 'interactive
))
108 '("(a b\n " .
"c d)"))))
112 (ert-deftest open-line
()
113 (should-error (open-line -
1))
114 (should-error (open-line))
115 (should (equal (simple-test--dummy-buffer (open-line 1))
116 '("(a b" .
"\n c d)")))
117 (should (equal (simple-test--dummy-buffer
118 (electric-indent-mode -
1)
119 (call-interactively #'open-line
))
120 '("(a b" .
"\n c d)")))
121 (should (equal (simple-test--dummy-buffer
122 (let ((current-prefix-arg 5))
123 (call-interactively #'open-line
)))
124 '("(a b" .
"\n\n\n\n\n c d)")))
125 (should (equal (simple-test--dummy-buffer (open-line 5))
126 '("(a b" .
"\n\n\n\n\n c d)")))
127 (should (equal (simple-test--dummy-buffer
130 '("(a b " .
"\nc d)"))))
132 (ert-deftest open-line-margin-and-prefix
()
133 (should (equal (simple-test--dummy-buffer
134 (let ((left-margin 10))
136 '("(a b" .
"\n\n\n c d)")))
137 (should (equal (simple-test--dummy-buffer
139 (let ((left-margin 2))
141 '(" " .
"\n (a b c d)")))
142 (should (equal (simple-test--dummy-buffer
143 (let ((fill-prefix "- - "))
145 '("(a b" .
"\n c d)")))
146 (should (equal (simple-test--dummy-buffer
148 (let ((fill-prefix "- - "))
150 '("- - " .
"\n(a b c d)"))))
152 ;; For a while, from 24 Oct - 21 Nov 2015, `open-line' in the Emacs
153 ;; development tree became sensitive to `electric-indent-mode', which
154 ;; it had not been before. This sensitivity was reverted for the
155 ;; Emacs 25 release, so it could be discussed further (see thread
156 ;; "Questioning the new behavior of `open-line'." on the Emacs Devel
157 ;; mailing list, and bug #21884).
158 (ert-deftest open-line-indent
()
159 (should (equal (simple-test--dummy-buffer
160 (electric-indent-local-mode 1)
162 '("(a b" .
"\n c d)")))
163 (should (equal (simple-test--dummy-buffer
164 (electric-indent-local-mode 1)
166 '("(a b" .
"\n c d)")))
167 (should (equal (simple-test--dummy-buffer
168 (electric-indent-local-mode 1)
169 (let ((current-prefix-arg nil
))
170 (call-interactively #'open-line
)
171 (call-interactively #'open-line
)))
172 '("(a b" .
"\n\n c d)")))
173 (should (equal (simple-test--dummy-buffer
174 (electric-indent-local-mode 1)
176 '("(a b" .
"\n\n\n\n\n c d)")))
177 (should (equal (simple-test--dummy-buffer
178 (electric-indent-local-mode 1)
179 (let ((current-prefix-arg 5))
180 (call-interactively #'open-line
)))
181 '("(a b" .
"\n\n\n\n\n c d)")))
182 (should (equal (simple-test--dummy-buffer
184 (electric-indent-local-mode 1)
186 '("(a b " .
"\nc d)"))))
188 ;; From 24 Oct - 21 Nov 2015, `open-line' took a second argument
189 ;; INTERACTIVE and ran `post-self-insert-hook' if the argument was
190 ;; true. This test tested that. Currently, however, `open-line'
191 ;; does not run `post-self-insert-hook' at all, so for now
192 ;; this test just makes sure that it doesn't.
193 (ert-deftest open-line-hook
()
195 (inc (lambda () (setq x
(1+ x
)))))
196 (simple-test--dummy-buffer
197 (add-hook 'post-self-insert-hook inc nil
'local
)
200 (simple-test--dummy-buffer
201 (add-hook 'post-self-insert-hook inc nil
'local
)
207 (add-hook 'post-self-insert-hook inc
)
208 (simple-test--dummy-buffer
211 (simple-test--dummy-buffer
214 (remove-hook 'post-self-insert-hook inc
))))
217 ;;; `delete-trailing-whitespace'
218 (ert-deftest simple-delete-trailing-whitespace--bug-21766
()
219 "Test bug#21766: delete-whitespace sometimes deletes non-whitespace."
220 (defvar python-indent-guess-indent-offset
) ; to avoid a warning
221 (let ((python (featurep 'python
))
222 (python-indent-guess-indent-offset nil
)
223 (delete-trailing-lines t
))
227 (insert (concat "query = \"\"\"WITH filtered AS \n"
229 "\"\"\".format(fv_)\n"
232 (delete-trailing-whitespace)
233 (should (string-equal (buffer-string)
234 (concat "query = \"\"\"WITH filtered AS\n"
236 "\"\"\".format(fv_)\n"))))
237 ;; Let's clean up if running interactive
238 (unless (or noninteractive python
)
239 (unload-feature 'python
)))))
241 (ert-deftest simple-delete-trailing-whitespace--formfeeds
()
242 "Test formfeeds are not deleted but whitespace past them is."
244 (with-syntax-table (make-syntax-table)
245 (modify-syntax-entry ?
\f " ") ; Make sure \f is whitespace
246 (insert " \f \n \f \f \n\nlast\n")
247 (delete-trailing-whitespace)
248 (should (string-equal (buffer-string) " \f\n \f \f\n\nlast\n"))
249 (should (equal ?\s
(char-syntax ?
\f)))
250 (should (equal ?\s
(char-syntax ?
\n))))))
253 ;;; undo auto-boundary tests
254 (ert-deftest undo-auto-boundary-timer
()
256 undo-auto-current-boundary-timer
))
258 (ert-deftest undo-auto--boundaries-added
()
259 ;; The change in the buffer should have caused addition
260 ;; to undo-auto--undoably-changed-buffers.
263 (setq buffer-undo-list nil
)
265 (member (current-buffer) undo-auto--undoably-changed-buffers
)))
266 ;; The head of buffer-undo-list should be the insertion event, and
270 (setq buffer-undo-list nil
)
272 (car buffer-undo-list
)))
273 ;; Now the head of the buffer-undo-list should be a boundary and so
274 ;; nil. We have to call auto-boundary explicitly because we are out
275 ;; of the command loop
278 (setq buffer-undo-list nil
)
280 (undo-auto--boundaries 'test
))))
282 ;; Test for a regression introduced by undo-auto--boundaries changes.
283 ;; https://lists.gnu.org/r/emacs-devel/2015-11/msg01652.html
284 (defun undo-test-kill-c-a-then-undo ()
286 (switch-to-buffer (current-buffer))
287 (setq buffer-undo-list nil
)
288 (insert "a\nb\n\c\n")
289 (goto-char (point-max))
290 ;; We use a keyboard macro because it adds undo events in the same
291 ;; way as if a user were involved.
292 (kmacro-call-macro nil nil nil
304 (defun undo-test-point-after-forward-kill ()
306 (switch-to-buffer (current-buffer))
307 (setq buffer-undo-list nil
)
308 (insert "kill word forward")
309 ;; Move to word "word".
311 (kmacro-call-macro nil nil nil
320 (ert-deftest undo-point-in-wrong-place
()
322 ;; returns 5 with the bug
324 (undo-test-kill-c-a-then-undo)))
327 (undo-test-point-after-forward-kill))))
329 (defmacro simple-test-undo-with-switched-buffer
(buffer &rest body
)
330 (declare (indent 1) (debug t
))
331 (let ((before-buffer (make-symbol "before-buffer")))
332 `(let ((,before-buffer
(current-buffer)))
335 (switch-to-buffer ,buffer
)
337 (switch-to-buffer ,before-buffer
)))))
339 ;; This tests for a regression in emacs 25.0 see bug #23632
340 (ert-deftest simple-test-undo-extra-boundary-in-tex
()
344 (simple-test-undo-with-switched-buffer
347 ;; This macro calls `latex-insert-block'
351 C-c C-o ;; latex-insert-block
356 (buffer-substring-no-properties
360 (ert-deftest missing-record-point-in-undo
()
361 "Check point is being restored correctly.
367 (generate-new-buffer " *temp*")
369 (setq buffer-undo-list nil
)
370 (insert "(progn (end-of-line) (insert \"hello\"))")
380 ;;; `eval-expression'
382 (ert-deftest eval-expression-print-format-sym
()
384 (cl-letf (((symbol-function 'read--expression
) (lambda (&rest _
) t
)))
385 (let ((current-prefix-arg '(4)))
386 (call-interactively #'eval-expression
)
387 (should (equal (buffer-string) "t"))))))
389 (ert-deftest eval-expression-print-format-sym-echo
()
390 ;; We can only check the echo area when running interactive.
391 (skip-unless (not noninteractive
))
393 (cl-letf (((symbol-function 'read--expression
) (lambda (&rest _
) t
)))
394 (let ((current-prefix-arg nil
))
396 (call-interactively #'eval-expression
)
397 (should (equal (current-message) "t"))))))
399 (ert-deftest eval-expression-print-format-small-int
()
401 (cl-letf (((symbol-function 'read--expression
) (lambda (&rest _
) ?A
)))
402 (let ((current-prefix-arg '(4)))
404 (call-interactively #'eval-expression
)
405 (should (equal (buffer-string) "65")))
406 (let ((current-prefix-arg 0))
408 (call-interactively #'eval-expression
)
409 (should (equal (buffer-string) "65 (#o101, #x41, ?A)"))))))
411 (ert-deftest eval-expression-print-format-small-int-echo
()
412 (skip-unless (not noninteractive
))
414 (cl-letf (((symbol-function 'read--expression
) (lambda (&rest _
) ?A
)))
415 (let ((current-prefix-arg nil
))
417 (call-interactively #'eval-expression
)
418 (should (equal (current-message) "65 (#o101, #x41, ?A)"))))))
420 (ert-deftest eval-expression-print-format-large-int
()
422 (cl-letf (((symbol-function 'read--expression
) (lambda (&rest _
) ?B
))
423 (eval-expression-print-maximum-character ?A
))
424 (let ((current-prefix-arg '(4)))
426 (call-interactively #'eval-expression
)
427 (should (equal (buffer-string) "66")))
428 (let ((current-prefix-arg 0))
430 (call-interactively #'eval-expression
)
431 (should (equal (buffer-string) "66 (#o102, #x42)")))
432 (let ((current-prefix-arg -
1))
434 (call-interactively #'eval-expression
)
435 (should (equal (buffer-string) "66 (#o102, #x42, ?B)"))))))
437 (ert-deftest eval-expression-print-format-large-int-echo
()
438 (skip-unless (not noninteractive
))
440 (cl-letf (((symbol-function 'read--expression
) (lambda (&rest _
) ?B
))
441 (eval-expression-print-maximum-character ?A
))
442 (let ((current-prefix-arg nil
))
444 (call-interactively #'eval-expression
)
445 (should (equal (current-message) "66 (#o102, #x42)")))
446 (let ((current-prefix-arg '-
))
448 (call-interactively #'eval-expression
)
449 (should (equal (current-message) "66 (#o102, #x42, ?B)"))))))
451 (ert-deftest command-execute-prune-command-history
()
452 "Check that Bug#31211 is fixed."
453 (let ((history-length 1)
454 (command-history ()))
455 (dotimes (_ (1+ history-length
))
456 (command-execute "" t
))
457 (should (= (length command-history
) history-length
))))
460 ;;; `line-number-at-pos'
462 (ert-deftest line-number-at-pos-in-widen-buffer
()
463 (let ((target-line 3))
465 (insert "a\nb\nc\nd\n")
466 (goto-char (point-min))
467 (forward-line (1- target-line
))
468 (should (equal (line-number-at-pos) target-line
))
469 (should (equal (line-number-at-pos nil t
) target-line
)))))
471 (ert-deftest line-number-at-pos-in-narrow-buffer
()
472 (let ((target-line 3))
474 (insert "a\nb\nc\nd\n")
475 (goto-char (point-min))
476 (forward-line (1- target-line
))
477 (narrow-to-region (line-beginning-position) (line-end-position))
478 (should (equal (line-number-at-pos) 1))
479 (should (equal (line-number-at-pos nil t
) target-line
)))))
481 (ert-deftest line-number-at-pos-keeps-restriction
()
483 (insert "a\nb\nc\nd\n")
484 (goto-char (point-min))
486 (narrow-to-region (line-beginning-position) (line-end-position))
487 (should (equal (line-number-at-pos) 1))
488 (line-number-at-pos nil t
)
489 (should (equal (line-number-at-pos) 1))))
491 (ert-deftest line-number-at-pos-keeps-point
()
494 (insert "a\nb\nc\nd\n")
495 (goto-char (point-min))
499 (line-number-at-pos nil t
)
500 (should (equal pos
(point))))))
502 (ert-deftest line-number-at-pos-when-passing-point
()
504 (insert "a\nb\nc\nd\n")
505 (should (equal (line-number-at-pos 1) 1))
506 (should (equal (line-number-at-pos 3) 2))
507 (should (equal (line-number-at-pos 5) 3))
508 (should (equal (line-number-at-pos 7) 4))))
513 (ert-deftest auto-fill-mode-no-break-before-length-of-fill-prefix
()
515 (setq-local fill-prefix
" ")
517 ;; Shouldn't break after 'foo' (3 characters) when the next
518 ;; line is indented >= to that, that wouldn't result in shorter
522 (should (string-equal (buffer-string) "foo bar"))))
527 (ert-deftest simple-tests-async-shell-command-30280
()
528 "Test for https://debbugs.gnu.org/30280 ."
529 (let* ((async-shell-command-buffer 'new-buffer
)
530 (async-shell-command-display-buffer nil
)
532 (first (buffer-name (generate-new-buffer base
)))
533 (second (generate-new-buffer-name base
))
534 ;; `save-window-excursion' doesn't restore frame configurations.
537 (emacs (expand-file-name invocation-name invocation-directory
)))
538 (skip-unless (file-executable-p emacs
))
539 ;; Let `shell-command' create the buffer as needed.
542 (save-window-excursion
543 ;; One command has no output, the other does.
544 ;; Removing the -eval argument also yields no output, but
545 ;; then both commands exit simultaneously when
546 ;; `accept-process-output' is called on the second command.
547 (dolist (form '("(sleep-for 8)" "(message \"\")"))
548 (async-shell-command (format "%s -Q -batch -eval '%s'"
551 ;; First command should neither have nor display output.
552 (let* ((buffer (get-buffer first
))
553 (process (get-buffer-process buffer
)))
554 (should (buffer-live-p buffer
))
556 (should (zerop (buffer-size buffer
)))
557 (should (not (get-buffer-window buffer
))))
558 ;; Second command should both have and display output.
559 (let* ((buffer (get-buffer second
))
560 (process (get-buffer-process buffer
)))
561 (should (buffer-live-p buffer
))
563 (should (accept-process-output process
4 nil t
))
564 (should (> (buffer-size buffer
) 0))
565 (should (get-buffer-window buffer
))))
566 (dolist (name (list first second
))
567 (let* ((buffer (get-buffer name
))
568 (process (and buffer
(get-buffer-process buffer
))))
569 (when process
(delete-process process
))
570 (when buffer
(kill-buffer buffer
)))))))
572 (provide 'simple-test
)
573 ;;; simple-test.el ends here