From 85096bdd29ccbf9a95f9abc0590c8fc70c2d0b4c Mon Sep 17 00:00:00 2001 From: Serj Date: Sat, 15 Feb 2020 14:47:23 +0100 Subject: [PATCH 1/5] Implement DefaultCodable decode implementation to default when key is not present --- Sources/BetterCodable/DefaultCodable.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Sources/BetterCodable/DefaultCodable.swift b/Sources/BetterCodable/DefaultCodable.swift index ed328c7..4ac41b4 100644 --- a/Sources/BetterCodable/DefaultCodable.swift +++ b/Sources/BetterCodable/DefaultCodable.swift @@ -30,3 +30,18 @@ public struct DefaultCodable: Codable { extension DefaultCodable: Equatable where Default.RawValue: Equatable { } extension DefaultCodable: Hashable where Default.RawValue: Hashable { } + +// MARK: - KeyedDecodingContainer +public extension KeyedDecodingContainer { + + /// Default implementation of decoding a DefaultCodable + /// + /// Decodes successfully if key is available if not fallsback to the default value provided. + func decode

(_: DefaultCodable

.Type, forKey key: Key) throws -> DefaultCodable

{ + if let value = try decodeIfPresent(DefaultCodable

.self, forKey: key) { + return value + } else { + return DefaultCodable(wrappedValue: P.defaultValue) + } + } +} From f3d7da491cffeacc98ce8e5dab536f3eacc656d8 Mon Sep 17 00:00:00 2001 From: Serj Date: Sat, 15 Feb 2020 15:20:27 +0100 Subject: [PATCH 2/5] Add test when key is not present to default dictionary --- Tests/BetterCodableTests/DefaulEmptyDictionaryTests.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Tests/BetterCodableTests/DefaulEmptyDictionaryTests.swift b/Tests/BetterCodableTests/DefaulEmptyDictionaryTests.swift index 5edad25..dbfab0e 100644 --- a/Tests/BetterCodableTests/DefaulEmptyDictionaryTests.swift +++ b/Tests/BetterCodableTests/DefaulEmptyDictionaryTests.swift @@ -11,6 +11,12 @@ class DefaultEmptyDictionaryTests: XCTestCase { let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) XCTAssertEqual(fixture.stringToInt, [:]) } + + func testDecodingKeyNotPresentDefaultsToEmptyDictionary() throws { + let jsonData = #"{}"#.data(using: .utf8)! + let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) + XCTAssertEqual(fixture.stringToInt, [:]) + } func testEncodingDecodedFailableDictionaryDefaultsToEmptyDictionary() throws { let jsonData = #"{ "stringToInt": null }"#.data(using: .utf8)! From bef95ebbd5fecdb8cacc8766c9bdd63c9e644d8a Mon Sep 17 00:00:00 2001 From: Serj Date: Sat, 15 Feb 2020 15:22:34 +0100 Subject: [PATCH 3/5] Add test when key is not present default array --- Tests/BetterCodableTests/DefaultEmptyArrayTests.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Tests/BetterCodableTests/DefaultEmptyArrayTests.swift b/Tests/BetterCodableTests/DefaultEmptyArrayTests.swift index a66f46b..b00d191 100644 --- a/Tests/BetterCodableTests/DefaultEmptyArrayTests.swift +++ b/Tests/BetterCodableTests/DefaultEmptyArrayTests.swift @@ -18,6 +18,13 @@ class DefaultEmptyArrayTests: XCTestCase { XCTAssertEqual(fixture.values, []) XCTAssertEqual(fixture.nonPrimitiveValues, []) } + + func testDecodingKeyNotPresentDefaultsToEmptyArray() throws { + let jsonData = #"{}"#.data(using: .utf8)! + let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) + XCTAssertEqual(fixture.values, []) + XCTAssertEqual(fixture.nonPrimitiveValues, []) + } func testEncodingDecodedFailableArrayDefaultsToEmptyArray() throws { let jsonData = #"{ "values": null, "nonPrimitiveValues": null }"#.data(using: .utf8)! From 740ee091ebb3197554b2d0f798e6e91d48ce066f Mon Sep 17 00:00:00 2001 From: Serj Agopian Date: Sat, 15 Feb 2020 15:30:42 +0100 Subject: [PATCH 4/5] Add test to DefaultFalse when key is not available --- Tests/BetterCodableTests/DefaultFalseTests.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Tests/BetterCodableTests/DefaultFalseTests.swift b/Tests/BetterCodableTests/DefaultFalseTests.swift index 65039b4..70dbce7 100644 --- a/Tests/BetterCodableTests/DefaultFalseTests.swift +++ b/Tests/BetterCodableTests/DefaultFalseTests.swift @@ -11,6 +11,12 @@ class DefaultFalseTests: XCTestCase { let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) XCTAssertEqual(fixture.truthy, false) } + + func testDecodingKeyNotPresentDefaultsToFalse() throws { + let jsonData = #"{}"#.data(using: .utf8)! + let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) + XCTAssertEqual(fixture.truthy, false) + } func testEncodingDecodedFailableArrayDefaultsToEmptyArray() throws { let jsonData = #"{ "truthy": null }"#.data(using: .utf8)! From 87d9e087005a39f7cd63d1ec8f5a57573435c29c Mon Sep 17 00:00:00 2001 From: Serj Agopian Date: Sat, 15 Feb 2020 15:31:04 +0100 Subject: [PATCH 5/5] Rename Bool tests from saying array to bool --- Tests/BetterCodableTests/DefaultFalseTests.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/BetterCodableTests/DefaultFalseTests.swift b/Tests/BetterCodableTests/DefaultFalseTests.swift index 70dbce7..1ce1ede 100644 --- a/Tests/BetterCodableTests/DefaultFalseTests.swift +++ b/Tests/BetterCodableTests/DefaultFalseTests.swift @@ -6,7 +6,7 @@ class DefaultFalseTests: XCTestCase { @DefaultFalse var truthy: Bool } - func testDecodingFailableArrayDefaultsToEmptyArray() throws { + func testDecodingFailableArrayDefaultsToFalse() throws { let jsonData = #"{ "truthy": null }"#.data(using: .utf8)! let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) XCTAssertEqual(fixture.truthy, false) @@ -18,7 +18,7 @@ class DefaultFalseTests: XCTestCase { XCTAssertEqual(fixture.truthy, false) } - func testEncodingDecodedFailableArrayDefaultsToEmptyArray() throws { + func testEncodingDecodedFailableArrayDefaultsToFalse() throws { let jsonData = #"{ "truthy": null }"#.data(using: .utf8)! var _fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) @@ -29,7 +29,7 @@ class DefaultFalseTests: XCTestCase { XCTAssertEqual(fixture.truthy, true) } - func testEncodingDecodedFulfillableArrayRetainsContents() throws { + func testEncodingDecodedFulfillableBoolRetainsValue() throws { let jsonData = #"{ "truthy": true }"#.data(using: .utf8)! let _fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) let fixtureData = try JSONEncoder().encode(_fixture)