aboutsummaryrefslogtreecommitdiff
path: root/tests/test-ai-term--live-count.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-24 06:43:45 -0400
committerCraig Jennings <c@cjennings.net>2026-06-24 06:43:45 -0400
commit4e1401d1499be3d24df78edd97310d200e719e10 (patch)
tree9fe55839f6ca7741eaf45ac9f286f5b1bef49089 /tests/test-ai-term--live-count.el
parent69931ef2923363e071cb125661ff2f0ed91e890e (diff)
downloaddotemacs-4e1401d1499be3d24df78edd97310d200e719e10.tar.gz
dotemacs-4e1401d1499be3d24df78edd97310d200e719e10.zip
feat(ai-term): wrap-teardown + shutdown entry points for rulesets
Add the three headless functions the rulesets wrap-it-up workflow calls via emacsclient -e, since this module owns the aiv- session naming, the agent buffer, and the geometry restore. cj/ai-term-quit kills a project's tmux session and agent buffer and restores the layout, idempotent and safe when already gone. cj/ai-term-live-count returns the integer count of live aiv- sessions for the shutdown safety gate. cj/ai-term-shutdown-countdown re-checks that gate, then runs an abort-able run-at-time countdown in the echo area and, uncancelled, runs the shutdown command (a defcustom so tests stub it). Reuses the existing kill/close helpers. 13 ERT tests cover the live-count parsing, the quit kill-and-idempotency, and the gate-abort/cancel/tick logic; the tmux and shutdown side effects are manual. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
Diffstat (limited to 'tests/test-ai-term--live-count.el')
-rw-r--r--tests/test-ai-term--live-count.el60
1 files changed, 60 insertions, 0 deletions
diff --git a/tests/test-ai-term--live-count.el b/tests/test-ai-term--live-count.el
new file mode 100644
index 000000000..1432599cc
--- /dev/null
+++ b/tests/test-ai-term--live-count.el
@@ -0,0 +1,60 @@
+;;; test-ai-term--live-count.el --- Tests for cj/ai-term-live-count -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; The shutdown safety gate: the integer count of live AI-term (aiv-*) tmux
+;; sessions, read by the rulesets wrap-it-up workflow via emacsclient -e. No
+;; server / no sessions is 0, not an error.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'ai-term)
+
+(defmacro test-ai-term-live-count--with-tmux (exit-code output &rest body)
+ "Run BODY with `process-file' mocked to a tmux list-sessions response.
+EXIT-CODE is returned (or the symbol `error' to signal); OUTPUT is written to
+the stdout destination buffer."
+ (declare (indent 2))
+ `(cl-letf (((symbol-function 'process-file)
+ (lambda (_program _infile destination _display &rest _args)
+ (when (eq ,exit-code 'error) (error "tmux: command not found"))
+ (let ((buffer (cond ((eq destination t) (current-buffer))
+ ((bufferp destination) destination)
+ ((consp destination)
+ (and (eq (car destination) t) (current-buffer))))))
+ (when (bufferp buffer)
+ (with-current-buffer buffer (insert ,output))))
+ ,exit-code)))
+ (let ((cj/ai-term-tmux-session-prefix "aiv-"))
+ ,@body)))
+
+(ert-deftest test-ai-term-live-count-counts-matching-sessions ()
+ "Normal: two aiv-* sessions among others count as 2."
+ (test-ai-term-live-count--with-tmux 0 "aiv-foo\nrandom\naiv-bar\n"
+ (should (= (cj/ai-term-live-count) 2))))
+
+(ert-deftest test-ai-term-live-count-single-session ()
+ "Boundary: a sole aiv-* session counts as 1."
+ (test-ai-term-live-count--with-tmux 0 "aiv-only\nother\n"
+ (should (= (cj/ai-term-live-count) 1))))
+
+(ert-deftest test-ai-term-live-count-no-matching-sessions ()
+ "Boundary: a running server with no aiv-* sessions is 0."
+ (test-ai-term-live-count--with-tmux 0 "other-a\nother-b\n"
+ (should (= (cj/ai-term-live-count) 0))))
+
+(ert-deftest test-ai-term-live-count-no-server ()
+ "Error: tmux exits non-zero (no server) -> 0, not a signal."
+ (test-ai-term-live-count--with-tmux 1 "no server running\n"
+ (should (= (cj/ai-term-live-count) 0))))
+
+(ert-deftest test-ai-term-live-count-tmux-missing ()
+ "Error: tmux not installed -> 0."
+ (test-ai-term-live-count--with-tmux 'error ""
+ (should (= (cj/ai-term-live-count) 0))))
+
+(provide 'test-ai-term--live-count)
+;;; test-ai-term--live-count.el ends here