aboutsummaryrefslogtreecommitdiff
path: root/tests/test-wttrin-query-request-id.el
blob: cf3c371da02a443f94964ac92e3f9767956153b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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