Skip to content

Commit 62e240a

Browse files
committed
Add symbol name unit tests
1 parent 9b13986 commit 62e240a

File tree

1 file changed

+358
-0
lines changed

1 file changed

+358
-0
lines changed
Lines changed: 358 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,358 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SwiftSyntax
14+
import XCTest
15+
16+
final class SymbolNameTests: XCTestCase {
17+
18+
// MARK: - Functions
19+
20+
func testFunctionNameWithoutParameters() {
21+
assertSymbolName(ofFunction: "func name() {}", expecting: "name()")
22+
}
23+
24+
func testFunctionNameWithSingleNamedParameter() {
25+
assertSymbolName(ofFunction: "func name(one: Int) {}", expecting: "name(one:)")
26+
}
27+
28+
func testFunctionNameWithSingleUnnamedParameter() {
29+
assertSymbolName(ofFunction: "func name(_: Int) {}", expecting: "name(_:)")
30+
}
31+
32+
func testFunctionNameWithExternalParameterName() {
33+
assertSymbolName(ofFunction: "func name(one two: Int) {}", expecting: "name(one:)")
34+
}
35+
36+
func testFunctionNameWithExplicitExternalParameterName() {
37+
assertSymbolName(ofFunction: "func name(one _: Int) {}", expecting: "name(one:)")
38+
}
39+
40+
func testFunctionNameWithImplicitExternalParameterName() {
41+
assertSymbolName(ofFunction: "func name(_ two: Int) {}", expecting: "name(_:)")
42+
}
43+
44+
func testFunctionNameWithOnlyAnonymousParameters() {
45+
assertSymbolName(ofFunction: "func name(_ _: Int) {}", expecting: "name(_:)")
46+
}
47+
48+
func testFunctionNameWithMultipleNamedParameters() {
49+
assertSymbolName(ofFunction: "func name(one two: Int, three: Int) {}", expecting: "name(one:three:)")
50+
}
51+
52+
func testFunctionNameWithAllParametersHavingExternalNames() {
53+
assertSymbolName(ofFunction: "func name(one two: Int, three four: Int) {}", expecting: "name(one:three:)")
54+
}
55+
56+
func testFunctionNameWithMixedNamedAndAnonymousParameters() {
57+
assertSymbolName(ofFunction: "func name(one two: Int, _ four: Int) {}", expecting: "name(one:_:)")
58+
}
59+
60+
func testFunctionNameWithAllAnonymousParameters() {
61+
assertSymbolName(ofFunction: "func name(_ two: Int, _ four: Int) {}", expecting: "name(_:_:)")
62+
}
63+
64+
func testFunctionNameWithBackticks() {
65+
assertSymbolName(ofFunction: "func `name`() {}", expecting: "`name`()")
66+
}
67+
68+
func testFunctionNameWithParameterNameInBackticks() {
69+
assertSymbolName(ofFunction: "func name(`one`: Int) {}", expecting: "name(`one`:)")
70+
}
71+
72+
// FIXME: Does this make sense?
73+
func testOperatorFunctionName() {
74+
assertSymbolName(ofFunction: "func == (one: Int, two: Int)", expecting: "==(one:two:)")
75+
}
76+
77+
private func assertSymbolName(
78+
ofFunction function: DeclSyntax,
79+
expecting expectedSymbolName: String,
80+
file: StaticString = #filePath,
81+
line: UInt = #line
82+
) {
83+
guard let functionDecl = function.as(FunctionDeclSyntax.self) else {
84+
XCTFail("Expected function declaration not found.", file: file, line: line)
85+
return
86+
}
87+
88+
XCTAssertEqual(functionDecl.symbolName, expectedSymbolName, file: file, line: line)
89+
}
90+
91+
// MARK: - Initializer
92+
93+
func testInitializerWithoutParameters() {
94+
assertSymbolName(ofInitializer: "init() {}", expecting: "init()")
95+
}
96+
97+
func testInitializerWithSingleNamedParameter() {
98+
assertSymbolName(ofInitializer: "init(one: Int) {}", expecting: "init(one:)")
99+
}
100+
101+
func testInitializerWithSingleUnnamedParameter() {
102+
assertSymbolName(ofInitializer: "init(_: Int) {}", expecting: "init(_:)")
103+
}
104+
105+
func testInitializerWithExternalParameterName() {
106+
assertSymbolName(ofInitializer: "init(one two: Int) {}", expecting: "init(one:)")
107+
}
108+
109+
func testInitializerWithExplicitExternalParameterName() {
110+
assertSymbolName(ofInitializer: "init(one _: Int) {}", expecting: "init(one:)")
111+
}
112+
113+
func testInitializerWithImplicitExternalParameterName() {
114+
assertSymbolName(ofInitializer: "init(_ two: Int) {}", expecting: "init(_:)")
115+
}
116+
117+
func testInitializerWithOnlyAnonymousParameters() {
118+
assertSymbolName(ofInitializer: "init(_ _: Int) {}", expecting: "init(_:)")
119+
}
120+
121+
func testInitializerWithMultipleNamedParameters() {
122+
assertSymbolName(ofInitializer: "init(one two: Int, three: Int) {}", expecting: "init(one:three:)")
123+
}
124+
125+
func testInitializerWithAllParametersHavingExternalNames() {
126+
assertSymbolName(ofInitializer: "init(one two: Int, three four: Int) {}", expecting: "init(one:three:)")
127+
}
128+
129+
func testInitializerWithMixedNamedAndAnonymousParameters() {
130+
assertSymbolName(ofInitializer: "init(one two: Int, _ four: Int) {}", expecting: "init(one:_:)")
131+
}
132+
133+
func testInitializerWithAllAnonymousParameters() {
134+
assertSymbolName(ofInitializer: "init(_ two: Int, _ four: Int) {}", expecting: "init(_:_:)")
135+
}
136+
137+
func testInitializerWithNameInBackticks() {
138+
assertSymbolName(ofInitializer: "init(`one`: Int) {}", expecting: "init(`one`:)")
139+
}
140+
141+
private func assertSymbolName(
142+
ofInitializer initializer: DeclSyntax,
143+
expecting expectedSymbolName: String,
144+
file: StaticString = #filePath,
145+
line: UInt = #line
146+
) {
147+
guard let initializerDecl = initializer.as(InitializerDeclSyntax.self) else {
148+
XCTFail("Expected initializer declaration not found.", file: file, line: line)
149+
return
150+
}
151+
152+
XCTAssertEqual(initializerDecl.symbolName, expectedSymbolName, file: file, line: line)
153+
}
154+
155+
// MARK: - Subscript
156+
157+
func testSubscriptNameWithoutParameters() {
158+
assertSymbolName(ofSubscript: "subscript() -> Int { 0 }", expecting: "subscript()")
159+
}
160+
161+
func testSubscriptNameWithSingleNamedParameter() {
162+
assertSymbolName(ofSubscript: "subscript(index: Int) -> Int { 0 }", expecting: "subscript(_:)")
163+
}
164+
165+
func testSubscriptNameWithSingleUnnamedParameter() {
166+
assertSymbolName(ofSubscript: "subscript(_: Int) -> Int { 0 }", expecting: "subscript(_:)")
167+
}
168+
169+
func testSubscriptNameWithExternalParameterName() {
170+
assertSymbolName(ofSubscript: "subscript(index i: Int) -> Int { 0 }", expecting: "subscript(index:)")
171+
}
172+
173+
func testSubscriptNameWithExplicitExternalParameterName() {
174+
assertSymbolName(ofSubscript: "subscript(index _: Int) -> Int { 0 }", expecting: "subscript(index:)")
175+
}
176+
177+
func testSubscriptNameWithImplicitExternalParameterName() {
178+
assertSymbolName(ofSubscript: "subscript(_ i: Int) -> Int { 0 }", expecting: "subscript(_:)")
179+
}
180+
181+
func testSubscriptNameWithOnlyAnonymousParameters() {
182+
assertSymbolName(ofSubscript: "subscript(_ _: Int) -> Int { 0 }", expecting: "subscript(_:)")
183+
}
184+
185+
func testSubscriptNameWithMultipleNamedParameters() {
186+
assertSymbolName(ofSubscript: "subscript(x: Int, y: Int) -> Int { 0 }", expecting: "subscript(_:_:)")
187+
}
188+
189+
func testSubscriptNameWithMultipleParametersAndExternalNames() {
190+
assertSymbolName(
191+
ofSubscript: "subscript(indexX x: Int, indexY y: Int) -> Int { 0 }",
192+
expecting: "subscript(indexX:indexY:)"
193+
)
194+
}
195+
196+
func testSubscriptNameWithParameterNameInBackticks() {
197+
assertSymbolName(ofSubscript: "subscript(`index` i: Int) -> Int { 0 }", expecting: "subscript(`index`:)")
198+
}
199+
200+
private func assertSymbolName(
201+
ofSubscript subscriptDeclaration: DeclSyntax,
202+
expecting expectedSymbolName: String,
203+
file: StaticString = #filePath,
204+
line: UInt = #line
205+
) {
206+
guard let subscriptDecl = subscriptDeclaration.as(SubscriptDeclSyntax.self) else {
207+
XCTFail("Expected subscript declaration not found.", file: file, line: line)
208+
return
209+
}
210+
211+
XCTAssertEqual(subscriptDecl.symbolName, expectedSymbolName, file: file, line: line)
212+
}
213+
214+
// MARK: - Enum Case Element
215+
216+
func testEnumCaseElementWithoutAssociatedValues() {
217+
assertSymbolName(ofEnumCaseElementFromEnumCase: "case a", expecting: "a")
218+
}
219+
220+
func testEnumCaseElementWithSingleNamedAssociatedValue() {
221+
assertSymbolName(ofEnumCaseElementFromEnumCase: "case b(c: Int)", expecting: "b(c:)")
222+
}
223+
224+
func testEnumCaseElementWithSingleUnnamedAssociatedValue() {
225+
assertSymbolName(ofEnumCaseElementFromEnumCase: "case d(Int)", expecting: "d(_:)")
226+
}
227+
228+
func testEnumCaseElementWithSingleUnnamedAssociatedValueWithUnderscore() {
229+
assertSymbolName(ofEnumCaseElementFromEnumCase: "case e(_: Int)", expecting: "e(_:)")
230+
}
231+
232+
func testEnumCaseElementWithMultipleNamedAssociatedValues() {
233+
assertSymbolName(ofEnumCaseElementFromEnumCase: "case f(g: Int, h: Int)", expecting: "f(g:h:)")
234+
}
235+
236+
func testEnumCaseElementNameWithBackticks() {
237+
assertSymbolName(ofEnumCaseElementFromEnumCase: "case `i`", expecting: "`i`")
238+
}
239+
240+
func testEnumCaseElementWithAssociatedValueNameInBackticks() {
241+
assertSymbolName(ofEnumCaseElementFromEnumCase: "case j(`k`: Int)", expecting: "j(`k`:)")
242+
}
243+
244+
private func assertSymbolName(
245+
ofEnumCaseElementFromEnumCase enumCaseDeclaration: DeclSyntax,
246+
expecting expectedSymbolName: String,
247+
file: StaticString = #filePath,
248+
line: UInt = #line
249+
) {
250+
guard let enumCaseDecl = enumCaseDeclaration.as(EnumCaseDeclSyntax.self),
251+
let enumCaseElement = enumCaseDecl.elements.first
252+
else {
253+
XCTFail("Expected enum case element declaration not found.", file: file, line: line)
254+
return
255+
}
256+
XCTAssertEqual(enumCaseElement.symbolName, expectedSymbolName, file: file, line: line)
257+
}
258+
259+
// MARK: - Macro
260+
261+
func testMacroDeclWithoutParameters() {
262+
assertSymbolName(
263+
ofMacroDecl: ##"macro myMacro() = #externalMacro"##,
264+
expecting: "myMacro()"
265+
)
266+
}
267+
268+
func testMacroDeclWithSingleNamedParameter() {
269+
assertSymbolName(
270+
ofMacroDecl: ##"macro myMacro(x: Int) = #externalMacro"##,
271+
expecting: "myMacro(x:)"
272+
)
273+
}
274+
275+
func testMacroDeclWithSingleUnnamedParameter() {
276+
assertSymbolName(
277+
ofMacroDecl: ##"macro myMacro(_: Int) = #externalMacro"##,
278+
expecting: "myMacro(_:)"
279+
)
280+
}
281+
282+
func testMacroDeclWithExternalParameterName() {
283+
assertSymbolName(
284+
ofMacroDecl: ##"macro myMacro(external internal: Int) = #externalMacro"##,
285+
expecting: "myMacro(external:)"
286+
)
287+
}
288+
289+
func testMacroDeclWithExplicitExternalParameterName() {
290+
assertSymbolName(
291+
ofMacroDecl: ##"macro myMacro(external _: Int) = #externalMacro"##,
292+
expecting: "myMacro(external:)"
293+
)
294+
}
295+
296+
func testMacroDeclWithImplicitExternalParameterName() {
297+
assertSymbolName(
298+
ofMacroDecl: ##"macro myMacro(_ internal: Int) = #externalMacro"##,
299+
expecting: "myMacro(_:)"
300+
)
301+
}
302+
303+
func testMacroDeclWithMultipleNamedParameters() {
304+
assertSymbolName(
305+
ofMacroDecl: ##"macro myMacro(x: Int, y: String) = #externalMacro"##,
306+
expecting: "myMacro(x:y:)"
307+
)
308+
}
309+
310+
func testMacroDeclWithAllParametersHavingExternalNames() {
311+
assertSymbolName(
312+
ofMacroDecl: ##"macro myMacro(external1 internal1: Int, external2 internal2: String) = #externalMacro"##,
313+
expecting: "myMacro(external1:external2:)"
314+
)
315+
}
316+
317+
func testMacroDeclWithMixedNamedAndUnnamedParameters() {
318+
assertSymbolName(
319+
ofMacroDecl: ##"macro myMacro(x: Int, _: String) = #externalMacro"##,
320+
expecting: "myMacro(x:_:)"
321+
)
322+
}
323+
324+
func testMacroDeclWithNameInBackticks() {
325+
assertSymbolName(
326+
ofMacroDecl: ##"macro `myMacro`() = #externalMacro"##,
327+
expecting: "`myMacro`()"
328+
)
329+
}
330+
331+
func testMacroDeclWithParameterNameInBackticks() {
332+
assertSymbolName(
333+
ofMacroDecl: ##"macro myMacro(`x`: Int) = #externalMacro"##,
334+
expecting: "myMacro(`x`:)"
335+
)
336+
}
337+
338+
func testMacroDeclWithExternalParameterNameInBackticks() {
339+
assertSymbolName(
340+
ofMacroDecl: ##"macro myMacro(`external` internal: Int) = #externalMacro"##,
341+
expecting: "myMacro(`external`:)"
342+
)
343+
}
344+
345+
private func assertSymbolName(
346+
ofMacroDecl macroDecl: DeclSyntax,
347+
expecting expectedSymbolName: String,
348+
file: StaticString = #filePath,
349+
line: UInt = #line
350+
) {
351+
guard let macroDeclSyntax = macroDecl.as(MacroDeclSyntax.self) else {
352+
XCTFail("Expected macro declaration not found.", file: file, line: line)
353+
return
354+
}
355+
356+
XCTAssertEqual(macroDeclSyntax.symbolName, expectedSymbolName, file: file, line: line)
357+
}
358+
}

0 commit comments

Comments
 (0)