| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- //
- // json_binder_object.t.h
- // json
- //
- // Created by Sam Jaffe on 2/27/17.
- //
- #include "json/json_binder.hpp"
- #include <gmock/gmock.h>
- using namespace json::binder;
- using namespace json::parser;
- using vec_t = std::vector<int>;
- using map_t = std::map<std::string, vec_t>;
- struct TestObject {
- int count;
- double average;
- map_t data;
- };
- bool operator==(TestObject const & lhs, TestObject const & rhs) {
- return lhs.count == rhs.count && lhs.average == rhs.average &&
- lhs.data == rhs.data;
- }
- class JsonBinderObjectTest : public ::testing::Test {
- protected:
- static object_binder<TestObject> & GetBinder() {
- static object_binder<TestObject> val = object_binder<TestObject>()(
- "count", &TestObject::count)("average", &TestObject::average)(
- "data", direct_binder<TestObject, map_t>(&TestObject::data));
- return val;
- }
- };
- TEST_F(JsonBinderObjectTest, ParsesSuccessfully) {
- char data[] = "{ \"count\":10, \"average\":1.0, "
- "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }}";
- TestObject out = {0, 0.0, {}};
- TestObject expected = {10, 1.0, {{"key1", {1, 2}}, {"key2", {3, 4}}}};
- EXPECT_NO_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all));
- EXPECT_THAT(out, expected);
- }
- TEST_F(JsonBinderObjectTest, IgnoresUnknownKeysByDefault) {
- char data[] = "{ \"count\":10, \"average\":1.0, "
- "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, "
- "\"lemon\":true}";
- TestObject out = {0, 0.0, {}};
- TestObject expected = {10, 1.0, {{"key1", {1, 2}}, {"key2", {3, 4}}}};
- EXPECT_NO_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all));
- EXPECT_THAT(out, expected);
- }
- TEST_F(JsonBinderObjectTest, ThrowsOnUnknownKeyWithSetting) {
- char data[] = "{ \"count\":10, \"average\":1.0, "
- "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, "
- "\"lemon\":true}";
- TestObject out = {0, 0.0, {}};
- EXPECT_THROW(
- parse(json::binder::bind(out, GetBinder()), data, disable_unknown_keys),
- json::malformed_json_exception);
- }
- TEST_F(JsonBinderObjectTest, AllowsMissingExpectedKeysByDefault) {
- char data[] = "{ \"count\":10, \"average\":1.0 }";
- TestObject out = {0, 0.0, {}};
- TestObject expected = {10, 1.0, {}};
- EXPECT_NO_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all));
- EXPECT_THAT(out, expected);
- }
- TEST_F(JsonBinderObjectTest, ThrowsOnMissingExpectedKeyWithSetting) {
- char data[] = "{ \"count\":10, \"average\":1.0 }";
- TestObject out = {0, 0.0, {}};
- EXPECT_THROW(
- parse(json::binder::bind(out, GetBinder()), data, disable_missing_keys),
- json::malformed_json_exception);
- }
- TEST_F(JsonBinderObjectTest, ThrowsMalformedObjectKey) {
- char data[] = "{ count\":10, \"average\":1.0 }";
- TestObject out = {0, 0.0, {}};
- EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
- json::malformed_json_exception);
- }
- TEST_F(JsonBinderObjectTest, ThrowsMalformedObjectAssoc) {
- char data[] = "{ \"count\"=10, \"average\":1.0 }";
- TestObject out = {0, 0.0, {}};
- EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
- json::malformed_json_exception);
- }
- TEST_F(JsonBinderObjectTest, ThrowsOnMissingStartToken) {
- char data[] = "\"count\":10, \"average\":1.0, "
- "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] } }";
- TestObject out = {0, 0.0, {}};
- EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
- json::malformed_json_exception);
- }
- TEST_F(JsonBinderObjectTest, ThrowsIfMissingValueForKey) {
- char data[] = "{ \"count\":10, \"average\":1.0, \"data\": }";
- TestObject out = {0, 0.0, {}};
- EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
- json::malformed_json_exception);
- }
- TEST_F(JsonBinderObjectTest, ThrowsOnMissingEndToken) {
- char data[] = "{ \"count\":10, \"average\":1.0, "
- "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }";
- TestObject out = {0, 0.0, {}};
- EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
- json::unterminated_json_exception);
- }
- TEST_F(JsonBinderObjectTest, ThrowsOnMissingValueForKeyEvenForUnknownKey) {
- char data[] = "{ \"count\":10, \"average\":1.0, "
- "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, "
- "\"lemon\":{\"key\": } }";
- TestObject out = {0, 0.0, {}};
- EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
- json::malformed_json_exception);
- }
- TEST_F(JsonBinderObjectTest, ThrowsOnMissingEndTokenEvenForUnknownKey) {
- char data[] = "{ \"count\":10, \"average\":1.0, "
- "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, "
- "\"lemon\":[1.0 }";
- TestObject out = {0, 0.0, {}};
- EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
- json::unterminated_json_exception);
- }
- TEST_F(JsonBinderObjectTest, ThrowsOnMissingEndTokenEvenForUnknownKey2) {
- char data[] = "{ \"count\":10, \"average\":1.0, "
- "\"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, "
- "\"lemon\":{\"key\":false }";
- TestObject out = {0, 0.0, {}};
- EXPECT_THROW(parse(json::binder::bind(out, GetBinder()), data, allow_all),
- json::unterminated_json_exception);
- }
- std::string ify(double value) {
- std::stringstream ss;
- ss << std::fixed << value;
- return ss.str();
- }
- TEST_F(JsonBinderObjectTest, WritesBackOriginalObject) {
- std::string const dbl = ify(1.0);
- std::string const expected = "{\"average\":1.000000,\"count\":10,"
- "\"data\":{\"key1\":[1,2],\"key2\":[3,4]}}";
- std::stringstream ss;
- TestObject const in = {10, 1.0, {{"key1", {1, 2}}, {"key2", {3, 4}}}};
- EXPECT_NO_THROW(write(json::binder::bind(in, GetBinder()), ss));
- EXPECT_THAT(ss.str(), expected);
- }
|