From ae134645e7efb5c7059246ea3617cb9cd453bebf Mon Sep 17 00:00:00 2001 From: kientux Date: Thu, 7 Jul 2022 15:00:40 +0700 Subject: [PATCH] Fix output of Optional type, add testcase --- Sources/Parameterize/Params.swift | 35 +++++++++++++++---- .../ParameterizeTests/ParameterizeTests.swift | 8 +++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/Sources/Parameterize/Params.swift b/Sources/Parameterize/Params.swift index f9798bf..9343301 100644 --- a/Sources/Parameterize/Params.swift +++ b/Sources/Parameterize/Params.swift @@ -37,19 +37,42 @@ extension Params: ParameterPair { var value: Any? { if let mapper = mapper { - return process(value: mapper(wrappedValue)) + return process(mappedValue: mapper(wrappedValue)) } else { - return process(value: wrappedValue) + return processWrappedValue() } } - private func process(value: Any?) -> Any? { - var v: Any? = nil + /// Two functions below have completely the same body + /// but it required to split to 2 functions + /// because with `wrappedValue`, we need to directly access + /// instead of go through `Any?` parameter, + /// or else it will be wrapped into an `Optional` type + /// and produces incorrect output. + + private func processWrappedValue() -> Any? { + var v: Any? + + if let value = wrappedValue as? OptionalProtocol { + v = value.wrapped + } else { + v = wrappedValue + } + + if let value = v as? ParamConvertible { + v = value.parameterValue + } + + return v + } + + private func process(mappedValue: Any?) -> Any? { + var v: Any? - if let value = value as? OptionalProtocol { + if let value = mappedValue as? OptionalProtocol { v = value.wrapped } else { - v = value + v = mappedValue } if let value = v as? ParamConvertible { diff --git a/Tests/ParameterizeTests/ParameterizeTests.swift b/Tests/ParameterizeTests/ParameterizeTests.swift index b1b0f57..3ea5da5 100644 --- a/Tests/ParameterizeTests/ParameterizeTests.swift +++ b/Tests/ParameterizeTests/ParameterizeTests.swift @@ -11,6 +11,10 @@ final class ParameterizeTests: XCTestCase { productsTypes: ["normal"]) let serialized = ParamSerializer().serialize(object: params) + /// make sure output type is `String`, not `Optional` + XCTAssertEqual("\(serialized["query"] ?? "")", "search") + XCTAssertNotEqual("\(serialized["query"] ?? "")", "Optional(\"search\")") + XCTAssertEqual(serialized["query"] as? String, "search") XCTAssertEqual(serialized["ids"] as? String, "1,2,3") XCTAssertEqual(serialized["page"] as? Int, 2) @@ -82,6 +86,10 @@ final class ParameterizeTests: XCTestCase { serialized = ParamSerializer().serialize(object: params) XCTAssertEqual(serialized["optionalCustomMapper"] as? Int, 101) + + /// make sure output type is `Int`, not `Optional` + XCTAssertEqual("\(serialized["optionalCustomMapper"] ?? 0)", "101") + XCTAssertNotEqual("\(serialized["optionalCustomMapper"] ?? 0)", "Optional(101)") } }