aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-05 09:37:12 -0500
committerCraig Jennings <c@cjennings.net>2026-05-05 09:37:12 -0500
commitb83865a65eb744f6d36c1c672a4d83a59d6383f8 (patch)
tree02619079973580147ccf2cf2e7e4567b7d69e022 /tests
parent14195e10b01fec3d9ded6e664a416c5cf3d33cc9 (diff)
downloademacs-wttrin-b83865a65eb744f6d36c1c672a4d83a59d6383f8.tar.gz
emacs-wttrin-b83865a65eb744f6d36c1c672a4d83a59d6383f8.zip
fix(ci): rewrite mode-init-order test and retry deps install
Two CI failures from the first run, neither a real bug in production code. The Emacs-snapshot job failed on `test-wttrin-mode-initialization-order-normal-mode-before-buffer-local-vars-calls-mode-first`. The original test mocked the `set' primitive to detect when `xterm-color--state' was first set. That worked on the byte-code path some older Emacs versions used, but `setq-local' doesn't go through the `set' function on Emacs master, so the mock never fired and the assertion read nil. The test was already brittle in isolation locally too. Rewrote the test to use `advice-add :before' on `wttrin-mode' and `make-local-variable'. Both are ordinary advisable functions, and `make-local-variable' is on the code path for every form that defines a buffer-local binding (`setq-local', `defvar-local', etc.) so the observation holds across Emacs versions. Renamed the test to drop "calls-mode-first" and use "mode-runs-before-xterm-color-state-binding" since that's what the new advice actually observes. The Emacs 26.3 job failed with a transient DNS error from elpa.gnu.org during `make deps'. Wrapped the install step in a 3-attempt retry with a 15-second backoff so a runner-side network blip doesn't fail the build. Applied to all three jobs (test, lint, coverage) since they all hit the same archives.
Diffstat (limited to 'tests')
-rw-r--r--tests/test-wttrin-mode-initialization-order.el89
1 files changed, 47 insertions, 42 deletions
diff --git a/tests/test-wttrin-mode-initialization-order.el b/tests/test-wttrin-mode-initialization-order.el
index 1def5f0..6554b64 100644
--- a/tests/test-wttrin-mode-initialization-order.el
+++ b/tests/test-wttrin-mode-initialization-order.el
@@ -5,19 +5,46 @@
;;; Commentary:
;; This test verifies that wttrin--display-weather initializes wttrin-mode
-;; BEFORE setting buffer-local variables. This prevents kill-all-local-variables
-;; (called by derived modes) from wiping out important state like xterm-color--state.
+;; BEFORE making `xterm-color--state' buffer-local. This prevents
+;; kill-all-local-variables (called by derived modes) from wiping out
+;; important state.
;;
;; Bug context: On fresh Emacs launch, weather displayed with no colors because
;; xterm-color--state was set buffer-local BEFORE wttrin-mode was called, and
;; wttrin-mode's kill-all-local-variables wiped it out.
+;;
+;; Earlier versions of this file mocked the `set' primitive to observe the
+;; ordering. That was fragile because `setq-local' doesn't always go through
+;; the `set' function -- the byte-code path differs across Emacs versions, and
+;; on Emacs master the mock missed the assignment entirely. This rewrite uses
+;; `advice-add' on `wttrin-mode' and `make-local-variable', both of which are
+;; ordinary advisable functions guaranteed to be invoked on every code path
+;; that defines a buffer-local binding.
;;; Code:
(require 'ert)
+(require 'cl-lib)
(require 'wttrin)
(require 'testutil-wttrin)
+(defvar test-wttrin--init-events nil
+ "Ordered list of init events captured during the order test.
+Each entry is `mode' or `xterm-color', recorded by advice on
+`wttrin-mode' and `make-local-variable' respectively. Reset before
+each test run.")
+
+(defun test-wttrin--record-mode-call (&rest _args)
+ "Advice that records a `mode' event when `wttrin-mode' runs."
+ (push 'mode test-wttrin--init-events))
+
+(defun test-wttrin--record-mlv-call (symbol &rest _args)
+ "Advice that records an `xterm-color' event when SYMBOL is the target.
+Only triggers for `xterm-color--state' so unrelated buffer-local
+declarations don't pollute the timeline."
+ (when (eq symbol 'xterm-color--state)
+ (push 'xterm-color test-wttrin--init-events)))
+
;;; Setup and Teardown
(defun test-wttrin-mode-init-setup ()
@@ -34,50 +61,28 @@
;;; Tests
-(ert-deftest test-wttrin-mode-initialization-order-normal-mode-before-buffer-local-vars-calls-mode-first ()
- "Test that wttrin-mode is activated before setting buffer-local variables.
-
-This test verifies the fix for the color rendering bug where xterm-color--state
-was wiped by kill-all-local-variables.
+(ert-deftest test-wttrin-mode-initialization-order-normal-mode-runs-before-xterm-color-state-binding ()
+ "Verify wttrin-mode runs before xterm-color--state is made buffer-local.
-The test strategy:
-1. Advise wttrin-mode to record when it's called
-2. Advise setq-local to record when buffer-local vars are set
-3. Call wttrin--display-weather
-4. Verify wttrin-mode was called BEFORE any buffer-local vars were set"
+If `make-local-variable' for `xterm-color--state' ran first, the subsequent
+`wttrin-mode' call would invoke `kill-all-local-variables' and wipe the
+state, leaving the rendered buffer without ANSI colors. Observing the
+ordering directly catches a regression that re-introduces the bug even if
+the outcome test happens to pass on a particular Emacs version."
(test-wttrin-mode-init-setup)
+ (setq test-wttrin--init-events nil)
+ (advice-add 'wttrin-mode :before #'test-wttrin--record-mode-call)
+ (advice-add 'make-local-variable :before #'test-wttrin--record-mlv-call)
(unwind-protect
(testutil-wttrin-with-clean-weather-buffer
- (let ((mode-called-at nil)
- (first-setq-local-at nil)
- (call-counter 0))
-
- ;; Advise to track when wttrin-mode is called
- (cl-letf (((symbol-function 'wttrin-mode)
- (let ((orig-fn (symbol-function 'wttrin-mode)))
- (lambda ()
- (setq mode-called-at (cl-incf call-counter))
- (funcall orig-fn))))
-
- ;; Advise to track first buffer-local variable set
- ((symbol-function 'set)
- (let ((orig-fn (symbol-function 'set)))
- (lambda (symbol value)
- ;; Track xterm-color--state specifically
- (when (and (eq symbol 'xterm-color--state)
- (null first-setq-local-at))
- (setq first-setq-local-at (cl-incf call-counter)))
- (funcall orig-fn symbol value)))))
-
- (wttrin--display-weather "Paris" "Test weather data")
-
- ;; Verify mode was called
- (should mode-called-at)
- ;; Verify buffer-local var was set
- (should first-setq-local-at)
- ;; Critical: mode must be called BEFORE buffer-local var
- (should (< mode-called-at first-setq-local-at)))))
-
+ (wttrin--display-weather "Paris" "Test weather data")
+ (let ((order (nreverse test-wttrin--init-events)))
+ (should (memq 'mode order))
+ (should (memq 'xterm-color order))
+ (should (< (cl-position 'mode order)
+ (cl-position 'xterm-color order)))))
+ (advice-remove 'wttrin-mode #'test-wttrin--record-mode-call)
+ (advice-remove 'make-local-variable #'test-wttrin--record-mlv-call)
(test-wttrin-mode-init-teardown)))
(ert-deftest test-wttrin-mode-initialization-order-normal-xterm-color-state-survives-mode-init ()