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