From d217888e5679aff063668930bd00892c4f5cb2b3 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Sun, 23 May 2021 14:06:14 -0700 Subject: [PATCH] close #18009 parseJson JInt vs JFloat; preserve -0.0 as JFloat to distinguish from 0.0 (#18067) --- lib/pure/json.nim | 2 +- tests/stdlib/tjsonutils.nim | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 3a9fa5898a..d5bbb86b86 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -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: diff --git a/tests/stdlib/tjsonutils.nim b/tests/stdlib/tjsonutils.nim index a55b0ca1d4..62486b8966 100644 --- a/tests/stdlib/tjsonutils.nim +++ b/tests/stdlib/tjsonutils.nim @@ -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