krz/orgstar

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

Tests/OrgCoreTests/ArchiveCommandTests.swift

15f6b0709d88971fb62ed432c3e5b8032643670a
orgstar/Tests/OrgCoreTests/ArchiveCommandTests.swift history · blame · raw

49 lines · 2722 bytes

 1import Foundation
 2import Testing
 3@testable import OrgCore
 4
 5struct ArchiveCommandTests {
 6    static let oracle = ProcessInfo.processInfo.environment["ORGSTAR_SKIP_ORACLE"] == nil
 7
 8    @Test(.enabled(if: oracle))
 9    func archivesInPlaceLikeOrg() throws {
10        let texts = [
11            "* P [0/2]\n** TODO a :x:\nbody\n** TODO b\n* Q\n",
12            "* P\n** a\n** Archive :ARCHIVE:\n*** old\n** b\n",
13            "* top\n* other :ARCHIVE:\n",
14            "* P\n** a\n\n** b\n",
15        ]
16        var cases: [EmacsOracle.Case] = []
17        var ours: [(String, Int, String?)] = []
18        for text in texts {
19            let ns = text as NSString
20            var starts: [Int] = []
21            var offset = 0
22            while offset < ns.length {
23                if ns.character(at: offset) == 42 { starts.append(offset) }
24                offset = NSMaxRange(ns.lineRange(for: NSRange(location: offset, length: 0)))
25            }
26            for start in starts {
27                for (command, form) in [(ToggleArchiveTag() as any OrgCommand, "(org-toggle-archive-tag)"), (ArchiveToSibling(), "(org-archive-to-archive-sibling)")] {
28                    cases.append(EmacsOracle.Case(text: text, point: EmacsOracle.point(start + 1, in: text), form: frozenClock(1_789_000_000, form)))
29                    var utc = Calendar(identifier: .gregorian)
30                    utc.timeZone = TimeZone(identifier: "UTC")!
31                    let context = EditContext(revision: 0, text: text, tree: OrgParser.parse(text), selection: [(start + 1)..<(start + 1)],
32                                              now: Date(timeIntervalSince1970: 1_789_000_000), calendar: utc)
33                    switch command.run(in: context) {
34                    case .commit(let result):
35                        let new = result.edits.sorted { $0.range.lowerBound > $1.range.lowerBound }.reduce(text) { $1.apply(to: $0) }
36                        ours.append((new, result.selection?.first?.lowerBound ?? start + 1, nil))
37                    case .failed(let message): ours.append((text, start + 1, message))
38                    default: ours.append((text, start + 1, "other"))
39                    }
40                }
41            }
42        }
43        for (i, theirs) in try EmacsOracle.run(cases).enumerated() {
44            let caret = EmacsOracle.offset(theirs.point, in: theirs.text)
45            #expect(ours[i].0 == theirs.text && ours[i].1 == caret && (ours[i].2 != nil) == !theirs.error.isEmpty,
46                    "\(cases[i].form) on \(cases[i].text.debugDescription) @\(cases[i].point)\nours:  \(ours[i].0.debugDescription) @\(ours[i].1) \(ours[i].2 ?? "")\nemacs: \(theirs.text.debugDescription) @\(caret) \(theirs.error)")
47        }
48    }
49}