1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/log/logtest.cpp
3 // Purpose: wxLog unit test
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
8 ///////////////////////////////////////////////////////////////////////////////
10 // ----------------------------------------------------------------------------
12 // ----------------------------------------------------------------------------
22 #include "wx/filefn.h"
25 #include "wx/scopeguard.h"
27 #if WXWIN_COMPATIBILITY_2_8
28 // we override deprecated DoLog() and DoLogString() in this test, suppress
30 #if wxCHECK_VISUALC_VERSION(7)
31 #pragma warning(disable: 4996)
33 #endif // WXWIN_COMPATIBILITY_2_8
35 // all calls to wxLogXXX() functions from this file will use this log component
36 #define wxLOG_COMPONENT "test"
38 // ----------------------------------------------------------------------------
40 // ----------------------------------------------------------------------------
42 // base class for all test loggers which simply store all logged messages for
43 // future examination in the test code
44 class TestLogBase
: public wxLog
49 const wxString
& GetLog(wxLogLevel level
) const
54 const wxLogRecordInfo
& GetInfo(wxLogLevel level
) const
56 return m_logsInfo
[level
];
61 for ( unsigned n
= 0; n
< WXSIZEOF(m_logs
); n
++ )
64 m_logsInfo
[n
] = wxLogRecordInfo();
69 wxString m_logs
[wxLOG_Trace
+ 1];
70 wxLogRecordInfo m_logsInfo
[wxLOG_Trace
+ 1];
72 wxDECLARE_NO_COPY_CLASS(TestLogBase
);
75 // simple log sink which just stores the messages logged for each level
76 class TestLog
: public TestLogBase
82 virtual void DoLogRecord(wxLogLevel level
,
84 const wxLogRecordInfo
& info
)
87 m_logsInfo
[level
] = info
;
91 wxDECLARE_NO_COPY_CLASS(TestLog
);
94 #if WXWIN_COMPATIBILITY_2_8
96 // log sink overriding the old DoLogXXX() functions should still work too
98 // this one overrides DoLog(char*)
99 class CompatTestLog
: public TestLogBase
105 virtual void DoLog(wxLogLevel level
, const char *str
, time_t WXUNUSED(t
))
110 // get rid of the warning about hiding the other overload
111 virtual void DoLog(wxLogLevel
WXUNUSED(level
),
112 const wchar_t *WXUNUSED(str
),
118 wxDECLARE_NO_COPY_CLASS(CompatTestLog
);
121 // and this one overload DoLogString(wchar_t*)
122 class CompatTestLog2
: public wxLog
127 const wxString
& Get() const { return m_msg
; }
130 virtual void DoLogString(const wchar_t *msg
, time_t WXUNUSED(t
))
135 // get rid of the warning
136 virtual void DoLogString(const char *WXUNUSED(msg
), time_t WXUNUSED(t
))
143 wxDECLARE_NO_COPY_CLASS(CompatTestLog2
);
146 #endif // WXWIN_COMPATIBILITY_2_8
148 // ----------------------------------------------------------------------------
150 // ----------------------------------------------------------------------------
152 class LogTestCase
: public CppUnit::TestCase
157 virtual void setUp();
158 virtual void tearDown();
161 CPPUNIT_TEST_SUITE( LogTestCase
);
162 CPPUNIT_TEST( Functions
);
163 CPPUNIT_TEST( Null
);
164 CPPUNIT_TEST( Component
);
166 CPPUNIT_TEST( Trace
);
167 #endif // wxDEBUG_LEVEL
168 #if WXWIN_COMPATIBILITY_2_8
169 CPPUNIT_TEST( CompatLogger
);
170 CPPUNIT_TEST( CompatLogger2
);
171 #endif // WXWIN_COMPATIBILITY_2_8
172 CPPUNIT_TEST( SysError
);
173 CPPUNIT_TEST_SUITE_END();
180 #endif // wxDEBUG_LEVEL
181 #if WXWIN_COMPATIBILITY_2_8
183 void CompatLogger2();
184 #endif // WXWIN_COMPATIBILITY_2_8
189 bool m_logWasEnabled
;
191 wxDECLARE_NO_COPY_CLASS(LogTestCase
);
194 // register in the unnamed registry so that these tests are run by default
195 CPPUNIT_TEST_SUITE_REGISTRATION( LogTestCase
);
197 // also include in it's own registry so that these tests can be run alone
198 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( LogTestCase
, "LogTestCase" );
200 void LogTestCase::setUp()
202 m_logOld
= wxLog::SetActiveTarget(m_log
= new TestLog
);
203 m_logWasEnabled
= wxLog::EnableLogging();
206 void LogTestCase::tearDown()
208 delete wxLog::SetActiveTarget(m_logOld
);
209 wxLog::EnableLogging(m_logWasEnabled
);
212 void LogTestCase::Functions()
214 wxLogMessage("Message");
215 CPPUNIT_ASSERT_EQUAL( "Message", m_log
->GetLog(wxLOG_Message
) );
217 wxLogError("Error %d", 17);
218 CPPUNIT_ASSERT_EQUAL( "Error 17", m_log
->GetLog(wxLOG_Error
) );
222 CPPUNIT_ASSERT_EQUAL( "Debug", m_log
->GetLog(wxLOG_Debug
) );
224 CPPUNIT_ASSERT_EQUAL( "", m_log
->GetLog(wxLOG_Debug
) );
228 void LogTestCase::Null()
232 wxLogWarning("%s warning", "Not important");
234 CPPUNIT_ASSERT_EQUAL( "", m_log
->GetLog(wxLOG_Warning
) );
237 wxLogWarning("%s warning", "Important");
238 CPPUNIT_ASSERT_EQUAL( "Important warning", m_log
->GetLog(wxLOG_Warning
) );
241 void LogTestCase::Component()
243 wxLogMessage("Message");
244 CPPUNIT_ASSERT_EQUAL( wxLOG_COMPONENT
,
245 m_log
->GetInfo(wxLOG_Message
).component
);
247 // completely disable logging for this component
248 wxLog::SetComponentLevel("test/ignore", wxLOG_FatalError
);
250 // but enable it for one of its subcomponents
251 wxLog::SetComponentLevel("test/ignore/not", wxLOG_Max
);
253 #undef wxLOG_COMPONENT
254 #define wxLOG_COMPONENT "test/ignore"
256 // this shouldn't be output as this component is ignored
258 CPPUNIT_ASSERT_EQUAL( "", m_log
->GetLog(wxLOG_Error
) );
260 // and so are its subcomponents
261 #undef wxLOG_COMPONENT
262 #define wxLOG_COMPONENT "test/ignore/sub/subsub"
264 CPPUNIT_ASSERT_EQUAL( "", m_log
->GetLog(wxLOG_Error
) );
266 // but one subcomponent is not
267 #undef wxLOG_COMPONENT
268 #define wxLOG_COMPONENT "test/ignore/not"
270 CPPUNIT_ASSERT_EQUAL( "Error", m_log
->GetLog(wxLOG_Error
) );
272 // restore the original value
273 #undef wxLOG_COMPONENT
274 #define wxLOG_COMPONENT "test"
282 const char *TEST_MASK
= "test";
284 // this is a test vararg function (a real one, not a variadic-template-like as
285 // wxVLogTrace(), so care should be taken with its arguments)
286 void TraceTest(const char *format
, ...)
289 va_start(argptr
, format
);
290 wxVLogTrace(TEST_MASK
, format
, argptr
);
294 } // anonymous namespace
296 void LogTestCase::Trace()
298 // we use wxLogTrace() or wxVLogTrace() from inside TraceTest()
299 // interchangeably here, it shouldn't make any difference
301 wxLogTrace(TEST_MASK
, "Not shown");
302 CPPUNIT_ASSERT_EQUAL( "", m_log
->GetLog(wxLOG_Trace
) );
304 wxLog::AddTraceMask(TEST_MASK
);
306 CPPUNIT_ASSERT_EQUAL( wxString::Format("(%s) Shown", TEST_MASK
),
307 m_log
->GetLog(wxLOG_Trace
) );
309 wxLog::RemoveTraceMask(TEST_MASK
);
312 TraceTest("Not shown again");
313 CPPUNIT_ASSERT_EQUAL( "", m_log
->GetLog(wxLOG_Trace
) );
316 #endif // wxDEBUG_LEVEL
318 #if WXWIN_COMPATIBILITY_2_8
320 void LogTestCase::CompatLogger()
323 wxLog
* const logOld
= wxLog::SetActiveTarget(&log
);
324 wxON_BLOCK_EXIT1( wxLog::SetActiveTarget
, logOld
);
326 wxLogError("Old error");
327 CPPUNIT_ASSERT_EQUAL( "Old error", log
.GetLog(wxLOG_Error
) );
330 void LogTestCase::CompatLogger2()
333 wxLog
* const logOld
= wxLog::SetActiveTarget(&log
);
334 wxON_BLOCK_EXIT1( wxLog::SetActiveTarget
, logOld
);
336 wxLogWarning("Old warning");
337 CPPUNIT_ASSERT_EQUAL( "Old warning", log
.Get() );
340 #endif // WXWIN_COMPATIBILITY_2_8
342 void LogTestCase::SysError()
346 wxLogSysError(17, "Error");
347 CPPUNIT_ASSERT( m_log
->GetLog(wxLOG_Error
).StartsWith("Error (", &s
) );
348 WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s
), s
.StartsWith("error 17") );
350 // The last error code seems to be set somewhere in MinGW CRT as its value
351 // is just not what we expect (ERROR_INVALID_PARAMETER instead of 0 and 0
352 // instead of ERROR_FILE_NOT_FOUND) so exclude the tests which rely on last
353 // error being preserved for this compiler.
355 wxLogSysError("Success");
356 CPPUNIT_ASSERT( m_log
->GetLog(wxLOG_Error
).StartsWith("Success (", &s
) );
357 WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s
), s
.StartsWith("error 0") );
359 wxOpen("no-such-file", 0, 0);
360 wxLogSysError("Not found");
361 CPPUNIT_ASSERT( m_log
->GetLog(wxLOG_Error
).StartsWith("Not found (", &s
) );
362 WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s
), s
.StartsWith("error 2") );
363 #endif // __MINGW32__