// // pattern_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/exception.h" #include "logger/log_manager.h" #include "logger/logpacket.h" #include "logger/properties.h" // Thursday, April 4, 2019 6:17:20 PM GMT namespace { constexpr const int NOW = 1554401840; } std::shared_ptr GetPatternLayout(std::string const & fmt) { using namespace logging; using namespace logging::property; properties props{_obj({{"pattern", _v(fmt)}})}; return layouts::instance().get("PatternLayout", props); } std::string DoFormat(std::string const & fmt, logging::logpacket const & pkt) { std::stringstream ss; GetPatternLayout(fmt)->format(ss, pkt); return ss.str(); } using namespace logging; logpacket getpkt(std::string const & msg) { return logpacket{{}, level::error, {}, "UNIT_TEST", msg}; }; TEST(PatternLayoutTest, EmptyFormatterCanParse) { EXPECT_NO_THROW(GetPatternLayout("")); } TEST(PatternLayoutTest, ThrowsForEndOfStringAfterPct) { EXPECT_THROW(GetPatternLayout("%"), logging::format_parsing_exception); } TEST(PatternLayoutTest, RawStringFmtReturnsSelf) { using testing::Eq; EXPECT_THAT(DoFormat("TEST STRING", {}), Eq("TEST STRING")); } TEST(PatternLayoutTest, NCharReturnsNewLine) { using testing::Eq; EXPECT_THAT(DoFormat("%n", {}), Eq("\n")); } TEST(PatternLayoutTest, DoublePctIsLiteral) { using testing::Eq; EXPECT_THAT(DoFormat("%%", {}), Eq("%")); } TEST(PatternLayoutTest, CatchesRawContentBeforeFmt) { using testing::Eq; EXPECT_THAT(DoFormat("TEST%%", {}), Eq("TEST%")); } TEST(PatternLayoutTest, CatchesRawContentAfterFmt) { using testing::Eq; EXPECT_THAT(DoFormat("%%TEST", {}), Eq("%TEST")); } TEST(PatternLayoutTest, HandlesDateFormatter) { using testing::Eq; EXPECT_THAT(DoFormat("%d", {{NOW,0}}), Eq("2019-04-04 18:17:20,000")); } TEST(PatternLayoutTest, FormatsMilliseconds) { using testing::Eq; EXPECT_THAT(DoFormat("%d", {{NOW,123000}}), Eq("2019-04-04 18:17:20,123")); } TEST(PatternLayoutTest, ThrowsIfCustomFmtUnterminated) { using testing::Eq; EXPECT_THROW(GetPatternLayout("%d{%"), logging::format_parsing_exception); } TEST(PatternLayoutTest, SupportsCustomFormatWithBrace) { using testing::Eq; EXPECT_THAT(DoFormat("%d{%Y}", {{NOW,0}}), Eq("2019")); } TEST(PatternLayoutTest, FormatsCustomMilliseconds) { using testing::Eq; EXPECT_THAT(DoFormat("%d{%_ms}", {{NOW,123000}}), Eq("123")); } TEST(PatternLayoutTest, SupportsISO8601Format) { using testing::Eq; EXPECT_THAT(DoFormat("%d{ISO8601}", {{NOW,0}}), Eq("2019-04-04T18:17:20.000Z")); } TEST(PatternLayoutTest, SupportsSingleDayFormat) { using testing::Eq; EXPECT_THAT(DoFormat("%d{ABSOLUTE}", {{NOW,0}}), Eq("18:17:20,000")); } TEST(PatternLayoutTest, SupportsHumanDateFormat) { using testing::Eq; EXPECT_THAT(DoFormat("%d{DATE}", {{NOW,0}}), Eq("04 Apr 2019 18:17:20,000")); } TEST(PatternLayoutTest, LoggerIdIsCToken) { using testing::Eq; EXPECT_THAT(DoFormat("%c", getpkt("HELLO")), Eq("UNIT_TEST")); } TEST(PatternLayoutTest, LogLevelIsPToken) { using testing::Eq; EXPECT_THAT(DoFormat("%p", getpkt("HELLO")), Eq("ERROR")); } TEST(PatternLayoutTest, LogMessageIsMToken) { using testing::Eq; EXPECT_THAT(DoFormat("%m", getpkt("HELLO")), Eq("HELLO")); } TEST(PatternLayoutTest, ThrowsOnUnknownToken) { using testing::Eq; EXPECT_THROW(GetPatternLayout("%q"), logging::unknown_format_specifier); } TEST(PatternLayoutTest, TokenCanBeTruncatedInFormat) { using testing::Eq; EXPECT_THAT(DoFormat("%.3m", getpkt("HELLO")), Eq("HEL")); } TEST(PatternLayoutTest, TokenCanBeLeftPadded) { using testing::Eq; EXPECT_THAT(DoFormat("%6m", getpkt("HELLO")), Eq(" HELLO")); } TEST(PatternLayoutTest, TokenCanBeRightPadded) { using testing::Eq; EXPECT_THAT(DoFormat("%-6m", getpkt("HELLO")), Eq("HELLO ")); } TEST(PatternLayoutTest, TokenCanBeSizeBound) { using testing::Eq; EXPECT_THAT(DoFormat("%6.8m", getpkt("HELLO")), Eq(" HELLO")); EXPECT_THAT(DoFormat("%6.8m", getpkt("HELLO FRIEND")), Eq("HELLO FR")); }