aboutsummaryrefslogtreecommitdiff
path: root/tests/test-auto-dim-config.el
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-auto-dim-config.el')
-rw-r--r--tests/test-auto-dim-config.el169
1 files changed, 168 insertions, 1 deletions
diff --git a/tests/test-auto-dim-config.el b/tests/test-auto-dim-config.el
index 869eb409..8b13fbb0 100644
--- a/tests/test-auto-dim-config.el
+++ b/tests/test-auto-dim-config.el
@@ -30,11 +30,105 @@
(progn
(should (bound-and-true-p auto-dim-other-buffers-mode))
(should (null auto-dim-other-buffers-dim-on-focus-out))
- (should (eq t auto-dim-other-buffers-dim-on-switch-to-minibuffer))
+ ;; Config intent only: this asserts the value the module just set, so it
+ ;; cannot fail even if the fork inverts what the flag MEANS. The two
+ ;; behavioral tests below are what actually pin the behavior.
+ (should (null auto-dim-other-buffers-dim-on-switch-to-minibuffer))
(should-not (assq 'fringe auto-dim-other-buffers-affected-faces)))
(when (fboundp 'auto-dim-other-buffers-mode)
(auto-dim-other-buffers-mode -1))))
+(defmacro test-auto-dim--with-two-windows (win-a win-b &rest body)
+ "Bind WIN-A and WIN-B to two live windows with the mode on, then run BODY.
+Restores the window configuration, the buffers, and the mode's PRIOR state.
+Restoring rather than force-disabling matters: `auto-dim-other-buffers-mode' is
+global, and switching it off unconditionally left a later test in this file
+asserting the mode is on with it off. That only stayed hidden because ERT runs
+tests alphabetically and the asserting test sorts first."
+ (declare (indent 2))
+ `(let ((config (current-window-configuration))
+ (was-on (bound-and-true-p auto-dim-other-buffers-mode)))
+ (unwind-protect
+ (let* ((,win-a (selected-window))
+ (,win-b (split-window)))
+ (set-window-buffer ,win-a (get-buffer-create " *adob-a*"))
+ (set-window-buffer ,win-b (get-buffer-create " *adob-b*"))
+ (select-window ,win-a)
+ (auto-dim-other-buffers-mode 1)
+ ,@body)
+ (when (fboundp 'auto-dim-other-buffers-mode)
+ (auto-dim-other-buffers-mode (if was-on 1 -1)))
+ (set-window-configuration config)
+ (dolist (name '(" *adob-a*" " *adob-b*"))
+ (when (get-buffer name) (kill-buffer name))))))
+
+(ert-deftest test-auto-dim-config-minibuffer-entry-leaves-previous-window-lit ()
+ "Normal: with the flag nil, entering the minibuffer leaves the previous window lit.
+This is the half that works, and the reason the flag is set to nil.
+
+Deliberately asserts the composite behavior rather than naming one function.
+Selecting the minibuffer fires the mode's own hooks, so the observable outcome is
+not attributable to the explicit `adob--update' call alone -- and the observable
+outcome is what the setting promises the user.
+
+The `win-b' assertions are positive controls. Without them this test passes
+against an implementation where dimming is broken everywhere, which looks
+identical to the implementation being correct."
+ (skip-unless (file-directory-p test-auto-dim--fork))
+ (require 'auto-dim-config)
+ (test-auto-dim--with-two-windows win-a win-b
+ (adob--rescan-windows)
+ (should (null (window-parameter win-a 'adob--dim)))
+ (should (window-parameter win-b 'adob--dim))
+ (select-window (minibuffer-window))
+ (adob--update)
+ (should (null (window-parameter win-a 'adob--dim)))
+ (should (window-parameter win-b 'adob--dim))))
+
+(ert-deftest test-auto-dim-config-minibuffer-entry-dims-when-flag-is-t ()
+ "Boundary: with the flag t, entering the minibuffer DOES dim the previous window.
+This is what gives the nil setting meaning. Without it the suite never shows the
+flag changing anything, so the config assertion in
+`test-auto-dim-config-applies-settings' has nothing standing behind it."
+ (skip-unless (file-directory-p test-auto-dim--fork))
+ (require 'auto-dim-config)
+ (test-auto-dim--with-two-windows win-a win-b
+ (let ((auto-dim-other-buffers-dim-on-switch-to-minibuffer t))
+ (adob--rescan-windows)
+ (should (null (window-parameter win-a 'adob--dim)))
+ (select-window (minibuffer-window))
+ (adob--update)
+ (should (window-parameter win-a 'adob--dim)))))
+
+(ert-deftest test-auto-dim-config-rescan-ignores-the-minibuffer-flag ()
+ "Error: `adob--rescan-windows' dims everything on a minibuffer selection.
+Known defect in the fork, pinned here rather than left undocumented. The
+rescan is on `window-configuration-change-hook' and dims by window identity
+alone -- and `(window-list nil \\='n)' excludes the minibuffer, so when the
+minibuffer is selected nothing matches and every window dims. A completion
+popup is the everyday case: `adob--update' honours the flag, this does not.
+
+Expected to fail until the fork honours the flag in the rescan too. When it
+starts passing, ERT reports an unexpected pass -- that is the signal to drop
+this test and stop treating the gap as open.
+
+The `win-b' positive control is load-bearing here. Three different broken
+implementations -- dimming disabled everywhere, the rescan never setting the
+parameter, `adob--update' made a no-op -- all produce an unexpected pass that
+would otherwise read as \"the fork fixed it\". Asserting that `win-b' is still
+dimmed separates a real fix from dimming having broken."
+ :expected-result :failed
+ (skip-unless (file-directory-p test-auto-dim--fork))
+ (require 'auto-dim-config)
+ (test-auto-dim--with-two-windows win-a win-b
+ (adob--rescan-windows)
+ (should (null (window-parameter win-a 'adob--dim)))
+ (should (window-parameter win-b 'adob--dim))
+ (select-window (minibuffer-window))
+ (adob--rescan-windows)
+ (should (window-parameter win-b 'adob--dim))
+ (should (null (window-parameter win-a 'adob--dim)))))
+
(defconst test-auto-dim--flat-dimmed-org-faces
(append (mapcar (lambda (n) (intern (format "org-level-%d" n)))
(number-sequence 1 8))
@@ -71,6 +165,19 @@ dimmed org-level-1. Without these, bullets stay lit in an unfocused window
even though every face under them dims.
`org-superstar-leading' is excluded on purpose -- see the test below.")
+(defconst test-auto-dim--hide-class-faces
+ '(org-hide org-superstar-leading org-indent)
+ "Faces whose foreground IS the background colour.
+That is what makes them invisible. They take `auto-dim-other-buffers-hide',
+never the flat dim, which would paint them visible grey.")
+
+(defconst test-auto-dim--no-foreground-faces
+ '(bold italic underline)
+ "Faces that carry no foreground, even through inheritance.
+They set weight, slant or underline only, so text wearing them takes its
+colour from `default', which is already remapped. They need no entry and
+must not gain one, or the alist grows entries that do nothing.")
+
(defconst test-auto-dim--keyword-dim-variants
'((org-faces-todo . org-faces-todo-dim)
(org-faces-doing . org-faces-doing-dim)
@@ -135,6 +242,66 @@ and reveal stars the user chose to hide. Same contract as `org-hide'."
(should entry)
(should (eq 'auto-dim-other-buffers-hide (car (cdr entry))))))
+(ert-deftest test-auto-dim-config-hide-class-faces-use-hide-face ()
+ "Error: every background-coloured face takes the -hide face.
+`org-hide', `org-superstar-leading' and `org-indent' all resolve to the
+background colour, which is what keeps folded text, leading stars and indent
+prefixes invisible. Flat-dimming any of them reveals what the user hid."
+ (skip-unless (file-directory-p test-auto-dim--fork))
+ (require 'auto-dim-config)
+ (dolist (face test-auto-dim--hide-class-faces)
+ (let ((entry (assq face auto-dim-other-buffers-affected-faces)))
+ (should entry)
+ (should (eq 'auto-dim-other-buffers-hide (car (cdr entry)))))))
+
+(ert-deftest test-auto-dim-config-no-org-face-left-unmapped ()
+ "Boundary: a fontified org buffer uses no face we forgot to handle.
+Four rounds of this bug all had the same shape: a face nobody enumerated,
+sitting ahead of a mapped face in a face list and outranking it. This walks
+a representative buffer, collects every face it actually uses (including the
+`line-prefix' and `wrap-prefix' org-indent hangs its faces on), and fails on
+anything that is neither mapped nor deliberately excluded.
+
+Built-in org only. org-superstar and org-drill are elpa packages, and the
+test run has no `package-initialize', so their faces are pinned by name in
+the tests above instead."
+ (skip-unless (file-directory-p test-auto-dim--fork))
+ (require 'auto-dim-config)
+ (require 'org)
+ (let ((used (make-hash-table :test #'eq))
+ (allowed (append test-auto-dim--no-foreground-faces
+ ;; Keyword class: deliberately unmapped so status stays
+ ;; readable in an unfocused window. Pinned by
+ ;; test-auto-dim-config-todo-priority-faces-not-flat-dimmed.
+ '(org-todo org-priority)
+ (mapcar #'car auto-dim-other-buffers-affected-faces))))
+ (with-temp-buffer
+ (insert "#+TITLE: T\n#+AUTHOR: A\n\n* H1 :tag:\n** TODO [#A] task\n"
+ "DEADLINE: <2026-07-10 Fri>\n:PROPERTIES:\n:K: v\n:END:\n"
+ "Body ~verbatim~ =code= [[https://x.org][link]].\n"
+ "| a | b |\n|---+---|\n| 1 | 2 |\n"
+ "#+begin_src sh\necho hi\n#+end_src\n"
+ "- [X] done item\n")
+ (org-mode)
+ (font-lock-ensure)
+ (let ((p (point-min)))
+ (while (< p (point-max))
+ (dolist (f (let ((v (get-text-property p 'face)))
+ (if (listp v) v (list v))))
+ (when (and f (symbolp f)) (puthash f t used)))
+ (dolist (prop '(line-prefix wrap-prefix))
+ (let ((s (get-text-property p prop)))
+ (when (stringp s)
+ (dolist (f (let ((v (get-text-property 0 'face s)))
+ (if (listp v) v (list v))))
+ (when (and f (symbolp f)) (puthash f t used))))))
+ (setq p (1+ p)))))
+ (let (unmapped)
+ (maphash (lambda (face _v)
+ (unless (memq face allowed) (push face unmapped)))
+ used)
+ (should (equal nil (sort unmapped #'string<))))))
+
(ert-deftest test-auto-dim-config-keyword-faces-keep-dim-variants ()
"Boundary: org TODO-keyword faces keep dedicated -dim variants, not flat dim.
Keyword status is scanned across unfocused windows, so it earns a variant;