diff options
| author | Michael Albinus | 2015-10-26 16:46:48 +0100 |
|---|---|---|
| committer | Michael Albinus | 2015-10-26 16:46:48 +0100 |
| commit | 0d9c67236cab3ffe9a8f1276e93a32e437c09bfc (patch) | |
| tree | cb63c930538f2761c47aadaa49e5f099a1b330d2 | |
| parent | 934bfb933f4981b2edaa208186e2f8781ab6cb9f (diff) | |
| download | emacs-0d9c67236cab3ffe9a8f1276e93a32e437c09bfc.tar.gz emacs-0d9c67236cab3ffe9a8f1276e93a32e437c09bfc.zip | |
Further work on `stopped' events in filenotify.el
* doc/lispref/os.texi (File Notifications): Rework examples.
* lisp/filenotify.el (file-notify--rm-descriptor): Optional parameter.
(file-notify--rm-descriptor, file-notify-callback): Improve check
for sending `stopped' event.
(file-notify-add-watch): Check for more events for `inotify'.
* test/automated/file-notify-tests.el
(file-notify--test-expected-events): New defvar.
(file-notify--test-with-events): Use it.
(file-notify--test-cleanup): Make it more robust when deleting
directories.
(file-notify--test-event-test): Check also for watched directories.
(file-notify--test-event-handler): Suppress temporary .#files.
(file-notify-test02-events, file-notify-test04-file-validity):
Rework `stopped' events.
(file-notify-test05-dir-validity): Wait for events when appropriate.
| -rw-r--r-- | doc/lispref/os.texi | 45 | ||||
| -rw-r--r-- | lisp/filenotify.el | 44 | ||||
| -rw-r--r-- | test/automated/file-notify-tests.el | 178 |
3 files changed, 156 insertions, 111 deletions
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 0160de82086..7050df86a18 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi | |||
| @@ -2697,6 +2697,11 @@ watch library. Otherwise, the actions @code{deleted} and | |||
| 2697 | (rename-file "/tmp/foo" "/tmp/bla") | 2697 | (rename-file "/tmp/foo" "/tmp/bla") |
| 2698 | @result{} Event (35025468 renamed "/tmp/foo" "/tmp/bla") | 2698 | @result{} Event (35025468 renamed "/tmp/foo" "/tmp/bla") |
| 2699 | @end group | 2699 | @end group |
| 2700 | |||
| 2701 | @group | ||
| 2702 | (delete-file "/tmp/bla") | ||
| 2703 | @result{} Event (35025468 deleted "/tmp/bla") | ||
| 2704 | @end group | ||
| 2700 | @end example | 2705 | @end example |
| 2701 | @end defun | 2706 | @end defun |
| 2702 | 2707 | ||
| @@ -2718,15 +2723,15 @@ also makes it invalid. | |||
| 2718 | 2723 | ||
| 2719 | @example | 2724 | @example |
| 2720 | @group | 2725 | @group |
| 2721 | (setq desc (file-notify-add-watch | 2726 | (make-directory "/tmp/foo") |
| 2722 | "/tmp/foo" '(change) 'my-notify-callback)) | 2727 | @result{} nil |
| 2723 | @result{} 35025468 | ||
| 2724 | @end group | 2728 | @end group |
| 2725 | 2729 | ||
| 2726 | @group | 2730 | @group |
| 2727 | (write-region "foo" nil "/tmp/foo") | 2731 | (setq desc |
| 2728 | @result{} Event (35025468 created "/tmp/foo") | 2732 | (file-notify-add-watch |
| 2729 | Event (35025468 changed "/tmp/foo") | 2733 | "/tmp/foo" '(change) 'my-notify-callback)) |
| 2734 | @result{} 35025468 | ||
| 2730 | @end group | 2735 | @end group |
| 2731 | 2736 | ||
| 2732 | @group | 2737 | @group |
| @@ -2735,8 +2740,32 @@ also makes it invalid. | |||
| 2735 | @end group | 2740 | @end group |
| 2736 | 2741 | ||
| 2737 | @group | 2742 | @group |
| 2738 | (delete-file "/tmp/foo") | 2743 | (write-region "bla" nil "/tmp/foo/bla") |
| 2739 | @result{} Event (35025468 deleted "/tmp/foo") | 2744 | @result{} Event (35025468 created "/tmp/foo/.#bla") |
| 2745 | Event (35025468 created "/tmp/foo/bla") | ||
| 2746 | Event (35025468 changed "/tmp/foo/bla") | ||
| 2747 | Event (35025468 changed "/tmp/foo/.#bla") | ||
| 2748 | @end group | ||
| 2749 | |||
| 2750 | @group | ||
| 2751 | ;; Deleting a file in the directory doesn't invalidate the watch. | ||
| 2752 | (delete-file "/tmp/foo/bla") | ||
| 2753 | @result{} Event (35025468 deleted "/tmp/foo/bla") | ||
| 2754 | @end group | ||
| 2755 | |||
| 2756 | @group | ||
| 2757 | (write-region "bla" nil "/tmp/foo/bla") | ||
| 2758 | @result{} Event (35025468 created "/tmp/foo/.#bla") | ||
| 2759 | Event (35025468 created "/tmp/foo/bla") | ||
| 2760 | Event (35025468 changed "/tmp/foo/bla") | ||
| 2761 | Event (35025468 changed "/tmp/foo/.#bla") | ||
| 2762 | @end group | ||
| 2763 | |||
| 2764 | @group | ||
| 2765 | ;; Deleting the directory invalidates the watch. | ||
| 2766 | (delete-directory "/tmp/foo" 'recursive) | ||
| 2767 | @result{} Event (35025468 deleted "/tmp/foo/bla") | ||
| 2768 | Event (35025468 deleted "/tmp/foo") | ||
| 2740 | Event (35025468 stopped "/tmp/foo") | 2769 | Event (35025468 stopped "/tmp/foo") |
| 2741 | @end group | 2770 | @end group |
| 2742 | 2771 | ||
diff --git a/lisp/filenotify.el b/lisp/filenotify.el index 55d9028f252..6a180a86570 100644 --- a/lisp/filenotify.el +++ b/lisp/filenotify.el | |||
| @@ -48,32 +48,33 @@ The value in the hash table is a list | |||
| 48 | Several values for a given DIR happen only for `inotify', when | 48 | Several values for a given DIR happen only for `inotify', when |
| 49 | different files from the same directory are watched.") | 49 | different files from the same directory are watched.") |
| 50 | 50 | ||
| 51 | (defun file-notify--rm-descriptor (descriptor) | 51 | (defun file-notify--rm-descriptor (descriptor &optional what) |
| 52 | "Remove DESCRIPTOR from `file-notify-descriptors'. | 52 | "Remove DESCRIPTOR from `file-notify-descriptors'. |
| 53 | DESCRIPTOR should be an object returned by `file-notify-add-watch'. | 53 | DESCRIPTOR should be an object returned by `file-notify-add-watch'. |
| 54 | If it is registered in `file-notify-descriptors', a stopped event is sent." | 54 | If it is registered in `file-notify-descriptors', a stopped event is sent. |
| 55 | WHAT is a file or directory name to be removed, needed just for `inotify'." | ||
| 55 | (let* ((desc (if (consp descriptor) (car descriptor) descriptor)) | 56 | (let* ((desc (if (consp descriptor) (car descriptor) descriptor)) |
| 56 | (file (if (consp descriptor) (cdr descriptor))) | 57 | (file (if (consp descriptor) (cdr descriptor))) |
| 57 | (registered (gethash desc file-notify-descriptors)) | 58 | (registered (gethash desc file-notify-descriptors)) |
| 58 | (dir (car registered))) | 59 | (dir (car registered))) |
| 59 | 60 | ||
| 60 | (when (consp registered) | 61 | (when (and (consp registered) (or (null what) (string-equal dir what))) |
| 61 | ;; Send `stopped' event. | 62 | ;; Send `stopped' event. |
| 62 | (dolist (entry (cdr registered)) | 63 | (dolist (entry (cdr registered)) |
| 63 | (funcall (cdr entry) | 64 | (funcall (cdr entry) |
| 64 | `(,(file-notify--descriptor desc) stopped | 65 | `(,(file-notify--descriptor desc) stopped |
| 65 | ,(or (and (stringp (car entry)) | 66 | ,(or (and (stringp (car entry)) |
| 66 | (expand-file-name (car entry) dir)) | 67 | (expand-file-name (car entry) dir)) |
| 67 | dir)))) | 68 | dir)))) |
| 68 | 69 | ||
| 69 | ;; Modify `file-notify-descriptors'. | 70 | ;; Modify `file-notify-descriptors'. |
| 70 | (if (not file) | 71 | (if (not file) |
| 71 | (remhash desc file-notify-descriptors) | 72 | (remhash desc file-notify-descriptors) |
| 72 | (setcdr registered | 73 | (setcdr registered |
| 73 | (delete (assoc file (cdr registered)) (cdr registered))) | 74 | (delete (assoc file (cdr registered)) (cdr registered))) |
| 74 | (if (null (cdr registered)) | 75 | (if (null (cdr registered)) |
| 75 | (remhash desc file-notify-descriptors) | 76 | (remhash desc file-notify-descriptors) |
| 76 | (puthash desc registered file-notify-descriptors)))))) | 77 | (puthash desc registered file-notify-descriptors)))))) |
| 77 | 78 | ||
| 78 | ;; This function is used by `gfilenotify', `inotify' and `w32notify' events. | 79 | ;; This function is used by `gfilenotify', `inotify' and `w32notify' events. |
| 79 | ;;;###autoload | 80 | ;;;###autoload |
| @@ -85,6 +86,7 @@ If EVENT is a filewatch event, call its callback. It has the format | |||
| 85 | 86 | ||
| 86 | Otherwise, signal a `file-notify-error'." | 87 | Otherwise, signal a `file-notify-error'." |
| 87 | (interactive "e") | 88 | (interactive "e") |
| 89 | ;;(message "file-notify-handle-event %S" event) | ||
| 88 | (if (and (eq (car event) 'file-notify) | 90 | (if (and (eq (car event) 'file-notify) |
| 89 | (>= (length event) 3)) | 91 | (>= (length event) 3)) |
| 90 | (funcall (nth 2 event) (nth 1 event)) | 92 | (funcall (nth 2 event) (nth 1 event)) |
| @@ -224,6 +226,7 @@ EVENT is the cadr of the event in `file-notify-handle-event' | |||
| 224 | (setq pending-event nil)) | 226 | (setq pending-event nil)) |
| 225 | 227 | ||
| 226 | ;; Check for stopped. | 228 | ;; Check for stopped. |
| 229 | ;;(message "file-notify-callback %S %S" file registered) | ||
| 227 | (setq | 230 | (setq |
| 228 | stopped | 231 | stopped |
| 229 | (or | 232 | (or |
| @@ -232,7 +235,9 @@ EVENT is the cadr of the event in `file-notify-handle-event' | |||
| 232 | (memq action '(deleted renamed)) | 235 | (memq action '(deleted renamed)) |
| 233 | (= (length (cdr registered)) 1) | 236 | (= (length (cdr registered)) 1) |
| 234 | (string-equal | 237 | (string-equal |
| 235 | (or (file-name-nondirectory file) "") (car (cadr registered)))))) | 238 | (file-name-nondirectory file) |
| 239 | (or (file-name-nondirectory (car registered)) | ||
| 240 | (car (cadr registered))))))) | ||
| 236 | 241 | ||
| 237 | ;; Apply callback. | 242 | ;; Apply callback. |
| 238 | (when (and action | 243 | (when (and action |
| @@ -257,7 +262,7 @@ EVENT is the cadr of the event in `file-notify-handle-event' | |||
| 257 | 262 | ||
| 258 | ;; Modify `file-notify-descriptors'. | 263 | ;; Modify `file-notify-descriptors'. |
| 259 | (when stopped | 264 | (when stopped |
| 260 | (file-notify--rm-descriptor (file-notify--descriptor desc)))))) | 265 | (file-notify--rm-descriptor (file-notify--descriptor desc) file))))) |
| 261 | 266 | ||
| 262 | ;; `gfilenotify' and `w32notify' return a unique descriptor for every | 267 | ;; `gfilenotify' and `w32notify' return a unique descriptor for every |
| 263 | ;; `file-notify-add-watch', while `inotify' returns a unique | 268 | ;; `file-notify-add-watch', while `inotify' returns a unique |
| @@ -324,8 +329,8 @@ FILE is the name of the file whose event is being reported." | |||
| 324 | (setq desc (funcall | 329 | (setq desc (funcall |
| 325 | handler 'file-notify-add-watch dir flags callback)) | 330 | handler 'file-notify-add-watch dir flags callback)) |
| 326 | 331 | ||
| 327 | ;; Check, whether Emacs has been compiled with file | 332 | ;; Check, whether Emacs has been compiled with file notification |
| 328 | ;; notification support. | 333 | ;; support. |
| 329 | (unless file-notify--library | 334 | (unless file-notify--library |
| 330 | (signal 'file-notify-error | 335 | (signal 'file-notify-error |
| 331 | '("No file notification package available"))) | 336 | '("No file notification package available"))) |
| @@ -344,7 +349,8 @@ FILE is the name of the file whose event is being reported." | |||
| 344 | (setq | 349 | (setq |
| 345 | l-flags | 350 | l-flags |
| 346 | (cond | 351 | (cond |
| 347 | ((eq file-notify--library 'inotify) '(create modify move delete)) | 352 | ((eq file-notify--library 'inotify) |
| 353 | '(create delete delete-self modify move-self move)) | ||
| 348 | ((eq file-notify--library 'w32notify) | 354 | ((eq file-notify--library 'w32notify) |
| 349 | '(file-name directory-name size last-write-time))))) | 355 | '(file-name directory-name size last-write-time))))) |
| 350 | (when (memq 'attribute-change flags) | 356 | (when (memq 'attribute-change flags) |
diff --git a/test/automated/file-notify-tests.el b/test/automated/file-notify-tests.el index 56b4f69597d..472c6927b87 100644 --- a/test/automated/file-notify-tests.el +++ b/test/automated/file-notify-tests.el | |||
| @@ -61,6 +61,8 @@ | |||
| 61 | (defvar file-notify--test-results nil) | 61 | (defvar file-notify--test-results nil) |
| 62 | (defvar file-notify--test-event nil) | 62 | (defvar file-notify--test-event nil) |
| 63 | (defvar file-notify--test-events nil) | 63 | (defvar file-notify--test-events nil) |
| 64 | (defvar file-notify--test-expected-events nil) | ||
| 65 | |||
| 64 | (defun file-notify--test-timeout () | 66 | (defun file-notify--test-timeout () |
| 65 | "Timeout to wait for arriving events, in seconds." | 67 | "Timeout to wait for arriving events, in seconds." |
| 66 | (if (file-remote-p temporary-file-directory) 6 3)) | 68 | (if (file-remote-p temporary-file-directory) 6 3)) |
| @@ -71,12 +73,12 @@ | |||
| 71 | 73 | ||
| 72 | (when (and file-notify--test-tmpfile | 74 | (when (and file-notify--test-tmpfile |
| 73 | (file-exists-p file-notify--test-tmpfile)) | 75 | (file-exists-p file-notify--test-tmpfile)) |
| 74 | (if (directory-name-p file-notify--test-tmpfile) | 76 | (if (file-directory-p file-notify--test-tmpfile) |
| 75 | (delete-directory file-notify--test-tmpfile 'recursive) | 77 | (delete-directory file-notify--test-tmpfile 'recursive) |
| 76 | (delete-file file-notify--test-tmpfile))) | 78 | (delete-file file-notify--test-tmpfile))) |
| 77 | (when (and file-notify--test-tmpfile1 | 79 | (when (and file-notify--test-tmpfile1 |
| 78 | (file-exists-p file-notify--test-tmpfile1)) | 80 | (file-exists-p file-notify--test-tmpfile1)) |
| 79 | (if (directory-name-p file-notify--test-tmpfile1) | 81 | (if (file-directory-p file-notify--test-tmpfile1) |
| 80 | (delete-directory file-notify--test-tmpfile1 'recursive) | 82 | (delete-directory file-notify--test-tmpfile1 'recursive) |
| 81 | (delete-file file-notify--test-tmpfile1))) | 83 | (delete-file file-notify--test-tmpfile1))) |
| 82 | (when (file-remote-p temporary-file-directory) | 84 | (when (file-remote-p temporary-file-directory) |
| @@ -87,7 +89,8 @@ | |||
| 87 | file-notify--test-tmpfile1 nil | 89 | file-notify--test-tmpfile1 nil |
| 88 | file-notify--test-desc nil | 90 | file-notify--test-desc nil |
| 89 | file-notify--test-results nil | 91 | file-notify--test-results nil |
| 90 | file-notify--test-events nil) | 92 | file-notify--test-events nil |
| 93 | file-notify--test-expected-events nil) | ||
| 91 | (when file-notify--test-event | 94 | (when file-notify--test-event |
| 92 | (error "file-notify--test-event should not be set but bound dynamically"))) | 95 | (error "file-notify--test-event should not be set but bound dynamically"))) |
| 93 | 96 | ||
| @@ -226,13 +229,16 @@ being the result.") | |||
| 226 | "Ert test function to be called by `file-notify--test-event-handler'. | 229 | "Ert test function to be called by `file-notify--test-event-handler'. |
| 227 | We cannot pass arguments, so we assume that `file-notify--test-event' | 230 | We cannot pass arguments, so we assume that `file-notify--test-event' |
| 228 | is bound somewhere." | 231 | is bound somewhere." |
| 229 | ;;(message "Event %S" file-notify--test-event) | ||
| 230 | ;; Check the descriptor. | 232 | ;; Check the descriptor. |
| 231 | (should (equal (car file-notify--test-event) file-notify--test-desc)) | 233 | (should (equal (car file-notify--test-event) file-notify--test-desc)) |
| 232 | ;; Check the file name. | 234 | ;; Check the file name. |
| 233 | (should | 235 | (should |
| 234 | (string-equal (file-notify--event-file-name file-notify--test-event) | 236 | (or (string-equal (file-notify--event-file-name file-notify--test-event) |
| 235 | file-notify--test-tmpfile)) | 237 | file-notify--test-tmpfile) |
| 238 | (string-equal (directory-file-name | ||
| 239 | (file-name-directory | ||
| 240 | (file-notify--event-file-name file-notify--test-event))) | ||
| 241 | file-notify--test-tmpfile))) | ||
| 236 | ;; Check the second file name if exists. | 242 | ;; Check the second file name if exists. |
| 237 | (when (eq (nth 1 file-notify--test-event) 'renamed) | 243 | (when (eq (nth 1 file-notify--test-event) 'renamed) |
| 238 | (should | 244 | (should |
| @@ -247,10 +253,15 @@ and the event to `file-notify--test-events'." | |||
| 247 | (let* ((file-notify--test-event event) | 253 | (let* ((file-notify--test-event event) |
| 248 | (result | 254 | (result |
| 249 | (ert-run-test (make-ert-test :body 'file-notify--test-event-test)))) | 255 | (ert-run-test (make-ert-test :body 'file-notify--test-event-test)))) |
| 250 | (setq file-notify--test-events | 256 | ;; Do not add temporary files, this would confuse the checks. |
| 251 | (append file-notify--test-events `(,file-notify--test-event)) | 257 | (unless (string-match |
| 252 | file-notify--test-results | 258 | (regexp-quote ".#") |
| 253 | (append file-notify--test-results `(,result))))) | 259 | (file-notify--event-file-name file-notify--test-event)) |
| 260 | ;;(message "file-notify--test-event-handler %S" file-notify--test-event) | ||
| 261 | (setq file-notify--test-events | ||
| 262 | (append file-notify--test-events `(,file-notify--test-event)) | ||
| 263 | file-notify--test-results | ||
| 264 | (append file-notify--test-results `(,result)))))) | ||
| 254 | 265 | ||
| 255 | (defun file-notify--test-make-temp-name () | 266 | (defun file-notify--test-make-temp-name () |
| 256 | "Create a temporary file name for test." | 267 | "Create a temporary file name for test." |
| @@ -270,6 +281,8 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." | |||
| 270 | (declare (indent 2)) | 281 | (declare (indent 2)) |
| 271 | (let ((outer (make-symbol "outer"))) | 282 | (let ((outer (make-symbol "outer"))) |
| 272 | `(let ((,outer file-notify--test-events)) | 283 | `(let ((,outer file-notify--test-events)) |
| 284 | (setq file-notify--test-expected-events | ||
| 285 | (append file-notify--test-expected-events ,events)) | ||
| 273 | (let (file-notify--test-events) | 286 | (let (file-notify--test-events) |
| 274 | ,@body | 287 | ,@body |
| 275 | (file-notify--wait-for-events | 288 | (file-notify--wait-for-events |
| @@ -281,21 +294,47 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." | |||
| 281 | (ert-deftest file-notify-test02-events () | 294 | (ert-deftest file-notify-test02-events () |
| 282 | "Check file creation/change/removal notifications." | 295 | "Check file creation/change/removal notifications." |
| 283 | (skip-unless (file-notify--test-local-enabled)) | 296 | (skip-unless (file-notify--test-local-enabled)) |
| 297 | |||
| 298 | (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) | ||
| 299 | file-notify--test-tmpfile1 (file-notify--test-make-temp-name)) | ||
| 300 | |||
| 284 | (unwind-protect | 301 | (unwind-protect |
| 285 | (progn | 302 | (progn |
| 286 | ;; Check creation, change, and deletion. | 303 | ;; Check creation, change and deletion. |
| 287 | (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) | 304 | (setq file-notify--test-desc |
| 288 | file-notify--test-tmpfile1 (file-notify--test-make-temp-name) | ||
| 289 | file-notify--test-desc | ||
| 290 | (file-notify-add-watch | 305 | (file-notify-add-watch |
| 291 | file-notify--test-tmpfile | 306 | file-notify--test-tmpfile |
| 292 | '(change) 'file-notify--test-event-handler)) | 307 | '(change) 'file-notify--test-event-handler)) |
| 293 | (file-notify--test-with-events | 308 | (file-notify--test-with-events |
| 294 | (file-notify--test-timeout) '(created changed deleted stopped) | 309 | (file-notify--test-timeout) '(created changed deleted) |
| 295 | (write-region | 310 | (write-region |
| 296 | "any text" nil file-notify--test-tmpfile nil 'no-message) | 311 | "any text" nil file-notify--test-tmpfile nil 'no-message) |
| 297 | (delete-file file-notify--test-tmpfile)) | 312 | (delete-file file-notify--test-tmpfile)) |
| 298 | (file-notify-rm-watch file-notify--test-desc) | 313 | ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. |
| 314 | (let (file-notify--test-events) | ||
| 315 | (file-notify-rm-watch file-notify--test-desc)) | ||
| 316 | |||
| 317 | ;; Check creation, change and deletion. There must be a | ||
| 318 | ;; `stopped' event when deleting the directory. It doesn't | ||
| 319 | ;; work for w32notify. | ||
| 320 | (unless (eq file-notify--library 'w32notify) | ||
| 321 | (make-directory file-notify--test-tmpfile) | ||
| 322 | (setq file-notify--test-desc | ||
| 323 | (file-notify-add-watch | ||
| 324 | file-notify--test-tmpfile | ||
| 325 | '(change) 'file-notify--test-event-handler)) | ||
| 326 | (file-notify--test-with-events | ||
| 327 | (file-notify--test-timeout) | ||
| 328 | ;; There are two `deleted' events, for the file and for | ||
| 329 | ;; the directory. | ||
| 330 | '(created changed deleted deleted stopped) | ||
| 331 | (write-region | ||
| 332 | "any text" nil (expand-file-name "foo" file-notify--test-tmpfile) | ||
| 333 | nil 'no-message) | ||
| 334 | (delete-directory file-notify--test-tmpfile 'recursive)) | ||
| 335 | ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. | ||
| 336 | (let (file-notify--test-events) | ||
| 337 | (file-notify-rm-watch file-notify--test-desc))) | ||
| 299 | 338 | ||
| 300 | ;; Check copy. | 339 | ;; Check copy. |
| 301 | (setq file-notify--test-desc | 340 | (setq file-notify--test-desc |
| @@ -308,8 +347,8 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." | |||
| 308 | ;; w32notify does not distinguish between `changed' and | 347 | ;; w32notify does not distinguish between `changed' and |
| 309 | ;; `attribute-changed'. | 348 | ;; `attribute-changed'. |
| 310 | (if (eq file-notify--library 'w32notify) | 349 | (if (eq file-notify--library 'w32notify) |
| 311 | '(created changed changed deleted stopped) | 350 | '(created changed changed deleted) |
| 312 | '(created changed deleted stopped)) | 351 | '(created changed deleted)) |
| 313 | (write-region | 352 | (write-region |
| 314 | "any text" nil file-notify--test-tmpfile nil 'no-message) | 353 | "any text" nil file-notify--test-tmpfile nil 'no-message) |
| 315 | (copy-file file-notify--test-tmpfile file-notify--test-tmpfile1) | 354 | (copy-file file-notify--test-tmpfile file-notify--test-tmpfile1) |
| @@ -319,7 +358,9 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." | |||
| 319 | (set-file-times file-notify--test-tmpfile '(0 0)) | 358 | (set-file-times file-notify--test-tmpfile '(0 0)) |
| 320 | (delete-file file-notify--test-tmpfile) | 359 | (delete-file file-notify--test-tmpfile) |
| 321 | (delete-file file-notify--test-tmpfile1)) | 360 | (delete-file file-notify--test-tmpfile1)) |
| 322 | (file-notify-rm-watch file-notify--test-desc) | 361 | ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. |
| 362 | (let (file-notify--test-events) | ||
| 363 | (file-notify-rm-watch file-notify--test-desc)) | ||
| 323 | 364 | ||
| 324 | ;; Check rename. | 365 | ;; Check rename. |
| 325 | (setq file-notify--test-desc | 366 | (setq file-notify--test-desc |
| @@ -328,13 +369,15 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." | |||
| 328 | '(change) 'file-notify--test-event-handler)) | 369 | '(change) 'file-notify--test-event-handler)) |
| 329 | (should file-notify--test-desc) | 370 | (should file-notify--test-desc) |
| 330 | (file-notify--test-with-events | 371 | (file-notify--test-with-events |
| 331 | (file-notify--test-timeout) '(created changed renamed stopped) | 372 | (file-notify--test-timeout) '(created changed renamed) |
| 332 | (write-region | 373 | (write-region |
| 333 | "any text" nil file-notify--test-tmpfile nil 'no-message) | 374 | "any text" nil file-notify--test-tmpfile nil 'no-message) |
| 334 | (rename-file file-notify--test-tmpfile file-notify--test-tmpfile1) | 375 | (rename-file file-notify--test-tmpfile file-notify--test-tmpfile1) |
| 335 | ;; After the rename, we won't get events anymore. | 376 | ;; After the rename, we won't get events anymore. |
| 336 | (delete-file file-notify--test-tmpfile1)) | 377 | (delete-file file-notify--test-tmpfile1)) |
| 337 | (file-notify-rm-watch file-notify--test-desc) | 378 | ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. |
| 379 | (let (file-notify--test-events) | ||
| 380 | (file-notify-rm-watch file-notify--test-desc)) | ||
| 338 | 381 | ||
| 339 | ;; Check attribute change. It doesn't work for w32notify. | 382 | ;; Check attribute change. It doesn't work for w32notify. |
| 340 | (unless (eq file-notify--library 'w32notify) | 383 | (unless (eq file-notify--library 'w32notify) |
| @@ -359,29 +402,16 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." | |||
| 359 | (set-file-times file-notify--test-tmpfile '(0 0)) | 402 | (set-file-times file-notify--test-tmpfile '(0 0)) |
| 360 | (read-event nil nil 0.1) | 403 | (read-event nil nil 0.1) |
| 361 | (delete-file file-notify--test-tmpfile)) | 404 | (delete-file file-notify--test-tmpfile)) |
| 362 | (file-notify-rm-watch file-notify--test-desc)) | 405 | ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. |
| 406 | (let (file-notify--test-events) | ||
| 407 | (file-notify-rm-watch file-notify--test-desc))) | ||
| 363 | 408 | ||
| 364 | ;; Check the global sequence again just to make sure that | 409 | ;; Check the global sequence again just to make sure that |
| 365 | ;; `file-notify--test-events' has been set correctly. | 410 | ;; `file-notify--test-events' has been set correctly. |
| 366 | (should (equal | 411 | (should (equal (mapcar #'cadr file-notify--test-events) |
| 367 | (mapcar #'cadr file-notify--test-events) | 412 | file-notify--test-expected-events)) |
| 368 | (if (eq file-notify--library 'w32notify) | ||
| 369 | '(created changed deleted stopped | ||
| 370 | created changed changed deleted stopped | ||
| 371 | created changed renamed stopped) | ||
| 372 | (if (file-remote-p temporary-file-directory) | ||
| 373 | '(created changed deleted stopped | ||
| 374 | created changed deleted stopped | ||
| 375 | created changed renamed stopped | ||
| 376 | attribute-changed attribute-changed | ||
| 377 | attribute-changed stopped) | ||
| 378 | '(created changed deleted stopped | ||
| 379 | created changed deleted stopped | ||
| 380 | created changed renamed stopped | ||
| 381 | attribute-changed attribute-changed stopped))))) | ||
| 382 | (should file-notify--test-results) | 413 | (should file-notify--test-results) |
| 383 | (dolist (result file-notify--test-results) | 414 | (dolist (result file-notify--test-results) |
| 384 | ;;(message "%s" (ert-test-result-messages result)) | ||
| 385 | (when (ert-test-failed-p result) | 415 | (when (ert-test-failed-p result) |
| 386 | (ert-fail | 416 | (ert-fail |
| 387 | (cadr (ert-test-result-with-condition-condition result)))))) | 417 | (cadr (ert-test-result-with-condition-condition result)))))) |
| @@ -463,41 +493,16 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." | |||
| 463 | file-notify--test-tmpfile | 493 | file-notify--test-tmpfile |
| 464 | '(change) #'file-notify--test-event-handler)) | 494 | '(change) #'file-notify--test-event-handler)) |
| 465 | (file-notify--test-with-events | 495 | (file-notify--test-with-events |
| 466 | (file-notify--test-timeout) '(created changed) | 496 | (file-notify--test-timeout) '(created changed deleted) |
| 467 | (should (file-notify-valid-p file-notify--test-desc)) | 497 | (should (file-notify-valid-p file-notify--test-desc)) |
| 468 | (write-region | 498 | (write-region |
| 469 | "any text" nil file-notify--test-tmpfile nil 'no-message) | 499 | "any text" nil file-notify--test-tmpfile nil 'no-message) |
| 470 | (should (file-notify-valid-p file-notify--test-desc))) | 500 | (delete-file file-notify--test-tmpfile)) |
| 471 | ;; After removing the watch, the descriptor must not be valid | 501 | ;; After deleting the file, the descriptor is still valid. |
| 502 | (should (file-notify-valid-p file-notify--test-desc)) | ||
| 503 | ;; After removing the watch, the descriptor must not be valid | ||
| 472 | ;; anymore. | 504 | ;; anymore. |
| 473 | (file-notify-rm-watch file-notify--test-desc) | 505 | (file-notify-rm-watch file-notify--test-desc) |
| 474 | (file-notify--wait-for-events | ||
| 475 | (file-notify--test-timeout) | ||
| 476 | (not (file-notify-valid-p file-notify--test-desc))) | ||
| 477 | (should-not (file-notify-valid-p file-notify--test-desc))) | ||
| 478 | |||
| 479 | ;; Cleanup. | ||
| 480 | (file-notify--test-cleanup)) | ||
| 481 | |||
| 482 | (unwind-protect | ||
| 483 | (progn | ||
| 484 | (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) | ||
| 485 | file-notify--test-desc | ||
| 486 | (file-notify-add-watch | ||
| 487 | file-notify--test-tmpfile | ||
| 488 | '(change) #'file-notify--test-event-handler)) | ||
| 489 | (file-notify--test-with-events | ||
| 490 | (file-notify--test-timeout) '(created changed) | ||
| 491 | (should (file-notify-valid-p file-notify--test-desc)) | ||
| 492 | (write-region | ||
| 493 | "any text" nil file-notify--test-tmpfile nil 'no-message) | ||
| 494 | (should (file-notify-valid-p file-notify--test-desc))) | ||
| 495 | ;; After deleting the file, the descriptor must not be valid | ||
| 496 | ;; anymore. | ||
| 497 | (delete-file file-notify--test-tmpfile) | ||
| 498 | (file-notify--wait-for-events | ||
| 499 | (file-notify--test-timeout) | ||
| 500 | (not (file-notify-valid-p file-notify--test-desc))) | ||
| 501 | (should-not (file-notify-valid-p file-notify--test-desc))) | 506 | (should-not (file-notify-valid-p file-notify--test-desc))) |
| 502 | 507 | ||
| 503 | ;; Cleanup. | 508 | ;; Cleanup. |
| @@ -506,26 +511,23 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." | |||
| 506 | (unwind-protect | 511 | (unwind-protect |
| 507 | ;; The batch-mode operation of w32notify is fragile (there's no | 512 | ;; The batch-mode operation of w32notify is fragile (there's no |
| 508 | ;; input threads to send the message to). | 513 | ;; input threads to send the message to). |
| 509 | (unless (and noninteractive (eq file-notify--library 'w32notify)) | 514 | ;(unless (and noninteractive (eq file-notify--library 'w32notify)) |
| 510 | (let ((temporary-file-directory (make-temp-file | 515 | (unless (eq file-notify--library 'w32notify) |
| 511 | "file-notify-test-parent" t))) | 516 | (let ((temporary-file-directory |
| 517 | (make-temp-file "file-notify-test-parent" t))) | ||
| 512 | (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) | 518 | (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) |
| 513 | file-notify--test-desc | 519 | file-notify--test-desc |
| 514 | (file-notify-add-watch | 520 | (file-notify-add-watch |
| 515 | file-notify--test-tmpfile | 521 | file-notify--test-tmpfile |
| 516 | '(change) #'file-notify--test-event-handler)) | 522 | '(change) #'file-notify--test-event-handler)) |
| 517 | (file-notify--test-with-events | 523 | (file-notify--test-with-events |
| 518 | (file-notify--test-timeout) '(created changed) | 524 | (file-notify--test-timeout) '(created changed deleted stopped) |
| 519 | (should (file-notify-valid-p file-notify--test-desc)) | 525 | (should (file-notify-valid-p file-notify--test-desc)) |
| 520 | (write-region | 526 | (write-region |
| 521 | "any text" nil file-notify--test-tmpfile nil 'no-message) | 527 | "any text" nil file-notify--test-tmpfile nil 'no-message) |
| 522 | (should (file-notify-valid-p file-notify--test-desc))) | 528 | (delete-directory temporary-file-directory t)) |
| 523 | ;; After deleting the parent, the descriptor must not be | 529 | ;; After deleting the parent directory, the descriptor must |
| 524 | ;; valid anymore. | 530 | ;; not be valid anymore. |
| 525 | (delete-directory temporary-file-directory t) | ||
| 526 | (file-notify--wait-for-events | ||
| 527 | (file-notify--test-timeout) | ||
| 528 | (not (file-notify-valid-p file-notify--test-desc))) | ||
| 529 | (should-not (file-notify-valid-p file-notify--test-desc)))) | 531 | (should-not (file-notify-valid-p file-notify--test-desc)))) |
| 530 | 532 | ||
| 531 | ;; Cleanup. | 533 | ;; Cleanup. |
| @@ -540,8 +542,8 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." | |||
| 540 | 542 | ||
| 541 | (unwind-protect | 543 | (unwind-protect |
| 542 | (progn | 544 | (progn |
| 543 | (setq file-notify--test-tmpfile (file-name-as-directory | 545 | (setq file-notify--test-tmpfile |
| 544 | (file-notify--test-make-temp-name))) | 546 | (file-name-as-directory (file-notify--test-make-temp-name))) |
| 545 | (make-directory file-notify--test-tmpfile) | 547 | (make-directory file-notify--test-tmpfile) |
| 546 | (setq file-notify--test-desc | 548 | (setq file-notify--test-desc |
| 547 | (file-notify-add-watch | 549 | (file-notify-add-watch |
| @@ -551,6 +553,9 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." | |||
| 551 | ;; After removing the watch, the descriptor must not be valid | 553 | ;; After removing the watch, the descriptor must not be valid |
| 552 | ;; anymore. | 554 | ;; anymore. |
| 553 | (file-notify-rm-watch file-notify--test-desc) | 555 | (file-notify-rm-watch file-notify--test-desc) |
| 556 | (file-notify--wait-for-events | ||
| 557 | (file-notify--test-timeout) | ||
| 558 | (not (file-notify-valid-p file-notify--test-desc))) | ||
| 554 | (should-not (file-notify-valid-p file-notify--test-desc))) | 559 | (should-not (file-notify-valid-p file-notify--test-desc))) |
| 555 | 560 | ||
| 556 | ;; Cleanup. | 561 | ;; Cleanup. |
| @@ -560,8 +565,8 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." | |||
| 560 | ;; The batch-mode operation of w32notify is fragile (there's no | 565 | ;; The batch-mode operation of w32notify is fragile (there's no |
| 561 | ;; input threads to send the message to). | 566 | ;; input threads to send the message to). |
| 562 | (unless (and noninteractive (eq file-notify--library 'w32notify)) | 567 | (unless (and noninteractive (eq file-notify--library 'w32notify)) |
| 563 | (setq file-notify--test-tmpfile (file-name-as-directory | 568 | (setq file-notify--test-tmpfile |
| 564 | (file-notify--test-make-temp-name))) | 569 | (file-name-as-directory (file-notify--test-make-temp-name))) |
| 565 | (make-directory file-notify--test-tmpfile) | 570 | (make-directory file-notify--test-tmpfile) |
| 566 | (setq file-notify--test-desc | 571 | (setq file-notify--test-desc |
| 567 | (file-notify-add-watch | 572 | (file-notify-add-watch |
| @@ -589,5 +594,10 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered." | |||
| 589 | (ert-run-tests-interactively "^file-notify-") | 594 | (ert-run-tests-interactively "^file-notify-") |
| 590 | (ert-run-tests-batch "^file-notify-"))) | 595 | (ert-run-tests-batch "^file-notify-"))) |
| 591 | 596 | ||
| 597 | ;; TODO: | ||
| 598 | |||
| 599 | ;; * It does not work yet for local gfilenotify and remote inotifywait. | ||
| 600 | ;; * For w32notify, no stopped events arrive when a directory is removed. | ||
| 601 | |||
| 592 | (provide 'file-notify-tests) | 602 | (provide 'file-notify-tests) |
| 593 | ;;; file-notify-tests.el ends here | 603 | ;;; file-notify-tests.el ends here |