diff options
| author | Craig Jennings <c@cjennings.net> | 2025-11-14 01:22:36 -0600 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2025-11-14 01:22:36 -0600 |
| commit | 1534be5b365431c885c4c5c09c7f157d94a9f942 (patch) | |
| tree | 76df1c4d2daf3b799b179ef0c1ee0ad1a2935cfb /tests/test-integration-mousetrap-mode-lighter-click.el | |
| parent | ce58581c4a8cc00054e063d4bbf4fbbaeb0a7b35 (diff) | |
feat(mousetrap): Add profile-based architecture and clickable lighter
Implement comprehensive profile-based system for selective mouse event
control with dynamic lighter and interactive toggling.
Features:
- Profile-based architecture (7 profiles: disabled, scroll-only,
primary-click, scroll+primary, read-only, interactive, full)
- Mode-specific configuration (dashboard, pdf-view, nov)
- Dynamic keymap building based on current major mode
- Clickable modeline lighter (🐭 when off, 🪤 when on)
- Dynamic reconfiguration without Emacs reload
- Mode inheritance support via derived-mode-p
Profiles define which event categories are allowed:
- primary-click: Left mouse button only
- secondary-click: Middle and right buttons
- drags: Drag selections
- multi-clicks: Double and triple clicks
- scroll: Mouse wheel/trackpad scrolling
Default configuration:
- dashboard-mode: primary-click (left-click only)
- pdf-view-mode: full (all events)
- nov-mode: full (all events)
- Other modes: disabled (all events blocked)
Tests:
- 66 comprehensive tests across 5 test files
- Unit tests for profile lookup and keymap building
- Integration tests for mode switching and dynamic config
- Lighter functionality and click interaction tests
- All tests passing
Known issue:
- Dashboard-mode clicks blocked despite primary-click profile
- Documented in todo.org for investigation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'tests/test-integration-mousetrap-mode-lighter-click.el')
| -rw-r--r-- | tests/test-integration-mousetrap-mode-lighter-click.el | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/tests/test-integration-mousetrap-mode-lighter-click.el b/tests/test-integration-mousetrap-mode-lighter-click.el new file mode 100644 index 00000000..fcae89a6 --- /dev/null +++ b/tests/test-integration-mousetrap-mode-lighter-click.el @@ -0,0 +1,174 @@ +;;; test-integration-mousetrap-mode-lighter-click.el --- Integration tests for lighter clicking -*- lexical-binding: t; -*- + +;;; Commentary: +;; Integration tests for mousetrap-mode lighter click functionality. +;; Tests that clicking the lighter properly toggles the mode AND +;; rebuilds the keymap based on the current major mode profile. + +;;; Code: + +(require 'ert) +(require 'mousetrap-mode) + +;;; Integration Tests - Lighter Click Behavior + +(ert-deftest test-integration-lighter-click-enables-mode-in-dashboard () + "Test clicking lighter in dashboard-mode enables mode with correct profile. +Dashboard uses primary-click profile which blocks scrolling but allows mouse-1." + (with-temp-buffer + (let ((major-mode 'dashboard-mode) + (mouse-trap-mode nil)) + ;; Start with mode disabled + (should-not mouse-trap-mode) + + ;; Simulate clicking lighter to enable (calls mouse-trap-mode with 1) + (mouse-trap-mode 1) + + ;; Mode should be enabled + (should mouse-trap-mode) + + ;; Keymap should be built for dashboard (primary-click profile) + (should (keymapp mouse-trap-mode-map)) + + ;; Verify profile-specific behavior: mouse-1 allowed, scroll blocked + (should (eq (lookup-key mouse-trap-mode-map (kbd "<mouse-1>")) nil)) + (should (eq (lookup-key mouse-trap-mode-map (kbd "<wheel-up>")) 'ignore)) + + ;; Keymap should be in minor-mode-map-alist + (should (assq 'mouse-trap-mode minor-mode-map-alist))))) + +(ert-deftest test-integration-lighter-click-disables-mode () + "Test clicking lighter when mode is enabled disables it and removes keymap." + (with-temp-buffer + (emacs-lisp-mode) + (mouse-trap-mode 1) + (should mouse-trap-mode) + (should (assq 'mouse-trap-mode minor-mode-map-alist)) + + ;; Simulate clicking lighter to disable + (mouse-trap-mode -1) + + ;; Mode should be disabled + (should-not mouse-trap-mode) + + ;; Keymap should be removed from minor-mode-map-alist + (should-not (assq 'mouse-trap-mode minor-mode-map-alist)))) + +(ert-deftest test-integration-lighter-click-toggle-updates-keymap () + "Test toggling mode via lighter click rebuilds keymap for current mode. +This is the critical test - when you click to enable, it should rebuild +the keymap based on the CURRENT major mode's profile." + (with-temp-buffer + (let ((major-mode 'dashboard-mode)) + ;; Start disabled + (mouse-trap-mode -1) + (should-not mouse-trap-mode) + + ;; Enable via click (simulate) + (mouse-trap-mode 1) + (should mouse-trap-mode) + + ;; Should have dashboard profile (primary-click) + (let ((map1 mouse-trap-mode-map)) + (should (eq (lookup-key map1 (kbd "<mouse-1>")) nil)) ; allowed + (should (eq (lookup-key map1 (kbd "<wheel-up>")) 'ignore)) ; blocked + + ;; Disable + (mouse-trap-mode -1) + (should-not mouse-trap-mode) + + ;; Change to different mode + (setq major-mode 'pdf-view-mode) + + ;; Enable again + (mouse-trap-mode 1) + (should mouse-trap-mode) + + ;; Should now have pdf-view profile (full - all allowed) + (let ((map2 mouse-trap-mode-map)) + (should (eq (lookup-key map2 (kbd "<mouse-1>")) nil)) ; allowed + (should (eq (lookup-key map2 (kbd "<wheel-up>")) nil))) ; allowed now! + + ;; Verify maps are different + (should-not (equal map1 mouse-trap-mode-map)))))) + +(ert-deftest test-integration-lighter-click-respects-buffer-local-mode () + "Test lighter click affects only current buffer (buffer-local behavior)." + (let ((buf1 (generate-new-buffer "test1")) + (buf2 (generate-new-buffer "test2"))) + (unwind-protect + (progn + ;; Buffer 1: enable mode manually + (with-current-buffer buf1 + (setq major-mode 'text-mode) ; Use setq to avoid hooks + (mouse-trap-mode 1) + (should mouse-trap-mode)) + + ;; Buffer 2: mode should be independent (not auto-enabled) + (with-current-buffer buf2 + (setq major-mode 'text-mode) ; Use setq to avoid hooks + (should-not mouse-trap-mode) + + ;; Enable in buf2 + (mouse-trap-mode 1) + (should mouse-trap-mode)) + + ;; Verify buf1 still enabled + (with-current-buffer buf1 + (should mouse-trap-mode)) + + ;; Disable buf2 via click + (with-current-buffer buf2 + (mouse-trap-mode -1) + (should-not mouse-trap-mode)) + + ;; Verify buf1 unaffected + (with-current-buffer buf1 + (should mouse-trap-mode))) + + (kill-buffer buf1) + (kill-buffer buf2)))) + +(ert-deftest test-integration-lighter-click-with-excluded-mode () + "Test lighter click works even in excluded modes. +Auto-enable is blocked, but manual toggle should still work." + (with-temp-buffer + (dired-mode default-directory) + + ;; Auto-enable is blocked for dired + (mouse-trap-maybe-enable) + (should-not mouse-trap-mode) + + ;; But manual toggle should work + (mouse-trap-mode 1) + (should mouse-trap-mode) + (should (assq 'mouse-trap-mode minor-mode-map-alist)) + + ;; Toggle off + (mouse-trap-mode -1) + (should-not mouse-trap-mode) + (should-not (assq 'mouse-trap-mode minor-mode-map-alist)))) + +(ert-deftest test-integration-lighter-click-multiple-rapid-toggles () + "Test rapid clicking (multiple toggles) is stable and doesn't corrupt state." + (with-temp-buffer + (emacs-lisp-mode) + + ;; Rapid toggle 10 times + (dotimes (i 10) + (if (= (mod i 2) 0) + (mouse-trap-mode 1) + (mouse-trap-mode -1))) + + ;; Should end in disabled state (even number of toggles) + (should-not mouse-trap-mode) + (should-not (assq 'mouse-trap-mode minor-mode-map-alist)) + + ;; Enable one more time to end enabled + (mouse-trap-mode 1) + (should mouse-trap-mode) + (should (assq 'mouse-trap-mode minor-mode-map-alist)) + (should (keymapp mouse-trap-mode-map)))) + +(provide 'test-integration-mousetrap-mode-lighter-click) +;;; test-integration-mousetrap-mode-lighter-click.el ends here |
