diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-14 17:23:37 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-14 17:23:37 -0500 |
| commit | 7ccc3f5c0d688914eff0f8501f85d3f40ab8601d (patch) | |
| tree | 96c1669768a87345747a441fa3effd265d5a74b3 /tests/test-ui-buffer-status-colors.el | |
| parent | abaf96f1b4b9efc296161e2315549f55377740b4 (diff) | |
| download | dotemacs-7ccc3f5c0d688914eff0f8501f85d3f40ab8601d.tar.gz dotemacs-7ccc3f5c0d688914eff0f8501f85d3f40ab8601d.zip | |
refactor(ui): color the cursor and modeline from theme faces, in sync
The cursor color and the modeline buffer-name indicator both hard-coded hex colors through cj/buffer-status-colors. Replaced that constant with cj/buffer-status-faces, mapping each buffer state to a theme face: read-only to error, overwrite and modified to warning, unmodified to success. A shared classifier (cj/buffer-status-state) and resolver (cj/buffer-status-color) in user-constants now drive both consumers, so the cursor and the modeline resolve their color from the active theme at use time and stay in sync, including the ghostel-terminal case the cursor already special-cased. Tests cover the map, the classifier, the resolver, and both integration paths.
Diffstat (limited to 'tests/test-ui-buffer-status-colors.el')
| -rw-r--r-- | tests/test-ui-buffer-status-colors.el | 243 |
1 files changed, 60 insertions, 183 deletions
diff --git a/tests/test-ui-buffer-status-colors.el b/tests/test-ui-buffer-status-colors.el index bb905ad4d..06e466b85 100644 --- a/tests/test-ui-buffer-status-colors.el +++ b/tests/test-ui-buffer-status-colors.el @@ -1,8 +1,11 @@ -;;; test-ui-buffer-status-colors.el --- Tests for buffer status colors -*- lexical-binding: t; -*- +;;; test-ui-buffer-status-colors.el --- Tests for buffer-status faces -*- lexical-binding: t; -*- ;;; Commentary: -;; Unit tests for buffer status color system. -;; Tests the state detection logic used by both cursor color and modeline. +;; The buffer-status state classifier (`cj/buffer-status-state'), the state->face +;; map (`cj/buffer-status-faces'), and the resolver (`cj/buffer-status-color') +;; drive both the cursor color and the modeline buffer-name color, kept in sync. +;; Theme faces (error / warning / success) replace the old hard-coded hexes so +;; the colors follow whatever theme is loaded. ;;; Code: @@ -11,211 +14,85 @@ (require 'ui-config) (require 'modeline-config) -;;; Color Constant Tests +;;; State -> face map -(ert-deftest test-buffer-status-colors-has-all-states () - "Test that all required states are defined in color alist." - (should (alist-get 'read-only cj/buffer-status-colors)) - (should (alist-get 'overwrite cj/buffer-status-colors)) - (should (alist-get 'modified cj/buffer-status-colors)) - (should (alist-get 'unmodified cj/buffer-status-colors))) +(ert-deftest test-buffer-status-faces-has-all-states () + "Normal: every buffer state is mapped to a face." + (dolist (state '(read-only overwrite modified unmodified)) + (should (alist-get state cj/buffer-status-faces)))) -(ert-deftest test-buffer-status-colors-values-are-strings () - "Test that all color values are strings (hex colors)." - (dolist (entry cj/buffer-status-colors) - (should (stringp (cdr entry))) - ;; Check if it looks like a hex color - (should (string-match-p "^#[0-9a-fA-F]\\{6\\}$" (cdr entry))))) +(ert-deftest test-buffer-status-faces-values-are-real-faces () + "Normal: every mapped value is an existing face." + (dolist (entry cj/buffer-status-faces) + (should (facep (cdr entry))))) -;;; Cursor Color State Detection Tests +(ert-deftest test-buffer-status-faces-mapping () + "Normal: read-only->error, overwrite/modified->warning, unmodified->success." + (should (eq (alist-get 'read-only cj/buffer-status-faces) 'error)) + (should (eq (alist-get 'overwrite cj/buffer-status-faces) 'warning)) + (should (eq (alist-get 'modified cj/buffer-status-faces) 'warning)) + (should (eq (alist-get 'unmodified cj/buffer-status-faces) 'success))) -(ert-deftest test-cursor-color-state-read-only-buffer () - "Test state detection for read-only buffer." +;;; State classifier (the shared function, exercised directly) + +(ert-deftest test-buffer-status-state-read-only () + "Normal: a read-only buffer reports `read-only'." (with-temp-buffer (setq buffer-read-only t) - (let* ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified)))) - (should (eq state 'read-only))))) - -(ert-deftest test-cursor-color-state-overwrite-mode () - "Test state detection for overwrite mode." + (should (eq (cj/buffer-status-state) 'read-only)))) + +(ert-deftest test-buffer-status-state-overwrite-wins-over-modified () + "Boundary: overwrite-mode takes priority over the modified state." (with-temp-buffer - (setq buffer-read-only nil) + (insert "x") (overwrite-mode 1) - (let* ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified)))) - (should (eq state 'overwrite))))) - -(ert-deftest test-cursor-color-state-modified-buffer () - "Test state detection for modified buffer." + (should (eq (cj/buffer-status-state) 'overwrite)))) + +(ert-deftest test-buffer-status-state-modified () + "Normal: a writeable buffer with unsaved changes reports `modified'." (with-temp-buffer - (setq buffer-read-only nil) - (insert "test") - (set-buffer-modified-p t) - (let* ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified)))) - (should (eq state 'modified))))) - -(ert-deftest test-cursor-color-state-unmodified-buffer () - "Test state detection for unmodified buffer." + (insert "x") + (should (eq (cj/buffer-status-state) 'modified)))) + +(ert-deftest test-buffer-status-state-unmodified () + "Normal: a clean writeable buffer reports `unmodified'." (with-temp-buffer - (setq buffer-read-only nil) (set-buffer-modified-p nil) - (let* ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified)))) - (should (eq state 'unmodified))))) - -(ert-deftest test-cursor-color-state-priority-read-only-over-modified () - "Test that read-only state takes priority over modified state." + (should (eq (cj/buffer-status-state) 'unmodified)))) + +(ert-deftest test-buffer-status-state-read-only-wins-over-modified () + "Boundary: read-only takes priority over modified." (with-temp-buffer - (insert "test") + (insert "x") (set-buffer-modified-p t) (setq buffer-read-only t) - (let* ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified)))) - (should (eq state 'read-only))))) - -(ert-deftest test-cursor-color-state-priority-overwrite-over-modified () - "Test that overwrite mode takes priority over modified state." - (with-temp-buffer - (insert "test") - (set-buffer-modified-p t) - (overwrite-mode 1) - (let* ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified)))) - (should (eq state 'overwrite))))) + (should (eq (cj/buffer-status-state) 'read-only)))) -;;; Integration Tests - Cursor Color Function +;;; Resolver -(ert-deftest test-cursor-color-function-exists () - "Test that cursor color function is defined." - (should (fboundp 'cj/set-cursor-color-according-to-mode))) +(ert-deftest test-buffer-status-color-resolves-through-the-face () + "Normal: the color is the mapped face's foreground." + (let ((orig (face-attribute 'error :foreground nil t))) + (unwind-protect + (progn + (set-face-foreground 'error "#abcdef") + (should (equal (cj/buffer-status-color 'read-only) "#abcdef"))) + (when (stringp orig) (set-face-foreground 'error orig))))) -(ert-deftest test-cursor-color-returns-correct-color-for-read-only () - "Test cursor color function returns red for read-only buffer." - (with-temp-buffer - (setq buffer-read-only t) - (let* ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified))) - (color (alist-get state cj/buffer-status-colors))) - (should (equal color "#f06a3f"))))) - -(ert-deftest test-cursor-color-returns-correct-color-for-overwrite () - "Test cursor color function returns gold for overwrite mode." - (with-temp-buffer - (overwrite-mode 1) - (let* ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified))) - (color (alist-get state cj/buffer-status-colors))) - (should (equal color "#c48702"))))) - -(ert-deftest test-cursor-color-returns-correct-color-for-modified () - "Test cursor color function returns green for modified buffer." - (with-temp-buffer - (insert "test") - (set-buffer-modified-p t) - (let* ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified))) - (color (alist-get state cj/buffer-status-colors))) - (should (equal color "#64aa0f"))))) - -(ert-deftest test-cursor-color-returns-correct-color-for-unmodified () - "Test cursor color function returns white for unmodified buffer." - (with-temp-buffer - (set-buffer-modified-p nil) - (let* ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified))) - (color (alist-get state cj/buffer-status-colors))) - (should (equal color "#ffffff"))))) +(ert-deftest test-buffer-status-color-nil-for-unknown-state () + "Error: an unknown state has no face, so no color." + (should-not (cj/buffer-status-color 'nonexistent))) -;;; Modeline Integration Tests +;;; Modeline integration (ert-deftest test-modeline-buffer-name-variable-exists () - "Test that modeline buffer name variable is defined." + "Normal: the modeline buffer-name construct is defined." (should (boundp 'cj/modeline-buffer-name))) (ert-deftest test-modeline-buffer-name-is-mode-line-construct () - "Test that modeline buffer name is a valid mode-line construct." + "Normal: it is an :eval mode-line construct." (should (listp cj/modeline-buffer-name)) (should (eq (car cj/modeline-buffer-name) :eval))) -;;; Edge Cases - -(ert-deftest test-buffer-status-new-buffer-starts-unmodified () - "Test that new buffer starts in unmodified state." - (with-temp-buffer - (let* ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified)))) - (should (eq state 'unmodified))))) - -(ert-deftest test-buffer-status-insert-makes-modified () - "Test that inserting text changes state to modified." - (with-temp-buffer - ;; Initially unmodified - (set-buffer-modified-p nil) - (let ((state1 (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified)))) - (should (eq state1 'unmodified))) - - ;; Insert text - (insert "test") - (let ((state2 (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified)))) - (should (eq state2 'modified))))) - -(ert-deftest test-buffer-status-explicit-unmodify () - "Test that explicitly setting unmodified works." - (with-temp-buffer - (insert "test") - (should (buffer-modified-p)) - - ;; Explicitly set unmodified - (set-buffer-modified-p nil) - (let ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified)))) - (should (eq state 'unmodified))))) - (provide 'test-ui-buffer-status-colors) ;;; test-ui-buffer-status-colors.el ends here |
