json/test/unit.cpp
2015-02-08 14:38:52 +01:00

897 lines
24 KiB
C++

#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "json.hpp"
using nlohmann::json;
#include <array>
#include <deque>
#include <forward_list>
#include <list>
#include <map>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
TEST_CASE("Constructors")
{
SECTION("create an empty value with a given type")
{
SECTION("null")
{
auto t = json::value_t::null;
json j(t);
CHECK(j.type() == t);
}
SECTION("object")
{
auto t = json::value_t::object;
json j(t);
CHECK(j.type() == t);
}
SECTION("array")
{
auto t = json::value_t::array;
json j(t);
CHECK(j.type() == t);
}
SECTION("boolean")
{
auto t = json::value_t::boolean;
json j(t);
CHECK(j.type() == t);
}
SECTION("string")
{
auto t = json::value_t::string;
json j(t);
CHECK(j.type() == t);
}
SECTION("number_integer")
{
auto t = json::value_t::number_integer;
json j(t);
CHECK(j.type() == t);
}
SECTION("number_float")
{
auto t = json::value_t::number_float;
json j(t);
CHECK(j.type() == t);
}
}
SECTION("create a null object (implicitly)")
{
SECTION("no parameter")
{
json j{};
CHECK(j.type() == json::value_t::null);
}
}
SECTION("create a null object (explicitly)")
{
SECTION("parameter")
{
json j(nullptr);
CHECK(j.type() == json::value_t::null);
}
}
SECTION("create an object (explicit)")
{
SECTION("empty object")
{
json::object_t o;
json j(o);
CHECK(j.type() == json::value_t::object);
}
SECTION("filled object")
{
json::object_t o {{"a", json(1)}, {"b", json(2.2)}, {"c", json(false)}, {"d", json("string")}, {"e", json()}};
json j(o);
CHECK(j.type() == json::value_t::object);
}
}
SECTION("create an object (implicit)")
{
// reference object
json::object_t o_reference {{"a", json(1)}, {"b", json(2.2)}, {"c", json(false)}, {"d", json("string")}, {"e", json()}};
json j_reference(o_reference);
SECTION("std::map<std::string, json>")
{
std::map<std::string, json> o {{"a", json(1)}, {"b", json(2.2)}, {"c", json(false)}, {"d", json("string")}, {"e", json()}};
json j(o);
CHECK(j.type() == json::value_t::object);
CHECK(j == j_reference);
}
SECTION("std::map<const char*, json>")
{
std::map<const char*, json> o {{"a", json(1)}, {"b", json(2.2)}, {"c", json(false)}, {"d", json("string")}, {"e", json()}};
json j(o);
CHECK(j.type() == json::value_t::object);
CHECK(j == j_reference);
}
SECTION("std::multimap<std::string, json>")
{
std::multimap<std::string, json> o {{"a", json(1)}, {"b", json(2.2)}, {"c", json(false)}, {"d", json("string")}, {"e", json()}};
json j(o);
CHECK(j.type() == json::value_t::object);
CHECK(j == j_reference);
}
SECTION("std::unordered_map<std::string, json>")
{
std::unordered_map<std::string, json> o {{"a", json(1)}, {"b", json(2.2)}, {"c", json(false)}, {"d", json("string")}, {"e", json()}};
json j(o);
CHECK(j.type() == json::value_t::object);
CHECK(j == j_reference);
}
SECTION("std::unordered_multimap<std::string, json>")
{
std::unordered_multimap<std::string, json> o {{"a", json(1)}, {"b", json(2.2)}, {"c", json(false)}, {"d", json("string")}, {"e", json()}};
json j(o);
CHECK(j.type() == json::value_t::object);
CHECK(j == j_reference);
}
SECTION("associative container literal")
{
json j({{"a", json(1)}, {"b", json(2.2)}, {"c", json(false)}, {"d", json("string")}, {"e", json()}});
CHECK(j.type() == json::value_t::object);
CHECK(j == j_reference);
}
}
SECTION("create an array (explicit)")
{
SECTION("empty array")
{
json::array_t a;
json j(a);
CHECK(j.type() == json::value_t::array);
}
SECTION("filled array")
{
json::array_t a {json(1), json(2.2), json(false), json("string"), json()};
json j(a);
CHECK(j.type() == json::value_t::array);
}
}
SECTION("create an array (implicit)")
{
// reference array
json::array_t a_reference {json(1), json(2.2), json(false), json("string"), json()};
json j_reference(a_reference);
SECTION("std::list<json>")
{
std::list<json> a {json(1), json(2.2), json(false), json("string"), json()};
json j(a);
CHECK(j.type() == json::value_t::array);
CHECK(j == j_reference);
}
SECTION("std::forward_list<json>")
{
std::forward_list<json> a {json(1), json(2.2), json(false), json("string"), json()};
json j(a);
CHECK(j.type() == json::value_t::array);
CHECK(j == j_reference);
}
SECTION("std::array<json>")
{
std::array<json, 5> a {{json(1), json(2.2), json(false), json("string"), json()}};
json j(a);
CHECK(j.type() == json::value_t::array);
CHECK(j == j_reference);
}
SECTION("std::vector<json>")
{
std::vector<json> a {json(1), json(2.2), json(false), json("string"), json()};
json j(a);
CHECK(j.type() == json::value_t::array);
CHECK(j == j_reference);
}
SECTION("std::deque<json>")
{
std::deque<json> a {json(1), json(2.2), json(false), json("string"), json()};
json j(a);
CHECK(j.type() == json::value_t::array);
CHECK(j == j_reference);
}
SECTION("std::set<json>")
{
std::set<json> a {json(1), json(2.2), json(false), json("string"), json()};
json j(a);
CHECK(j.type() == json::value_t::array);
// we cannot really check for equality here
}
SECTION("std::unordered_set<json>")
{
std::unordered_set<json> a {json(1), json(2.2), json(false), json("string"), json()};
json j(a);
CHECK(j.type() == json::value_t::array);
// we cannot really check for equality here
}
SECTION("sequence container literal")
{
json j({json(1), json(2.2), json(false), json("string"), json()});
CHECK(j.type() == json::value_t::array);
CHECK(j == j_reference);
}
}
SECTION("create a string (explicit)")
{
SECTION("empty string")
{
json::string_t s;
json j(s);
CHECK(j.type() == json::value_t::string);
}
SECTION("filled string")
{
json::string_t s {"Hello world"};
json j(s);
CHECK(j.type() == json::value_t::string);
}
}
SECTION("create a string (implicit)")
{
// reference string
json::string_t s_reference {"Hello world"};
json j_reference(s_reference);
SECTION("std::string")
{
std::string s {"Hello world"};
json j(s);
CHECK(j.type() == json::value_t::string);
CHECK(j == j_reference);
}
SECTION("char[]")
{
char s[] {"Hello world"};
json j(s);
CHECK(j.type() == json::value_t::string);
CHECK(j == j_reference);
}
SECTION("const char*")
{
const char* s {"Hello world"};
json j(s);
CHECK(j.type() == json::value_t::string);
CHECK(j == j_reference);
}
SECTION("string literal")
{
json j("Hello world");
CHECK(j.type() == json::value_t::string);
CHECK(j == j_reference);
}
}
SECTION("create a boolean (explicit)")
{
SECTION("empty boolean")
{
json::boolean_t b{};
json j(b);
CHECK(j.type() == json::value_t::boolean);
}
SECTION("filled boolean (true)")
{
json j(true);
CHECK(j.type() == json::value_t::boolean);
}
SECTION("filled boolean (false)")
{
json j(false);
CHECK(j.type() == json::value_t::boolean);
}
}
SECTION("create an integer number (explicit)")
{
SECTION("uninitialized value")
{
json::number_integer_t n{};
json j(n);
CHECK(j.type() == json::value_t::number_integer);
}
SECTION("initialized value")
{
json::number_integer_t n(42);
json j(n);
CHECK(j.type() == json::value_t::number_integer);
}
}
SECTION("create an integer number (implicit)")
{
// reference object
json::number_integer_t n_reference = 42;
json j_reference(n_reference);
SECTION("short")
{
short n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("unsigned short")
{
unsigned short n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int")
{
int n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("unsigned int")
{
unsigned int n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("long")
{
long n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("unsigned long")
{
short n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("long long")
{
long long n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("unsigned long long")
{
unsigned long long n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int8_t")
{
int8_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int16_t")
{
int16_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int32_t")
{
int32_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int64_t")
{
int64_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int_fast8_t")
{
int_fast8_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int_fast16_t")
{
int_fast16_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int_fast32_t")
{
int_fast32_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int_fast64_t")
{
int_fast64_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int_least8_t")
{
int_least8_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int_least16_t")
{
int_least16_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int_least32_t")
{
int_least32_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("int_least64_t")
{
int_least64_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("uint8_t")
{
uint8_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("uint16_t")
{
uint16_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("uint32_t")
{
uint32_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("uint64_t")
{
uint64_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("uint_fast8_t")
{
uint_fast8_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("uint_fast16_t")
{
uint_fast16_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("uint_fast32_t")
{
uint_fast32_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("uint_fast64_t")
{
uint_fast64_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("uint_least8_t")
{
uint_least8_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("uint_least16_t")
{
uint_least16_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("uint_least32_t")
{
uint_least32_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("uint_least64_t")
{
uint_least64_t n = 42;
json j(n);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("integer literal without suffix")
{
json j(42);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("integer literal with u suffix")
{
json j(42u);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("integer literal with l suffix")
{
json j(42l);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("integer literal with ul suffix")
{
json j(42ul);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("integer literal with ll suffix")
{
json j(42ll);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
SECTION("integer literal with ull suffix")
{
json j(42ull);
CHECK(j.type() == json::value_t::number_integer);
CHECK(j == j_reference);
}
}
SECTION("create a floating-point number (explicit)")
{
SECTION("uninitialized value")
{
json::number_float_t n{};
json j(n);
CHECK(j.type() == json::value_t::number_float);
}
SECTION("initialized value")
{
json::number_float_t n(42.23);
json j(n);
CHECK(j.type() == json::value_t::number_float);
}
}
SECTION("create a floating-point number (implicit)")
{
// reference object
json::number_float_t n_reference = 42.23;
json j_reference(n_reference);
SECTION("float")
{
float n = 42.23;
json j(n);
CHECK(j.type() == json::value_t::number_float);
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
}
SECTION("double")
{
double n = 42.23;
json j(n);
CHECK(j.type() == json::value_t::number_float);
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
}
SECTION("long double")
{
long double n = 42.23;
json j(n);
CHECK(j.type() == json::value_t::number_float);
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
}
SECTION("floating-point literal without suffix")
{
json j(42.23);
CHECK(j.type() == json::value_t::number_float);
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
}
SECTION("integer literal with f suffix")
{
json j(42.23f);
CHECK(j.type() == json::value_t::number_float);
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
}
SECTION("integer literal with l suffix")
{
json j(42.23l);
CHECK(j.type() == json::value_t::number_float);
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
}
}
SECTION("create a container (array or object) from an initializer list")
{
SECTION("empty initializer list")
{
SECTION("explicit")
{
std::initializer_list<json> l;
json j(l);
CHECK(j.type() == json::value_t::object);
}
SECTION("implicit")
{
json j {};
CHECK(j.type() == json::value_t::null);
}
}
SECTION("one element")
{
SECTION("array")
{
SECTION("explicit")
{
std::initializer_list<json> l = {json(json::array_t())};
json j(l);
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json j {json::array_t()};
CHECK(j.type() == json::value_t::array);
}
}
SECTION("object")
{
SECTION("explicit")
{
std::initializer_list<json> l = {json(json::object_t())};
json j(l);
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json j {json::object_t()};
CHECK(j.type() == json::value_t::array);
}
}
SECTION("string")
{
SECTION("explicit")
{
std::initializer_list<json> l = {json("Hello world")};
json j(l);
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json j {"Hello world"};
CHECK(j.type() == json::value_t::array);
}
}
SECTION("boolean")
{
SECTION("explicit")
{
std::initializer_list<json> l = {json(true)};
json j(l);
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json j {true};
CHECK(j.type() == json::value_t::array);
}
}
SECTION("number (integer)")
{
SECTION("explicit")
{
std::initializer_list<json> l = {json(1)};
json j(l);
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json j {1};
CHECK(j.type() == json::value_t::array);
}
}
SECTION("number (floating-point)")
{
SECTION("explicit")
{
std::initializer_list<json> l = {json(42.23)};
json j(l);
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json j {42.23};
CHECK(j.type() == json::value_t::array);
}
}
}
SECTION("more elements")
{
SECTION("explicit")
{
std::initializer_list<json> l = {1, 42.23, true, nullptr, json::object_t(), json::array_t()};
json j(l);
CHECK(j.type() == json::value_t::array);
}
SECTION("implicit")
{
json j {1, 42.23, true, nullptr, json::object_t(), json::array_t()};
CHECK(j.type() == json::value_t::array);
}
}
SECTION("implicit type deduction")
{
SECTION("object")
{
json j { {"one", 1}, {"two", 2.2}, {"three", false} };
CHECK(j.type() == json::value_t::object);
}
SECTION("array")
{
json j { {"one", 1}, {"two", 2.2}, {"three", false}, 13 };
CHECK(j.type() == json::value_t::array);
}
}
SECTION("explicit type deduction")
{
SECTION("empty object")
{
json j = json::object();
CHECK(j.type() == json::value_t::object);
}
SECTION("object")
{
json j = json::object({ {"one", 1}, {"two", 2.2}, {"three", false} });
CHECK(j.type() == json::value_t::object);
}
SECTION("object with error")
{
CHECK_THROWS_AS(json::object({ {"one", 1}, {"two", 2.2}, {"three", false}, 13 }), std::logic_error);
}
SECTION("empty array")
{
json j = json::array();
CHECK(j.type() == json::value_t::array);
}
SECTION("array")
{
json j = json::array({ {"one", 1}, {"two", 2.2}, {"three", false} });
CHECK(j.type() == json::value_t::array);
}
}
}
}