diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test-ai-vterm--close.el | 86 | ||||
| -rw-r--r-- | tests/test-ai-vterm--f9-in-vterm.el | 27 |
2 files changed, 93 insertions, 20 deletions
diff --git a/tests/test-ai-vterm--close.el b/tests/test-ai-vterm--close.el new file mode 100644 index 00000000..eb89bcc2 --- /dev/null +++ b/tests/test-ai-vterm--close.el @@ -0,0 +1,86 @@ +;;; test-ai-vterm--close.el --- Tests for graceful agent close -*- lexical-binding: t; -*- + +;;; Commentary: +;; `cj/ai-vterm-close' tears an agent down gracefully: kill its tmux +;; session (stopping the agent process), kill the vterm buffer, and +;; remove its window. These tests cover the pure pieces -- the +;; tmux-kill helper, the per-buffer teardown, and the target selection -- +;; with `process-file' and the prompt mocked at the boundary. + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'ai-vterm) + +(ert-deftest test-ai-vterm--kill-tmux-session-runs-kill-session () + "Normal: invokes `tmux kill-session -t <session>'." + (let (captured) + (cl-letf (((symbol-function 'process-file) + (lambda (program &rest args) + (setq captured (cons program args)) + 0))) + (cj/--ai-vterm-kill-tmux-session "aiv-foo")) + (should (equal (car captured) "tmux")) + (should (member "kill-session" captured)) + (should (member "-t" captured)) + (should (member "aiv-foo" captured)))) + +(ert-deftest test-ai-vterm--kill-tmux-session-swallows-error () + "Error: returns nil when tmux is unavailable (process-file signals)." + (cl-letf (((symbol-function 'process-file) + (lambda (&rest _) (error "no tmux")))) + (should (null (cj/--ai-vterm-kill-tmux-session "aiv-foo"))))) + +(ert-deftest test-ai-vterm--close-buffer-kills-session-and-buffer () + "Normal: derives the session from default-directory, kills it and the buffer." + (let ((buf (get-buffer-create "agent [foo]")) + captured-session) + (with-current-buffer buf (setq-local default-directory "/tmp/foo/")) + (cl-letf (((symbol-function 'cj/--ai-vterm-kill-tmux-session) + (lambda (s) (setq captured-session s) 0))) + (cj/--ai-vterm-close-buffer buf)) + (should (equal captured-session "aiv-foo")) + (should-not (buffer-live-p buf)))) + +(ert-deftest test-ai-vterm--close-buffer-noop-on-non-agent () + "Boundary: does nothing for a buffer that is not an agent buffer." + (let ((buf (get-buffer-create "*not-an-agent*")) + (called nil)) + (unwind-protect + (progn + (cl-letf (((symbol-function 'cj/--ai-vterm-kill-tmux-session) + (lambda (_s) (setq called t) 0))) + (cj/--ai-vterm-close-buffer buf)) + (should-not called) + (should (buffer-live-p buf))) + (when (buffer-live-p buf) (kill-buffer buf))))) + +(ert-deftest test-ai-vterm--close-target-current-agent-buffer () + "Normal: returns the current buffer when it is an agent buffer." + (let ((buf (get-buffer-create "agent [cur]"))) + (unwind-protect + (with-current-buffer buf + (should (eq (cj/--ai-vterm-close-target) buf))) + (kill-buffer buf)))) + +(ert-deftest test-ai-vterm--close-target-sole-agent () + "Normal: returns the only live agent buffer when current isn't an agent." + (let ((buf (get-buffer-create "agent [only]"))) + (unwind-protect + (with-temp-buffer + (cl-letf (((symbol-function 'cj/--ai-vterm-agent-buffers) + (lambda () (list buf)))) + (should (eq (cj/--ai-vterm-close-target) buf)))) + (kill-buffer buf)))) + +(ert-deftest test-ai-vterm--close-target-none-returns-nil () + "Boundary: nil when current buffer isn't an agent and none are alive." + (with-temp-buffer + (cl-letf (((symbol-function 'cj/--ai-vterm-agent-buffers) (lambda () nil))) + (should (null (cj/--ai-vterm-close-target)))))) + +(provide 'test-ai-vterm--close) +;;; test-ai-vterm--close.el ends here diff --git a/tests/test-ai-vterm--f9-in-vterm.el b/tests/test-ai-vterm--f9-in-vterm.el index 1901127e..ec67ac9b 100644 --- a/tests/test-ai-vterm--f9-in-vterm.el +++ b/tests/test-ai-vterm--f9-in-vterm.el @@ -24,11 +24,11 @@ (should (eq (keymap-lookup vterm-mode-map "<f9>") #'cj/ai-vterm))) (ert-deftest test-ai-vterm-f9-family-bound-in-vterm-mode-map () - "Normal: the C-/M- F9 variants are bound in `vterm-mode-map' too. -`M-<f9>' toggles gptel's *AI-Assistant* window (rebound here from -the old `cj/ai-vterm-pick-buffer' command, which was removed)." + "Normal: the C-/M-/C-S- F9 variants are bound in `vterm-mode-map' too. +`M-<f9>' and `C-S-<f9>' both close an agent via `cj/ai-vterm-close'." (should (eq (keymap-lookup vterm-mode-map "C-<f9>") #'cj/ai-vterm-pick-project)) - (should (eq (keymap-lookup vterm-mode-map "M-<f9>") #'cj/toggle-gptel))) + (should (eq (keymap-lookup vterm-mode-map "M-<f9>") #'cj/ai-vterm-close)) + (should (eq (keymap-lookup vterm-mode-map "C-S-<f9>") #'cj/ai-vterm-close))) (ert-deftest test-ai-vterm-f9-not-self-insert-in-vterm () "Boundary: vterm's default <f9> -> `vterm--self-insert' was overridden." @@ -37,24 +37,11 @@ the old `cj/ai-vterm-pick-buffer' command, which was removed)." (ert-deftest test-ai-vterm-f9-still-bound-globally () "Normal: the global F9 family bindings are intact. `<f9>' toggles the ai-vterm agent window; `C-<f9>' picks a project -agent; `M-<f9>' toggles gptel's *AI-Assistant* window (rebound from -the retired `cj/ai-vterm-pick-buffer')." +agent; `M-<f9>' and `C-S-<f9>' close an agent via `cj/ai-vterm-close'." (should (eq (lookup-key (current-global-map) (kbd "<f9>")) #'cj/ai-vterm)) (should (eq (lookup-key (current-global-map) (kbd "C-<f9>")) #'cj/ai-vterm-pick-project)) - (should (eq (lookup-key (current-global-map) (kbd "M-<f9>")) #'cj/toggle-gptel))) - -(ert-deftest test-ai-vterm-toggle-gptel-autoloaded-without-ai-config () - "Regression: loading `ai-vterm.el' must not require `ai-config.el'. -The M-F9 binding targets `cj/toggle-gptel', which lives in -`ai-config.el'. The dependency is declared via `autoload' so that -byte-compiling `ai-vterm.el' does not warn and so that requiring -`ai-vterm' in isolation leaves `cj/toggle-gptel' fboundp as an -autoload sigil pointing at `ai-config'. Without this, ai-vterm -would either need a full `(require 'ai-config)' at load time or -ship a known byte-compile warning." - (should-not (featurep 'ai-config)) - (should (fboundp 'cj/toggle-gptel)) - (should (autoloadp (symbol-function 'cj/toggle-gptel)))) + (should (eq (lookup-key (current-global-map) (kbd "M-<f9>")) #'cj/ai-vterm-close)) + (should (eq (lookup-key (current-global-map) (kbd "C-S-<f9>")) #'cj/ai-vterm-close))) (provide 'test-ai-vterm--f9-in-vterm) ;;; test-ai-vterm--f9-in-vterm.el ends here |
