aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test-ai-term--active-agent-dirs.el50
-rw-r--r--tests/test-ai-term--collapse-split.el14
-rw-r--r--tests/test-ai-term--next-agent-buffer.el73
-rw-r--r--tests/test-ai-term--next-agent-dir.el48
-rw-r--r--tests/test-ai-term--next-no-agents.el4
5 files changed, 112 insertions, 77 deletions
diff --git a/tests/test-ai-term--active-agent-dirs.el b/tests/test-ai-term--active-agent-dirs.el
new file mode 100644
index 000000000..86e557b42
--- /dev/null
+++ b/tests/test-ai-term--active-agent-dirs.el
@@ -0,0 +1,50 @@
+;;; test-ai-term--active-agent-dirs.el --- Tests for cj/--ai-term-active-agent-dirs -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; The queue `cj/ai-term-next' steps through: project dirs with an active
+;; agent, which is either a live agent buffer (attached) or a live tmux session
+;; with no Emacs buffer (detached). Folding detached sessions in is what lets
+;; the step key reach and attach a session that isn't currently on screen.
+;; Candidates / buffers / sessions are mocked so the enumeration logic is
+;; exercised without a real tmux server.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'ai-term)
+
+(ert-deftest test-ai-term--active-agent-dirs-includes-attached-and-detached ()
+ "Normal: dirs with a live buffer OR a live session are active and sorted by
+name; dirs with neither are excluded."
+ (let ((buf (get-buffer-create (cj/--ai-term-buffer-name "/p/alpha"))))
+ (unwind-protect
+ (cl-letf (((symbol-function 'cj/--ai-term-candidates)
+ (lambda (&rest _) '("/p/alpha" "/p/beta" "/p/gamma" "/p/delta")))
+ ((symbol-function 'cj/--ai-term-agent-buffers)
+ (lambda (&rest _) (list buf)))
+ ((symbol-function 'cj/--ai-term-live-tmux-sessions)
+ (lambda (&rest _) (list (cj/--ai-term-tmux-session-name "/p/gamma")))))
+ ;; alpha attached (buffer), gamma detached (session); beta/delta neither.
+ (should (equal '("/p/alpha" "/p/gamma") (cj/--ai-term-active-agent-dirs))))
+ (kill-buffer buf))))
+
+(ert-deftest test-ai-term--active-agent-dirs-detached-only ()
+ "Normal: a dir with only a live session (no buffer) is included -- the detached case."
+ (cl-letf (((symbol-function 'cj/--ai-term-candidates) (lambda (&rest _) '("/p/solo")))
+ ((symbol-function 'cj/--ai-term-agent-buffers) (lambda (&rest _) nil))
+ ((symbol-function 'cj/--ai-term-live-tmux-sessions)
+ (lambda (&rest _) (list (cj/--ai-term-tmux-session-name "/p/solo")))))
+ (should (equal '("/p/solo") (cj/--ai-term-active-agent-dirs)))))
+
+(ert-deftest test-ai-term--active-agent-dirs-empty-when-none-active ()
+ "Boundary: no live buffers and no sessions -> an empty queue."
+ (cl-letf (((symbol-function 'cj/--ai-term-candidates) (lambda (&rest _) '("/p/a" "/p/b")))
+ ((symbol-function 'cj/--ai-term-agent-buffers) (lambda (&rest _) nil))
+ ((symbol-function 'cj/--ai-term-live-tmux-sessions) (lambda (&rest _) nil)))
+ (should (null (cj/--ai-term-active-agent-dirs)))))
+
+(provide 'test-ai-term--active-agent-dirs)
+;;; test-ai-term--active-agent-dirs.el ends here
diff --git a/tests/test-ai-term--collapse-split.el b/tests/test-ai-term--collapse-split.el
index d7b4ee17f..a09af5598 100644
--- a/tests/test-ai-term--collapse-split.el
+++ b/tests/test-ai-term--collapse-split.el
@@ -59,7 +59,12 @@ different agent (stale quit-restore after slot reuse)."
(agent-a (get-buffer-create "agent [collapse-a]"))
(agent-b (get-buffer-create "agent [collapse-b]"))
(agent-c (get-buffer-create "agent [collapse-c]"))
- (cj/--ai-term-last-was-bury nil))
+ (cj/--ai-term-last-was-bury nil)
+ ;; Isolate the layout-capture globals cj/ai-term writes on toggle-off,
+ ;; so this test doesn't leak last-direction/last-size into others -- the
+ ;; display-rule test splits via display-saved, which reads them.
+ (cj/--ai-term-last-direction nil)
+ (cj/--ai-term-last-size nil))
(unwind-protect
(save-window-excursion
(delete-other-windows)
@@ -89,7 +94,12 @@ to a NON-agent buffer (the working file), never another agent. Before the fix,
(let ((work (get-buffer-create "*test-collapse-sw-work*"))
(agent-a (get-buffer-create "agent [collapse-sw-a]"))
(agent-b (get-buffer-create "agent [collapse-sw-b]"))
- (cj/--ai-term-last-was-bury nil))
+ (cj/--ai-term-last-was-bury nil)
+ ;; Isolate the layout-capture globals cj/ai-term writes on toggle-off,
+ ;; so this test doesn't leak last-direction/last-size into others -- the
+ ;; display-rule test splits via display-saved, which reads them.
+ (cj/--ai-term-last-direction nil)
+ (cj/--ai-term-last-size nil))
(unwind-protect
(save-window-excursion
(delete-other-windows)
diff --git a/tests/test-ai-term--next-agent-buffer.el b/tests/test-ai-term--next-agent-buffer.el
deleted file mode 100644
index 330714a92..000000000
--- a/tests/test-ai-term--next-agent-buffer.el
+++ /dev/null
@@ -1,73 +0,0 @@
-;;; test-ai-term--next-agent-buffer.el --- Tests for cj/--ai-term-next-agent-buffer -*- lexical-binding: t; -*-
-
-;;; Commentary:
-;; The pure decision helper behind `cj/ai-term-next' (s-F9). Given the
-;; current agent buffer and the ordered list of live agent buffers, it
-;; returns the next buffer in the queue, wrapping after the last. A nil
-;; or non-member CURRENT returns the first; an empty list returns nil.
-;; No buffer or window side effects -- list logic only.
-
-;;; Code:
-
-(require 'ert)
-
-(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
-(require 'ai-term)
-
-(ert-deftest test-ai-term--next-agent-buffer-advances-from-first ()
- "Normal: current is the first element -> returns the second."
- (let ((a (get-buffer-create "agent [a]"))
- (b (get-buffer-create "agent [b]"))
- (c (get-buffer-create "agent [c]")))
- (unwind-protect
- (should (eq b (cj/--ai-term-next-agent-buffer a (list a b c))))
- (mapc #'kill-buffer (list a b c)))))
-
-(ert-deftest test-ai-term--next-agent-buffer-advances-from-middle ()
- "Normal: current in the middle -> returns the following element."
- (let ((a (get-buffer-create "agent [a]"))
- (b (get-buffer-create "agent [b]"))
- (c (get-buffer-create "agent [c]")))
- (unwind-protect
- (should (eq c (cj/--ai-term-next-agent-buffer b (list a b c))))
- (mapc #'kill-buffer (list a b c)))))
-
-(ert-deftest test-ai-term--next-agent-buffer-wraps-after-last ()
- "Boundary: current is the last element -> wraps to the first."
- (let ((a (get-buffer-create "agent [a]"))
- (b (get-buffer-create "agent [b]"))
- (c (get-buffer-create "agent [c]")))
- (unwind-protect
- (should (eq a (cj/--ai-term-next-agent-buffer c (list a b c))))
- (mapc #'kill-buffer (list a b c)))))
-
-(ert-deftest test-ai-term--next-agent-buffer-single-element-returns-itself ()
- "Boundary: a one-agent queue wraps current back to itself."
- (let ((a (get-buffer-create "agent [a]")))
- (unwind-protect
- (should (eq a (cj/--ai-term-next-agent-buffer a (list a))))
- (kill-buffer a))))
-
-(ert-deftest test-ai-term--next-agent-buffer-nil-current-returns-first ()
- "Boundary: nil current (no agent displayed) -> returns the first."
- (let ((a (get-buffer-create "agent [a]"))
- (b (get-buffer-create "agent [b]")))
- (unwind-protect
- (should (eq a (cj/--ai-term-next-agent-buffer nil (list a b))))
- (mapc #'kill-buffer (list a b)))))
-
-(ert-deftest test-ai-term--next-agent-buffer-non-member-current-returns-first ()
- "Error: current not in the queue -> returns the first rather than nil."
- (let ((a (get-buffer-create "agent [a]"))
- (b (get-buffer-create "agent [b]"))
- (stray (get-buffer-create "agent [stray]")))
- (unwind-protect
- (should (eq a (cj/--ai-term-next-agent-buffer stray (list a b))))
- (mapc #'kill-buffer (list a b stray)))))
-
-(ert-deftest test-ai-term--next-agent-buffer-empty-queue-returns-nil ()
- "Boundary: an empty queue returns nil (nothing to switch to)."
- (should (null (cj/--ai-term-next-agent-buffer nil '()))))
-
-(provide 'test-ai-term--next-agent-buffer)
-;;; test-ai-term--next-agent-buffer.el ends here
diff --git a/tests/test-ai-term--next-agent-dir.el b/tests/test-ai-term--next-agent-dir.el
new file mode 100644
index 000000000..b5cf1cdf5
--- /dev/null
+++ b/tests/test-ai-term--next-agent-dir.el
@@ -0,0 +1,48 @@
+;;; test-ai-term--next-agent-dir.el --- Tests for cj/--ai-term-next-agent-dir -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; The pure decision helper behind `cj/ai-term-next'. Given the current
+;; active-agent project dir and the ordered list of active-agent dirs, it
+;; returns the next dir in the queue, wrapping after the last. A nil or
+;; non-member CURRENT returns the first; an empty list returns nil. Dirs are
+;; matched with `member' (string equality). No side effects -- list logic only.
+
+;;; Code:
+
+(require 'ert)
+
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'ai-term)
+
+(defconst test-ai-term--dirs '("/p/a" "/p/b" "/p/c"))
+
+(ert-deftest test-ai-term--next-agent-dir-advances-from-first ()
+ "Normal: current is the first element -> returns the second."
+ (should (equal "/p/b" (cj/--ai-term-next-agent-dir "/p/a" test-ai-term--dirs))))
+
+(ert-deftest test-ai-term--next-agent-dir-advances-from-middle ()
+ "Normal: current in the middle -> returns the following element."
+ (should (equal "/p/c" (cj/--ai-term-next-agent-dir "/p/b" test-ai-term--dirs))))
+
+(ert-deftest test-ai-term--next-agent-dir-wraps-after-last ()
+ "Boundary: current is the last element -> wraps to the first."
+ (should (equal "/p/a" (cj/--ai-term-next-agent-dir "/p/c" test-ai-term--dirs))))
+
+(ert-deftest test-ai-term--next-agent-dir-single-element-returns-itself ()
+ "Boundary: a one-agent queue wraps current back to itself."
+ (should (equal "/p/a" (cj/--ai-term-next-agent-dir "/p/a" '("/p/a")))))
+
+(ert-deftest test-ai-term--next-agent-dir-nil-current-returns-first ()
+ "Boundary: nil current (no agent displayed) -> returns the first."
+ (should (equal "/p/a" (cj/--ai-term-next-agent-dir nil '("/p/a" "/p/b")))))
+
+(ert-deftest test-ai-term--next-agent-dir-non-member-current-returns-first ()
+ "Error: current not in the queue -> returns the first rather than nil."
+ (should (equal "/p/a" (cj/--ai-term-next-agent-dir "/p/stray" '("/p/a" "/p/b")))))
+
+(ert-deftest test-ai-term--next-agent-dir-empty-queue-returns-nil ()
+ "Boundary: an empty queue returns nil (nothing to switch to)."
+ (should (null (cj/--ai-term-next-agent-dir nil '()))))
+
+(provide 'test-ai-term--next-agent-dir)
+;;; test-ai-term--next-agent-dir.el ends here
diff --git a/tests/test-ai-term--next-no-agents.el b/tests/test-ai-term--next-no-agents.el
index ef87d71ee..59132df8e 100644
--- a/tests/test-ai-term--next-no-agents.el
+++ b/tests/test-ai-term--next-no-agents.el
@@ -17,7 +17,7 @@
(ert-deftest test-ai-term-next-no-agents-launches-picker ()
"Error: no agents open -> launches the picker instead of erroring."
(let ((picked 0))
- (cl-letf (((symbol-function 'cj/--ai-term-agent-buffers) (lambda (&rest _) nil))
+ (cl-letf (((symbol-function 'cj/--ai-term-active-agent-dirs) (lambda (&rest _) nil))
((symbol-function 'cj/--ai-term-displayed-agent-window) (lambda (&rest _) nil))
((symbol-function 'cj/ai-term-pick-project) (lambda (&rest _) (setq picked (1+ picked)))))
(cj/ai-term-next)
@@ -25,7 +25,7 @@
(ert-deftest test-ai-term-next-no-agents-does-not-signal ()
"Error: no agents open -> returns normally, no user-error raised."
- (cl-letf (((symbol-function 'cj/--ai-term-agent-buffers) (lambda (&rest _) nil))
+ (cl-letf (((symbol-function 'cj/--ai-term-active-agent-dirs) (lambda (&rest _) nil))
((symbol-function 'cj/--ai-term-displayed-agent-window) (lambda (&rest _) nil))
((symbol-function 'cj/ai-term-pick-project) (lambda (&rest _) nil)))
(should (progn (cj/ai-term-next) t))))