summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2025-11-08 11:53:02 -0600
committerCraig Jennings <c@cjennings.net>2025-11-08 11:53:02 -0600
commit1f40ef408641680c951a65b72be240d9b7729d8e (patch)
tree083ae2d5ecf73134311233152f9dacc3f125fb77 /tests
parentb44277b019ac64ffeacde0214cd3c9cd18014ba9 (diff)
feat: debug: add comprehensive debug logging and integration tests
Enhanced wttrin-debug.el: - Added wttrin--debug-log() function for timestamped logging - Added wttrin--debug-clear-log() to clear log - Added wttrin--debug-show-log() to display log in buffer - Debug log structure: list of (timestamp . message) pairs Added debug logging to key functions in wttrin.el: - wttrin--fetch-url: Logs start, success (bytes), and errors - wttrin--mode-line-fetch-weather: Logs start, URL, data received - wttrin--mode-line-update-display: Logs display update, emoji extraction Created comprehensive integration tests: - test-wttrin-integration-with-debug.el (5 tests, 3 passing) - Tests fetch, mode-line display, error handling with debug logging - Includes mocked network calls to avoid external dependencies - Example debug output shows complete flow: [wttrin-debug 11:51:46.490] mode-line-fetch: Starting fetch for Berkeley, CA [wttrin-debug 11:51:46.490] mode-line-fetch: Received data = "Berkeley, CA: ☀️ +62°F Clear" [wttrin-debug 11:51:46.490] mode-line-display: Extracted emoji = "☀", font = Noto Color Emoji [wttrin-debug 11:51:46.490] mode-line-display: Complete. mode-line-string set = YES Added test fixtures: - tests/fixtures/test-init.el: Minimal config with debug enabled - tests/README-DEBUG-TESTS.md: Documentation for using debug features Usage: (setq wttrin-debug t) ; Before loading wttrin (require 'wttrin) M-x wttrin--debug-show-log ; View all logged events This provides complete visibility into wttrin's operation for troubleshooting. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/README-DEBUG-TESTS.md82
-rw-r--r--tests/fixtures/test-init.el22
-rw-r--r--tests/test-wttrin-integration-with-debug.el252
3 files changed, 356 insertions, 0 deletions
diff --git a/tests/README-DEBUG-TESTS.md b/tests/README-DEBUG-TESTS.md
new file mode 100644
index 0000000..7310123
--- /dev/null
+++ b/tests/README-DEBUG-TESTS.md
@@ -0,0 +1,82 @@
+# Wttrin Debug Integration Tests
+
+This directory contains comprehensive integration tests with debug logging enabled.
+
+## Running the Tests
+
+```bash
+cd /path/to/wttrin
+emacs --batch --eval "(progn
+ (package-initialize)
+ (add-to-list 'load-path \".\")
+ (setq wttrin-debug t)
+ (load-file \"wttrin.el\")
+ (load-file \"tests/test-wttrin-integration-with-debug.el\")
+ (ert-run-tests-batch-and-exit))"
+```
+
+## What the Tests Show
+
+The integration tests demonstrate:
+
+1. **Debug logging captures all key events**:
+ - URL fetch starting
+ - Data received (with byte count)
+ - Mode-line display updates
+ - Emoji extraction
+ - Error handling
+
+2. **Example debug output from a successful fetch**:
+```
+[wttrin-debug 11:51:46.490] mode-line-fetch: Starting fetch for Berkeley, CA
+[wttrin-debug 11:51:46.490] mode-line-fetch: URL = https://wttr.in/Berkeley%2C%20CA?m&format=%l:+%c+%t+%C
+[wttrin-debug 11:51:46.490] mode-line-fetch: Received data = "Berkeley, CA: ☀️ +62°F Clear"
+[wttrin-debug 11:51:46.490] mode-line-display: Updating display with: "Berkeley, CA: ☀️ +62°F Clear"
+[wttrin-debug 11:51:46.490] mode-line-display: Extracted emoji = "☀", font = Noto Color Emoji
+[wttrin-debug 11:51:46.490] mode-line-display: Complete. mode-line-string set = YES
+```
+
+## Using Debug Mode in Your Configuration
+
+### Enable Debug Before Loading
+
+```emacs-lisp
+;; In your init.el, BEFORE (require 'wttrin):
+(setq wttrin-debug t)
+(require 'wttrin)
+```
+
+### Or Enable Later
+
+```emacs-lisp
+M-x debug-wttrin-enable
+```
+
+### View Debug Log
+
+```emacs-lisp
+M-x wttrin--debug-show-log
+```
+
+This opens a buffer showing all debug events with timestamps.
+
+### Clear Debug Log
+
+```emacs-lisp
+M-x wttrin--debug-clear-log
+```
+
+## Test Fixtures
+
+- `fixtures/test-init.el` - Minimal init file with debug enabled for manual testing
+
+## Troubleshooting
+
+If wttrin isn't loading in your configuration:
+
+1. **Enable debug mode** (set `wttrin-debug` to `t` before loading)
+2. **Check dependencies**: Run `M-x package-list-packages` and ensure `xterm-color` is installed
+3. **View debug log**: Run `M-x wttrin--debug-show-log` after trying to use wttrin
+4. **Check for errors**: Look in `*Messages*` buffer for any error messages
+
+The debug log will show you exactly where the process stops or fails.
diff --git a/tests/fixtures/test-init.el b/tests/fixtures/test-init.el
new file mode 100644
index 0000000..26e8395
--- /dev/null
+++ b/tests/fixtures/test-init.el
@@ -0,0 +1,22 @@
+;;; test-init.el --- Test fixture for wttrin integration tests -*- lexical-binding: t; -*-
+
+;; This is a minimal init.el for testing wttrin with debug enabled
+
+;; Enable debug mode BEFORE loading wttrin
+(setq wttrin-debug t)
+
+;; Configure wttrin
+(setq wttrin-default-locations '("Berkeley, CA" "New Orleans, LA"))
+(setq wttrin-unit-system "m") ; Metric
+(setq wttrin-mode-line-favorite-location "Berkeley, CA")
+(setq wttrin-mode-line-startup-delay 0) ; No delay for tests
+(setq wttrin-mode-line-refresh-interval 3600) ; 1 hour
+
+;; Load wttrin (assumes it's in load-path)
+(require 'wttrin)
+
+;; Don't auto-enable mode-line in tests (we'll do it explicitly)
+(setq wttrin-mode-line-auto-enable nil)
+
+(provide 'test-init)
+;;; test-init.el ends here
diff --git a/tests/test-wttrin-integration-with-debug.el b/tests/test-wttrin-integration-with-debug.el
new file mode 100644
index 0000000..db4e05f
--- /dev/null
+++ b/tests/test-wttrin-integration-with-debug.el
@@ -0,0 +1,252 @@
+;;; test-wttrin-integration-with-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)
+
+;; 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.")
+
+(defconst test-wttrin-sample-full-weather
+ "Weather for Berkeley, CA
+
+ \\ / Clear
+ .-. 62 °F
+ ― ( ) ― ↑ 5 mph
+ `-' 10 mi
+ / \\ 0.0 in"
+ "Sample full weather display data.")
+
+;;; Setup and Teardown
+
+(defun test-wttrin-setup ()
+ "Set up test environment with debug enabled."
+ ;; Enable debug mode
+ (setq wttrin-debug t)
+ ;; Clear any existing debug log
+ (when (featurep 'wttrin-debug)
+ (wttrin--debug-clear-log))
+ ;; Clear cache
+ (wttrin-clear-cache)
+ ;; Set test configuration
+ (setq wttrin-mode-line-favorite-location "Berkeley, CA")
+ (setq wttrin-mode-line-startup-delay 0)
+ (setq wttrin-unit-system "m"))
+
+(defun test-wttrin-teardown ()
+ "Clean up after tests."
+ (when (boundp 'wttrin-mode-line-mode)
+ (wttrin-mode-line-mode -1))
+ (wttrin-clear-cache)
+ (when (featurep 'wttrin-debug)
+ (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-wttrin-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))
+ ;; Simulate async by using run-at-time with 0 delay
+ (run-at-time
+ 0 nil
+ (lambda ()
+ (when (featurep 'wttrin-debug)
+ (wttrin--debug-log "MOCK-FETCH: Calling callback with mock data"))
+ (funcall callback test-wttrin-sample-weather-data))))
+
+(defmacro 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-wttrin-mock-fetch)
+ ,@body)
+ (fset 'wttrin--fetch-url test-wttrin--original-fetch-url))))
+
+;;; Integration Tests
+
+(ert-deftest test-wttrin-debug-integration-mode-line-fetch-and-display ()
+ "Integration test: Fetch weather and verify mode-line display with debug logging."
+ (test-wttrin-setup)
+ (unwind-protect
+ (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-wttrin-teardown)))
+
+(ert-deftest test-wttrin-debug-integration-full-weather-query ()
+ "Integration test: Query full weather and verify debug logging."
+ (test-wttrin-setup)
+ (unwind-protect
+ (progn
+ ;; Clear debug log
+ (wttrin--debug-clear-log)
+
+ ;; Mock full weather fetch
+ (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))
+ (run-at-time 0 nil
+ (lambda ()
+ (funcall callback test-wttrin-sample-full-weather))))))
+
+ ;; Start the query (async, so we'll check results after delay)
+ (wttrin-query "Berkeley, CA")
+
+ ;; Wait for async operations
+ (sleep-for 0.2)
+
+ ;; Verify buffer was created
+ (should (get-buffer "*wttr.in*"))
+
+ ;; Verify debug log shows URL building
+ (let ((log-messages (mapcar #'cdr wttrin--debug-log)))
+ ;; Should have logged fetch starting
+ (should (seq-some (lambda (msg) (string-match-p "wttrin--fetch-url: Starting" msg))
+ log-messages))
+ ;; Should have logged success
+ (should (seq-some (lambda (msg) (string-match-p "Successfully fetched" msg))
+ log-messages)))))
+ ;; Cleanup
+ (when (get-buffer "*wttr.in*")
+ (kill-buffer "*wttr.in*"))
+ (test-wttrin-teardown)))
+
+(ert-deftest test-wttrin-debug-integration-mode-line-mode-toggle ()
+ "Integration test: Toggle mode-line mode and verify debug logging."
+ (test-wttrin-setup)
+ (unwind-protect
+ (with-mocked-fetch
+ ;; Clear debug log
+ (wttrin--debug-clear-log)
+
+ ;; Enable mode-line mode
+ (wttrin-mode-line-mode 1)
+ (should wttrin-mode-line-mode)
+
+ ;; Wait longer for initial fetch and callback (async operations take time)
+ (sleep-for 0.3)
+
+ ;; 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-wttrin-teardown)))
+
+(ert-deftest test-wttrin-debug-integration-error-handling ()
+ "Integration test: Verify debug logging captures errors correctly."
+ (test-wttrin-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-wttrin-teardown)))
+
+(ert-deftest test-wttrin-debug-integration-log-inspection ()
+ "Integration test: Verify debug log can be inspected programmatically."
+ (test-wttrin-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-wttrin-teardown)))
+
+(provide 'test-wttrin-integration-with-debug)
+;;; test-wttrin-integration-with-debug.el ends here