aboutsummaryrefslogtreecommitdiffstats
path: root/test/lisp/replace-tests.el
diff options
context:
space:
mode:
authorTino Calancha2018-06-03 23:28:30 +0900
committerTino Calancha2018-06-03 23:28:30 +0900
commit5fa73a7d98040f749f4cd45cfa40cf3c1c8cc2e3 (patch)
tree01511805dc80acff47aba83bb967b81daa229f6a /test/lisp/replace-tests.el
parent031004e81b1507c4594ae253faaafcda31f253c8 (diff)
downloademacs-5fa73a7d98040f749f4cd45cfa40cf3c1c8cc2e3.tar.gz
emacs-5fa73a7d98040f749f4cd45cfa40cf3c1c8cc2e3.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 (query-replace-undo-bug31538): New test. Backport: (cherry picked from commits ea133e04f49afa7928e49a3ac4a85b47f6f13f01 and 7dcfdf5b14325ae7996f272f14c72810d7c84944)
Diffstat (limited to 'test/lisp/replace-tests.el')
-rw-r--r--test/lisp/replace-tests.el133
1 files changed, 84 insertions, 49 deletions
diff --git a/test/lisp/replace-tests.el b/test/lisp/replace-tests.el
index 40ee838e679..3fcdce6704f 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,71 @@ 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
365(defvar replace-tests-bind-read-string nil
366 "A string to bind `read-string' and avoid the prompt.")
367
368(defmacro replace-tests-with-undo (input from to char-nums def-chr &rest body)
369 "Helper to test `query-replace' undo feature.
370INPUT is a string to insert in a temporary buffer.
371FROM is the string to match and replace.
372TO is the replacement string.
373CHAR-NUMS is a list of elements (CHAR . NUMS), where CHAR is
374one of the characters `,', `?\\s', `u', `U', `E' or `q'
375and NUMS a list of integers.
376DEF-CHAR is the character `?\\s' or `q'.
377BODY is a list of forms to evaluate.
378
379Use CHAR-NUMS and DEF-CHAR to temporary bind the function value of
380`read-event', thus avoiding the prompt.
381For instance, if CHAR-NUMS is the lists ((?\\s . (1 2 3)) (?u . (4))),
382then replace 3 matches of FROM with TO, and undo the last replacement.
383
384Return the last evalled form in BODY."
385 (declare (indent 5) (debug (stringp stringp stringp form characterp body)))
386 (let ((text (gensym "text"))
387 (count (gensym "count")))
388 `(let* ((,text ,input)
389 (,count 0)
390 (inhibit-message t))
391 (with-temp-buffer
392 (insert ,text)
393 (goto-char 1)
394 ;; Bind `read-event' to simulate user input.
395 ;; If `replace-tests-bind-read-string' is non-nil, then
396 ;; bind `read-string' as well.
397 (cl-letf (((symbol-function 'read-event)
398 (lambda (&rest args)
399 (cl-incf ,count)
400 (pcase ,count ; Build the clauses from CHAR-NUMS
401 ,@(append
402 (delq nil
403 (mapcar
404 (lambda (chr)
405 (when-let (it (alist-get chr char-nums))
406 (if (cdr it)
407 `(,(cons 'or it) ,chr)
408 `(,(car it) ,chr))))
409 '(?, ?\s ?u ?U ?E ?q)))
410 `((_ ,def-chr))))))
411 ((symbol-function 'read-string)
412 (if replace-tests-bind-read-string
413 (lambda (&rest args) replace-tests-bind-read-string)
414 (symbol-function 'read-string))))
415 (perform-replace ,from ,to t t nil))
416 ,@body))))
417
361(defun replace-tests--query-replace-undo (&optional comma) 418(defun replace-tests--query-replace-undo (&optional comma)
362 (with-temp-buffer 419 (let ((input "111"))
363 (insert "111") 420 (if comma
364 (goto-char 1) 421 (should
365 (let ((count 0)) 422 (replace-tests-with-undo
366 ;; Don't wait for user input. 423 input "1" "2" ((?, . (2)) (?u . (3)) (?q . (4))) ?\s (buffer-string)))
367 (cl-letf (((symbol-function 'read-event) 424 (should
368 (lambda (&rest args) 425 (replace-tests-with-undo
369 (cl-incf count) 426 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 427
379(ert-deftest query-replace--undo () 428(ert-deftest query-replace--undo ()
380 (should (string= "211" (replace-tests--query-replace-undo))) 429 (should (string= "211" (replace-tests--query-replace-undo)))
@@ -382,42 +431,28 @@ Each element has the format:
382 431
383(ert-deftest query-replace-undo-bug31073 () 432(ert-deftest query-replace-undo-bug31073 ()
384 "Test for https://debbugs.gnu.org/31073 ." 433 "Test for https://debbugs.gnu.org/31073 ."
385 (let ((text "aaa aaa") 434 (let ((input "aaa aaa"))
386 (count 0)) 435 (should
387 (with-temp-buffer 436 (replace-tests-with-undo
388 (insert text) 437 input "a" "B" ((?\s . (1 2 3)) (?U . (4))) ?q
389 (goto-char 1) 438 (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 439
402(ert-deftest query-replace-undo-bug31492 () 440(ert-deftest query-replace-undo-bug31492 ()
403 "Test for https://debbugs.gnu.org/31492 ." 441 "Test for https://debbugs.gnu.org/31492 ."
404 (let ((text "a\nb\nc\n") 442 (let ((input "a\nb\nc\n"))
405 (count 0) 443 (should
406 (inhibit-message t)) 444 (replace-tests-with-undo
407 (with-temp-buffer 445 input "^\\|\b\\|$" "foo" ((?\s . (1 2)) (?U . (3))) ?q
408 (insert text) 446 (string= input (buffer-string))))))
409 (goto-char 1) 447
410 (cl-letf (((symbol-function 'read-event) 448(ert-deftest query-replace-undo-bug31538 ()
411 (lambda (&rest args) 449 "Test for https://debbugs.gnu.org/31538 ."
412 (cl-incf count) 450 (let ((input "aaa aaa")
413 (let ((val (pcase count 451 (replace-tests-bind-read-string "Bfoo"))
414 ((or 1 2) ?\s) ; replace current and go next 452 (should
415 (3 ?U) ; undo-all 453 (replace-tests-with-undo
416 (_ ?q)))) ; exit 454 input "a" "B" ((?\s . (1 2 3)) (?E . (4)) (?U . (5))) ?q
417 val)))) 455 (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 456
422 457
423;;; replace-tests.el ends here 458;;; replace-tests.el ends here