Skip to content

Commit eba8793

Browse files
committed
Added integer literal expressibility for Response Status Codes and covered Response and Response Status Code with unit tests.
1 parent d557a52 commit eba8793

File tree

5 files changed

+224
-5
lines changed

5 files changed

+224
-5
lines changed

Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/OpenAPIKit/OpenAPI.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ extension OpenAPI {
3434
return "When parsing Open API JSON, an expected keyword was missing. Carefully read your JSON keys to make sure all keys required by OpenAPI are spelled correctly. Underlying error: "
3535
+ (err ?? "") + ". PATH: \(path)"
3636
case .foundNeither(option1: let option1, option2: let option2, codingPath: let path, notOption1Because: let reason1, notOption2Because: let reason2):
37-
return "Found neither of two expected things. Expected either \(option1) or \(option2). \n\nPATH: \(path).\n\n Could not have been \(option1) because: \(reason1).\n\n Could not have been \(option2) because: \(reason2)"
37+
return "Found neither of two expected things. Expected either \(option1) or \(option2). \n\nPATH: \(path).\n\n Could not have been \(option1) because: \(String(describing:reason1)).\n\n Could not have been \(option2) because: \(String(describing:reason2))"
3838
case .unsatisfied(requirement: let requirement, codingPath: let path):
3939
return "Unsatisfied OpenAPI requirement: \(requirement). PATH: \(path)"
4040
case .unknown(codingPath: let path):

Sources/OpenAPIKit/Response.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ extension OpenAPI {
2323
}
2424
}
2525

