]> git.saurik.com Git - wxWidgets.git/blame - tests/log/logtest.cpp
Consistently handle DST start time in wxDateTime::Set().
[wxWidgets.git] / tests / log / logtest.cpp
CommitLineData
ece5e6a4
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: tests/log/logtest.cpp
3// Purpose: wxLog unit test
4// Author: Vadim Zeitlin
5// Created: 2009-07-07
ece5e6a4
VZ
6// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
7///////////////////////////////////////////////////////////////////////////////
8
9// ----------------------------------------------------------------------------
10// headers
11// ----------------------------------------------------------------------------
12
13#include "testprec.h"
14
15#ifdef __BORLANDC__
16 #pragma hdrstop
17#endif
18
19#ifndef WX_PRECOMP
20 #include "wx/log.h"
f9136b63 21 #include "wx/filefn.h"
ece5e6a4
VZ
22#endif // WX_PRECOMP
23
bc73d5ae
VZ
24#include "wx/scopeguard.h"
25
48557701
VZ
26#if WXWIN_COMPATIBILITY_2_8
27 // we override deprecated DoLog() and DoLogString() in this test, suppress
28 // warnings about it
29 #if wxCHECK_VISUALC_VERSION(7)
30 #pragma warning(disable: 4996)
31 #endif // VC++ 7+
32#endif // WXWIN_COMPATIBILITY_2_8
33
c602c59b
VZ
34// all calls to wxLogXXX() functions from this file will use this log component
35#define wxLOG_COMPONENT "test"
36
ece5e6a4 37// ----------------------------------------------------------------------------
bc73d5ae 38// test loggers
ece5e6a4
VZ
39// ----------------------------------------------------------------------------
40
bc73d5ae
VZ
41// base class for all test loggers which simply store all logged messages for
42// future examination in the test code
43class TestLogBase : public wxLog
ece5e6a4
VZ
44{
45public:
bc73d5ae 46 TestLogBase() { }
ece5e6a4 47
c602c59b 48 const wxString& GetLog(wxLogLevel level) const
ece5e6a4
VZ
49 {
50 return m_logs[level];
51 }
52
c602c59b
VZ
53 const wxLogRecordInfo& GetInfo(wxLogLevel level) const
54 {
55 return m_logsInfo[level];
56 }
57
ece5e6a4
VZ
58 void Clear()
59 {
60 for ( unsigned n = 0; n < WXSIZEOF(m_logs); n++ )
c602c59b 61 {
ece5e6a4 62 m_logs[n].clear();
c602c59b
VZ
63 m_logsInfo[n] = wxLogRecordInfo();
64 }
ece5e6a4
VZ
65 }
66
67protected:
bc73d5ae 68 wxString m_logs[wxLOG_Trace + 1];
c602c59b 69 wxLogRecordInfo m_logsInfo[wxLOG_Trace + 1];
bc73d5ae
VZ
70
71 wxDECLARE_NO_COPY_CLASS(TestLogBase);
72};
73
74// simple log sink which just stores the messages logged for each level
75class TestLog : public TestLogBase
76{
77public:
78 TestLog() { }
79
80protected:
81 virtual void DoLogRecord(wxLogLevel level,
82 const wxString& msg,
c602c59b 83 const wxLogRecordInfo& info)
bc73d5ae
VZ
84 {
85 m_logs[level] = msg;
c602c59b 86 m_logsInfo[level] = info;
bc73d5ae
VZ
87 }
88
89private:
90 wxDECLARE_NO_COPY_CLASS(TestLog);
91};
92
93#if WXWIN_COMPATIBILITY_2_8
94
95// log sink overriding the old DoLogXXX() functions should still work too
96
97// this one overrides DoLog(char*)
98class CompatTestLog : public TestLogBase
99{
100public:
101 CompatTestLog() { }
102
103protected:
104 virtual void DoLog(wxLogLevel level, const char *str, time_t WXUNUSED(t))
ece5e6a4
VZ
105 {
106 m_logs[level] = str;
107 }
108
bc73d5ae
VZ
109 // get rid of the warning about hiding the other overload
110 virtual void DoLog(wxLogLevel WXUNUSED(level),
111 const wchar_t *WXUNUSED(str),
112 time_t WXUNUSED(t))
113 {
114 }
ece5e6a4
VZ
115
116private:
bc73d5ae
VZ
117 wxDECLARE_NO_COPY_CLASS(CompatTestLog);
118};
ece5e6a4 119
bc73d5ae
VZ
120// and this one overload DoLogString(wchar_t*)
121class CompatTestLog2 : public wxLog
122{
123public:
124 CompatTestLog2() { }
125
126 const wxString& Get() const { return m_msg; }
127
128protected:
129 virtual void DoLogString(const wchar_t *msg, time_t WXUNUSED(t))
130 {
131 m_msg = msg;
132 }
133
134 // get rid of the warning
135 virtual void DoLogString(const char *WXUNUSED(msg), time_t WXUNUSED(t))
136 {
137 }
138
139private:
140 wxString m_msg;
141
142 wxDECLARE_NO_COPY_CLASS(CompatTestLog2);
ece5e6a4
VZ
143};
144
bc73d5ae
VZ
145#endif // WXWIN_COMPATIBILITY_2_8
146
ece5e6a4
VZ
147// ----------------------------------------------------------------------------
148// test class
149// ----------------------------------------------------------------------------
150
151class LogTestCase : public CppUnit::TestCase
152{
153public:
154 LogTestCase() { }
155
156 virtual void setUp();
157 virtual void tearDown();
158
159private:
160 CPPUNIT_TEST_SUITE( LogTestCase );
161 CPPUNIT_TEST( Functions );
162 CPPUNIT_TEST( Null );
c602c59b 163 CPPUNIT_TEST( Component );
ece5e6a4
VZ
164#if wxDEBUG_LEVEL
165 CPPUNIT_TEST( Trace );
166#endif // wxDEBUG_LEVEL
bc73d5ae
VZ
167#if WXWIN_COMPATIBILITY_2_8
168 CPPUNIT_TEST( CompatLogger );
169 CPPUNIT_TEST( CompatLogger2 );
170#endif // WXWIN_COMPATIBILITY_2_8
b804f992 171 CPPUNIT_TEST( SysError );
66b370d0 172 CPPUNIT_TEST( NoWarnings );
ece5e6a4
VZ
173 CPPUNIT_TEST_SUITE_END();
174
175 void Functions();
176 void Null();
c602c59b 177 void Component();
ece5e6a4
VZ
178#if wxDEBUG_LEVEL
179 void Trace();
180#endif // wxDEBUG_LEVEL
bc73d5ae
VZ
181#if WXWIN_COMPATIBILITY_2_8
182 void CompatLogger();
183 void CompatLogger2();
184#endif // WXWIN_COMPATIBILITY_2_8
b804f992 185 void SysError();
66b370d0 186 void NoWarnings();
ece5e6a4
VZ
187
188 TestLog *m_log;
189 wxLog *m_logOld;
190 bool m_logWasEnabled;
191
192 wxDECLARE_NO_COPY_CLASS(LogTestCase);
193};
194
195// register in the unnamed registry so that these tests are run by default
196CPPUNIT_TEST_SUITE_REGISTRATION( LogTestCase );
197
e3778b4d 198// also include in its own registry so that these tests can be run alone
ece5e6a4
VZ
199CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( LogTestCase, "LogTestCase" );
200
201void LogTestCase::setUp()
202{
203 m_logOld = wxLog::SetActiveTarget(m_log = new TestLog);
204 m_logWasEnabled = wxLog::EnableLogging();
205}
206
207void LogTestCase::tearDown()
208{
209 delete wxLog::SetActiveTarget(m_logOld);
210 wxLog::EnableLogging(m_logWasEnabled);
211}
212
213void LogTestCase::Functions()
214{
215 wxLogMessage("Message");
216 CPPUNIT_ASSERT_EQUAL( "Message", m_log->GetLog(wxLOG_Message) );
217
218 wxLogError("Error %d", 17);
219 CPPUNIT_ASSERT_EQUAL( "Error 17", m_log->GetLog(wxLOG_Error) );
220
221 wxLogDebug("Debug");
222#if wxDEBUG_LEVEL
223 CPPUNIT_ASSERT_EQUAL( "Debug", m_log->GetLog(wxLOG_Debug) );
224#else
225 CPPUNIT_ASSERT_EQUAL( "", m_log->GetLog(wxLOG_Debug) );
226#endif
227}
228
229void LogTestCase::Null()
230{
231 {
232 wxLogNull noLog;
233 wxLogWarning("%s warning", "Not important");
234
235 CPPUNIT_ASSERT_EQUAL( "", m_log->GetLog(wxLOG_Warning) );
236 }
237
238 wxLogWarning("%s warning", "Important");
239 CPPUNIT_ASSERT_EQUAL( "Important warning", m_log->GetLog(wxLOG_Warning) );
240}
241
c602c59b
VZ
242void LogTestCase::Component()
243{
244 wxLogMessage("Message");
245 CPPUNIT_ASSERT_EQUAL( wxLOG_COMPONENT,
246 m_log->GetInfo(wxLOG_Message).component );
247
248 // completely disable logging for this component
249 wxLog::SetComponentLevel("test/ignore", wxLOG_FatalError);
250
251 // but enable it for one of its subcomponents
252 wxLog::SetComponentLevel("test/ignore/not", wxLOG_Max);
253
254 #undef wxLOG_COMPONENT
255 #define wxLOG_COMPONENT "test/ignore"
256
257 // this shouldn't be output as this component is ignored
258 wxLogError("Error");
259 CPPUNIT_ASSERT_EQUAL( "", m_log->GetLog(wxLOG_Error) );
260
261 // and so are its subcomponents
262 #undef wxLOG_COMPONENT
263 #define wxLOG_COMPONENT "test/ignore/sub/subsub"
264 wxLogError("Error");
265 CPPUNIT_ASSERT_EQUAL( "", m_log->GetLog(wxLOG_Error) );
266
267 // but one subcomponent is not
268 #undef wxLOG_COMPONENT
269 #define wxLOG_COMPONENT "test/ignore/not"
270 wxLogError("Error");
271 CPPUNIT_ASSERT_EQUAL( "Error", m_log->GetLog(wxLOG_Error) );
272
273 // restore the original value
274 #undef wxLOG_COMPONENT
275 #define wxLOG_COMPONENT "test"
276}
277
ece5e6a4
VZ
278#if wxDEBUG_LEVEL
279
89d62794
VZ
280namespace
281{
282
283const char *TEST_MASK = "test";
284
285// this is a test vararg function (a real one, not a variadic-template-like as
286// wxVLogTrace(), so care should be taken with its arguments)
287void TraceTest(const char *format, ...)
288{
289 va_list argptr;
290 va_start(argptr, format);
291 wxVLogTrace(TEST_MASK, format, argptr);
292 va_end(argptr);
293}
294
295} // anonymous namespace
296
ece5e6a4
VZ
297void LogTestCase::Trace()
298{
89d62794
VZ
299 // we use wxLogTrace() or wxVLogTrace() from inside TraceTest()
300 // interchangeably here, it shouldn't make any difference
ece5e6a4
VZ
301
302 wxLogTrace(TEST_MASK, "Not shown");
303 CPPUNIT_ASSERT_EQUAL( "", m_log->GetLog(wxLOG_Trace) );
304
305 wxLog::AddTraceMask(TEST_MASK);
89d62794 306 TraceTest("Shown");
ece5e6a4
VZ
307 CPPUNIT_ASSERT_EQUAL( wxString::Format("(%s) Shown", TEST_MASK),
308 m_log->GetLog(wxLOG_Trace) );
309
310 wxLog::RemoveTraceMask(TEST_MASK);
311 m_log->Clear();
312
89d62794 313 TraceTest("Not shown again");
ece5e6a4
VZ
314 CPPUNIT_ASSERT_EQUAL( "", m_log->GetLog(wxLOG_Trace) );
315}
316
317#endif // wxDEBUG_LEVEL
bc73d5ae
VZ
318
319#if WXWIN_COMPATIBILITY_2_8
320
321void LogTestCase::CompatLogger()
322{
323 CompatTestLog log;
324 wxLog * const logOld = wxLog::SetActiveTarget(&log);
325 wxON_BLOCK_EXIT1( wxLog::SetActiveTarget, logOld );
326
327 wxLogError("Old error");
328 CPPUNIT_ASSERT_EQUAL( "Old error", log.GetLog(wxLOG_Error) );
329}
330
331void LogTestCase::CompatLogger2()
332{
333 CompatTestLog2 log;
334 wxLog * const logOld = wxLog::SetActiveTarget(&log);
335 wxON_BLOCK_EXIT1( wxLog::SetActiveTarget, logOld );
336
337 wxLogWarning("Old warning");
338 CPPUNIT_ASSERT_EQUAL( "Old warning", log.Get() );
339}
340
341#endif // WXWIN_COMPATIBILITY_2_8
b804f992
VZ
342
343void LogTestCase::SysError()
344{
345 wxString s;
b804f992
VZ
346
347 wxLogSysError(17, "Error");
348 CPPUNIT_ASSERT( m_log->GetLog(wxLOG_Error).StartsWith("Error (", &s) );
3cfa70b7
VZ
349 WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s), s.StartsWith("error 17") );
350
351 // The last error code seems to be set somewhere in MinGW CRT as its value
352 // is just not what we expect (ERROR_INVALID_PARAMETER instead of 0 and 0
353 // instead of ERROR_FILE_NOT_FOUND) so exclude the tests which rely on last
354 // error being preserved for this compiler.
355#ifndef __MINGW32__
356 wxLogSysError("Success");
357 CPPUNIT_ASSERT( m_log->GetLog(wxLOG_Error).StartsWith("Success (", &s) );
358 WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s), s.StartsWith("error 0") );
b804f992
VZ
359
360 wxOpen("no-such-file", 0, 0);
361 wxLogSysError("Not found");
362 CPPUNIT_ASSERT( m_log->GetLog(wxLOG_Error).StartsWith("Not found (", &s) );
363 WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s), s.StartsWith("error 2") );
3cfa70b7 364#endif // __MINGW32__
b804f992
VZ
365}
366
66b370d0
VZ
367void LogTestCase::NoWarnings()
368{
369 // Check that "else" branch is [not] taken as expected and that this code
370 // compiles without warnings (which used to not be the case).
371
372 bool b = wxFalse;
373 if ( b )
374 wxLogError("Not logged");
375 else
376 b = !b;
377
378 CPPUNIT_ASSERT( b );
379
380 if ( b )
381 wxLogError("If");
382 else
383 CPPUNIT_FAIL("Should not be taken");
384
385 CPPUNIT_ASSERT_EQUAL( "If", m_log->GetLog(wxLOG_Error) );
386}