diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/vmime/tests/testRunner.cpp	Tue Aug 17 11:19:54 2021 +0200
@@ -0,0 +1,296 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 3 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Linking this library statically or dynamically with other modules is making
+// a combined work based on this library.  Thus, the terms and conditions of
+// the GNU General Public License cover the whole combination.
+//
+
+#include <sys/time.h>
+#include <time.h>
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <memory>
+
+#include <cppunit/XmlOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/TestListener.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/TestResultCollector.h>
+#include <cppunit/TestFailure.h>
+#include <cppunit/SourceLine.h>
+#include <cppunit/Exception.h>
+#include <cppunit/tools/XmlDocument.h>
+#include <cppunit/tools/XmlElement.h>
+
+#include "vmime/vmime.hpp"
+#include "vmime/platforms/posix/posixHandler.hpp"
+
+
+class Clock
+{
+public:
+
+	void reset()
+	{
+		struct timezone tz;
+
+		gettimeofday(&m_start, &tz);
+	}
+
+	double getDuration() const
+	{
+		struct timeval tv;
+		struct timezone tz;
+
+		gettimeofday(&tv, &tz);
+
+		return static_cast <double>(tv.tv_sec - m_start.tv_sec)
+			+ static_cast <double>(tv.tv_usec - m_start.tv_usec) / 1000000.0;
+	}
+
+private:
+
+	struct timeval m_start;
+};
+
+
+class XmlTestListener : public CppUnit::TestListener
+{
+public:
+
+	XmlTestListener()
+		: m_doc("utf-8"), m_testElt(NULL)
+	{
+		m_doc.setRootElement(new CppUnit::XmlElement("TestRun"));
+	}
+
+	void startTest(CppUnit::Test* test)
+	{
+		m_testElt = new CppUnit::XmlElement("Test");
+		m_suiteElt.back()->addElement(m_testElt);
+
+		m_testElt->addElement(new CppUnit::XmlElement("Name", test->getName()));
+
+		m_chrono.reset();
+	}
+
+	void addFailure(const CppUnit::TestFailure& failure)
+	{
+		CppUnit::XmlElement* failElt = new CppUnit::XmlElement("Failure");
+		m_testElt->addElement(failElt);
+
+		failElt->addElement(new CppUnit::XmlElement("FailureType",
+			failure.isError() ? "Error" : "Assertion"));
+
+		if (failure.sourceLine().isValid())
+		{
+			CppUnit::XmlElement* locElt = new CppUnit::XmlElement("Location");
+			failElt->addElement(locElt);
+
+			locElt->addElement(new CppUnit::XmlElement("File", failure.sourceLine().fileName()));
+			locElt->addElement(new CppUnit::XmlElement("Line", failure.sourceLine().lineNumber()));
+		}
+
+		CppUnit::XmlElement* exElt = new CppUnit::XmlElement("Exception");
+		failElt->addElement(exElt);
+
+		exElt->addElement(new CppUnit::XmlElement("Message", failure.thrownException()->what()));
+	}
+
+	void endTest(CppUnit::Test* /* test */)
+	{
+		std::ostringstream ossTime;
+		ossTime << (m_chrono.getDuration() * 1000.0);
+
+		m_testElt->addElement(new CppUnit::XmlElement("Time", ossTime.str()));
+
+		m_testElt = NULL;
+	}
+
+	void startSuite(CppUnit::Test* suite)
+	{
+		if (suite->getName() == "All Tests")
+			return;
+
+		CppUnit::XmlElement* suiteElt = new CppUnit::XmlElement("Suite");
+
+		if (m_suiteElt.size() == 0)
+			m_doc.rootElement().addElement(suiteElt);
+		else
+			m_suiteElt.back()->addElement(suiteElt);
+
+		m_suiteElt.push_back(suiteElt);
+
+		suiteElt->addElement(new CppUnit::XmlElement("Name", suite->getName()));
+	}
+
+	void endSuite(CppUnit::Test* /* suite */)
+	{
+		if (m_suiteElt.size())
+			m_suiteElt.pop_back();
+	}
+
+	void startTestRun(CppUnit::Test* /* test */, CppUnit::TestResult* /* eventManager */)
+	{
+	}
+
+	void endTestRun(CppUnit::Test* /* test */, CppUnit::TestResult* /* eventManager */)
+	{
+	}
+
+	void output(std::ostream& os)
+	{
+		os << m_doc.toString();
+	}
+
+private:
+
+	Clock m_chrono;
+
+	CppUnit::XmlDocument m_doc;
+	std::vector <CppUnit::XmlElement*> m_suiteElt;
+	CppUnit::XmlElement* m_testElt;
+};
+
+
+
+// see testUtils.hpp
+
+std::vector <std::string>& getTestModules()
+{
+	static std::vector <std::string> allModules;
+	return allModules;
+}
+
+
+void registerTestModule(const char* name_)
+{
+	std::vector <std::string>& testModules = getTestModules();
+	std::string name(name_);
+
+	if (std::find(testModules.begin(), testModules.end(), name) == testModules.end())
+		testModules.push_back(name);
+}
+
+
+const std::string getNormalizedPath(const std::string& path)
+{
+	std::string res = path;
+
+	for (std::size_t i = 0, n = res.length() ; i < n ; ++i)
+	{
+		if (res[i] == '\\')
+			res[i] = '/';
+	}
+
+	return res;
+}
+
+
+const std::string getFileNameFromPath(const std::string& path)
+{
+	const std::size_t pos = path.find_last_of('/');
+
+	if (pos == std::string::npos)
+		return "";
+
+	return path.substr(pos + 1);
+}
+
+
+static char g_moduleNameBuffer[2048];
+
+
+const char* getTestModuleNameFromSourceFile(const char *path_)
+{
+	static const std::string testRunnerPath(getNormalizedPath(__FILE__));
+	static const std::string testRunnerFileName(getFileNameFromPath(testRunnerPath));
+
+	const std::string path = getNormalizedPath(path_);
+
+	// "/path/to/testRunner.cpp" --> "/path/to/"
+	const std::string basePath
+		(testRunnerPath.begin(), testRunnerPath.end() - testRunnerFileName.length());
+
+	// "/path/to/module/testFile.cpp" --> "module/testFile.cpp"
+	const std::string testFileName(getFileNameFromPath(path));
+	const std::string testPath(path.begin() + basePath.length(), path.end());
+
+	// "module/testFile.cpp" --> "module"
+	const std::string moduleName(testPath.substr(0, testPath.length() - testFileName.length() - 1));
+	std::copy(moduleName.begin(), moduleName.end(), g_moduleNameBuffer);
+	g_moduleNameBuffer[moduleName.length()] = 0;
+
+	return g_moduleNameBuffer;
+}
+
+
+int main(int argc, char* argv[])
+{
+	// Parse arguments
+	bool xmlOutput = false;
+
+	for (int c = 1 ; c < argc ; ++c)
+	{
+		const std::string arg = argv[c];
+
+		if (arg == "--xml")
+			xmlOutput = true;
+	}
+
+	// Run the tests
+	if (xmlOutput)
+	{
+		// Get the test suites from the registry and add them to the list of tests to run
+		CppUnit::TestRunner runner;
+
+		for (unsigned int i = 0 ; i < getTestModules().size() ; ++i)
+		{
+			runner.addTest(CppUnit::TestFactoryRegistry::
+				getRegistry(getTestModules()[i]).makeTest());
+		}
+
+		std::auto_ptr <XmlTestListener> xmlListener(new XmlTestListener);
+
+		CppUnit::TestResult controller;
+		controller.addListener(xmlListener.get());
+
+		CppUnit::TestResultCollector result;
+		controller.addListener(&result);
+
+		runner.run(controller);
+
+		xmlListener->output(std::cout);
+
+		// Return error code 1 if a test failed
+		return result.wasSuccessful() ? 0 : 1;
+	}
+	else
+	{
+		// Get the top level suite from the registry
+		CppUnit::TextUi::TestRunner runner;
+		runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+		return runner.run() ? 0 : 1;
+	}
+}
+