Tests/OrgCoreTests/ParserElementTests.swift
79 lines · 3147 bytes
1import Testing
2@testable import OrgCore
3
4func childKinds(_ text: String) -> [SyntaxKind] {
5 let root = OrgParser.parse(text).root
6 let container = root.children.first { $0.kind == .zerothSection || $0.kind == .section }!
7 return container.children.map(\.kind)
8}
9
10struct ParserElementTests {
11 @Test func planningAndPropertiesFollowHeading() {
12 let text = "* a\nSCHEDULED: <2026-10-04 Sun>\n:PROPERTIES:\n:ID: x\n:END:\nbody\n"
13 #expect(childKinds(text) == [.heading, .planning, .propertyDrawer, .paragraph])
14 }
15
16 @Test func planningElsewhereIsText() {
17 #expect(childKinds("SCHEDULED: <2026-10-04 Sun>\n") == [.paragraph])
18 }
19
20 @Test func blocks() {
21 #expect(childKinds("#+begin_src sh\n,* escaped\n:END:\n#+end_src\nafter\n") == [.block, .paragraph])
22 #expect(childKinds("#+BEGIN: clocktable\n#+END:\n") == [.dynamicBlock])
23 }
24
25 @Test func headingsEndBlocks() {
26 #expect(childKinds("#+begin_src sh\n* heading\n#+end_src\n") == [.paragraph])
27 }
28
29 @Test func unclosedBlockIsParagraph() {
30 #expect(childKinds("#+begin_src sh\necho\n") == [.paragraph])
31 }
32
33 @Test func drawersHoldElements() {
34 let root = OrgParser.parse(":LOGBOOK:\nCLOCK: [2026-10-04 Sun 10:00]\n:END:\n").root
35 let drawer = root.children[0].children[0]
36 #expect(drawer.kind == .drawer)
37 #expect(drawer.children.map(\.kind) == [.clock])
38 }
39
40 @Test func keywords() {
41 #expect(childKinds("#+TITLE: x\n#+NAME: t\n#+ATTR_HTML: :width 10\n") == [.keyword, .affiliatedKeyword, .affiliatedKeyword])
42 }
43
44 @Test func commentsAndFixedWidthGroup() {
45 #expect(childKinds("# a\n# b\n: c\n: d\n-----\n") == [.comment, .fixedWidth, .horizontalRule])
46 }
47
48 @Test func tableWithFormulas() {
49 let root = OrgParser.parse("| a |\n|---|\n| 1 |\n#+TBLFM: $1=2\n#+TBLFM: $1=3\n").root
50 let table = root.children[0].children[0]
51 #expect(table.kind == .table)
52 #expect(table.children.map(\.kind) == [.tableRow, .tableRow, .tableRow, .tableFormula, .tableFormula])
53 }
54
55 @Test func footnoteDefinition() {
56 #expect(childKinds("[fn:1] note\ncontinued\n\nafter\n") == [.footnoteDefinition, .paragraph])
57 }
58
59 @Test func listsNestByIndent() {
60 let text = "- a\n more\n - b\n- c\n\nafter\n"
61 let root = OrgParser.parse(text).root
62 let list = root.children[0].children[0]
63 #expect(list.kind == .plainList)
64 #expect(list.children.map(\.kind) == [.item, .item])
65 #expect(list.children[0].children.map(\.kind) == [.paragraph, .plainList])
66 #expect(childKinds(text) == [.plainList, .paragraph])
67 }
68
69 @Test func twoBlankLinesEndAList() {
70 #expect(childKinds("- a\n\n\n- b\n") == [.plainList, .plainList])
71 #expect(childKinds("- a\n\n- b\n") == [.plainList])
72 }
73
74 @Test func paragraphStopsAtElementStart() {
75 #expect(childKinds("text\n| a |\n") == [.paragraph, .table])
76 #expect(childKinds("text\n#+begin_quote\nq\n#+end_quote\n") == [.paragraph, .block])
77 #expect(childKinds("text\n#+begin_quote\nq\n") == [.paragraph])
78 }
79}