From 1f21770e2247339f41e063fbc356a68e0d550518 Mon Sep 17 00:00:00 2001 From: Brian King Date: Thu, 15 Dec 2016 10:58:54 -0500 Subject: [PATCH 1/6] Fix a bug where a function 'any' slipped into the shadow of the expected 'any' variable --- Sources/MarshaledObject.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/MarshaledObject.swift b/Sources/MarshaledObject.swift index ced2a6f..f00a262 100644 --- a/Sources/MarshaledObject.swift +++ b/Sources/MarshaledObject.swift @@ -119,6 +119,7 @@ public extension MarshaledObject { } public func value(for key: KeyType) throws -> [String: A]? { + let any = try self.any(for: key) do { return try [String: A].value(from: any) } From 6e19d7c72a1b49caa120915ecd562f86499efda8 Mon Sep 17 00:00:00 2001 From: Brian King Date: Thu, 15 Dec 2016 10:59:35 -0500 Subject: [PATCH 2/6] Add a generic operator to provide better dictionary support --- Sources/Operators.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sources/Operators.swift b/Sources/Operators.swift index f2a4b75..b417036 100644 --- a/Sources/Operators.swift +++ b/Sources/Operators.swift @@ -52,3 +52,6 @@ public func <| (dictionary: MarshaledObject, key: String) throws -> JSONObject { public func <| (dictionary: MarshaledObject, key: String) throws -> [JSONObject] { return try dictionary.value(for: key) } +public func <| (dictionary: MarshaledObject, key: String) throws -> [String: A] { + return try dictionary.value(for: key) +} From 9a4ff53cedfebe1eb7e16a301641ebf5eb01f35f Mon Sep 17 00:00:00 2001 From: Brian King Date: Thu, 15 Dec 2016 11:00:19 -0500 Subject: [PATCH 3/6] Add a test for generic optional dictionary value(for:) --- MarshalTests/MarshalTests.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/MarshalTests/MarshalTests.swift b/MarshalTests/MarshalTests.swift index 4dfd266..40322e4 100644 --- a/MarshalTests/MarshalTests.swift +++ b/MarshalTests/MarshalTests.swift @@ -155,9 +155,17 @@ class MarshalTests: XCTestCase { let dead = try! !person.value(for: "living") XCTAssertTrue(dead) - let result: [String: Bool] = try! json.value(for: "result") + var result: [String: Bool] = try! json.value(for: "result") XCTAssertEqual(result.count, 1) XCTAssertEqual(result["ok"], true) + do { + // Check the optional getter + result = try json.value(for: "result") ?? [:] + XCTAssertNotNil(result) + } + catch { + XCTFail() + } } func testOptionalDictionary() { From 6166791d4843b94d14c6e20ad26bb828b1791fe1 Mon Sep 17 00:00:00 2001 From: Brian King Date: Thu, 15 Dec 2016 11:04:12 -0500 Subject: [PATCH 4/6] Add optional generic dictionary operator --- Sources/Operators.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sources/Operators.swift b/Sources/Operators.swift index b417036..04c617b 100644 --- a/Sources/Operators.swift +++ b/Sources/Operators.swift @@ -55,3 +55,6 @@ public func <| (dictionary: MarshaledObject, key: String) throws -> [JSONObject] public func <| (dictionary: MarshaledObject, key: String) throws -> [String: A] { return try dictionary.value(for: key) } +public func <| (dictionary: MarshaledObject, key: String) throws -> [String: A]? { + return try dictionary.value(for: key) +} From 5d5fc166979e4c2c16f8dd063b4a500211f1e041 Mon Sep 17 00:00:00 2001 From: Brian King Date: Thu, 15 Dec 2016 11:04:33 -0500 Subject: [PATCH 5/6] Add tests for generic dictionary operators --- MarshalTests/MarshalTests.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MarshalTests/MarshalTests.swift b/MarshalTests/MarshalTests.swift index 40322e4..079cc82 100644 --- a/MarshalTests/MarshalTests.swift +++ b/MarshalTests/MarshalTests.swift @@ -398,6 +398,7 @@ class MarshalTests: XCTestCase { "huge": Int.max, "decimal": 1.2, "array": [ "a", "b", "c" ], + "boolDictionary": [ "a": true, "b": false, "c": true ], "nested": [ "key": "value" ] @@ -414,6 +415,8 @@ class MarshalTests: XCTestCase { let huge: Int = try result <| "huge" let decimal: Float = try result <| "decimal" let array: [String] = try result <| "array" + let boolDictionary: [String: Bool] = try result <| "boolDictionary" + let optBoolDictionary: [String: Bool]? = try result <| "boolDictionary" let nested: [String:Any] = try result <| "nested" XCTAssertEqual(string, "A String") @@ -426,6 +429,8 @@ class MarshalTests: XCTestCase { XCTAssertEqual(decimal, 1.2) XCTAssertEqual(array, [ "a", "b", "c" ]) XCTAssertEqual(nested as! [String:String], [ "key": "value" ]) + XCTAssertEqual(boolDictionary, [ "a": true, "b": false, "c": true ]) + XCTAssertEqual(boolDictionary, optBoolDictionary ?? [:]) } catch { XCTFail("Error converting MarshalDictionary: \(error)") } From 0d1ca86b068fb6a35cab55de91248f43cafd83c2 Mon Sep 17 00:00:00 2001 From: Brian King Date: Thu, 15 Dec 2016 13:43:17 -0500 Subject: [PATCH 6/6] Catch the missing key exception --- MarshalTests/MarshalTests.swift | 2 +- Sources/MarshaledObject.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MarshalTests/MarshalTests.swift b/MarshalTests/MarshalTests.swift index 72ee581..e90df73 100644 --- a/MarshalTests/MarshalTests.swift +++ b/MarshalTests/MarshalTests.swift @@ -161,7 +161,7 @@ class MarshalTests: XCTestCase { do { // Check the optional getter result = try json.value(for: "result") ?? [:] - XCTAssertNotNil(result) + result = try json.value(for: "emptyKey") ?? [:] } catch { XCTFail() diff --git a/Sources/MarshaledObject.swift b/Sources/MarshaledObject.swift index 89ce57c..563857b 100644 --- a/Sources/MarshaledObject.swift +++ b/Sources/MarshaledObject.swift @@ -119,8 +119,8 @@ public extension MarshaledObject { } public func value(for key: KeyType) throws -> [String: A]? { - let any = try self.any(for: key) do { + let any = try self.any(for: key) return try [String: A].value(from: any) } catch MarshalError.keyNotFound {