1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/log/logtest.cpp
3 // Purpose: wxLog unit test
4 // Author: Vadim Zeitlin
6 // Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
7 ///////////////////////////////////////////////////////////////////////////////
9 // ----------------------------------------------------------------------------
11 // ----------------------------------------------------------------------------
21 #include "wx/filefn.h"
24 #include "wx/scopeguard.h"
26 #if WXWIN_COMPATIBILITY_2_8
27 // we override deprecated DoLog() and DoLogString() in this test, suppress
29 #if wxCHECK_VISUALC_VERSION(7)
30 #pragma warning(disable: 4996)
32 #endif // WXWIN_COMPATIBILITY_2_8
34 // all calls to wxLogXXX() functions from this file will use this log component
35 #define wxLOG_COMPONENT "test"
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 // base class for all test loggers which simply store all logged messages for
42 // future examination in the test code
43 class TestLogBase
: public wxLog
48 const wxString
& GetLog(wxLogLevel level
) const
53 const wxLogRecordInfo
& GetInfo(wxLogLevel level
) const
55 return m_logsInfo
[level
];
60 for ( unsigned n
= 0; n
< WXSIZEOF(m_logs
); n
++ )
63 m_logsInfo
[n
] = wxLogRecordInfo();
68 wxString m_logs
[wxLOG_Trace
+ 1];
69 wxLogRecordInfo m_logsInfo
[wxLOG_Trace
+ 1];
71 wxDECLARE_NO_COPY_CLASS(TestLogBase
);
74 // simple log sink which just stores the messages logged for each level
75 class TestLog
: public TestLogBase
81 virtual void DoLogRecord(wxLogLevel level
,
83 const wxLogRecordInfo
& info
)
86 m_logsInfo
[level
] = info
;
90 wxDECLARE_NO_COPY_CLASS(TestLog
);
93 #if WXWIN_COMPATIBILITY_2_8
95 // log sink overriding the old DoLogXXX() functions should still work too
97 // this one overrides DoLog(char*)
98 class CompatTestLog
: public TestLogBase
104 virtual void DoLog(wxLogLevel level
, const char *str
, time_t WXUNUSED(t
))
109 // get rid of the warning about hiding the other overload
110 virtual void DoLog(wxLogLevel
WXUNUSED(level
),
111 const wchar_t *WXUNUSED(str
),
117 wxDECLARE_NO_COPY_CLASS(CompatTestLog
);
120 // and this one overload DoLogString(wchar_t*)
121 class CompatTestLog2
: public wxLog
126 const wxString
& Get() const { return m_msg
; }
129 virtual void DoLogString(const wchar_t *msg
, time_t WXUNUSED(t
))
134 // get rid of the warning
135 virtual void DoLogString(const char *WXUNUSED(msg
), time_t WXUNUSED(t
))
142 wxDECLARE_NO_COPY_CLASS(CompatTestLog2
);
145 #endif // WXWIN_COMPATIBILITY_2_8
147 // ----------------------------------------------------------------------------
149 // ----------------------------------------------------------------------------
151 class LogTestCase
: public CppUnit::TestCase
156 virtual void setUp();
157 virtual void tearDown();
160 CPPUNIT_TEST_SUITE( LogTestCase
);
161 CPPUNIT_TEST( Functions
);
162 CPPUNIT_TEST( Null
);
163 CPPUNIT_TEST( Component
);
165 CPPUNIT_TEST( Trace
);
166 #endif // wxDEBUG_LEVEL
167 #if WXWIN_COMPATIBILITY_2_8
168 CPPUNIT_TEST( CompatLogger
);
169 CPPUNIT_TEST( CompatLogger2
);
170 #endif // WXWIN_COMPATIBILITY_2_8
171 CPPUNIT_TEST( SysError
);
172 CPPUNIT_TEST( NoWarnings
);
173 CPPUNIT_TEST_SUITE_END();
180 #endif // wxDEBUG_LEVEL
181 #if WXWIN_COMPATIBILITY_2_8
183 void CompatLogger2();
184 #endif // WXWIN_COMPATIBILITY_2_8
190 bool m_logWasEnabled
;
192 wxDECLARE_NO_COPY_CLASS(LogTestCase
);
195 // register in the unnamed registry so that these tests are run by default
196 CPPUNIT_TEST_SUITE_REGISTRATION( LogTestCase
);
198 // also include in its own registry so that these tests can be run alone
199 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( LogTestCase
, "LogTestCase" );
201 void LogTestCase::setUp()
203 m_logOld
= wxLog::SetActiveTarget(m_log
= new TestLog
);
204 m_logWasEnabled
= wxLog::EnableLogging();
207 void LogTestCase::tearDown()
209 delete wxLog::SetActiveTarget(m_logOld
);
210 wxLog::EnableLogging(m_logWasEnabled
);
213 void LogTestCase::Functions()
215 wxLogMessage("Message");
216 CPPUNIT_ASSERT_EQUAL( "Message", m_log
->GetLog(wxLOG_Message
) );
218 wxLogError("Error %d", 17);
219 CPPUNIT_ASSERT_EQUAL( "Error 17", m_log
->GetLog(wxLOG_Error
) );
223 CPPUNIT_ASSERT_EQUAL( "Debug", m_log
->GetLog(wxLOG_Debug
) );
225 CPPUNIT_ASSERT_EQUAL( "", m_log
->GetLog(wxLOG_Debug
) );
229 void LogTestCase::Null()
233 wxLogWarning("%s warning", "Not important");
235 CPPUNIT_ASSERT_EQUAL( "", m_log
->GetLog(wxLOG_Warning
) );
238 wxLogWarning("%s warning", "Important");
239 CPPUNIT_ASSERT_EQUAL( "Important warning", m_log
->GetLog(wxLOG_Warning
) );
242 void LogTestCase::Component()
244 wxLogMessage("Message");
245 CPPUNIT_ASSERT_EQUAL( wxLOG_COMPONENT
,
246 m_log
->GetInfo(wxLOG_Message
).component
);
248 // completely disable logging for this component
249 wxLog::SetComponentLevel("test/ignore", wxLOG_FatalError
);
251 // but enable it for one of its subcomponents
252 wxLog::SetComponentLevel("test/ignore/not", wxLOG_Max
);
254 #undef wxLOG_COMPONENT
255 #define wxLOG_COMPONENT "test/ignore"
257 // this shouldn't be output as this component is ignored
259 CPPUNIT_ASSERT_EQUAL( "", m_log
->GetLog(wxLOG_Error
) );
261 // and so are its subcomponents
262 #undef wxLOG_COMPONENT
263 #define wxLOG_COMPONENT "test/ignore/sub/subsub"
265 CPPUNIT_ASSERT_EQUAL( "", m_log
->GetLog(wxLOG_Error
) );
267 // but one subcomponent is not
268 #undef wxLOG_COMPONENT
269 #define wxLOG_COMPONENT "test/ignore/not"
271 CPPUNIT_ASSERT_EQUAL( "Error", m_log
->GetLog(wxLOG_Error
) );
273 // restore the original value
274 #undef wxLOG_COMPONENT
275 #define wxLOG_COMPONENT "test"
283 const char *TEST_MASK
= "test";
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)
287 void TraceTest(const char *format
, ...)
290 va_start(argptr
, format
);
291 wxVLogTrace(TEST_MASK
, format
, argptr
);
295 } // anonymous namespace
297 void LogTestCase::Trace()
299 // we use wxLogTrace() or wxVLogTrace() from inside TraceTest()
300 // interchangeably here, it shouldn't make any difference
302 wxLogTrace(TEST_MASK
, "Not shown");
303 CPPUNIT_ASSERT_EQUAL( "", m_log
->GetLog(wxLOG_Trace
) );
305 wxLog::AddTraceMask(TEST_MASK
);
307 CPPUNIT_ASSERT_EQUAL( wxString::Format("(%s) Shown", TEST_MASK
),
308 m_log
->GetLog(wxLOG_Trace
) );
310 wxLog::RemoveTraceMask(TEST_MASK
);
313 TraceTest("Not shown again");
314 CPPUNIT_ASSERT_EQUAL( "", m_log
->GetLog(wxLOG_Trace
) );
317 #endif // wxDEBUG_LEVEL
319 #if WXWIN_COMPATIBILITY_2_8
321 void LogTestCase::CompatLogger()
324 wxLog
* const logOld
= wxLog::SetActiveTarget(&log
);
325 wxON_BLOCK_EXIT1( wxLog::SetActiveTarget
, logOld
);
327 wxLogError("Old error");
328 CPPUNIT_ASSERT_EQUAL( "Old error", log
.GetLog(wxLOG_Error
) );
331 void LogTestCase::CompatLogger2()
334 wxLog
* const logOld
= wxLog::SetActiveTarget(&log
);
335 wxON_BLOCK_EXIT1( wxLog::SetActiveTarget
, logOld
);
337 wxLogWarning("Old warning");
338 CPPUNIT_ASSERT_EQUAL( "Old warning", log
.Get() );
341 #endif // WXWIN_COMPATIBILITY_2_8
343 void LogTestCase::SysError()
347 wxLogSysError(17, "Error");
348 CPPUNIT_ASSERT( m_log
->GetLog(wxLOG_Error
).StartsWith("Error (", &s
) );
349 WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s
), s
.StartsWith("error 17") );
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.
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") );
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") );
364 #endif // __MINGW32__
367 void LogTestCase::NoWarnings()
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).
374 wxLogError("Not logged");
383 CPPUNIT_FAIL("Should not be taken");
385 CPPUNIT_ASSERT_EQUAL( "If", m_log
->GetLog(wxLOG_Error
) );