-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathDateCodingTests.swift
78 lines (67 loc) · 2.93 KB
/
DateCodingTests.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
@testable import ExtrasJSON
import XCTest
class DateCodingTests: XCTestCase {
@propertyWrapper
struct DateStringCoding: Codable {
var wrappedValue: Date
init(wrappedValue: Date) {
self.wrappedValue = wrappedValue
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let dateString = try container.decode(String.self)
guard let date = Self.dateFormatter.date(from: dateString) else {
let dateFormat = String(describing: Self.dateFormatter.dateFormat)
throw DecodingError.dataCorruptedError(in: container, debugDescription:
"Expected date to be in format `\(dateFormat)`, but `\(dateString) does not forfill format`")
}
self.wrappedValue = date
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
let dateString = Self.dateFormatter.string(from: self.wrappedValue)
try container.encode(dateString)
}
private static let dateFormatter: DateFormatter = Self.createDateFormatter()
private static func createDateFormatter() -> DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.locale = Locale(identifier: "en_US_POSIX")
return formatter
}
}
struct MyEvent: Codable {
@DateStringCoding
var eventTime: Date
}
func testDecodeDatePropertyWrapper() {
do {
let dateString = "2020-03-18T13:11:10.000Z"
let json = #"{"eventTime": "\#(dateString)"}"#
let result = try XJSONDecoder().decode(MyEvent.self, from: [UInt8](json.utf8))
let components = DateComponents(
calendar: Calendar(identifier: .gregorian), timeZone: TimeZone(secondsFromGMT: 0),
year: 2020, month: 03, day: 18, hour: 13, minute: 11, second: 10, nanosecond: 0
)
XCTAssertEqual(result.eventTime, components.date)
} catch {
XCTFail("Unexpected error: \(error)")
}
}
func testEncodeDatePropertyWrapper() {
do {
let dateString = "2020-03-18T13:11:10.000Z"
let json = #"{"eventTime":"\#(dateString)"}"#
let components = DateComponents(
calendar: Calendar(identifier: .gregorian), timeZone: TimeZone(secondsFromGMT: 0),
year: 2020, month: 03, day: 18, hour: 13, minute: 11, second: 10, nanosecond: 0
)
let event = MyEvent(eventTime: components.date!)
let bytes = try XJSONEncoder().encode(event)
XCTAssertEqual(String(decoding: bytes, as: Unicode.UTF8.self), json)
} catch {
XCTFail("Unexpected error: \(error)")
}
}
}