summaryrefslogtreecommitdiff
path: root/tests/test-wttrin--mode-line-start.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-04-04 12:26:16 -0500
committerCraig Jennings <c@cjennings.net>2026-04-04 12:26:16 -0500
commitea5636c51361b86d132d647ee3548d208394878e (patch)
treea60ab847c7324417ca7de46e73d370ba2af90d05 /tests/test-wttrin--mode-line-start.el
parentb74b98f177d92d50ddbede900ba41212e07c5f63 (diff)
downloademacs-wttrin-ea5636c51361b86d132d647ee3548d208394878e.tar.gz
emacs-wttrin-ea5636c51361b86d132d647ee3548d208394878e.zip
test: add 50 tests for untested functions; fix nil crash in save-debug-data
Add 11 new test files covering wttrin--save-debug-data, wttrin--buffer-cache-refresh, wttrin--mode-line-stop, wttrin--mode-line-start, wttrin-query, wttrin-requery-force, wttrin-mode-line-click, wttrin-mode-line-force-refresh, wttrin-fetch-raw-string, wttrin-clear-cache, and wttrin-requery. Fix bug in wttrin--save-debug-data where nil raw-string caused (insert nil) crash — reachable when debug mode is on and fetch fails. Refactor wttrin-requery: extract wttrin--requery-location so the core kill-buffer-and-query logic is testable without mocking completing-read. 267 tests total (was 217), all passing.
Diffstat (limited to 'tests/test-wttrin--mode-line-start.el')
-rw-r--r--tests/test-wttrin--mode-line-start.el157
1 files changed, 157 insertions, 0 deletions
diff --git a/tests/test-wttrin--mode-line-start.el b/tests/test-wttrin--mode-line-start.el
new file mode 100644
index 0000000..e97c185
--- /dev/null
+++ b/tests/test-wttrin--mode-line-start.el
@@ -0,0 +1,157 @@
+;;; test-wttrin--mode-line-start.el --- Tests for wttrin--mode-line-start -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2025 Craig Jennings
+
+;;; Commentary:
+
+;; Unit tests for wttrin--mode-line-start function.
+;; Tests that starting mode-line display sets up placeholder, timers, and scheduling.
+
+;;; Code:
+
+(require 'ert)
+(require 'wttrin)
+(require 'testutil-wttrin)
+
+;;; Setup and Teardown
+
+(defun test-wttrin--mode-line-start-setup ()
+ "Setup for mode-line-start tests."
+ (testutil-wttrin-setup)
+ (setq wttrin-mode-line-string nil)
+ (setq wttrin--mode-line-cache nil)
+ (setq wttrin--mode-line-timer nil)
+ (setq wttrin--buffer-refresh-timer nil))
+
+(defun test-wttrin--mode-line-start-teardown ()
+ "Teardown for mode-line-start tests."
+ (testutil-wttrin-teardown)
+ (when (timerp wttrin--mode-line-timer)
+ (cancel-timer wttrin--mode-line-timer))
+ (when (timerp wttrin--buffer-refresh-timer)
+ (cancel-timer wttrin--buffer-refresh-timer))
+ (setq wttrin-mode-line-string nil)
+ (setq wttrin--mode-line-cache nil)
+ (setq wttrin--mode-line-timer nil)
+ (setq wttrin--buffer-refresh-timer nil))
+
+;;; Normal Cases
+
+(ert-deftest test-wttrin--mode-line-start-normal-shows-placeholder-immediately ()
+ "Starting mode-line should show the hourglass placeholder right away."
+ (test-wttrin--mode-line-start-setup)
+ (unwind-protect
+ (let ((wttrin-favorite-location "Paris")
+ (wttrin-mode-line-emoji-font nil))
+ ;; Mock run-at-time so no real timers fire
+ (cl-letf (((symbol-function 'run-at-time)
+ (lambda (_time _repeat _func) (list 'mock-timer))))
+ (wttrin--mode-line-start)
+ ;; Placeholder should be visible
+ (should wttrin-mode-line-string)
+ (should (string-match-p "⏳" (substring-no-properties wttrin-mode-line-string)))))
+ (test-wttrin--mode-line-start-teardown)))
+
+(ert-deftest test-wttrin--mode-line-start-normal-schedules-delayed-initial-fetch ()
+ "Initial weather fetch should be scheduled after startup-delay seconds."
+ (test-wttrin--mode-line-start-setup)
+ (unwind-protect
+ (let ((wttrin-favorite-location "Paris")
+ (wttrin-mode-line-startup-delay 5)
+ (scheduled-calls nil))
+ (cl-letf (((symbol-function 'run-at-time)
+ (lambda (time repeat func)
+ (push (list :time time :repeat repeat :func func) scheduled-calls)
+ (list 'mock-timer))))
+ (wttrin--mode-line-start)
+ ;; One of the calls should be the delayed initial fetch
+ (let ((initial-fetch (seq-find (lambda (call)
+ (and (= (plist-get call :time) 5)
+ (null (plist-get call :repeat))))
+ scheduled-calls)))
+ (should initial-fetch)
+ (should (eq (plist-get initial-fetch :func)
+ #'wttrin--mode-line-fetch-weather)))))
+ (test-wttrin--mode-line-start-teardown)))
+
+(ert-deftest test-wttrin--mode-line-start-normal-creates-repeating-mode-line-timer ()
+ "A repeating timer should be created for periodic mode-line refresh."
+ (test-wttrin--mode-line-start-setup)
+ (unwind-protect
+ (let ((wttrin-favorite-location "Paris")
+ (wttrin-mode-line-refresh-interval 3600)
+ (scheduled-calls nil))
+ (cl-letf (((symbol-function 'run-at-time)
+ (lambda (time repeat func)
+ (push (list :time time :repeat repeat :func func) scheduled-calls)
+ (list 'mock-timer))))
+ (wttrin--mode-line-start)
+ ;; Should have a repeating timer for mode-line fetch
+ (let ((repeating-fetch (seq-find (lambda (call)
+ (and (equal (plist-get call :repeat) 3600)
+ (eq (plist-get call :func)
+ #'wttrin--mode-line-fetch-weather)))
+ scheduled-calls)))
+ (should repeating-fetch))))
+ (test-wttrin--mode-line-start-teardown)))
+
+(ert-deftest test-wttrin--mode-line-start-normal-creates-buffer-refresh-timer ()
+ "A repeating timer should be created for periodic buffer cache refresh."
+ (test-wttrin--mode-line-start-setup)
+ (unwind-protect
+ (let ((wttrin-favorite-location "Paris")
+ (wttrin-refresh-interval 3600)
+ (scheduled-calls nil))
+ (cl-letf (((symbol-function 'run-at-time)
+ (lambda (time repeat func)
+ (push (list :time time :repeat repeat :func func) scheduled-calls)
+ (list 'mock-timer))))
+ (wttrin--mode-line-start)
+ ;; Should have a repeating timer for buffer cache refresh
+ (let ((buffer-refresh (seq-find (lambda (call)
+ (and (equal (plist-get call :repeat) 3600)
+ (eq (plist-get call :func)
+ #'wttrin--buffer-cache-refresh)))
+ scheduled-calls)))
+ (should buffer-refresh))))
+ (test-wttrin--mode-line-start-teardown)))
+
+;;; Boundary Cases
+
+(ert-deftest test-wttrin--mode-line-start-boundary-nil-location-skips-setup ()
+ "When no favorite location is set, no timers or placeholder should be created."
+ (test-wttrin--mode-line-start-setup)
+ (unwind-protect
+ (let ((wttrin-favorite-location nil)
+ (run-at-time-called nil))
+ (cl-letf (((symbol-function 'run-at-time)
+ (lambda (_time _repeat _func)
+ (setq run-at-time-called t)
+ (list 'mock-timer))))
+ (wttrin--mode-line-start)
+ (should-not run-at-time-called)
+ (should-not wttrin-mode-line-string)
+ (should-not wttrin--mode-line-timer)))
+ (test-wttrin--mode-line-start-teardown)))
+
+(ert-deftest test-wttrin--mode-line-start-boundary-cancels-existing-timers ()
+ "Starting when timers already exist should cancel old timers before creating new ones."
+ (test-wttrin--mode-line-start-setup)
+ (unwind-protect
+ (let ((wttrin-favorite-location "Paris")
+ (cancelled-timers nil))
+ ;; Create fake existing timers
+ (setq wttrin--mode-line-timer (run-at-time 99999 nil #'ignore))
+ (setq wttrin--buffer-refresh-timer (run-at-time 99999 nil #'ignore))
+ (let ((old-ml-timer wttrin--mode-line-timer)
+ (old-buf-timer wttrin--buffer-refresh-timer))
+ (cl-letf (((symbol-function 'run-at-time)
+ (lambda (_time _repeat _func) (list 'mock-timer))))
+ (wttrin--mode-line-start)
+ ;; Old timers should have been replaced
+ (should-not (eq wttrin--mode-line-timer old-ml-timer))
+ (should-not (eq wttrin--buffer-refresh-timer old-buf-timer)))))
+ (test-wttrin--mode-line-start-teardown)))
+
+(provide 'test-wttrin--mode-line-start)
+;;; test-wttrin--mode-line-start.el ends here