Tests/OrgCoreTests/ExportOptionsTests.swift
107 lines · 5519 bytes
5 symbols in this file
1import Foundation
2import Testing
3@testable import OrgCore
4
5struct ExportOptionsTests {
6 static let oracle = ProcessInfo.processInfo.environment["ORGSTAR_SKIP_ORACLE"] == nil
7
8 @Test func readsOptions() {
9 let o = ExportOptions.parse("#+OPTIONS: toc:2 num:nil tags:not-in-toc\n#+OPTIONS: todo:nil ^:{} pri:t H:4\n#+EXCLUDE_TAGS: private\n#+HTML_HEAD: <link rel=x>\n")
10 #expect(o.toc == 2 && o.num == nil && o.tags && !o.tagsInTOC && !o.todo && o.scripts == .braces && o.priority && o.headlineLevels == 4)
11 #expect(o.excludeTags == ["private"] && o.htmlHead == ["<link rel=x>"])
12 #expect(ExportOptions.parse("* x\n").toc == 3)
13 #expect(ExportOptions.parse("#+OPTIONS: H:2 toc:t\n").toc == 2)
14 }
15
16 @Test func pagesFollowOptions() {
17 let org = """
18 #+TITLE: Doc
19 #+OPTIONS: ^:{} pri:t
20 #+HTML_HEAD: <link rel="stylesheet" href="s.css">
21 * TODO [#A] One :work:
22 x_1 y_{2} \\(a^2\\) $b$ and $5
23 ** Two
24 * Secret :noexport:
25 hidden
26 * COMMENT Draft
27 gone
28 * Old :ARCHIVE:
29 archived body
30 """
31 let page = HTMLExport.page(org, fallbackTitle: "f")
32 #expect(page.contains("<div id=\"table-of-contents\""))
33 #expect(page.contains("<span class=\"section-number-2\">1.</span>"))
34 #expect(page.contains("<span class=\"section-number-3\">1.1.</span>"))
35 #expect(page.contains("x_1 y<sub>2</sub>"))
36 #expect(page.contains("<span class=\"priority\">[#A]</span>"))
37 #expect(page.contains("<link rel=\"stylesheet\" href=\"s.css\">"))
38 #expect(page.contains("MathJax-script") && page.contains("\\(a^2\\)"))
39 #expect(!page.contains("hidden") && !page.contains("Secret") && !page.contains("gone"))
40 #expect(page.contains("Old") && !page.contains("archived body"))
41 let plain = HTMLExport.page("#+OPTIONS: toc:nil num:nil todo:nil tags:nil\n* TODO A :t:\n", fallbackTitle: "f")
42 #expect(!plain.contains("id=\"table-of-contents\"") && !plain.contains("section-number") && !plain.contains("TODO") && !plain.contains("class=\"tag\""))
43 let selected = HTMLExport.page("* A\na\n* B :export:\nb\n** C\nc\n", fallbackTitle: "f")
44 #expect(!selected.contains("<p>a</p>") && selected.contains("<p>b</p>") && selected.contains("<p>c</p>"))
45 }
46
47 @Test(.enabled(if: oracle))
48 func expandsPropertyMacroLikeOrg() throws {
49 let text = """
50 #+PROPERTY: color filecolor
51 Top: [{{{property(color)}}}]
52 * One
53 :PROPERTIES:
54 :color: red
55 :Size: big
56 :CUSTOM_ID: one
57 :END:
58 In one: [{{{property(color)}}}] [{{{property(SIZE)}}}] [{{{property(missing)}}}] [{{{property(ITEM)}}}]
59 ** Child
60 Child: [{{{property(color)}}}]
61 * Two
62 Two: [{{{property(color,*One)}}}] [{{{property(color,#one)}}}] [{{{property(Size, One)}}}]
63 """ + "\n"
64 let emacs = try EmacsOracle.evaluate(text, """
65 (progn
66 (require 'ox)
67 (org-macro-initialize-templates)
68 (org-macro-replace-all org-macro-templates)
69 (list (buffer-substring-no-properties (point-min) (point-max))))
70 """)
71 let ours = ExportPreprocess.macros(text, path: nil)
72 #expect(ours.contains("[red] [big] [] [One]") && ours == emacs.first, "ours:\n\(ours)\nemacs:\n\(emacs.first ?? "")")
73 }
74
75 @Test(.enabled(if: oracle))
76 func expandsIncludesAndMacrosLikeOrg() throws {
77 let folder = FileManager.default.temporaryDirectory.appendingPathComponent("orgstar-include-\(UUID().uuidString)")
78 try FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
79 defer { try? FileManager.default.removeItem(at: folder) }
80 try "* Part\nbody\n** Sub\nsub body\n* Other\n:PROPERTIES:\n:CUSTOM_ID: oth\n:END:\nother\n".write(to: folder.appendingPathComponent("part.org"), atomically: true, encoding: .utf8)
81 try "line 1\nline 2\n* not a heading\nline 4\nline 5\n".write(to: folder.appendingPathComponent("code.sh"), atomically: true, encoding: .utf8)
82 let text = """
83 #+TITLE: The Doc
84 #+AUTHOR: Me
85 #+MACRO: greet Hello, $1 and $2!
86 Intro {{{title}}} by {{{author}}}.
87 #+INCLUDE: "part.org"
88 #+INCLUDE: "part.org::*Sub" :minlevel 1
89 #+INCLUDE: "part.org::#oth"
90 #+INCLUDE: "code.sh" src sh :lines "2-4"
91 #+INCLUDE: "code.sh" example
92 {{{greet(you\\, me,them)}}} {{{n}}} {{{n}}} {{{n(x)}}} {{{keyword(AUTHOR)}}} {{{input-file}}}
93 """ + "\n"
94 let path = folder.appendingPathComponent("main.org").path
95 try text.write(toFile: path, atomically: true, encoding: .utf8)
96 let emacs = try EmacsOracle.evaluate(text, """
97 (with-current-buffer (find-file-noselect \(lispString(path)))
98 (require 'ox)
99 (org-export-expand-include-keyword)
100 (org-macro-initialize-templates)
101 (org-macro-replace-all org-macro-templates)
102 (list (buffer-substring-no-properties (point-min) (point-max))))
103 """)
104 let ours = ExportPreprocess.macros(ExportPreprocess.includes(text, directory: folder), path: path)
105 #expect(ours == emacs.first, "ours:\n\(ours)\nemacs:\n\(emacs.first ?? "")")
106 }
107}