aboutsummaryrefslogtreecommitdiff
path: root/tests/test-wttrin--add-buffer-instructions.el
blob: fdd7c91d84875c76414579ea0367cb5803e7ded6 (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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
;;; test-wttrin--add-buffer-instructions.el --- Tests for wttrin--add-buffer-instructions -*- lexical-binding: t; -*-

;; Copyright (C) 2024-2026 Craig Jennings

;;; Commentary:
;; Unit tests for wttrin--add-buffer-instructions function.
;; Tests adding user instructions to buffer content.

;;; Code:

(require 'ert)
(require 'wttrin)
(require 'testutil-wttrin)

;;; Setup and Teardown

(defun test-wttrin--expected-footer ()
  "Return the footer string `wttrin--add-buffer-instructions' should produce.
Width 23 is pinned here as a literal, independent of the production
constant, so the test fails if the visible layout drifts."
  (concat "\n\n"
          (format "%-23s%s" "This view" "Saved locations") "\n"
          (format "%-23s%s" "[a] another" "[s] save") "\n"
          (format "%-23s%s" "[g] refresh" "[d] make default") "\n"
          (format "%-23s%s" "[q] quit" "[r] rename") "\n"
          (format "%-23s%s" "" "[x] remove")))

(defun test-wttrin--add-buffer-instructions-setup ()
  "Setup for add-buffer-instructions tests."
  (testutil-wttrin-setup))

(defun test-wttrin--add-buffer-instructions-teardown ()
  "Teardown for add-buffer-instructions tests."
  (testutil-wttrin-teardown))

;;; Normal Cases

(ert-deftest test-wttrin--add-buffer-instructions-normal-empty-buffer-adds-instructions ()
  "Test adding instructions to empty buffer."
  (with-temp-buffer
    (wttrin--add-buffer-instructions)
    (should (string= (test-wttrin--expected-footer)
                     (buffer-string)))))

(ert-deftest test-wttrin--add-buffer-instructions-normal-with-existing-content-appends-instructions ()
  "Test adding instructions to buffer with existing content."
  (with-temp-buffer
    (insert "Weather: Sunny\nTemperature: 20°C")
    (wttrin--add-buffer-instructions)
    (should (string= (concat "Weather: Sunny\nTemperature: 20°C"
                             (test-wttrin--expected-footer))
                     (buffer-string)))))

(ert-deftest test-wttrin--add-buffer-instructions-normal-preserves-point-moves-to-end ()
  "Test that point is moved to end after adding instructions."
  (with-temp-buffer
    (insert "Some content")
    (goto-char (point-min))
    (wttrin--add-buffer-instructions)
    (should (= (point) (point-max)))))

(ert-deftest test-wttrin--add-buffer-instructions-normal-called-twice-adds-instructions-twice ()
  "Test that calling function twice adds instructions twice (not idempotent)."
  (with-temp-buffer
    (insert "Weather")
    (wttrin--add-buffer-instructions)
    (let ((first-result (buffer-string)))
      (wttrin--add-buffer-instructions)
      ;; Should add instructions again, not check if they already exist
      (should-not (string= first-result (buffer-string)))
      ;; Check for two occurrences of the header by counting matches
      (let ((count 0))
        (with-temp-buffer
          (insert first-result)
          (goto-char (point-min))
          (while (search-forward "This view" nil t)
            (setq count (1+ count))))
        ;; After first call, should have 1 occurrence
        (should (= 1 count)))
      ;; After second call, check for 2 occurrences
      (let ((count 0))
        (save-excursion
          (goto-char (point-min))
          (while (search-forward "This view" nil t)
            (setq count (1+ count))))
        (should (= 2 count))))))

(ert-deftest test-wttrin--add-buffer-instructions-normal-key-chords-carry-key-face ()
  "Bracketed key chords are styled with `wttrin-key'."
  (with-temp-buffer
    (wttrin--add-buffer-instructions)
    (goto-char (point-min))
    (search-forward "[a]")
    ;; point is just after the closing bracket; the bracket char is part
    ;; of the "[a]" segment
    (should (eq (get-text-property (1- (point)) 'face) 'wttrin-key))))

(ert-deftest test-wttrin--add-buffer-instructions-normal-prose-carries-instructions-face ()
  "The footer prose is styled with `wttrin-instructions'."
  (with-temp-buffer
    (wttrin--add-buffer-instructions)
    (goto-char (point-min))
    (search-forward "another")
    (should (eq (get-text-property (1- (point)) 'face) 'wttrin-instructions))))

;;; Boundary Cases

(ert-deftest test-wttrin--add-buffer-instructions-boundary-point-at-beginning-appends-at-end ()
  "Test adding instructions when point is at beginning of buffer."
  (with-temp-buffer
    (insert "Weather data here")
    (goto-char (point-min))
    (wttrin--add-buffer-instructions)
    (should (string-suffix-p "[x] remove"
                             (buffer-string)))))

(ert-deftest test-wttrin--add-buffer-instructions-boundary-point-in-middle-appends-at-end ()
  "Test adding instructions when point is in middle of buffer."
  (with-temp-buffer
    (insert "Line 1\nLine 2\nLine 3")
    (goto-char (point-min))
    (forward-line 1)
    (wttrin--add-buffer-instructions)
    (should (string-suffix-p "[x] remove"
                             (buffer-string)))))

(ert-deftest test-wttrin--add-buffer-instructions-boundary-trailing-newlines-preserves-newlines ()
  "Test adding instructions to buffer that already ends with newlines."
  (with-temp-buffer
    (insert "Weather\n\n\n")
    (wttrin--add-buffer-instructions)
    (should (string= (concat "Weather\n\n\n" (test-wttrin--expected-footer))
                     (buffer-string)))))

(ert-deftest test-wttrin--add-buffer-instructions-boundary-very-large-buffer-appends-at-end ()
  "Test adding instructions to large buffer."
  (with-temp-buffer
    (insert (make-string 10000 ?x))
    (wttrin--add-buffer-instructions)
    (goto-char (point-max))
    (should (looking-back "\\[x\\] remove" nil))))

;;; Error Cases

(ert-deftest test-wttrin--add-buffer-instructions-error-read-only-buffer-signals-error ()
  "Test that function signals error when buffer is read-only."
  (with-temp-buffer
    (insert "Some content")
    (read-only-mode 1)
    (should-error (wttrin--add-buffer-instructions)
                  :type 'buffer-read-only)))

(ert-deftest test-wttrin--add-buffer-instructions-error-narrowed-buffer-adds-at-narrowed-end ()
  "Test adding instructions to narrowed buffer adds at narrowed end."
  (with-temp-buffer
    (insert "Line 1\nLine 2\nLine 3\nLine 4")
    (goto-char (point-min))
    (forward-line 1)
    (let ((start (point)))
      (forward-line 1)
      (narrow-to-region start (point))
      (wttrin--add-buffer-instructions)
      ;; Instructions should be added at end of narrowed region
      (widen)
      (goto-char start)
      (forward-line 1)
      (should (looking-at-p "\n\nThis view")))))

(provide 'test-wttrin--add-buffer-instructions)
;;; test-wttrin--add-buffer-instructions.el ends here