Skip to content

Commit

Permalink
OCKOutcomeValue requiring all key values (#508)
Browse files Browse the repository at this point in the history
  • Loading branch information
cbaker6 authored Oct 2, 2020
1 parent 4d18cb0 commit 248c42c
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 25 deletions.
54 changes: 29 additions & 25 deletions CareKitStore/CareKitStore/Structs/OCKOutcomeValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public struct OCKOutcomeValue: Codable, Equatable, OCKObjectCompatible, CustomSt
case
kind, units, uuid, value, type, index,
createdDate, updatedDate, schemaVersion, tags,
groupIdentifier, remoteID, userInfo, source, timezone
groupIdentifier, remoteID, userInfo, source, timezone, asset, notes
}

public init(from decoder: Decoder) throws {
Expand All @@ -80,29 +80,31 @@ public struct OCKOutcomeValue: Codable, Equatable, OCKObjectCompatible, CustomSt
value = try container.decode(Date.self, forKey: .value)
}

kind = try container.decode(String?.self, forKey: .kind)
units = try container.decode(String?.self, forKey: .units)
index = try container.decode(Int?.self, forKey: .index)
uuid = try container.decode(UUID?.self, forKey: .uuid)
createdDate = try container.decode(Date?.self, forKey: .createdDate)
updatedDate = try container.decode(Date?.self, forKey: .updatedDate)
schemaVersion = try container.decode(OCKSemanticVersion?.self, forKey: .schemaVersion)
groupIdentifier = try container.decode(String?.self, forKey: .groupIdentifier)
tags = try container.decode([String]?.self, forKey: .tags)
remoteID = try container.decode(String?.self, forKey: .remoteID)
source = try container.decode(String?.self, forKey: .source)
userInfo = try container.decode([String: String]?.self, forKey: .userInfo)
kind = try container.decodeIfPresent(String.self, forKey: .kind)
units = try container.decodeIfPresent(String.self, forKey: .units)
index = try container.decodeIfPresent(Int.self, forKey: .index)
uuid = try container.decodeIfPresent(UUID.self, forKey: .uuid)
createdDate = try container.decodeIfPresent(Date.self, forKey: .createdDate)
updatedDate = try container.decodeIfPresent(Date.self, forKey: .updatedDate)
schemaVersion = try container.decodeIfPresent(OCKSemanticVersion.self, forKey: .schemaVersion)
groupIdentifier = try container.decodeIfPresent(String.self, forKey: .groupIdentifier)
tags = try container.decodeIfPresent([String].self, forKey: .tags)
remoteID = try container.decodeIfPresent(String.self, forKey: .remoteID)
source = try container.decodeIfPresent(String.self, forKey: .source)
userInfo = try container.decodeIfPresent([String: String].self, forKey: .userInfo)
timezone = try container.decode(TimeZone.self, forKey: .timezone)
asset = try container.decodeIfPresent(String.self, forKey: .asset)
notes = try container.decodeIfPresent([OCKNote].self, forKey: .notes)
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)

try container.encode(type, forKey: .type)
try container.encode(kind, forKey: .kind)
try container.encode(units, forKey: .units)
try container.encode(index, forKey: .index)
try container.encode(uuid, forKey: .uuid)
try container.encodeIfPresent(kind, forKey: .kind)
try container.encodeIfPresent(units, forKey: .units)
try container.encodeIfPresent(index, forKey: .index)
try container.encodeIfPresent(uuid, forKey: .uuid)

var encodedValue = false
if let value = integerValue { try container.encode(value, forKey: .value); encodedValue = true } else
Expand All @@ -117,14 +119,16 @@ public struct OCKOutcomeValue: Codable, Equatable, OCKObjectCompatible, CustomSt
throw EncodingError.invalidValue(value, EncodingError.Context(codingPath: [CodingKeys.value], debugDescription: message))
}

