krz/orgstar

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

Tests/OrgCoreTests/PropertyCommandTests.swift

main
orgstar/Tests/OrgCoreTests/PropertyCommandTests.swift history · blame · raw

72 lines · 3803 bytes

4 symbols in this file
 1import Foundation
 2import Testing
 3@testable import OrgCore
 4
 5struct PropertyCommandTests {
 6    static let oracle = ProcessInfo.processInfo.environment["ORGSTAR_SKIP_ORACLE"] == nil
 7
 8    static let text = """
 9        #+PROPERTY: Color_ALL red green "dark blue" :ETC
10        * Parent
11        :PROPERTIES:
12        :Size_ALL: S M L 010
13        :Size:     M
14        :END:
15        ** Child
16        :PROPERTIES:
17        :Size:     L
18        :Color:    green
19        :Done:     [ ]
20        :END:
21        body
22        ** Bare
23        SCHEDULED: <2026-10-05 Mon>
24        * Other
25        :PROPERTIES:
26        :Size:     S
27        :END:
28        """ + "\n"
29
30    func compare(_ cases: [(at: String, command: any OrgCommand, answers: [String: String], form: String)]) throws {
31        let ns = Self.text as NSString
32        let emacs = try EmacsOracle.run(cases.map { c in
33            EmacsOracle.Case(text: Self.text, point: EmacsOracle.point(ns.range(of: c.at).location, in: Self.text), form: c.form)
34        })
35        for (c, theirs) in zip(cases, emacs) {
36            let ours = runCommand(c.command, Self.text, caret: ns.range(of: c.at).location, answers: c.answers)
37            #expect(ours.text == theirs.text, "\(c.form) at \(c.at)\nours:  \(ours.text.debugDescription) \(ours.failure ?? "")\nemacs: \(theirs.text.debugDescription) \(theirs.error)")
38            #expect((ours.failure != nil) == !theirs.error.isEmpty, "\(c.form): \(ours.failure ?? "") vs \(theirs.error)")
39        }
40    }
41
42    @Test(.enabled(if: oracle))
43    func setsAndDeletesLikeOrg() throws {
44        try compare([
45            ("Child", ReadAndSetProperty(), ["property": "Color", "value": "red"], "(org-set-property \"Color\" \"red\")"),
46            ("Bare", ReadAndSetProperty(), ["property": "Size", "value": "S"], "(org-set-property \"Size\" \"S\")"),
47            ("Other", ReadAndSetProperty(), ["property": "Size", "value": "S"], "(org-set-property \"Size\" \"S\")"),
48            ("Child", DeleteProperty(), ["property": "Color"], "(org-delete-property \"Color\")"),
49            ("Other", DeleteProperty(), [:], "(org-delete-property \"Size\")"),
50            ("Parent", DeleteProperty(globally: true), ["property": "Size"], "(org-delete-property-globally \"Size\")"),
51            (":Size:     L", NextAllowedValue(previous: false), [:], "(org-property-next-allowed-value)"),
52            (":Size:     L", NextAllowedValue(previous: true), [:], "(org-property-next-allowed-value t)"),
53            (":Size:     M", NextAllowedValue(previous: false), [:], "(org-property-next-allowed-value)"),
54            (":Color:    green", NextAllowedValue(previous: false), [:], "(org-property-next-allowed-value)"),
55            (":Done:", NextAllowedValue(previous: false), [:], "(org-property-next-allowed-value)"),
56            (":Size:     S", NextAllowedValue(previous: false), [:], "(org-property-next-allowed-value)"),
57        ])
58    }
59
60    @Test(.enabled(if: oracle))
61    func findsAllowedValuesLikeOrg() throws {
62        let ns = Self.text as NSString
63        let spots = [("Child", "Size"), ("Child", "Color"), ("Other", "Size"), ("Child", "TODO"), ("Child", "PRIORITY"), ("Bare", "Shape")]
64        let forms = spots.map { at, key in
65            "(progn (goto-char \(EmacsOracle.point(ns.range(of: at).location, in: Self.text))) (mapconcat #'identity (org-property-get-allowed-values (point) \(lispString(key))) \"|\"))"
66        }
67        let emacs = try EmacsOracle.evaluate(Self.text, "(with-current-buffer (find-file-noselect \"oracle.org\") (list \(forms.joined(separator: " "))))")
68        let tree = OrgParser.parse(Self.text)
69        let ours = spots.map { at, key in PropertyValues.allowed(key, at: ns.range(of: at).location, text: Self.text, tree: tree)?.values.joined(separator: "|") ?? "" }
70        #expect(ours == emacs)
71    }
72}