diff options
| author | Tino Calancha | 2018-05-26 11:28:21 +0900 |
|---|---|---|
| committer | Tino Calancha | 2018-05-26 11:31:26 +0900 |
| commit | ea133e04f49afa7928e49a3ac4a85b47f6f13f01 (patch) | |
| tree | bb297df626833d9160287fa9c9c0e8f85dd70f6e /test | |
| parent | 48d6212655c347ded7f4ec398467e05c6bce1dc7 (diff) | |
| download | emacs-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.el | 137 |
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'. | ||
| 366 | CHAR-NUMS is a list of elements (CHAR . NUMS). | ||
| 367 | CHAR is one of the chars ?, ?\s ?u ?U ?E ?q. | ||
| 368 | NUMS is a list of integers; they are the patters to match, | ||
| 369 | while CHAR is the return value. | ||
| 370 | DEF-CHAR is the default character to return in the `pcase' | ||
| 371 | when 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. | ||
| 387 | INPUT is a string to insert in a temporary buffer. | ||
| 388 | FROM is the string to match for replace. | ||
| 389 | TO is the replacement string. | ||
| 390 | CHAR-NUMS is a list of elements (CHAR . NUMS). | ||
| 391 | CHAR is one of the chars ?, ?\s ?u ?U ?E ?q. | ||
| 392 | NUMS is a list of integers. | ||
| 393 | DEF-CHAR is the char ?\s or ?q. | ||
| 394 | BODY is a list of forms. | ||
| 395 | Return 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 |