diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test-jumper-public-wrappers.el | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/tests/test-jumper-public-wrappers.el b/tests/test-jumper-public-wrappers.el new file mode 100644 index 00000000..99279344 --- /dev/null +++ b/tests/test-jumper-public-wrappers.el @@ -0,0 +1,175 @@ +;;; test-jumper-public-wrappers.el --- Tests for the interactive jumper wrappers -*- lexical-binding: t; -*- + +;;; Commentary: +;; Internal helpers (`jumper--do-store-location', +;; `jumper--do-jump-to-location', `jumper--do-remove-location') are +;; already tested in test-jumper.el. This file covers the three +;; interactive entry points that dispatch user input (and messages) +;; into those helpers: +;; +;; jumper-store-location +;; jumper-jump-to-location +;; jumper-remove-location +;; +;; `message' is captured to verify the user-visible feedback path; +;; `completing-read' is stubbed when the wrapper prompts the user. + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'jumper) + +(defmacro test-jumper-wrappers--with-clean-state (&rest body) + "Reset jumper state and capture messages, then evaluate BODY." + `(let ((jumper--registers (make-vector jumper-max-locations nil)) + (jumper--next-index 0) + (captured-message nil)) + ;; Clear the 'z' last-location register so completing-read prompts + ;; don't show it from a previous test run in the same process. + (set-register jumper--last-location-register nil) + (dotimes (i jumper-max-locations) + (set-register (+ ?0 i) nil)) + (cl-letf (((symbol-function 'message) + (lambda (fmt &rest args) + (setq captured-message (apply #'format fmt args))))) + ,@body))) + +;;; jumper-store-location + +(ert-deftest test-jumper-wrapper-store-fresh-location-messages-register () + "Normal: storing a fresh location messages the register that was assigned." + (test-jumper-wrappers--with-clean-state + (with-temp-buffer + (insert "alpha\n") + (goto-char (point-min)) + (jumper-store-location) + (should (string-match-p "register" captured-message)) + (should (= jumper--next-index 1))))) + +(ert-deftest test-jumper-wrapper-store-duplicate-messages-already-stored () + "Boundary: storing the same location twice surfaces the duplicate path." + (test-jumper-wrappers--with-clean-state + (with-temp-buffer + (insert "alpha\n") + (goto-char (point-min)) + (jumper-store-location) + (setq captured-message nil) + (jumper-store-location) + (should (string-match-p "already stored" captured-message)) + (should (= jumper--next-index 1))))) + +(ert-deftest test-jumper-wrapper-store-when-full-messages-no-space () + "Boundary: storing when every register is taken surfaces the no-space path." + (test-jumper-wrappers--with-clean-state + (with-temp-buffer + (dotimes (i jumper-max-locations) + (insert (format "line %d\n" i)) + (goto-char (point-max)) + (jumper-store-location)) + (insert "one-more\n") + (goto-char (point-max)) + (setq captured-message nil) + (jumper-store-location) + (should (string-match-p "all jump locations" captured-message))))) + +;;; jumper-jump-to-location + +(ert-deftest test-jumper-wrapper-jump-no-locations-messages () + "Normal: with no stored locations the wrapper surfaces the empty state." + (test-jumper-wrappers--with-clean-state + (jumper-jump-to-location) + (should (string-match-p "No locations" captured-message)))) + +(ert-deftest test-jumper-wrapper-jump-single-location-already-there () + "Normal: single-location toggle from the stored position surfaces the +already-there message." + (test-jumper-wrappers--with-clean-state + (with-temp-buffer + (insert "alpha\n") + (goto-char (point-min)) + (jumper-store-location) + (setq captured-message nil) + ;; Don't move -- jump should detect we're at the stored location. + (jumper-jump-to-location) + (should (string-match-p "already at" captured-message))))) + +(ert-deftest test-jumper-wrapper-jump-multi-location-prompts () + "Normal: with multiple locations the wrapper prompts via completing-read +and jumps to the selected entry." + (test-jumper-wrappers--with-clean-state + (with-temp-buffer + (insert "alpha\nbeta\n") + ;; Two stored locations at different points. + (goto-char (point-min)) + (jumper-store-location) + (forward-line) + (jumper-store-location) + (setq captured-message nil) + ;; Stub the prompt to pick the first candidate (index 0). + (cl-letf (((symbol-function 'completing-read) + (lambda (_prompt collection &rest _) + ;; Pick whichever candidate maps to integer 0. + (car (cl-find-if (lambda (cell) (equal (cdr cell) 0)) + collection))))) + (jumper-jump-to-location)) + (should (string-match-p "Jumped" captured-message))))) + +;;; jumper-remove-location + +(ert-deftest test-jumper-wrapper-remove-no-locations-messages () + "Normal: removing with no stored locations surfaces the empty state." + (test-jumper-wrappers--with-clean-state + (jumper-remove-location) + (should (string-match-p "No locations" captured-message)))) + +(ert-deftest test-jumper-wrapper-remove-prompts-and-deletes () + "Normal: with locations stored, removing prompts and deletes the chosen one." + (test-jumper-wrappers--with-clean-state + (with-temp-buffer + (insert "alpha\nbeta\n") + (goto-char (point-min)) + (jumper-store-location) + (forward-line) + (jumper-store-location) + (should (= jumper--next-index 2)) + (cl-letf (((symbol-function 'completing-read) + (lambda (_prompt collection &rest _) + (car (cl-find-if (lambda (cell) (equal (cdr cell) 0)) + collection))))) + (setq captured-message nil) + (jumper-remove-location)) + (should (string-match-p "Location removed" captured-message)) + (should (= jumper--next-index 1))))) + +(ert-deftest test-jumper-wrapper-remove-cancel-keeps-state () + "Boundary: choosing Cancel surfaces the cancelled message and changes nothing." + (test-jumper-wrappers--with-clean-state + (with-temp-buffer + (insert "alpha\n") + (goto-char (point-min)) + (jumper-store-location) + (cl-letf (((symbol-function 'completing-read) + (lambda (_prompt collection &rest _) + (car (cl-find-if (lambda (cell) (equal (cdr cell) -1)) + collection))))) + (setq captured-message nil) + (jumper-remove-location)) + (should (string-match-p "cancelled" captured-message)) + (should (= jumper--next-index 1))))) + +;;; jumper-setup-keys + +(ert-deftest test-jumper-setup-keys-binds-prefix-to-jumper-map () + "Normal: `jumper-setup-keys' wires the prefix key to `jumper-map'." + (let ((jumper-prefix-key "C-c M-j")) + (jumper-setup-keys) + (should (eq (keymap-lookup (current-global-map) jumper-prefix-key) + jumper-map)) + ;; Cleanup so the test binding doesn't leak. + (keymap-global-unset jumper-prefix-key))) + +(provide 'test-jumper-public-wrappers) +;;; test-jumper-public-wrappers.el ends here |
