json_binder_object_test.cxx 5.0 KB

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