Tests/OrgCoreTests/ObjectParseTests.swift
58 lines · 3148 bytes
3 symbols in this file
1import Foundation
2import Testing
3@testable import OrgCore
4
5/// Where org-element finds objects of each kind, against our tree.
6struct ObjectParseTests {
7 static let oracle = ProcessInfo.processInfo.environment["ORGSTAR_SKIP_ORACLE"] == nil
8
9 static let text = """
10 * Objects
11 Entities \\alpha, \\alpha{}beta, \\nbsp and \\notanentity.
12 Scripts x_1 y^2 a_{b c} d^{e} f_(g) h^* snake_case_name n^-1 e_{x_{y}} 2_1.5a.
13 Not after space _x ^y.
14 Math $x$ and $x+y$, $$e=mc^2$$ and \\(a^2\\) and \\[b\\] and \\frac{1}{2} and \\textbf[opt]{bold}.
15 Money $5 and $10, not math $ x$ nor $x $.
16 A radio <<<Target Word>>> here; the target word links, Target Words don't.
17 In *bold \\beta x_2* and [[link][\\gamma]].
18 \\begin{equation}
19 x = y^2
20 \\end{equation}
21 \\begin{align*} a \\end{align*}
22 \\begin{x}
23 never closed
24 """ + "\n"
25
26 static let kinds: [(lisp: String, ours: [SyntaxKind])] = [
27 ("entity", [.entity]), ("subscript", [.subscript]), ("superscript", [.superscript]),
28 ("latex-fragment", [.latexFragment]), ("radio-target", [.radioTarget]), ("latex-environment", [.latexEnvironment]),
29 ]
30
31 func ours(_ kinds: [SyntaxKind]) -> [String] {
32 OrgParser.parse(Self.text).root.descendants().filter { kinds.contains($0.kind) }.map { "\($0.range.lowerBound) \($0.range.upperBound)" }
33 }
34
35 @Test(.enabled(if: oracle))
36 func objectsMatchOrgElement() throws {
37 let forms = Self.kinds.map { kind in
38 """
39 (mapconcat (lambda (o) (format "%d %d" (1- (org-element-begin o))
40 (1- (save-excursion (goto-char (org-element-end o)) (skip-chars-backward " \\t") (point)))))
41 (org-element-map (org-element-parse-buffer) '\(kind.lisp) #'identity) ",")
42 """
43 }
44 let emacs = try EmacsOracle.evaluate(Self.text, "(with-current-buffer (find-file-noselect \"oracle.org\") (list \(forms.joined(separator: " "))))")
45 for (i, kind) in Self.kinds.enumerated() {
46 let theirs = emacs[i].split(separator: ",").map(String.init)
47 #expect(ours(kind.ours) == theirs, "\(kind.lisp)")
48 }
49 // Radio links: links whose text is a radio target's.
50 let links = try EmacsOracle.evaluate(Self.text, """
51 (with-current-buffer (find-file-noselect "oracle.org")
52 (list (mapconcat (lambda (o) (format "%d %d" (1- (org-element-begin o)) (1- (save-excursion (goto-char (org-element-end o)) (skip-chars-backward " \\t") (point)))))
53 (org-element-map (org-element-parse-buffer) 'link (lambda (l) (and (equal (org-element-property :type l) "radio") l))) ",")))
54 """)
55 let radio = OrgParser.parse(Self.text).root.descendants().filter { $0.kind == .link && $0.tokens.first { $0.kind == .linkPath } == nil && !$0.text.hasPrefix("[") && !$0.text.hasPrefix("<") && !$0.text.contains(":") }
56 #expect(radio.map { "\($0.range.lowerBound) \($0.range.upperBound)" } == links[0].split(separator: ",").map(String.init))
57 }
58}