| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- //
- // json_binder_object.t.h
- // json
- //
- // Created by Sam Jaffe on 2/27/17.
- //
- #pragma once
- #include <cxxtest/TestSuite.h>
- #include "json/json_binder.hpp"
- using namespace json::binder;
- using namespace json::parser;
- class json_binder_object_TestSuite : public CxxTest::TestSuite {
- public:
- using vec_t = std::vector<int>;
- using map_t = std::map<std::string, vec_t>;
- struct TestObject {
- int count;
- double average;
- std::map<std::string, std::vector<int>> data;
- bool operator==(TestObject const & other) const {
- return count == other.count && average == other.average && data == other.data;
- }
- };
-
- static object_binder<TestObject> GetImpl() {
- return object_binder<TestObject>()
- ("count", &TestObject::count)
- ("average", &TestObject::average)
- ("data", direct_binder<TestObject, map_t>(&TestObject::data));
- }
-
- static object_binder<TestObject> & Get() {
- static object_binder<TestObject> val = GetImpl();
- return val;
- }
-
- void test_construct_object_from_json() {
- 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}}} };
- TS_ASSERT_THROWS_NOTHING(parse(json::binder::bind(out, Get()), data, allow_all));
- TS_ASSERT_EQUALS(out, expected);
- }
-
- void test_permits_extra_keys() {
- 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}}} };
- TS_ASSERT_THROWS_NOTHING(parse(json::binder::bind(out, Get()), data, allow_all));
- TS_ASSERT_EQUALS(out, expected);
- }
-
- void test_throws_on_extra_keys_with_flag() {
- char data[] = "{ \"count\":10, \"average\":1.0, \"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, \"lemon\":true}";
- TestObject out = { 0, 0.0, {} };
- TS_ASSERT_THROWS(parse(json::binder::bind(out, Get()), data,
- disable_unknown_keys),
- json::malformed_json_exception);
- }
-
- void test_permits_missing_keys() {
- char data[] = "{ \"count\":10, \"average\":1.0 }";
- TestObject out = { 0, 0.0, {} };
- TestObject expected = { 10, 1.0, {} };
- TS_ASSERT_THROWS_NOTHING(parse(json::binder::bind(out, Get()), data, allow_all));
- TS_ASSERT_EQUALS(out, expected);
- }
- void test_throws_if_missing_keys_with_flag() {
- char data[] = "{ \"count\":10, \"average\":1.0 }";
- TestObject out = { 0, 0.0, {} };
- TS_ASSERT_THROWS(parse(json::binder::bind(out, Get()), data,
- disable_missing_keys),
- json::malformed_json_exception);
- }
-
- void test_throws_if_object_unstarted() {
- char data[] = "\"count\":10, \"average\":1.0, \"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] } }";
- TestObject out = { 0, 0.0, {} };
- TS_ASSERT_THROWS(parse(json::binder::bind(out, Get()), data, allow_all),
- json::malformed_json_exception);
- }
-
- void test_throws_if_object_missing_associative_token() {
- char data[] = "{ \"count\":10, \"average\":1.0, \"data\": }";
- TestObject out = { 0, 0.0, {} };
- TS_ASSERT_THROWS(parse(json::binder::bind(out, Get()), data, allow_all),
- json::malformed_json_exception);
- }
- void test_throws_if_object_unterminated() {
- char data[] = "{ \"count\":10, \"average\":1.0, \"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }";
- TestObject out = { 0, 0.0, {} };
- TS_ASSERT_THROWS(parse(json::binder::bind(out, Get()), data, allow_all),
- json::unterminated_json_exception);
- }
-
- void test_throws_if_object_missing_associative_token_discard_t() {
- char data[] = "{ \"count\":10, \"average\":1.0, \"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, \"lemon\":{\"key\": } }";
- TestObject out = { 0, 0.0, {} };
- TS_ASSERT_THROWS(parse(json::binder::bind(out, Get()), data, allow_all),
- json::malformed_json_exception);
- }
-
- void test_throws_if_object_unterminated_array_discard_t() {
- char data[] = "{ \"count\":10, \"average\":1.0, \"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, \"lemon\":[1.0 }";
- TestObject out = { 0, 0.0, {} };
- TS_ASSERT_THROWS(parse(json::binder::bind(out, Get()), data, allow_all),
- json::unterminated_json_exception);
- }
- void test_throws_if_object_unterminated_object_discard_t() {
- char data[] = "{ \"count\":10, \"average\":1.0, \"data\":{ \"key1\":[1, 2], \"key2\":[3, 4] }, \"lemon\":{\"key\":false }";
- TestObject out = { 0, 0.0, {} };
- TS_ASSERT_THROWS(parse(json::binder::bind(out, Get()), data, allow_all),
- json::unterminated_json_exception);
- }
-
- std::string ify(double value) {
- std::stringstream ss;
- ss << std::fixed << value;
- return ss.str();
- }
-
- void test_write_object_is_composed_of_correct_data() {
- std::string const dbl = ify(1.0);
- std::string const expected = "{\"average\":"+dbl+",\"count\":10,\"data\":{\"key1\":[1,2],\"key2\":[3,4]}}";
- std::stringstream ss;
- TestObject const in = { 10, 1.0, { { "key1", {1, 2} }, { "key2", {3, 4} } } };
- TS_ASSERT_THROWS_NOTHING(write(json::binder::bind(in, Get()), ss));
- TS_ASSERT_EQUALS(ss.str(), expected);
- }
- };
|