aboutsummaryrefslogtreecommitdiff
path: root/tests/test-pearl-mapping.el
blob: b5faa3da9e5750decb1149a693a0708f1225e840 (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
;;; test-pearl-mapping.el --- Tests for pearl mapping helpers -*- lexical-binding: t; -*-

;; Copyright (C) 2026 Craig Jennings

;; Author: Craig Jennings <c@cjennings.net>

;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; Unit tests for the pure mapping helpers in pearl.el:
;; Linear state <-> org keyword, the cached TODO-states regex, and
;; Linear priority -> org cookie / readable name.

;;; Code:

(require 'test-bootstrap (expand-file-name "test-bootstrap.el"))

;; A small, explicit mapping used across the state tests so cases don't
;; depend on the package default.
(defmacro test-pearl--with-mapping (mapping &rest body)
  "Run BODY with the state mapping bound to MAPPING and the cache cleared."
  (declare (indent 1))
  `(let ((pearl-state-to-todo-mapping ,mapping)
         (pearl-todo-states-pattern nil)
         (pearl--todo-states-pattern-source nil))
     ,@body))

;; pearl--map-linear-state-to-org (the static name->keyword lookup) was removed
;; in the keyword-cycle save: the keyword is now always the slug of the state
;; name (`pearl--state-name-to-keyword'), matching the workspace-derived #+TODO
;; header, and the keyword->state-id direction resolves through the team's
;; states (`pearl--resolve-keyword-to-state'), not a flat mapping.  The mapping
;; alist itself survives only as the source for `pearl--get-todo-states-pattern'
;; (tested below).

;;; pearl--get-todo-states-pattern

(ert-deftest test-pearl-get-todo-states-pattern-builds-alternation ()
  "The pattern is the org keywords joined with regex alternation."
  (test-pearl--with-mapping '(("Todo" . "TODO") ("In Progress" . "IN-PROGRESS") ("Done" . "DONE"))
    (should (string-equal "TODO\\|IN-PROGRESS\\|DONE"
                          (pearl--get-todo-states-pattern)))))

(ert-deftest test-pearl-get-todo-states-pattern-empty-mapping ()
  "An empty mapping yields an empty pattern string."
  (test-pearl--with-mapping '()
    (should (string-equal "" (pearl--get-todo-states-pattern)))))

(ert-deftest test-pearl-get-todo-states-pattern-recomputes-after-mapping-change ()
  "The cached pattern is recomputed when the mapping changes mid-session.

Regression for the stale-cache bug: a once-populated pattern must not
outlive a change to `pearl-state-to-todo-mapping'."
  (test-pearl--with-mapping '(("Todo" . "TODO") ("Done" . "DONE"))
    (should (string-equal "TODO\\|DONE" (pearl--get-todo-states-pattern)))
    ;; Change the mapping after the pattern has been cached.
    (setq pearl-state-to-todo-mapping
          '(("Todo" . "TODO") ("In Progress" . "DOING") ("Done" . "DONE")))
    (should (string-equal "TODO\\|DOING\\|DONE"
                          (pearl--get-todo-states-pattern)))))

;;; pearl--map-linear-priority-to-org

(ert-deftest test-pearl-map-linear-priority-to-org-known-values ()
  "Linear priorities 1-4 map to org cookies A-D."
  (should (string-equal "[#A]" (pearl--map-linear-priority-to-org 1)))
  (should (string-equal "[#B]" (pearl--map-linear-priority-to-org 2)))
  (should (string-equal "[#C]" (pearl--map-linear-priority-to-org 3)))
  (should (string-equal "[#D]" (pearl--map-linear-priority-to-org 4))))

(ert-deftest test-pearl-map-linear-priority-to-org-none-no-cookie ()
  "Priority 0 (No priority) maps to no cookie, distinct from Medium's [#C]."
  (should (string-equal "" (pearl--map-linear-priority-to-org 0))))

(ert-deftest test-pearl-map-linear-priority-to-org-nil-and-unknown-no-cookie ()
  "A nil or out-of-range priority maps to no cookie."
  (should (string-equal "" (pearl--map-linear-priority-to-org nil)))
  (should (string-equal "" (pearl--map-linear-priority-to-org 99))))

;;; pearl--get-linear-priority-name

(ert-deftest test-pearl-get-linear-priority-name-known-values ()
  "Linear priorities 1-4 have readable names."
  (should (string-equal "Urgent" (pearl--get-linear-priority-name 1)))
  (should (string-equal "High"   (pearl--get-linear-priority-name 2)))
  (should (string-equal "Medium" (pearl--get-linear-priority-name 3)))
  (should (string-equal "Low"    (pearl--get-linear-priority-name 4))))

(ert-deftest test-pearl-get-linear-priority-name-none-and-unknown ()
  "Zero (None), nil, and out-of-range priorities read as None."
  (should (string-equal "None" (pearl--get-linear-priority-name 0)))
  (should (string-equal "None" (pearl--get-linear-priority-name nil)))
  (should (string-equal "None" (pearl--get-linear-priority-name 99))))

;;; pearl-get-priorities

(ert-deftest test-pearl-get-priorities-returns-fixed-alist ()
  "The priority list maps the five Linear priority names to their integers."
  (let ((priorities (pearl-get-priorities)))
    (should (equal 0 (cdr (assoc "No priority" priorities))))
    (should (equal 1 (cdr (assoc "Urgent" priorities))))
    (should (equal 2 (cdr (assoc "High" priorities))))
    (should (equal 3 (cdr (assoc "Medium" priorities))))
    (should (equal 4 (cdr (assoc "Low" priorities))))))

(provide 'test-pearl-mapping)
;;; test-pearl-mapping.el ends here