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