comparison 3rdparty/vmime/tests/testRunner.cpp @ 0:a4671277546c tip

created the repository for the thymian project
author ferencd
date Tue, 17 Aug 2021 11:19:54 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:a4671277546c
1 //
2 // VMime library (http://www.vmime.org)
3 // Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 3 of
8 // the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 //
19 // Linking this library statically or dynamically with other modules is making
20 // a combined work based on this library. Thus, the terms and conditions of
21 // the GNU General Public License cover the whole combination.
22 //
23
24 #include <sys/time.h>
25 #include <time.h>
26
27 #include <iostream>
28 #include <vector>
29 #include <algorithm>
30 #include <memory>
31
32 #include <cppunit/XmlOutputter.h>
33 #include <cppunit/extensions/TestFactoryRegistry.h>
34 #include <cppunit/ui/text/TestRunner.h>
35 #include <cppunit/TestListener.h>
36 #include <cppunit/TestResult.h>
37 #include <cppunit/TestResultCollector.h>
38 #include <cppunit/TestFailure.h>
39 #include <cppunit/SourceLine.h>
40 #include <cppunit/Exception.h>
41 #include <cppunit/tools/XmlDocument.h>
42 #include <cppunit/tools/XmlElement.h>
43
44 #include "vmime/vmime.hpp"
45 #include "vmime/platforms/posix/posixHandler.hpp"
46
47
48 class Clock
49 {
50 public:
51
52 void reset()
53 {
54 struct timezone tz;
55
56 gettimeofday(&m_start, &tz);
57 }
58
59 double getDuration() const
60 {
61 struct timeval tv;
62 struct timezone tz;
63
64 gettimeofday(&tv, &tz);
65
66 return static_cast <double>(tv.tv_sec - m_start.tv_sec)
67 + static_cast <double>(tv.tv_usec - m_start.tv_usec) / 1000000.0;
68 }
69
70 private:
71
72 struct timeval m_start;
73 };
74
75
76 class XmlTestListener : public CppUnit::TestListener
77 {
78 public:
79
80 XmlTestListener()
81 : m_doc("utf-8"), m_testElt(NULL)
82 {
83 m_doc.setRootElement(new CppUnit::XmlElement("TestRun"));
84 }
85
86 void startTest(CppUnit::Test* test)
87 {
88 m_testElt = new CppUnit::XmlElement("Test");
89 m_suiteElt.back()->addElement(m_testElt);
90
91 m_testElt->addElement(new CppUnit::XmlElement("Name", test->getName()));
92
93 m_chrono.reset();
94 }
95
96 void addFailure(const CppUnit::TestFailure& failure)
97 {
98 CppUnit::XmlElement* failElt = new CppUnit::XmlElement("Failure");
99 m_testElt->addElement(failElt);
100
101 failElt->addElement(new CppUnit::XmlElement("FailureType",
102 failure.isError() ? "Error" : "Assertion"));
103
104 if (failure.sourceLine().isValid())
105 {
106 CppUnit::XmlElement* locElt = new CppUnit::XmlElement("Location");
107 failElt->addElement(locElt);
108
109 locElt->addElement(new CppUnit::XmlElement("File", failure.sourceLine().fileName()));
110 locElt->addElement(new CppUnit::XmlElement("Line", failure.sourceLine().lineNumber()));
111 }
112
113 CppUnit::XmlElement* exElt = new CppUnit::XmlElement("Exception");
114 failElt->addElement(exElt);
115
116 exElt->addElement(new CppUnit::XmlElement("Message", failure.thrownException()->what()));
117 }
118
119 void endTest(CppUnit::Test* /* test */)
120 {
121 std::ostringstream ossTime;
122 ossTime << (m_chrono.getDuration() * 1000.0);
123
124 m_testElt->addElement(new CppUnit::XmlElement("Time", ossTime.str()));
125
126 m_testElt = NULL;
127 }
128
129 void startSuite(CppUnit::Test* suite)
130 {
131 if (suite->getName() == "All Tests")
132 return;
133
134 CppUnit::XmlElement* suiteElt = new CppUnit::XmlElement("Suite");
135
136 if (m_suiteElt.size() == 0)
137 m_doc.rootElement().addElement(suiteElt);
138 else
139 m_suiteElt.back()->addElement(suiteElt);
140
141 m_suiteElt.push_back(suiteElt);
142
143 suiteElt->addElement(new CppUnit::XmlElement("Name", suite->getName()));
144 }
145
146 void endSuite(CppUnit::Test* /* suite */)
147 {
148 if (m_suiteElt.size())
149 m_suiteElt.pop_back();
150 }
151
152 void startTestRun(CppUnit::Test* /* test */, CppUnit::TestResult* /* eventManager */)
153 {
154 }
155
156 void endTestRun(CppUnit::Test* /* test */, CppUnit::TestResult* /* eventManager */)
157 {
158 }
159
160 void output(std::ostream& os)
161 {
162 os << m_doc.toString();
163 }
164
165 private:
166
167 Clock m_chrono;
168
169 CppUnit::XmlDocument m_doc;
170 std::vector <CppUnit::XmlElement*> m_suiteElt;
171 CppUnit::XmlElement* m_testElt;
172 };
173
174
175
176 // see testUtils.hpp
177
178 std::vector <std::string>& getTestModules()
179 {
180 static std::vector <std::string> allModules;
181 return allModules;
182 }
183
184
185 void registerTestModule(const char* name_)
186 {
187 std::vector <std::string>& testModules = getTestModules();
188 std::string name(name_);
189
190 if (std::find(testModules.begin(), testModules.end(), name) == testModules.end())
191 testModules.push_back(name);
192 }
193
194
195 const std::string getNormalizedPath(const std::string& path)
196 {
197 std::string res = path;
198
199 for (std::size_t i = 0, n = res.length() ; i < n ; ++i)
200 {
201 if (res[i] == '\\')
202 res[i] = '/';
203 }
204
205 return res;
206 }
207
208
209 const std::string getFileNameFromPath(const std::string& path)
210 {
211 const std::size_t pos = path.find_last_of('/');
212
213 if (pos == std::string::npos)
214 return "";
215
216 return path.substr(pos + 1);
217 }
218
219
220 static char g_moduleNameBuffer[2048];
221
222
223 const char* getTestModuleNameFromSourceFile(const char *path_)
224 {
225 static const std::string testRunnerPath(getNormalizedPath(__FILE__));
226 static const std::string testRunnerFileName(getFileNameFromPath(testRunnerPath));
227
228 const std::string path = getNormalizedPath(path_);
229
230 // "/path/to/testRunner.cpp" --> "/path/to/"
231 const std::string basePath
232 (testRunnerPath.begin(), testRunnerPath.end() - testRunnerFileName.length());
233
234 // "/path/to/module/testFile.cpp" --> "module/testFile.cpp"
235 const std::string testFileName(getFileNameFromPath(path));
236 const std::string testPath(path.begin() + basePath.length(), path.end());
237
238 // "module/testFile.cpp" --> "module"
239 const std::string moduleName(testPath.substr(0, testPath.length() - testFileName.length() - 1));
240 std::copy(moduleName.begin(), moduleName.end(), g_moduleNameBuffer);
241 g_moduleNameBuffer[moduleName.length()] = 0;
242
243 return g_moduleNameBuffer;
244 }
245
246
247 int main(int argc, char* argv[])
248 {
249 // Parse arguments
250 bool xmlOutput = false;
251
252 for (int c = 1 ; c < argc ; ++c)
253 {
254 const std::string arg = argv[c];
255
256 if (arg == "--xml")
257 xmlOutput = true;
258 }
259
260 // Run the tests
261 if (xmlOutput)
262 {
263 // Get the test suites from the registry and add them to the list of tests to run
264 CppUnit::TestRunner runner;
265
266 for (unsigned int i = 0 ; i < getTestModules().size() ; ++i)
267 {
268 runner.addTest(CppUnit::TestFactoryRegistry::
269 getRegistry(getTestModules()[i]).makeTest());
270 }
271
272 std::auto_ptr <XmlTestListener> xmlListener(new XmlTestListener);
273
274 CppUnit::TestResult controller;
275 controller.addListener(xmlListener.get());
276
277 CppUnit::TestResultCollector result;
278 controller.addListener(&result);
279
280 runner.run(controller);
281
282 xmlListener->output(std::cout);
283
284 // Return error code 1 if a test failed
285 return result.wasSuccessful() ? 0 : 1;
286 }
287 else
288 {
289 // Get the top level suite from the registry
290 CppUnit::TextUi::TestRunner runner;
291 runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
292
293 return runner.run() ? 0 : 1;
294 }
295 }
296