// // json_binder_value_double.t.h // json // // Created by Sam Jaffe on 2/25/17. // #include "json/json_binder.hpp" #include using namespace json::binder; using namespace json::parser; using namespace ::testing; TEST(JsonBinderDoubleTest, ParsesDouble) { char data[] = "0.5"; double out = 0.0; value_binder binder{}; parse(bind(out, binder), data, allow_all); EXPECT_THAT(out, 0.5); } TEST(JsonBinderDoubleTest, ParsesScientific) { char data[] = "2e4"; double out = 0.0; value_binder binder{}; EXPECT_NO_THROW(parse(bind(out, binder), data, allow_all)); } TEST(JsonBinderDoubleTest, ThrowsOnEOB) { char data[] = ""; double out = 0.0; value_binder binder{}; EXPECT_THROW(parse(bind(out, binder), data, allow_all), json::json_numeric_exception); } TEST(JsonBinderDoubleTest, ThrowsOnNaN) { char data[] = "one half"; double out = 0.0; value_binder binder{}; EXPECT_THROW(parse(bind(out, binder), data, allow_all), json::json_numeric_exception); } TEST(JsonBinderDoubleTest, ThrowsOnTokenConcat) { char data[] = "5.0boo"; double out = 0.0; value_binder binder{}; EXPECT_THROW(parse(bind(out, binder), data, disable_concatenated_json_bodies), json::malformed_json_exception); EXPECT_THAT(out, 5.0); } TEST(JsonBinderDoubleTest, OutputIsEssentiallyEqualDblMax) { char data[] = "1.79769e+308"; double out = 0.0; value_binder binder{}; EXPECT_NO_THROW(parse(bind(out, binder), data, allow_all)); EXPECT_THAT(out, DoubleNear(std::numeric_limits::max(), 1E303)); } TEST(JsonBinderDoubleTest, ThrowsOnOOBMax) { char data[] = "1.8e+308"; double out = 0.0; value_binder binder{}; EXPECT_THROW(parse(bind(out, binder), data, allow_all), json::json_numeric_width_exception); } TEST(JsonBinderDoubleTest, OutputIsEssentiallyEqualDblLowest) { char data[] = "-1.79769e+308"; double out = 0.0; value_binder binder{}; EXPECT_NO_THROW(parse(bind(out, binder), data, allow_all)); EXPECT_THAT(out, DoubleNear(std::numeric_limits::lowest(), 1E303)); } TEST(JsonBinderDoubleTest, ThrowsOnOOBLowest) { char data[] = "-1.8e+308"; double out = 0.0; value_binder binder{}; EXPECT_THROW(parse(bind(out, binder), data, allow_all), json::json_numeric_width_exception); } TEST(JsonBinderDoubleTest, OutputIsEssentiallyEqualDblMin) { char data[] = "2.22508e-308"; // 2.22507e-308 is min according to cppreference double out = 0.0; value_binder binder{}; EXPECT_NO_THROW(parse(bind(out, binder), data, allow_all)); EXPECT_THAT(out, DoubleNear(std::numeric_limits::min(), 1E-303)); } TEST(JsonBinderDoubleTest, ThrowsOnOOBMin) { char data[] = "2e-308"; double out = 0.0; value_binder binder{}; EXPECT_THROW(parse(bind(out, binder), data, allow_all), json::json_numeric_width_exception); } TEST(JsonBinderDoubleTest, ParseNoLossWithExactRep) { std::stringstream ss; double in = 500., out = 0; value_binder binder{}; write(bind(in, binder), ss); parse(bind(out, binder), ss.str().c_str(), allow_all); EXPECT_THAT(out, in); } TEST(JsonBinderDoubleTest, ParseNoLossWithInexactRep) { std::stringstream ss; double in = 0.3, out = 0; value_binder binder{}; write(bind(in, binder), ss); parse(bind(out, binder), ss.str().c_str(), allow_all); EXPECT_THAT(out, in); } TEST(JsonBinderDoubleTest, ParseNoLossWithLargeNumberSci) { std::stringstream ss; double in = 1.34e300, out = 0.0; value_binder binder{}; write(bind(in, binder), ss); parse(bind(out, binder), ss.str().c_str(), allow_all); EXPECT_THAT(out, in); } TEST(JsonBinderDoubleTest, ParseNoLossWithLargeNegativeNumberSci) { std::stringstream ss; double in = 1.34e-300, out = 0.0; value_binder binder{}; write(bind(in, binder), ss); parse(bind(out, binder), ss.str().c_str(), allow_all); EXPECT_THAT(out, DoubleNear(in, 1e-299)); } TEST(JsonBinderDoubleTest, ParseNoLossWithLargeNumber) { std::stringstream ss; double in = 52450012.25, out = 0.0; value_binder binder{}; write(bind(in, binder), ss); parse(bind(out, binder), ss.str().c_str(), allow_all); EXPECT_THAT(out, in); } TEST(JsonBinderDoubleTest, ParseEssentiallyEqualAtSeveralDecimalPlaces) { std::stringstream ss; double in = 0.0002517867, out = 0.0; value_binder binder{}; write(bind(in, binder), ss); EXPECT_NO_THROW(parse(bind(out, binder), ss.str().c_str(), allow_all)); EXPECT_THAT(out, DoubleNear(in, 0.000001)); }