diff options
| author | Craig Jennings <c@cjennings.net> | 2025-10-26 21:21:38 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2025-10-26 21:21:38 -0500 |
| commit | 03719a065c21bf683a9b90c83ab26ee0dc069cc7 (patch) | |
| tree | d0ee9238323ca6dcf55817c10138e9637f35ab42 /tests/test-custom-misc-jump-to-matching-paren.el | |
| parent | 220efbbecd366bc3337c73ad4d902716a9733dae (diff) | |
test+fix:custom-misc: add tests and fix fraction glyph bug
Add test coverage for 4 functions in custom-misc.el:
- cj/replace-fraction-glyphs (24 tests)
- cj/format-region-or-buffer (17 tests)
- cj/count-words-buffer-or-region (20 tests)
- cj/jump-to-matching-paren (18 tests)
Refactored functions using internal/interactive split pattern:
- Internal functions (cj/--function-name) contain business logic with
explicit parameters and validation
- Interactive wrappers handle UI concerns (region detection, messages)
- Tests call internal functions directly (no mocking required)
Bug Fix: cj/--replace-fraction-glyphs
Fixed "Invalid search bound" error when converting glyphs to text.
Original code used fixed end position which became invalid when
replacements changed buffer size. Fixed by using copy-marker for
dynamic end position tracking.
Diffstat (limited to 'tests/test-custom-misc-jump-to-matching-paren.el')
| -rw-r--r-- | tests/test-custom-misc-jump-to-matching-paren.el | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/tests/test-custom-misc-jump-to-matching-paren.el b/tests/test-custom-misc-jump-to-matching-paren.el new file mode 100644 index 00000000..973b6dfa --- /dev/null +++ b/tests/test-custom-misc-jump-to-matching-paren.el @@ -0,0 +1,197 @@ +;;; test-custom-misc-jump-to-matching-paren.el --- Tests for cj/jump-to-matching-paren -*- lexical-binding: t; -*- + +;;; Commentary: +;; Tests for the cj/jump-to-matching-paren function from custom-misc.el +;; +;; This function jumps to matching delimiters using Emacs's sexp navigation. +;; It works with any delimiter that has matching syntax according to the +;; current syntax table (parentheses, brackets, braces, etc.). +;; +;; Unlike other functions in this test suite, this is an INTERACTIVE function +;; that moves point and displays messages. We test it as an integration test +;; by setting up buffers, positioning point, calling the function, and +;; verifying where point ends up. +;; +;; Key behaviors: +;; - When on opening delimiter: jump forward to matching closing delimiter +;; - When on closing delimiter: jump backward to matching opening delimiter +;; - When just after closing delimiter: jump backward to matching opening +;; - When not on delimiter: display message, don't move +;; - When no matching delimiter: display error message, don't move + +;;; Code: + +(require 'ert) +(require 'testutil-general) + +;; Add modules directory to load path +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) + +;; Stub dependencies before loading the module +(defvar cj/custom-keymap (make-sparse-keymap) + "Stub keymap for testing.") + +;; Now load the actual production module +(require 'custom-misc) + +;;; Test Helpers + +(defun test-jump-to-matching-paren (text point-position) + "Test cj/jump-to-matching-paren with TEXT and point at POINT-POSITION. +Returns the new point position after calling the function. +POINT-POSITION is 1-indexed (1 = first character)." + (with-temp-buffer + (emacs-lisp-mode) ; Use elisp mode for proper syntax table + (insert text) + (goto-char point-position) + (cj/jump-to-matching-paren) + (point))) + +;;; Normal Cases - Forward Jump (Opening to Closing) + +(ert-deftest test-jump-paren-forward-simple () + "Should jump forward from opening paren to closing paren." + ;; Text: "(hello)" + ;; Start at position 1 (on opening paren) + ;; Should end at position 8 (after closing paren) + (should (= 8 (test-jump-to-matching-paren "(hello)" 1)))) + +(ert-deftest test-jump-paren-forward-nested () + "Should jump forward over nested parens." + ;; Text: "(foo (bar))" + ;; Start at position 1 (on outer opening paren) + ;; Should end at position 12 (after outer closing paren) + (should (= 12 (test-jump-to-matching-paren "(foo (bar))" 1)))) + +(ert-deftest test-jump-paren-forward-inner-nested () + "Should jump forward from inner opening paren." + ;; Text: "(foo (bar))" + ;; Start at position 6 (on inner opening paren) + ;; Should end at position 11 (after inner closing paren) + (should (= 11 (test-jump-to-matching-paren "(foo (bar))" 6)))) + +(ert-deftest test-jump-bracket-forward () + "Should jump forward from opening bracket." + ;; Text: "[1 2 3]" + ;; Start at position 1 + ;; Should end at position 8 + (should (= 8 (test-jump-to-matching-paren "[1 2 3]" 1)))) + +;; Note: Braces are not treated as matching delimiters in emacs-lisp-mode +;; so we don't test them here + +;;; Normal Cases - Backward Jump (Closing to Opening) + +(ert-deftest test-jump-paren-backward-simple () + "Should jump backward from closing paren to opening paren." + ;; Text: "(hello)" + ;; Start at position 7 (on closing paren) + ;; Should end at position 2 (after opening paren) + (should (= 2 (test-jump-to-matching-paren "(hello)" 7)))) + +(ert-deftest test-jump-paren-backward-nested () + "Should jump backward over nested parens from after outer closing." + ;; Text: "(foo (bar))" + ;; Start at position 12 (after outer closing paren) + ;; backward-sexp goes back to before opening paren + (should (= 1 (test-jump-to-matching-paren "(foo (bar))" 12)))) + +(ert-deftest test-jump-paren-backward-inner-nested () + "Should jump backward from inner closing paren." + ;; Text: "(foo (bar))" + ;; Start at position 10 (on inner closing paren) + ;; Should end at position 7 (after inner opening paren) + (should (= 7 (test-jump-to-matching-paren "(foo (bar))" 10)))) + +(ert-deftest test-jump-bracket-backward () + "Should jump backward from after closing bracket." + ;; Text: "[1 2 3]" + ;; Start at position 8 (after ]) + ;; backward-sexp goes back one sexp + (should (= 1 (test-jump-to-matching-paren "[1 2 3]" 8)))) + +;;; Normal Cases - Jump from After Closing Delimiter + +(ert-deftest test-jump-paren-after-closing () + "Should jump backward when just after closing paren." + ;; Text: "(hello)" + ;; Start at position 8 (after closing paren) + ;; backward-sexp goes back one sexp, ending before the opening paren + (should (= 1 (test-jump-to-matching-paren "(hello)" 8)))) + +;;; Boundary Cases - No Movement + +(ert-deftest test-jump-paren-not-on-delimiter () + "Should not move when not on delimiter." + ;; Text: "(hello world)" + ;; Start at position 3 (on 'e' in hello) + ;; Should stay at position 3 + (should (= 3 (test-jump-to-matching-paren "(hello world)" 3)))) + +(ert-deftest test-jump-paren-on-whitespace () + "Should not move when on whitespace." + ;; Text: "(hello world)" + ;; Start at position 7 (on space) + ;; Should stay at position 7 + (should (= 7 (test-jump-to-matching-paren "(hello world)" 7)))) + +;;; Boundary Cases - Unmatched Delimiters + +(ert-deftest test-jump-paren-unmatched-opening () + "Should not move from unmatched opening paren." + ;; Text: "(hello" + ;; Start at position 1 (on opening paren with no closing) + ;; Should stay at position 1 + (should (= 1 (test-jump-to-matching-paren "(hello" 1)))) + +(ert-deftest test-jump-paren-unmatched-closing () + "Should move to beginning from unmatched closing paren." + ;; Text: "hello)" + ;; Start at position 6 (on closing paren with no opening) + ;; backward-sexp with unmatched closing paren goes to beginning + (should (= 1 (test-jump-to-matching-paren "hello)" 6)))) + +;;; Boundary Cases - Empty Delimiters + +(ert-deftest test-jump-paren-empty () + "Should jump over empty parens." + ;; Text: "()" + ;; Start at position 1 + ;; Should end at position 3 + (should (= 3 (test-jump-to-matching-paren "()" 1)))) + +(ert-deftest test-jump-paren-empty-backward () + "Should stay put when on closing paren of empty parens." + ;; Text: "()" + ;; Start at position 2 (on closing paren) + ;; backward-sexp from closing of empty parens gives an error, so stays at 2 + (should (= 2 (test-jump-to-matching-paren "()" 2)))) + +;;; Boundary Cases - Multiple Delimiter Types + +(ert-deftest test-jump-paren-mixed-delimiters () + "Should jump over mixed delimiter types." + ;; Text: "(foo [bar {baz}])" + ;; Start at position 1 (on opening paren) + ;; Should end at position 18 (after closing paren) + (should (= 18 (test-jump-to-matching-paren "(foo [bar {baz}])" 1)))) + +(ert-deftest test-jump-bracket-in-parens () + "Should jump from bracket inside parens." + ;; Text: "(foo [bar])" + ;; Start at position 6 (on opening bracket) + ;; Should end at position 11 (after closing bracket) + (should (= 11 (test-jump-to-matching-paren "(foo [bar])" 6)))) + +;;; Complex Cases - Strings and Comments + +(ert-deftest test-jump-paren-over-string () + "Should jump over parens containing strings." + ;; Text: "(\"hello (world)\")" + ;; Start at position 1 (on opening paren) + ;; Should end at position 18 (after closing paren) + ;; The parens in the string should be ignored + (should (= 18 (test-jump-to-matching-paren "(\"hello (world)\")" 1)))) + +(provide 'test-custom-misc-jump-to-matching-paren) +;;; test-custom-misc-jump-to-matching-paren.el ends here |