26+
extension OpenAPI.Response {
27+
public typealias Map = [StatusCode: Either<OpenAPI.Response, JSONReference<OpenAPI.Components, OpenAPI.Response>>]
28+
}
29+
30+
// MARK: - Status Code
2631
extension OpenAPI.Response {
2732
public enum StatusCode: RawRepresentable, Equatable, Hashable {
2833
public typealias RawValue = String
@@ -43,13 +48,22 @@ extension OpenAPI.Response {
4348
public init?(rawValue: String) {
4449
if let val = Int(rawValue) {
4550
self = .status(code: val)
46-
} else {
51+
52+
} else if rawValue == OpenAPI.Response.StatusCode.default.rawValue {
4753
self = .default
54+
55+
} else {
56+
return nil
4857
}
4958
}
5059
}
60+
}
5161

52-
public typealias Map = [StatusCode: Either<OpenAPI.Response, JSONReference<OpenAPI.Components, OpenAPI.Response>>]
62+
extension OpenAPI.Response.StatusCode: ExpressibleByIntegerLiteral {
63+
64+
public init(integerLiteral value: Int) {
65+
self = .status(code: value)
66+
}
5367
}
5468

5569
// MARK: - Codable

Tests/OpenAPIKitTests/ResponseTests.swift

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,191 @@ import XCTest
1010
import OpenAPIKit
1111

1212
final class ResponseTests: XCTestCase {
13+
func test_Initialization() {
14+
let r1 = OpenAPI.Response(description: "hello world",
15+
content: [:])
16+
XCTAssertEqual(r1.description, "hello world")
1317

18+
let content = OpenAPI.Content(schema: .init(JSONReference<OpenAPI.Components, JSONSchema>.file("hello.yml")))
19+
let r2 = OpenAPI.Response(description: "",
20+
content: [.json: content])
21+
XCTAssertEqual(r2.description, "")
22+
XCTAssertEqual(r2.content, [.json: content])
23+
}
1424
}
1525

1626
// MARK: Response Status Code
1727
extension ResponseTests {
28+
func test_defaultFromString() {
29+
typealias StatusCode = OpenAPI.Response.StatusCode
30+
XCTAssertEqual(StatusCode(rawValue: "default"), .default)
31+
XCTAssertEqual(StatusCode(rawValue: "default")?.rawValue, "default")
32+
}
1833

34+
func test_codeFromString() {
35+
typealias StatusCode = OpenAPI.Response.StatusCode
36+
XCTAssertEqual(StatusCode(rawValue: "123"), .status(code: 123))
37+
XCTAssertEqual(StatusCode(rawValue: "123")?.rawValue, "123")
38+
XCTAssertEqual(StatusCode(rawValue: "404"), .status(code: 404))
39+
XCTAssertEqual(StatusCode(rawValue: "404")?.rawValue, "404")
40+
XCTAssertEqual(StatusCode(rawValue: "500"), .status(code: 500))
41+
XCTAssertEqual(StatusCode(rawValue: "500")?.rawValue, "500")
42+
}
43+
44+
func test_NilForNonIntegerString() {
45+
typealias StatusCode = OpenAPI.Response.StatusCode
46+
XCTAssertNil(StatusCode(rawValue: "hello"))
47+
}
48+
49+
func test_codeFromIntegerLiteral() {
50+
typealias StatusCode = OpenAPI.Response.StatusCode
51+
XCTAssertEqual(123, StatusCode.status(code: 123))
52+
XCTAssertEqual(404, StatusCode.status(code: 404))
53+
XCTAssertEqual(500, StatusCode.status(code: 500))
54+
}
1955
}
2056

2157
// MARK: - Codable
58+
@available(OSX 10.13, *)
2259
extension ResponseTests {
60+
func test_emptyDescriptionEmptyContent_encode() {
61+
let response = OpenAPI.Response(description: "", content: [:])
62+
let encodedResponse = try! testStringFromEncoding(of: response)
63+
64+
XCTAssertEqual(encodedResponse,
65+
"""
66+
{
67+
"description" : ""
68+
}
69+
"""
70+
)
71+
}
72+
73+
func test_emptyDescriptionEmptyContent_decode() {
74+
let responseData =
75+
"""
76+
{
77+
"description" : ""
78+
}
79+
""".data(using: .utf8)!
80+
let response = try! testDecoder.decode(OpenAPI.Response.self, from: responseData)
81+
82+
XCTAssertEqual(response, OpenAPI.Response(description: "", content: [:]))
83+
84+
let responseData2 =
85+
"""
86+
{
87+
"content": {},
88+
"description" : ""
89+
}
90+
""".data(using: .utf8)!
91+
let response2 = try! testDecoder.decode(OpenAPI.Response.self, from: responseData2)
92+
93+
XCTAssertEqual(response2, OpenAPI.Response(description: "", content: [:]))
94+
}
95+
96+
func test_populatedDescriptionPopulatedContent_encode() {
97+
let content = OpenAPI.Content(schema: .init(.string))
98+
let response = OpenAPI.Response(description: "hello world", content: [.json: content])
99+
100+
let encodedResponse = try! testStringFromEncoding(of: response)
101+
102+
XCTAssertEqual(encodedResponse,
103+
"""
104+
{
105+
"content" : {
106+
"application\\/json" : {
107+
"schema" : {
108+
"type" : "string"
109+
}
110+
}
111+
},
112+
"description" : "hello world"
113+
}
114+
"""
115+
)
116+
}
117+
118+
func test_populatedDescriptionPopulatedContent_decode() {
119+
let responseData =
120+
"""
121+
{
122+
"description": "hello world",
123+
"content": { "application/json": { "schema": { "type": "string" } } }
124+
}
125+
""".data(using: .utf8)!
23126

127+
let response = try! testDecoder.decode(OpenAPI.Response.self, from: responseData)
128+
129+
let content = OpenAPI.Content(schema: .init(.string(required: false)))
130+
XCTAssertEqual(response, OpenAPI.Response(description: "hello world", content: [.json: content]))
131+
}
24132
}
25133

26134
// MARK: Response Status Code
135+
@available(OSX 10.13, *)
27136
extension ResponseTests {
28137

138+
struct StatusCodeWrapper: Codable, Equatable {
139+
let status: OpenAPI.Response.StatusCode
140+
}
141+
142+
func test_defaultStatusCode_encode() {
143+
let status = StatusCodeWrapper(status: .default)
144+
let encodedStatus = try! testStringFromEncoding(of: status)
145+
146+
XCTAssertEqual(encodedStatus,
147+
"""
148+
{
149+
"status" : "default"
150+
}
151+
"""
152+
)
153+
}
154+
155+
func test_defaultStatusCode_decode() {
156+
let statusCodeData =
157+
"""
158+
{
159+
"status": "default"
160+
}
161+
""".data(using: .utf8)!
162+
163+
XCTAssertEqual(try! testDecoder.decode(StatusCodeWrapper.self, from: statusCodeData), StatusCodeWrapper(status: .default))
164+
}
165+
166+
func test_numberStatusCode_encode() {
167+
let status = StatusCodeWrapper(status: 123)
168+
let encodedStatus = try! testStringFromEncoding(of: status)
169+
170+
XCTAssertEqual(encodedStatus,
171+
"""
172+
{
173+
"status" : "123"
174+
}
175+
"""
176+
)
177+
}
178+
179+
func test_numberStatusCode_decode() {
180+
let statusCodeData =
181+
"""
182+
{
183+
"status": "123"
184+
}
185+
""".data(using: .utf8)!
186+
187+
XCTAssertEqual(try! testDecoder.decode(StatusCodeWrapper.self, from: statusCodeData), StatusCodeWrapper(status: 123))
188+
}
189+
190+
func test_nonesenseStatusCode_decode_throws() {
191+
let statusCodeData =
192+
"""
193+
{
194+
"status": "hello world"
195+
}
196+
""".data(using: .utf8)!
197+
198+
XCTAssertThrowsError(try testDecoder.decode(StatusCodeWrapper.self, from: statusCodeData))
199+
}
29200
}

Tests/OpenAPIKitTests/XCTestManifests.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
#if !canImport(ObjectiveC)
22
import XCTest
33

4+
extension AnyJSONCaseIterableTests {
5+
// DO NOT MODIFY: This is autogenerated, use:
6+
// `swift test --generate-linuxmain`
7+
// to regenerate.
8+
static let __allTests__AnyJSONCaseIterableTests = [
9+
("test_CodableToAllCases", test_CodableToAllCases),
10+
("testAnyCodableToAllCases", testAnyCodableToAllCases),
11+
]
12+
}
13+
414
extension ContentTests {
515
// DO NOT MODIFY: This is autogenerated, use:
616
// `swift test --generate-linuxmain`
@@ -38,6 +48,28 @@ extension RequestTests {
3848
]
3949
}
4050

51+
extension ResponseTests {
52+
// DO NOT MODIFY: This is autogenerated, use:
53+
// `swift test --generate-linuxmain`
54+
// to regenerate.
55+
static let __allTests__ResponseTests = [
56+
("test_codeFromIntegerLiteral", test_codeFromIntegerLiteral),
57+
("test_codeFromString", test_codeFromString),
58+
("test_defaultFromString", test_defaultFromString),
59+
("test_defaultStatusCode_decode", test_defaultStatusCode_decode),
60+
("test_defaultStatusCode_encode", test_defaultStatusCode_encode),
61+
("test_emptyDescriptionEmptyContent_decode", test_emptyDescriptionEmptyContent_decode),
62+
("test_emptyDescriptionEmptyContent_encode", test_emptyDescriptionEmptyContent_encode),
63+
("test_Initialization", test_Initialization),
64+
("test_NilForNonIntegerString", test_NilForNonIntegerString),
65+
("test_nonesenseStatusCode_decode_throws", test_nonesenseStatusCode_decode_throws),
66+
("test_numberStatusCode_decode", test_numberStatusCode_decode),
67+
("test_numberStatusCode_encode", test_numberStatusCode_encode),
68+
("test_populatedDescriptionPopulatedContent_decode", test_populatedDescriptionPopulatedContent_decode),
69+
("test_populatedDescriptionPopulatedContent_encode", test_populatedDescriptionPopulatedContent_encode),
70+
]
71+
}
72+
4173
extension SchemaObjectTests {
4274
// DO NOT MODIFY: This is autogenerated, use:
4375
// `swift test --generate-linuxmain`
@@ -164,8 +196,10 @@ extension SchemaObjectTests {
164196

165197
public func __allTests() -> [XCTestCaseEntry] {
166198
return [
199+
testCase(AnyJSONCaseIterableTests.__allTests__AnyJSONCaseIterableTests),
167200
testCase(ContentTests.__allTests__ContentTests),
168201
testCase(RequestTests.__allTests__RequestTests),
202+
testCase(ResponseTests.__allTests__ResponseTests),
169203
testCase(SchemaObjectTests.__allTests__SchemaObjectTests),
170204
]
171205
}

0 commit comments

Comments
 (0)