AtlatestRepositoryfolio

folio / tree / testtest-task.sgl

1(import (sigil test)
2 (sigil struct)
3 (folio task))
4
5;; ============================================================
6;; task-line?
7;; ============================================================
8
9(test-group "task-line?"
10 (test "open task"
11 (assert-true (task-line? "- [ ] Do something")))
13 (test "completed task"
14 (assert-true (task-line? "- [x] Done thing")))
16 (test "completed task uppercase X"
17 (assert-true (task-line? "- [X] Done thing")))
19 (test "leading whitespace"
20 (assert-true (task-line? " - [ ] Indented task")))
22 (test "not a task - regular list item"
23 (assert-false (task-line? "- Regular item")))
25 (test "not a task - heading"
26 (assert-false (task-line? "## Heading")))
28 (test "not a task - empty"
29 (assert-false (task-line? ""))))
31;; ============================================================
32;; parse-task-line
33;; ============================================================
35(test-group "parse-task-line"
36 (test "simple open task"
37 (let ((task (parse-task-line "- [ ] Do something")))
38 (assert-true (folio-task? task))
39 (assert-equal "Do something" (folio-task-text task))
40 (assert-false (folio-task-done? task))
41 (assert-equal '() (folio-task-metadata task))))
43 (test "completed task"
44 (let ((task (parse-task-line "- [x] Done thing")))
45 (assert-true (folio-task-done? task))
46 (assert-equal "Done thing" (folio-task-text task))))
48 (test "task with metadata"
49 (let ((task (parse-task-line "- [ ] Fix bug {priority: high, due: 2026-03-20}")))
50 (assert-equal "Fix bug" (folio-task-text task))
51 (assert-equal "high" (task-priority task))
52 (assert-equal "2026-03-20" (task-due task))))
54 (test "task with id in metadata"
55 (let ((task (parse-task-line "- [ ] Thing {id: t-a3f2, priority: low}")))
56 (assert-equal "t-a3f2" (folio-task-id task))
57 (assert-equal "low" (task-priority task))))
59 (test "completed task with completed date"
60 (let ((task (parse-task-line "- [x] Old task {completed: 2026-03-13}")))
61 (assert-true (folio-task-done? task))
62 (assert-equal "2026-03-13" (task-completed task))))
64 (test "task with multiple tags"
65 (let ((task (parse-task-line "- [ ] Tag task {tags: ops dev}")))
66 (assert-equal '("ops" "dev") (task-tags task))))
68 (test "task with single tag"
69 (let ((task (parse-task-line "- [ ] Tag task {tags: ops}")))
70 (assert-equal '("ops") (task-tags task))))
72 (test "returns #f for non-task"
73 (assert-false (parse-task-line "Just a regular line")))
75 (test "returns #f for empty string"
76 (assert-false (parse-task-line ""))))
78;; ============================================================
79;; parse-task-metadata
80;; ============================================================
82(test-group "parse-task-metadata"
83 (test "single key-value"
84 (assert-equal '((priority . "high"))
85 (parse-task-metadata "priority: high")))
87 (test "multiple key-values"
88 (assert-equal '((priority . "high") (due . "2026-03-20"))
89 (parse-task-metadata "priority: high, due: 2026-03-20")))
91 (test "empty string"
92 (assert-equal '() (parse-task-metadata "")))
94 (test "whitespace handling"
95 (assert-equal '((key . "value"))
96 (parse-task-metadata " key : value "))))
98;; ============================================================
99;; serialize-task-metadata
100;; ============================================================
102(test-group "serialize-task-metadata"
103 (test "empty metadata"
104 (assert-equal "" (serialize-task-metadata '())))
106 (test "single pair"
107 (assert-equal "{priority: high}"
108 (serialize-task-metadata '((priority . "high")))))
110 (test "multiple pairs"
111 (assert-equal "{id: t-a3f2, priority: high}"
112 (serialize-task-metadata '((id . "t-a3f2") (priority . "high"))))))
114;; ============================================================
115;; task->line roundtrip
116;; ============================================================
118(test-group "task->line"
119 (test "simple open task"
120 (assert-equal "- [ ] Do something"
121 (task->line (folio-task text: "Do something"))))
123 (test "completed task"
124 (assert-equal "- [x] Done"
125 (task->line (folio-task text: "Done" done?: #t))))
127 (test "task with metadata"
128 (assert-equal "- [ ] Fix bug {priority: high}"
129 (task->line (folio-task text: "Fix bug"
130 metadata: '((priority . "high"))))))
132 (test "roundtrip preserves content"
133 (let* ((line "- [ ] My task {id: t-1234, priority: medium}")
134 (task (parse-task-line line))
135 (result (task->line task)))
136 (assert-equal line result))))