Tests/OrgCoreTests/ArchiveCommandTests.swift
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}