Aeson 或 Wai.JSON QuasiQuoter 的问题——将 0.0 转换为 0
Issue with Aeson or Wai.JSON QuasiQuoter -- Converts 0.0 to 0
我正在使用 Test.Hspec.Wai.JSON
检查我的 api 端点的 return 值。我注意到每当我创建一个值为 0.0
的 json 时,当测试运行时,它会将其转换为 0
(Int) 并且如果 api returns 0.0
,测试失败。
let j = [json|{"test":0.0}|]
request "GET" "some_url" [("Content-Type", "application/json")] ""
`shouldRespondWith` j {matchStatus = 200}
body mismatch:
expected: {"test":0} ---> this is the issue (0.0 has become 0)
but got: {"test":0.0}
我在 Haskell 方面并没有那么先进,无法找出库代码中发生这种情况的位置。我查看了 Test.Hspec.Wai.JSON
的源代码,它似乎依赖于 Aeson.QQ
,所以不太确定问题的根源。这是Test.Hspec.Wai.JSON source and this is the Aeson.QQ Source
因此,我的工作是编写一个 FromJSON
实例来解析整个响应并检查填写的记录。这有点乏味。
关于库代码中的什么导致此问题的任何建议?以及如何修复它?
谢谢,
嫌疑人似乎是这一行 Data.Aeson.QQ
:
toExp (JsonNumber n) = [|Number (fromRational $(return $ LitE $ RationalL (toRational n)))|]
它将数字转换为 Rational
,将其转换为 Haskell 表达式,然后将生成的表达式转换回 Number
。这最终放弃了它是 0.0
而不是 0
.
的事实
这通常不会成为问题,因为 Aeson 正确定义了 ==
以使 Number
具有相同的值。这成为 Test.Hspec.Wai.JSON
的实际问题;它的工作方式是将对象编码回 ByteString
并期望它与它完全匹配。
虽然 Data.Aeson.QQ
是您问题的根本原因,但我不会责怪它。相反,Test.Hspec.Wai.JSON
不应该序列化 JSON 对象并期望它们的表示是等价的。相反,它应该反序列化实际响应并比较解码对象的相等性。 (毕竟,floating-point/integer 不是唯一可能的问题。它也无法处理重新排序的对象键。)我不熟悉 Hspec,所以我不确定你是怎么做的让它这样做。
我正在使用 Test.Hspec.Wai.JSON
检查我的 api 端点的 return 值。我注意到每当我创建一个值为 0.0
的 json 时,当测试运行时,它会将其转换为 0
(Int) 并且如果 api returns 0.0
,测试失败。
let j = [json|{"test":0.0}|]
request "GET" "some_url" [("Content-Type", "application/json")] ""
`shouldRespondWith` j {matchStatus = 200}
body mismatch:
expected: {"test":0} ---> this is the issue (0.0 has become 0)
but got: {"test":0.0}
我在 Haskell 方面并没有那么先进,无法找出库代码中发生这种情况的位置。我查看了 Test.Hspec.Wai.JSON
的源代码,它似乎依赖于 Aeson.QQ
,所以不太确定问题的根源。这是Test.Hspec.Wai.JSON source and this is the Aeson.QQ Source
因此,我的工作是编写一个 FromJSON
实例来解析整个响应并检查填写的记录。这有点乏味。
关于库代码中的什么导致此问题的任何建议?以及如何修复它?
谢谢,
嫌疑人似乎是这一行 Data.Aeson.QQ
:
toExp (JsonNumber n) = [|Number (fromRational $(return $ LitE $ RationalL (toRational n)))|]
它将数字转换为 Rational
,将其转换为 Haskell 表达式,然后将生成的表达式转换回 Number
。这最终放弃了它是 0.0
而不是 0
.
这通常不会成为问题,因为 Aeson 正确定义了 ==
以使 Number
具有相同的值。这成为 Test.Hspec.Wai.JSON
的实际问题;它的工作方式是将对象编码回 ByteString
并期望它与它完全匹配。
虽然 Data.Aeson.QQ
是您问题的根本原因,但我不会责怪它。相反,Test.Hspec.Wai.JSON
不应该序列化 JSON 对象并期望它们的表示是等价的。相反,它应该反序列化实际响应并比较解码对象的相等性。 (毕竟,floating-point/integer 不是唯一可能的问题。它也无法处理重新排序的对象键。)我不熟悉 Hspec,所以我不确定你是怎么做的让它这样做。