5 #include <boost/test/unit_test.hpp>
7 #include "log/logger.hpp"
8 #include "log/format.hpp"
10 BOOST_AUTO_TEST_SUITE( TestLogger )
12 static inline bool head_and_tail_equal( const std::string& str, const std::string& head, const std::string& tail ) {
13 return str.size() >= head.size() + tail.size()
14 and std::equal( head.begin(), head.end(), str.begin() )
15 and std::equal( tail.rbegin(), tail.rend(), str.rbegin() )
19 BOOST_AUTO_TEST_CASE( basic_log ) {
20 auto stream = std::ostringstream{};
21 auto logger = logger::logger_set{stream};
23 logger.log( logger::level::note, "foo", " bar ", 23, ' ', 42.0, " baz" );
25 BOOST_CHECK( head_and_tail_equal( stream.str(), "[note ][", "]: foo bar 23 42 baz\n" ) );
28 BOOST_AUTO_TEST_CASE( basic_logf ) {
29 auto stream = std::ostringstream{};
30 auto logger = logger::logger_set{stream};
32 logger.logf( logger::level::note, "bla%sblub%s%%", "foo", 42 );
34 BOOST_CHECK( head_and_tail_equal( stream.str(), "[note ][", "]: blafooblub42%\n" ) );
37 BOOST_AUTO_TEST_CASE( log_hiding ) {
38 auto stream1 = std::ostringstream{};
39 auto logger1 = logger::logger_set{stream1};
41 auto stream2 = std::ostringstream{};
42 auto logger2 = logger::logger_set{stream2};
44 logger::note( "foobar" );
46 BOOST_CHECK( stream1.str().empty() );
47 BOOST_CHECK( head_and_tail_equal( stream2.str(), "[note ][", "]: foobar\n" ) );
50 BOOST_AUTO_TEST_CASE( log_restoration ) {
51 auto stream1 = std::ostringstream{};
52 auto logger1 = logger::logger_set{stream1};
55 auto stream2 = std::ostringstream{};
56 auto logger2 = logger::logger_set{stream2};
59 logger::note( "foobar" );
61 BOOST_CHECK( head_and_tail_equal( stream1.str(), "[note ][", "]: foobar\n" ) );
64 BOOST_AUTO_TEST_CASE( non_global_log ) {
65 auto stream1 = std::ostringstream{};
66 auto logger1 = logger::logger_set{stream1};
68 auto stream2 = std::ostringstream{};
69 auto logger2 = logger::logger_set{{stream2}, logger::auto_register::off};
71 logger::note( "foobar" );
73 BOOST_CHECK( head_and_tail_equal( stream1.str(), "[note ][", "]: foobar\n" ) );
74 BOOST_CHECK( stream2.str().empty() );
77 BOOST_AUTO_TEST_CASE( concat_alias_methods ) {
79 auto stream = std::ostringstream{};
80 auto logger = logger::logger_set{{stream, logger::level::debug}};
82 logger.debug( "foo" );
84 BOOST_CHECK( head_and_tail_equal( stream.str(), "[debug][", "]: foo\n" ) );
88 auto stream = std::ostringstream{};
89 auto logger = logger::logger_set{{stream, logger::level::note}};
93 BOOST_CHECK( head_and_tail_equal( stream.str(), "[note ][", "]: foo\n" ) );
97 auto stream = std::ostringstream{};
98 auto logger = logger::logger_set{{stream, logger::level::warn}};
100 logger.warn( "foo" );
102 BOOST_CHECK( head_and_tail_equal( stream.str(), "[warn ][", "]: foo\n" ) );
106 auto stream = std::ostringstream{};
107 auto logger = logger::logger_set{{stream, logger::level::error}};
109 logger.error( "foo" );
111 BOOST_CHECK( head_and_tail_equal( stream.str(), "[error][", "]: foo\n" ) );
115 auto stream = std::ostringstream{};
116 auto logger = logger::logger_set{{stream, logger::level::fatal}};
118 logger.fatal( "foo" );
120 BOOST_CHECK( head_and_tail_equal( stream.str(), "[fatal][", "]: foo\n" ) );
124 BOOST_AUTO_TEST_CASE( format_alias_methods ) {
126 auto stream = std::ostringstream{};
127 auto logger = logger::logger_set{{stream, logger::level::debug}};
129 logger.debugf( "foo" );
131 BOOST_CHECK( head_and_tail_equal( stream.str(), "[debug][", "]: foo\n" ) );
135 auto stream = std::ostringstream{};
136 auto logger = logger::logger_set{{stream, logger::level::note}};
138 logger.notef( "foo" );
140 BOOST_CHECK( head_and_tail_equal( stream.str(), "[note ][", "]: foo\n" ) );
144 auto stream = std::ostringstream{};
145 auto logger = logger::logger_set{{stream, logger::level::warn}};
147 logger.warnf( "foo" );
149 BOOST_CHECK( head_and_tail_equal( stream.str(), "[warn ][", "]: foo\n" ) );
153 auto stream = std::ostringstream{};
154 auto logger = logger::logger_set{{stream, logger::level::error}};
156 logger.errorf( "foo" );
158 BOOST_CHECK( head_and_tail_equal( stream.str(), "[error][", "]: foo\n" ) );
162 auto stream = std::ostringstream{};
163 auto logger = logger::logger_set{{stream, logger::level::fatal}};
165 logger.fatalf( "foo" );
167 BOOST_CHECK( head_and_tail_equal( stream.str(), "[fatal][", "]: foo\n" ) );
171 BOOST_AUTO_TEST_CASE( concat_alias_functions ) {
173 auto stream = std::ostringstream{};
174 auto logger = logger::logger_set{{stream, logger::level::debug}};
176 logger::debug( "foo" );
178 BOOST_CHECK( head_and_tail_equal( stream.str(), "[debug][", "]: foo\n" ) );
182 auto stream = std::ostringstream{};
183 auto logger = logger::logger_set{{stream, logger::level::note}};
185 logger::note( "foo" );
187 BOOST_CHECK( head_and_tail_equal( stream.str(), "[note ][", "]: foo\n" ) );
191 auto stream = std::ostringstream{};
192 auto logger = logger::logger_set{{stream, logger::level::warn}};
194 logger::warn( "foo" );
196 BOOST_CHECK( head_and_tail_equal( stream.str(), "[warn ][", "]: foo\n" ) );
200 auto stream = std::ostringstream{};
201 auto logger = logger::logger_set{{stream, logger::level::error}};
203 logger::error( "foo" );
205 BOOST_CHECK( head_and_tail_equal( stream.str(), "[error][", "]: foo\n" ) );
209 auto stream = std::ostringstream{};
210 auto logger = logger::logger_set{{stream, logger::level::fatal}};
212 logger::fatal( "foo" );
214 BOOST_CHECK( head_and_tail_equal( stream.str(), "[fatal][", "]: foo\n" ) );
218 BOOST_AUTO_TEST_CASE( format_alias_functions ) {
220 auto stream = std::ostringstream{};
221 auto logger = logger::logger_set{{stream, logger::level::debug}};
223 logger::debugf( "foo" );
225 BOOST_CHECK( head_and_tail_equal( stream.str(), "[debug][", "]: foo\n" ) );
229 auto stream = std::ostringstream{};
230 auto logger = logger::logger_set{{stream, logger::level::note}};
232 logger::notef( "foo" );
234 BOOST_CHECK( head_and_tail_equal( stream.str(), "[note ][", "]: foo\n" ) );
238 auto stream = std::ostringstream{};
239 auto logger = logger::logger_set{{stream, logger::level::warn}};
241 logger::warnf( "foo" );
243 BOOST_CHECK( head_and_tail_equal( stream.str(), "[warn ][", "]: foo\n" ) );
247 auto stream = std::ostringstream{};
248 auto logger = logger::logger_set{{stream, logger::level::error}};
250 logger::errorf( "foo" );
252 BOOST_CHECK( head_and_tail_equal( stream.str(), "[error][", "]: foo\n" ) );
256 auto stream = std::ostringstream{};
257 auto logger = logger::logger_set{{stream, logger::level::fatal}};
259 logger::fatalf( "foo" );
261 BOOST_CHECK( head_and_tail_equal( stream.str(), "[fatal][", "]: foo\n" ) );
265 BOOST_AUTO_TEST_CASE( formatting_exceptions ) {
266 auto stream = std::ostringstream{};
267 auto logger = logger::logger_set{stream};
269 BOOST_CHECK_THROW( logger.notef( "%" ), std::invalid_argument );
270 BOOST_CHECK_THROW( logger.notef( "%s" ), std::invalid_argument );
271 BOOST_CHECK_THROW( logger.notef( "%e" ), std::invalid_argument );
274 BOOST_AUTO_TEST_CASE( multiple_calls ) {
275 auto stream = std::ostringstream{};
276 auto logger = logger::logger_set{stream};
278 logger::note( "foo1" );
279 logger::debug( "foo2" );
280 logger::warn( "foo3" );
281 logger::note( "foo4" );
283 const auto result = stream.str();
285 const auto foo1 = result.find( "foo1" );
286 const auto foo2 = result.find( "foo2" );
287 const auto foo3 = result.find( "foo3" );
288 const auto foo4 = result.find( "foo4" );
290 BOOST_CHECK_LT( foo1, foo3 );
291 BOOST_CHECK_LT( foo3, foo4 );
292 BOOST_CHECK_NE( foo4, std::string::npos );
293 BOOST_CHECK_EQUAL( foo2, std::string::npos );
296 BOOST_AUTO_TEST_CASE( multiple_calls_nested ) {
297 auto stream = std::ostringstream{};
298 auto logger = logger::logger_set{stream};
300 logger::note( "foo1" );
303 auto stream = std::ostringstream{};
304 auto logger = logger::logger_set{stream};
306 logger::note( "foo2" );
309 logger::note( "foo3" );
311 const auto result = stream.str();
312 const auto foo1 = result.find( "foo1" );
313 const auto foo2 = result.find( "foo2" );
314 const auto foo3 = result.find( "foo3" );
316 BOOST_CHECK_LT( foo1, foo3 );
317 BOOST_CHECK_NE( foo3, std::string::npos );
318 BOOST_CHECK_EQUAL( foo2, std::string::npos );
321 BOOST_AUTO_TEST_CASE( extending_current_logger ) {
322 auto stream1 = std::ostringstream{};
323 auto logger1 = logger::logger_set{stream1};
325 auto stream2 = std::ostringstream{};
327 auto logger2 = logger::current_logger_extended( {stream2} );
328 logger::note( "foo1" );
331 BOOST_CHECK( head_and_tail_equal( stream1.str(), "[note ][", "]: foo1\n" ) );
332 BOOST_CHECK( head_and_tail_equal( stream2.str(), "[note ][", "]: foo1\n" ) );
337 logger::note( "foo2" );
339 BOOST_CHECK( head_and_tail_equal( stream1.str(), "[note ][", "]: foo2\n" ) );
340 BOOST_CHECK( stream2.str().empty() );
343 BOOST_AUTO_TEST_CASE( closed_filestream_exception ) {
344 std::ofstream stream;
346 BOOST_CHECK_THROW( logger::logger_set {stream}, std::runtime_error );
349 BOOST_AUTO_TEST_CASE( formated_strings ) {
350 using namespace logger::format::literals;
351 using logger::conv::to_string;
353 BOOST_CHECK_EQUAL( to_string( ""_fmt( "foo" ) ), "foo" );
354 BOOST_CHECK_EQUAL( to_string( "_3"_fmt( "foo" ) ), "foo" );
355 BOOST_CHECK_EQUAL( to_string( "_6"_fmt( "foo" ) ), "foo___" );
356 BOOST_CHECK_EQUAL( to_string( "_10l"_fmt( "foo" ) ), "foo_______" );
357 BOOST_CHECK_EQUAL( to_string( "_10r"_fmt( "foo" ) ), "_______foo" );
360 BOOST_AUTO_TEST_CASE( formated_ints ) {
361 using namespace logger::format::literals;
362 using logger::conv::to_string;
364 BOOST_CHECK_EQUAL( to_string( ""_fmt( 3 ) ), "3" );
365 BOOST_CHECK_EQUAL( to_string( "03"_fmt( 3 ) ), "003" );
366 BOOST_CHECK_EQUAL( to_string( "03"_fmt( 13 ) ), "013" );
367 BOOST_CHECK_EQUAL( to_string( "03x"_fmt( 13 ) ), "00d" );
368 BOOST_CHECK_EQUAL( to_string( "03o"_fmt( 13 ) ), "015" );
369 BOOST_CHECK_EQUAL( to_string( "03d"_fmt( 13 ) ), "013" );
370 BOOST_CHECK_EQUAL( to_string( "03s"_fmt( 13 ) ), "013" );
373 BOOST_AUTO_TEST_CASE( formated_ints_variadic_api ) {
374 using logger::conv::to_string;
375 using logger::format::fmt;
377 BOOST_CHECK_EQUAL( to_string( fmt( 3 ) ), "3" );
378 BOOST_CHECK_EQUAL( to_string( fmt( 3, logger::format::width_t {3} ) ), " 3" );
381 BOOST_AUTO_TEST_CASE( formated_ints_variadic_api_literals ) {
382 using logger::conv::to_string;
383 using logger::format::fmt;
385 using namespace logger::format::literals;
387 BOOST_CHECK_EQUAL( to_string( fmt( 3 ) ), "3" );
388 BOOST_CHECK_EQUAL( to_string( fmt( 3, 3_w ) ), " 3" );
389 BOOST_CHECK_EQUAL( to_string( fmt( 10, 3_w, 8_b, 'x'_f ) ), "x12" );
392 BOOST_AUTO_TEST_SUITE_END()