krz/orgstar

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

Tests/OrgCoreTests/InlineTests.swift

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

89 lines · 4467 bytes

 1import Testing
 2@testable import OrgCore
 3
 4/// `kind:text` for each object directly inside the first paragraph.
 5func objects(_ text: String) -> [String] {
 6    let paragraph = OrgParser.parse(text).root.descendants().first { $0.kind == .paragraph }!
 7    return paragraph.children.map { "\($0.kind.rawValue):\($0.text)" }
 8}
 9
10struct InlineTests {
11    @Test(arguments: [
12        ("*b* /i/ _u_ +s+ =v= ~c~", ["bold:*b*", "italic:/i/", "underline:_u_", "strikeThrough:+s+", "verbatim:=v=", "code:~c~"]),
13        ("a*b* (*c*) \"*d*\"", ["bold:*c*", "bold:*d*"]),
14        ("x *y * z", []),
15        ("*y*z", []),
16        ("*a\nb*", ["bold:*a\nb*"]),
17        ("*a\nb\nc*", []),
18        ("=*not bold*=", ["verbatim:=*not bold*="]),
19        ("[[https://a.b][the *site*]]", ["link:[[https://a.b][the *site*]]"]),
20        ("[[file:x.org]]", ["link:[[file:x.org]]"]),
21        ("<https://a.b/c>", ["link:<https://a.b/c>"]),
22        ("see https://a.b/c.", ["link:https://a.b/c"]),
23        ("<2026-10-04 Sun 10:00-11:30 +1w -2d>", ["timestamp:<2026-10-04 Sun 10:00-11:30 +1w -2d>"]),
24        ("[2026-10-04 Sun]--[2026-10-06 Tue]", ["timestamp:[2026-10-04 Sun]--[2026-10-06 Tue]"]),
25        ("a [fn:1] and [fn::inline [x] note]", ["footnoteReference:[fn:1]", "footnoteReference:[fn::inline [x] note]"]),
26        ("a [1/3] [50%]", ["statisticsCookie:[1/3]", "statisticsCookie:[50%]"]),
27        ("a <<target>> {{{m(x, y)}}}", ["target:<<target>>", "macro:{{{m(x, y)}}}"]),
28        ("\\(x^2\\) and src_sh[:results raw]{echo {a}}", ["latexFragment:\\(x^2\\)", "inlineSourceBlock:src_sh[:results raw]{echo {a}}"]),
29        ("N^2 and e^{i}", ["superscript:^2", "superscript:^{i}"]),
30        ("end\\\\\nnext", ["lineBreak:\\\\"]),
31    ])
32    func recognizes(text: String, expected: [String]) {
33        #expect(objects(text) == expected)
34    }
35
36    @Test func emphasisNests() {
37        let bold = OrgParser.parse("*bold /italic/ x*\n").root.descendants().first { $0.kind == .bold }!
38        #expect(bold.children.map(\.kind) == [.italic])
39        #expect(bold.tokens.first?.kind == .marker)
40    }
41
42    @Test func linkParts() {
43        let link = OrgParser.parse("[[id:abc][desc]]\n").root.descendants().first { $0.kind == .link }!
44        #expect(link.tokens.map(\.kind) == [.marker, .linkPath, .marker, .marker])
45        #expect(link.tokens.first { $0.kind == .linkPath }?.text == "id:abc")
46        #expect(link.children.map(\.kind) == [.linkDescription])
47    }
48
49    @Test func noLinksInsideLinkDescriptions() {
50        let link = OrgParser.parse("[[a][see https://b.c]]\n").root.descendants().first { $0.kind == .link }!
51        #expect(link.descendants().filter { $0.kind == .link }.count == 1)
52    }
53
54    @Test func headingTitlesHoldObjects() {
55        let title = OrgParser.parse("* TODO Read [[https://a.b][it]] [1/2]\n").root.descendants().first { $0.kind == .title }!
56        #expect(title.children.map(\.kind) == [.link, .statisticsCookie])
57    }
58
59    @Test func planningHoldsTimestamps() {
60        let planning = OrgParser.parse("* a\nDEADLINE: <2026-10-04 Sun -2d> SCHEDULED: <2026-10-01 Thu>\n").root
61            .descendants().first { $0.kind == .planning }!
62        #expect(planning.children.map(\.kind) == [.timestamp, .timestamp])
63    }
64
65    @Test func itemsSplitBulletAndCheckbox() {
66        let item = OrgParser.parse("  - [X] done *now*\n    more\n").root.descendants().first { $0.kind == .item }!
67        #expect(item.tokens.map(\.kind) == [.whitespace, .bullet, .whitespace, .checkbox, .whitespace])
68        #expect(item.children.map(\.kind) == [.paragraph])
69        #expect(item.children[0].text == "done *now*\n    more\n")
70    }
71
72    @Test func emptyItem() {
73        let item = OrgParser.parse("-\n").root.descendants().first { $0.kind == .item }!
74        #expect(item.tokens.map(\.kind) == [.bullet, .newline])
75    }
76
77    @Test func tableCells() {
78        let rows = OrgParser.parse("| *a* || b\n|---+---|\n").root.descendants().filter { $0.kind == .tableRow }
79        #expect(rows[0].children.map(\.text) == [" *a* ", "", " b"])
80        #expect(rows[0].children[0].children.map(\.kind) == [.bold])
81        #expect(rows[1].children.isEmpty)
82    }
83
84    @Test func footnoteDefinitionLabelIsNotAReference() {
85        let definition = OrgParser.parse("[fn:1] see [fn:2]\n").root.descendants().first { $0.kind == .footnoteDefinition }!
86        #expect(definition.tokens.first?.text == "[fn:1]")
87        #expect(definition.children.map(\.kind) == [.footnoteReference])
88    }
89}