json_binder_value_double_test.cxx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. //
  2. // json_binder_value_double.t.h
  3. // json
  4. //
  5. // Created by Sam Jaffe on 2/25/17.
  6. //
  7. #include "json/json_binder.hpp"
  8. #include <gmock/gmock.h>
  9. using namespace json::binder;
  10. using namespace json::parser;
  11. using namespace ::testing;
  12. TEST(JsonBinderDoubleTest, ParsesDouble) {
  13. char data[] = "0.5";
  14. double out = 0.0;
  15. value_binder<double> binder{};
  16. parse(bind(out, binder), data, allow_all);
  17. EXPECT_THAT(out, 0.5);
  18. }
  19. TEST(JsonBinderDoubleTest, ParsesScientific) {
  20. char data[] = "2e4";
  21. double out = 0.0;
  22. value_binder<double> binder{};
  23. EXPECT_NO_THROW(parse(bind(out, binder), data, allow_all));
  24. }
  25. TEST(JsonBinderDoubleTest, ThrowsOnEOB) {
  26. char data[] = "";
  27. double out = 0.0;
  28. value_binder<double> binder{};
  29. EXPECT_THROW(parse(bind(out, binder), data, allow_all),
  30. json::json_numeric_exception);
  31. }
  32. TEST(JsonBinderDoubleTest, ThrowsOnNaN) {
  33. char data[] = "one half";
  34. double out = 0.0;
  35. value_binder<double> binder{};
  36. EXPECT_THROW(parse(bind(out, binder), data, allow_all),
  37. json::json_numeric_exception);
  38. }
  39. TEST(JsonBinderDoubleTest, ThrowsOnTokenConcat) {
  40. char data[] = "5.0boo";
  41. double out = 0.0;
  42. value_binder<double> binder{};
  43. EXPECT_THROW(parse(bind(out, binder), data, disable_concatenated_json_bodies),
  44. json::malformed_json_exception);
  45. EXPECT_THAT(out, 5.0);
  46. }
  47. TEST(JsonBinderDoubleTest, OutputIsEssentiallyEqualDblMax) {
  48. char data[] = "1.79769e+308";
  49. double out = 0.0;
  50. value_binder<double> binder{};
  51. EXPECT_NO_THROW(parse(bind(out, binder), data, allow_all));
  52. EXPECT_THAT(out, DoubleNear(std::numeric_limits<double>::max(), 1E303));
  53. }
  54. TEST(JsonBinderDoubleTest, ThrowsOnOOBMax) {
  55. char data[] = "1.8e+308";
  56. double out = 0.0;
  57. value_binder<double> binder{};
  58. EXPECT_THROW(parse(bind(out, binder), data, allow_all),
  59. json::json_numeric_width_exception);
  60. }
  61. TEST(JsonBinderDoubleTest, OutputIsEssentiallyEqualDblLowest) {
  62. char data[] = "-1.79769e+308";
  63. double out = 0.0;
  64. value_binder<double> binder{};
  65. EXPECT_NO_THROW(parse(bind(out, binder), data, allow_all));
  66. EXPECT_THAT(out, DoubleNear(std::numeric_limits<double>::lowest(), 1E303));
  67. }
  68. TEST(JsonBinderDoubleTest, ThrowsOnOOBLowest) {
  69. char data[] = "-1.8e+308";
  70. double out = 0.0;
  71. value_binder<double> binder{};
  72. EXPECT_THROW(parse(bind(out, binder), data, allow_all),
  73. json::json_numeric_width_exception);
  74. }
  75. TEST(JsonBinderDoubleTest, OutputIsEssentiallyEqualDblMin) {
  76. char data[] = "2.22508e-308"; // 2.22507e-308 is min according to cppreference
  77. double out = 0.0;
  78. value_binder<double> binder{};
  79. EXPECT_NO_THROW(parse(bind(out, binder), data, allow_all));
  80. EXPECT_THAT(out, DoubleNear(std::numeric_limits<double>::min(), 1E-303));
  81. }
  82. TEST(JsonBinderDoubleTest, ThrowsOnOOBMin) {
  83. char data[] = "2e-308";
  84. double out = 0.0;
  85. value_binder<double> binder{};
  86. EXPECT_THROW(parse(bind(out, binder), data, allow_all),
  87. json::json_numeric_width_exception);
  88. }
  89. TEST(JsonBinderDoubleTest, ParseNoLossWithExactRep) {
  90. std::stringstream ss;
  91. double in = 500., out = 0;
  92. value_binder<double> binder{};
  93. write(bind(in, binder), ss);
  94. parse(bind(out, binder), ss.str().c_str(), allow_all);
  95. EXPECT_THAT(out, in);
  96. }
  97. TEST(JsonBinderDoubleTest, ParseNoLossWithInexactRep) {
  98. std::stringstream ss;
  99. double in = 0.3, out = 0;
  100. value_binder<double> binder{};
  101. write(bind(in, binder), ss);
  102. parse(bind(out, binder), ss.str().c_str(), allow_all);
  103. EXPECT_THAT(out, in);
  104. }
  105. TEST(JsonBinderDoubleTest, ParseNoLossWithLargeNumberSci) {
  106. std::stringstream ss;
  107. double in = 1.34e300, out = 0.0;
  108. value_binder<double> binder{};
  109. write(bind(in, binder), ss);
  110. parse(bind(out, binder), ss.str().c_str(), allow_all);
  111. EXPECT_THAT(out, in);
  112. }
  113. TEST(JsonBinderDoubleTest, ParseNoLossWithLargeNegativeNumberSci) {
  114. std::stringstream ss;
  115. double in = 1.34e-300, out = 0.0;
  116. value_binder<double> binder{};
  117. write(bind(in, binder), ss);
  118. parse(bind(out, binder), ss.str().c_str(), allow_all);
  119. EXPECT_THAT(out, DoubleNear(in, 1e-299));
  120. }
  121. TEST(JsonBinderDoubleTest, ParseNoLossWithLargeNumber) {
  122. std::stringstream ss;
  123. double in = 52450012.25, out = 0.0;
  124. value_binder<double> binder{};
  125. write(bind(in, binder), ss);
  126. parse(bind(out, binder), ss.str().c_str(), allow_all);
  127. EXPECT_THAT(out, in);
  128. }
  129. TEST(JsonBinderDoubleTest, ParseEssentiallyEqualAtSeveralDecimalPlaces) {
  130. std::stringstream ss;
  131. double in = 0.0002517867, out = 0.0;
  132. value_binder<double> binder{};
  133. write(bind(in, binder), ss);
  134. EXPECT_NO_THROW(parse(bind(out, binder), ss.str().c_str(), allow_all));
  135. EXPECT_THAT(out, DoubleNear(in, 0.000001));
  136. }