krz/orgstar

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

Tests/OrgIndexTests/FileRecordTests.swift

ab6ccec56eca03d0dadf2c9332aab10c4490eb62
orgstar/Tests/OrgIndexTests/FileRecordTests.swift history · blame · raw

71 lines · 3135 bytes

 1import OrgCore
 2import Testing
 3@testable import OrgIndex
 4
 5func record(_ path: String, _ text: String, kind: FileKind = .org, settings: IndexSettings = IndexSettings()) -> FileRecord {
 6    FileRecord(path: path, root: "/notes", kind: kind, bytes: Array(text.utf8), mtime: 1, settings: settings)
 7}
 8
 9struct FileRecordTests {
10    let text = """
11    #+FILETAGS: :work:
12    #+PROPERTY: OWNER team
13    * TODO [#A] Plan the launch :big:
14    SCHEDULED: <2026-10-05 Mon +1w -2d>
15    :PROPERTIES:
16    :ID: plan
17    :CATEGORY: launch
18    :END:
19    Draft the [[https://example.com][brief]] and see [[id:other]].
20    ** DONE Child
21    CLOSED: [2026-10-04 Sun 09:00]
22    :LOGBOOK:
23    CLOCK: [2026-10-04 Sun 08:00]--[2026-10-04 Sun 09:00] =>  1:00
24    :END:
25    <2026-10-06 Tue>
26
27    """
28
29    @Test func headings() throws {
30        let headings = record("/notes/a.org", text).headings
31        #expect(headings.count == 2)
32        let plan = headings[0]
33        #expect(plan.todo == "TODO" && !plan.isDone && plan.priority == "A")
34        #expect(plan.orgID == "plan")
35        #expect(plan.outlinePath == ["Plan the launch"])
36        #expect(plan.body.contains("Draft the"))
37        #expect(!plan.body.contains("Child"))
38        #expect(plan.tags == [TagRow(name: "work", inherited: true), TagRow(name: "big", inherited: false)])
39        #expect(plan.links == [LinkRow(type: "https", target: "https://example.com"), LinkRow(type: "id", target: "id:other")])
40        #expect(plan.timestamps == [TimestampRow(kind: .scheduled, start: "2026-10-05", end: nil, repeater: "+1w", warning: "-2d")])
41
42        let child = headings[1]
43        #expect(child.parent == 0 && child.isDone)
44        #expect(child.outlinePath == ["Plan the launch", "Child"])
45        #expect(child.tags.map(\.name) == ["work", "big"])
46        #expect(child.clocks == [ClockRow(start: "2026-10-04T08:00", end: "2026-10-04T09:00", minutes: 60)])
47        #expect(child.timestamps.map(\.kind) == [.closed, .active])
48        #expect(child.properties == [PropertyRow(key: "CATEGORY", value: "launch", inherited: true)])
49    }
50
51    @Test func propertyInheritanceFollowsSettings() {
52        let settings = IndexSettings(semantic: SemanticSettings(propertyInheritance: .all))
53        let child = record("/notes/a.org", text, settings: settings).headings[1]
54        #expect(child.properties.contains(PropertyRow(key: "OWNER", value: "team", inherited: true)))
55    }
56
57    @Test func linksBeforeTheFirstHeadingBelongToTheFile() {
58        let file = record("/notes/a.org", "#+TITLE: A\nSee [[file:b.org]] and https://x.org.\n* H\n[[id:h]]\n")
59        #expect(file.links == [LinkRow(type: "file", target: "file:b.org"), LinkRow(type: "https", target: "https://x.org")])
60        #expect(file.headings[0].links == [LinkRow(type: "id", target: "id:h")])
61    }
62
63    @Test func archiveTag() {
64        let headings = record("/notes/a.org", "* a :ARCHIVE:\n** b\n* c\n").headings
65        #expect(headings.map(\.archived) == [true, true, false])
66    }
67
68    @Test func conflictCopiesHaveNoHeadings() {
69        #expect(record("/notes/a.sync-conflict-1.org", "* a\n", kind: .conflict).headings.isEmpty)
70    }
71}