From 6cf0aac96ae0abb455ee8525e0ede9a63f5974f3 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Tue, 4 Nov 2025 07:56:31 -0600 Subject: Add comprehensive ERT test suite and fix critical bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Session 1: Testing infrastructure and initial test coverage Bug fixes in wttrin.el: - Fix wttrin-additional-url-params to handle nil unit system - Remove incorrect callback parameter to url-retrieve-synchronously - Add nil buffer check for network failures - Strip HTTP headers before decoding response - Kill buffer after fetch to prevent memory leaks - Fix double concatenation of URL params in cache function - Add proper URL encoding via new wttrin--build-url function Refactoring: - Extract wttrin--build-url as pure, testable function - Separate URL building logic from network I/O Test infrastructure (33 tests, 100% passing): - tests/testutil-wttrin.el: Shared test utilities - tests/test-wttrin-additional-url-params.el: 7 tests - tests/test-wttrin--make-cache-key.el: 9 tests - tests/test-wttrin--build-url.el: 10 tests - tests/test-wttrin--cleanup-cache-if-needed.el: 7 tests Documentation: - docs/testing-plan.org: Comprehensive testing roadmap - docs/bugs.org: Bug analysis from code review - docs/NOTES.org: Session tracking and guidelines - docs/session-1-summary.org: Detailed session summary Next session: Cache workflow tests, parsing logic extraction, integration tests 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- docs/testing-plan.org | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 docs/testing-plan.org (limited to 'docs/testing-plan.org') diff --git a/docs/testing-plan.org b/docs/testing-plan.org new file mode 100644 index 0000000..e2fae9a --- /dev/null +++ b/docs/testing-plan.org @@ -0,0 +1,152 @@ +* WTTRIN Testing Plan + +** Methods Analysis + +*** Pure Logic Functions (Easy to Test - No Refactoring Needed) +These functions have no side effects and can be tested directly: + +**** =wttrin-additional-url-params= (Line 103) +- *Purpose*: Concatenates unit system into URL parameter +- *Current issues*: Has a bug (returns "?" when wttrin-unit-system is nil) +- *Test categories*: + - Normal: wttrin-unit-system = "m", should return "?m" + - Normal: wttrin-unit-system = "u", should return "?u" + - Boundary: wttrin-unit-system = nil, currently returns "?" (bug!) + - Boundary: wttrin-unit-system = "", should return "?" + - Error: wttrin-unit-system is number/list (type error) + +**** =wttrin--make-cache-key= (Line 183) +- *Purpose*: Creates cache key from location and settings +- *Test categories*: + - Normal: location + unit system, returns "location|m" + - Normal: location with no unit system, returns "location|default" + - Boundary: Empty location string + - Boundary: Location with special characters (spaces, commas, Unicode) + - Error: nil location + +**** =wttrin--cleanup-cache-if-needed= (Line 217) +- *Purpose*: Removes oldest 20% of cache entries when cache exceeds max size +- *Test categories*: + - Normal: Cache at max, removes correct number of oldest entries + - Normal: Cache under max, does nothing + - Boundary: Cache exactly at max limit + - Boundary: Empty cache + - Boundary: Cache with 1 entry at max=1 + +*** Functions Needing Refactoring (Mixed Logic + Side Effects) + +**** =wttrin-fetch-raw-string= (Line 107) +*Current state*: Mixes URL building, network I/O, and decoding + +*Refactoring plan*: +- Create =wttrin--build-url= (pure): Takes query, returns URL string +- Create =wttrin--fetch-url= (I/O): Takes URL, returns raw response +- Keep =wttrin-fetch-raw-string= as thin wrapper calling both + +*Tests for =wttrin--build-url=*: +- Normal: query "Paris" → "https://wttr.in/Paris?A" +- Normal: query with unit system "m" → "https://wttr.in/Paris?mA" +- Boundary: query with spaces "New York" → properly encoded URL +- Boundary: query with special chars ",./~" → properly encoded +- Boundary: Empty query → "https://wttr.in/?A" +- Error: nil query → error + +*Tests for =wttrin--fetch-url=*: +- Mock url-retrieve-synchronously +- Normal: successful fetch returns buffer content +- Error: nil buffer (network failure) → error +- Error: HTTP error codes (404, 500) → error + +**** =wttrin-query= (Line 133) +*Current state*: Mixes data fetching, parsing, buffer creation, display, keymaps + +*Refactoring plan*: +- Create =wttrin--parse-weather-data= (pure): Takes raw string, returns structured data +- Create =wttrin--format-weather-buffer= (pure): Takes structured data, returns formatted string +- Keep =wttrin-query= for buffer/display/keymap setup + +*Tests for =wttrin--parse-weather-data=*: +- Normal: Valid weather data → parsed location, timestamp, body +- Boundary: Minimal valid data +- Error: "ERROR" in response → returns nil or signals error +- Error: Malformed data → handles gracefully + +*Tests for =wttrin--format-weather-buffer=*: +- Normal: Formatted data with location, timestamp, weather +- Boundary: Empty weather body +- Boundary: Very long weather data + +*** Cache Functions (Testable with Mocking) + +**** =wttrin--get-cached-or-fetch= (Line 187) +*Test categories*: +- Normal: Cache hit with fresh data → returns cached data +- Normal: Cache miss → fetches new data and caches it +- Normal: Cache hit with stale data → fetches new data +- Boundary: Force refresh bypasses cache +- Error: Fetch fails, cached data available → returns stale cache +- Error: Fetch fails, no cached data → propagates error + +*** Interactive Functions (Minimal Testing Needed) +These are thin wrappers around logic - test the logic, not the UI: + +- =wttrin= (Line 251) - Just calls wttrin-query with completing-read result +- =wttrin-exit= (Line 117) - Just calls quit-window +- =wttrin-requery= (Line 122) - Just prompts and calls wttrin-query +- =wttrin-requery-force= (Line 240) - Sets flag and calls wttrin-query +- =wttrin-clear-cache= (Line 231) - Just calls clrhash + +** Test File Structure + +Following the quality-engineer.org guidelines: + +*** Unit Test Files (tests/ directory) +- =test-wttrin-additional-url-params.el= +- =test-wttrin--make-cache-key.el= +- =test-wttrin--cleanup-cache-if-needed.el= +- =test-wttrin--build-url.el= (after refactoring) +- =test-wttrin--parse-weather-data.el= (after refactoring) +- =test-wttrin--format-weather-buffer.el= (after refactoring) +- =test-wttrin--get-cached-or-fetch.el= + +*** Integration Test Files +- =test-integration-wttrin-cache-workflow.el= (cache hit/miss/refresh) +- =test-integration-wttrin-fetch-display.el= (fetch → parse → display) + +*** Test Utilities +- =testutil-wttrin.el= (shared test helpers) + +** Refactoring Priority + +*** Phase 1: Test Pure Functions (No Refactoring Needed) +1. =wttrin-additional-url-params= +2. =wttrin--make-cache-key= +3. =wttrin--cleanup-cache-if-needed= + +*** Phase 2: Refactor and Test URL Building +1. Extract =wttrin--build-url= from =wttrin-fetch-raw-string= +2. Write tests for =wttrin--build-url= +3. Extract =wttrin--fetch-url= (I/O portion) +4. Write tests for =wttrin--fetch-url= (mocked) + +*** Phase 3: Refactor and Test Query Logic +1. Extract =wttrin--parse-weather-data= +2. Write tests for parsing +3. Extract =wttrin--format-weather-buffer= +4. Write tests for formatting + +*** Phase 4: Integration Tests +1. Cache workflow tests +2. Fetch-to-display workflow tests + +** Estimated Test Count +- Pure functions: ~30 tests +- Refactored functions: ~40 tests +- Cache logic: ~15 tests +- Integration: ~10 tests +*Total*: ~95 tests + +** Session Progress Tracking +- Session 1 (2025-11-03): Created testing plan, identified functions +- Session 2: TBD - Start with Phase 1 +- Session 3+: Continue through phases -- cgit v1.2.3