Skip to content

Commit 2123075

Browse files
committed
add Snippet parsing tests
1 parent 2be40ba commit 2123075

File tree

3 files changed

+318
-6
lines changed

3 files changed

+318
-6
lines changed

Sources/MarkdownPluginSwift/Snippets/SnippetParser.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ extension SnippetParser
2828
private mutating
2929
func visit(trivia:Trivia, at position:AbsolutePosition)
3030
{
31-
var newline:(position:AbsolutePosition, indent:Int)? = nil
31+
var newline:(indent:Int, end:AbsolutePosition)? = nil
3232
var current:AbsolutePosition = position
3333
for piece:TriviaPiece in trivia
3434
{
@@ -44,8 +44,12 @@ extension SnippetParser
4444

4545
switch piece
4646
{
47-
case .newlines, .carriageReturnLineFeeds:
48-
newline = (position: range.lowerBound, indent: 0)
47+
case .newlines:
48+
newline = (indent: 0, end: min(current.advanced(by: 1), range.upperBound))
49+
continue
50+
51+
case .carriageReturnLineFeeds:
52+
newline = (indent: 0, end: min(current.advanced(by: 2), range.upperBound))
4953
continue
5054

5155
case .spaces(let count):
@@ -70,7 +74,7 @@ extension SnippetParser
7074
}
7175

7276
guard
73-
let leading:(position:AbsolutePosition, indent:Int) = newline
77+
let (indent, before):(Int, AbsolutePosition) = newline
7478
else
7579
{
7680
// We only care about line comments at the beginning of a line.
@@ -88,8 +92,8 @@ extension SnippetParser
8892
// newline. So code that uses these indices **must** clamp them to the bounds
8993
// of the source text.
9094
self.push(marker: .init(statement: statement,
91-
indent: leading.indent,
92-
before: leading.position,
95+
indent: indent,
96+
before: before,
9397
after: range.upperBound.advanced(by: 1),
9498
line: location.line))
9599
}
Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
import MarkdownPluginSwift
2+
import Testing
3+
4+
extension Main
5+
{
6+
struct Snippets
7+
{
8+
}
9+
}
10+
extension Main.Snippets:TestBattery
11+
{
12+
static
13+
func run(tests:TestGroup)
14+
{
15+
if let tests:TestGroup = tests / "MissingFinalNewline"
16+
{
17+
Self.run(tests: tests,
18+
snippet:
19+
"""
20+
print("Hi Barbie!")
21+
""",
22+
caption:
23+
"""
24+
""",
25+
slices:
26+
"""
27+
print("Hi Barbie!")
28+
""")
29+
}
30+
if let tests:TestGroup = tests / "NoCaption"
31+
{
32+
Self.run(tests: tests,
33+
snippet:
34+
"""
35+
print("Hi Barbie!")
36+
37+
""",
38+
caption:
39+
"""
40+
""",
41+
slices:
42+
"""
43+
print("Hi Barbie!")
44+
45+
""")
46+
}
47+
if let tests:TestGroup = tests / "WithCaption"
48+
{
49+
Self.run(tests: tests,
50+
snippet:
51+
"""
52+
// Here’s how to say ‘hi’ to Barbie.
53+
54+
print("Hi Barbie!")
55+
56+
""",
57+
caption:
58+
"""
59+
Here’s how to say ‘hi’ to Barbie.
60+
""",
61+
slices:
62+
"""
63+
print("Hi Barbie!")
64+
65+
""")
66+
}
67+
if let tests:TestGroup = tests / "WithCaptionDocComment"
68+
{
69+
Self.run(tests: tests,
70+
snippet:
71+
"""
72+
/// Here’s how to say ‘hi’ to Barbie.
73+
///
74+
/// This is a multi-line comment.
75+
76+
print("Hi Barbie!")
77+
78+
""",
79+
caption:
80+
"""
81+
Here’s how to say ‘hi’ to Barbie.
82+
83+
This is a multi-line comment.
84+
""",
85+
slices:
86+
"""
87+
print("Hi Barbie!")
88+
89+
""")
90+
}
91+
if let tests:TestGroup = tests / "CollapseWhitespace"
92+
{
93+
Self.run(tests: tests,
94+
snippet:
95+
"""
96+
/// Here’s how to say ‘hi’ to Barbie.
97+
98+
99+
100+
print("Hi Barbie!")
101+
102+
""",
103+
caption:
104+
"""
105+
Here’s how to say ‘hi’ to Barbie.
106+
""",
107+
slices:
108+
"""
109+
print("Hi Barbie!")
110+
111+
""")
112+
}
113+
if let tests:TestGroup = tests / "TriviaOnly"
114+
{
115+
Self.run(tests: tests,
116+
snippet:
117+
"""
118+
/// Here’s how to say ‘hi’ to Barbie.
119+
120+
// print("Hi Barbie!")
121+
122+
""",
123+
caption:
124+
"""
125+
Here’s how to say ‘hi’ to Barbie.
126+
""",
127+
slices:
128+
"""
129+
// print("Hi Barbie!")
130+
131+
""")
132+
}
133+
if let tests:TestGroup = tests / "TriviaOnlyManualViewbox"
134+
{
135+
Self.run(tests: tests,
136+
snippet:
137+
"""
138+
/// Here’s how to say ‘hi’ to Barbie.
139+
140+
// snippet.HI_BARBIE
141+
142+
// print("Hi Barbie!")
143+
144+
145+
146+
// snippet.end
147+
148+
""",
149+
caption:
150+
"""
151+
Here’s how to say ‘hi’ to Barbie.
152+
""",
153+
slices:
154+
"""
155+
156+
// print("Hi Barbie!")
157+
158+
""")
159+
}
160+
if let tests:TestGroup = tests / "Indented"
161+
{
162+
Self.run(tests: tests,
163+
snippet:
164+
"""
165+
/// Here’s how to say ‘hi’ to Barbie.
166+
167+
@main
168+
enum Main
169+
{
170+
// snippet.HI_BARBIE
171+
static func main()
172+
{
173+
print("Hi Barbie!")
174+
}
175+
// snippet.end
176+
}
177+
178+
""",
179+
caption:
180+
"""
181+
Here’s how to say ‘hi’ to Barbie.
182+
""",
183+
slices:
184+
"""
185+
@main
186+
enum Main
187+
{
188+
189+
""",
190+
"""
191+
static func main()
192+
{
193+
print("Hi Barbie!")
194+
}
195+
196+
""")
197+
}
198+
if let tests:TestGroup = tests / "IndentedNonContiguous"
199+
{
200+
Self.run(tests: tests,
201+
snippet:
202+
"""
203+
/// Here’s how to say ‘hi’ to Barbie.
204+
// snippet.end
205+
@main
206+
enum Main
207+
{
208+
// snippet.HI_BARBIE
209+
static func main()
210+
{
211+
print("Hi Barbie!")
212+
213+
// snippet.hide
214+
215+
print("Hi Ken!")
216+
217+
// snippet.show
218+
}
219+
// snippet.end
220+
}
221+
222+
""",
223+
caption:
224+
"""
225+
Here’s how to say ‘hi’ to Barbie.
226+
""",
227+
slices:
228+
"""
229+
""",
230+
"""
231+
static func main()
232+
{
233+
print("Hi Barbie!")
234+
}
235+
236+
""")
237+
}
238+
if let tests:TestGroup = tests / "Empty"
239+
{
240+
Self.run(tests: tests,
241+
snippet:
242+
"""
243+
/// Here’s how to say ‘hi’ to Barbie.
244+
245+
// snippet.end
246+
@main
247+
enum Main
248+
{
249+
// snippet.HI_BARBIE
250+
251+
// snippet.end
252+
static func main()
253+
{
254+
print("Hi Barbie!")
255+
}
256+
}
257+
258+
""",
259+
caption:
260+
"""
261+
Here’s how to say ‘hi’ to Barbie.
262+
""",
263+
slices:
264+
"""
265+
""",
266+
"""
267+
""")
268+
}
269+
}
270+
}
271+
extension Main.Snippets
272+
{
273+
private static
274+
func run(tests:TestGroup, snippet:String, caption:String, slices expected:String...)
275+
{
276+
let swift:Markdown.SwiftLanguage = .swift
277+
let (caption, slices):(String, [Markdown.SnippetSlice]) = swift.parse(
278+
snippet: [_].init(snippet.utf8))
279+
280+
if let tests:TestGroup = tests / "Caption"
281+
{
282+
tests.expect(caption ==? caption)
283+
}
284+
if let tests:TestGroup = tests / "Count"
285+
{
286+
tests.expect(slices.count ==? expected.count)
287+
}
288+
for (i, expected):(Int, String) in expected.enumerated()
289+
{
290+
guard
291+
let tests:TestGroup = tests / "\(i)"
292+
else
293+
{
294+
continue
295+
}
296+
if slices.indices.contains(i)
297+
{
298+
tests.expect("\(slices[i].code.safe)" ==? expected)
299+
}
300+
else
301+
{
302+
tests.expect(value: nil as Markdown.SnippetSlice?)
303+
continue
304+
}
305+
}
306+
}
307+
}

Sources/SymbolGraphLinkerTests/Main.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ enum Main:TestMain
1111
Lists.self,
1212
ListsWithMultipleItems.self,
1313
Parameters.self,
14+
Snippets.self,
1415
Topics.self,
1516
]
1617
}

0 commit comments

Comments
 (0)