-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDjotTest.swift
More file actions
162 lines (147 loc) · 4.66 KB
/
Copy pathDjotTest.swift
File metadata and controls
162 lines (147 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import XCTest
@testable import SwiftDjot
class DjotTests: XCTestCase {
public static let quiet = "" == "" // edit during debugging
func testDemo() {
if !Self.quiet {
XCTAssert(Djot.DEMO_OK == Djot.demo())
}
}
func testHtml() {
checkHtml("hi")
}
func testHtmlEmoji() {
checkHtml("🦗")
}
func checkHtml(_ header: String) {
let me = Djot()
let parse = me.parse("# \(header)\n")
guard let parse = assertOk(parse) else { return }
let html = me.html(parse)
guard let html = assertOk(html) else { return }
let expected = "<sectionid=\"\(header)\"><h1>\(header)</h1></section>"
check(parse, html, expected)
}
func testEvents() {
let me = Djot()
let peResult = me.parseEvents("# hi\n")
guard let result = assertOk(peResult) else { return }
let (parse, events) = result
let expected = """
[["+heading",1,1],["str",3,4],["-heading",5,5]]
"""
check(parse, events, expected)
}
/// CDjot permits running parses in parallel in different instances.
/// Though the code sets Lua "global" values, they are scoped to the Lua parser instance held by the Djot.
func testHtmlDuals() {
let me1 = Djot()
let parse1 = me1.parse("# hi\n")
let me2 = Djot()
let parse2 = me2.parse("# low\n")
guard let parse1 = assertOk(parse1) else { return } // failed already
guard let parse2 = assertOk(parse2) else { return } // failed already
let html2 = me2.html(parse2) // invalidates parse1 IF global
let html1 = me1.html(parse1) // using invalidated parse?
guard let htm1Result = assertOk(html1, "hi") else { return }
guard let htm2Result = assertOk(html2, "lo") else { return }
let expected1 = "<sectionid=\"hi\"><h1>hi</h1></section>"
check(parse1, htm1Result, expected1)
let expected2 = "<sectionid=\"low\"><h1>low</h1></section>"
check(parse2, htm2Result, expected2)
}
/// Verify that stale parses trigger the corresponding error.
func testInvalidParse() {
let me = Djot()
let parse1 = me.parse("# hi\n")
guard let parse1 = assertOk(parse1) else { return }
_ = me.parse("# hi\n") // invalidates parse1
let html1 = me.html(parse1)
switch html1 {
case .success(_): XCTFail("should have failed")
case let .failure(err):
let exp = Djot.DjotErr.invalidParse
XCTAssertEqual(exp.index, err.index)
}
}
/// djot seems to tolerate the invalid-unicode character, but we detect it in the result
func testHtmlWithInvalidEncoding() {
let doc = "hi" + String(CBridge.invalidUnicodeChar) + "!"
let me = Djot()
let parse = me.parse("# \(doc)\n")
guard let parse = assertOk(parse) else { return }
let html = me.html(parse)
switch html {
case let .failure(err):
switch err {
case let .resultStrCopy(cerr):
switch cerr {
case let .encodingError(s, i):
if let index = CBridge.unicodeInvalidAt(s) {
XCTAssertEqual(index, i, "wrong index for unicode invalid")
}
return // done/pass
}
default:
break
}
default:
break
}
XCTFail("invalid encoding [\(doc)]expected fail, got \(html)")
}
func assertOk<T, E: Error>(
_ result: Result<T, E>,
_ label: String? = "Result",
permitPartial: Bool = false,
line: UInt = #line
) -> T? {
switch result {
case let .success(result): return result
case let .failure(error):
if let err = error as? CBridgeErr {
XCTFail(errStr(err, label), line: line)
return nil
}
if let err = error as? Djot.DjotErr {
XCTFail(errStr(err, label), line: line)
return nil
}
XCTFail("programmer error: not DjotErr or CBridgeErr", line: line)
}
return nil
}
func check(
_ parse: Djot.Parse,
_ actual: String?,
_ strippedExpected: String,
_ line: UInt = #line
) {
let label = " - expected \"\(strippedExpected)\""
guard let actual = actual else {
XCTFail("no result \(label)", line: line)
return
}
guard parse.ok else {
XCTFail("not ok \(label)", line: line)
return
}
let strippedActual = strip(actual)
XCTAssertEqual(
strippedExpected,
strippedActual,
"actual: \"\(actual)\" \(label)",
line: line
)
}
func strip(_ s: String) -> String {
s.replacingOccurrences(of: " ", with: "")
.replacingOccurrences(of: "\n", with: "")
}
func errStr(_ e: Djot.DjotErr?, _ suffix: String? = nil) -> String {
(nil == e ? "nil DjotErr" : "\(e!)") + "\(suffix ?? "")"
}
func errStr(_ e: CBridgeErr!, _ suffix: String? = nil) -> String {
nil == e ? "nil CBridgeErr" : "\(e!)" + "\(suffix ?? "")"
}
}