]> git.saurik.com Git - wxWidgets.git/blob - tests/log/logtest.cpp
Try to avoid accidental use of wxXmlNode in XRC handlers.
[wxWidgets.git] / tests / log / logtest.cpp
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
44 class TestLogBase : public wxLog
45 {
46 public:
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
68 protected:
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
76 class TestLog : public TestLogBase
77 {
78 public:
79 TestLog() { }
80
81 protected:
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
90 private:
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*)
99 class CompatTestLog : public TestLogBase
100 {
101 public:
102 CompatTestLog() { }
103
104 protected:
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
117 private:
118 wxDECLARE_NO_COPY_CLASS(CompatTestLog);
119 };
120
121 // and this one overload DoLogString(wchar_t*)
122 class CompatTestLog2 : public wxLog
123 {
124 public:
125 CompatTestLog2() { }
126
127 const wxString& Get() const { return m_msg; }
128
129 protected:
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
140 private:
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
152 class LogTestCase : public CppUnit::TestCase
153 {
154 public:
155 LogTestCase() { }
156
157 virtual void setUp();
158 virtual void tearDown();
159
160 private:
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
195 CPPUNIT_TEST_SUITE_REGISTRATION( LogTestCase );
196
197 // also include in its own registry so that these tests can be run alone
198 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( LogTestCase, "LogTestCase" );
199
200 void LogTestCase::setUp()
201 {
202 m_logOld = wxLog::SetActiveTarget(m_log = new TestLog);
203 m_logWasEnabled = wxLog::EnableLogging();
204 }
205
206 void LogTestCase::tearDown()
207 {
208 delete wxLog::SetActiveTarget(m_logOld);
209 wxLog::EnableLogging(m_logWasEnabled);
210 }
211
212 void 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
228 void 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
241 void 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
279 namespace
280 {
281
282 const 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)
286 void 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
296 void 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
320 void 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
330 void 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
342 void 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