close #18009 parseJson JInt vs JFloat; preserve -0.0 as JFloat to distinguish from 0.0 (#18067)

This commit is contained in:
Timothee Cour
2021-05-23 14:06:14 -07:00
committed by GitHub
parent 1421a3bf26
commit d217888e56
2 changed files with 17 additions and 2 deletions

View File

@@ -938,7 +938,7 @@ when defined(js):
of "[object Array]": return JArray
of "[object Object]": return JObject
of "[object Number]":
if isInteger(x):
if isInteger(x) and 1.0 / cast[float](x) != -Inf: # preserve -0.0 as float
if isSafeInteger(x):
return JInt
else:

View File

@@ -4,7 +4,8 @@ discard """
import std/jsonutils
import std/json
from std/math import isNaN
from std/math import isNaN, signbit
from stdtest/testutils import whenRuntimeJs
proc testRoundtrip[T](t: T, expected: string) =
# checks that `T => json => T2 => json2` is such that json2 = json
@@ -123,6 +124,20 @@ template fn() =
testRoundtripVal((Inf, -Inf, 0.0, -0.0, 1.0)): """["inf","-inf",0.0,-0.0,1.0]"""
doAssert ($NaN.toJson).parseJson.jsonTo(float).isNaN
block: # bug #18009; unfixable unless we change parseJson (which would have overhead),
# but at least we can guarantee that the distinction between 0.0 and -0.0 is preserved.
let a = (0, 0.0, -0.0, 0.5, 1, 1.0)
testRoundtripVal(a): "[0,0.0,-0.0,0.5,1,1.0]"
let a2 = $($a.toJson).parseJson
whenRuntimeJs:
doAssert a2 == "[0,0,-0.0,0.5,1,1]"
do:
doAssert a2 == "[0,0.0,-0.0,0.5,1,1.0]"
let b = a2.parseJson.jsonTo(type(a))
doAssert not b[1].signbit
doAssert b[2].signbit
doAssert not b[3].signbit
block: # case object
type Foo = object
x0: float