json_binder_object_test.cxx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. //
  2. // json_binder_object.t.h
  3. // json
  4. //
  5. // Created by Sam Jaffe on 2/27/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 vec_t = std::vector<int>;
  12. using map_t = std::map<std::string, vec_t>;
  13. struct TestObject {
  14. int count;
  15. double average;
  16. map_t data;
  17. };
  18. bool operator==(TestObject const & lhs, TestObject const & rhs) {
  19. return lhs.count == rhs.count
  20. && lhs.average == rhs.average
  21. && lhs.data == rhs.data;
  22. }
  23. class JsonBinderObjectTest : public ::testing::Test {
  24. protected:
  25. static object_binder<TestObject> & GetBinder() {
  26. static object_binder<TestObject> val = object_binder<TestObject>()
  27. ("count", &TestObject::count)
  28. ("average", &TestObject::average)
  29. ("data", direct_binder<TestObject, map_t>(&TestObject::data));
  30. return val;
  31. }
  32. };
  33. TEST_F(JsonBinderObjectTest, ParsesSuccessfully) {
  34. char data[] = "{ \"count\":10, \"average\":1.0, "
  35. "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }}";
  36. TestObject out = { 0, 0.0, {} };
  37. TestObject expected = { 10, 1.0, {{"key1", {1, 2}},{"key2", {3, 4}}} };
  38. EXPECT_NO_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all));
  39. EXPECT_THAT(out, expected);
  40. }
  41. TEST_F(JsonBinderObjectTest, IgnoresUnknownKeysByDefault) {
  42. char data[] = "{ \"count\":10, \"average\":1.0, "
  43. "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, "
  44. "\"lemon\":true}";
  45. TestObject out = { 0, 0.0, {} };
  46. TestObject expected = { 10, 1.0, {{"key1", {1, 2}},{"key2", {3, 4}}} };
  47. EXPECT_NO_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all));
  48. EXPECT_THAT(out, expected);
  49. }
  50. TEST_F(JsonBinderObjectTest, ThrowsOnUnknownKeyWithSetting) {
  51. char data[] = "{ \"count\":10, \"average\":1.0, "
  52. "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, "
  53. "\"lemon\":true}";
  54. TestObject out = { 0, 0.0, {} };
  55. EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data,
  56. disable_unknown_keys),
  57. json::malformed_json_exception);
  58. }
  59. TEST_F(JsonBinderObjectTest, AllowsMissingExpectedKeysByDefault) {
  60. char data[] = "{ \"count\":10, \"average\":1.0 }";
  61. TestObject out = { 0, 0.0, {} };
  62. TestObject expected = { 10, 1.0, {} };
  63. EXPECT_NO_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all));
  64. EXPECT_THAT(out, expected);
  65. }
  66. TEST_F(JsonBinderObjectTest, ThrowsOnMissingExpectedKeyWithSetting) {
  67. char data[] = "{ \"count\":10, \"average\":1.0 }";
  68. TestObject out = { 0, 0.0, {} };
  69. EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data,
  70. disable_missing_keys),
  71. json::malformed_json_exception);
  72. }
  73. TEST_F(JsonBinderObjectTest, ThrowsOnMissingStartToken) {
  74. char data[] = "\"count\":10, \"average\":1.0, "
  75. "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] } }";
  76. TestObject out = { 0, 0.0, {} };
  77. EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
  78. json::malformed_json_exception);
  79. }
  80. TEST_F(JsonBinderObjectTest, ThrowsIfMissingValueForKey) {
  81. char data[] = "{ \"count\":10, \"average\":1.0, \"data\": }";
  82. TestObject out = { 0, 0.0, {} };
  83. EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
  84. json::malformed_json_exception);
  85. }
  86. TEST_F(JsonBinderObjectTest, ThrowsOnMissingEndToken) {
  87. char data[] = "{ \"count\":10, \"average\":1.0, "
  88. "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }";
  89. TestObject out = { 0, 0.0, {} };
  90. EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
  91. json::unterminated_json_exception);
  92. }
  93. TEST_F(JsonBinderObjectTest, ThrowsOnMissingValueForKeyEvenForUnknownKey) {
  94. char data[] = "{ \"count\":10, \"average\":1.0, "
  95. "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, "
  96. "\"lemon\":{\"key\": } }";
  97. TestObject out = { 0, 0.0, {} };
  98. EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
  99. json::malformed_json_exception);
  100. }
  101. TEST_F(JsonBinderObjectTest, ThrowsOnMissingEndTokenEvenForUnknownKey) {
  102. char data[] = "{ \"count\":10, \"average\":1.0, "
  103. "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, "
  104. "\"lemon\":[1.0 }";
  105. TestObject out = { 0, 0.0, {} };
  106. EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
  107. json::unterminated_json_exception);
  108. }
  109. TEST_F(JsonBinderObjectTest, ThrowsOnMissingEndTokenEvenForUnknownKey2) {
  110. char data[] = "{ \"count\":10, \"average\":1.0, "
  111. "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, "
  112. "\"lemon\":{\"key\":false }";
  113. TestObject out = { 0, 0.0, {} };
  114. EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
  115. json::unterminated_json_exception);
  116. }
  117. std::string ify(double value) {
  118. std::stringstream ss;
  119. ss << std::fixed << value;
  120. return ss.str();
  121. }
  122. TEST_F(JsonBinderObjectTest, WritesBackOriginalObject) {
  123. std::string const dbl = ify(1.0);
  124. std::string const expected = "{\"average\":1.000000,\"count\":10,"
  125. "\"data\":{\"key1\":[1,2],\"key2\":[3,4]}}";
  126. std::stringstream ss;
  127. TestObject const in = { 10, 1.0, { { "key1", {1, 2} }, { "key2", {3, 4} } } };
  128. EXPECT_NO_THROW(write(json::binder::bind(in, GetBinder()), ss));
  129. EXPECT_THAT(ss.str(), expected);
  130. }