diff options
Diffstat (limited to 'tests/test-ai-vterm--show-or-create.el')
| -rw-r--r-- | tests/test-ai-vterm--show-or-create.el | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/tests/test-ai-vterm--show-or-create.el b/tests/test-ai-vterm--show-or-create.el new file mode 100644 index 00000000..28e0faeb --- /dev/null +++ b/tests/test-ai-vterm--show-or-create.el @@ -0,0 +1,119 @@ +;;; test-ai-vterm--show-or-create.el --- Tests for cj/--ai-vterm-show-or-create -*- lexical-binding: t; -*- + +;;; Commentary: +;; Tests the show-or-create branching: +;; +;; - buffer absent -> vterm called, claude command sent +;; - buffer present, live -> vterm not called, buffer displayed +;; - buffer present, dead -> old buffer killed, vterm recreates +;; +;; vterm functions are stubbed so the test does no process spawning. + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'ai-vterm) + +;; vterm isn't loaded in batch -- provide stubs so cl-letf has overrides. +(unless (fboundp 'vterm) + (defun vterm (&optional _name) nil)) +(unless (fboundp 'vterm-send-string) + (defun vterm-send-string (_s &optional _) nil)) +(unless (fboundp 'vterm-send-return) + (defun vterm-send-return () nil)) + +(defmacro test-ai-vterm--with-mock-vterm (vars &rest body) + "Run BODY with vterm + send-string + send-return mocked. + +VARS is a plist of capture variable names: :calls, :strings, :returns, +:default-dir. The test references these names directly inside BODY." + (declare (indent 1) (debug t)) + (let ((calls (plist-get vars :calls)) + (strings (plist-get vars :strings)) + (returns (plist-get vars :returns)) + (ddir (plist-get vars :default-dir))) + `(let ((,calls '()) + (,strings '()) + (,returns 0) + (,ddir nil)) + (cl-letf (((symbol-function 'vterm) + (lambda (&optional name) + (push name ,calls) + (setq ,ddir default-directory) + (with-current-buffer (get-buffer-create name) + (current-buffer)))) + ((symbol-function 'vterm-send-string) + (lambda (s &optional _) (push s ,strings))) + ((symbol-function 'vterm-send-return) + (lambda () (cl-incf ,returns)))) + ,@body)))) + +(defun test-ai-vterm--cleanup (name) + "Kill buffer NAME if it exists." + (when (get-buffer name) + (kill-buffer name))) + +(ert-deftest test-ai-vterm--show-or-create-creates-when-buffer-missing () + "Normal: no existing buffer -> vterm called once, claude cmd sent." + (let ((name "claude [normal-create-test]")) + (test-ai-vterm--cleanup name) + (unwind-protect + (test-ai-vterm--with-mock-vterm (:calls calls :strings strings + :returns returns :default-dir ddir) + (cj/--ai-vterm-show-or-create "/tmp/some-project" name) + (should (equal calls (list name))) + (should (equal strings (list cj/ai-vterm-claude-command))) + (should (= returns 1)) + (should (equal ddir "/tmp/some-project"))) + (test-ai-vterm--cleanup name)))) + +(ert-deftest test-ai-vterm--show-or-create-displays-existing-when-process-live () + "Normal: buffer exists with live process -> vterm not called." + (let ((name "claude [reuse-test]")) + (test-ai-vterm--cleanup name) + (unwind-protect + (let ((buf (get-buffer-create name))) + (cl-letf (((symbol-function 'cj/--ai-vterm-process-live-p) + (lambda (b) (and (eq b buf) t)))) + (test-ai-vterm--with-mock-vterm (:calls calls :strings strings + :returns returns :default-dir _ddir) + (cj/--ai-vterm-show-or-create "/tmp/reuse" name) + (should (null calls)) + (should (null strings)) + (should (= returns 0))))) + (test-ai-vterm--cleanup name)))) + +(ert-deftest test-ai-vterm--show-or-create-recreates-when-process-dead () + "Boundary: buffer exists with dead process -> killed and recreated." + (let ((name "claude [dead-test]")) + (test-ai-vterm--cleanup name) + (unwind-protect + (let ((stale (get-buffer-create name))) + (cl-letf (((symbol-function 'cj/--ai-vterm-process-live-p) + (lambda (_b) nil))) + (test-ai-vterm--with-mock-vterm (:calls calls :strings strings + :returns returns :default-dir _ddir) + (cj/--ai-vterm-show-or-create "/tmp/dead" name) + (should (equal calls (list name))) + (should (equal strings (list cj/ai-vterm-claude-command))) + (should (= returns 1)) + (should-not (buffer-live-p stale))))) + (test-ai-vterm--cleanup name)))) + +(ert-deftest test-ai-vterm--show-or-create-returns-buffer () + "Normal: return value is the vterm buffer." + (let ((name "claude [return-test]")) + (test-ai-vterm--cleanup name) + (unwind-protect + (test-ai-vterm--with-mock-vterm (:calls _c :strings _s + :returns _r :default-dir _d) + (let ((result (cj/--ai-vterm-show-or-create "/tmp/return" name))) + (should (bufferp result)) + (should (equal (buffer-name result) name)))) + (test-ai-vterm--cleanup name)))) + +(provide 'test-ai-vterm--show-or-create) +;;; test-ai-vterm--show-or-create.el ends here |
