Проблема с Aeson или Wai.JSON QuasiQuoter - конвертирует 0,0 в 0

Я использую Test.Hspec.Wai.JSON чтобы проверить возвращаемое значение моих конечных точек API. Я заметил, что всякий раз, когда я создаю JSON со значением 0.0Когда тест выполняется, он преобразует его в 0 (Int) и если API возвращается 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} 

Я не настолько продвинут в Хаскеле, чтобы выяснить, где в коде библиотеки это происходит. Я посмотрел на исходный код Test.Hspec.Wai.JSON и, кажется, полагаться на Aeson.QQ так что не совсем уверен источник проблемы. Это источник Test.Hspec.Wai.JSON, а это источник Aeson.QQ

В связи с этим моя работа заключалась в том, чтобы написать FromJSON экземпляр, чтобы проанализировать весь ответ и проверить заполненную запись. Это немного утомительно.

Любые предложения относительно того, что в коде библиотеки вызывает это? И как это исправить?

Спасибо,

1 ответ

Решение

Подозреваемый, кажется, это линия 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 и ожидать, что их представления будут эквивалентны. Скорее, он должен десериализовать фактический ответ и сравнить декодированные объекты на равенство. (В конце концов, с плавающей точкой / целым числом не единственно возможная проблема. Он также не сможет обрабатывать переупорядоченные ключи объекта.) Я не знаком с Hspec, поэтому не уверен, как вы Заставь это сделать.

Другие вопросы по тегам