diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-28 04:06:12 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-28 04:06:12 -0400 |
| commit | ce74e30562dfac3f599a94a45ac16c3c2319ab41 (patch) | |
| tree | 0677f2538373bd87099a3c69b249b495689277f5 /tests | |
| parent | 19e103fea2e55a3e3bc3a777b4c618e644b57760 (diff) | |
| download | emacs-wttrin-ce74e30562dfac3f599a94a45ac16c3c2319ab41.tar.gz emacs-wttrin-ce74e30562dfac3f599a94a45ac16c3c2319ab41.zip | |
fix: drop stale async weather responses that overwrite a newer query
wttrin-query reuses the single *wttr.in* buffer, so requesting Paris then Berlin
and having Paris return last overwrote the Berlin buffer. Each query now stamps
a monotonic request id on the buffer; the callback displays only when its
captured id still matches, so a superseded response is ignored.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test-wttrin-query-request-id.el | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/tests/test-wttrin-query-request-id.el b/tests/test-wttrin-query-request-id.el new file mode 100644 index 0000000..cf3c371 --- /dev/null +++ b/tests/test-wttrin-query-request-id.el @@ -0,0 +1,56 @@ +;;; test-wttrin-query-request-id.el --- Stale async response guard -*- lexical-binding: t; -*- + +;; Copyright (C) 2024-2026 Craig Jennings + +;;; Commentary: +;; wttrin-query reuses the single *wttr.in* buffer, so an async response for an +;; earlier query that completes after a later one must not overwrite the newer +;; buffer. A per-buffer request id, captured in the callback closure, drops the +;; stale response. + +;;; Code: + +(require 'ert) +(require 'cl-lib) +(require 'wttrin) +(require 'testutil-wttrin) + +(ert-deftest test-wttrin-query-normal-current-callback-displays () + "Normal: a query's own callback (matching request id) displays its result." + (let ((cb nil) (displayed nil)) + (unwind-protect + (cl-letf (((symbol-function 'wttrin--get-cached-or-fetch) + (lambda (_loc c) (setq cb c))) + ((symbol-function 'switch-to-buffer) + (lambda (buf &rest _) (set-buffer buf))) + ((symbol-function 'wttrin--display-weather) + (lambda (query &rest _) (setq displayed query)))) + (wttrin-query "Paris") + (funcall cb "paris-data") + (should (equal displayed "Paris"))) + (when (get-buffer "*wttr.in*") (kill-buffer "*wttr.in*"))))) + +(ert-deftest test-wttrin-query-error-stale-callback-does-not-overwrite-newer () + "Error: a slow response for an earlier query does not overwrite a newer query. +Paris then Berlin share the *wttr.in* buffer; the Paris callback arriving after +Berlin must be ignored." + (let ((callbacks nil) (displayed nil)) + (unwind-protect + (cl-letf (((symbol-function 'wttrin--get-cached-or-fetch) + (lambda (_loc cb) (push cb callbacks))) + ((symbol-function 'switch-to-buffer) + (lambda (buf &rest _) (set-buffer buf))) + ((symbol-function 'wttrin--display-weather) + (lambda (query &rest _) (setq displayed query)))) + (wttrin-query "Paris") + (wttrin-query "Berlin") + (let ((paris-cb (cadr callbacks)) ; first pushed + (berlin-cb (car callbacks))) ; last pushed + (funcall berlin-cb "berlin-data") + (should (equal displayed "Berlin")) + (funcall paris-cb "paris-data") + (should (equal displayed "Berlin")))) + (when (get-buffer "*wttr.in*") (kill-buffer "*wttr.in*"))))) + +(provide 'test-wttrin-query-request-id) +;;; test-wttrin-query-request-id.el ends here |
