]> git.saurik.com Git - wxWidgets.git/blame - tests/test.cpp
define wxUSE_REGKEY for WinCE too (closes #10211)
[wxWidgets.git] / tests / test.cpp
CommitLineData
670ec357
VS
1///////////////////////////////////////////////////////////////////////////////
2// Name: test.cpp
3// Purpose: Test program for wxWidgets
4// Author: Mike Wetherell
5// RCS-ID: $Id$
6// Copyright: (c) 2004 Mike Wetherell
7// Licence: wxWidgets licence
8///////////////////////////////////////////////////////////////////////////////
9
8899b155
RN
10// For compilers that support precompilation, includes "wx/wx.h"
11// and "wx/cppunit.h"
12#include "testprec.h"
670ec357
VS
13
14#ifdef __BORLANDC__
15 #pragma hdrstop
16#endif
17
18// for all others, include the necessary headers
19#ifndef WX_PRECOMP
20 #include "wx/wx.h"
21#endif
22
afd90468 23#include "wx/beforestd.h"
6d9407fe
VZ
24#ifdef __VISUALC__
25 #pragma warning(disable:4100)
26#endif
afd90468 27#include <cppunit/TestListener.h>
6d9407fe
VZ
28#ifdef __VISUALC__
29 #pragma warning(default:4100)
30#endif
afd90468
VZ
31#include <cppunit/Test.h>
32#include <cppunit/TestResult.h>
33#include "wx/afterstd.h"
34
670ec357 35#include "wx/cmdline.h"
670ec357
VS
36#include <iostream>
37
3e5f6c1c
WS
38using CppUnit::Test;
39using CppUnit::TestSuite;
40using CppUnit::TestFactoryRegistry;
3e5f6c1c 41
afd90468 42
6d9407fe
VZ
43// Displays the test name before starting to execute it: this helps with
44// diagnosing where exactly does a test crash or hang when/if it does.
afd90468
VZ
45class DetailListener : public CppUnit::TestListener
46{
47public:
48 DetailListener(bool doTiming = false):
49 CppUnit::TestListener(),
50 m_timing(doTiming)
51 {
52 }
53
54 virtual void startTest(CppUnit::Test *test)
55 {
6d9407fe 56 std::cout << test->getName () << " ";
afd90468
VZ
57 m_watch.Start();
58 }
59
60 virtual void endTest(CppUnit::Test * WXUNUSED(test))
61 {
62 m_watch.Pause();
63 if ( m_timing )
6d9407fe
VZ
64 std::cout << " (in "<< m_watch.Time() << " ms )";
65 std::cout << "\n";
afd90468
VZ
66 }
67
68protected :
69 bool m_timing;
70 wxStopWatch m_watch;
71};
72
5098c258 73using namespace std;
670ec357 74
c0d9b217
VZ
75#if wxUSE_GUI
76 typedef wxApp TestAppBase;
77#else
78 typedef wxAppConsole TestAppBase;
79#endif
80
670ec357
VS
81// The application class
82//
c0d9b217 83class TestApp : public TestAppBase
670ec357
VS
84{
85public:
86 TestApp();
87
88 // standard overrides
c0d9b217
VZ
89 virtual void OnInitCmdLine(wxCmdLineParser& parser);
90 virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
91 virtual bool OnInit();
92 virtual int OnRun();
93 virtual int OnExit();
670ec357
VS
94
95private:
8dae9169 96 void List(Test *test, const string& parent = "") const;
670ec357
VS
97
98 // command lines options/parameters
99 bool m_list;
a81f3066 100 bool m_longlist;
afd90468
VZ
101 bool m_detail;
102 bool m_timing;
a81f3066 103 vector<string> m_registries;
670ec357
VS
104};
105
106IMPLEMENT_APP_CONSOLE(TestApp)
107
108TestApp::TestApp()
8dae9169
VS
109 : m_list(false),
110 m_longlist(false)
670ec357
VS
111{
112}
113
114// Init
115//
116bool TestApp::OnInit()
117{
c0d9b217
VZ
118 if ( !TestAppBase::OnInit() )
119 return false;
120
670ec357 121 cout << "Test program for wxWidgets\n"
3e5f6c1c 122 << "build: " << WX_BUILD_OPTIONS_SIGNATURE << std::endl;
9f7a07ab 123
c0d9b217
VZ
124#if wxUSE_GUI
125 // create a hidden parent window to be used as parent for the GUI controls
126 new wxFrame(NULL, wxID_ANY, "Hidden wx test frame");
127#endif // wxUSE_GUI
128
129 return true;
9f10e7c7 130}
670ec357
VS
131
132// The table of command line options
133//
134void TestApp::OnInitCmdLine(wxCmdLineParser& parser)
135{
c0d9b217 136 TestAppBase::OnInitCmdLine(parser);
670ec357
VS
137
138 static const wxCmdLineEntryDesc cmdLineDesc[] = {
aa3b041e
VZ
139 { wxCMD_LINE_SWITCH, "l", "list",
140 "list the test suites, do not run them",
a81f3066 141 wxCMD_LINE_VAL_NONE, 0 },
aa3b041e
VZ
142 { wxCMD_LINE_SWITCH, "L", "longlist",
143 "list the test cases, do not run them",
670ec357 144 wxCMD_LINE_VAL_NONE, 0 },
afd90468
VZ
145 { wxCMD_LINE_SWITCH, "d", "detail",
146 "print the test case names, run them",
147 wxCMD_LINE_VAL_NONE, 0 },
148 { wxCMD_LINE_SWITCH, "t", "timing",
149 "print names and mesure running time of individual test, run them",
150 wxCMD_LINE_VAL_NONE, 0 },
aa3b041e 151 { wxCMD_LINE_PARAM, NULL, NULL, "REGISTRY", wxCMD_LINE_VAL_STRING,
a81f3066 152 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE },
aa3b041e 153 wxCMD_LINE_DESC_END
670ec357
VS
154 };
155
156 parser.SetDesc(cmdLineDesc);
157}
158
159// Handle command line options
160//
161bool TestApp::OnCmdLineParsed(wxCmdLineParser& parser)
162{
a81f3066
VS
163 if (parser.GetParamCount())
164 for (size_t i = 0; i < parser.GetParamCount(); i++)
165 m_registries.push_back(string(parser.GetParam(i).mb_str()));
166 else
167 m_registries.push_back("");
3e5f6c1c 168
a81f3066
VS
169 m_longlist = parser.Found(_T("longlist"));
170 m_list = m_longlist || parser.Found(_T("list"));
afd90468
VZ
171 m_timing = parser.Found(_T("timing"));
172 m_detail = !m_timing && parser.Found(_T("detail"));
670ec357 173
c0d9b217 174 return TestAppBase::OnCmdLineParsed(parser);
670ec357
VS
175}
176
177// Run
178//
179int TestApp::OnRun()
180{
2976d6cb 181 CppUnit::TextTestRunner runner;
a81f3066
VS
182
183 for (size_t i = 0; i < m_registries.size(); i++) {
184 auto_ptr<Test> test(m_registries[i].empty() ?
185 TestFactoryRegistry::getRegistry().makeTest() :
186 TestFactoryRegistry::getRegistry(m_registries[i]).makeTest());
187
188 TestSuite *suite = dynamic_cast<TestSuite*>(test.get());
189
190 if (suite && suite->countTestCases() == 0)
191 wxLogError(_T("No such test suite: %s"),
192 wxString(m_registries[i].c_str(), wxConvUTF8).c_str());
193 else if (m_list)
194 List(test.get());
195 else
196 runner.addTest(test.release());
670ec357 197 }
a81f3066 198
2976d6cb
VZ
199 if ( m_list )
200 return EXIT_SUCCESS;
201
202 runner.setOutputter(new CppUnit::CompilerOutputter(&runner.result(), cout));
14dc53b2 203
86ca2b4c 204#if wxUSE_LOG
a81f3066 205 // Switch off logging unless --verbose
3e5f6c1c
WS
206 bool verbose = wxLog::GetVerbose();
207 wxLog::EnableLogging(verbose);
86ca2b4c 208#else
3e5f6c1c
WS
209 bool verbose = false;
210#endif
211
2976d6cb
VZ
212 // there is a bug
213 // (http://sf.net/tracker/index.php?func=detail&aid=1649369&group_id=11795&atid=111795)
214 // in some versions of cppunit: they write progress dots to cout (and not
215 // cerr) and don't flush it so all the dots appear at once at the end which
216 // is not very useful so unbuffer cout to work around this
217 cout.setf(ios::unitbuf);
218
afd90468
VZ
219 // add detail listener if needed
220 DetailListener detailListener(m_timing);
221 if ( m_detail || m_timing )
222 runner.eventManager().addListener(&detailListener);
223
2976d6cb 224 return runner.run("", false, true, !verbose) ? EXIT_SUCCESS : EXIT_FAILURE;
670ec357
VS
225}
226
c0d9b217
VZ
227int TestApp::OnExit()
228{
229#if wxUSE_GUI
230 delete GetTopWindow();
231#endif // wxUSE_GUI
232
233 return 0;
234}
235
670ec357
VS
236// List the tests
237//
8dae9169 238void TestApp::List(Test *test, const string& parent /*=""*/) const
670ec357 239{
670ec357 240 TestSuite *suite = dynamic_cast<TestSuite*>(test);
8dae9169
VS
241 string name;
242
bc10103e 243 if (suite) {
8dae9169
VS
244 // take the last component of the name and append to the parent
245 name = test->getName();
246 string::size_type i = name.find_last_of(".:");
f44eaed6
RN
247 if (i != string::npos)
248 name = name.substr(i + 1);
249 name = parent + "." + name;
8dae9169
VS
250
251 // drop the 1st component from the display and indent
252 if (parent != "") {
253 string::size_type j = i = name.find('.', 1);
254 while ((j = name.find('.', j + 1)) != string::npos)
255 cout << " ";
256 cout << " " << name.substr(i + 1) << "\n";
257 }
a81f3066 258
f69577be 259 typedef vector<Test*> Tests;
670ec357
VS
260 typedef Tests::const_iterator Iter;
261
f69577be 262 const Tests& tests = suite->getTests();
670ec357
VS
263
264 for (Iter it = tests.begin(); it != tests.end(); ++it)
8dae9169 265 List(*it, name);
670ec357 266 }
bc10103e
VS
267 else if (m_longlist) {
268 string::size_type i = 0;
269 while ((i = parent.find('.', i + 1)) != string::npos)
270 cout << " ";
271 cout << " " << test->getName() << "\n";
272 }
670ec357 273}