1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2026-04-24 21:12:45 +02:00

Major plugin refactor and cleanup.

Switched to POCO library for unified platform/library interface.
Deprecated the external module API. It was creating more problems than solving.
Removed most built-in libraries in favor of system libraries for easier maintenance.
Cleaned and secured code with help from static analyzers.
This commit is contained in:
Sandu Liviu Catalin
2021-01-30 08:51:39 +02:00
parent e0e34b4030
commit 4a6bfc086c
6219 changed files with 1209835 additions and 454916 deletions
+16
View File
@@ -0,0 +1,16 @@
//
// CppUnitException.cpp
//
#include "CppUnit/CppUnitException.h"
namespace CppUnit {
const std::string CppUnitException::CPPUNIT_UNKNOWNFILENAME = "<unknown>";
const int CppUnitException::CPPUNIT_UNKNOWNLINENUMBER = -1;
} // namespace CppUnit
+185
View File
@@ -0,0 +1,185 @@
//
// TestCase.cpp
//
#include <stdexcept>
#include <math.h>
#include "CppUnit/TestCase.h"
#include "CppUnit/TestResult.h"
#include "CppUnit/estring.h"
#include <typeinfo>
#include <iostream>
using namespace std;
namespace CppUnit {
// Create a default TestResult
TestResult* TestCase::defaultResult()
{
return new TestResult;
}
// Check for a failed general assertion
void TestCase::assertImplementation(bool condition, const std::string& conditionExpression, long lineNumber, const std::string& fileName)
{
if (!condition)
throw CppUnitException(conditionExpression, lineNumber, fileName);
}
void TestCase::loop1assertImplementation(bool condition, const std::string& conditionExpression, long lineNumber, long data1lineNumber, const std::string& fileName)
{
if (!condition)
throw CppUnitException(conditionExpression, lineNumber, data1lineNumber, fileName);
}
void TestCase::loop2assertImplementation(bool condition, const std::string& conditionExpression, long lineNumber, long data1lineNumber, long data2lineNumber, const std::string& fileName)
{
if (!condition)
throw CppUnitException(conditionExpression, lineNumber, data1lineNumber, data2lineNumber, fileName);
}
// Check for a failed equality assertion
void TestCase::assertEquals(long expected, long actual, long lineNumber, const std::string& fileName)
{
if (expected != actual)
assertImplementation(false, notEqualsMessage(expected, actual), lineNumber, fileName);
}
// Check for a failed equality assertion
void TestCase::assertEquals(double expected, double actual, double delta, long lineNumber, const std::string& fileName)
{
if (fabs(expected - actual) > delta)
assertImplementation(false, notEqualsMessage(expected, actual), lineNumber, fileName);
}
// Check for a failed equality assertion
void TestCase::assertEquals(const void* expected, const void* actual, long lineNumber, const std::string& fileName)
{
if (expected != actual)
assertImplementation(false, notEqualsMessage(expected, actual), lineNumber, fileName);
}
// Check for a failed equality assertion
void TestCase::assertEquals(const std::string& expected, const std::string& actual, long lineNumber, const std::string& fileName)
{
if (expected != actual)
assertImplementation(false, notEqualsMessage(expected, actual), lineNumber, fileName);
}
void TestCase::assertNotNull(const void* pointer, const std::string& pointerExpression, long lineNumber, const std::string& fileName)
{
if (pointer == NULL)
throw CppUnitException(pointerExpression + " must not be NULL", lineNumber, fileName);
}
void TestCase::assertNull(const void* pointer, const std::string& pointerExpression, long lineNumber, const std::string& fileName)
{
if (pointer != NULL)
throw CppUnitException(pointerExpression + " must be NULL", lineNumber, fileName);
}
void TestCase::fail(const std::string& message, long lineNumber, const std::string& fileName)
{
throw CppUnitException(std::string("fail: ") + message, lineNumber, fileName);
}
void TestCase::warn(const std::string& message, long lineNumber, const std::string& fileName)
{
std::cout << "Warning [" << fileName << ':' << lineNumber << "]: " << message << std::endl;
}
// Run the test and catch any exceptions that are triggered by it
void TestCase::run(TestResult *result)
{
result->startTest(this);
setUp();
try
{
runTest();
}
catch (CppUnitException& e)
{
CppUnitException* copy = new CppUnitException(e);
result->addFailure(this, copy);
}
catch (std::exception& e)
{
std::string msg(typeid(e).name());
msg.append(": ");
msg.append(e.what());
result->addError(this, new CppUnitException(msg));
}
catch (...)
{
CppUnitException *e = new CppUnitException ("unknown exception");
result->addError (this, e);
}
tearDown ();
result->endTest(this);
}
// A default run method
TestResult* TestCase::run()
{
TestResult* result = defaultResult();
run(result);
return result;
}
// All the work for runTest is deferred to subclasses
void TestCase::runTest()
{
}
// Build a message about a failed equality check
std::string TestCase::notEqualsMessage(long expected, long actual)
{
return "expected: " + estring(expected) + " but was: " + estring(actual);
}
// Build a message about a failed equality check
std::string TestCase::notEqualsMessage(double expected, double actual)
{
return "expected: " + estring(expected) + " but was: " + estring(actual);
}
// Build a message about a failed equality check
std::string TestCase::notEqualsMessage(const void* expected, const void* actual)
{
return "expected: " + estring(expected) + " but was: " + estring(actual);
}
// Build a message about a failed equality check
std::string TestCase::notEqualsMessage(const std::string& expected, const std::string& actual)
{
return "expected: \"" + expected + "\" but was: \"" + actual + "\"";
}
} // namespace CppUnit
+41
View File
@@ -0,0 +1,41 @@
//
// TestDecorator.cpp
//
#include "CppUnit/TestDecorator.h"
namespace CppUnit {
TestDecorator::TestDecorator(Test* test)
{
_test = test;
}
TestDecorator::~TestDecorator()
{
}
int TestDecorator::countTestCases() const
{
return _test->countTestCases();
}
void TestDecorator::run(TestResult* result)
{
_test->run(result);
}
std::string TestDecorator::toString() const
{
return _test->toString();
}
} // namespace CppUnit
+20
View File
@@ -0,0 +1,20 @@
//
// TestFailure.cpp
//
#include "CppUnit/TestFailure.h"
#include "CppUnit/Test.h"
namespace CppUnit {
// Returns a short description of the failure.
std::string TestFailure::toString()
{
return _failedTest->toString () + ": " + _thrownException->what();
}
} // namespace CppUnit
+27
View File
@@ -0,0 +1,27 @@
//
// TestResult.cpp
//
#include "CppUnit/TestResult.h"
namespace CppUnit {
// Destroys a test result
TestResult::~TestResult()
{
std::vector<TestFailure*>::iterator it;
for (it = _errors.begin(); it != _errors.end(); ++it)
delete *it;
for (it = _failures.begin(); it != _failures.end(); ++it)
delete *it;
delete _syncObject;
}
} // namespace CppUnit
+235
View File
@@ -0,0 +1,235 @@
//
// TestRunner.cpp
//
#include "CppUnit/TestRunner.h"
#include "CppUnit/Test.h"
#include "CppUnit/TestSuite.h"
#include "CppUnit/TextTestResult.h"
#include <iostream>
#include <fstream>
namespace CppUnit {
TestRunner::TestRunner():
_ostr(std::cout)
{
}
TestRunner::TestRunner(std::ostream& ostr):
_ostr(ostr)
{
}
TestRunner::~TestRunner()
{
for (Mappings::iterator it = _mappings.begin(); it != _mappings.end(); ++it)
delete it->second;
}
void TestRunner::printBanner()
{
_ostr
<< "Usage: driver [-all] [-ignore <file> ] [-long] [-print] [-wait] [name] ..." << std::endl
<< " where name is the name of a test case class" << std::endl;
}
bool TestRunner::run(const std::vector<std::string>& args)
{
std::string testCase;
int numberOfTests = 0;
bool success = true;
bool all = false;
bool wait = false;
bool printed = false;
bool longRunning = false;
std::string ignore;
std::vector<std::string> setup;
std::vector<Test*> tests;
for (int i = 1; i < args.size(); i++)
{
const std::string& arg = args[i];
if (arg == "-wait")
{
wait = true;
continue;
}
else if (arg == "-all")
{
all = true;
continue;
}
else if (arg == "-long")
{
longRunning = true;
continue;
}
else if (arg == "-ignore")
{
ignore = args[++i];
continue;
}
else if (arg == "-print")
{
for (Mappings::iterator it = _mappings.begin(); it != _mappings.end(); ++it)
{
print(it->first, it->second, 0);
}
printed = true;
continue;
}
else if (arg == "-setup")
{
if (i + 1 < args.size())
setup.push_back(args[++i]);
continue;
}
if (!all)
{
testCase = arg;
if (testCase == "")
{
printBanner();
return false;
}
Test* testToRun = 0;
for (Mappings::iterator it = _mappings.begin(); !testToRun && it != _mappings.end(); ++it)
{
testToRun = find(testCase, it->second, it->first);
}
if (testToRun)
{
collectAllTestCases(testToRun, tests);
}
if (!testToRun)
{
_ostr << "Test " << testCase << " not found." << std::endl;
return false;
}
}
}
if (all)
{
tests.clear();
for (Mappings::iterator it = _mappings.begin(); it != _mappings.end(); ++it)
{
collectAllTestCases(it->second, tests);
}
}
TextTestResult result(_ostr, ignore);
for (std::vector<Test*>::const_iterator it = tests.begin(); it != tests.end(); ++it)
{
Test* testToRun = *it;
if(testToRun->getType() == Test::Long && !longRunning)
continue;
if (setup.size() > 0)
testToRun->addSetup(setup);
testToRun->run(&result);
numberOfTests++;
}
_ostr << result << std::endl;
success = result.wasSuccessful();
if (numberOfTests == 0 && !printed)
{
printBanner();
return false;
}
if (wait)
{
_ostr << "<RETURN> to continue" << std::endl;
std::cin.get();
}
return success;
}
void TestRunner::addTest(const std::string& name, Test* test)
{
_mappings.push_back(Mapping(name, test));
}
void TestRunner::print(const std::string& name, Test* pTest, int indent)
{
for (int i = 0; i < indent; ++i)
_ostr << " ";
_ostr << name << std::endl;
TestSuite* pSuite = dynamic_cast<TestSuite*>(pTest);
if (pSuite)
{
const std::vector<Test*>& tests = pSuite->tests();
for (std::vector<Test*>::const_iterator it = tests.begin(); it != tests.end(); ++it)
{
print((*it)->toString(), *it, indent + 1);
}
}
}
Test* TestRunner::find(const std::string& name, Test* pTest, const std::string& testName)
{
if (testName.find(name) != std::string::npos)
{
return pTest;
}
else
{
TestSuite* pSuite = dynamic_cast<TestSuite*>(pTest);
if (pSuite)
{
const std::vector<Test*>& tests = pSuite->tests();
for (std::vector<Test*>::const_iterator it = tests.begin(); it != tests.end(); ++it)
{
Test* result = find(name, *it, (*it)->toString());
if (result) return result;
}
}
return 0;
}
}
int TestRunner::collectAllTestCases(Test* pTest, std::vector<Test*>& testcases)
{
int added = 0;
if (pTest->getType() == Test::Suite)
{
TestSuite* pSuite = dynamic_cast<TestSuite*>(pTest);
if (pSuite)
{
const std::vector<Test*>& tests = pSuite->tests();
for (std::vector<Test*>::const_iterator it = tests.begin(); it != tests.end(); ++it)
{
added += collectAllTestCases(*it, testcases);
}
}
}
else
{
testcases.push_back(pTest);
added = 1;
}
return added;
}
} // namespace CppUnit
+49
View File
@@ -0,0 +1,49 @@
//
// TestSuite.cpp
//
#include "CppUnit/TestSuite.h"
#include "CppUnit/TestResult.h"
namespace CppUnit {
// Deletes all tests in the suite.
void TestSuite::deleteContents()
{
for (std::vector<Test*>::iterator it = _tests.begin(); it != _tests.end(); ++it)
delete *it;
}
// Runs the tests and collects their result in a TestResult.
void TestSuite::run(TestResult *result)
{
for (std::vector<Test*>::iterator it = _tests.begin(); it != _tests.end(); ++it)
{
if (result->shouldStop ())
break;
Test *test = *it;
if (!setup().empty())
test->addSetup(setup());
test->run(result);
}
}
// Counts the number of test cases that will be run by this test.
int TestSuite::countTestCases() const
{
int count = 0;
for (std::vector<Test*>::const_iterator it = _tests.begin (); it != _tests.end (); ++it)
count += (*it)->countTestCases();
return count;
}
} // namespace CppUnit
+288
View File
@@ -0,0 +1,288 @@
//
// TextTestResult.cpp
//
#include "CppUnit/TextTestResult.h"
#include "CppUnit/CppUnitException.h"
#include "CppUnit/Test.h"
#include "CppUnit/estring.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <cstdlib>
#include <cctype>
#include <exception>
namespace CppUnit {
TextTestResult::TextTestResult() :
_ostr(std::cout)
{
}
TextTestResult::TextTestResult(const std::string& ignore):
_ostr(std::cout)
{
if (!ignore.empty())
{
try
{
std::ifstream ifs(ignore);
if (ifs.is_open())
{
char line[256];
while (ifs.getline(line, sizeof(line)))
{
if (line[0] == '#')
continue;
std::string ignored(line);
ignoring(ignored);
}
ifs.close();
}
}
catch (std::exception& e)
{
std::cout << e.what() << std::endl;
}
}
setup();
}
TextTestResult::TextTestResult(std::ostream& ostr):
_ostr(ostr)
{
}
TextTestResult::TextTestResult(std::ostream& ostr, const std::string& ignore) :
_ostr(ostr)
{
if (!ignore.empty())
{
std::ifstream ifs(ignore);
if (ifs.is_open())
{
char line[256];
while (ifs.getline(line, sizeof(line)))
{
if (line[0] == '#')
continue;
std::string ignored(line);
ignoring(ignored);
}
ifs.close();
}
}
setup();
}
void TextTestResult::ignoring(const std::string ignore)
{
std::string::const_iterator it = ignore.begin();
std::string::const_iterator end = ignore.end();
for (;;)
{
while (it != end && (std::isspace(*it) || *it == '"' || *it == ',' || *it == '\'')) ++it;
if (it == end)
break;
std::string test;
while (it != end && *it != ',' && *it != '"' && *it != '\'') test += *it++;
if (!test.empty()) _ignored.insert(test.erase(test.find_last_not_of(" \n\r\t") + 1));
}
}
void TextTestResult::setup()
{
#if !defined(_WIN32_WCE)
const char* env = std::getenv("CPPUNIT_IGNORE");
if (env)
{
std::string ignored = env;
ignoring(ignored);
}
#endif
}
void TextTestResult::addError(Test* test, CppUnitException* e)
{
if (_ignored.find(test->toString()) == _ignored.end())
{
TestResult::addError(test, e);
_ostr << "ERROR" << std::flush;
}
else
{
_ostr << "ERROR (ignored)" << std::flush;
}
}
void TextTestResult::addFailure(Test* test, CppUnitException* e)
{
if (_ignored.find(test->toString()) == _ignored.end())
{
TestResult::addFailure(test, e);
_ostr << "FAILURE" << std::flush;
}
else
{
_ostr << "FAILURE (ignored)" << std::flush;
}
}
void TextTestResult::startTest(Test* test)
{
TestResult::startTest(test);
_ostr << "\n" << shortName(test->toString()) << ": " << std::flush;
}
void TextTestResult::printErrors(std::ostream& stream)
{
if (testErrors() != 0)
{
stream << "\n";
if (testErrors() == 1)
stream << "There was " << testErrors() << " error: " << std::endl;
else
stream << "There were " << testErrors() << " errors: " << std::endl;
int i = 1;
for (std::vector<TestFailure*>::iterator it = errors().begin(); it != errors().end(); ++it)
{
TestFailure* failure = *it;
CppUnitException* e = failure->thrownException();
stream << std::setw(2) << i
<< ": "
<< failure->failedTest()->toString() << "\n"
<< " \"" << (e ? e->what() : "") << "\"\n"
<< " in \""
<< (e ? e->fileName() : std::string())
<< "\", line ";
if (e == 0)
{
stream << "0";
}
else
{
stream << e->lineNumber();
if (e->data2LineNumber() != CppUnitException::CPPUNIT_UNKNOWNLINENUMBER)
{
stream << " data lines " << e->data1LineNumber()
<< ", " << e->data2LineNumber();
}
else if (e->data1LineNumber() != CppUnitException::CPPUNIT_UNKNOWNLINENUMBER)
{
stream << " data line " << e->data1LineNumber();
}
}
stream << std::endl;
i++;
}
}
}
void TextTestResult::printFailures(std::ostream& stream)
{
if (testFailures() != 0)
{
stream << "\n";
if (testFailures() == 1)
stream << "There was " << testFailures() << " failure: " << std::endl;
else
stream << "There were " << testFailures() << " failures: " << std::endl;
int i = 1;
for (std::vector<TestFailure*>::iterator it = failures().begin(); it != failures().end(); ++it)
{
TestFailure* failure = *it;
CppUnitException* e = failure->thrownException();
stream << std::setw(2) << i
<< ": "
<< failure->failedTest()->toString() << "\n"
<< " \"" << (e ? e->what() : "") << "\"\n"
<< " in \""
<< (e ? e->fileName() : std::string())
<< "\", line ";
if (e == 0)
{
stream << "0";
}
else
{
stream << e->lineNumber();
if (e->data2LineNumber() != CppUnitException::CPPUNIT_UNKNOWNLINENUMBER)
{
stream << " data lines "
<< e->data1LineNumber()
<< ", " << e->data2LineNumber();
}
else if (e->data1LineNumber() != CppUnitException::CPPUNIT_UNKNOWNLINENUMBER)
{
stream << " data line " << e->data1LineNumber();
}
}
stream << std::endl;
i++;
}
}
}
void TextTestResult::print(std::ostream& stream)
{
printHeader(stream);
printErrors(stream);
printFailures(stream);
}
void TextTestResult::printHeader(std::ostream& stream)
{
stream << "\n\n";
if (wasSuccessful())
stream << "OK ("
<< runTests() << " tests)"
<< std::endl;
else
stream << "!!!FAILURES!!!" << "\n"
<< "Runs: "
<< runTests ()
<< " Failures: "
<< testFailures ()
<< " Errors: "
<< testErrors ()
<< std::endl;
}
std::string TextTestResult::shortName(const std::string& testName)
{
std::string::size_type pos = testName.rfind('.');
if (pos != std::string::npos)
return std::string(testName, pos + 1);
else
return testName;
}
} // namespace CppUnit