diff options
| author | Craig Jennings <c@cjennings.net> | 2025-11-08 11:53:02 -0600 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2025-11-08 11:53:02 -0600 |
| commit | 1f40ef408641680c951a65b72be240d9b7729d8e (patch) | |
| tree | 083ae2d5ecf73134311233152f9dacc3f125fb77 /tests | |
| parent | b44277b019ac64ffeacde0214cd3c9cd18014ba9 (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.md | 82 | ||||
| -rw-r--r-- | tests/fixtures/test-init.el | 22 | ||||
| -rw-r--r-- | tests/test-wttrin-integration-with-debug.el | 252 |
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 |
