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