Skip to content

Commit

Permalink
Change to using a single date formatter and update unit tests. (#285)
Browse files Browse the repository at this point in the history
  • Loading branch information
cprince-foreflight authored Dec 14, 2023
1 parent 266c374 commit cc4e0e3
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 22 deletions.
24 changes: 22 additions & 2 deletions Sources/Segment/Utilities/JSON.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,37 @@ import Foundation
import JSONSafeEncoder

extension JSONDecoder {
enum JSONDecodingError: Error {
case couldNotDecodeDate(String)
}

static var `default`: JSONDecoder {
let d = JSONDecoder()
d.dateDecodingStrategy = .formatted(DateFormatter.iso8601)

d.dateDecodingStrategy = .custom({ decoder throws -> Date in
let stringDate = try decoder.singleValueContainer().decode(String.self)

guard let date = stringDate.iso8601() else {
throw JSONDecodingError.couldNotDecodeDate(stringDate)
}

return date
})

return d
}
}

extension JSONSafeEncoder {
static var `default`: JSONSafeEncoder {
let e = JSONSafeEncoder()
e.dateEncodingStrategy = .formatted(DateFormatter.iso8601)

e.dateEncodingStrategy = .custom({ date, encoder in
let stringDate = date.iso8601()
var container = encoder.singleValueContainer()
try container.encode(stringDate)
})

e.nonConformingFloatEncodingStrategy = JSON.jsonNonConformingNumberStrategy
return e
}
Expand Down
11 changes: 0 additions & 11 deletions Sources/Segment/Utilities/iso8601.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,3 @@ internal extension String {
return SegmentISO8601DateFormatter.shared.date(from: self)
}
}

extension DateFormatter {
static let iso8601: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
formatter.calendar = Calendar(identifier: .iso8601)
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.locale = Locale(identifier: "en_US_POSIX")
return formatter
}()
}
32 changes: 23 additions & 9 deletions Tests/Segment-Tests/JSON_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,28 +56,42 @@ class JSONTests: XCTestCase {
struct TestStruct: Codable {
let myDate: Date
}

let now = Date(timeIntervalSinceNow: 0)

let test = TestStruct(myDate: now)

let expectedDateString = "2023-12-14T16:03:14.300Z"
let expectedDate = try XCTUnwrap(expectedDateString.iso8601())

let test = TestStruct(myDate: expectedDate)
let object = try JSON(with: test)
let encoder = JSONSafeEncoder.default
encoder.outputFormatting = .prettyPrinted

do {
let json = try encoder.encode(object)
XCTAssertNotNil(json)
let newTest = try! JSONDecoder.default.decode(TestStruct.self, from: json)
XCTAssertEqual(newTest.myDate.toString(), now.toString())
XCTAssertEqual(newTest.myDate.toString(), "\"\(expectedDateString)\"")
} catch {
print(error)
XCTFail()
}
let dummyProps = ["myDate": now] // <- conforms to Codable

let dummyProps = ["myDate": expectedDate] // <- conforms to Codable
let j = try! JSON(dummyProps)
let anotherTest: TestStruct! = j.codableValue()
XCTAssertEqual(anotherTest.myDate.toString(), now.toString())
XCTAssertEqual(anotherTest.myDate.toString(), "\"\(expectedDateString)\"")

// Non-Codable (e.g., Objective-C) interface

let dictWithDate = ["myDate": expectedDate]
let json = try JSON(dictWithDate)
let value = json["myDate"]

guard case .string(let actualDateString) = value else {
XCTFail()
return
}

XCTAssertEqual(expectedDateString, actualDateString)
}

func testJSONCollectionTypes() throws {
Expand Down

0 comments on commit cc4e0e3

Please sign in to comment.