diff options
| author | Po Lu | 2022-06-08 20:33:42 +0800 |
|---|---|---|
| committer | Po Lu | 2022-06-08 20:34:13 +0800 |
| commit | 0fd60451bc098b57bdcbddfa98cfa210a6b0ab78 (patch) | |
| tree | 87391cefa7f0bc64460c72a66be10b7e1c0fa24e | |
| parent | efe9940567da259d871432cfda4cdf94542ac98e (diff) | |
| download | emacs-0fd60451bc098b57bdcbddfa98cfa210a6b0ab78.tar.gz emacs-0fd60451bc098b57bdcbddfa98cfa210a6b0ab78.zip | |
Allow running some DND tests interactively
* src/xselect.c (x_get_local_selection): Respect new variable.
(syms_of_xselect): New variable
`x-treat-local-requests-remotely'.
* test/lisp/dnd-tests.el (x-begin-drag, gui-set-selection):
Don't redefine these functions under X.
(dnd-tests-verify-selection-data): Use
`x-get-selection-internal' under X.
(dnd-tests-extract-selection-data): New function.
(dnd-tests-begin-text-drag): Update accordingly.
(dnd-tests-begin-file-drag, dnd-tests-begin-drag-files):
Temporarily skip these tests under X.
| -rw-r--r-- | src/xselect.c | 13 | ||||
| -rw-r--r-- | test/lisp/dnd-tests.el | 140 |
2 files changed, 99 insertions, 54 deletions
diff --git a/src/xselect.c b/src/xselect.c index 40b6571e0ad..a234c7188f3 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -353,7 +353,10 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type, | |||
| 353 | 353 | ||
| 354 | if (!NILP (handler_fn)) | 354 | if (!NILP (handler_fn)) |
| 355 | value = call3 (handler_fn, selection_symbol, | 355 | value = call3 (handler_fn, selection_symbol, |
| 356 | (local_request ? Qnil : target_type), | 356 | ((local_request |
| 357 | && NILP (Vx_treat_local_requests_remotely)) | ||
| 358 | ? Qnil | ||
| 359 | : target_type), | ||
| 357 | tem); | 360 | tem); |
| 358 | else | 361 | else |
| 359 | value = Qnil; | 362 | value = Qnil; |
| @@ -2798,6 +2801,14 @@ A value of 0 means wait as long as necessary. This is initialized from the | |||
| 2798 | \"*selectionTimeout\" resource. */); | 2801 | \"*selectionTimeout\" resource. */); |
| 2799 | x_selection_timeout = 0; | 2802 | x_selection_timeout = 0; |
| 2800 | 2803 | ||
| 2804 | DEFVAR_LISP ("x-treat-local-requests-remotely", Vx_treat_local_requests_remotely, | ||
| 2805 | doc: /* Whether to treat local selection requests as remote ones. | ||
| 2806 | |||
| 2807 | If non-nil, selection converters for string types (`STRING', | ||
| 2808 | `UTF8_STRING', `COMPOUND_TEXT', etc) will encode the strings, even | ||
| 2809 | when Emacs itself is converting the selection. */); | ||
| 2810 | Vx_treat_local_requests_remotely = Qnil; | ||
| 2811 | |||
| 2801 | /* QPRIMARY is defined in keyboard.c. */ | 2812 | /* QPRIMARY is defined in keyboard.c. */ |
| 2802 | DEFSYM (QSECONDARY, "SECONDARY"); | 2813 | DEFSYM (QSECONDARY, "SECONDARY"); |
| 2803 | DEFSYM (QSTRING, "STRING"); | 2814 | DEFSYM (QSTRING, "STRING"); |
diff --git a/test/lisp/dnd-tests.el b/test/lisp/dnd-tests.el index 1e5b1f823fb..c7e537e53f9 100644 --- a/test/lisp/dnd-tests.el +++ b/test/lisp/dnd-tests.el | |||
| @@ -22,7 +22,9 @@ | |||
| 22 | ;; Tests for stuff in dnd.el that doesn't require a window system. | 22 | ;; Tests for stuff in dnd.el that doesn't require a window system. |
| 23 | 23 | ||
| 24 | ;; The drag API tests only check the behavior of the simplified drag | 24 | ;; The drag API tests only check the behavior of the simplified drag |
| 25 | ;; APIs in dnd.el. Actual drags are not performed. | 25 | ;; APIs in dnd.el. Actual drags are not performed during the |
| 26 | ;; automated testing process (make check), but some of the tests can | ||
| 27 | ;; also be run under X. | ||
| 26 | 28 | ||
| 27 | ;;; Code: | 29 | ;;; Code: |
| 28 | 30 | ||
| @@ -35,51 +37,59 @@ | |||
| 35 | (defvar dnd-tests-selection-table nil | 37 | (defvar dnd-tests-selection-table nil |
| 36 | "Alist of selection names to their values.") | 38 | "Alist of selection names to their values.") |
| 37 | 39 | ||
| 38 | ;; Substitute for x-begin-drag, which isn't present on all systems. | 40 | (defvar x-treat-local-requests-remotely) |
| 39 | (defalias 'x-begin-drag | ||
| 40 | (lambda (_targets &optional action frame &rest _) | ||
| 41 | ;; Verify that frame is either nil or a valid frame. | ||
| 42 | (when (and frame (not (frame-live-p frame))) | ||
| 43 | (signal 'wrong-type-argument frame)) | ||
| 44 | ;; Verify that the action is valid and pretend the drag succeeded | ||
| 45 | ;; (by returning the action). | ||
| 46 | (cl-ecase action | ||
| 47 | ('XdndActionCopy action) | ||
| 48 | ('XdndActionMove action) | ||
| 49 | ('XdndActionLink action) | ||
| 50 | ;; These two are not technically valid, but x-begin-drag accepts | ||
| 51 | ;; them anyway. | ||
| 52 | ('XdndActionPrivate action) | ||
| 53 | ('XdndActionAsk 'XdndActionPrivate)))) | ||
| 54 | 41 | ||
| 55 | ;; This doesn't work during tests. | 42 | ;; Define some replacements for functions used by the drag-and-drop |
| 56 | (defalias 'gui-set-selection | 43 | ;; code on X when running under something else. |
| 57 | (lambda (type data) | 44 | (unless (eq window-system 'x) |
| 58 | (or (gui--valid-simple-selection-p data) | 45 | ;; Substitute for x-begin-drag, which isn't present on all systems. |
| 59 | (and (vectorp data) | 46 | (defalias 'x-begin-drag |
| 60 | (let ((valid t)) | 47 | (lambda (_targets &optional action frame &rest _) |
| 61 | (dotimes (i (length data)) | 48 | ;; Verify that frame is either nil or a valid frame. |
| 62 | (or (gui--valid-simple-selection-p (aref data i)) | 49 | (when (and frame (not (frame-live-p frame))) |
| 63 | (setq valid nil))) | 50 | (signal 'wrong-type-argument frame)) |
| 64 | valid)) | 51 | ;; Verify that the action is valid and pretend the drag succeeded |
| 65 | (signal 'error (list "invalid selection" data))) | 52 | ;; (by returning the action). |
| 66 | (setf (alist-get type dnd-tests-selection-table) data))) | 53 | (cl-ecase action |
| 54 | ('XdndActionCopy action) | ||
| 55 | ('XdndActionMove action) | ||
| 56 | ('XdndActionLink action) | ||
| 57 | ;; These two are not technically valid, but x-begin-drag accepts | ||
| 58 | ;; them anyway. | ||
| 59 | ('XdndActionPrivate action) | ||
| 60 | ('XdndActionAsk 'XdndActionPrivate)))) | ||
| 61 | |||
| 62 | ;; This doesn't work during tests. | ||
| 63 | (defalias 'gui-set-selection | ||
| 64 | (lambda (type data) | ||
| 65 | (or (gui--valid-simple-selection-p data) | ||
| 66 | (and (vectorp data) | ||
| 67 | (let ((valid t)) | ||
| 68 | (dotimes (i (length data)) | ||
| 69 | (or (gui--valid-simple-selection-p (aref data i)) | ||
| 70 | (setq valid nil))) | ||
| 71 | valid)) | ||
| 72 | (signal 'error (list "invalid selection" data))) | ||
| 73 | (setf (alist-get type dnd-tests-selection-table) data)))) | ||
| 67 | 74 | ||
| 68 | (defun dnd-tests-verify-selection-data (type) | 75 | (defun dnd-tests-verify-selection-data (type) |
| 69 | "Return the data of the drag-and-drop selection converted to TYPE." | 76 | "Return the data of the drag-and-drop selection converted to TYPE." |
| 70 | (let* ((basic-value (cdr (assq 'XdndSelection | 77 | (if (eq window-system 'x) |
| 71 | dnd-tests-selection-table))) | 78 | (let ((x-treat-local-requests-remotely t)) |
| 72 | (local-value (if (stringp basic-value) | 79 | (x-get-selection-internal 'XdndSelection type)) |
| 73 | (or (get-text-property 0 type basic-value) | 80 | (let* ((basic-value (cdr (assq 'XdndSelection |
| 74 | basic-value) | 81 | dnd-tests-selection-table))) |
| 75 | basic-value)) | 82 | (local-value (if (stringp basic-value) |
| 76 | (converter-list (cdr (assq type selection-converter-alist))) | 83 | (or (get-text-property 0 type basic-value) |
| 77 | (converter (if (consp converter-list) | 84 | basic-value) |
| 78 | (cdr converter-list) | 85 | basic-value)) |
| 79 | converter-list))) | 86 | (converter-list (cdr (assq type selection-converter-alist))) |
| 80 | (if (and local-value converter) | 87 | (converter (if (consp converter-list) |
| 81 | (funcall converter 'XdndSelection type local-value) | 88 | (cdr converter-list) |
| 82 | (error "No selection converter or local value: %s" type)))) | 89 | converter-list))) |
| 90 | (if (and local-value converter) | ||
| 91 | (funcall converter 'XdndSelection type local-value) | ||
| 92 | (error "No selection converter or local value: %s" type))))) | ||
| 83 | 93 | ||
| 84 | (defun dnd-tests-remote-accessible-p () | 94 | (defun dnd-tests-remote-accessible-p () |
| 85 | "Return if a test involving remote files can proceed." | 95 | "Return if a test involving remote files can proceed." |
| @@ -119,7 +129,26 @@ Return a list of its hostname, real path, and local path." | |||
| 119 | (+ beg 1 | 129 | (+ beg 1 |
| 120 | (string-to-number (match-string 5 netfile))))))))) | 130 | (string-to-number (match-string 5 netfile))))))))) |
| 121 | 131 | ||
| 132 | (defun dnd-tests-extract-selection-data (selection expect-cons) | ||
| 133 | "Return the selection data in SELECTION. | ||
| 134 | SELECTION can either be the value of `gui-get-selection', or the | ||
| 135 | return value of a selection converter. | ||
| 136 | |||
| 137 | If EXPECT-CONS, then expect SELECTION to be a cons (when not | ||
| 138 | running under X). | ||
| 139 | |||
| 140 | This function only tries to handle strings." | ||
| 141 | (when (and expect-cons (not (eq window-system 'x))) | ||
| 142 | (should (and (consp selection) | ||
| 143 | (stringp (cdr selection))))) | ||
| 144 | (if (stringp selection) | ||
| 145 | selection | ||
| 146 | (cdr selection))) | ||
| 147 | |||
| 122 | (ert-deftest dnd-tests-begin-text-drag () | 148 | (ert-deftest dnd-tests-begin-text-drag () |
| 149 | ;; When running this test under X, please make sure to drop onto a | ||
| 150 | ;; program with reasonably correct behavior, such as dtpad, gedit, | ||
| 151 | ;; or Mozilla. | ||
| 123 | ;; ASCII Latin-1 UTF-8 | 152 | ;; ASCII Latin-1 UTF-8 |
| 124 | (let ((test-text "hello, everyone! sæl öllsömul! всем привет")) | 153 | (let ((test-text "hello, everyone! sæl öllsömul! всем привет")) |
| 125 | ;; Verify that dragging works. | 154 | ;; Verify that dragging works. |
| @@ -128,26 +157,29 @@ Return a list of its hostname, real path, and local path." | |||
| 128 | ;; Verify that the important data types are converted correctly. | 157 | ;; Verify that the important data types are converted correctly. |
| 129 | (let ((string-data (dnd-tests-verify-selection-data 'STRING))) | 158 | (let ((string-data (dnd-tests-verify-selection-data 'STRING))) |
| 130 | ;; Check that the Latin-1 target is converted correctly. | 159 | ;; Check that the Latin-1 target is converted correctly. |
| 131 | (should (equal (cdr string-data) | 160 | (should (equal (dnd-tests-extract-selection-data string-data t) |
| 132 | (encode-coding-string test-text | 161 | (encode-coding-string test-text |
| 133 | 'iso-8859-1)))) | 162 | 'iso-8859-1)))) |
| 134 | ;; And that UTF8_STRING and the Xdnd UTF8 string are as well. | 163 | ;; And that UTF8_STRING and the Xdnd UTF8 string are as well. |
| 135 | (let ((string-data (dnd-tests-verify-selection-data | 164 | (let* ((string-data (dnd-tests-verify-selection-data |
| 136 | 'UTF8_STRING)) | 165 | 'UTF8_STRING)) |
| 137 | (string-data-1 (cdr (dnd-tests-verify-selection-data | 166 | (string-data-1 (dnd-tests-verify-selection-data |
| 138 | 'text/plain\;charset=utf-8)))) | 167 | 'text/plain\;charset=utf-8)) |
| 139 | (should (and (stringp (cdr string-data)) | 168 | (extracted-1 (dnd-tests-extract-selection-data string-data-1 t)) |
| 140 | (stringp string-data-1))) | 169 | (extracted (dnd-tests-extract-selection-data string-data t))) |
| 141 | (should (equal (cdr string-data) string-data-1))) | 170 | (should (and (stringp extracted) (stringp extracted-1))) |
| 171 | (should (equal extracted extracted))) | ||
| 142 | ;; Now check text/plain. | 172 | ;; Now check text/plain. |
| 143 | (let ((string-data (dnd-tests-verify-selection-data | 173 | (let ((string-data (dnd-tests-verify-selection-data |
| 144 | 'text/plain))) | 174 | 'text/plain))) |
| 145 | (should (equal (cdr string-data) | 175 | (should (equal (dnd-tests-extract-selection-data string-data t) |
| 146 | (encode-coding-string test-text 'ascii)))))) | 176 | (encode-coding-string test-text 'ascii)))))) |
| 147 | 177 | ||
| 148 | (ert-deftest dnd-tests-begin-file-drag () | 178 | (ert-deftest dnd-tests-begin-file-drag () |
| 149 | ;; These tests also involve handling remote file names. | 179 | ;; These tests also involve handling remote file names. |
| 150 | (skip-unless (dnd-tests-remote-accessible-p)) | 180 | (skip-unless (and (dnd-tests-remote-accessible-p) |
| 181 | ;; TODO: make these tests work under X. | ||
| 182 | (not (eq window-system 'x)))) | ||
| 151 | (let ((normal-temp-file (expand-file-name (make-temp-name "dnd-test") | 183 | (let ((normal-temp-file (expand-file-name (make-temp-name "dnd-test") |
| 152 | temporary-file-directory)) | 184 | temporary-file-directory)) |
| 153 | (remote-temp-file (dnd-tests-make-temp-name))) | 185 | (remote-temp-file (dnd-tests-make-temp-name))) |
| @@ -210,7 +242,9 @@ Return a list of its hostname, real path, and local path." | |||
| 210 | (delete-file remote-temp-file)))) | 242 | (delete-file remote-temp-file)))) |
| 211 | 243 | ||
| 212 | (ert-deftest dnd-tests-begin-drag-files () | 244 | (ert-deftest dnd-tests-begin-drag-files () |
| 213 | (skip-unless (dnd-tests-remote-accessible-p)) | 245 | (skip-unless (and (dnd-tests-remote-accessible-p) |
| 246 | ;; TODO: make these tests work under X. | ||
| 247 | (not (eq window-system 'x)))) | ||
| 214 | (let ((normal-temp-file (expand-file-name (make-temp-name "dnd-test") | 248 | (let ((normal-temp-file (expand-file-name (make-temp-name "dnd-test") |
| 215 | temporary-file-directory)) | 249 | temporary-file-directory)) |
| 216 | (normal-temp-file-1 (expand-file-name (make-temp-name "dnd-test") | 250 | (normal-temp-file-1 (expand-file-name (make-temp-name "dnd-test") |