try container.encode(updatedDate, forKey: .updatedDate)
try container.encode(createdDate, forKey: .createdDate)
try container.encode(schemaVersion, forKey: .schemaVersion)
try container.encode(groupIdentifier, forKey: .groupIdentifier)
try container.encode(tags, forKey: .tags)
try container.encode(remoteID, forKey: .remoteID)
try container.encode(source, forKey: .source)
try container.encode(userInfo, forKey: .userInfo)
try container.encodeIfPresent(updatedDate, forKey: .updatedDate)
try container.encodeIfPresent(createdDate, forKey: .createdDate)
try container.encodeIfPresent(schemaVersion, forKey: .schemaVersion)
try container.encodeIfPresent(groupIdentifier, forKey: .groupIdentifier)
try container.encodeIfPresent(tags, forKey: .tags)
try container.encodeIfPresent(remoteID, forKey: .remoteID)
try container.encodeIfPresent(source, forKey: .source)
try container.encodeIfPresent(userInfo, forKey: .userInfo)
try container.encodeIfPresent(asset, forKey: .asset)
try container.encodeIfPresent(notes, forKey: .notes)
try container.encode(timezone, forKey: .timezone)
}

Expand Down
72 changes: 72 additions & 0 deletions CareKitStore/CareKitStoreTests/Structs/TestOutcomeValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,78 @@ class TestOutcomeValue: XCTestCase {
testEqualityOfEncodings(outcome1: value1, outcome2: value2)
}
}

func testProperDecodingWhenMissingValues() throws {
let valueToDecode = "{\"value\": 10,\"timezone\": {\"identifier\": \"America/New_York\"},\"type\": \"\(OCKOutcomeValueType.integer.rawValue)\"}"

guard let data = valueToDecode.data(using: .utf8) else {
throw OCKStoreError.invalidValue(reason: "Error: Couldn't get data as utf8")
}

let decoded = try JSONDecoder().decode(OCKOutcomeValue.self, from: data)

XCTAssertNil(decoded.asset)
XCTAssertNil(decoded.notes)
XCTAssertEqual(decoded.timezone, TimeZone(identifier: "America/New_York"))
if let decodedUnderValue = decoded.value as? Int {
XCTAssertEqual(decodedUnderValue, 10)
} else {
XCTFail("Should have underlying value")
}
}

func testCodingAllEntries() throws {
var value = OCKOutcomeValue(10)
let valueNote = OCKNote(author: "myId", title: "hello", content: "world")

//Value
value.index = 0
value.kind = "whale"
value.units = "m/s"

//OCKObjectCompatible
value.uuid = UUID()
value.createdDate = Date().addingTimeInterval(-200)
value.updatedDate = Date().addingTimeInterval(-99)
value.timezone = .current
value.userInfo = ["String": "String"]
value.remoteID = "we"
value.groupIdentifier = "mine"
value.tags = ["one", "two"]
value.schemaVersion = .init(majorVersion: 4)
value.source = "yo"
value.asset = "pic"
value.notes = [valueNote]

let encoded = try JSONEncoder().encode(value)
let decoded = try JSONDecoder().decode(OCKOutcomeValue.self, from: encoded)

XCTAssertEqual(decoded.index, value.index)
XCTAssertEqual(decoded.kind, value.kind)
XCTAssertEqual(decoded.units, value.units)
if let decodedUnderValue = decoded.value as? Int,
let currentUnderValue = value.value as? Int {
XCTAssertEqual(decodedUnderValue, currentUnderValue)
} else {
XCTFail("Should have underlying value")
}

XCTAssertEqual(decoded.uuid, value.uuid)
XCTAssertEqual(decoded.createdDate, value.createdDate)
XCTAssertEqual(decoded.updatedDate, value.updatedDate)
XCTAssertEqual(decoded.timezone, value.timezone)
XCTAssertEqual(decoded.userInfo, value.userInfo)
XCTAssertEqual(decoded.remoteID, value.remoteID)
XCTAssertEqual(decoded.source, value.source)
XCTAssertEqual(decoded.schemaVersion, value.schemaVersion)
XCTAssertEqual(decoded.tags, value.tags)
XCTAssertEqual(decoded.groupIdentifier, value.groupIdentifier)
XCTAssertEqual(decoded.asset, value.asset)
XCTAssertEqual(decoded.notes?.count, 1)
XCTAssertEqual(decoded.notes?.first?.author, "myId")
XCTAssertEqual(decoded.notes?.first?.title, "hello")
XCTAssertEqual(decoded.notes?.first?.content, "world")
}

func testEvolvingValue() {
var value = OCKOutcomeValue("abc")
Expand Down

0 comments on commit 248c42c

Please sign in to comment.