json_binder_value_double.t.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. //
  2. // json_binder_value_double.t.h
  3. // json
  4. //
  5. // Created by Sam Jaffe on 2/25/17.
  6. //
  7. #pragma once
  8. #include <cxxtest/TestSuite.h>
  9. #include "json/json_binder.hpp"
  10. using namespace json::binder;
  11. using namespace json::parser;
  12. class json_binder_value_float_TestSuite : public CxxTest::TestSuite {
  13. public:
  14. void test_bind_to_double_type() {
  15. char data[] = "0.5";
  16. double out = 0.0;
  17. value_binder<double> binder{};
  18. parse(bind(out, binder), data, allow_all);
  19. TS_ASSERT_EQUALS(out, 0.5);
  20. }
  21. void test_parse_out_scientific_notation() {
  22. char data[] = "2e4";
  23. double out = 0.0;
  24. value_binder<double> binder{};
  25. TS_ASSERT_THROWS_NOTHING(parse(bind(out, binder), data, allow_all));
  26. }
  27. void test_parse_throws_on_no_data() {
  28. char data[] = "";
  29. double out = 0.0;
  30. value_binder<double> binder{};
  31. TS_ASSERT_THROWS(parse(bind(out, binder), data, allow_all),
  32. json::json_numeric_exception);
  33. }
  34. void test_parse_throws_on_non_numeric_data() {
  35. char data[] = "one half";
  36. double out = 0.0;
  37. value_binder<double> binder{};
  38. TS_ASSERT_THROWS(parse(bind(out, binder), data, allow_all),
  39. json::json_numeric_exception);
  40. }
  41. void test_parse_throws_on_incorrectly_terminated_data_with_flag() {
  42. char data[] = "5.0boo";
  43. double out = 0.0;
  44. value_binder<double> binder{};
  45. TS_ASSERT_THROWS(parse(bind(out, binder), data,
  46. disable_concatenated_json_bodies),
  47. json::malformed_json_exception);
  48. TS_ASSERT_EQUALS(out, 5.0);
  49. }
  50. void test_parses_double_max_scientific_within_five_decimal_places() {
  51. char data[] = "1.79769e+308";
  52. double out = 0.0;
  53. value_binder<double> binder{};
  54. TS_ASSERT_THROWS_NOTHING(parse(bind(out, binder), data, allow_all));
  55. TS_ASSERT_DELTA(out, std::numeric_limits<double>::max(), 1E303);
  56. }
  57. void test_throws_exception_on_number_out_of_range_max() {
  58. char data[] = "1.8e+308";
  59. double out = 0.0;
  60. value_binder<double> binder{};
  61. TS_ASSERT_THROWS(parse(bind(out, binder), data, allow_all),
  62. json::json_numeric_width_exception);
  63. }
  64. void test_parses_double_lowest_scientific_within_five_decimal_places() {
  65. char data[] = "-1.79769e+308";
  66. double out = 0.0;
  67. value_binder<double> binder{};
  68. TS_ASSERT_THROWS_NOTHING(parse(bind(out, binder), data, allow_all));
  69. TS_ASSERT_DELTA(out, std::numeric_limits<double>::lowest(), 1E303);
  70. }
  71. void test_throws_exception_on_number_out_of_range_lowest() {
  72. char data[] = "-1.8e+308";
  73. double out = 0.0;
  74. value_binder<double> binder{};
  75. TS_ASSERT_THROWS(parse(bind(out, binder), data, allow_all),
  76. json::json_numeric_width_exception);
  77. }
  78. void test_parses_double_min_scientific_within_five_decimal_places() {
  79. char data[] = "2.22508e-308"; // 2.22507e-308 is min according to cppreference
  80. double out = 0.0;
  81. value_binder<double> binder{};
  82. TS_ASSERT_THROWS_NOTHING(parse(bind(out, binder), data, allow_all));
  83. TS_ASSERT_DELTA(out, std::numeric_limits<double>::min(), 1E-303);
  84. }
  85. void test_throws_exception_on_number_out_of_range_min() {
  86. char data[] = "2e-308";
  87. double out = 0.0;
  88. value_binder<double> binder{};
  89. TS_ASSERT_THROWS(parse(bind(out, binder), data, allow_all),
  90. json::json_numeric_width_exception);
  91. }
  92. void test_double_number_written_is_equal_exact_binary() {
  93. std::stringstream ss;
  94. double in = 500., out = 0;
  95. value_binder<double> binder{};
  96. write(bind(in, binder), ss);
  97. parse(bind(out, binder), ss.str().c_str(), allow_all);
  98. TS_ASSERT_EQUALS(out, in);
  99. }
  100. void test_double_number_written_is_equal_inexact_binary() {
  101. std::stringstream ss;
  102. double in = 0.3, out = 0;
  103. value_binder<double> binder{};
  104. write(bind(in, binder), ss);
  105. parse(bind(out, binder), ss.str().c_str(), allow_all);
  106. TS_ASSERT_EQUALS(out, in);
  107. }
  108. void test_double_number_written_is_equal_at_high_absolute_value() {
  109. std::stringstream ss;
  110. double in = 1.34e300, out = 0.0;
  111. value_binder<double> binder{};
  112. write(bind(in, binder), ss);
  113. parse(bind(out, binder), ss.str().c_str(), allow_all);
  114. TS_ASSERT_EQUALS(out, in);
  115. }
  116. void test_double_number_written_is_equal_at_low_absolute_value() {
  117. std::stringstream ss;
  118. double in = 1.34e-300, out = 0.0;
  119. value_binder<double> binder{};
  120. write(bind(in, binder), ss);
  121. parse(bind(out, binder), ss.str().c_str(), allow_all);
  122. TS_ASSERT_DELTA(out, in, 1e-299);
  123. }
  124. void test_double_number_written_is_equal_at_high_absolute_value_nonscientific() {
  125. std::stringstream ss;
  126. double in = 52450012.25, out = 0.0;
  127. value_binder<double> binder{};
  128. write(bind(in, binder), ss);
  129. parse(bind(out, binder), ss.str().c_str(), allow_all);
  130. TS_ASSERT_EQUALS(out, in);
  131. }
  132. void test_double_number_written_is_equal_at_low_absolute_value_nonscientific() {
  133. std::stringstream ss;
  134. double in = 0.0002517867, out = 0.0;
  135. value_binder<double> binder{};
  136. write(bind(in, binder), ss);
  137. parse(bind(out, binder), ss.str().c_str(), allow_all);
  138. TS_ASSERT_DELTA(out, in, 0.000001);
  139. }
  140. };