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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
;;; testutil-wttrin.el --- Test utilities for wttrin -*- lexical-binding: t; -*-
;; Copyright (C) 2025 Craig Jennings
;;; Commentary:
;; Shared test utilities for wttrin test suite.
;; Provides helper functions, fixtures, and common setup/teardown functionality.
;;; Code:
(require 'ert)
;;; Test Data Fixtures
(defconst testutil-wttrin-sample-weather-response
"Weather report: Paris, France
\\ / Partly cloudy
_ /\"\".-. 22 °C
\\_( ). ↓ 15 km/h
/(___(__) 10 km
0.0 mm"
"Sample weather response for testing parsing logic.")
(defconst testutil-wttrin-sample-error-response
"ERROR: Unknown location; please try ~curl wttr.in/:help"
"Sample error response from wttr.in service.")
(defconst testutil-wttrin-sample-ansi-response
"Weather report: Paris
\x1b[38;5;226m \\ /\x1b[0m Partly cloudy
\x1b[38;5;226m _ /\"\"\x1b[38;5;250m.-.\x1b[0m \x1b[38;5;118m+13\x1b[0m(\x1b[38;5;082m12\x1b[0m) °C
\x1b[38;5;226m \\_\x1b[38;5;250m( ). \x1b[0m ↑ \x1b[38;5;190m12\x1b[0m km/h
"
"Sample weather data with ANSI color codes for testing rendering.")
(defconst testutil-wttrin-sample-full-weather
"Weather for Berkeley, CA
\\ / Clear
.-. 62 °F
― ( ) ― ↑ 5 mph
`-' 10 mi
/ \\ 0.0 in"
"Sample full weather display data for integration tests.")
;;; Cache Testing Helpers
(defun testutil-wttrin-clear-cache ()
"Clear the wttrin cache for test isolation."
(clrhash wttrin--cache))
(defun testutil-wttrin-add-to-cache (location data &optional age-seconds)
"Add DATA to cache for LOCATION, optionally aged by AGE-SECONDS."
(let* ((cache-key (wttrin--make-cache-key location))
(timestamp (if age-seconds
(- (float-time) age-seconds)
(float-time))))
(puthash cache-key (cons timestamp data) wttrin--cache)))
(defun testutil-wttrin-cache-size ()
"Return the current number of entries in the cache."
(hash-table-count wttrin--cache))
;;; Custom Variable Management
(defmacro testutil-wttrin-with-unit-system (unit-system &rest body)
"Execute BODY with wttrin-unit-system temporarily set to UNIT-SYSTEM."
(declare (indent 1))
`(let ((wttrin-unit-system ,unit-system))
,@body))
(defmacro testutil-wttrin-with-cache-ttl (ttl &rest body)
"Execute BODY with wttrin-cache-ttl temporarily set to TTL."
(declare (indent 1))
`(let ((wttrin-cache-ttl ,ttl))
,@body))
(defmacro testutil-wttrin-with-cache-max (max-entries &rest body)
"Execute BODY with wttrin-cache-max-entries temporarily set to MAX-ENTRIES."
(declare (indent 1))
`(let ((wttrin-cache-max-entries ,max-entries))
,@body))
;;; Buffer Management
(defmacro testutil-wttrin-with-clean-weather-buffer (&rest body)
"Execute BODY with clean *wttr.in* buffer setup/teardown."
(declare (indent 0))
`(progn
(when (get-buffer "*wttr.in*")
(kill-buffer "*wttr.in*"))
(unwind-protect
(progn ,@body)
(when (get-buffer "*wttr.in*")
(kill-buffer "*wttr.in*")))))
;;; HTTP Mock Helpers
(defmacro testutil-wttrin-mock-http-response (response-body &rest body)
"Mock url-retrieve to return HTTP 200 with RESPONSE-BODY, execute BODY."
(declare (indent 1))
`(cl-letf (((symbol-function 'url-retrieve)
(lambda (url callback)
(with-temp-buffer
(insert "HTTP/1.1 200 OK\n\n")
(insert ,response-body)
(funcall callback nil)))))
,@body))
;;; Test Setup and Teardown
(defun testutil-wttrin-setup ()
"Common setup for wttrin tests.
Call this at the beginning of each test."
(testutil-wttrin-clear-cache)
(setq wttrin--force-refresh nil))
(defun testutil-wttrin-teardown ()
"Common teardown for wttrin tests.
Call this at the end of each test."
(testutil-wttrin-clear-cache)
(setq wttrin--force-refresh nil))
(provide 'testutil-wttrin)
;;; testutil-wttrin.el ends here
|