Mercurial > code
view C++/tests/Json/main.cpp @ 407:25ef13e25338
Json: remove undefined, not part of JSON spec
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 06 Oct 2015 09:05:53 +0200 |
parents | d485d36a8de1 |
children | ee155fc84c56 |
line wrap: on
line source
/* * main.cpp -- test the jansson wrapper * * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <set> #include <unordered_map> #include <gtest/gtest.h> #include "Json.h" /* -------------------------------------------------------- * Miscellaneous * -------------------------------------------------------- */ TEST(Misc, copy) { json::Object object; object.insert("integer", 123); object.insert("true", true); json::Object object2{object}; ASSERT_TRUE(object2.isObject()); ASSERT_EQ(123, object2["integer"].toInt()); ASSERT_TRUE(object2["true"].toBool()); } TEST(Misc, copyAssign) { json::Object object; { json::Object tmp; tmp.insert("integer", 123); tmp.insert("true", true); object = tmp; } ASSERT_TRUE(object.isObject()); ASSERT_EQ(123, object["integer"].toInt()); ASSERT_TRUE(object["true"].toBool()); } TEST(Misc, move) { json::Object object(123); json::Object object2(std::move(object)); ASSERT_TRUE(object2.isInt()); ASSERT_EQ(123, object2.toInt()); } TEST(Misc, moveAssign) { json::Object object(123); json::Object object2; object2 = std::move(object); ASSERT_TRUE(object2.isInt()); ASSERT_EQ(123, object2.toInt()); } /* -------------------------------------------------------- * json::Value constructors * -------------------------------------------------------- */ TEST(Constructors, null) { try { json::Value value{nullptr}; ASSERT_TRUE(value.isNull()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(Constructors, boolean) { try { json::Value value{true}; ASSERT_TRUE(value.isBool()); ASSERT_TRUE(value.toBool()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(Constructors, integer) { try { json::Value value{123}; ASSERT_TRUE(value.isInt()); ASSERT_TRUE(value.isNumber()); ASSERT_TRUE(value.isNumber()); ASSERT_EQ(123, value.toInt()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(Constructors, real) { try { json::Value value{9.2}; ASSERT_TRUE(value.isNumber()); ASSERT_TRUE(value.isNumber()); ASSERT_FALSE(value.isInt()); ASSERT_EQ(9.2, value.toReal()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(Constructors, string) { try { json::Value value("hello"); ASSERT_TRUE(value.isString()); ASSERT_EQ("hello", value.toString()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } /* -------------------------------------------------------- * Object * -------------------------------------------------------- */ TEST(Object, set) { try { json::Object object; object.insert("integer", 123); object.insert("string", "hello"); object.insert("true", true); ASSERT_EQ(123, object["integer"].toInt()); ASSERT_EQ("hello", object["string"].toString()); ASSERT_TRUE(object["true"].toBool()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(Object, clear) { try { json::Object object; object.insert("integer", 123); object.insert("string", "hello"); object.insert("true", true); object.clear(); ASSERT_EQ(0, static_cast<int>(object.size())); ASSERT_FALSE(object.contains("integer")); ASSERT_FALSE(object.contains("string")); ASSERT_FALSE(object.contains("true")); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(Object, erase) { try { json::Object object; object.insert("integer", 123); object.insert("string", "hello"); object.insert("true", true); object.erase("integer"); ASSERT_EQ(2, static_cast<int>(object.size())); ASSERT_FALSE(object.contains("integer")); ASSERT_TRUE(object.contains("string")); ASSERT_TRUE(object.contains("true")); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(ObjectInitializer, simple) { try { json::Object object{ { "username", "jean" }, { "age", 99 } }; ASSERT_EQ(2, static_cast<int>(object.size())); ASSERT_EQ("jean", object["username"].toString()); ASSERT_EQ(99, object["age"].toInt()); } catch (const std::exception &ex) { FAIL() << ex.what(); } } TEST(ObjectInitializer, deep) { try { json::Object object{ { "username", "jean" }, { "age", 99 }, { "network", json::Object{ { "port", 9999 }, { "host", "localhost" } } } }; // First ASSERT_EQ(3, static_cast<int>(object.size())); ASSERT_EQ("jean", object["username"].toString()); ASSERT_EQ(99, object["age"].toInt()); // Second json::Object network = object["network"].toObject(); ASSERT_TRUE(network.isObject()); ASSERT_EQ(2, static_cast<int>(network.size())); ASSERT_EQ(9999, network["port"].toInt()); ASSERT_EQ("localhost", network["host"].toString()); } catch (const std::exception &ex) { FAIL() << ex.what(); } } /* -------------------------------------------------------- * Array * -------------------------------------------------------- */ TEST(Array, push) { try { json::Array array; ASSERT_TRUE(array.isArray()); array.push(1); array.push("hello"); array.push(true); ASSERT_EQ(3, static_cast<int>(array.size())); ASSERT_TRUE(array[0].toBool()); ASSERT_EQ("hello", array[1].toString()); ASSERT_EQ(1, array[2].toInt()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(Array, append) { try { json::Array array; ASSERT_TRUE(array.isArray()); array.append(1); array.append("hello"); array.append(true); ASSERT_EQ(3, static_cast<int>(array.size())); ASSERT_EQ(1, array[0].toInt()); ASSERT_EQ("hello", array[1].toString()); ASSERT_TRUE(array[2].toBool()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(Array, insert) { try { json::Array array; ASSERT_TRUE(array.isArray()); array.insert(0, 1); array.insert(1, "hello"); array.insert(0, true); ASSERT_EQ(3, static_cast<int>(array.size())); ASSERT_TRUE(array[0].toBool()); ASSERT_EQ(1, array[1].toInt()); ASSERT_EQ("hello", array[2].toString()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(Array, clear) { try { json::Array array; array.append(1); array.append("hello"); array.append(true); array.clear(); ASSERT_EQ(0, static_cast<int>(array.size())); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(Array, erase) { try { json::Array array; array.append(1); array.append("hello"); array.append(true); array.erase(0); ASSERT_EQ(2, static_cast<int>(array.size())); ASSERT_EQ("hello", array[0].toString()); ASSERT_TRUE(array[1].toBool()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } #if 0 TEST(Array, eraseIterator) { try { json::Array array; array.append(1); array.append("hello"); array.append(true); array.erase(array.begin()); ASSERT_EQ(2, static_cast<int>(array.size())); ASSERT_EQ("hello", array[0].toString()); ASSERT_TRUE(array[1].toBool()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(Array, eraseConstIterator) { try { json::Array array; array.append(1); array.append("hello"); array.append(true); array.erase(array.cbegin()); ASSERT_EQ(2, static_cast<int>(array.size())); ASSERT_EQ("hello", array[0].toString()); ASSERT_TRUE(array[1].toBool()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } #endif TEST(ArrayInitializer, simple) { try { json::Array array{123, true, "hello"}; ASSERT_EQ(3, static_cast<int>(array.size())); ASSERT_EQ(123, array[0].toInt()); ASSERT_TRUE(array[1].toBool()); ASSERT_EQ("hello", array[2].toString()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(ArrayInitializer, deep) { try { json::Array array{ 123, true, "hello", json::Array{ 321, false, "olleh" } }; // First ASSERT_EQ(4, static_cast<int>(array.size())); ASSERT_EQ(123, array[0].toInt()); ASSERT_TRUE(array[1].toBool()); ASSERT_EQ("hello", array[2].toString()); // Second json::Array array2 = array[3].toArray(); ASSERT_TRUE(array.isArray()); ASSERT_EQ(3, static_cast<int>(array2.size())); ASSERT_EQ(321, array2[0].toInt()); ASSERT_FALSE(array2[1].toBool()); ASSERT_EQ("olleh", array2[2].toString()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } /* -------------------------------------------------------- * I/O * -------------------------------------------------------- */ TEST(FileRead, simple) { try { json::Document doc(json::File{"Json/simple.json"}); ASSERT_TRUE(doc.isObject()); ASSERT_FALSE(doc.isArray()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(FileRead, fail) { try { json::Document(json::File{"Json/notexist.json"}); FAIL() << "Exception expected"; } catch (const json::Error &) { } } #if 0 TEST(FileWrite, simple) { try { json::Object object{ { "name", "jean" }, { "age", 99 } }; object.write(std::ofstream("object-write.json")); json::Object object2 = json::Document(json::File("object-write.json")).toObject(); ASSERT_EQ(object2, object); } catch (const json::Error &ex) { FAIL() << ex.what(); } } #endif TEST(StringRead, simple) { try { json::Document doc(json::Buffer{"{ \"license\": \"ISC\" }"}); ASSERT_TRUE(doc.isObject()); ASSERT_FALSE(doc.isArray()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST(StringRead, fail) { try { json::Document(json::Buffer{"{ \"license\": ISC }"}); FAIL() << "Exception expected"; } catch (const json::Error &ex) { } } #if 0 TEST(StringWrite, simple) { try { json::Object object{ { "name", "jean" }, { "age", 99 } }; json::Object object2 = json::Document(object.dump()).toObject(); ASSERT_EQ(object2, object); } catch (const json::Error &ex) { FAIL() << ex.what(); } } #endif /* -------------------------------------------------------- * Object read * -------------------------------------------------------- */ class ObjectRead : public testing::Test { protected: json::Object m_object; json::Object m_objectAll; public: ObjectRead() { m_object = json::Document(json::File{"Json/object.json"}).toObject(); m_objectAll = json::Document(json::File{"Json/object-all.json"}).toObject(); } }; TEST_F(ObjectRead, simple) { try { json::Value name = m_object["name"]; json::Value description = m_object["description"]; ASSERT_TRUE(name.isString()); ASSERT_TRUE(description.isString()); ASSERT_EQ("simple", name.toString()); ASSERT_EQ("basic JSON file", description.toString()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST_F(ObjectRead, all) { try { ASSERT_TRUE(m_objectAll.contains("integer")); ASSERT_FALSE(m_objectAll.contains("unexistant")); ASSERT_TRUE(m_objectAll["integer"].isInt()); ASSERT_TRUE(m_objectAll["integer"].isNumber()); ASSERT_EQ(123, m_objectAll["integer"].toInt()); ASSERT_TRUE(m_objectAll["real"].isNumber()); ASSERT_TRUE(m_objectAll["real"].isNumber()); ASSERT_EQ(9.2, m_objectAll["real"].toReal()); ASSERT_TRUE(m_objectAll["false"].isBool()); ASSERT_FALSE(m_objectAll["false"].toBool()); ASSERT_FALSE(m_objectAll["false"].toBool()); ASSERT_TRUE(m_objectAll["true"].isBool()); ASSERT_TRUE(m_objectAll["true"].toBool()); ASSERT_TRUE(m_objectAll["true"].toBool()); ASSERT_TRUE(m_objectAll["null"].isNull()); ASSERT_TRUE(m_objectAll["object"].isObject()); ASSERT_TRUE(m_objectAll["array"].isArray()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } /* -------------------------------------------------------- * Array read * -------------------------------------------------------- */ class ArrayRead : public testing::Test { protected: json::Array m_array; json::Array m_arrayAll; public: ArrayRead() { m_array = json::Document(json::File{"Json/array.json"}).toArray(); m_arrayAll = json::Document(json::File{"Json/array-all.json"}).toArray(); } }; TEST_F(ArrayRead, simple) { try { ASSERT_EQ(3, static_cast<int>(m_array.size())); ASSERT_EQ(1, m_array[0].toInt()); ASSERT_EQ(2, m_array[1].toInt()); ASSERT_EQ(3, m_array[2].toInt()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } TEST_F(ArrayRead, all) { try { ASSERT_TRUE(m_arrayAll[0].isInt()); ASSERT_TRUE(m_arrayAll[0].isNumber()); ASSERT_EQ(123, m_arrayAll[0].toInt()); ASSERT_TRUE(m_arrayAll[1].isNumber()); ASSERT_TRUE(m_arrayAll[1].isNumber()); ASSERT_EQ(9.2, m_arrayAll[1].toReal()); ASSERT_TRUE(m_arrayAll[2].isBool()); ASSERT_FALSE(m_arrayAll[2].toBool()); ASSERT_FALSE(m_arrayAll[2].toBool()); ASSERT_TRUE(m_arrayAll[3].isBool()); ASSERT_TRUE(m_arrayAll[3].toBool()); ASSERT_TRUE(m_arrayAll[3].toBool()); ASSERT_TRUE(m_arrayAll[4].isNull()); ASSERT_TRUE(m_arrayAll[5].isObject()); ASSERT_TRUE(m_arrayAll[6].isArray()); } catch (const json::Error &ex) { FAIL() << ex.what(); } } /* -------------------------------------------------------- * Object iterators * -------------------------------------------------------- */ class ObjectIteratorsTest : public testing::Test { protected: json::Object m_object; public: ObjectIteratorsTest() { m_object.insert("integer", 1); m_object.insert("string", "hello"); m_object.insert("boolean", true); } }; TEST_F(ObjectIteratorsTest, operators) { // Read only (non const) { std::set<std::string> expected{"boolean", "integer", "string"}; std::set<std::string> result; std::unordered_map<std::string, json::Value> values; auto it = m_object.begin(); auto end = m_object.end(); while (it != end) { values.insert({it->first, it->second}); result.insert((*it++).first); } ASSERT_EQ(expected, result); ASSERT_EQ(1, values["integer"].toInt()); ASSERT_EQ("hello", values["string"].toString()); ASSERT_TRUE(values["boolean"].toBool()); } // Read only (const) { std::set<std::string> expected{"boolean", "integer", "string"}; std::set<std::string> result; std::unordered_map<std::string, json::Value> values; auto it = m_object.cbegin(); auto end = m_object.cend(); while (it != end) { values.insert({it->first, it->second}); result.insert((*it++).first); } ASSERT_EQ(expected, result); ASSERT_EQ(1, values["integer"].toInt()); ASSERT_EQ("hello", values["string"].toString()); ASSERT_TRUE(values["boolean"].toBool()); } } TEST_F(ObjectIteratorsTest, assign) { // Assign (non const) { auto it = m_object.begin(); auto key = it->first; it->second = json::Value("CHANGED"); ASSERT_EQ("CHANGED", m_object[key].toString()); ASSERT_EQ("CHANGED", it->second.toString()); ASSERT_EQ(3, static_cast<int>(m_object.size())); } } #if 0 TEST_F(ObjectIteratorsTest, assignConst) { // Assign (const) { auto it = m_object.cbegin(); auto key = it->first; auto orig = it->second; it->second = json::Value("CHANGED"); ASSERT_TRUE(m_object.contains(key)); ASSERT_EQ(orig, m_object[key]); ASSERT_EQ(3, static_cast<int>(m_object.size())); } } #endif /* -------------------------------------------------------- * Array iterators * -------------------------------------------------------- */ class ArrayIteratorsTest : public testing::Test { protected: json::Array m_array; public: ArrayIteratorsTest() { m_array.append(1); m_array.append("hello"); m_array.append(true); } }; TEST_F(ArrayIteratorsTest, operators) { // Read only (non const) { auto it = m_array.begin(); ASSERT_EQ(1, (*it).toInt()); ASSERT_EQ(1, it->toInt()); ASSERT_EQ("hello", it[1].toString()); ASSERT_TRUE(it[2].toBool()); auto it2 = it + 1; ASSERT_EQ(1, it2[-1].toInt()); ASSERT_EQ("hello", it2->toString()); ASSERT_TRUE(it2[1].toBool()); auto it3 = it; ASSERT_TRUE(it2 != it); ASSERT_FALSE(it3 != it); ASSERT_FALSE(it2 == it); ASSERT_TRUE(it3 == it); ASSERT_TRUE(it3 >= it); ASSERT_TRUE(it2 >= it); ASSERT_TRUE(it2 > it); ASSERT_FALSE(it3 > it); ASSERT_FALSE(it2 <= it); ASSERT_TRUE(it3 <= it); ASSERT_FALSE(it2 < it); ASSERT_FALSE(it3 < it); } // Read only (const) { auto it = m_array.cbegin(); ASSERT_EQ(1, (*it).toInt()); ASSERT_EQ(1, it->toInt()); ASSERT_EQ("hello", it[1].toString()); ASSERT_TRUE(it[2].toBool()); auto it2 = it + 1; ASSERT_EQ(1, it2[-1].toInt()); ASSERT_EQ("hello", it2->toString()); ASSERT_TRUE(it2[1].toBool()); auto it3 = it; ASSERT_TRUE(it2 != it); ASSERT_FALSE(it3 != it); ASSERT_FALSE(it2 == it); ASSERT_TRUE(it3 == it); ASSERT_TRUE(it3 >= it); ASSERT_TRUE(it2 >= it); ASSERT_TRUE(it2 > it); ASSERT_FALSE(it3 > it); ASSERT_FALSE(it2 <= it); ASSERT_TRUE(it3 <= it); ASSERT_FALSE(it2 < it); ASSERT_FALSE(it3 < it); } } TEST_F(ArrayIteratorsTest, assign) { // Assign (non const) { auto it = m_array.begin(); *it = json::Value(9999); ASSERT_EQ(3, static_cast<int>(m_array.size())); ASSERT_EQ(9999, it->toInt()); ASSERT_EQ(9999, m_array[0].toInt()); } } #if 0 TEST_F(ArrayIteratorsTest, assignConst) { // Assign (const) { auto it = m_array.cbegin(); *it = json::Value(9999); ASSERT_EQ(3, static_cast<int>(m_array.size())); ASSERT_EQ(1, it->toInt()); ASSERT_EQ(1, m_array[0].toInt()); } } #endif TEST_F(ArrayIteratorsTest, castToRef) { json::Array array{1, 2, 3}; int i = 1; for (const json::Value &v : array) { ASSERT_EQ(i++, v.toInt()); } } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }