Skip to content

Commit 8f6efea

Browse files
committed
adding more tests
1 parent 75e490a commit 8f6efea

File tree

6 files changed

+2020
-4
lines changed

6 files changed

+2020
-4
lines changed

Sources/SyntaxKit/Expressions/ReferenceExp.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,16 @@ public struct ReferenceExp: CodeBlock {
4646
public var syntax: SyntaxProtocol {
4747
// For capture lists, we need to create a proper reference
4848
// This will be handled by the Closure syntax when used in capture lists
49-
let baseExpr = ExprSyntax(
50-
fromProtocol: base.syntax.as(ExprSyntax.self)
51-
?? DeclReferenceExprSyntax(baseName: .identifier(""))
52-
)
49+
let baseExpr: ExprSyntax
50+
if let enumCase = base as? EnumCase {
51+
// Handle EnumCase specially - use expression syntax for enum cases in expressions
52+
baseExpr = enumCase.asExpressionSyntax
53+
} else {
54+
baseExpr = ExprSyntax(
55+
fromProtocol: base.syntax.as(ExprSyntax.self)
56+
?? DeclReferenceExprSyntax(baseName: .identifier(""))
57+
)
58+
}
5359

5460
// Create a custom expression that represents a reference
5561
// This will be used by the Closure to create proper capture syntax
Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
//
2+
// ConditionalOpTests.swift
3+
// SyntaxKitTests
4+
//
5+
// Created by Leo Dion.
6+
// Copyright © 2025 BrightDigit.
7+
//
8+
// Permission is hereby granted, free of charge, to any person
9+
// obtaining a copy of this software and associated documentation
10+
// files (the "Software"), to deal in the Software without
11+
// restriction, including without limitation the rights to use,
12+
// copy, modify, merge, publish, distribute, sublicense, and/or
13+
// sell copies of the Software, and to permit persons to whom the
14+
// Software is furnished to do so, subject to the following
15+
// conditions:
16+
//
17+
// The above copyright notice and this permission notice shall be
18+
// included in all copies or substantial portions of the Software.
19+
//
20+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27+
// OTHER DEALINGS IN THE SOFTWARE.
28+
//
29+
30+
import SwiftSyntax
31+
import Testing
32+
33+
@testable import SyntaxKit
34+
35+
/// Test suite for ConditionalOp expression functionality.
36+
///
37+
/// This test suite covers the ternary conditional operator expression
38+
/// (`condition ? then : else`) functionality in SyntaxKit.
39+
internal final class ConditionalOpTests {
40+
/// Tests basic conditional operator with simple expressions.
41+
@Test("Basic conditional operator generates correct syntax")
42+
internal func testBasicConditionalOp() {
43+
let conditional = ConditionalOp(
44+
if: VariableExp("isEnabled"),
45+
then: VariableExp("true"),
46+
else: VariableExp("false")
47+
)
48+
49+
let syntax = conditional.syntax
50+
let description = syntax.description
51+
52+
#expect(description.contains("isEnabled ? true : false"))
53+
}
54+
55+
/// Tests conditional operator with complex expressions.
56+
@Test("Conditional operator with complex expressions generates correct syntax")
57+
internal func testConditionalOpWithComplexExpressions() {
58+
let conditional = ConditionalOp(
59+
if: VariableExp("user.isLoggedIn"),
60+
then: Call("getUserProfile"),
61+
else: Call("getDefaultProfile")
62+
)
63+
64+
let syntax = conditional.syntax
65+
let description = syntax.description
66+
67+
#expect(description.contains("user.isLoggedIn ? getUserProfile() : getDefaultProfile()"))
68+
}
69+
70+
/// Tests conditional operator with enum cases.
71+
@Test("Conditional operator with enum cases generates correct syntax")
72+
internal func testConditionalOpWithEnumCases() {
73+
let conditional = ConditionalOp(
74+
if: VariableExp("status"),
75+
then: EnumCase("active"),
76+
else: EnumCase("inactive")
77+
)
78+
79+
let syntax = conditional.syntax
80+
let description = syntax.description
81+
82+
#expect(description.contains("status ? .active : .inactive"))
83+
}
84+
85+
/// Tests conditional operator with mixed enum cases and expressions.
86+
@Test("Conditional operator with mixed enum cases and expressions generates correct syntax")
87+
internal func testConditionalOpWithMixedEnumCasesAndExpressions() {
88+
let conditional = ConditionalOp(
89+
if: VariableExp("isActive"),
90+
then: EnumCase("active"),
91+
else: VariableExp("defaultStatus")
92+
)
93+
94+
let syntax = conditional.syntax
95+
let description = syntax.description
96+
97+
#expect(description.contains("isActive ? .active : defaultStatus"))
98+
}
99+
100+
/// Tests conditional operator with nested conditional operators.
101+
@Test("Nested conditional operators generate correct syntax")
102+
internal func testNestedConditionalOperators() {
103+
let innerConditional = ConditionalOp(
104+
if: VariableExp("isPremium"),
105+
then: VariableExp("premiumValue"),
106+
else: VariableExp("standardValue")
107+
)
108+
109+
let outerConditional = ConditionalOp(
110+
if: VariableExp("isEnabled"),
111+
then: innerConditional,
112+
else: VariableExp("disabledValue")
113+
)
114+
115+
let syntax = outerConditional.syntax
116+
let description = syntax.description
117+
118+
#expect(
119+
description.contains("isEnabled ? isPremium ? premiumValue : standardValue : disabledValue"))
120+
}
121+
122+
/// Tests conditional operator with function calls.
123+
@Test("Conditional operator with function calls generates correct syntax")
124+
internal func testConditionalOpWithFunctionCalls() {
125+
let conditional = ConditionalOp(
126+
if: Call("isValid"),
127+
then: Call("processValid"),
128+
else: Call("handleInvalid")
129+
)
130+
131+
let syntax = conditional.syntax
132+
let description = syntax.description
133+
134+
#expect(description.contains("isValid() ? processValid() : handleInvalid()"))
135+
}
136+
137+
/// Tests conditional operator with property access.
138+
@Test("Conditional operator with property access generates correct syntax")
139+
internal func testConditionalOpWithPropertyAccess() {
140+
let conditional = ConditionalOp(
141+
if: PropertyAccessExp(base: VariableExp("user"), propertyName: "isAdmin"),
142+
then: PropertyAccessExp(base: VariableExp("user"), propertyName: "adminSettings"),
143+
else: PropertyAccessExp(base: VariableExp("user"), propertyName: "defaultSettings")
144+
)
145+
146+
let syntax = conditional.syntax
147+
let description = syntax.description
148+
149+
#expect(description.contains("user.isAdmin ? user.adminSettings : user.defaultSettings"))
150+
}
151+
152+
/// Tests conditional operator with literal values.
153+
@Test("Conditional operator with literal values generates correct syntax")
154+
internal func testConditionalOpWithLiteralValues() {
155+
let conditional = ConditionalOp(
156+
if: VariableExp("count"),
157+
then: Literal.integer(42),
158+
else: Literal.integer(0)
159+
)
160+
161+
let syntax = conditional.syntax
162+
let description = syntax.description
163+
164+
#expect(description.contains("count ? 42 : 0"))
165+
}
166+
167+
/// Tests conditional operator with string literals.
168+
@Test("Conditional operator with string literals generates correct syntax")
169+
internal func testConditionalOpWithStringLiterals() {
170+
let conditional = ConditionalOp(
171+
if: VariableExp("isError"),
172+
then: Literal.string("Error occurred"),
173+
else: Literal.string("Success")
174+
)
175+
176+
let syntax = conditional.syntax
177+
let description = syntax.description
178+
179+
#expect(description.contains("isError ? \"Error occurred\" : \"Success\""))
180+
}
181+
182+
/// Tests conditional operator with boolean literals.
183+
@Test("Conditional operator with boolean literals generates correct syntax")
184+
internal func testConditionalOpWithBooleanLiterals() {
185+
let conditional = ConditionalOp(
186+
if: VariableExp("condition"),
187+
then: Literal.boolean(true),
188+
else: Literal.boolean(false)
189+
)
190+
191+
let syntax = conditional.syntax
192+
let description = syntax.description
193+
194+
#expect(description.contains("condition ? true : false"))
195+
}
196+
197+
/// Tests conditional operator with array literals.
198+
@Test("Conditional operator with array literals generates correct syntax")
199+
internal func testConditionalOpWithArrayLiterals() {
200+
let conditional = ConditionalOp(
201+
if: VariableExp("isFull"),
202+
then: Literal.array([Literal.string("item1"), Literal.string("item2")]),
203+
else: Literal.array([])
204+
)
205+
206+
let syntax = conditional.syntax
207+
let description = syntax.description
208+
209+
#expect(description.contains("isFull ? [\"item1\", \"item2\"] : []"))
210+
}
211+
212+
/// Tests conditional operator with dictionary literals.
213+
@Test("Conditional operator with dictionary literals generates correct syntax")
214+
internal func testConditionalOpWithDictionaryLiterals() {
215+
let conditional = ConditionalOp(
216+
if: VariableExp("hasConfig"),
217+
then: Literal.dictionary([(Literal.string("key"), Literal.string("value"))]),
218+
else: Literal.dictionary([])
219+
)
220+
221+
let syntax = conditional.syntax
222+
let description = syntax.description
223+
224+
#expect(description.contains("hasConfig ? [\"key\":\"value\"] : [:]"))
225+
}
226+
227+
/// Tests conditional operator with tuple expressions.
228+
@Test("Conditional operator with tuple expressions generates correct syntax")
229+
internal func testConditionalOpWithTupleExpressions() {
230+
let conditional = ConditionalOp(
231+
if: VariableExp("isSuccess"),
232+
then: Literal.tuple([Literal.string("success"), Literal.integer(200)]),
233+
else: Literal.tuple([Literal.string("error"), Literal.integer(404)])
234+
)
235+
236+
let syntax = conditional.syntax
237+
let description = syntax.description
238+
239+
#expect(description.contains("isSuccess ? (\"success\", 200) : (\"error\", 404)"))
240+
}
241+
242+
/// Tests conditional operator with nil coalescing.
243+
@Test("Conditional operator with nil coalescing generates correct syntax")
244+
internal func testConditionalOpWithNilCoalescing() {
245+
let conditional = ConditionalOp(
246+
if: VariableExp("optionalValue"),
247+
then: VariableExp("optionalValue"),
248+
else: Literal.string("default")
249+
)
250+
251+
let syntax = conditional.syntax
252+
let description = syntax.description
253+
254+
#expect(description.contains("optionalValue ? optionalValue : \"default\""))
255+
}
256+
257+
/// Tests conditional operator with type casting.
258+
@Test("Conditional operator with type casting generates correct syntax")
259+
internal func testConditionalOpWithTypeCasting() {
260+
let conditional = ConditionalOp(
261+
if: VariableExp("isString"),
262+
then: VariableExp("value as String"),
263+
else: VariableExp("value as Int")
264+
)
265+
266+
let syntax = conditional.syntax
267+
let description = syntax.description
268+
269+
#expect(description.contains("isString ? value as String : value as Int"))
270+
}
271+
272+
/// Tests conditional operator with closure expressions.
273+
@Test("Conditional operator with closure expressions generates correct syntax")
274+
internal func testConditionalOpWithClosureExpressions() {
275+
let conditional = ConditionalOp(
276+
if: VariableExp("useAsync"),
277+
then: Closure(body: { VariableExp("asyncResult") }),
278+
else: Closure(body: { VariableExp("syncResult") })
279+
)
280+
281+
let syntax = conditional.syntax
282+
let description = syntax.description.normalize()
283+
284+
#expect(description.contains("useAsync ? { asyncResult } : { syncResult }".normalize()))
285+
}
286+
287+
/// Tests conditional operator with complex nested structures.
288+
@Test("Conditional operator with complex nested structures generates correct syntax")
289+
internal func testConditionalOpWithComplexNestedStructures() {
290+
let conditional = ConditionalOp(
291+
if: Call("isAuthenticated"),
292+
then: Call("getUserData"),
293+
else: Call("getGuestData")
294+
)
295+
296+
let syntax = conditional.syntax
297+
let description = syntax.description
298+
299+
#expect(description.contains("isAuthenticated() ? getUserData() : getGuestData()"))
300+
}
301+
}

0 commit comments

Comments
 (0)