branch: externals/ellama
commit 1d9c8c5ee94ae428d2eb5aaca7257e85f67c64cf
Author: Sergey Kostyaev <[email protected]>
Commit: Sergey Kostyaev <[email protected]>

    Add tests for ellama helper functions and error handling
    
    Introduce unit tests covering ellama-remove-reasoning, mode-derived helpers,
    tool call error detection, error handler retry logic on tool errors, error
    handling for non-tool errors, chat-done callback behavior, and setup to use
    local ellama-tools. These tests validate correct behavior and edge cases.
---
 tests/test-ellama.el | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/tests/test-ellama.el b/tests/test-ellama.el
index c233f7aff7..6317d4fac2 100644
--- a/tests/test-ellama.el
+++ b/tests/test-ellama.el
@@ -1137,6 +1137,105 @@ region, season, or type)! 🍎🍊"))))
     (should (equal captured
                   '("Unknown tool 'search' called" system)))))
 
+(ert-deftest test-ellama-remove-reasoning ()
+  (should (equal
+           (ellama-remove-reasoning "<think>\nabc\n</think>\nFinal")
+           "Final"))
+  (should (equal
+           (ellama-remove-reasoning "Before <think>x</think> After")
+           "Before  After")))
+
+(ert-deftest test-ellama-mode-derived-helpers ()
+  (let ((ellama-major-mode 'org-mode)
+        (ellama-nick-prefix-depth 3))
+    (should (equal (ellama-get-nick-prefix-for-mode) "***"))
+    (should (equal (ellama-get-session-file-extension) "org")))
+  (let ((ellama-major-mode 'text-mode)
+        (ellama-nick-prefix-depth 2))
+    (should (equal (ellama-get-nick-prefix-for-mode) "##"))
+    (should (equal (ellama-get-session-file-extension) "md"))))
+
+(ert-deftest test-ellama--tool-call-error-p ()
+  (unless (get 'ellama-test-tool-call-error-2 'error-conditions)
+    (define-error 'ellama-test-tool-call-error-2
+      "Tool call test error"
+      'llm-tool-call-error))
+  (should (ellama--tool-call-error-p 'ellama-test-tool-call-error-2))
+  (should-not (ellama--tool-call-error-p 'error))
+  (should-not (ellama--tool-call-error-p nil)))
+
+(ert-deftest test-ellama--error-handler-retry-on-tool-call-error ()
+  (unless (get 'ellama-test-tool-call-error-3 'error-conditions)
+    (define-error 'ellama-test-tool-call-error-3
+      "Tool call retry error"
+      'llm-tool-call-error))
+  (let ((retry-called nil)
+        (err-called nil)
+        (appended nil))
+    (with-temp-buffer
+      (cl-letf (((symbol-function 'ellama--append-tool-error-to-prompt)
+                 (lambda (_prompt msg)
+                   (setq appended msg))))
+        (let ((handler
+               (ellama--error-handler
+                (current-buffer)
+                (lambda (_msg) (setq err-called t))
+                'prompt
+                (lambda () (setq retry-called t)))))
+          (funcall handler 'ellama-test-tool-call-error-3 "tool failed"))))
+    (should retry-called)
+    (should-not err-called)
+    (should (equal appended "tool failed"))))
+
+(ert-deftest test-ellama--error-handler-calls-errcb-for-non-tool-errors ()
+  (let ((err-msg nil)
+        (request-mode-arg nil)
+        (spinner-stop-called nil)
+        (ellama--change-group (prepare-change-group))
+        (ellama-spinner-enabled t))
+    (with-temp-buffer
+      (setq-local ellama--current-request 'request)
+      (activate-change-group ellama--change-group)
+      (cl-letf (((symbol-function 'cancel-change-group)
+                 (lambda (_cg) nil))
+                ((symbol-function 'spinner-stop)
+                 (lambda () (setq spinner-stop-called t)))
+                ((symbol-function 'ellama-request-mode)
+                 (lambda (arg)
+                   (setq request-mode-arg arg))))
+        (let ((handler
+               (ellama--error-handler
+                (current-buffer)
+                (lambda (msg) (setq err-msg msg))
+                'prompt
+                (lambda () (error "Retry should not run")))))
+          (funcall handler 'error "bad")))
+      (should (null ellama--current-request)))
+    (should (equal err-msg "bad"))
+    (should (equal request-mode-arg -1))
+    (should spinner-stop-called)))
+
+(ert-deftest test-ellama-chat-done-appends-user-header-and-callbacks ()
+  (let* ((ellama-major-mode 'org-mode)
+         (ellama-user-nick "Tester")
+         (ellama-nick-prefix-depth 2)
+         (ellama-session-auto-save nil)
+         (global-callback-text nil)
+         (local-callback-text nil)
+         (ellama-chat-done-callback (lambda (text)
+                                      (setq global-callback-text text))))
+    (with-temp-buffer
+      (insert "Assistant output")
+      (cl-letf (((symbol-function 'ellama--scroll)
+                 (lambda (&optional _buffer _point) nil)))
+        (ellama-chat-done "final"
+                          (lambda (text)
+                            (setq local-callback-text text))))
+      (should (equal (buffer-string)
+                     "Assistant output\n\n** Tester:\n"))
+      (should (equal global-callback-text "final"))
+      (should (equal local-callback-text "final")))))
+
 (defun ellama-test--ensure-local-ellama-tools ()
   "Ensure tests use local `ellama-tools.el' from project root."
   (unless (fboundp 'ellama-tools--sanitize-tool-text-output)

Reply via email to