aboutsummaryrefslogtreecommitdiffstats
path: root/test/src
diff options
context:
space:
mode:
authorMichael Albinus2022-01-31 15:26:06 +0100
committerMichael Albinus2022-01-31 15:26:06 +0100
commit3ca32105d2bd88120e2ecf9a28febc6c78b3eb0d (patch)
tree580c1f25689f9caba52f8f4b542671ba32ee3a44 /test/src
parent6da021fce86a06a97b0bff76f69aa57759533dc9 (diff)
downloademacs-3ca32105d2bd88120e2ecf9a28febc6c78b3eb0d.tar.gz
emacs-3ca32105d2bd88120e2ecf9a28febc6c78b3eb0d.zip
Extend filelock-tests.el for bug#53207
* test/src/filelock-tests.el (filelock-tests--fixture): Make it a defmacro. Adapt callees. (filelock-tests-unlock-spoiled, filelock-tests-kill-buffer-spoiled): Simplify. (filelock-tests-detect-external-change): New test
Diffstat (limited to 'test/src')
-rw-r--r--test/src/filelock-tests.el217
1 files changed, 122 insertions, 95 deletions
diff --git a/test/src/filelock-tests.el b/test/src/filelock-tests.el
index 21478a1a0f2..97642669a0d 100644
--- a/test/src/filelock-tests.el
+++ b/test/src/filelock-tests.el
@@ -31,26 +31,26 @@
31(require 'ert-x) 31(require 'ert-x)
32(require 'seq) 32(require 'seq)
33 33
34(defun filelock-tests--fixture (test-function) 34(defmacro filelock-tests--fixture (&rest body)
35 "Call TEST-FUNCTION under a test fixture. 35 "Call BODY under a test fixture.
36Create a test directory and a buffer whose `buffer-file-name' and 36Create a test directory and a buffer whose `buffer-file-name' and
37`buffer-file-truename' are a file within it, then call 37`buffer-file-truename' are a file within it, then call BODY.
38TEST-FUNCTION. Finally, delete the buffer and the test 38Finally, delete the buffer and the test directory."
39directory." 39 (declare (debug (body)))
40 (ert-with-temp-directory temp-dir 40 `(ert-with-temp-directory temp-dir
41 (let ((name (concat (file-name-as-directory temp-dir) 41 (let ((name (concat (file-name-as-directory temp-dir)
42 "userfile")) 42 "userfile"))
43 (create-lockfiles t)) 43 (create-lockfiles t))
44 (with-temp-buffer 44 (with-temp-buffer
45 (setq buffer-file-name name 45 (setq buffer-file-name name
46 buffer-file-truename name) 46 buffer-file-truename name)
47 (unwind-protect 47 (unwind-protect
48 (save-current-buffer 48 (save-current-buffer
49 (funcall test-function)) 49 ,@body)
50 ;; Set `buffer-file-truename' nil to prevent unlocking, 50 ;; Set `buffer-file-truename' nil to prevent unlocking,
51 ;; which might prompt the user and/or signal errors. 51 ;; which might prompt the user and/or signal errors.
52 (setq buffer-file-name nil 52 (setq buffer-file-name nil
53 buffer-file-truename nil)))))) 53 buffer-file-truename nil))))))
54 54
55(defun filelock-tests--make-lock-name (file-name) 55(defun filelock-tests--make-lock-name (file-name)
56 "Return the lock file name for FILE-NAME. 56 "Return the lock file name for FILE-NAME.
@@ -86,105 +86,132 @@ the case)."
86(ert-deftest filelock-tests-lock-unlock-no-errors () 86(ert-deftest filelock-tests-lock-unlock-no-errors ()
87 "Check that locking and unlocking works without error." 87 "Check that locking and unlocking works without error."
88 (filelock-tests--fixture 88 (filelock-tests--fixture
89 (lambda () 89 (should-not (file-locked-p (buffer-file-name)))
90 (should-not (file-locked-p (buffer-file-name)))
91 90
92 ;; inserting text should lock the buffer's file. 91 ;; Inserting text should lock the buffer's file.
93 (insert "this locks the buffer's file") 92 (insert "this locks the buffer's file")
94 (filelock-tests--should-be-locked) 93 (filelock-tests--should-be-locked)
95 (unlock-buffer) 94 (unlock-buffer)
96 (set-buffer-modified-p nil) 95 (set-buffer-modified-p nil)
97 (should-not (file-locked-p (buffer-file-name))) 96 (should-not (file-locked-p (buffer-file-name)))
98 97
99 ;; `set-buffer-modified-p' should lock the buffer's file. 98 ;; `set-buffer-modified-p' should lock the buffer's file.
100 (set-buffer-modified-p t) 99 (set-buffer-modified-p t)
101 (filelock-tests--should-be-locked) 100 (filelock-tests--should-be-locked)
102 (unlock-buffer) 101 (unlock-buffer)
103 (should-not (file-locked-p (buffer-file-name))) 102 (should-not (file-locked-p (buffer-file-name)))
104 103
105 (should-not (file-locked-p (buffer-file-name)))))) 104 (should-not (file-locked-p (buffer-file-name)))))
106 105
107(ert-deftest filelock-tests-lock-spoiled () 106(ert-deftest filelock-tests-lock-spoiled ()
108 "Check `lock-buffer' ." 107 "Check `lock-buffer'."
109 (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support 108 (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support
110 (filelock-tests--fixture 109 (filelock-tests--fixture
111 (lambda () 110 (filelock-tests--spoil-lock-file buffer-file-truename)
112 (filelock-tests--spoil-lock-file buffer-file-truename) 111 ;; FIXME: errors when locking a file are ignored; should they be?
113 ;; FIXME: errors when locking a file are ignored; should they be? 112 (set-buffer-modified-p t)
114 (set-buffer-modified-p t) 113 (filelock-tests--unspoil-lock-file buffer-file-truename)
115 (filelock-tests--unspoil-lock-file buffer-file-truename) 114 (should-not (file-locked-p buffer-file-truename))))
116 (should-not (file-locked-p buffer-file-truename)))))
117 115
118(ert-deftest filelock-tests-file-locked-p-spoiled () 116(ert-deftest filelock-tests-file-locked-p-spoiled ()
119 "Check that `file-locked-p' fails if the lockfile is \"spoiled\"." 117 "Check that `file-locked-p' fails if the lockfile is \"spoiled\"."
120 (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support 118 (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support
121 (filelock-tests--fixture 119 (filelock-tests--fixture
122 (lambda () 120 (filelock-tests--spoil-lock-file buffer-file-truename)
123 (filelock-tests--spoil-lock-file buffer-file-truename) 121 (let ((err (should-error (file-locked-p (buffer-file-name)))))
124 (let ((err (should-error (file-locked-p (buffer-file-name))))) 122 (should (equal (seq-subseq err 0 2)
125 (should (equal (seq-subseq err 0 2) 123 (if (eq system-type 'windows-nt)
126 (if (eq system-type 'windows-nt) 124 '(permission-denied "Testing file lock")
127 '(permission-denied "Testing file lock") 125 '(file-error "Testing file lock")))))))
128 '(file-error "Testing file lock"))))))))
129 126
130(ert-deftest filelock-tests-unlock-spoiled () 127(ert-deftest filelock-tests-unlock-spoiled ()
131 "Check that `unlock-buffer' fails if the lockfile is \"spoiled\"." 128 "Check that `unlock-buffer' fails if the lockfile is \"spoiled\"."
132 (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support 129 (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support
133 (filelock-tests--fixture 130 (filelock-tests--fixture
134 (lambda () 131 ;; Set the buffer modified with file locking temporarily disabled.
135 ;; Set the buffer modified with file locking temporarily 132 (let ((create-lockfiles nil))
136 ;; disabled. 133 (set-buffer-modified-p t))
137 (let ((create-lockfiles nil)) 134 (should-not (file-locked-p buffer-file-truename))
138 (set-buffer-modified-p t)) 135 (filelock-tests--spoil-lock-file buffer-file-truename)
139 (should-not (file-locked-p buffer-file-truename)) 136
140 (filelock-tests--spoil-lock-file buffer-file-truename) 137 ;; Errors from `unlock-buffer' should call
141 138 ;; `userlock--handle-unlock-error' (bug#46397).
142 ;; Errors from `unlock-buffer' should call 139 (cl-letf (((symbol-function 'userlock--handle-unlock-error)
143 ;; `userlock--handle-unlock-error' (bug#46397). 140 (lambda (err) (signal (car err) (cdr err)))))
144 (let (errors) 141 (should (equal
145 (cl-letf (((symbol-function 'userlock--handle-unlock-error) 142 (if (eq system-type 'windows-nt)
146 (lambda (err) (push err errors)))) 143 '(permission-denied "Unlocking file")
147 (unlock-buffer)) 144 '(file-error "Unlocking file"))
148 (should (consp errors)) 145 (seq-subseq (should-error (unlock-buffer)) 0 2))))))
149 (should (equal
150 (if (eq system-type 'windows-nt)
151 '(permission-denied "Unlocking file")
152 '(file-error "Unlocking file"))
153 (seq-subseq (car errors) 0 2)))
154 (should (equal (length errors) 1))))))
155 146
156(ert-deftest filelock-tests-kill-buffer-spoiled () 147(ert-deftest filelock-tests-kill-buffer-spoiled ()
157 "Check that `kill-buffer' fails if a lockfile is \"spoiled\"." 148 "Check that `kill-buffer' fails if a lockfile is \"spoiled\"."
158 (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support 149 (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support
159 (filelock-tests--fixture 150 (filelock-tests--fixture
160 (lambda () 151 ;; Set the buffer modified with file locking temporarily disabled.
161 ;; Set the buffer modified with file locking temporarily 152 (let ((create-lockfiles nil))
162 ;; disabled. 153 (set-buffer-modified-p t))
163 (let ((create-lockfiles nil)) 154 (should-not (file-locked-p buffer-file-truename))
164 (set-buffer-modified-p t)) 155 (filelock-tests--spoil-lock-file buffer-file-truename)
165 (should-not (file-locked-p buffer-file-truename)) 156
166 (filelock-tests--spoil-lock-file buffer-file-truename) 157 ;; Kill the current buffer. Because the buffer is modified Emacs
167 158 ;; will attempt to unlock it. Temporarily bind `yes-or-no-p' to a
168 ;; Kill the current buffer. Because the buffer is modified Emacs 159 ;; function that fakes a "yes" answer for the "Buffer modified;
169 ;; will attempt to unlock it. Temporarily bind `yes-or-no-p' to 160 ;; kill anyway?" prompt.
170 ;; a function that fakes a "yes" answer for the "Buffer modified; 161 ;;
171 ;; kill anyway?" prompt. 162 ;; File errors from unlocking files should call
172 ;; 163 ;; `userlock--handle-unlock-error' (bug#46397).
173 ;; File errors from unlocking files should call 164 (cl-letf (((symbol-function 'yes-or-no-p) #'always)
174 ;; `userlock--handle-unlock-error' (bug#46397). 165 ((symbol-function 'userlock--handle-unlock-error)
175 (let (errors) 166 (lambda (err) (signal (car err) (cdr err)))))
167 (should (equal
168 (if (eq system-type 'windows-nt)
169 '(permission-denied "Unlocking file")
170 '(file-error "Unlocking file"))
171 (seq-subseq (should-error (kill-buffer)) 0 2))))))
172
173(ert-deftest filelock-tests-detect-external-change ()
174 "Check that an external file modification is reported."
175 (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support
176 (skip-unless (executable-find "touch"))
177 (skip-unless (executable-find "echo"))
178 (dolist (cl '(t nil))
179 (filelock-tests--fixture
180 (let ((create-lockfiles cl))
181 (write-region "foo" nil (buffer-file-name))
182 (revert-buffer nil 'noconfirm)
183 (should-not (file-locked-p (buffer-file-name)))
184
185 ;; Just changing the file modification on disk doesn't hurt,
186 ;; because file contents in buffer and on disk look equal.
187 (shell-command (format "touch %s" (buffer-file-name)))
188 (insert "bar")
189 (when cl (filelock-tests--should-be-locked))
190
191 ;; Bug#53207: with `create-lockfiles' nil, saving the buffer
192 ;; results in a prompt.
176 (cl-letf (((symbol-function 'yes-or-no-p) 193 (cl-letf (((symbol-function 'yes-or-no-p)
177 (lambda (&rest _) t)) 194 (lambda (_) (ert-fail "Test failed unexpectedly"))))
178 ((symbol-function 'userlock--handle-unlock-error) 195 (save-buffer))
179 (lambda (err) (push err errors)))) 196 (should-not (file-locked-p (buffer-file-name)))
180 (kill-buffer)) 197
181 (should (consp errors)) 198 ;; Changing the file contents on disk hurts when buffer is
182 (should (equal 199 ;; modified. There shall be a query, which we answer.
183 (if (eq system-type 'windows-nt) 200 ;; *Messages* buffer is checked for prompt.
184 '(permission-denied "Unlocking file") 201 (shell-command (format "echo bar >>%s" (buffer-file-name)))
185 '(file-error "Unlocking file")) 202 (cl-letf (((symbol-function 'read-char-choice)
186 (seq-subseq (car errors) 0 2))) 203 (lambda (prompt &rest _) (message "%s" prompt) ?y)))
187 (should (equal (length errors) 1)))))) 204 (ert-with-message-capture captured-messages
205 ;; `ask-user-about-supersession-threat' does not work in
206 ;; batch mode, let's simulate interactiveness.
207 (let (noninteractive)
208 (insert "baz"))
209 (should (string-match-p
210 (format
211 "^%s changed on disk; really edit the buffer\\?"
212 (file-name-nondirectory (buffer-file-name)))
213 captured-messages))))
214 (when cl (filelock-tests--should-be-locked))))))
188 215
189(provide 'filelock-tests) 216(provide 'filelock-tests)
190;;; filelock-tests.el ends here 217;;; filelock-tests.el ends here