json_binder_custom_test.cxx 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. //
  2. // json_binder_custom.t.h
  3. // json
  4. //
  5. // Created by Sam Jaffe on 9/12/17.
  6. //
  7. #include <gmock/gmock.h>
  8. #include "json/json_binder.hpp"
  9. #include <iomanip>
  10. #include <cmath>
  11. using namespace json::binder;
  12. using namespace json::parser;
  13. class precision_binder : public binder_impl<double> {
  14. public:
  15. precision_binder(int d) : digits(d), trunc(std::pow(10, d)) {}
  16. virtual ~precision_binder() = default;
  17. binder_impl<double> * clone() const override {
  18. return new precision_binder{*this};
  19. }
  20. void parse(double & value, char const * & str, options) const override {
  21. std::sscanf(str, "%lf", &value);
  22. value = static_cast<long long>(value * trunc) / trunc;
  23. json::parse_discard_token(str); // Advance to the boundary
  24. }
  25. void write(double const & value, std::ostream & out) const override {
  26. out << std::fixed << std::setprecision(digits) << value;
  27. }
  28. private:
  29. int digits;
  30. double trunc;
  31. };
  32. struct CustomObject {
  33. double A; // four_digits
  34. double B; // two_digits
  35. double C;
  36. };
  37. bool operator==(CustomObject const & lhs, CustomObject const & rhs) {
  38. return lhs.A == rhs.A && lhs.B == rhs.B && lhs.C == rhs.C;
  39. }
  40. class JsonBinderCustomTest : public ::testing::Test {
  41. protected:
  42. static object_binder<CustomObject> & GetBinder() {
  43. static object_binder<CustomObject> val = object_binder<CustomObject>()
  44. ("A", &CustomObject::A, precision_binder(4))
  45. ("B", &CustomObject::B, precision_binder(2))
  46. ("C", &CustomObject::C);
  47. return val;
  48. }
  49. };
  50. TEST_F(JsonBinderCustomTest, CustomBindersWillParse) {
  51. char data[] = "{\"A\":1.00008, \"B\":1.0, \"C\":1.523211102}";
  52. CustomObject out{0.0, 0.0, 0.0};
  53. CustomObject const expected{1.0, 1.0, 1.523211102};
  54. EXPECT_NO_THROW(parse(json::binder::bind(out, GetBinder()), data));
  55. EXPECT_THAT(out, expected);
  56. }