diff options
| author | João Távora | 2026-01-10 22:47:23 +0000 |
|---|---|---|
| committer | João Távora | 2026-01-11 03:42:01 +0000 |
| commit | 189e39c52a08276bf1521bbe507e0b87ae90c2dc (patch) | |
| tree | 2fc1f4df8c4afde73fff4fb449646d360caf845a | |
| parent | fefd6526e268b8cf7c0a65bc6aaa91d2b83f123f (diff) | |
| download | emacs-189e39c52a08276bf1521bbe507e0b87ae90c2dc.tar.gz emacs-189e39c52a08276bf1521bbe507e0b87ae90c2dc.zip | |
Eglot: improve automated test machinery
* test/lisp/progmodes/eglot-tests.el
(eglot--wait-for): Fix thinkos and improve.
(eglot--tests-connect): Take TIMEOUT and SERVER kwargs.
(eglot-test-eclipse-connect)
(eglot-test-slow-sync-connection-wait)
(eglot-test-slow-sync-connection-intime): Update
eglot--tests-connect call.
| -rw-r--r-- | test/lisp/progmodes/eglot-tests.el | 81 |
1 files changed, 46 insertions, 35 deletions
diff --git a/test/lisp/progmodes/eglot-tests.el b/test/lisp/progmodes/eglot-tests.el index ac6fd5174bb..0062645ea37 100644 --- a/test/lisp/progmodes/eglot-tests.el +++ b/test/lisp/progmodes/eglot-tests.el | |||
| @@ -238,39 +238,47 @@ directory hierarchy." | |||
| 238 | ,@body) | 238 | ,@body) |
| 239 | (remove-hook 'jsonrpc-event-hook #',log-event-hook-sym)))))) | 239 | (remove-hook 'jsonrpc-event-hook #',log-event-hook-sym)))))) |
| 240 | 240 | ||
| 241 | (cl-defmacro eglot--wait-for ((events-sym &optional (timeout 1) message) args &body body) | 241 | (cl-defmacro eglot--wait-for ((events-sym &optional (timeout 1) message) |
| 242 | args &body body) | ||
| 242 | (declare (indent 2) (debug (sexp sexp sexp &rest form))) | 243 | (declare (indent 2) (debug (sexp sexp sexp &rest form))) |
| 243 | `(eglot--with-timeout '(,timeout ,(or message | 244 | `(eglot--with-timeout '(,timeout |
| 244 | (format "waiting for:\n%s" (pp-to-string body)))) | 245 | ,(or message |
| 246 | (format "waiting for:\n%s" (pp-to-string body)))) | ||
| 245 | (eglot--test-message "waiting for `%s'" (with-output-to-string | 247 | (eglot--test-message "waiting for `%s'" (with-output-to-string |
| 246 | (mapc #'princ ',body))) | 248 | (mapc #'princ ',body))) |
| 247 | (let ((events | 249 | (let ((probe |
| 248 | (cl-loop thereis (cl-loop for json in ,events-sym | 250 | (cl-loop |
| 249 | for method = (plist-get json :method) | 251 | thereis |
| 250 | when (keywordp method) | 252 | (cl-loop for (json . tail) on ,events-sym |
| 251 | do (plist-put json :method | 253 | for method = (plist-get json :method) |
| 252 | (substring | 254 | when (keywordp method) |
| 253 | (symbol-name method) | 255 | do (plist-put |
| 254 | 1)) | 256 | json :method (substring (symbol-name method) 1)) |
| 255 | when (funcall | 257 | when (funcall (jsonrpc-lambda ,args ,@body) json) |
| 256 | (jsonrpc-lambda ,args ,@body) json) | 258 | return json |
| 257 | return (cons json before) | 259 | do |
| 258 | collect json into before) | 260 | (unless |
| 259 | for i from 0 | 261 | ;; $/progress is *truly* uninteresting and spammy |
| 260 | when (zerop (mod i 5)) | 262 | (and (string-match "$/progress" (format "%s" method))) |
| 261 | ;; do (eglot--test-message "still struggling to find in %s" | 263 | (eglot--test-message |
| 262 | ;; ,events-sym) | 264 | "skip uninteresting event %s[%s]" |
| 263 | do | 265 | (plist-get json :method) |
| 264 | ;; `read-event' is essential to have the file | 266 | (plist-get json :id))) |
| 265 | ;; watchers come through. | 267 | finally (setq ,events-sym tail)) |
| 266 | (cond ((fboundp 'flush-standard-output) | 268 | for i from 0 |
| 267 | (read-event nil nil 0.1) (princ ".") | 269 | when (zerop (mod i 5)) |
| 268 | (flush-standard-output)) | 270 | ;; do (eglot--test-message "still struggling to find in %s" |
| 269 | (t | 271 | ;; ,events-sym) |
| 270 | (read-event "." nil 0.1))) | 272 | do |
| 271 | (accept-process-output nil 0.1)))) | 273 | ;; `read-event' is essential to have the file |
| 272 | (setq ,events-sym (cdr events)) | 274 | ;; watchers come through. |
| 273 | (cl-destructuring-bind (&key method id &allow-other-keys) (car events) | 275 | (cond ((fboundp 'flush-standard-output) |
| 276 | (read-event nil nil 0.1) (princ ".") | ||
| 277 | (flush-standard-output)) | ||
| 278 | (t | ||
| 279 | (read-event "." nil 0.1))) | ||
| 280 | (accept-process-output nil 0.1)))) | ||
| 281 | (cl-destructuring-bind (&key method id &allow-other-keys) probe | ||
| 274 | (eglot--test-message "detected: %s" | 282 | (eglot--test-message "detected: %s" |
| 275 | (or method (and id (format "id=%s" id)))))))) | 283 | (or method (and id (format "id=%s" id)))))))) |
| 276 | 284 | ||
| @@ -286,10 +294,13 @@ directory hierarchy." | |||
| 286 | (define-derived-mode typescript-mode prog-mode "TypeScript") | 294 | (define-derived-mode typescript-mode prog-mode "TypeScript") |
| 287 | (add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-mode))) | 295 | (add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-mode))) |
| 288 | 296 | ||
| 289 | (defun eglot--tests-connect (&optional timeout) | 297 | (cl-defun eglot--tests-connect (&key timeout server) |
| 290 | (let* ((timeout (or timeout 10)) | 298 | (let* ((timeout (or timeout 10)) |
| 291 | (eglot-sync-connect t) | 299 | (eglot-sync-connect t) |
| 292 | (eglot-connect-timeout timeout)) | 300 | (eglot-connect-timeout timeout) |
| 301 | (eglot-server-programs | ||
| 302 | (if server `((,major-mode . ,(string-split server))) | ||
| 303 | eglot-server-programs))) | ||
| 293 | (apply #'eglot--connect (eglot--guess-contact)))) | 304 | (apply #'eglot--connect (eglot--guess-contact)))) |
| 294 | 305 | ||
| 295 | (defun eglot--simulate-key-event (char) | 306 | (defun eglot--simulate-key-event (char) |
| @@ -317,7 +328,7 @@ directory hierarchy." | |||
| 317 | (with-current-buffer | 328 | (with-current-buffer |
| 318 | (eglot--find-file-noselect "project/src/main/java/foo/Main.java") | 329 | (eglot--find-file-noselect "project/src/main/java/foo/Main.java") |
| 319 | (eglot--sniffing (:server-notifications s-notifs) | 330 | (eglot--sniffing (:server-notifications s-notifs) |
| 320 | (should (eglot--tests-connect 20)) | 331 | (should (eglot--tests-connect :timeout 20)) |
| 321 | (eglot--wait-for (s-notifs 10) | 332 | (eglot--wait-for (s-notifs 10) |
| 322 | (&key _id method &allow-other-keys) | 333 | (&key _id method &allow-other-keys) |
| 323 | (string= method "language/status")))))) | 334 | (string= method "language/status")))))) |
| @@ -1069,7 +1080,7 @@ int main() { | |||
| 1069 | (let ((eglot-sync-connect t) | 1080 | (let ((eglot-sync-connect t) |
| 1070 | (eglot-server-programs | 1081 | (eglot-server-programs |
| 1071 | `((c-mode . ("sh" "-c" "sleep 1 && clangd"))))) | 1082 | `((c-mode . ("sh" "-c" "sleep 1 && clangd"))))) |
| 1072 | (should (eglot--tests-connect 3)))))) | 1083 | (should (eglot--tests-connect :timeout 3)))))) |
| 1073 | 1084 | ||
| 1074 | (ert-deftest eglot-test-slow-sync-connection-intime () | 1085 | (ert-deftest eglot-test-slow-sync-connection-intime () |
| 1075 | "Connect synchronously with `eglot-sync-connect' set to 2." | 1086 | "Connect synchronously with `eglot-sync-connect' set to 2." |
| @@ -1081,7 +1092,7 @@ int main() { | |||
| 1081 | (let ((eglot-sync-connect 2) | 1092 | (let ((eglot-sync-connect 2) |
| 1082 | (eglot-server-programs | 1093 | (eglot-server-programs |
| 1083 | `((c-mode . ("sh" "-c" "sleep 1 && clangd"))))) | 1094 | `((c-mode . ("sh" "-c" "sleep 1 && clangd"))))) |
| 1084 | (should (eglot--tests-connect 3)))))) | 1095 | (should (eglot--tests-connect :timeout 3)))))) |
| 1085 | 1096 | ||
| 1086 | (ert-deftest eglot-test-slow-async-connection () | 1097 | (ert-deftest eglot-test-slow-async-connection () |
| 1087 | "Connect asynchronously with `eglot-sync-connect' set to 2." | 1098 | "Connect asynchronously with `eglot-sync-connect' set to 2." |