blob: 20adf06ca8e1bd4e9832e00db3be789eea0a4e09 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
;;; test-wttrin-mode-initialization-order.el --- Test mode initialization order -*- lexical-binding: t; -*-
;; Copyright (C) 2025 Craig Jennings
;;; 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.
;;
;; 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.
;;; Code:
(require 'ert)
(require 'wttrin)
(require 'testutil-wttrin)
(defun test-wttrin-mode-init-setup ()
"Setup for mode initialization tests."
(testutil-wttrin-setup)
(when (get-buffer "*wttr.in*")
(kill-buffer "*wttr.in*")))
(defun test-wttrin-mode-init-teardown ()
"Teardown for mode initialization tests."
(testutil-wttrin-teardown)
(when (get-buffer "*wttr.in*")
(kill-buffer "*wttr.in*")))
(ert-deftest test-wttrin-mode-initialization-order-mode-before-buffer-local-vars ()
"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.
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"
(test-wttrin-mode-init-setup)
(unwind-protect
(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))))
(test-wttrin-mode-init-teardown)))
(ert-deftest test-wttrin-mode-initialization-order-xterm-color-state-survives ()
"Test that xterm-color--state remains buffer-local after wttrin--display-weather.
This verifies that the state isn't wiped by kill-all-local-variables."
(test-wttrin-mode-init-setup)
(unwind-protect
(progn
(wttrin--display-weather "London" "Test data")
(should (get-buffer "*wttr.in*"))
(with-current-buffer "*wttr.in*"
;; xterm-color--state should be buffer-local
(should (local-variable-p 'xterm-color--state))
;; It should have the correct value
(should (eq xterm-color--state :char))))
(test-wttrin-mode-init-teardown)))
(provide 'test-wttrin-mode-initialization-order)
;;; test-wttrin-mode-initialization-order.el ends here
|