Skip to content

Commit edd8177

Browse files
committed
[Fix #3645] Show a spinner in the mode line while tests are running
Reuses the existing spinner infrastructure from cider-client.el. The spinner starts when tests are dispatched and stops when results arrive (or on error/not-found).
1 parent b06a9b4 commit edd8177

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### New features
66

7+
- [#3645](https://github.com/clojure-emacs/cider/issues/3645): Show a spinner in the mode line while tests are running.
78
- [#3865](https://github.com/clojure-emacs/cider/pull/3865): Add default session feature to bypass sesman's project-based dispatch (`cider-set-default-session`, `cider-clear-default-session`).
89

910
### Bugs fixed
@@ -12,6 +13,9 @@
1213
### Changes
1314

1415
- Bump the injected nREPL version to 1.6.
16+
### Changes
17+
18+
- Rename `cider-eval-spinner-type`, `cider-show-eval-spinner`, and `cider-eval-spinner-delay` to `cider-spinner-type`, `cider-show-spinner`, and `cider-spinner-delay`. The old names are kept as obsolete aliases.
1519

1620
## 1.21.0 (2026-02-07)
1721

lisp/cider-test.el

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@
6161
:type 'boolean
6262
:package-version '(cider . "0.9.0"))
6363

64+
(defvar cider-test--spinner-buffers nil
65+
"List of buffers where test spinners are active.")
66+
6467
(defvar cider-test--current-repl nil
6568
"Contains the reference to the REPL where the tests were last invoked from.
6669
This is needed for *cider-test-report* navigation
@@ -540,6 +543,26 @@ timing data for the overall run, per-namespace, and per-var respectively."
540543
(current-buffer))))
541544

542545

546+
;;; Test spinner
547+
548+
(defun cider-test-spinner-start (buffer)
549+
"Start a test spinner in BUFFER.
550+
Uses `cider-show-spinner' to decide whether to show it.
551+
Tracks BUFFER for later cleanup by `cider-test-spinner-stop'."
552+
(when (and cider-show-spinner
553+
(buffer-live-p buffer)
554+
(not (memq buffer cider-test--spinner-buffers)))
555+
(cider-spinner-start buffer)
556+
(push buffer cider-test--spinner-buffers)))
557+
558+
(defun cider-test-spinner-stop ()
559+
"Stop all active test spinners."
560+
(dolist (buffer cider-test--spinner-buffers)
561+
(when (buffer-live-p buffer)
562+
(with-current-buffer buffer
563+
(when spinner-current (spinner-stop)))))
564+
(setq cider-test--spinner-buffers nil))
565+
543566
;;; Message echo
544567

545568
(defun cider-test-echo-running (ns &optional test)
@@ -723,6 +746,7 @@ running them."
723746
;; we generate a different message when running individual tests
724747
(cider-test-echo-running ns (car tests))
725748
(cider-test-echo-running ns)))
749+
(cider-test-spinner-start (current-buffer))
726750
(setq cider-test--current-repl conn)
727751
(let* ((retest? (eq :non-passing ns))
728752
(request `("op" ,(cond ((stringp ns) "test")
@@ -747,6 +771,10 @@ running them."
747771
request
748772
(lambda (response)
749773
(nrepl-dbind-response response (summary results status out err elapsed-time ns-elapsed-time var-elapsed-time)
774+
(when (or (member "done" status)
775+
(member "error" status)
776+
(member "namespace-not-found" status))
777+
(cider-test-spinner-stop))
750778
(cond ((member "namespace-not-found" status)
751779
(unless silent
752780
(message "No test namespace: %s" (cider-propertize ns 'ns))))

test/cider-test-tests.el

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
(require 'buttercup)
2929
(require 'cider-test)
30+
(require 'spinner)
3031

3132
;; Please, for each `describe', ensure there's an `it' block, so that its execution is visible in CI.
3233

@@ -41,3 +42,51 @@
4142
(expect (cider-test--string-contains-newline "Hello\\nWorld")
4243
:to-equal
4344
t)))
45+
46+
(describe "cider-test-spinner-start"
47+
(it "starts a spinner in the given buffer when enabled"
48+
(let ((cider-show-spinner t)
49+
(buf (generate-new-buffer " *test-spinner*")))
50+
(unwind-protect
51+
(progn
52+
(cider-test-spinner-start buf)
53+
(expect (buffer-local-value 'spinner-current buf) :to-be-truthy)
54+
(expect cider-test--spinner-buffers :to-contain buf))
55+
(when (buffer-live-p buf)
56+
(with-current-buffer buf
57+
(when spinner-current (spinner-stop)))
58+
(kill-buffer buf))
59+
(setq cider-test--spinner-buffers nil))))
60+
61+
(it "does nothing when cider-show-spinner is nil"
62+
(let ((cider-show-spinner nil)
63+
(buf (generate-new-buffer " *test-spinner*")))
64+
(unwind-protect
65+
(progn
66+
(cider-test-spinner-start buf)
67+
(expect (buffer-local-value 'spinner-current buf) :not :to-be-truthy)
68+
(expect cider-test--spinner-buffers :not :to-contain buf))
69+
(kill-buffer buf)))))
70+
71+
(describe "cider-test-spinner-stop"
72+
(it "stops spinners in all tracked buffers"
73+
(let ((cider-show-spinner t)
74+
(buf1 (generate-new-buffer " *test-spinner-1*"))
75+
(buf2 (generate-new-buffer " *test-spinner-2*")))
76+
(unwind-protect
77+
(progn
78+
(cider-test-spinner-start buf1)
79+
(cider-test-spinner-start buf2)
80+
(expect (spinner--active-p (buffer-local-value 'spinner-current buf1))
81+
:to-be-truthy)
82+
(expect (spinner--active-p (buffer-local-value 'spinner-current buf2))
83+
:to-be-truthy)
84+
(cider-test-spinner-stop)
85+
(expect (spinner--active-p (buffer-local-value 'spinner-current buf1))
86+
:not :to-be-truthy)
87+
(expect (spinner--active-p (buffer-local-value 'spinner-current buf2))
88+
:not :to-be-truthy)
89+
(expect cider-test--spinner-buffers :to-equal nil))
90+
(when (buffer-live-p buf1) (kill-buffer buf1))
91+
(when (buffer-live-p buf2) (kill-buffer buf2))
92+
(setq cider-test--spinner-buffers nil)))))

0 commit comments

Comments
 (0)