// Copyright (c) 2011, Thomas Goyne // // Permission to use, copy, modify, and 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. // // $Id$ /// @file libaegisub_cajun.cpp /// @brief Cajun/Json tests. /// @ingroup cajun #include "main.h" #include #include #include #include class lagi_cajun : public libagi { }; TEST(lagi_cajun, CastNonConst) { json::UnknownElement Integer = 0; json::UnknownElement Double = 0.0; json::UnknownElement String = "1"; json::UnknownElement Boolean = false; json::UnknownElement Array = json::Array(); json::UnknownElement Object = json::Object(); EXPECT_NO_THROW(static_cast(Integer)); EXPECT_NO_THROW(static_cast(Double)); EXPECT_NO_THROW(static_cast(String)); EXPECT_NO_THROW(static_cast(Boolean)); EXPECT_NO_THROW(static_cast(Array)); EXPECT_NO_THROW(static_cast(Object)); EXPECT_NO_THROW(static_cast(Integer)); EXPECT_NO_THROW(static_cast(Double)); EXPECT_NO_THROW(static_cast(String)); EXPECT_NO_THROW(static_cast(Boolean)); EXPECT_NO_THROW(static_cast(Array)); EXPECT_NO_THROW(static_cast(Object)); } TEST(lagi_cajun, CastConst) { const json::UnknownElement Integer = 10; const json::UnknownElement Double = 10.0; const json::UnknownElement String = "1"; const json::UnknownElement Boolean = false; const json::UnknownElement Array = json::Array(); const json::UnknownElement Object = json::Object(); /* these shouldn't compile EXPECT_NO_THROW(static_cast(Integer)); EXPECT_NO_THROW(static_cast(Double)); EXPECT_NO_THROW(static_cast(String)); EXPECT_NO_THROW(static_cast(Boolean)); EXPECT_NO_THROW(static_cast(Array)); EXPECT_NO_THROW(static_cast(Object)); */ EXPECT_NO_THROW(static_cast(Integer)); EXPECT_NO_THROW(static_cast(Double)); EXPECT_NO_THROW(static_cast(String)); EXPECT_NO_THROW(static_cast(Boolean)); EXPECT_NO_THROW(static_cast(Array)); EXPECT_NO_THROW(static_cast(Object)); EXPECT_EQ(10, static_cast(Integer)); EXPECT_EQ(10, static_cast(Double)); EXPECT_STREQ("1", static_cast(String).c_str()); EXPECT_FALSE(static_cast(Boolean)); EXPECT_TRUE(static_cast(Array).empty()); EXPECT_TRUE(static_cast(Object).empty()); } TEST(lagi_cajun, ObjectStoreInteger) { json::Object obj; obj["Integer"] = 1; EXPECT_EQ(1, static_cast(obj["Integer"])); EXPECT_THROW(static_cast(obj["Integer"]), json::Exception); EXPECT_THROW(static_cast(obj["Integer"]), json::Exception); EXPECT_THROW(static_cast(obj["Integer"]), json::Exception); EXPECT_THROW(static_cast(obj["Integer"]), json::Exception); EXPECT_THROW(static_cast(obj["Integer"]), json::Exception); } TEST(lagi_cajun, ObjectStoreDouble) { json::Object obj; obj["Double"] = 1.0; EXPECT_EQ(1.0, static_cast(obj["Double"])); EXPECT_THROW(static_cast(obj["Double"]), json::Exception); EXPECT_THROW(static_cast(obj["Double"]), json::Exception); EXPECT_THROW(static_cast(obj["Double"]), json::Exception); EXPECT_THROW(static_cast(obj["Double"]), json::Exception); EXPECT_THROW(static_cast(obj["Double"]), json::Exception); } TEST(lagi_cajun, ObjectStoreString) { json::Object obj; obj["String"] = "test"; EXPECT_STREQ("test", static_cast(obj["String"]).c_str()); EXPECT_THROW(static_cast(obj["String"]), json::Exception); EXPECT_THROW(static_cast(obj["String"]), json::Exception); EXPECT_THROW(static_cast(obj["String"]), json::Exception); EXPECT_THROW(static_cast(obj["String"]), json::Exception); EXPECT_THROW(static_cast(obj["String"]), json::Exception); } TEST(lagi_cajun, ObjectStoreBoolean) { json::Object obj; obj["Boolean"] = true; EXPECT_TRUE(static_cast(obj["Boolean"])); EXPECT_THROW(static_cast(obj["Boolean"]), json::Exception); EXPECT_THROW(static_cast(obj["Boolean"]), json::Exception); EXPECT_THROW(static_cast(obj["Boolean"]), json::Exception); EXPECT_THROW(static_cast(obj["Boolean"]), json::Exception); EXPECT_THROW(static_cast(obj["Boolean"]), json::Exception); } TEST(lagi_cajun, ObjectStoreNull) { json::Object obj; obj["Null"] = json::Null(); EXPECT_NO_THROW(static_cast(obj["Null"])); // null is implicitly convertible to everything EXPECT_NO_THROW(static_cast(obj["Null"])); obj["Null"] = json::Null(); EXPECT_NO_THROW(static_cast(obj["Null"])); obj["Null"] = json::Null(); EXPECT_NO_THROW(static_cast(obj["Null"])); obj["Null"] = json::Null(); EXPECT_NO_THROW(static_cast(obj["Null"])); obj["Null"] = json::Null(); EXPECT_NO_THROW(static_cast(obj["Null"])); obj["Null"] = json::Null(); EXPECT_NO_THROW(static_cast(obj["Null"])); // obj["Null"] should no longer be of type Null EXPECT_THROW(static_cast(obj["Null"]), json::Exception); } TEST(lagi_cajun, ObjectCreateArray) { json::Object obj; obj["Inside"] = ""; json::Array array; array.push_back(std::move(obj)); EXPECT_STREQ("", static_cast(static_cast(array[0])["Inside"]).c_str()); } TEST(lagi_cajun, Read) { json::UnknownElement root; std::istringstream doc("{\"String\" : \"This is a test\", \"Boolean\" : false, \"Null\" : null }"); EXPECT_NO_THROW(json::Reader::Read(root, doc)); json::Object& obj = root; EXPECT_NO_THROW(obj["String"]); EXPECT_STREQ("This is a test", static_cast(obj["String"]).c_str()); EXPECT_FALSE(static_cast(obj["Boolean"])); EXPECT_NO_THROW(static_cast(obj["Null"])); } TEST(lagi_cajun, Write) { json::Object obj; obj["Boolean"] = true; obj["String"] = "This \"is\" \\a \t test"; std::stringstream stream; EXPECT_NO_THROW(agi::JsonWriter::Write(obj, stream)); EXPECT_STREQ("{\n\t\"Boolean\" : true,\n\t\"String\" : \"This \\\"is\\\" \\\\a \\t test\"\n}", stream.str().c_str()); stream.str(""); EXPECT_NO_THROW(agi::JsonWriter::Write(json::Array(), stream)); EXPECT_STREQ("[]", stream.str().c_str()); stream.str(""); EXPECT_NO_THROW(agi::JsonWriter::Write(json::Object(), stream)); EXPECT_STREQ("{}", stream.str().c_str()); stream.str(""); EXPECT_NO_THROW(agi::JsonWriter::Write(true, stream)); EXPECT_STREQ("true", stream.str().c_str()); stream.str(""); EXPECT_NO_THROW(agi::JsonWriter::Write(false, stream)); EXPECT_STREQ("false", stream.str().c_str()); stream.str(""); EXPECT_NO_THROW(agi::JsonWriter::Write(json::Null(), stream)); EXPECT_STREQ("null", stream.str().c_str()); } TEST(lagi_cajun, ReaderParserErrors) { json::UnknownElement ue; std::istringstream missing_comma("[1 2]"); EXPECT_THROW(json::Reader::Read(ue, missing_comma), json::Exception); std::istringstream garbage_after_number("123!"); EXPECT_THROW(json::Reader::Read(ue, garbage_after_number), json::Exception); std::istringstream unexpected_eof("["); EXPECT_THROW(json::Reader::Read(ue, unexpected_eof), json::Exception); std::istringstream bad_initial_token("]"); EXPECT_THROW(json::Reader::Read(ue, bad_initial_token), json::Exception); std::istringstream garbage_after_end("[]a"); EXPECT_THROW(json::Reader::Read(ue, garbage_after_end), json::Exception); std::istringstream empty_str(""); EXPECT_THROW(json::Reader::Read(ue, empty_str), json::Exception); std::istringstream dupe_keys("{\"a\": [], \"a\": 0}"); EXPECT_THROW(json::Reader::Read(ue, dupe_keys), json::Exception); std::istringstream unique_keys("{\"a\": [], \"b\": 0}"); EXPECT_NO_THROW(json::Reader::Read(ue, unique_keys)); } TEST(lagi_cajun, ReaderScanErrors) { json::UnknownElement ue; std::istringstream doc("[true, false, thiswontwork]"); EXPECT_THROW(json::Reader::Read(ue, doc), json::Exception); std::istringstream garbage_after_number("123abc"); EXPECT_THROW(json::Reader::Read(ue, garbage_after_number), json::Exception); std::istringstream bad_escape("\"\\j\""); EXPECT_THROW(json::Reader::Read(ue, bad_escape), json::Exception); std::istringstream unexpected_eof("\"abc"); EXPECT_THROW(json::Reader::Read(ue, unexpected_eof), json::Exception); } std::string roundtrip_test(const char *in) { std::istringstream iss(in); json::UnknownElement ele; json::Reader::Read(ele, iss); std::stringstream oss; agi::JsonWriter::Write(ele, oss); return oss.str(); } TEST(lagi_cajun, round_double_roundtrips) { EXPECT_STREQ("1.0", roundtrip_test("1.0").c_str()); } TEST(lagi_cajun, representable_double_roundtrips) { EXPECT_STREQ("1.5", roundtrip_test("1.5").c_str()); } TEST(lagi_cajun, int_roundtrips) { EXPECT_STREQ("1", roundtrip_test("1").c_str()); } TEST(lagi_cajun, bool_roundtrips) { EXPECT_STREQ("true", roundtrip_test("true").c_str()); EXPECT_STREQ("false", roundtrip_test("false").c_str()); } TEST(lagi_cajun, null_roundtrips) { EXPECT_STREQ("null", roundtrip_test("null").c_str()); }