From 10fa6f4e2e7150ad99827721ada1ae4badcc5e90 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Tue, 23 Jun 2026 20:12:58 -0400 Subject: chore(ai): archive gptel and remove it from the live config I archived gptel to archive/gptel/ since I rarely use it. Moved there: the six gptel modules (ai-config, ai-conversations, ai-conversations-browser, ai-mcp, ai-quick-ask, ai-rewrite), the gptel-tools/ directory, custom/gptel-prompts.el, their test files and utilities, and the four gptel-only specs. Scrubbed from the live config: the ai-config require in init.el, which also drops the whole C-; a keymap; the gptel-mode emojify hook in font-config.el; the gptel-tools entries in the Makefile clean target and the coverage runner; and the gptel feature notes in README. Cancelled the open gptel tasks in todo.org (the AI Open Work issues, the feature-extension brainstorm, the velox gptel-magit bug). ai-term stays. It is the ghostel Claude launcher, independent of gptel. Verified: every module loads, a batch init launch reaches completion clean, and the full test suite shows only pre-existing coverage failures unrelated to this change. --- tests/test-ai-config-helpers.el | 183 ---------------------------------------- 1 file changed, 183 deletions(-) delete mode 100644 tests/test-ai-config-helpers.el (limited to 'tests/test-ai-config-helpers.el') diff --git a/tests/test-ai-config-helpers.el b/tests/test-ai-config-helpers.el deleted file mode 100644 index cdbc0f6e..00000000 --- a/tests/test-ai-config-helpers.el +++ /dev/null @@ -1,183 +0,0 @@ -;;; test-ai-config-helpers.el --- Tests for ai-config helper functions -*- lexical-binding: t; -*- - -;;; Commentary: -;; Covers helpers that don't depend on a live gptel install: -;; -;; cj/auth-source-secret -;; cj/anthropic-api-key (caching wrapper) -;; cj/openai-api-key (caching wrapper) -;; cj/gptel--add-file-to-context -;; cj/gptel-clear-buffer -;; cj/gptel-context-clear -;; cj/gptel-insert-model-heading -;; -;; External primitives (`auth-source-search', `gptel-add-file', etc.) -;; are stubbed so the tests never touch the keyring or the network. - -;;; Code: - -(require 'ert) -(require 'cl-lib) - -(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) -(require 'ai-config) - -;; Make `gptel-context--alist' a real dynamic variable for the fallback -;; test below. Under lexical-binding a plain `let' is lexical, so the -;; `setq' inside `cj/gptel-context-clear' would otherwise miss it. -(defvar gptel-context--alist nil - "Dynamic stand-in for the gptel-context alist (gptel not loaded here).") - -;;; cj/auth-source-secret - -(ert-deftest test-ai-config-auth-source-secret-returns-string () - "Normal: a plain-string secret comes back as-is." - (cl-letf (((symbol-function 'auth-source-search) - (lambda (&rest _) '((:secret "plaintext"))))) - (should (equal (cj/auth-source-secret "example.com" "user") - "plaintext")))) - -(ert-deftest test-ai-config-auth-source-secret-unwraps-function () - "Normal: a function secret is funcall'd to retrieve the value." - (cl-letf (((symbol-function 'auth-source-search) - (lambda (&rest _) (list (list :secret (lambda () "called")))))) - (should (equal (cj/auth-source-secret "example.com" "user") - "called")))) - -(ert-deftest test-ai-config-auth-source-secret-errors-when-missing () - "Error: an empty result raises a clear error." - (cl-letf (((symbol-function 'auth-source-search) - (lambda (&rest _) nil))) - (should-error (cj/auth-source-secret "nope.example.com" "user") - :type 'error))) - -;;; cj/anthropic-api-key / cj/openai-api-key - -(ert-deftest test-ai-config-anthropic-api-key-caches-after-first-call () - "Normal: a subsequent call returns the cached value without re-fetching." - (let ((cj/anthropic-api-key-cached nil) - (call-count 0)) - (cl-letf (((symbol-function 'auth-source-search) - (lambda (&rest _) - (cl-incf call-count) - '((:secret "anth-key"))))) - (should (equal (cj/anthropic-api-key) "anth-key")) - (should (equal (cj/anthropic-api-key) "anth-key")) - (should (= call-count 1))))) - -(ert-deftest test-ai-config-openai-api-key-caches-after-first-call () - "Normal: same caching contract as the anthropic key." - (let ((cj/openai-api-key-cached nil) - (call-count 0)) - (cl-letf (((symbol-function 'auth-source-search) - (lambda (&rest _) - (cl-incf call-count) - '((:secret "oai-key"))))) - (should (equal (cj/openai-api-key) "oai-key")) - (should (equal (cj/openai-api-key) "oai-key")) - (should (= call-count 1))))) - -;;; cj/gptel--add-file-to-context - -(ert-deftest test-ai-config-add-file-to-context-adds-existing-file () - "Normal: an existing file is added and the function returns t." - (let ((tmp (make-temp-file "ai-config-add-file-"))) - (unwind-protect - (let ((gptel-context--alist nil) - (added nil)) - (cl-letf (((symbol-function 'gptel-add-file) - (lambda (f) (setq added f))) - ((symbol-function 'message) #'ignore)) - (should (eq (cj/gptel--add-file-to-context tmp) t)) - (should (equal added tmp)))) - (delete-file tmp)))) - -(ert-deftest test-ai-config-add-file-to-context-skips-missing-file () - "Boundary: a non-existent path returns nil and doesn't call gptel-add-file." - (let ((called nil)) - (cl-letf (((symbol-function 'gptel-add-file) - (lambda (_) (setq called t)))) - (should-not (cj/gptel--add-file-to-context "/no/such/path")) - (should-not called)))) - -(ert-deftest test-ai-config-add-file-to-context-skips-nil-path () - "Boundary: a nil path returns nil without calling gptel-add-file." - (let ((called nil)) - (cl-letf (((symbol-function 'gptel-add-file) - (lambda (_) (setq called t)))) - (should-not (cj/gptel--add-file-to-context nil)) - (should-not called)))) - -;;; cj/gptel-clear-buffer - -(ert-deftest test-ai-config-clear-buffer-erases-in-gptel-org-buffer () - "Normal: a gptel-mode org buffer is erased and the fresh org prefix is reinserted." - (with-temp-buffer - (delay-mode-hooks (org-mode)) - (setq-local gptel-mode t) - (insert "* Existing conversation\nstuff\n") - (let ((msg nil)) - (cl-letf (((symbol-function 'message) - (lambda (fmt &rest args) - (setq msg (apply #'format fmt args))))) - (cj/gptel-clear-buffer)) - (should (string-match-p "cleared" msg))) - ;; The fresh prefix is an org heading starting with "* ". - (should (string-prefix-p "* " (buffer-string))) - (should-not (string-match-p "Existing conversation" (buffer-string))))) - -(ert-deftest test-ai-config-clear-buffer-noop-when-not-gptel-org () - "Boundary: in a non-gptel buffer the function messages and changes nothing." - (with-temp-buffer - (insert "untouched\n") - (let ((msg nil)) - (cl-letf (((symbol-function 'message) - (lambda (fmt &rest args) - (setq msg (apply #'format fmt args))))) - (cj/gptel-clear-buffer)) - (should (string-match-p "Not a GPTel buffer" msg)) - (should (equal (buffer-string) "untouched\n"))))) - -;;; cj/gptel-context-clear - -(ert-deftest test-ai-config-context-clear-uses-remove-all-when-available () - "Normal: when `gptel-context-remove-all' is bound, it wins the cond. -The stub must be a command because `cj/gptel-context-clear' invokes it -via `call-interactively'." - (let ((called nil) - (msg nil)) - (cl-letf (((symbol-function 'gptel-context-remove-all) - (lambda () (interactive) (setq called 'remove-all))) - ((symbol-function 'message) - (lambda (fmt &rest args) (setq msg (apply #'format fmt args))))) - (cj/gptel-context-clear)) - (should (eq called 'remove-all)) - (should (string-match-p "cleared" msg)))) - -(ert-deftest test-ai-config-context-clear-falls-back-to-alist-setq () - "Boundary: when no clearing function exists, the alist is set to nil." - (let ((gptel-context--alist '((:dummy))) - (msg nil)) - (cl-letf (((symbol-function 'fboundp) - (lambda (sym) - (not (memq sym '(gptel-context-remove-all gptel-context-clear))))) - ((symbol-function 'message) - (lambda (fmt &rest args) (setq msg (apply #'format fmt args))))) - (cj/gptel-context-clear)) - (should (null gptel-context--alist)) - (should (string-match-p "cleared" msg)))) - -;;; cj/gptel-insert-model-heading - -(ert-deftest test-ai-config-insert-model-heading-inserts-at-given-position () - "Normal: an Org heading is inserted at RESPONSE-BEGIN-POS." - (with-temp-buffer - (insert "response text") - (cl-letf (((symbol-function 'cj/gptel-backend-and-model) - (lambda () "Anthropic: claude-test [2026-05-13 12:00:00]"))) - (cj/gptel-insert-model-heading (point-min) (point-max))) - (should (string-prefix-p "* Anthropic: claude-test" (buffer-string))) - (should (string-match-p "\nresponse text" (buffer-string))))) - -(provide 'test-ai-config-helpers) -;;; test-ai-config-helpers.el ends here -- cgit v1.2.3