Skip to content

Commit 1983d5b

Browse files
authored
Merge pull request #15 from mattpolzin/catch-undefined-parameters
catch undefined path parameters before they cause a swift compilation…
2 parents 67a735e + 480d9ca commit 1983d5b

File tree

2 files changed

+58
-4
lines changed

2 files changed

+58
-4
lines changed

Sources/JSONAPISwiftGen/Swift Generators/Test Generators/APIRequestTestSwiftGen.swift

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ public struct APIRequestTestSwiftGen: SwiftGenerator {
3535
.filter { !$0.context.inQuery } // for now these are handled as a block rather than each as separate args
3636
.map(APIRequestTestSwiftGen.argument)
3737

38+
let undefinedPaarameterArgNames = Array(
39+
pathComponents.components
40+
.compactMap(Self.urlParameterSwiftName)
41+
.filter { !parameterArgs.lazy.map(\.name).contains($0) }
42+
)
43+
44+
if !undefinedPaarameterArgNames.isEmpty {
45+
throw Error.pathParametersNotDefined(names: undefinedPaarameterArgNames)
46+
}
47+
3848
let requestBodyTypeDef = SwiftTypeDef(name: "RequestBody", specializationReps: [])
3949
let responseBodyTypeDef = SwiftTypeDef(name: "ResponseBody", specializationReps: [])
4050

@@ -169,12 +179,11 @@ public struct APIRequestTestSwiftGen: SwiftGenerator {
169179
originatingAt hostUrl: URL
170180
) -> Decl {
171181
let pathString = path.components.map { component in
172-
guard component.first == "{",
173-
component.last == "}" else {
174-
return component
182+
guard let swiftName = urlParameterSwiftName(component) else {
183+
return component
175184
}
176185
return "\\("
177-
+ propertyCased(String(component.dropFirst().dropLast()))
186+
+ swiftName
178187
+ ")"
179188
}.joined(separator: "/")
180189

@@ -185,6 +194,18 @@ public struct APIRequestTestSwiftGen: SwiftGenerator {
185194
)
186195
}
187196

197+
/// Get a property-cased name if the given string is an OpenAPI path parameter variable
198+
/// (which means it is enclosed in brackets `{ }`). Otherwise, returns `nil`.
199+
static func urlParameterSwiftName(
200+
_ pathComponent: String
201+
) -> String? {
202+
guard pathComponent.first == "{",
203+
pathComponent.last == "}" else {
204+
return nil
205+
}
206+
return propertyCased(String(pathComponent.dropFirst().dropLast()))
207+
}
208+
188209
private static func parameterSnippet(from parameter: DereferencedParameter) throws -> Decl {
189210
let (parameterName, parameterType) = try argument(for: parameter)
190211

@@ -226,6 +247,8 @@ public struct APIRequestTestSwiftGen: SwiftGenerator {
226247
case parameterContentMapNotSupported
227248
case unsupportedParameterSchema
228249

250+
case pathParametersNotDefined(names: [String])
251+
229252
case duplicateFunctionArgumentDetected
230253
}
231254
}

Tests/JSONAPISwiftGenTests/APIRequestTestSwiftGenTests.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,44 @@
88
import XCTest
99
import JSONAPI
1010
import JSONAPITesting
11+
import OpenAPIKit
12+
import JSONAPISwiftGen
1113

1214
import Foundation
1315
#if canImport(FoundationNetworking)
1416
import FoundationNetworking
1517
#endif
1618

1719
final class APIRequestTestSwiftGenTests: XCTestCase {
20+
func test_undefinedPathParameters() {
21+
XCTAssertThrowsError(
22+
try APIRequestTestSwiftGen(
23+
method: .post,
24+
server: OpenAPI.Server(url: URL(string: "http://website.com")!),
25+
pathComponents: "/widgets/{widget_id}",
26+
parameters: []
27+
)
28+
)
29+
}
30+
31+
func test_noUndefinedPathParameters() throws {
32+
// just prove this does not throw for now.
33+
34+
// TODO: test could actually test for the given parameter
35+
// being part of the resulting function signature or even more.
36+
_ = try APIRequestTestSwiftGen(
37+
method: .post,
38+
server: OpenAPI.Server(url: URL(string: "http://website.com")!),
39+
pathComponents: "/widgets/{widget_id}",
40+
parameters: [
41+
OpenAPI.Parameter(
42+
name: "widget_id",
43+
context: .path,
44+
schema: .string
45+
).dereferenced(in: .noComponents)
46+
]
47+
)
48+
}
1849
}
1950

2051
// MARK: - START - Function written to generated test suites

0 commit comments

Comments
 (0)