aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorTino Calancha2018-05-26 11:28:21 +0900
committerTino Calancha2018-05-26 11:31:26 +0900
commitea133e04f49afa7928e49a3ac4a85b47f6f13f01 (patch)
treebb297df626833d9160287fa9c9c0e8f85dd70f6e /test
parent48d6212655c347ded7f4ec398467e05c6bce1dc7 (diff)
downloademacs-ea133e04f49afa7928e49a3ac4a85b47f6f13f01.tar.gz
emacs-ea133e04f49afa7928e49a3ac4a85b47f6f13f01.zip
query-replace undo: Handle when user edits the replacement string
* lisp/replace.el (perform-replace): Update the replacement string after the user edit it (Fix Bug#31538). * test/lisp/replace-tests.el (replace-tests-clauses): New function. (replace-tests-bind-read-string): New variable. (replace-tests-with-undo): Macro to create boilerplate code. (query-replace-undo-bug31073): Use it. (query-replace-undo-bug31538): New test.
Diffstat (limited to 'test')
-rw-r--r--test/lisp/replace-tests.el137
1 files changed, 88 insertions, 49 deletions
diff --git a/test/lisp/replace-tests.el b/test/lisp/replace-tests.el
index 40ee838e679..67372bf82fb 100644
--- a/test/lisp/replace-tests.el
+++ b/test/lisp/replace-tests.el
@@ -23,6 +23,7 @@
23;;; Code: 23;;; Code:
24 24
25(require 'ert) 25(require 'ert)
26(eval-when-compile (require 'subr-x))
26 27
27(ert-deftest query-replace--split-string-tests () 28(ert-deftest query-replace--split-string-tests ()
28 (let ((sep (propertize "\0" 'separator t))) 29 (let ((sep (propertize "\0" 'separator t)))
@@ -358,23 +359,75 @@ Each element has the format:
358(dotimes (i (length replace-occur-tests)) 359(dotimes (i (length replace-occur-tests))
359 (replace-occur-test-create i)) 360 (replace-occur-test-create i))
360 361
362
363;;; Tests for `query-replace' undo feature.
364(defun replace-tests-clauses (char-nums def-chr)
365 "Build the clauses of the `pcase' in `replace-tests-with-undo'.
366CHAR-NUMS is a list of elements (CHAR . NUMS).
367CHAR is one of the chars ?, ?\s ?u ?U ?E ?q.
368NUMS is a list of integers; they are the patters to match,
369while CHAR is the return value.
370DEF-CHAR is the default character to return in the `pcase'
371when any of the clauses match."
372 (append
373 (delq nil
374 (mapcar (lambda (chr)
375 (when-let (it (cadr (assq chr char-nums)))
376 (if (cdr it)
377 `(,(cons 'or it) ,chr)
378 `(,(car it) ,chr))))
379 '(?, ?\s ?u ?U ?E ?q)))
380 `((_ ,def-chr))))
381
382(defvar replace-tests-bind-read-string nil
383 "A string to bind `read-string' and avoid the prompt.")
384
385(defmacro replace-tests-with-undo (input from to char-nums def-chr &rest body)
386 "Helper to test `query-replace' undo feature.
387INPUT is a string to insert in a temporary buffer.
388FROM is the string to match for replace.
389TO is the replacement string.
390CHAR-NUMS is a list of elements (CHAR . NUMS).
391CHAR is one of the chars ?, ?\s ?u ?U ?E ?q.
392NUMS is a list of integers.
393DEF-CHAR is the char ?\s or ?q.
394BODY is a list of forms.
395Return the last evaled form in BODY."
396 (declare (indent 5) (debug (stringp stringp stringp form characterp body)))
397 (let ((text (gensym "text"))
398 (count (gensym "count")))
399 `(let* ((,text ,input)
400 (,count 0)
401 (inhibit-message t))
402 (with-temp-buffer
403 (insert ,text)
404 (goto-char 1)
405 ;; Bind `read-event' to simulate user input.
406 ;; If `replace-tests-bind-read-string' is non-nil, then
407 ;; bind `read-string' as well.
408 (cl-letf (((symbol-function 'read-event)
409 (lambda (&rest args)
410 (cl-incf ,count)
411 (let ((val
412 (pcase ,count
413 ,@(replace-tests-clauses char-nums def-chr))))
414 val)))
415 ((symbol-function 'read-string)
416 (if replace-tests-bind-read-string
417 (lambda (&rest args) replace-tests-bind-read-string)
418 (symbol-function 'read-string))))
419 (perform-replace ,from ,to t t nil))
420 ,@body))))
421
361(defun replace-tests--query-replace-undo (&optional comma) 422(defun replace-tests--query-replace-undo (&optional comma)
362 (with-temp-buffer 423 (let ((input "111"))
363 (insert "111") 424 (if comma
364 (goto-char 1) 425 (should
365 (let ((count 0)) 426 (replace-tests-with-undo
366 ;; Don't wait for user input. 427 input "1" "2" ((?, (2)) (?u (3)) (?q (4))) ?\s (buffer-string)))
367 (cl-letf (((symbol-function 'read-event) 428 (should
368 (lambda (&rest args) 429 (replace-tests-with-undo
369 (cl-incf count) 430 input "1" "2" ((?\s (2)) (?u (3)) (?q (4))) ?\s (buffer-string))))))
370 (let ((val (pcase count
371 ('2 (if comma ?, ?\s)) ; replace and: ',' no move; '\s' go next
372 ('3 ?u) ; undo
373 ('4 ?q) ; exit
374 (_ ?\s)))) ; replace current and go next
375 val))))
376 (perform-replace "1" "2" t nil nil)))
377 (buffer-string)))
378 431
379(ert-deftest query-replace--undo () 432(ert-deftest query-replace--undo ()
380 (should (string= "211" (replace-tests--query-replace-undo))) 433 (should (string= "211" (replace-tests--query-replace-undo)))
@@ -382,42 +435,28 @@ Each element has the format:
382 435
383(ert-deftest query-replace-undo-bug31073 () 436(ert-deftest query-replace-undo-bug31073 ()
384 "Test for https://debbugs.gnu.org/31073 ." 437 "Test for https://debbugs.gnu.org/31073 ."
385 (let ((text "aaa aaa") 438 (let ((input "aaa aaa"))
386 (count 0)) 439 (should
387 (with-temp-buffer 440 (replace-tests-with-undo
388 (insert text) 441 input "a" "B" ((?\s (1 2 3)) (?U (4))) ?q
389 (goto-char 1) 442 (string= input (buffer-string))))))
390 (cl-letf (((symbol-function 'read-event)
391 (lambda (&rest args)
392 (cl-incf count)
393 (let ((val (pcase count
394 ((or 1 2 3) ?\s) ; replace current and go next
395 (4 ?U) ; undo-all
396 (_ ?q)))) ; exit
397 val))))
398 (perform-replace "a" "B" t nil nil))
399 ;; After undo text must be the same.
400 (should (string= text (buffer-string))))))
401 443
402(ert-deftest query-replace-undo-bug31492 () 444(ert-deftest query-replace-undo-bug31492 ()
403 "Test for https://debbugs.gnu.org/31492 ." 445 "Test for https://debbugs.gnu.org/31492 ."
404 (let ((text "a\nb\nc\n") 446 (let ((input "a\nb\nc\n"))
405 (count 0) 447 (should
406 (inhibit-message t)) 448 (replace-tests-with-undo
407 (with-temp-buffer 449 input "^\\|\b\\|$" "foo" ((?\s (1 2)) (?U (3))) ?q
408 (insert text) 450 (string= input (buffer-string))))))
409 (goto-char 1) 451
410 (cl-letf (((symbol-function 'read-event) 452(ert-deftest query-replace-undo-bug31538 ()
411 (lambda (&rest args) 453 "Test for https://debbugs.gnu.org/31538 ."
412 (cl-incf count) 454 (let ((input "aaa aaa")
413 (let ((val (pcase count 455 (replace-tests-bind-read-string "Bfoo"))
414 ((or 1 2) ?\s) ; replace current and go next 456 (should
415 (3 ?U) ; undo-all 457 (replace-tests-with-undo
416 (_ ?q)))) ; exit 458 input "a" "B" ((?\s (1 2 3)) (?E (4)) (?U (5))) ?q
417 val)))) 459 (string= input (buffer-string))))))
418 (perform-replace "^\\|\b\\|$" "foo" t t nil))
419 ;; After undo text must be the same.
420 (should (string= text (buffer-string))))))
421 460
422 461
423;;; replace-tests.el ends here 462;;; replace-tests.el ends here