Skip to content

Commit 722c1ab

Browse files
authored
Fix range responses (#198)
Fix range responses ### Motivation Fixes #197, broken range responses, such as `4xx`. ### Modifications Fix the bug, seems to have been some old copy paste gone wrong, and we didn't have a test for it. ### Result Now range responses work again. ### Test Plan Changed one of the status code responses to be a range response, updated fixtures. Reviewed by: glbrntt Builds: ✔︎ pull request validation (5.8) - Build finished. ✔︎ pull request validation (5.9) - Build finished. ✔︎ pull request validation (docc test) - Build finished. ✔︎ pull request validation (integration test) - Build finished. ✔︎ pull request validation (nightly) - Build finished. ✔︎ pull request validation (soundness) - Build finished. #198
1 parent e4b4624 commit 722c1ab

File tree

10 files changed

+41
-44
lines changed

10 files changed

+41
-44
lines changed

Sources/_OpenAPIGeneratorCore/Translator/Responses/translateResponseOutcome.swift

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -454,35 +454,24 @@ extension ServerFileTranslator {
454454
codeBlocks.append(.expression(returnExpr))
455455

456456
let caseKind: SwitchCaseKind
457-
switch responseKind {
458-
case .code, .`default`:
459-
let optionalStatusCode: [String]
460-
if responseKind.wantsStatusCode {
461-
optionalStatusCode = ["statusCode"]
462-
} else {
463-
optionalStatusCode = []
464-
}
465-
caseKind = .`case`(
466-
.dot(responseKind.identifier),
467-
optionalStatusCode + ["value"]
468-
)
469-
codeBlocks =
470-
[
471-
.expression(
472-
.suppressUnusedWarning(
473-
for: "value"
474-
)
457+
let optionalStatusCode: [String]
458+
if responseKind.wantsStatusCode {
459+
optionalStatusCode = ["statusCode"]
460+
} else {
461+
optionalStatusCode = []
462+
}
463+
caseKind = .`case`(
464+
.dot(responseKind.identifier),
465+
optionalStatusCode + ["value"]
466+
)
467+
codeBlocks =
468+
[
469+
.expression(
470+
.suppressUnusedWarning(
471+
for: "value"
475472
)
476-
] + codeBlocks
477-
case let .range(range):
478-
caseKind = .`case`(
479-
.binaryOperation(
480-
left: .literal(range.lowerBound),
481-
operation: .rangeInclusive,
482-
right: .literal(range.upperBound)
483473
)
484-
)
485-
}
474+
] + codeBlocks
486475

487476
return .init(
488477
kind: caseKind,

Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ paths:
111111
application/json:
112112
schema:
113113
$ref: '#/components/schemas/Pet'
114-
'400':
114+
'4XX':
115115
$ref: '#/components/responses/ErrorBadRequest'
116116
/pets/stats:
117117
get:

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public struct Client: APIProtocol {
215215
throw converter.makeUnexpectedContentTypeError(contentType: contentType)
216216
}
217217
return .created(.init(headers: headers, body: body))
218-
case 400:
218+
case 400...499:
219219
let headers: Components.Responses.ErrorBadRequest.Headers = .init(
220220
X_Reason: try converter.getOptionalHeaderFieldAsText(
221221
in: response.headerFields,
@@ -241,7 +241,10 @@ public struct Client: APIProtocol {
241241
} else {
242242
throw converter.makeUnexpectedContentTypeError(contentType: contentType)
243243
}
244-
return .badRequest(.init(headers: headers, body: body))
244+
return .clientError(
245+
statusCode: response.statusCode,
246+
.init(headers: headers, body: body)
247+
)
245248
default: return .undocumented(statusCode: response.statusCode, .init())
246249
}
247250
}

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,9 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol {
248248
)
249249
}
250250
return response
251-
case let .badRequest(value):
251+
case let .clientError(statusCode, value):
252252
suppressUnusedWarning(value)
253-
var response = Response(statusCode: 400)
253+
var response = Response(statusCode: statusCode)
254254
suppressMutabilityWarning(&response)
255255
try converter.setHeaderFieldAsText(
256256
in: &response.headerFields,

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,10 +1040,10 @@ public enum Operations {
10401040
case created(Operations.createPet.Output.Created)
10411041
/// Bad request
10421042
///
1043-
/// - Remark: Generated from `#/paths//pets/post(createPet)/responses/400`.
1043+
/// - Remark: Generated from `#/paths//pets/post(createPet)/responses/4XX`.
10441044
///
1045-
/// HTTP response code: `400 badRequest`.
1046-
case badRequest(Components.Responses.ErrorBadRequest)
1045+
/// HTTP response code: `400...499 clientError`.
1046+
case clientError(statusCode: Int, Components.Responses.ErrorBadRequest)
10471047
/// Undocumented response.
10481048
///
10491049
/// A response with a code that is not documented in the OpenAPI document.

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes/Client.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public struct Client: APIProtocol {
215215
throw converter.makeUnexpectedContentTypeError(contentType: contentType)
216216
}
217217
return .created(.init(headers: headers, body: body))
218-
case 400:
218+
case 400...499:
219219
let headers: Components.Responses.ErrorBadRequest.Headers = .init(
220220
X_hyphen_Reason: try converter.getOptionalHeaderFieldAsText(
221221
in: response.headerFields,
@@ -241,7 +241,10 @@ public struct Client: APIProtocol {
241241
} else {
242242
throw converter.makeUnexpectedContentTypeError(contentType: contentType)
243243
}
244-
return .badRequest(.init(headers: headers, body: body))
244+
return .clientError(
245+
statusCode: response.statusCode,
246+
.init(headers: headers, body: body)
247+
)
245248
default: return .undocumented(statusCode: response.statusCode, .init())
246249
}
247250
}

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes/Server.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,9 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol {
248248
)
249249
}
250250
return response
251-
case let .badRequest(value):
251+
case let .clientError(statusCode, value):
252252
suppressUnusedWarning(value)
253-
var response = Response(statusCode: 400)
253+
var response = Response(statusCode: statusCode)
254254
suppressMutabilityWarning(&response)
255255
try converter.setHeaderFieldAsText(
256256
in: &response.headerFields,

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes/Types.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,10 +1042,10 @@ public enum Operations {
10421042
case created(Operations.createPet.Output.Created)
10431043
/// Bad request
10441044
///
1045-
/// - Remark: Generated from `#/paths//pets/post(createPet)/responses/400`.
1045+
/// - Remark: Generated from `#/paths//pets/post(createPet)/responses/4XX`.
10461046
///
1047-
/// HTTP response code: `400 badRequest`.
1048-
case badRequest(Components.Responses.ErrorBadRequest)
1047+
/// HTTP response code: `400...499 clientError`.
1048+
case clientError(statusCode: Int, Components.Responses.ErrorBadRequest)
10491049
/// Undocumented response.
10501050
///
10511051
/// A response with a code that is not documented in the OpenAPI document.

Tests/PetstoreConsumerTests/Test_Client.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,11 @@ final class Test_Client: XCTestCase {
217217
let response = try await client.createPet(
218218
.init(body: .json(.init(name: "Fluffz")))
219219
)
220-
guard case let .badRequest(value) = response else {
220+
guard case let .clientError(statusCode, value) = response else {
221221
XCTFail("Unexpected response: \(response)")
222222
return
223223
}
224+
XCTAssertEqual(statusCode, 400)
224225
XCTAssertEqual(value.headers.X_Reason, "bad luck")
225226
switch value.body {
226227
case .json(let body):

Tests/PetstoreConsumerTests/Test_Server.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ final class Test_Server: XCTestCase {
186186
func testCreatePet_400() async throws {
187187
client = .init(
188188
createPetBlock: { input in
189-
.badRequest(
189+
.clientError(
190+
statusCode: 400,
190191
.init(
191192
headers: .init(
192193
X_Reason: "bad luck"

0 commit comments

Comments
 (0)