json_layout_test.cxx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. //
  2. // json_layout_test.cxx
  3. // logger_test
  4. //
  5. // Created by Sam Jaffe on 4/13/19.
  6. //
  7. #include <gmock/gmock.h>
  8. #include "resource_factory/prototype_factory.hpp"
  9. #include "logger/detail/layout.h"
  10. #include "logger/log_manager.h"
  11. #include "logger/logpacket.h"
  12. #include "logger/properties.h"
  13. TEST(JsonLayoutTest, CanConstructWithNoConfig) {
  14. EXPECT_NO_THROW(logging::layouts::instance().get("JsonLayout", {}));
  15. }
  16. // Thursday, April 4, 2019 6:17:20 PM GMT
  17. namespace {
  18. constexpr const int NOW = 1554401840;
  19. }
  20. std::string const formatted_output = R"({
  21. "instant": {
  22. "epochSecond": 1554401840,
  23. "nanoOfSecond": 123456000
  24. },
  25. "level": "warning",
  26. "loggerName": "UnitTest",
  27. "message": "This is a test message"
  28. })";
  29. std::string const compact_output = "{\"instant\":{\"epochSecond\":"
  30. "1554401840,\"nanoOfSecond\":123456000},\"level\":\"warning\","
  31. "\"loggerName\":\"UnitTest\",\"message\":\"This is a test message\"}";
  32. TEST(JsonLayoutTest, LogsInformationInJSON) {
  33. using namespace logging;
  34. auto playout = layouts::instance().get("JsonLayout", {});
  35. std::stringstream ss;
  36. playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest",
  37. "This is a test message"});
  38. using testing::Eq;
  39. EXPECT_THAT(ss.str(), Eq(formatted_output));
  40. }
  41. TEST(JsonLayoutTest, CompactMeansNoWhitespace) {
  42. using namespace logging;
  43. using namespace logging::property;
  44. properties const props{_obj({
  45. {"compact", _v(true)}
  46. })};
  47. auto playout = layouts::instance().get("JsonLayout", props);
  48. std::stringstream ss;
  49. playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest",
  50. "This is a test message"});
  51. using testing::Eq;
  52. EXPECT_THAT(ss.str(), Eq(compact_output));
  53. }
  54. TEST(JsonLayoutTest, EOLPropertyAppendsNewline) {
  55. using namespace logging;
  56. using namespace logging::property;
  57. properties const props{_obj({
  58. {"eventEol", _v(true)}
  59. })};
  60. auto playout = layouts::instance().get("JsonLayout", props);
  61. std::stringstream ss;
  62. playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest",
  63. "This is a test message"});
  64. using testing::EndsWith;
  65. using testing::StartsWith;
  66. EXPECT_THAT(ss.str(), StartsWith(formatted_output));
  67. EXPECT_THAT(ss.str(), EndsWith(logging::NEWLINE_TOKEN));
  68. }
  69. std::string const struct_output = R"({
  70. "instant": {
  71. "epochSecond": 1554401840,
  72. "nanoOfSecond": 123456000
  73. },
  74. "level": "warning",
  75. "loggerName": "UnitTest",
  76. "message": "{225}"
  77. })";
  78. struct example {
  79. int content;
  80. };
  81. std::ostream & operator<<(std::ostream & os, example const & ex) {
  82. return os << '{' << ex.content << '}';
  83. }
  84. std::string const struct_json_output = R"({
  85. "instant": {
  86. "epochSecond": 1554401840,
  87. "nanoOfSecond": 123456000
  88. },
  89. "level": "warning",
  90. "loggerName": "UnitTest",
  91. "message": {
  92. "content":225
  93. }
  94. })";
  95. struct json_example {
  96. int content;
  97. };
  98. std::ostream & operator<<(std::ostream & os, json_example const & ex) {
  99. return os << '{' << ex.content << '}';
  100. }
  101. TEST(JsonLayoutTest, MessageCanBeLoggedAsJSON) {
  102. using namespace logging;
  103. using namespace logging::property;
  104. properties const props{_obj({
  105. {"objectMessageAsJsonObject", _v(true)}
  106. })};
  107. auto playout = layouts::instance().get("JsonLayout", props);
  108. std::stringstream ss;
  109. json_example ex{225};
  110. playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest",
  111. {"This is a test message", ex}});
  112. using testing::Eq;
  113. EXPECT_THAT(ss.str(), Eq(struct_json_output));
  114. }
  115. TEST(JsonLayoutTest, ObjectLackingJsonDefaultsToString) {
  116. using namespace logging;
  117. using namespace logging::property;
  118. properties const props{_obj({
  119. {"objectMessageAsJsonObject", _v(true)}
  120. })};
  121. auto playout = layouts::instance().get("JsonLayout", props);
  122. std::stringstream ss;
  123. example ex{225};
  124. playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest",
  125. {"This is a test message", ex}});
  126. using testing::Eq;
  127. EXPECT_THAT(ss.str(), Eq(struct_output));
  128. }