Skip to content

Commit

Permalink
Update URIValueFromNodeDecoder for DeepObject.
Browse files Browse the repository at this point in the history
### Motivation

As discussed in [[Generator] Add support of deepObject style in query params #538](apple/swift-openapi-generator#538 (comment)), there is a misimplementation of the `decodeRootIfPresent` method in `URIValueFromNodeDecoder`. When using the `deepObject` style, the node for `rootValue` is correctly empty, containing only the sub-objects.

Without this PR, the tests for [Add support of deepObject style in query params #538](apple/swift-openapi-generator#538) are failing.

### Modifications

- Updated the `decodeRootIfPresent(_ type:) throws -> T` method to ignore whether `currentElementAsArray` is empty or not.

### Result

- Enables the tests in the [Generator part of the PR](apple/swift-openapi-generator#538) to pass successfully.

### Test Plan

This PR includes unit tests that validate the change to `decodeRootIfPresent(_ type:) throws -> T` within `Test_Converter+Server` as well as in `Test_serverConversionExtensions`.
  • Loading branch information
kstefanou52 committed Oct 29, 2024
1 parent daa2fb5 commit b35daeb
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ final class URIValueFromNodeDecoder {
/// - Throws: When a decoding error occurs.
func decodeRootIfPresent<T: Decodable>(_ type: T.Type = T.self) throws -> T? {
// The root is only nil if the node is empty.
if try currentElementAsArray().isEmpty { return nil }
if style != .deepObject, try currentElementAsArray().isEmpty {
return nil
}
return try decodeRoot(type)
}
}
Expand Down
24 changes: 24 additions & 0 deletions Tests/OpenAPIRuntimeTests/Conversion/Test_Converter+Server.swift
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,18 @@ final class Test_ServerConverterExtensions: Test_Runtime {
XCTAssertEqual(value, ["foo", "bar"])
}

func test_getOptionalQueryItemAsURI_deepObject_exploded() throws {
let query: Substring = "sort%5Bid%5D=ascending&sort%5Bname%5D=descending"
let value: [String: String]? = try converter.getOptionalQueryItemAsURI(
in: query,
style: .deepObject,
explode: true,
name: "sort",
as: [String: String].self
)
XCTAssertEqual(value, ["id": "ascending", "name": "descending"])
}

func test_getRequiredQueryItemAsURI_arrayOfStrings() throws {
let query: Substring = "search=foo&search=bar"
let value: [String] = try converter.getRequiredQueryItemAsURI(
Expand All @@ -195,6 +207,18 @@ final class Test_ServerConverterExtensions: Test_Runtime {
XCTAssertEqual(value, ["foo", "bar"])
}

func test_getRequiredQueryItemAsURI_deepObject_exploded() throws {
let query: Substring = "sort%5Bid%5D=ascending&sort%5Bname%5D=descending"
let value: [String: String] = try converter.getRequiredQueryItemAsURI(
in: query,
style: .deepObject,
explode: true,
name: "sort",
as: [String: String].self
)
XCTAssertEqual(value, ["id": "ascending", "name": "descending"])
}

func test_getOptionalQueryItemAsURI_date() throws {
let query: Substring = "search=\(testDateEscapedString)"
let value: Date? = try converter.getOptionalQueryItemAsURI(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ final class Test_URIValueFromNodeDecoder: Test_Runtime {
case blue
}

struct SimpleDeepObject: Decodable, Equatable {
let id: String
let name: String
}

// An empty string.
try test(["root": [""]], "", key: "root")

Expand Down Expand Up @@ -88,6 +93,14 @@ final class Test_URIValueFromNodeDecoder: Test_Runtime {
key: "root"
)

try test(
["id": ["ascending"], "name": ["descending"]],
SimpleDeepObject(id: "ascending", name: "descending"),
key: "sort",
style: .deepObject,
explode: true
)

func test<T: Decodable & Equatable>(
_ node: URIParsedNode,
_ expectedValue: T,
Expand Down

0 comments on commit b35daeb

Please sign in to comment.