json_binder_value_double_test.cxx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. //
  2. // json_binder_value_double.t.h
  3. // json
  4. //
  5. // Created by Sam Jaffe on 2/25/17.
  6. //
  7. #include <gmock/gmock.h>
  8. #include "json/json_binder.hpp"
  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,
  44. disable_concatenated_json_bodies),
  45. json::malformed_json_exception);
  46. EXPECT_THAT(out, 5.0);
  47. }
  48. TEST(JsonBinderDoubleTest, OutputIsEssentiallyEqualDblMax) {
  49. char data[] = "1.79769e+308";
  50. double out = 0.0;
  51. value_binder<double> binder{};
  52. EXPECT_NO_THROW(parse(bind(out, binder), data, allow_all));
  53. EXPECT_THAT(out, DoubleNear(std::numeric_limits<double>::max(), 1E303));
  54. }
  55. TEST(JsonBinderDoubleTest, ThrowsOnOOBMax) {
  56. char data[] = "1.8e+308";
  57. double out = 0.0;
  58. value_binder<double> binder{};
  59. EXPECT_THROW(parse(bind(out, binder), data, allow_all),
  60. json::json_numeric_width_exception);
  61. }
  62. TEST(JsonBinderDoubleTest, OutputIsEssentiallyEqualDblLowest) {
  63. char data[] = "-1.79769e+308";
  64. double out = 0.0;
  65. value_binder<double> binder{};
  66. EXPECT_NO_THROW(parse(bind(out, binder), data, allow_all));
  67. EXPECT_THAT(out, DoubleNear(std::numeric_limits<double>::lowest(), 1E303));
  68. }
  69. TEST(JsonBinderDoubleTest, ThrowsOnOOBLowest) {
  70. char data[] = "-1.8e+308";
  71. double out = 0.0;
  72. value_binder<double> binder{};
  73. EXPECT_THROW(parse(bind(out, binder), data, allow_all),
  74. json::json_numeric_width_exception);
  75. }
  76. TEST(JsonBinderDoubleTest, OutputIsEssentiallyEqualDblMin) {
  77. char data[] = "2.22508e-308"; // 2.22507e-308 is min according to cppreference
  78. double out = 0.0;
  79. value_binder<double> binder{};
  80. EXPECT_NO_THROW(parse(bind(out, binder), data, allow_all));
  81. EXPECT_THAT(out, DoubleNear(std::numeric_limits<double>::min(), 1E-303));
  82. }
  83. TEST(JsonBinderDoubleTest, ThrowsOnOOBMin) {
  84. char data[] = "2e-308";
  85. double out = 0.0;
  86. value_binder<double> binder{};
  87. EXPECT_THROW(parse(bind(out, binder), data, allow_all),
  88. json::json_numeric_width_exception);
  89. }
  90. TEST(JsonBinderDoubleTest, ParseNoLossWithExactRep) {
  91. std::stringstream ss;
  92. double in = 500., out = 0;
  93. value_binder<double> binder{};
  94. write(bind(in, binder), ss);
  95. parse(bind(out, binder), ss.str().c_str(), allow_all);
  96. EXPECT_THAT(out, in);
  97. }
  98. TEST(JsonBinderDoubleTest, ParseNoLossWithInexactRep) {
  99. std::stringstream ss;
  100. double in = 0.3, out = 0;
  101. value_binder<double> binder{};
  102. write(bind(in, binder), ss);
  103. parse(bind(out, binder), ss.str().c_str(), allow_all);
  104. EXPECT_THAT(out, in);
  105. }
  106. TEST(JsonBinderDoubleTest, ParseNoLossWithLargeNumberSci) {
  107. std::stringstream ss;
  108. double in = 1.34e300, out = 0.0;
  109. value_binder<double> binder{};
  110. write(bind(in, binder), ss);
  111. parse(bind(out, binder), ss.str().c_str(), allow_all);
  112. EXPECT_THAT(out, in);
  113. }
  114. TEST(JsonBinderDoubleTest, ParseNoLossWithLargeNegativeNumberSci) {
  115. std::stringstream ss;
  116. double in = 1.34e-300, out = 0.0;
  117. value_binder<double> binder{};
  118. write(bind(in, binder), ss);
  119. parse(bind(out, binder), ss.str().c_str(), allow_all);
  120. EXPECT_THAT(out, DoubleNear(in, 1e-299));
  121. }
  122. TEST(JsonBinderDoubleTest, ParseNoLossWithLargeNumber) {
  123. std::stringstream ss;
  124. double in = 52450012.25, out = 0.0;
  125. value_binder<double> binder{};
  126. write(bind(in, binder), ss);
  127. parse(bind(out, binder), ss.str().c_str(), allow_all);
  128. EXPECT_THAT(out, in);
  129. }
  130. TEST(JsonBinderDoubleTest, ParseEssentiallyEqualAtSeveralDecimalPlaces) {
  131. std::stringstream ss;
  132. double in = 0.0002517867, out = 0.0;
  133. value_binder<double> binder{};
  134. write(bind(in, binder), ss);
  135. EXPECT_NO_THROW(parse(bind(out, binder), ss.str().c_str(), allow_all));
  136. EXPECT_THAT(out, DoubleNear(in, 0.000001));
  137. }