// // json_layout_test.cxx // logger_test // // Created by Sam Jaffe on 4/13/19. // #include #include "resource_factory/prototype_factory.hpp" #include "logger/detail/layout.h" #include "logger/log_manager.h" #include "logger/logpacket.h" #include "logger/properties.h" TEST(JsonLayoutTest, CanConstructWithNoConfig) { EXPECT_NO_THROW(logging::layouts::instance().get("JsonLayout", {})); } // Thursday, April 4, 2019 6:17:20 PM GMT namespace { constexpr const int NOW = 1554401840; } std::string const formatted_output = R"({ "instant": { "epochSecond": 1554401840, "nanoOfSecond": 123456000 }, "level": "warning", "loggerName": "UnitTest", "message": "This is a test message" })"; std::string const compact_output = "{\"instant\":{\"epochSecond\":" "1554401840,\"nanoOfSecond\":123456000},\"level\":\"warning\"," "\"loggerName\":\"UnitTest\",\"message\":\"This is a test message\"}"; TEST(JsonLayoutTest, LogsInformationInJSON) { using namespace logging; auto playout = layouts::instance().get("JsonLayout", {}); std::stringstream ss; playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest", "This is a test message"}); using testing::Eq; EXPECT_THAT(ss.str(), Eq(formatted_output)); } TEST(JsonLayoutTest, CompactMeansNoWhitespace) { using namespace logging; using namespace logging::property; properties const props{_obj({ {"compact", _v(true)} })}; auto playout = layouts::instance().get("JsonLayout", props); std::stringstream ss; playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest", "This is a test message"}); using testing::Eq; EXPECT_THAT(ss.str(), Eq(compact_output)); } TEST(JsonLayoutTest, EOLPropertyAppendsNewline) { using namespace logging; using namespace logging::property; properties const props{_obj({ {"eventEol", _v(true)} })}; auto playout = layouts::instance().get("JsonLayout", props); std::stringstream ss; playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest", "This is a test message"}); using testing::EndsWith; using testing::StartsWith; EXPECT_THAT(ss.str(), StartsWith(formatted_output)); EXPECT_THAT(ss.str(), EndsWith(logging::NEWLINE_TOKEN)); } std::string const struct_output = R"({ "instant": { "epochSecond": 1554401840, "nanoOfSecond": 123456000 }, "level": "warning", "loggerName": "UnitTest", "message": "{225}" })"; struct example { int content; }; std::ostream & operator<<(std::ostream & os, example const & ex) { return os << '{' << ex.content << '}'; } std::string const struct_json_output = R"({ "instant": { "epochSecond": 1554401840, "nanoOfSecond": 123456000 }, "level": "warning", "loggerName": "UnitTest", "message": { "content":225 } })"; struct json_example { int content; }; std::ostream & operator<<(std::ostream & os, json_example const & ex) { return os << '{' << ex.content << '}'; } TEST(JsonLayoutTest, MessageCanBeLoggedAsJSON) { using namespace logging; using namespace logging::property; properties const props{_obj({ {"objectMessageAsJsonObject", _v(true)} })}; auto playout = layouts::instance().get("JsonLayout", props); std::stringstream ss; json_example ex{225}; playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest", {"This is a test message", ex}}); using testing::Eq; EXPECT_THAT(ss.str(), Eq(struct_json_output)); } TEST(JsonLayoutTest, ObjectLackingJsonDefaultsToString) { using namespace logging; using namespace logging::property; properties const props{_obj({ {"objectMessageAsJsonObject", _v(true)} })}; auto playout = layouts::instance().get("JsonLayout", props); std::stringstream ss; example ex{225}; playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest", {"This is a test message", ex}}); using testing::Eq; EXPECT_THAT(ss.str(), Eq(struct_output)); }