1 | #include "includes.h" |
2 | #include "test_sink.h" |
3 | |
4 | using spdlog::memory_buf_t; |
5 | using spdlog::details::to_string_view; |
6 | |
7 | // log to str and return it |
8 | template<typename... Args> |
9 | static std::string log_to_str(const std::string &msg, const Args &... args) |
10 | { |
11 | std::ostringstream oss; |
12 | auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss); |
13 | spdlog::logger oss_logger("pattern_tester" , oss_sink); |
14 | oss_logger.set_level(spdlog::level::info); |
15 | |
16 | oss_logger.set_formatter(std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(args...))); |
17 | |
18 | oss_logger.info(msg); |
19 | return oss.str(); |
20 | } |
21 | |
22 | TEST_CASE("custom eol" , "[pattern_formatter]" ) |
23 | { |
24 | std::string msg = "Hello custom eol test" ; |
25 | std::string eol = ";)" ; |
26 | REQUIRE(log_to_str(msg, "%v" , spdlog::pattern_time_type::local, ";)" ) == msg + eol); |
27 | } |
28 | |
29 | TEST_CASE("empty format" , "[pattern_formatter]" ) |
30 | { |
31 | REQUIRE(log_to_str("Some message" , "" , spdlog::pattern_time_type::local, "" ).empty()); |
32 | } |
33 | |
34 | TEST_CASE("empty format2" , "[pattern_formatter]" ) |
35 | { |
36 | REQUIRE(log_to_str("Some message" , "" , spdlog::pattern_time_type::local, "\n" ) == "\n" ); |
37 | } |
38 | |
39 | TEST_CASE("level" , "[pattern_formatter]" ) |
40 | { |
41 | REQUIRE(log_to_str("Some message" , "[%l] %v" , spdlog::pattern_time_type::local, "\n" ) == "[info] Some message\n" ); |
42 | } |
43 | |
44 | TEST_CASE("short level" , "[pattern_formatter]" ) |
45 | { |
46 | REQUIRE(log_to_str("Some message" , "[%L] %v" , spdlog::pattern_time_type::local, "\n" ) == "[I] Some message\n" ); |
47 | } |
48 | |
49 | TEST_CASE("name" , "[pattern_formatter]" ) |
50 | { |
51 | REQUIRE(log_to_str("Some message" , "[%n] %v" , spdlog::pattern_time_type::local, "\n" ) == "[pattern_tester] Some message\n" ); |
52 | } |
53 | |
54 | TEST_CASE("date MM/DD/YY " , "[pattern_formatter]" ) |
55 | { |
56 | auto now_tm = spdlog::details::os::localtime(); |
57 | std::stringstream oss; |
58 | oss << std::setfill('0') << std::setw(2) << now_tm.tm_mon + 1 << "/" << std::setw(2) << now_tm.tm_mday << "/" << std::setw(2) |
59 | << (now_tm.tm_year + 1900) % 1000 << " Some message\n" ; |
60 | REQUIRE(log_to_str("Some message" , "%D %v" , spdlog::pattern_time_type::local, "\n" ) == oss.str()); |
61 | } |
62 | |
63 | TEST_CASE("color range test1" , "[pattern_formatter]" ) |
64 | { |
65 | auto formatter = std::make_shared<spdlog::pattern_formatter>("%^%v%$" , spdlog::pattern_time_type::local, "\n" ); |
66 | |
67 | memory_buf_t buf; |
68 | spdlog::fmt_lib::format_to(std::back_inserter(buf), "Hello" ); |
69 | memory_buf_t formatted; |
70 | std::string logger_name = "test" ; |
71 | spdlog::details::log_msg msg(logger_name, spdlog::level::info, spdlog::string_view_t(buf.data(), buf.size())); |
72 | formatter->format(msg, formatted); |
73 | REQUIRE(msg.color_range_start == 0); |
74 | REQUIRE(msg.color_range_end == 5); |
75 | REQUIRE(log_to_str("hello" , "%^%v%$" , spdlog::pattern_time_type::local, "\n" ) == "hello\n" ); |
76 | } |
77 | |
78 | TEST_CASE("color range test2" , "[pattern_formatter]" ) |
79 | { |
80 | auto formatter = std::make_shared<spdlog::pattern_formatter>("%^%$" , spdlog::pattern_time_type::local, "\n" ); |
81 | std::string logger_name = "test" ; |
82 | spdlog::details::log_msg msg(logger_name, spdlog::level::info, "" ); |
83 | memory_buf_t formatted; |
84 | formatter->format(msg, formatted); |
85 | REQUIRE(msg.color_range_start == 0); |
86 | REQUIRE(msg.color_range_end == 0); |
87 | REQUIRE(log_to_str("" , "%^%$" , spdlog::pattern_time_type::local, "\n" ) == "\n" ); |
88 | } |
89 | |
90 | TEST_CASE("color range test3" , "[pattern_formatter]" ) |
91 | { |
92 | auto formatter = std::make_shared<spdlog::pattern_formatter>("%^***%$" ); |
93 | std::string logger_name = "test" ; |
94 | spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored" ); |
95 | memory_buf_t formatted; |
96 | formatter->format(msg, formatted); |
97 | REQUIRE(msg.color_range_start == 0); |
98 | REQUIRE(msg.color_range_end == 3); |
99 | } |
100 | |
101 | TEST_CASE("color range test4" , "[pattern_formatter]" ) |
102 | { |
103 | auto formatter = std::make_shared<spdlog::pattern_formatter>("XX%^YYY%$" , spdlog::pattern_time_type::local, "\n" ); |
104 | std::string logger_name = "test" ; |
105 | spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored" ); |
106 | |
107 | memory_buf_t formatted; |
108 | formatter->format(msg, formatted); |
109 | REQUIRE(msg.color_range_start == 2); |
110 | REQUIRE(msg.color_range_end == 5); |
111 | REQUIRE(log_to_str("ignored" , "XX%^YYY%$" , spdlog::pattern_time_type::local, "\n" ) == "XXYYY\n" ); |
112 | } |
113 | |
114 | TEST_CASE("color range test5" , "[pattern_formatter]" ) |
115 | { |
116 | auto formatter = std::make_shared<spdlog::pattern_formatter>("**%^" ); |
117 | std::string logger_name = "test" ; |
118 | spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored" ); |
119 | memory_buf_t formatted; |
120 | formatter->format(msg, formatted); |
121 | REQUIRE(msg.color_range_start == 2); |
122 | REQUIRE(msg.color_range_end == 0); |
123 | } |
124 | |
125 | TEST_CASE("color range test6" , "[pattern_formatter]" ) |
126 | { |
127 | auto formatter = std::make_shared<spdlog::pattern_formatter>("**%$" ); |
128 | std::string logger_name = "test" ; |
129 | spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored" ); |
130 | memory_buf_t formatted; |
131 | formatter->format(msg, formatted); |
132 | REQUIRE(msg.color_range_start == 0); |
133 | REQUIRE(msg.color_range_end == 2); |
134 | } |
135 | |
136 | // |
137 | // Test padding |
138 | // |
139 | |
140 | TEST_CASE("level_left_padded" , "[pattern_formatter]" ) |
141 | { |
142 | REQUIRE(log_to_str("Some message" , "[%8l] %v" , spdlog::pattern_time_type::local, "\n" ) == "[ info] Some message\n" ); |
143 | REQUIRE(log_to_str("Some message" , "[%8!l] %v" , spdlog::pattern_time_type::local, "\n" ) == "[ info] Some message\n" ); |
144 | } |
145 | |
146 | TEST_CASE("level_right_padded" , "[pattern_formatter]" ) |
147 | { |
148 | REQUIRE(log_to_str("Some message" , "[%-8l] %v" , spdlog::pattern_time_type::local, "\n" ) == "[info ] Some message\n" ); |
149 | REQUIRE(log_to_str("Some message" , "[%-8!l] %v" , spdlog::pattern_time_type::local, "\n" ) == "[info ] Some message\n" ); |
150 | } |
151 | |
152 | TEST_CASE("level_center_padded" , "[pattern_formatter]" ) |
153 | { |
154 | REQUIRE(log_to_str("Some message" , "[%=8l] %v" , spdlog::pattern_time_type::local, "\n" ) == "[ info ] Some message\n" ); |
155 | REQUIRE(log_to_str("Some message" , "[%=8!l] %v" , spdlog::pattern_time_type::local, "\n" ) == "[ info ] Some message\n" ); |
156 | } |
157 | |
158 | TEST_CASE("short level_left_padded" , "[pattern_formatter]" ) |
159 | { |
160 | REQUIRE(log_to_str("Some message" , "[%3L] %v" , spdlog::pattern_time_type::local, "\n" ) == "[ I] Some message\n" ); |
161 | REQUIRE(log_to_str("Some message" , "[%3!L] %v" , spdlog::pattern_time_type::local, "\n" ) == "[ I] Some message\n" ); |
162 | } |
163 | |
164 | TEST_CASE("short level_right_padded" , "[pattern_formatter]" ) |
165 | { |
166 | REQUIRE(log_to_str("Some message" , "[%-3L] %v" , spdlog::pattern_time_type::local, "\n" ) == "[I ] Some message\n" ); |
167 | REQUIRE(log_to_str("Some message" , "[%-3!L] %v" , spdlog::pattern_time_type::local, "\n" ) == "[I ] Some message\n" ); |
168 | } |
169 | |
170 | TEST_CASE("short level_center_padded" , "[pattern_formatter]" ) |
171 | { |
172 | REQUIRE(log_to_str("Some message" , "[%=3L] %v" , spdlog::pattern_time_type::local, "\n" ) == "[ I ] Some message\n" ); |
173 | REQUIRE(log_to_str("Some message" , "[%=3!L] %v" , spdlog::pattern_time_type::local, "\n" ) == "[ I ] Some message\n" ); |
174 | } |
175 | |
176 | TEST_CASE("left_padded_short" , "[pattern_formatter]" ) |
177 | { |
178 | REQUIRE(log_to_str("Some message" , "[%3n] %v" , spdlog::pattern_time_type::local, "\n" ) == "[pattern_tester] Some message\n" ); |
179 | REQUIRE(log_to_str("Some message" , "[%3!n] %v" , spdlog::pattern_time_type::local, "\n" ) == "[pat] Some message\n" ); |
180 | } |
181 | |
182 | TEST_CASE("right_padded_short" , "[pattern_formatter]" ) |
183 | { |
184 | REQUIRE(log_to_str("Some message" , "[%-3n] %v" , spdlog::pattern_time_type::local, "\n" ) == "[pattern_tester] Some message\n" ); |
185 | REQUIRE(log_to_str("Some message" , "[%-3!n] %v" , spdlog::pattern_time_type::local, "\n" ) == "[pat] Some message\n" ); |
186 | } |
187 | |
188 | TEST_CASE("center_padded_short" , "[pattern_formatter]" ) |
189 | { |
190 | REQUIRE(log_to_str("Some message" , "[%=3n] %v" , spdlog::pattern_time_type::local, "\n" ) == "[pattern_tester] Some message\n" ); |
191 | REQUIRE(log_to_str("Some message" , "[%=3!n] %v" , spdlog::pattern_time_type::local, "\n" ) == "[pat] Some message\n" ); |
192 | } |
193 | |
194 | TEST_CASE("left_padded_huge" , "[pattern_formatter]" ) |
195 | { |
196 | REQUIRE(log_to_str("Some message" , "[%-300n] %v" , spdlog::pattern_time_type::local, "\n" ) == |
197 | "[pattern_tester ] Some message\n" ); |
198 | |
199 | REQUIRE(log_to_str("Some message" , "[%-300!n] %v" , spdlog::pattern_time_type::local, "\n" ) == |
200 | "[pattern_tester ] Some message\n" ); |
201 | } |
202 | |
203 | TEST_CASE("left_padded_max" , "[pattern_formatter]" ) |
204 | { |
205 | REQUIRE(log_to_str("Some message" , "[%-64n] %v" , spdlog::pattern_time_type::local, "\n" ) == |
206 | "[pattern_tester ] Some message\n" ); |
207 | |
208 | REQUIRE(log_to_str("Some message" , "[%-64!n] %v" , spdlog::pattern_time_type::local, "\n" ) == |
209 | "[pattern_tester ] Some message\n" ); |
210 | } |
211 | |
212 | // Test padding + truncate flag |
213 | |
214 | TEST_CASE("paddinng_truncate" , "[pattern_formatter]" ) |
215 | { |
216 | REQUIRE(log_to_str("123456" , "%6!v" , spdlog::pattern_time_type::local, "\n" ) == "123456\n" ); |
217 | REQUIRE(log_to_str("123456" , "%5!v" , spdlog::pattern_time_type::local, "\n" ) == "12345\n" ); |
218 | REQUIRE(log_to_str("123456" , "%7!v" , spdlog::pattern_time_type::local, "\n" ) == " 123456\n" ); |
219 | |
220 | REQUIRE(log_to_str("123456" , "%-6!v" , spdlog::pattern_time_type::local, "\n" ) == "123456\n" ); |
221 | REQUIRE(log_to_str("123456" , "%-5!v" , spdlog::pattern_time_type::local, "\n" ) == "12345\n" ); |
222 | REQUIRE(log_to_str("123456" , "%-7!v" , spdlog::pattern_time_type::local, "\n" ) == "123456 \n" ); |
223 | |
224 | REQUIRE(log_to_str("123456" , "%=6!v" , spdlog::pattern_time_type::local, "\n" ) == "123456\n" ); |
225 | REQUIRE(log_to_str("123456" , "%=5!v" , spdlog::pattern_time_type::local, "\n" ) == "12345\n" ); |
226 | REQUIRE(log_to_str("123456" , "%=7!v" , spdlog::pattern_time_type::local, "\n" ) == "123456 \n" ); |
227 | |
228 | REQUIRE(log_to_str("123456" , "%0!v" , spdlog::pattern_time_type::local, "\n" ) == "\n" ); |
229 | } |
230 | |
231 | TEST_CASE("padding_truncate_funcname" , "[pattern_formatter]" ) |
232 | { |
233 | spdlog::sinks::test_sink_st test_sink; |
234 | |
235 | const char *pattern = "%v [%5!!]" ; |
236 | auto formatter = std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(pattern)); |
237 | test_sink.set_formatter(std::move(formatter)); |
238 | |
239 | spdlog::details::log_msg msg1{spdlog::source_loc{"ignored" , 1, "func" }, "test_logger" , spdlog::level::info, "message" }; |
240 | test_sink.log(msg1); |
241 | REQUIRE(test_sink.lines()[0] == "message [ func]" ); |
242 | |
243 | spdlog::details::log_msg msg2{spdlog::source_loc{"ignored" , 1, "function" }, "test_logger" , spdlog::level::info, "message" }; |
244 | test_sink.log(msg2); |
245 | REQUIRE(test_sink.lines()[1] == "message [funct]" ); |
246 | } |
247 | |
248 | TEST_CASE("padding_funcname" , "[pattern_formatter]" ) |
249 | { |
250 | spdlog::sinks::test_sink_st test_sink; |
251 | |
252 | const char *pattern = "%v [%10!]" ; |
253 | auto formatter = std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(pattern)); |
254 | test_sink.set_formatter(std::move(formatter)); |
255 | |
256 | spdlog::details::log_msg msg1{spdlog::source_loc{"ignored" , 1, "func" }, "test_logger" , spdlog::level::info, "message" }; |
257 | test_sink.log(msg1); |
258 | REQUIRE(test_sink.lines()[0] == "message [ func]" ); |
259 | |
260 | spdlog::details::log_msg msg2{spdlog::source_loc{"ignored" , 1, "func567890123" }, "test_logger" , spdlog::level::info, "message" }; |
261 | test_sink.log(msg2); |
262 | REQUIRE(test_sink.lines()[1] == "message [func567890123]" ); |
263 | } |
264 | |
265 | TEST_CASE("clone-default-formatter" , "[pattern_formatter]" ) |
266 | { |
267 | auto formatter_1 = std::make_shared<spdlog::pattern_formatter>(); |
268 | auto formatter_2 = formatter_1->clone(); |
269 | std::string logger_name = "test" ; |
270 | spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message" ); |
271 | |
272 | memory_buf_t formatted_1; |
273 | memory_buf_t formatted_2; |
274 | formatter_1->format(msg, formatted_1); |
275 | formatter_2->format(msg, formatted_2); |
276 | |
277 | REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2)); |
278 | } |
279 | |
280 | TEST_CASE("clone-default-formatter2" , "[pattern_formatter]" ) |
281 | { |
282 | auto formatter_1 = std::make_shared<spdlog::pattern_formatter>("%+" ); |
283 | auto formatter_2 = formatter_1->clone(); |
284 | std::string logger_name = "test" ; |
285 | spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message" ); |
286 | |
287 | memory_buf_t formatted_1; |
288 | memory_buf_t formatted_2; |
289 | formatter_1->format(msg, formatted_1); |
290 | formatter_2->format(msg, formatted_2); |
291 | |
292 | REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2)); |
293 | } |
294 | |
295 | TEST_CASE("clone-formatter" , "[pattern_formatter]" ) |
296 | { |
297 | auto formatter_1 = std::make_shared<spdlog::pattern_formatter>("%D %X [%] [%n] %v" ); |
298 | auto formatter_2 = formatter_1->clone(); |
299 | std::string logger_name = "test" ; |
300 | spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message" ); |
301 | |
302 | memory_buf_t formatted_1; |
303 | memory_buf_t formatted_2; |
304 | formatter_1->format(msg, formatted_1); |
305 | formatter_2->format(msg, formatted_2); |
306 | |
307 | REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2)); |
308 | } |
309 | |
310 | TEST_CASE("clone-formatter-2" , "[pattern_formatter]" ) |
311 | { |
312 | using spdlog::pattern_time_type; |
313 | auto formatter_1 = std::make_shared<spdlog::pattern_formatter>("%D %X [%] [%n] %v" , pattern_time_type::utc, "xxxxxx\n" ); |
314 | auto formatter_2 = formatter_1->clone(); |
315 | std::string logger_name = "test2" ; |
316 | spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message" ); |
317 | |
318 | memory_buf_t formatted_1; |
319 | memory_buf_t formatted_2; |
320 | formatter_1->format(msg, formatted_1); |
321 | formatter_2->format(msg, formatted_2); |
322 | |
323 | REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2)); |
324 | } |
325 | |
326 | class custom_test_flag : public spdlog::custom_flag_formatter |
327 | { |
328 | public: |
329 | explicit custom_test_flag(std::string txt) |
330 | : some_txt{std::move(txt)} |
331 | {} |
332 | |
333 | void format(const spdlog::details::log_msg &, const std::tm &tm, spdlog::memory_buf_t &dest) override |
334 | { |
335 | if (some_txt == "throw_me" ) |
336 | { |
337 | throw spdlog::spdlog_ex("custom_flag_exception_test" ); |
338 | } |
339 | else if (some_txt == "time" ) |
340 | { |
341 | auto formatted = spdlog::fmt_lib::format("{:d}:{:02d}{:s}" , tm.tm_hour % 12, tm.tm_min, tm.tm_hour / 12 ? "PM" : "AM" ); |
342 | dest.append(formatted.data(), formatted.data() + formatted.size()); |
343 | return; |
344 | } |
345 | some_txt = std::string(padinfo_.width_, ' ') + some_txt; |
346 | dest.append(some_txt.data(), some_txt.data() + some_txt.size()); |
347 | } |
348 | spdlog::details::padding_info get_padding_info() |
349 | { |
350 | return padinfo_; |
351 | } |
352 | |
353 | std::string some_txt; |
354 | |
355 | std::unique_ptr<custom_flag_formatter> clone() const override |
356 | { |
357 | return spdlog::details::make_unique<custom_test_flag>(some_txt); |
358 | } |
359 | }; |
360 | // test clone with custom flag formatters |
361 | TEST_CASE("clone-custom_formatter" , "[pattern_formatter]" ) |
362 | { |
363 | auto formatter_1 = std::make_shared<spdlog::pattern_formatter>(); |
364 | formatter_1->add_flag<custom_test_flag>('t', "custom_output" ).set_pattern("[%n] [%t] %v" ); |
365 | auto formatter_2 = formatter_1->clone(); |
366 | std::string logger_name = "logger-name" ; |
367 | spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message" ); |
368 | |
369 | memory_buf_t formatted_1; |
370 | memory_buf_t formatted_2; |
371 | formatter_1->format(msg, formatted_1); |
372 | formatter_2->format(msg, formatted_2); |
373 | |
374 | auto expected = spdlog::fmt_lib::format("[logger-name] [custom_output] some message{}" , spdlog::details::os::default_eol); |
375 | |
376 | REQUIRE(to_string_view(formatted_1) == expected); |
377 | REQUIRE(to_string_view(formatted_2) == expected); |
378 | } |
379 | |
380 | // |
381 | // Test source location formatting |
382 | // |
383 | |
384 | #ifdef _WIN32 |
385 | static const char *const test_path = "\\a\\b\\c/myfile.cpp" ; |
386 | #else |
387 | static const char *const test_path = "/a/b//myfile.cpp" ; |
388 | #endif |
389 | |
390 | TEST_CASE("short filename formatter-1" , "[pattern_formatter]" ) |
391 | { |
392 | spdlog::pattern_formatter formatter("%s" , spdlog::pattern_time_type::local, "" ); |
393 | memory_buf_t formatted; |
394 | std::string logger_name = "logger-name" ; |
395 | spdlog::source_loc source_loc{test_path, 123, "some_func()" }; |
396 | spdlog::details::log_msg msg(source_loc, "logger-name" , spdlog::level::info, "Hello" ); |
397 | formatter.format(msg, formatted); |
398 | |
399 | REQUIRE(to_string_view(formatted) == "myfile.cpp" ); |
400 | } |
401 | |
402 | TEST_CASE("short filename formatter-2" , "[pattern_formatter]" ) |
403 | { |
404 | spdlog::pattern_formatter formatter("%s:%#" , spdlog::pattern_time_type::local, "" ); |
405 | memory_buf_t formatted; |
406 | std::string logger_name = "logger-name" ; |
407 | spdlog::source_loc source_loc{"myfile.cpp" , 123, "some_func()" }; |
408 | spdlog::details::log_msg msg(source_loc, "logger-name" , spdlog::level::info, "Hello" ); |
409 | formatter.format(msg, formatted); |
410 | |
411 | REQUIRE(to_string_view(formatted) == "myfile.cpp:123" ); |
412 | } |
413 | |
414 | TEST_CASE("short filename formatter-3" , "[pattern_formatter]" ) |
415 | { |
416 | spdlog::pattern_formatter formatter("%s %v" , spdlog::pattern_time_type::local, "" ); |
417 | memory_buf_t formatted; |
418 | std::string logger_name = "logger-name" ; |
419 | spdlog::source_loc source_loc{"" , 123, "some_func()" }; |
420 | spdlog::details::log_msg msg(source_loc, "logger-name" , spdlog::level::info, "Hello" ); |
421 | formatter.format(msg, formatted); |
422 | |
423 | REQUIRE(to_string_view(formatted) == " Hello" ); |
424 | } |
425 | |
426 | TEST_CASE("full filename formatter" , "[pattern_formatter]" ) |
427 | { |
428 | spdlog::pattern_formatter formatter("%g" , spdlog::pattern_time_type::local, "" ); |
429 | memory_buf_t formatted; |
430 | std::string logger_name = "logger-name" ; |
431 | spdlog::source_loc source_loc{test_path, 123, "some_func()" }; |
432 | spdlog::details::log_msg msg(source_loc, "logger-name" , spdlog::level::info, "Hello" ); |
433 | formatter.format(msg, formatted); |
434 | |
435 | REQUIRE(to_string_view(formatted) == test_path); |
436 | } |
437 | |
438 | TEST_CASE("custom flags" , "[pattern_formatter]" ) |
439 | { |
440 | auto formatter = std::make_shared<spdlog::pattern_formatter>(); |
441 | formatter->add_flag<custom_test_flag>('t', "custom1" ).add_flag<custom_test_flag>('u', "custom2" ).set_pattern("[%n] [%t] [%u] %v" ); |
442 | |
443 | memory_buf_t formatted; |
444 | |
445 | spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name" , spdlog::level::info, "some message" ); |
446 | formatter->format(msg, formatted); |
447 | auto expected = spdlog::fmt_lib::format("[logger-name] [custom1] [custom2] some message{}" , spdlog::details::os::default_eol); |
448 | |
449 | REQUIRE(to_string_view(formatted) == expected); |
450 | } |
451 | |
452 | TEST_CASE("custom flags-padding" , "[pattern_formatter]" ) |
453 | { |
454 | auto formatter = std::make_shared<spdlog::pattern_formatter>(); |
455 | formatter->add_flag<custom_test_flag>('t', "custom1" ).add_flag<custom_test_flag>('u', "custom2" ).set_pattern("[%n] [%t] [%5u] %v" ); |
456 | |
457 | memory_buf_t formatted; |
458 | |
459 | spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name" , spdlog::level::info, "some message" ); |
460 | formatter->format(msg, formatted); |
461 | auto expected = spdlog::fmt_lib::format("[logger-name] [custom1] [ custom2] some message{}" , spdlog::details::os::default_eol); |
462 | |
463 | REQUIRE(to_string_view(formatted) == expected); |
464 | } |
465 | |
466 | TEST_CASE("custom flags-exception" , "[pattern_formatter]" ) |
467 | { |
468 | auto formatter = std::make_shared<spdlog::pattern_formatter>(); |
469 | formatter->add_flag<custom_test_flag>('t', "throw_me" ).add_flag<custom_test_flag>('u', "custom2" ).set_pattern("[%n] [%t] [%u] %v" ); |
470 | |
471 | memory_buf_t formatted; |
472 | spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name" , spdlog::level::info, "some message" ); |
473 | CHECK_THROWS_AS(formatter->format(msg, formatted), spdlog::spdlog_ex); |
474 | } |
475 | |
476 | TEST_CASE("override need_localtime" , "[pattern_formatter]" ) |
477 | { |
478 | auto formatter = std::make_shared<spdlog::pattern_formatter>(spdlog::pattern_time_type::local, "\n" ); |
479 | formatter->add_flag<custom_test_flag>('t', "time" ).set_pattern("%t> %v" ); |
480 | |
481 | { |
482 | memory_buf_t formatted; |
483 | spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name" , spdlog::level::info, "some message" ); |
484 | formatter->format(msg, formatted); |
485 | REQUIRE(to_string_view(formatted) == "0:00AM> some message\n" ); |
486 | } |
487 | |
488 | { |
489 | formatter->need_localtime(); |
490 | |
491 | auto now_tm = spdlog::details::os::localtime(); |
492 | std::stringstream oss; |
493 | oss << (now_tm.tm_hour % 12) << ":" << std::setfill('0') << std::setw(2) << now_tm.tm_min << (now_tm.tm_hour / 12 ? "PM" : "AM" ) |
494 | << "> some message\n" ; |
495 | |
496 | memory_buf_t formatted; |
497 | spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name" , spdlog::level::info, "some message" ); |
498 | formatter->format(msg, formatted); |
499 | REQUIRE(to_string_view(formatted) == oss.str()); |
500 | } |
501 | } |
502 | |