Skip to content

Commit

Permalink
Merge branch 'main' into day/rpcv2-cbor
Browse files Browse the repository at this point in the history
  • Loading branch information
dayaffe authored Jan 9, 2025
2 parents 7181815 + 5a922d8 commit e5d1a56
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
8 changes: 7 additions & 1 deletion Sources/SmithyJSON/Reader/Reader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import struct Foundation.Data
import struct Foundation.Date
import class Foundation.NSNull
import class Foundation.NSNumber
import class Foundation.NSDecimalNumber
import func CoreFoundation.CFGetTypeID
import func CoreFoundation.CFBooleanGetTypeID

Expand Down Expand Up @@ -126,7 +127,12 @@ public extension Reader {

func readIfPresent() throws -> Double? {
switch jsonNode {
case .number(let number): return number.doubleValue
case .number(let number):
if let decimalNumber = number as? NSDecimalNumber {
return Double("\(decimalNumber.decimalValue)")
} else {
return number.doubleValue
}
case .string(let string):
switch string {
case "NaN": return .nan
Expand Down
46 changes: 46 additions & 0 deletions Tests/SmithyJSONTests/FloatingPointTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import XCTest
@_spi(SmithyReadWrite) import SmithyReadWrite
@_spi(SmithyReadWrite) import SmithyJSON

// It appears that the doubleValue property on NSNumber & its associated types can sometimes lose
// precision from the original number.
//
// This set of tests is intended to verify that Doubles and Floats can be read accurately from JSON.

final class FloatingPointTests: XCTestCase {

static var originalFloats = [Float]()
static var floatData = Data()
static var originalDoubles = [Double]()
static var doubleData = Data()

// Renders 250 floats & doubles to JSON arrays. Numbers are random so they will
// likely use all available decimal places.
static override func setUp() {
originalFloats = (1..<250).map { _ in Float.random(in: 0.0...1.0) }
originalDoubles = (1..<250).map { _ in Double.random(in: 0.0...1.0) }
floatData = try! JSONEncoder().encode(originalFloats)
doubleData = try! JSONEncoder().encode(originalDoubles)
}

// Read the floats from JSON using JSONReader, and compare the values to the original.
func test_floatRead() throws {
let reader = try Reader.from(data: Self.floatData)
let floats = try reader.readList(memberReadingClosure: ReadingClosures.readFloat(from:), memberNodeInfo: "", isFlattened: false)
XCTAssert(floats == Self.originalFloats)
}

// Read the doubles from JSON using JSONReader, and compare the values to the original.
func test_doubleRead() throws {
let reader = try Reader.from(data: Self.doubleData)
let doubles = try reader.readList(memberReadingClosure: ReadingClosures.readDouble(from:), memberNodeInfo: "", isFlattened: false)
XCTAssert(doubles == Self.originalDoubles)
}
}

0 comments on commit e5d1a56

Please sign in to comment.