Skip to content

Commit 6d23806

Browse files
Add unit tests
1 parent 9dbb13a commit 6d23806

File tree

2 files changed

+554
-0
lines changed

2 files changed

+554
-0
lines changed
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
import SwiftSyntax
2+
import SwiftSyntaxBuilder
3+
import XCTest
4+
5+
@testable import SpyableMacro
6+
7+
final class UT_AccessLevelModifierRewriter: XCTestCase {
8+
9+
// MARK: - Normal Access Level Rewriting Tests
10+
11+
func test_visit_withPublicAccessLevel_shouldAddPublicModifier() {
12+
// Given
13+
let accessLevel = DeclModifierSyntax(name: .keyword(.public))
14+
let rewriter = AccessLevelModifierRewriter(newAccessLevel: accessLevel)
15+
16+
let originalFunction = FunctionDeclSyntax(
17+
modifiers: [],
18+
name: .identifier("testFunction"),
19+
signature: FunctionSignatureSyntax(
20+
parameterClause: FunctionParameterClauseSyntax(parameters: [])
21+
)
22+
) {}
23+
24+
// When
25+
let rewrittenFunction = rewriter.visit(originalFunction).as(FunctionDeclSyntax.self)!
26+
27+
// Then
28+
let modifiers = rewrittenFunction.modifiers
29+
XCTAssertEqual(modifiers.count, 1)
30+
XCTAssertEqual(modifiers.first?.name.text, "public")
31+
}
32+
33+
func test_visit_withInternalAccessLevel_shouldAddInternalModifier() {
34+
// Given
35+
let accessLevel = DeclModifierSyntax(name: .keyword(.internal))
36+
let rewriter = AccessLevelModifierRewriter(newAccessLevel: accessLevel)
37+
38+
let originalVariable = VariableDeclSyntax(
39+
modifiers: [],
40+
bindingSpecifier: .keyword(.var)
41+
) {
42+
PatternBindingSyntax(
43+
pattern: IdentifierPatternSyntax(identifier: .identifier("testVar")),
44+
typeAnnotation: TypeAnnotationSyntax(type: TypeSyntax("String"))
45+
)
46+
}
47+
48+
// When
49+
let rewrittenVariable = rewriter.visit(originalVariable).as(VariableDeclSyntax.self)!
50+
51+
// Then
52+
let modifiers = rewrittenVariable.modifiers
53+
XCTAssertEqual(modifiers.count, 1)
54+
XCTAssertEqual(modifiers.first?.name.text, "internal")
55+
}
56+
57+
func test_visit_withPrivateAccessLevel_shouldConvertToFileprivate() {
58+
// Given
59+
let accessLevel = DeclModifierSyntax(name: .keyword(.private))
60+
let rewriter = AccessLevelModifierRewriter(newAccessLevel: accessLevel)
61+
62+
let originalFunction = FunctionDeclSyntax(
63+
modifiers: [],
64+
name: .identifier("testFunction"),
65+
signature: FunctionSignatureSyntax(
66+
parameterClause: FunctionParameterClauseSyntax(parameters: [])
67+
)
68+
) {}
69+
70+
// When
71+
let rewrittenFunction = rewriter.visit(originalFunction).as(FunctionDeclSyntax.self)!
72+
73+
// Then
74+
let modifiers = rewrittenFunction.modifiers
75+
XCTAssertEqual(modifiers.count, 1)
76+
XCTAssertEqual(modifiers.first?.name.text, "fileprivate")
77+
}
78+
79+
// MARK: - Initializer Special Case Tests
80+
81+
func test_visit_withOpenAccessLevel_onInitializer_shouldUsePublicInstead() {
82+
// Given
83+
let accessLevel = DeclModifierSyntax(name: .keyword(.open))
84+
let rewriter = AccessLevelModifierRewriter(newAccessLevel: accessLevel)
85+
86+
let originalInit = InitializerDeclSyntax(
87+
modifiers: [],
88+
signature: FunctionSignatureSyntax(
89+
parameterClause: FunctionParameterClauseSyntax(parameters: [])
90+
)
91+
) {}
92+
93+
// When
94+
let rewrittenInit = rewriter.visit(originalInit).as(InitializerDeclSyntax.self)!
95+
96+
// Then
97+
let modifiers = rewrittenInit.modifiers
98+
XCTAssertEqual(modifiers.count, 1)
99+
XCTAssertEqual(modifiers.first?.name.text, "public")
100+
}
101+
102+
func test_visit_withOpenAccessLevel_onInitializerWithOverride_shouldPreserveOverrideAndAddPublic() {
103+
// Given
104+
let accessLevel = DeclModifierSyntax(name: .keyword(.open))
105+
let rewriter = AccessLevelModifierRewriter(newAccessLevel: accessLevel)
106+
107+
let originalInit = InitializerDeclSyntax(
108+
modifiers: [DeclModifierSyntax(name: .keyword(.override))],
109+
signature: FunctionSignatureSyntax(
110+
parameterClause: FunctionParameterClauseSyntax(parameters: [])
111+
)
112+
) {}
113+
114+
// When
115+
let rewrittenInit = rewriter.visit(originalInit).as(InitializerDeclSyntax.self)!
116+
117+
// Then
118+
let modifiers = rewrittenInit.modifiers
119+
XCTAssertEqual(modifiers.count, 2)
120+
121+
let modifierTexts = modifiers.map { $0.name.text }
122+
XCTAssertTrue(modifierTexts.contains("override"))
123+
XCTAssertTrue(modifierTexts.contains("public"))
124+
}
125+
126+
func test_visit_withOpenAccessLevel_onInitializerWithConvenience_shouldPreserveConvenienceAndAddPublic() {
127+
// Given
128+
let accessLevel = DeclModifierSyntax(name: .keyword(.open))
129+
let rewriter = AccessLevelModifierRewriter(newAccessLevel: accessLevel)
130+
131+
let originalInit = InitializerDeclSyntax(
132+
modifiers: [DeclModifierSyntax(name: .keyword(.convenience))],
133+
signature: FunctionSignatureSyntax(
134+
parameterClause: FunctionParameterClauseSyntax(parameters: [])
135+
)
136+
) {}
137+
138+
// When
139+
let rewrittenInit = rewriter.visit(originalInit).as(InitializerDeclSyntax.self)!
140+
141+
// Then
142+
let modifiers = rewrittenInit.modifiers
143+
XCTAssertEqual(modifiers.count, 2)
144+
145+
let modifierTexts = modifiers.map { $0.name.text }
146+
XCTAssertTrue(modifierTexts.contains("convenience"))
147+
XCTAssertTrue(modifierTexts.contains("public"))
148+
}
149+
150+
func test_visit_withOpenAccessLevel_onNonInitializer_shouldUseOpen() {
151+
// Given
152+
let accessLevel = DeclModifierSyntax(name: .keyword(.open))
153+
let rewriter = AccessLevelModifierRewriter(newAccessLevel: accessLevel)
154+
155+
let originalFunction = FunctionDeclSyntax(
156+
modifiers: [],
157+
name: .identifier("testFunction"),
158+
signature: FunctionSignatureSyntax(
159+
parameterClause: FunctionParameterClauseSyntax(parameters: [])
160+
)
161+
) {}
162+
163+
// When
164+
let rewrittenFunction = rewriter.visit(originalFunction).as(FunctionDeclSyntax.self)!
165+
166+
// Then
167+
let modifiers = rewrittenFunction.modifiers
168+
XCTAssertEqual(modifiers.count, 1)
169+
XCTAssertEqual(modifiers.first?.name.text, "open")
170+
}
171+
172+
// MARK: - Preserve Existing Modifiers Tests
173+
174+
func test_visit_withExistingModifiers_shouldPreserveAndAddAccessLevel() {
175+
// Given
176+
let accessLevel = DeclModifierSyntax(name: .keyword(.public))
177+
let rewriter = AccessLevelModifierRewriter(newAccessLevel: accessLevel)
178+
179+
let originalFunction = FunctionDeclSyntax(
180+
modifiers: [
181+
DeclModifierSyntax(name: .keyword(.static)),
182+
DeclModifierSyntax(name: .keyword(.final))
183+
],
184+
name: .identifier("testFunction"),
185+
signature: FunctionSignatureSyntax(
186+
parameterClause: FunctionParameterClauseSyntax(parameters: [])
187+
)
188+
) {}
189+
190+
// When
191+
let rewrittenFunction = rewriter.visit(originalFunction).as(FunctionDeclSyntax.self)!
192+
193+
// Then
194+
let modifiers = rewrittenFunction.modifiers
195+
XCTAssertEqual(modifiers.count, 3)
196+
197+
let modifierTexts = modifiers.map { $0.name.text }
198+
XCTAssertTrue(modifierTexts.contains("static"))
199+
XCTAssertTrue(modifierTexts.contains("final"))
200+
XCTAssertTrue(modifierTexts.contains("public"))
201+
}
202+
203+
// MARK: - Function Parameter Tests
204+
205+
func test_visit_onFunctionParameter_shouldNotModify() {
206+
// Given
207+
let accessLevel = DeclModifierSyntax(name: .keyword(.public))
208+
let rewriter = AccessLevelModifierRewriter(newAccessLevel: accessLevel)
209+
210+
let parameter = FunctionParameterSyntax(
211+
modifiers: [],
212+
firstName: .identifier("param"),
213+
type: TypeSyntax("String")
214+
)
215+
216+
// When
217+
let rewrittenParameter = rewriter.visit(parameter).as(FunctionParameterSyntax.self)!
218+
219+
// Then
220+
XCTAssertEqual(rewrittenParameter.modifiers.count, 0)
221+
}
222+
223+
// MARK: - Edge Cases Tests
224+
225+
func test_visit_withEmptyModifierList_shouldAddAccessLevel() {
226+
// Given
227+
let accessLevel = DeclModifierSyntax(name: .keyword(.internal))
228+
let rewriter = AccessLevelModifierRewriter(newAccessLevel: accessLevel)
229+
230+
let originalClass = ClassDeclSyntax(
231+
modifiers: [],
232+
name: .identifier("TestClass")
233+
) {}
234+
235+
// When
236+
let rewrittenClass = rewriter.visit(originalClass).as(ClassDeclSyntax.self)!
237+
238+
// Then
239+
let modifiers = rewrittenClass.modifiers
240+
XCTAssertEqual(modifiers.count, 1)
241+
XCTAssertEqual(modifiers.first?.name.text, "internal")
242+
}
243+
244+
func test_init_withPrivateAccessLevel_shouldConvertToFileprivateInInit() {
245+
// Given & When
246+
let accessLevel = DeclModifierSyntax(name: .keyword(.private))
247+
let rewriter = AccessLevelModifierRewriter(newAccessLevel: accessLevel)
248+
249+
// Then
250+
XCTAssertEqual(rewriter.newAccessLevel.name.text, "fileprivate")
251+
}
252+
253+
func test_init_withNonPrivateAccessLevel_shouldKeepOriginal() {
254+
// Given & When
255+
let accessLevel = DeclModifierSyntax(name: .keyword(.public))
256+
let rewriter = AccessLevelModifierRewriter(newAccessLevel: accessLevel)
257+
258+
// Then
259+
XCTAssertEqual(rewriter.newAccessLevel.name.text, "public")
260+
}
261+
}

0 commit comments

Comments
 (0)