aboutsummaryrefslogtreecommitdiff
path: root/tests/test-integration-debug.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-02-17 19:14:14 -0600
committerCraig Jennings <c@cjennings.net>2026-02-17 19:14:14 -0600
commit28b7e4cecadce207d532b8d42346c3823450a35f (patch)
tree4d8772206e10c59762ae1e60343d4bc8dded77b5 /tests/test-integration-debug.el
parentbf989bb594680eb2e3b69f55752353aa33cb47bb (diff)
downloademacs-wttrin-28b7e4cecadce207d532b8d42346c3823450a35f.tar.gz
emacs-wttrin-28b7e4cecadce207d532b8d42346c3823450a35f.zip
refactor: tests: standardize naming, consolidate files, and expand testutil
- Expand testutil-wttrin.el with shared fixtures and macros (testutil-wttrin-with-clean-weather-buffer, testutil-wttrin-mock-http-response, sample ANSI/weather constants) - Consolidate cache tests: port unique tests from cleanup-cache-constants and cleanup-cache-refactored into cleanup-cache-if-needed, delete obsolete files - Extract startup-delay tests into dedicated file - Add setup/teardown and (require 'testutil-wttrin) to all test files - Rename all 160 tests to follow test-<module>-<category>-<scenario>-<expected-result> convention - Rename integration test file and add detailed docstrings - Update Makefile glob to discover new integration test naming pattern Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'tests/test-integration-debug.el')
-rw-r--r--tests/test-integration-debug.el292
1 files changed, 292 insertions, 0 deletions
diff --git a/tests/test-integration-debug.el b/tests/test-integration-debug.el
new file mode 100644
index 0000000..db2706b
--- /dev/null
+++ b/tests/test-integration-debug.el
@@ -0,0 +1,292 @@
+;;; test-integration-debug.el --- Integration test with debug enabled -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2024 Craig Jennings
+
+;;; Commentary:
+;; Comprehensive integration test that:
+;; 1. Enables debug mode
+;; 2. Mocks weather fetch to avoid network calls
+;; 3. Tests mode-line display with real weather data
+;; 4. Verifies debug log captures key events
+
+;;; Code:
+
+(require 'ert)
+(require 'wttrin)
+(require 'testutil-wttrin)
+
+;; Sample weather data from wttr.in custom format API
+(defconst test-wttrin-sample-weather-data
+ "Berkeley, CA: ☀️ +62°F Clear"
+ "Sample weather data in wttr.in custom format.")
+
+;;; Setup and Teardown
+
+(defun test-integration-debug-setup ()
+ "Set up test environment with debug enabled."
+ ;; Enable debug mode
+ (setq wttrin-debug t)
+ ;; Load debug module if not already loaded
+ (unless (featurep 'wttrin-debug)
+ (require 'wttrin-debug))
+ ;; Clear any existing debug log
+ (wttrin-debug-clear-log)
+ ;; Clear cache
+ (wttrin-clear-cache)
+ ;; Set test configuration
+ (setq wttrin-favorite-location "Berkeley, CA")
+ (setq wttrin-mode-line-startup-delay 1) ; Minimum valid value
+ (setq wttrin-unit-system "m"))
+
+(defun test-integration-debug-teardown ()
+ "Clean up after tests."
+ (when (boundp 'wttrin-mode-line-mode)
+ (wttrin-mode-line-mode -1))
+ (wttrin-clear-cache)
+ (wttrin-debug-clear-log)
+ (setq wttrin-mode-line-string nil)
+ (setq wttrin--mode-line-tooltip-data nil))
+
+;;; Mock URL Fetching
+
+(defvar test-wttrin--original-fetch-url nil
+ "Original wttrin--fetch-url function for restoration after test.")
+
+(defun test-integration-debug-mock-fetch (url callback)
+ "Mock version of wttrin--fetch-url that returns fake weather data.
+URL is ignored. CALLBACK is called with mock data."
+ (when (featurep 'wttrin-debug)
+ (wttrin--debug-log "MOCK-FETCH: Called with URL: %s" url))
+ ;; Call callback directly (synchronous) since run-at-time doesn't work well in batch mode
+ (when (featurep 'wttrin-debug)
+ (wttrin--debug-log "MOCK-FETCH: Calling callback with mock data"))
+ (funcall callback test-wttrin-sample-weather-data))
+
+(defmacro test-integration-debug-with-mocked-fetch (&rest body)
+ "Execute BODY with wttrin--fetch-url mocked to return test data."
+ `(let ((test-wttrin--original-fetch-url (symbol-function 'wttrin--fetch-url)))
+ (unwind-protect
+ (progn
+ (fset 'wttrin--fetch-url #'test-integration-debug-mock-fetch)
+ ,@body)
+ (fset 'wttrin--fetch-url test-wttrin--original-fetch-url))))
+
+;;; Integration Tests
+
+(ert-deftest test-integration-debug-mode-line-fetch-and-display-logs-events ()
+ "Test the mode-line weather fetch and display pipeline with debug logging.
+
+Context: The mode-line weather feature fetches weather data asynchronously
+and updates the mode-line string with an emoji icon and tooltip.
+
+Components integrated:
+- `wttrin--mode-line-fetch-weather' (async fetch trigger)
+- `wttrin--mode-line-update-display' (mode-line string formatting)
+- `wttrin--debug-log' (debug event capture)
+
+Validates that a successful fetch sets the mode-line string with an emoji,
+stores tooltip data, and logs fetch-start, data-received, display-update,
+and emoji-extraction events to the debug log."
+ (test-integration-debug-setup)
+ (unwind-protect
+ (test-integration-debug-with-mocked-fetch
+ ;; Clear debug log
+ (wttrin-debug-clear-log)
+
+ ;; Fetch weather for mode-line
+ (wttrin--mode-line-fetch-weather)
+
+ ;; Wait for async callback to complete (mocked, so should be fast)
+ (sleep-for 0.1)
+
+ ;; Verify mode-line string was set
+ (should wttrin-mode-line-string)
+ (should (stringp wttrin-mode-line-string))
+ (should (string-match-p "☀" wttrin-mode-line-string)) ; Should contain emoji
+
+ ;; Verify tooltip data was set
+ (should wttrin--mode-line-tooltip-data)
+ (should (string= test-wttrin-sample-weather-data wttrin--mode-line-tooltip-data))
+
+ ;; Verify debug log captured key events
+ (let ((log-messages (mapcar #'cdr wttrin--debug-log)))
+ ;; Should have logged the fetch start
+ (should (seq-some (lambda (msg) (string-match-p "mode-line-fetch: Starting" msg))
+ log-messages))
+ ;; Should have logged receiving data
+ (should (seq-some (lambda (msg) (string-match-p "mode-line-fetch: Received data" msg))
+ log-messages))
+ ;; Should have logged display update
+ (should (seq-some (lambda (msg) (string-match-p "mode-line-display:" msg))
+ log-messages))
+ ;; Should have logged emoji extraction
+ (should (seq-some (lambda (msg) (string-match-p "Extracted emoji" msg))
+ log-messages))))
+ (test-integration-debug-teardown)))
+
+(ert-deftest test-integration-debug-full-weather-query-creates-buffer ()
+ "Test the full weather query pipeline from fetch through buffer display.
+
+Context: When a user calls `wttrin-query', the system fetches weather data,
+processes it through ANSI filtering, and displays it in a dedicated buffer.
+
+Components integrated:
+- `wttrin-query' (user-facing entry point)
+- `wttrin--fetch-url' (HTTP fetch, mocked)
+- `wttrin--display-weather' (buffer creation and content rendering)
+- `wttrin--debug-log' (debug event capture)
+
+Validates that a full weather query creates the *wttr.in* buffer and
+that the debug log records the mock fetch call."
+ (test-integration-debug-setup)
+ (unwind-protect
+ (progn
+ ;; Clear debug log
+ (wttrin-debug-clear-log)
+
+ ;; Mock full weather fetch (synchronous for batch mode)
+ (cl-letf (((symbol-function 'wttrin--fetch-url)
+ (lambda (url callback)
+ (when (featurep 'wttrin-debug)
+ (wttrin--debug-log "MOCK-FETCH: Full weather query for URL: %s" url))
+ ;; Call directly instead of using run-at-time (doesn't work in batch)
+ (funcall callback testutil-wttrin-sample-full-weather))))
+
+ ;; Start the query (now synchronous with mocked fetch)
+ (wttrin-query "Berkeley, CA")
+
+ ;; Verify buffer was created
+ (should (get-buffer "*wttr.in*"))
+
+ ;; Verify debug log shows mock was called
+ (let ((log-messages (mapcar #'cdr wttrin--debug-log)))
+ ;; Should have logged the mock fetch
+ (should (seq-some (lambda (msg) (string-match-p "MOCK-FETCH: Full weather query" msg))
+ log-messages)))))
+ ;; Cleanup
+ (when (get-buffer "*wttr.in*")
+ (kill-buffer "*wttr.in*"))
+ (test-integration-debug-teardown)))
+
+(ert-deftest test-integration-debug-mode-line-mode-toggle-updates-global-string ()
+ "Test enabling and disabling wttrin-mode-line-mode updates global state.
+
+Context: `wttrin-mode-line-mode' is a global minor mode that adds a weather
+widget to the Emacs mode-line. Toggling it should cleanly add/remove state.
+
+Components integrated:
+- `wttrin-mode-line-mode' (global minor mode toggle)
+- `wttrin--mode-line-fetch-weather' (initial data fetch)
+- `global-mode-string' (Emacs mode-line display list)
+
+Validates that enabling the mode sets `wttrin-mode-line-string' and adds it
+to `global-mode-string', and that disabling clears both."
+ (test-integration-debug-setup)
+ (unwind-protect
+ (test-integration-debug-with-mocked-fetch
+ ;; Clear debug log
+ (wttrin-debug-clear-log)
+
+ ;; Enable mode-line mode
+ (wttrin-mode-line-mode 1)
+ (should wttrin-mode-line-mode)
+
+ ;; Manually trigger the initial fetch instead of waiting for timer
+ ;; (timers don't process well in batch mode)
+ (wttrin--mode-line-fetch-weather)
+
+ ;; Verify mode-line string is set
+ (should wttrin-mode-line-string)
+
+ ;; Verify global-mode-string contains our widget
+ (should (member 'wttrin-mode-line-string global-mode-string))
+
+ ;; Disable mode-line mode
+ (wttrin-mode-line-mode -1)
+ (should-not wttrin-mode-line-mode)
+
+ ;; Verify mode-line string is cleared
+ (should-not wttrin-mode-line-string)
+
+ ;; Verify removed from global-mode-string
+ (should-not (member 'wttrin-mode-line-string global-mode-string)))
+ (test-integration-debug-teardown)))
+
+(ert-deftest test-integration-debug-error-handling-logs-no-data-received ()
+ "Test that network errors are handled gracefully and logged to debug.
+
+Context: When wttr.in is unreachable or returns an error, the fetch callback
+receives nil. The mode-line handler should not crash and should log the error.
+
+Components integrated:
+- `wttrin--mode-line-fetch-weather' (fetch trigger)
+- `wttrin--fetch-url' (HTTP fetch, mocked to return nil)
+- `wttrin--debug-log' (error event capture)
+
+Validates that a nil fetch response does not crash and that a
+\"No data received\" message is recorded in the debug log."
+ (test-integration-debug-setup)
+ (unwind-protect
+ (progn
+ ;; Clear debug log
+ (wttrin-debug-clear-log)
+
+ ;; Mock fetch that returns nil (simulating network error)
+ (cl-letf (((symbol-function 'wttrin--fetch-url)
+ (lambda (url callback)
+ (when (featurep 'wttrin-debug)
+ (wttrin--debug-log "MOCK-FETCH: Simulating error for URL: %s" url))
+ (run-at-time 0 nil (lambda () (funcall callback nil))))))
+
+ ;; Try to fetch (should handle error gracefully)
+ (wttrin--mode-line-fetch-weather)
+
+ ;; Wait for async callback
+ (sleep-for 0.1)
+
+ ;; Verify error was logged
+ (let ((log-messages (mapcar #'cdr wttrin--debug-log)))
+ (should (seq-some (lambda (msg) (string-match-p "No data received" msg))
+ log-messages)))))
+ (test-integration-debug-teardown)))
+
+(ert-deftest test-integration-debug-log-inspection-stores-timestamped-entries ()
+ "Test that the debug log stores structured entries that can be inspected.
+
+Context: The debug log is an alist of (timestamp . message) pairs used for
+diagnosing issues. It should support programmatic inspection and clearing.
+
+Components integrated:
+- `wttrin--debug-log' (log writing)
+- `wttrin-debug-clear-log' (log clearing)
+- `wttrin--debug-log' variable (log storage as alist)
+
+Validates that log entries are (string . string) cons cells, that formatted
+messages are stored correctly, and that clearing empties the log."
+ (test-integration-debug-setup)
+ (unwind-protect
+ (progn
+ ;; Clear and add some test log entries
+ (wttrin-debug-clear-log)
+ (wttrin--debug-log "Test message 1")
+ (wttrin--debug-log "Test message 2 with arg: %s" "value")
+
+ ;; Verify log structure
+ (should (= 2 (length wttrin--debug-log)))
+ (should (consp (car wttrin--debug-log))) ; Each entry is (timestamp . message)
+ (should (stringp (caar wttrin--debug-log))) ; Timestamp is string
+ (should (stringp (cdar wttrin--debug-log))) ; Message is string
+
+ ;; Verify messages
+ (let ((messages (mapcar #'cdr wttrin--debug-log)))
+ (should (member "Test message 1" messages))
+ (should (seq-some (lambda (msg) (string-match-p "Test message 2.*value" msg))
+ messages)))
+
+ ;; Clear log
+ (wttrin-debug-clear-log)
+ (should (= 0 (length wttrin--debug-log))))
+ (test-integration-debug-teardown)))
+
+(provide 'test-integration-debug)
+;;; test-integration-debug.el ends here