Tests/OrgIndexTests/FileRecordTests.swift
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}