krz/orgstar

A native macOS editor for org-mode files. editor org-mode swift

Tests/OrgCoreTests/AgendaItemTextTests.swift

16086b4cf2caff5328774b2cd5ae3ffe1ab65ca4
orgstar/Tests/OrgCoreTests/AgendaItemTextTests.swift history · blame · raw

69 lines · 3523 bytes

 1import Foundation
 2import Testing
 3@testable import OrgCore
 4
 5struct AgendaItemTextTests {
 6    static let file = """
 7        * TODO [#A] Write the report [1/3] :work:urgent:
 8        SCHEDULED: <2026-10-01 Thu>
 9        * WAIT Call [[https://example.com][the bank]] about <2026-10-05 Mon> fees [50%]
10        DEADLINE: <2026-10-05 Mon>
11        * Plain heading with no keyword :home:
12        SCHEDULED: <2026-10-05 Mon 08:00-09:30>
13        * DONE [#C]   Spaced    out   title
14        SCHEDULED: <2026-10-05 Mon>
15        * TODO Renew passport
16        DEADLINE: <2026-10-09 Fri>
17        * TODO Weekly review
18        SCHEDULED: <2026-09-28 Mon +1w>
19        """
20
21    static let today = Days.absolute(year: 2026, month: 10, day: 5)
22
23    static func items(on day: Int = today) -> [AgendaItem] {
24        let source = AgendaSource(path: "t.org", text: file, defaults: OrgSettings.default.withTodoKeywords("TODO WAIT | DONE KILL")!)
25        return Agenda.list([source], start: day, days: 1, today: today, now: (9, 0)).flatMap(\.items).filter { $0.path != nil }
26    }
27
28    static func item(_ title: String, on day: Int = today) -> AgendaItem {
29        items(on: day).first { $0.title == title && $0.kind != .timestamp }!
30    }
31
32    @Test func titlesLeaveOutKeywordPriorityCookiesTimestampsAndTags() {
33        let titles = Set(Self.items().map(\.title))
34        #expect(titles == ["Write the report", "Call the bank about fees", "Plain heading with no keyword", "Spaced out title", "Renew passport", "Weekly review"])
35        let report = Self.item("Write the report")
36        #expect(report.extra.hasPrefix("Sched."))
37        #expect(report.priorityLetter == "A" && report.progress == "1/3" && report.tags == ["work", "urgent"] && report.todo == "TODO")
38        let call = Self.item("Call the bank about fees")
39        #expect(call.priorityLetter == nil && call.progress == "50%" && call.todo == "WAIT")
40        let done = Self.item("Spaced out title")
41        #expect(done.isDone && done.priorityLetter == "C")
42        #expect(Self.item("Plain heading with no keyword").todo == nil)
43    }
44
45    @Test func planningDaysAreTheTimestampsDays() {
46        #expect(Self.item("Write the report").planningDay == Self.today - 4)
47        #expect(Self.item("Call the bank about fees").planningDay == Self.today)
48        #expect(Self.item("Renew passport").planningDay == Self.today + 4)
49        // A repeater's occurrence on a later day.
50        #expect(Self.item("Weekly review", on: Self.today + 7).planningDay == Self.today + 7)
51        #expect(Self.items().filter { $0.kind == .timestamp }.allSatisfy { $0.planningDay == nil })
52    }
53
54    @Test func skipIfDoneLeavesDoneEntriesOutOnTheirDay() {
55        let source = AgendaSource(path: "t.org", text: Self.file, defaults: OrgSettings.default.withTodoKeywords("TODO WAIT | DONE KILL")!)
56        var options = AgendaOptions()
57        #expect(Agenda.list([source], start: Self.today, days: 1, today: Self.today, now: (9, 0), options: options)[0].items.contains { $0.isDone })
58        options.skipScheduledIfDone = true
59        #expect(!Agenda.list([source], start: Self.today, days: 1, today: Self.today, now: (9, 0), options: options)[0].items.contains { $0.isDone })
60    }
61
62    @Test(arguments: [
63        (0, "0d"), (3, "3d"), (13, "13d"), (14, "2w"), (59, "8w"), (60, "2mo"), (120, "4mo"), (364, "11mo"),
64        (365, "1y"), (499, "1y 4mo"), (730, "2y"), (729, "1y 11mo"), (-3, "3d"),
65    ])
66    func compactAges(days: Int, text: String) {
67        #expect(AgendaAge.compact(days) == text)
68    }
69}