krz/orgstar

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

Tests/OrgCoreTests/TableTransformTests.swift

778058aafc7ddacee4a613b1da87c60aa0c8e113
orgstar/Tests/OrgCoreTests/TableTransformTests.swift history · blame · raw

72 lines · 3835 bytes

5 symbols in this file
 1import Foundation
 2import Testing
 3@testable import OrgCore
 4
 5struct TableTransformTests {
 6    static let oracle = ProcessInfo.processInfo.environment["ORGSTAR_SKIP_ORACLE"] == nil
 7
 8    static let table = """
 9        Intro
10        | Name   | Qty | When                   | Time |
11        |--------+-----+------------------------+------|
12        | pear   |  10 | <2026-03-01 Sun>       | 1:30 |
13        | Apple  |   2 | [2025-12-24 Thu 10:00] | 0:45 |
14        | *fig*  | 2.5 |                        | 2h   |
15        | banana |  -1 | <2026-01-15 Thu>       |      |
16        |--------+-----+------------------------+------|
17        | total  |     |                        |      |
18        After
19        """ + "\n"
20
21    func compare(_ cases: [(text: String, at: String, command: any OrgCommand, answers: [String: String], form: String)]) throws {
22        let emacs = try EmacsOracle.run(cases.map { c in
23            EmacsOracle.Case(text: c.text, point: EmacsOracle.point(NSMaxRange((c.text as NSString).range(of: c.at)), in: c.text), form: c.form)
24        })
25        for (c, theirs) in zip(cases, emacs) {
26            let ours = runCommand(c.command, c.text, caret: NSMaxRange((c.text as NSString).range(of: c.at)), answers: c.answers)
27            let theirCaret = EmacsOracle.offset(theirs.point, in: theirs.text)
28            #expect(ours.text == theirs.text && ours.caret == theirCaret && ours.failure == nil,
29                    "\(c.form) at \(c.at)\nours:  \(ours.text.debugDescription) @\(ours.caret) \(ours.failure ?? "")\nemacs: \(theirs.text.debugDescription) @\(theirCaret) \(theirs.error)")
30        }
31    }
32
33    @Test(.enabled(if: oracle))
34    func sortsAndTransposesLikeOrg() throws {
35        var cases: [(text: String, at: String, command: any OrgCommand, answers: [String: String], form: String)] = []
36        for (at, key) in [("| pea", "a"), ("| pea", "A"), ("|  10", "n"), ("|  10", "N"), ("Sun", "t"), ("1:3", "t"), ("1:3", "T")] {
37            cases.append((Self.table, at, SortTableLines(), ["sort": key], "(org-table-sort-lines nil ?\(key))"))
38        }
39        cases.append((Self.table, "Appl", TransposeTable(), [:], "(org-table-transpose-table-at-point)"))
40        cases.append(("| a | b | c |\n| 1 | 2 |\n", "| 1", TransposeTable(), [:], "(org-table-transpose-table-at-point)"))
41        try compare(cases)
42    }
43
44    @Test(.enabled(if: oracle))
45    func convertsRegionsLikeOrg() throws {
46        let inputs = [
47            "a,b,c\n1,\"x, y\",3\n\"q\"\"r\",,z\n",
48            "a\tb\tc\n1\t2\t3\n",
49            "alpha  beta gamma\none   two  three\n",
50        ]
51        for input in inputs {
52            let text = "Before\n" + input + "After\n"
53            let start = 7
54            let end = start + (input as NSString).length
55            let emacs = try EmacsOracle.run([EmacsOracle.Case(text: text, point: EmacsOracle.point(start, in: text), form: "(org-table-convert-region \(EmacsOracle.point(start, in: text)) \(EmacsOracle.point(end, in: text)))")])
56            let buffer = EmacsBuffer(text, point: start)
57            buffer.tableConvertRegion(start, end)
58            #expect(buffer.string == emacs[0].text, "ours:  \(buffer.string.debugDescription)\nemacs: \(emacs[0].text.debugDescription)")
59        }
60    }
61
62    @Test(.enabled(if: oracle))
63    func exportsLikeOrg() throws {
64        let text = "| a | b, c | \"q\" |\n|---+------+-----|\n| <5> |  |  |\n| 1 | x | y |\n"
65        let emacs = try EmacsOracle.evaluate(text, """
66            (with-current-buffer (find-file-noselect "oracle.org") (goto-char 3)
67              (list (orgtbl-to-csv (org-table-to-lisp) nil) (orgtbl-to-tsv (org-table-to-lisp) nil)))
68            """)
69        #expect(ImportTable.exportText(text, at: 2, path: "t.csv") == emacs[0] + "\n")
70        #expect(ImportTable.exportText(text, at: 2, path: "t.tsv") == emacs[1] + "\n")
71    }
72}