-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathBibleTextNodeTests.swift
More file actions
132 lines (106 loc) · 4.28 KB
/
BibleTextNodeTests.swift
File metadata and controls
132 lines (106 loc) · 4.28 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
@testable import YouVersionPlatformCore
import Testing
@Test
func testParse_DivSpanStructure() throws {
let html = "<div><div class=\"q1\"><span class=\"yv-v\" v=\"1\"></span><span class=\"yv-vlbl\">1</span>Praise the <span class=\"nd\">Lord</span>, all you nations;</div></div>"
let root = try #require(try BibleTextNode.parse(html))
#expect(root.type == .root)
#expect(root.children.count == 1)
let outer = try #require(root.children.first)
#expect(outer.type == .block)
let inner = try #require(outer.children.first)
#expect(inner.type == .block)
#expect(inner.classes.contains("q1"))
// children: [span.yv-v, span.yv-vlbl, text("Praise the"), span.nd, text(", all you nations;")]
#expect(inner.children.count == 5)
let verseMarker = inner.children[0]
#expect(verseMarker.type == .span)
#expect(verseMarker.classes.contains("yv-v"))
#expect(verseMarker.attributes["v"] == "1")
#expect(verseMarker.textSegments.isEmpty)
let verseLabel = inner.children[1]
#expect(verseLabel.type == .span)
#expect(verseLabel.classes.contains("yv-vlbl"))
#expect(verseLabel.children.count == 1)
let verseLabelText = verseLabel.children[0]
#expect(verseLabelText.type == .text)
#expect(verseLabelText.text == "1")
let textBefore = inner.children[2]
#expect(textBefore.type == .text)
#expect(textBefore.text == "Praise the ") // trailing space preserved from HTML
let nameDivine = inner.children[3]
#expect(nameDivine.type == .span)
#expect(nameDivine.classes.contains("nd"))
#expect(nameDivine.children.count == 1)
let nameDivineText = nameDivine.children[0]
#expect(nameDivineText.type == .text)
#expect(nameDivineText.text == "Lord")
let textAfter = inner.children[4]
#expect(textAfter.type == .text)
#expect(textAfter.text == ", all you nations;")
}
@Test
func testParse_GenesisIntroContainsText() throws {
let html = """
<div>
<div class="pi">
<span class="yv-v" v="1"></span>
<span class="yv-vlbl">1</span>
In the beginning, God created the heavens and the earth.
</div>
</div>
"""
let root = try #require(try BibleTextNode.parse(html))
func collectTexts(_ node: BibleTextNode) -> [String] {
var texts: [String] = []
if node.type == .text {
let trimmed = node.text.trimmingCharacters(in: .whitespacesAndNewlines)
if !trimmed.isEmpty {
texts.append(trimmed)
}
}
for child in node.children {
texts.append(contentsOf: collectTexts(child))
}
return texts
}
let texts = collectTexts(root)
#expect(texts.contains("In the beginning, God created the heavens and the earth."))
}
@Test
func testParse_SpacesBetweenInlineSpansArePreserved() throws {
let html = "<div><span>One</span> <span>Two</span> <span>Three three three</span>.</div>"
let root = try #require(try BibleTextNode.parse(html))
let block = try #require(root.children.first)
let renderedText = collectRenderedText(from: block)
#expect(renderedText == "One Two Three three three.")
}
@Test
func testParse_MixedWhitespaceAndInlineNodesCollapseToSingleSpaces() throws {
let html = "<div> Start <span>middle</span>\n\t <span>end</span> done </div>"
let root = try #require(try BibleTextNode.parse(html))
let block = try #require(root.children.first)
let renderedText = collectRenderedText(from: block)
#expect(renderedText == "Start middle end done")
}
@Test
func testParse_LeadingWhitespaceBeforeFirstChildIsIgnored() throws {
let html = "<div> <span>One</span> <span>Two</span></div>"
let root = try #require(try BibleTextNode.parse(html))
let block = try #require(root.children.first)
let renderedText = collectRenderedText(from: block)
#expect(renderedText == "One Two")
}
private func collectRenderedText(from node: BibleTextNode) -> String {
var text = ""
appendRenderedText(from: node, into: &text)
return text.trimmingCharacters(in: .whitespacesAndNewlines)
}
private func appendRenderedText(from node: BibleTextNode, into text: inout String) {
if node.type == .text {
text += node.text
}
for child in node.children {
appendRenderedText(from: child, into: &text)
}
}