|
|
@@ -0,0 +1,122 @@
|
|
|
+//
|
|
|
+// json_binder_object.t.h
|
|
|
+// json
|
|
|
+//
|
|
|
+// Created by Sam Jaffe on 2/27/17.
|
|
|
+//
|
|
|
+
|
|
|
+#pragma once
|
|
|
+
|
|
|
+#include <cxxtest/TestSuite.h>
|
|
|
+#include "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);
|
|
|
+ }
|
|
|
+};
|