From 53728f560c08ec52948e51b642cf971379bb2774 Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Wed, 19 Jul 2023 17:51:34 -0500 Subject: [PATCH 1/2] Adding test coverage to zero in one the problem --- .../Schema Object/JSONSchemaTests.swift | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/Tests/OpenAPIKitTests/Schema Object/JSONSchemaTests.swift b/Tests/OpenAPIKitTests/Schema Object/JSONSchemaTests.swift index 8c8bcc325..3ace6e69d 100644 --- a/Tests/OpenAPIKitTests/Schema Object/JSONSchemaTests.swift +++ b/Tests/OpenAPIKitTests/Schema Object/JSONSchemaTests.swift @@ -4597,6 +4597,12 @@ extension SchemaObjectTests { .reference(.component(named: "test")) ] ) + let allOfWithReferenceAndDescription = JSONSchema.all( + of: [ + .fragment(description: "hello"), + .reference(.component(named: "test")) + ] + ) testEncodingPropertyLines(entity: allOf, propertyLines: [ "\"allOf\" : [", @@ -4660,6 +4666,17 @@ extension SchemaObjectTests { " }", "]" ]) + + testEncodingPropertyLines(entity: allOfWithReferenceAndDescription, propertyLines: [ + "\"allOf\" : [", + " {", + " \"description\" : \"hello\"", + " },", + " {", + " \"$ref\" : \"#\\/components\\/schemas\\/test\"", + " }", + "]" + ]) } func test_decodeAll() throws { @@ -4701,10 +4718,35 @@ extension SchemaObjectTests { } """.data(using: .utf8)! + let allWithReferenceAndDescriptionData = """ + { + "allOf": [ + { "description": "hello" }, + { "$ref": "#/components/schemas/test" } + ] + } + """.data(using: .utf8)! + + let nestedOptionalAllData = """ + { + "type": "object", + "properties": { + "prop1": { + "allOf": [ + { "description": "hello" }, + { "$ref": "#/components/schemas/test" } + ] + } + } + } + """.data(using: .utf8)! + let all = try orderUnstableDecode(JSONSchema.self, from: allData) let allWithTitle = try orderUnstableDecode(JSONSchema.self, from: allWithTitleData) let allWithDiscriminator = try orderUnstableDecode(JSONSchema.self, from: allWithDiscriminatorData) let allWithReference = try orderUnstableDecode(JSONSchema.self, from: allWithReferenceData) + let allWithReferenceAndDescription = try orderUnstableDecode(JSONSchema.self, from: allWithReferenceAndDescriptionData) + let nestedOptionalAll = try orderUnstableDecode(JSONSchema.self, from: nestedOptionalAllData) XCTAssertEqual( all, @@ -4747,6 +4789,29 @@ extension SchemaObjectTests { ] ) ) + + XCTAssertEqual( + allWithReferenceAndDescription, + JSONSchema.all( + of: [ + .fragment(description: "hello"), + .reference(.component(named: "test")) + ] + ) + ) + + XCTAssertEqual( + nestedOptionalAll, + JSONSchema.object( + properties: [ + "prop1": JSONSchema.all( + of: .fragment(description: "hello"), + .reference(.component(named: "test")), + required: false + ) + ] + ) + ) } func test_encodeOne() { From 1a379dd7d95bf80bf7519701b6988ade603d7ffe Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Wed, 19 Jul 2023 18:22:46 -0500 Subject: [PATCH 2/2] Make allOf required status propagate to its fragments since in any object context the fragments are all part of the same whole. --- .../OpenAPIKit/Schema Object/JSONSchema.swift | 4 +-- .../Schema Object/JSONSchemaTests.swift | 28 ++++++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Sources/OpenAPIKit/Schema Object/JSONSchema.swift b/Sources/OpenAPIKit/Schema Object/JSONSchema.swift index f782d995c..6fa2c7f42 100644 --- a/Sources/OpenAPIKit/Schema Object/JSONSchema.swift +++ b/Sources/OpenAPIKit/Schema Object/JSONSchema.swift @@ -365,7 +365,7 @@ extension JSONSchema { case .fragment(let context): return .fragment(context.optionalContext()) case .all(of: let fragments, core: let core): - return .all(of: fragments, core: core.optionalContext()) + return .all(of: fragments.map { $0.optionalSchemaObject() }, core: core.optionalContext()) case .one(of: let schemas, core: let core): return .one(of: schemas, core: core.optionalContext()) case .any(of: let schemas, core: let core): @@ -395,7 +395,7 @@ extension JSONSchema { case .fragment(let context): return .fragment(context.requiredContext()) case .all(of: let fragments, core: let core): - return .all(of: fragments, core: core.requiredContext()) + return .all(of: fragments.map { $0.requiredSchemaObject() }, core: core.requiredContext()) case .one(of: let schemas, core: let core): return .one(of: schemas, core: core.requiredContext()) case .any(of: let schemas, core: let core): diff --git a/Tests/OpenAPIKitTests/Schema Object/JSONSchemaTests.swift b/Tests/OpenAPIKitTests/Schema Object/JSONSchemaTests.swift index 3ace6e69d..07e088dab 100644 --- a/Tests/OpenAPIKitTests/Schema Object/JSONSchemaTests.swift +++ b/Tests/OpenAPIKitTests/Schema Object/JSONSchemaTests.swift @@ -911,6 +911,16 @@ final class SchemaObjectTests: XCTestCase { XCTAssertFalse(not.required) XCTAssertFalse(fragment.required) + // all fragments within required get flipped too: + switch(allOf) { + case .all(of: let schemas, core: _): + for schema in schemas { + XCTAssertFalse(schema.required) + } + default: + break + } + XCTAssertTrue(reference.required) } @@ -951,6 +961,16 @@ final class SchemaObjectTests: XCTestCase { XCTAssertTrue(not.required) XCTAssertTrue(reference.required) XCTAssertTrue(fragment.required) + + // all fragments within required get flipped too: + switch(allOf) { + case .all(of: let schemas, core: _): + for schema in schemas { + XCTAssertTrue(schema.required) + } + default: + break + } } func test_notNullableToNullable() { @@ -4805,10 +4825,10 @@ extension SchemaObjectTests { JSONSchema.object( properties: [ "prop1": JSONSchema.all( - of: .fragment(description: "hello"), - .reference(.component(named: "test")), - required: false - ) + of: .fragment(required: false, description: "hello"), + .reference(.component(named: "test")), + required: false + ) ] ) )