]> WPIA git - cassiopeia.git/blob - test/src/log.cpp
ce7a7ace67875f114b1862515319fd9ec83070c8
[cassiopeia.git] / test / src / log.cpp
1 #include <iostream>
2 #include <sstream>
3 #include <stdexcept>
4
5 #include <boost/test/unit_test.hpp>
6
7 #include "log/logger.hpp"
8 #include "log/format.hpp"
9
10 BOOST_AUTO_TEST_SUITE( TestLogger )
11
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() )
16             ;
17 }
18
19 BOOST_AUTO_TEST_CASE( basic_log ) {
20     auto stream = std::ostringstream{};
21     auto logger = logger::logger_set{stream};
22
23     logger.log( logger::level::note, "foo", " bar ", 23, ' ', 42.0, " baz" );
24
25     BOOST_CHECK( head_and_tail_equal( stream.str(), "[note ][", "]: foo bar 23 42 baz\n" ) );
26 }
27
28 BOOST_AUTO_TEST_CASE( basic_logf ) {
29     auto stream = std::ostringstream{};
30     auto logger = logger::logger_set{stream};
31
32     logger.logf( logger::level::note, "bla%sblub%s%%", "foo", 42 );
33
34     BOOST_CHECK( head_and_tail_equal( stream.str(), "[note ][", "]: blafooblub42%\n" ) );
35 }
36
37 BOOST_AUTO_TEST_CASE( log_hiding ) {
38     auto stream1 = std::ostringstream{};
39     auto logger1 = logger::logger_set{stream1};
40
41     auto stream2 = std::ostringstream{};
42     auto logger2 = logger::logger_set{stream2};
43
44     logger::note( "foobar" );
45
46     BOOST_CHECK( stream1.str().empty() );
47     BOOST_CHECK( head_and_tail_equal( stream2.str(), "[note ][", "]: foobar\n" ) );
48 }
49
50 BOOST_AUTO_TEST_CASE( log_restoration ) {
51     auto stream1 = std::ostringstream{};
52     auto logger1 = logger::logger_set{stream1};
53
54     {
55         auto stream2 = std::ostringstream{};
56         auto logger2 = logger::logger_set{stream2};
57     }
58
59     logger::note( "foobar" );
60
61     BOOST_CHECK( head_and_tail_equal( stream1.str(), "[note ][", "]: foobar\n" ) );
62 }
63
64 BOOST_AUTO_TEST_CASE( non_global_log ) {
65     auto stream1 = std::ostringstream{};
66     auto logger1 = logger::logger_set{stream1};
67
68     auto stream2 = std::ostringstream{};
69     auto logger2 = logger::logger_set{{stream2}, logger::auto_register::off};
70
71     logger::note( "foobar" );
72
73     BOOST_CHECK( head_and_tail_equal( stream1.str(), "[note ][", "]: foobar\n" ) );
74     BOOST_CHECK( stream2.str().empty() );
75 }
76
77 BOOST_AUTO_TEST_CASE( concat_alias_methods ) {
78     {
79         auto stream = std::ostringstream{};
80         auto logger = logger::logger_set{{stream, logger::level::debug}};
81
82         logger.debug( "foo" );
83
84         BOOST_CHECK( head_and_tail_equal( stream.str(), "[debug][", "]: foo\n" ) );
85     }
86
87     {
88         auto stream = std::ostringstream{};
89         auto logger = logger::logger_set{{stream, logger::level::note}};
90
91         logger.note( "foo" );
92
93         BOOST_CHECK( head_and_tail_equal( stream.str(), "[note ][", "]: foo\n" ) );
94     }
95
96     {
97         auto stream = std::ostringstream{};
98         auto logger = logger::logger_set{{stream, logger::level::warn}};
99
100         logger.warn( "foo" );
101
102         BOOST_CHECK( head_and_tail_equal( stream.str(), "[warn ][", "]: foo\n" ) );
103     }
104
105     {
106         auto stream = std::ostringstream{};
107         auto logger = logger::logger_set{{stream, logger::level::error}};
108
109         logger.error( "foo" );
110
111         BOOST_CHECK( head_and_tail_equal( stream.str(), "[error][", "]: foo\n" ) );
112     }
113
114     {
115         auto stream = std::ostringstream{};
116         auto logger = logger::logger_set{{stream, logger::level::fatal}};
117
118         logger.fatal( "foo" );
119
120         BOOST_CHECK( head_and_tail_equal( stream.str(), "[fatal][", "]: foo\n" ) );
121     }
122 }
123
124 BOOST_AUTO_TEST_CASE( format_alias_methods ) {
125     {
126         auto stream = std::ostringstream{};
127         auto logger = logger::logger_set{{stream, logger::level::debug}};
128
129         logger.debugf( "foo" );
130
131         BOOST_CHECK( head_and_tail_equal( stream.str(), "[debug][", "]: foo\n" ) );
132     }
133
134     {
135         auto stream = std::ostringstream{};
136         auto logger = logger::logger_set{{stream, logger::level::note}};
137
138         logger.notef( "foo" );
139
140         BOOST_CHECK( head_and_tail_equal( stream.str(), "[note ][", "]: foo\n" ) );
141     }
142
143     {
144         auto stream = std::ostringstream{};
145         auto logger = logger::logger_set{{stream, logger::level::warn}};
146
147         logger.warnf( "foo" );
148
149         BOOST_CHECK( head_and_tail_equal( stream.str(), "[warn ][", "]: foo\n" ) );
150     }
151
152     {
153         auto stream = std::ostringstream{};
154         auto logger = logger::logger_set{{stream, logger::level::error}};
155
156         logger.errorf( "foo" );
157
158         BOOST_CHECK( head_and_tail_equal( stream.str(), "[error][", "]: foo\n" ) );
159     }
160
161     {
162         auto stream = std::ostringstream{};
163         auto logger = logger::logger_set{{stream, logger::level::fatal}};
164
165         logger.fatalf( "foo" );
166
167         BOOST_CHECK( head_and_tail_equal( stream.str(), "[fatal][", "]: foo\n" ) );
168     }
169 }
170
171 BOOST_AUTO_TEST_CASE( concat_alias_functions ) {
172     {
173         auto stream = std::ostringstream{};
174         auto logger = logger::logger_set{{stream, logger::level::debug}};
175
176         logger::debug( "foo" );
177
178         BOOST_CHECK( head_and_tail_equal( stream.str(), "[debug][", "]: foo\n" ) );
179     }
180
181     {
182         auto stream = std::ostringstream{};
183         auto logger = logger::logger_set{{stream, logger::level::note}};
184
185         logger::note( "foo" );
186
187         BOOST_CHECK( head_and_tail_equal( stream.str(), "[note ][", "]: foo\n" ) );
188     }
189
190     {
191         auto stream = std::ostringstream{};
192         auto logger = logger::logger_set{{stream, logger::level::warn}};
193
194         logger::warn( "foo" );
195
196         BOOST_CHECK( head_and_tail_equal( stream.str(), "[warn ][", "]: foo\n" ) );
197     }
198
199     {
200         auto stream = std::ostringstream{};
201         auto logger = logger::logger_set{{stream, logger::level::error}};
202
203         logger::error( "foo" );
204
205         BOOST_CHECK( head_and_tail_equal( stream.str(), "[error][", "]: foo\n" ) );
206     }
207
208     {
209         auto stream = std::ostringstream{};
210         auto logger = logger::logger_set{{stream, logger::level::fatal}};
211
212         logger::fatal( "foo" );
213
214         BOOST_CHECK( head_and_tail_equal( stream.str(), "[fatal][", "]: foo\n" ) );
215     }
216 }
217
218 BOOST_AUTO_TEST_CASE( format_alias_functions ) {
219     {
220         auto stream = std::ostringstream{};
221         auto logger = logger::logger_set{{stream, logger::level::debug}};
222
223         logger::debugf( "foo" );
224
225         BOOST_CHECK( head_and_tail_equal( stream.str(), "[debug][", "]: foo\n" ) );
226     }
227
228     {
229         auto stream = std::ostringstream{};
230         auto logger = logger::logger_set{{stream, logger::level::note}};
231
232         logger::notef( "foo" );
233
234         BOOST_CHECK( head_and_tail_equal( stream.str(), "[note ][", "]: foo\n" ) );
235     }
236
237     {
238         auto stream = std::ostringstream{};
239         auto logger = logger::logger_set{{stream, logger::level::warn}};
240
241         logger::warnf( "foo" );
242
243         BOOST_CHECK( head_and_tail_equal( stream.str(), "[warn ][", "]: foo\n" ) );
244     }
245
246     {
247         auto stream = std::ostringstream{};
248         auto logger = logger::logger_set{{stream, logger::level::error}};
249
250         logger::errorf( "foo" );
251
252         BOOST_CHECK( head_and_tail_equal( stream.str(), "[error][", "]: foo\n" ) );
253     }
254
255     {
256         auto stream = std::ostringstream{};
257         auto logger = logger::logger_set{{stream, logger::level::fatal}};
258
259         logger::fatalf( "foo" );
260
261         BOOST_CHECK( head_and_tail_equal( stream.str(), "[fatal][", "]: foo\n" ) );
262     }
263 }
264
265 BOOST_AUTO_TEST_CASE( formatting_exceptions ) {
266     auto stream = std::ostringstream{};
267     auto logger = logger::logger_set{stream};
268
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 );
272 }
273
274 BOOST_AUTO_TEST_CASE( multiple_calls ) {
275     auto stream = std::ostringstream{};
276     auto logger = logger::logger_set{stream};
277
278     logger::note( "foo1" );
279     logger::debug( "foo2" );
280     logger::warn( "foo3" );
281     logger::note( "foo4" );
282
283     const auto result = stream.str();
284
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" );
289
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 );
294 }
295
296 BOOST_AUTO_TEST_CASE( multiple_calls_nested ) {
297     auto stream = std::ostringstream{};
298     auto logger = logger::logger_set{stream};
299
300     logger::note( "foo1" );
301
302     {
303         auto stream = std::ostringstream{};
304         auto logger = logger::logger_set{stream};
305
306         logger::note( "foo2" );
307     }
308
309     logger::note( "foo3" );
310
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" );
315
316     BOOST_CHECK_LT( foo1, foo3 );
317     BOOST_CHECK_NE( foo3, std::string::npos );
318     BOOST_CHECK_EQUAL( foo2, std::string::npos );
319 }
320
321 BOOST_AUTO_TEST_CASE( extending_current_logger ) {
322     auto stream1 = std::ostringstream{};
323     auto logger1 = logger::logger_set{stream1};
324
325     auto stream2 = std::ostringstream{};
326     {
327         auto logger2 = logger::current_logger_extended( {stream2} );
328         logger::note( "foo1" );
329     }
330
331     BOOST_CHECK( head_and_tail_equal( stream1.str(), "[note ][", "]: foo1\n" ) );
332     BOOST_CHECK( head_and_tail_equal( stream2.str(), "[note ][", "]: foo1\n" ) );
333
334     stream1.str( "" );
335     stream2.str( "" );
336
337     logger::note( "foo2" );
338
339     BOOST_CHECK( head_and_tail_equal( stream1.str(), "[note ][", "]: foo2\n" ) );
340     BOOST_CHECK( stream2.str().empty() );
341 }
342
343 BOOST_AUTO_TEST_CASE( closed_filestream_exception ) {
344     std::ofstream stream;
345
346     BOOST_CHECK_THROW( logger::logger_set {stream}, std::runtime_error );
347 }
348
349 BOOST_AUTO_TEST_CASE( formated_strings ) {
350     using namespace logger::format::literals;
351     using logger::conv::to_string;
352
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" );
358 }
359
360 BOOST_AUTO_TEST_CASE( formated_ints ) {
361     using namespace logger::format::literals;
362     using logger::conv::to_string;
363
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" );
371 }
372
373 BOOST_AUTO_TEST_CASE( formated_ints_variadic_api ) {
374     using logger::conv::to_string;
375     using logger::format::fmt;
376
377     BOOST_CHECK_EQUAL( to_string( fmt( 3 ) ), "3" );
378     BOOST_CHECK_EQUAL( to_string( fmt( 3, logger::format::width_t {3} ) ), "  3" );
379 }
380
381 BOOST_AUTO_TEST_CASE( formated_ints_variadic_api_literals ) {
382     using logger::conv::to_string;
383     using logger::format::fmt;
384
385     using namespace logger::format::literals;
386
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" );
390 }
391
392 BOOST_AUTO_TEST_SUITE_END()