From 0a9440945cbfda25cfb1271e6094b9c3568bd35c Mon Sep 17 00:00:00 2001 From: Matt Polzin Date: Wed, 30 Aug 2023 09:14:07 -0500 Subject: [PATCH 1/3] fix bug with conversion of Server Variable enum from OAS 3.0 to 3.1 --- Sources/OpenAPIKitCompat/Compat30To31.swift | 11 +++++++++-- .../DocumentConversionTests.swift | 14 +++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Sources/OpenAPIKitCompat/Compat30To31.swift b/Sources/OpenAPIKitCompat/Compat30To31.swift index 0f2aa235e..b16b82c84 100644 --- a/Sources/OpenAPIKitCompat/Compat30To31.swift +++ b/Sources/OpenAPIKitCompat/Compat30To31.swift @@ -87,8 +87,15 @@ extension OpenAPIKit30.OpenAPI.Server: To31 { public func to31() -> OpenAPIKit.OpenAPI.Server { let newVariables = variables.mapValues { variable in - OpenAPIKit.OpenAPI.Server.Variable( - enum: variable.enum, + let enumValue: [String]? + if !variable.enum.isEmpty { + enumValue = variable.enum + } else { + enumValue = nil + } + + return OpenAPIKit.OpenAPI.Server.Variable( + enum: enumValue, default: variable.default, description: variable.description, vendorExtensions: variable.vendorExtensions diff --git a/Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift b/Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift index cff4a22a5..c908b9965 100644 --- a/Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift +++ b/Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift @@ -77,6 +77,13 @@ final class DocumentConversionTests: XCTestCase { description: "hi", variables: ["hello": .init(enum: ["1"], default: "1", description: "described", vendorExtensions: ["x-hi": "hello"])], vendorExtensions: ["x-test": 2] + ), + .init( + urlTemplate: try .init(templateString: "{protocol}://{hostname}/api/v3"), + variables: [ + "protocol": .init(default: "http", description: "protocol"), + "hostname": .init(default: "HOSTNAME", description: "host name") + ] ) ], paths: [:], @@ -479,10 +486,15 @@ fileprivate func assertEqualNewToOld(_ newServer: OpenAPIKit.OpenAPI.Server?, _ XCTAssertEqual(newServer.urlTemplate, oldServer.urlTemplate) XCTAssertEqual(newServer.description, oldServer.description) XCTAssertEqual(newServer.vendorExtensions, oldServer.vendorExtensions) + XCTAssertEqual(newServer.variables.count, oldServer.variables.count) for (key, newVariable) in newServer.variables { let oldVariable = oldServer.variables[key] XCTAssertEqual(newVariable.description, oldVariable?.description) - XCTAssertEqual(newVariable.`enum`, oldVariable?.`enum`) + if (oldVariable?.enum ?? []).isEmpty { + XCTAssertNil(newVariable.`enum`) + } else { + XCTAssertEqual(newVariable.`enum`, oldVariable?.`enum`) + } XCTAssertEqual(newVariable.`default`, oldVariable?.`default`) XCTAssertEqual(newVariable.vendorExtensions, oldVariable?.vendorExtensions) } From e9ced35c82c7d9256a09897dec06a99d672663f6 Mon Sep 17 00:00:00 2001 From: Matt Polzin Date: Wed, 30 Aug 2023 09:23:02 -0500 Subject: [PATCH 2/3] disambiguate a closure and add validations to document conversion tests --- Sources/OpenAPIKitCompat/Compat30To31.swift | 2 +- .../DocumentConversionTests.swift | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Sources/OpenAPIKitCompat/Compat30To31.swift b/Sources/OpenAPIKitCompat/Compat30To31.swift index b16b82c84..01cc8b4bb 100644 --- a/Sources/OpenAPIKitCompat/Compat30To31.swift +++ b/Sources/OpenAPIKitCompat/Compat30To31.swift @@ -86,7 +86,7 @@ extension OpenAPIKit30.OpenAPI.Server: To31 { /// to facilitate incremental migration within your codebase from OpenAPIKit30 to OpenAPIKit. public func to31() -> OpenAPIKit.OpenAPI.Server { - let newVariables = variables.mapValues { variable in + let newVariables: OrderedDictionary = variables.mapValues { variable in let enumValue: [String]? if !variable.enum.isEmpty { enumValue = variable.enum diff --git a/Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift b/Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift index c908b9965..f5401e17d 100644 --- a/Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift +++ b/Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift @@ -24,6 +24,8 @@ final class DocumentConversionTests: XCTestCase { try assertEqualNewToOld(newDoc, oldDoc) XCTAssertEqual(newDoc.openAPIVersion, .v3_1_0) + + try newDoc.validate() } func test_vendorExtensionsOnDoc() throws { @@ -39,6 +41,8 @@ final class DocumentConversionTests: XCTestCase { let newDoc = oldDoc.convert(to: .v3_1_0) try assertEqualNewToOld(newDoc, oldDoc) + + try newDoc.validate() } func test_fullInfo() throws { @@ -60,6 +64,8 @@ final class DocumentConversionTests: XCTestCase { let newDoc = oldDoc.convert(to: .v3_1_0) try assertEqualNewToOld(newDoc, oldDoc) + + try newDoc.validate() } func test_servers() throws { @@ -93,6 +99,8 @@ final class DocumentConversionTests: XCTestCase { let newDoc = oldDoc.convert(to: .v3_1_0) try assertEqualNewToOld(newDoc, oldDoc) + + try newDoc.validate() } func test_paths() throws { @@ -194,6 +202,8 @@ final class DocumentConversionTests: XCTestCase { let newDoc = oldDoc.convert(to: .v3_1_0) try assertEqualNewToOld(newDoc, oldDoc) + + try newDoc.validate() } func testJSONSchemas() throws { @@ -300,6 +310,8 @@ final class DocumentConversionTests: XCTestCase { let newDoc = oldDoc.convert(to: .v3_1_0) try assertEqualNewToOld(newDoc, oldDoc) + + try newDoc.validate() } func testSecurity() throws { @@ -330,6 +342,8 @@ final class DocumentConversionTests: XCTestCase { let newDoc2 = oldDoc2.convert(to: .v3_1_0) try assertEqualNewToOld(newDoc2, oldDoc2) + + try newDoc.validate() } func testTags() throws { @@ -371,6 +385,8 @@ final class DocumentConversionTests: XCTestCase { let newDoc3 = oldDoc3.convert(to: .v3_1_0) try assertEqualNewToOld(newDoc3, oldDoc3) + + try newDoc.validate() } func testExternalDocs() throws { @@ -405,6 +421,8 @@ final class DocumentConversionTests: XCTestCase { let newDoc = oldDoc.convert(to: .v3_1_0) try assertEqualNewToOld(newDoc, oldDoc) + + try newDoc.validate() } // TODO: more tests From ee075c2d6789922116dba127c656a4dc0d5328ad Mon Sep 17 00:00:00 2001 From: Matt Polzin Date: Wed, 30 Aug 2023 09:40:05 -0500 Subject: [PATCH 3/3] fix tests to pass new validation checks --- .../DocumentConversionTests.swift | 61 +++++++++++-------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift b/Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift index f5401e17d..464e82a86 100644 --- a/Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift +++ b/Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift @@ -147,23 +147,25 @@ final class DocumentConversionTests: XCTestCase { .component(named: "security"): ["hello"] ] - let operation = OpenAPIKit30.OpenAPI.Operation( - tags: ["hello"], - summary: "sum", - description: "described", - externalDocs: externalDocs, - operationId: "ident", - parameters: params, - requestBody: .request(request), - responses: [200: .b(response)], - callbacks: [ - "callback": .b(callbacks), - "other_callback": .a(.component(named: "other_callback"))], - deprecated: true, - security: [securityRequirement], - servers: [server], - vendorExtensions: ["x-hello": 101] - ) + let operation = (0...7).map { idx in + OpenAPIKit30.OpenAPI.Operation( + tags: ["hello"], + summary: "sum", + description: "described", + externalDocs: externalDocs, + operationId: "ident\(idx)", + parameters: params, + requestBody: .request(request), + responses: [200: .b(response)], + callbacks: [ + "callback": .b(callbacks), + "other_callback": .a(.component(named: "other_callback"))], + deprecated: true, + security: [securityRequirement], + servers: [server], + vendorExtensions: ["x-hello": 101] + ) + } let oldDoc = OpenAPIKit30.OpenAPI.Document( info: .init(title: "Hello", version: "1.0.0"), @@ -185,18 +187,22 @@ final class DocumentConversionTests: XCTestCase { .a(.internal(.component(name: "test"))), .parameter(.init(name: "test", context: .query, schema: .string)) ], - get: operation, - put: operation, - post: operation, - delete: operation, - options: operation, - head: operation, - patch: operation, - trace: operation, + get: operation[0], + put: operation[1], + post: operation[2], + delete: operation[3], + options: operation[4], + head: operation[5], + patch: operation[6], + trace: operation[7], vendorExtensions: ["x-test": 123] ) ], - components: .noComponents + components: .init( + parameters: [ + "test": .init(name: "referencedParam", context: .query, schema: .string) + ] + ) ) let newDoc = oldDoc.convert(to: .v3_1_0) @@ -244,7 +250,8 @@ final class DocumentConversionTests: XCTestCase { let components = OpenAPIKit30.OpenAPI.Components( schemas: [ - "schema1": .string + "schema1": .string, + "test3_param": .integer(format: .int32, required: false) ], responses: [ "response1": response