initial commit
This commit is contained in:
commit
279ceb25dd
73 files changed
+7181
No files matched your search
@@ -0,0 +1,32 @@
|
||||
#include "AssertException.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
AssertException::AssertException(char const* description, char const* filename, int const lineNumber)
|
||||
: m_lineNumber(lineNumber)
|
||||
{
|
||||
std::strcpy(m_description, description);
|
||||
std::strcpy(m_filename, filename);
|
||||
}
|
||||
|
||||
AssertException::~AssertException() throw()
|
||||
{
|
||||
}
|
||||
|
||||
char const* AssertException::what() const throw()
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
char const* AssertException::Filename() const
|
||||
{
|
||||
return m_filename;
|
||||
}
|
||||
|
||||
int AssertException::LineNumber() const
|
||||
{
|
||||
return m_lineNumber;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef UNITTEST_ASSERTEXCEPTION_H
|
||||
#define UNITTEST_ASSERTEXCEPTION_H
|
||||
|
||||
#include <exception>
|
||||
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
class AssertException : public std::exception
|
||||
{
|
||||
public:
|
||||
AssertException(char const* description, char const* filename, int lineNumber);
|
||||
virtual ~AssertException() throw();
|
||||
|
||||
virtual char const* what() const throw();
|
||||
|
||||
char const* Filename() const;
|
||||
int LineNumber() const;
|
||||
|
||||
private:
|
||||
char m_description[512];
|
||||
char m_filename[256];
|
||||
int m_lineNumber;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,102 @@
|
||||
#ifndef UNITTEST_CHECKMACROS_H
|
||||
#define UNITTEST_CHECKMACROS_H
|
||||
|
||||
#include "Checks.h"
|
||||
#include "AssertException.h"
|
||||
#include "MemoryOutStream.h"
|
||||
#include "TestDetails.h"
|
||||
|
||||
#ifdef CHECK
|
||||
#error UnitTest++ redefines CHECK
|
||||
#endif
|
||||
|
||||
|
||||
#define CHECK(value) \
|
||||
do \
|
||||
{ \
|
||||
try { \
|
||||
if (!UnitTest::Check(value)) \
|
||||
testResults_.OnTestFailure( UnitTest::TestDetails(m_details, __LINE__), #value); \
|
||||
} \
|
||||
catch (...) { \
|
||||
testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
|
||||
"Unhandled exception in CHECK(" #value ")"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_EQUAL(expected, actual) \
|
||||
do \
|
||||
{ \
|
||||
try { \
|
||||
UnitTest::CheckEqual(testResults_, expected, actual, UnitTest::TestDetails(m_details, __LINE__)); \
|
||||
} \
|
||||
catch (...) { \
|
||||
testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
|
||||
"Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_CLOSE(expected, actual, tolerance) \
|
||||
do \
|
||||
{ \
|
||||
try { \
|
||||
UnitTest::CheckClose(testResults_, expected, actual, tolerance, UnitTest::TestDetails(m_details, __LINE__)); \
|
||||
} \
|
||||
catch (...) { \
|
||||
testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
|
||||
"Unhandled exception in CHECK_CLOSE(" #expected ", " #actual ")"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_ARRAY_EQUAL(expected, actual, count) \
|
||||
do \
|
||||
{ \
|
||||
try { \
|
||||
UnitTest::CheckArrayEqual(testResults_, expected, actual, count, UnitTest::TestDetails(m_details, __LINE__)); \
|
||||
} \
|
||||
catch (...) { \
|
||||
testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
|
||||
"Unhandled exception in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_ARRAY_CLOSE(expected, actual, count, tolerance) \
|
||||
do \
|
||||
{ \
|
||||
try { \
|
||||
UnitTest::CheckArrayClose(testResults_, expected, actual, count, tolerance, UnitTest::TestDetails(m_details, __LINE__)); \
|
||||
} \
|
||||
catch (...) { \
|
||||
testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
|
||||
"Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, tolerance) \
|
||||
do \
|
||||
{ \
|
||||
try { \
|
||||
UnitTest::CheckArray2DClose(testResults_, expected, actual, rows, columns, tolerance, UnitTest::TestDetails(m_details, __LINE__)); \
|
||||
} \
|
||||
catch (...) { \
|
||||
testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
|
||||
"Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define CHECK_THROW(expression, ExpectedExceptionType) \
|
||||
do \
|
||||
{ \
|
||||
bool caught_ = false; \
|
||||
try { expression; } \
|
||||
catch (ExpectedExceptionType const&) { caught_ = true; } \
|
||||
catch (...) {} \
|
||||
if (!caught_) \
|
||||
testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), "Expected exception: \"" #ExpectedExceptionType "\" not thrown"); \
|
||||
} while(0)
|
||||
|
||||
#define CHECK_ASSERT(expression) \
|
||||
CHECK_THROW(expression, UnitTest::AssertException);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "Checks.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
namespace {
|
||||
|
||||
void CheckStringsEqual(TestResults& results, char const* expected, char const* actual,
|
||||
TestDetails const& details)
|
||||
{
|
||||
if (std::strcmp(expected, actual))
|
||||
{
|
||||
UnitTest::MemoryOutStream stream;
|
||||
stream << "Expected " << expected << " but was " << actual;
|
||||
|
||||
results.OnTestFailure(details, stream.GetText());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CheckEqual(TestResults& results, char const* expected, char const* actual,
|
||||
TestDetails const& details)
|
||||
{
|
||||
CheckStringsEqual(results, expected, actual, details);
|
||||
}
|
||||
|
||||
void CheckEqual(TestResults& results, char* expected, char* actual,
|
||||
TestDetails const& details)
|
||||
{
|
||||
CheckStringsEqual(results, expected, actual, details);
|
||||
}
|
||||
|
||||
void CheckEqual(TestResults& results, char* expected, char const* actual,
|
||||
TestDetails const& details)
|
||||
{
|
||||
CheckStringsEqual(results, expected, actual, details);
|
||||
}
|
||||
|
||||
void CheckEqual(TestResults& results, char const* expected, char* actual,
|
||||
TestDetails const& details)
|
||||
{
|
||||
CheckStringsEqual(results, expected, actual, details);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
#ifndef UNITTEST_CHECKS_H
|
||||
#define UNITTEST_CHECKS_H
|
||||
|
||||
#include "Config.h"
|
||||
#include "TestResults.h"
|
||||
#include "MemoryOutStream.h"
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
|
||||
template< typename Value >
|
||||
bool Check(Value const value)
|
||||
{
|
||||
return !!value; // doing double negative to avoid silly VS warnings
|
||||
}
|
||||
|
||||
|
||||
template< typename Expected, typename Actual >
|
||||
void CheckEqual(TestResults& results, Expected const expected, Actual const actual, TestDetails const& details)
|
||||
{
|
||||
if (!(expected == actual))
|
||||
{
|
||||
UnitTest::MemoryOutStream stream;
|
||||
stream << "Expected " << expected << " but was " << actual;
|
||||
|
||||
results.OnTestFailure(details, stream.GetText());
|
||||
}
|
||||
}
|
||||
|
||||
void CheckEqual(TestResults& results, char const* expected, char const* actual, TestDetails const& details);
|
||||
|
||||
void CheckEqual(TestResults& results, char* expected, char* actual, TestDetails const& details);
|
||||
|
||||
void CheckEqual(TestResults& results, char* expected, char const* actual, TestDetails const& details);
|
||||
|
||||
void CheckEqual(TestResults& results, char const* expected, char* actual, TestDetails const& details);
|
||||
|
||||
template< typename Expected, typename Actual, typename Tolerance >
|
||||
bool AreClose(Expected const expected, Actual const actual, Tolerance const tolerance)
|
||||
{
|
||||
return (actual >= (expected - tolerance)) && (actual <= (expected + tolerance));
|
||||
}
|
||||
|
||||
template< typename Expected, typename Actual, typename Tolerance >
|
||||
void CheckClose(TestResults& results, Expected const expected, Actual const actual, Tolerance const tolerance,
|
||||
TestDetails const& details)
|
||||
{
|
||||
if (!AreClose(expected, actual, tolerance))
|
||||
{
|
||||
UnitTest::MemoryOutStream stream;
|
||||
stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual;
|
||||
|
||||
results.OnTestFailure(details, stream.GetText());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template< typename Expected, typename Actual >
|
||||
void CheckArrayEqual(TestResults& results, Expected const expected, Actual const actual,
|
||||
int const count, TestDetails const& details)
|
||||
{
|
||||
bool equal = true;
|
||||
for (int i = 0; i < count; ++i)
|
||||
equal &= (expected[i] == actual[i]);
|
||||
|
||||
if (!equal)
|
||||
{
|
||||
UnitTest::MemoryOutStream stream;
|
||||
stream << "Expected [ ";
|
||||
for (int i = 0; i < count; ++i)
|
||||
stream << expected[i] << " ";
|
||||
stream << "] but was [ ";
|
||||
for (int i = 0; i < count; ++i)
|
||||
stream << actual[i] << " ";
|
||||
stream << "]";
|
||||
|
||||
results.OnTestFailure(details, stream.GetText());
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Expected, typename Actual, typename Tolerance >
|
||||
bool ArrayAreClose(Expected const expected, Actual const actual, int const count, Tolerance const tolerance)
|
||||
{
|
||||
bool equal = true;
|
||||
for (int i = 0; i < count; ++i)
|
||||
equal &= AreClose(expected[i], actual[i], tolerance);
|
||||
return equal;
|
||||
}
|
||||
|
||||
template< typename Expected, typename Actual, typename Tolerance >
|
||||
void CheckArrayClose(TestResults& results, Expected const expected, Actual const actual,
|
||||
int const count, Tolerance const tolerance, TestDetails const& details)
|
||||
{
|
||||
bool equal = ArrayAreClose(expected, actual, count, tolerance);
|
||||
|
||||
if (!equal)
|
||||
{
|
||||
UnitTest::MemoryOutStream stream;
|
||||
stream << "Expected [ ";
|
||||
for (int i = 0; i < count; ++i)
|
||||
stream << expected[i] << " ";
|
||||
stream << "] +/- " << tolerance << " but was [ ";
|
||||
for (int i = 0; i < count; ++i)
|
||||
stream << actual[i] << " ";
|
||||
stream << "]";
|
||||
|
||||
results.OnTestFailure(details, stream.GetText());
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Expected, typename Actual, typename Tolerance >
|
||||
void CheckArray2DClose(TestResults& results, Expected const expected, Actual const actual,
|
||||
int const rows, int const columns, Tolerance const tolerance, TestDetails const& details)
|
||||
{
|
||||
bool equal = true;
|
||||
for (int i = 0; i < rows; ++i)
|
||||
equal &= ArrayAreClose(expected[i], actual[i], columns, tolerance);
|
||||
|
||||
if (!equal)
|
||||
{
|
||||
UnitTest::MemoryOutStream stream;
|
||||
stream << "Expected [ ";
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
stream << "[ ";
|
||||
for (int j = 0; j < columns; ++j)
|
||||
stream << expected[i][j] << " ";
|
||||
stream << "] ";
|
||||
}
|
||||
stream << "] +/- " << tolerance << " but was [ ";
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
stream << "[ ";
|
||||
for (int j = 0; j < columns; ++j)
|
||||
stream << actual[i][j] << " ";
|
||||
stream << "] ";
|
||||
}
|
||||
stream << "]";
|
||||
|
||||
results.OnTestFailure(details, stream.GetText());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef UNITTEST_CONFIG_H
|
||||
#define UNITTEST_CONFIG_H
|
||||
|
||||
// Standard defines documented here: http://predef.sourceforge.net
|
||||
|
||||
#if defined _MSC_VER
|
||||
#pragma warning(disable:4127) // conditional expression is constant
|
||||
#pragma warning(disable:4702) // unreachable code
|
||||
#pragma warning(disable:4722) // destructor never returns, potential memory leak
|
||||
#endif
|
||||
|
||||
#if defined(unix) || defined(__unix__) || defined(__unix) || defined(linux) || \
|
||||
defined(__APPLE__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__FreeBSD__)
|
||||
#define UNITTEST_POSIX
|
||||
#endif
|
||||
|
||||
#if defined (__MINGW32__)
|
||||
#define UNITTEST_MINGW
|
||||
#endif
|
||||
|
||||
// by default, MemoryOutStream is implemented in terms of std::ostringstream.
|
||||
// uncomment this line to use the custom MemoryOutStream (no deps on std::ostringstream).
|
||||
//#define UNITTEST_USE_CUSTOM_STREAMS
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "DeferredTestReporter.h"
|
||||
#include "TestDetails.h"
|
||||
|
||||
using namespace UnitTest;
|
||||
|
||||
void DeferredTestReporter::ReportTestStart(TestDetails const& details)
|
||||
{
|
||||
m_results.push_back(DeferredTestResult(details.suiteName, details.testName));
|
||||
}
|
||||
|
||||
void DeferredTestReporter::ReportFailure(TestDetails const& details, char const* failure)
|
||||
{
|
||||
DeferredTestResult& r = m_results.back();
|
||||
r.failed = true;
|
||||
r.failures.push_back(DeferredTestResult::Failure(details.lineNumber, failure));
|
||||
r.failureFile = details.filename;
|
||||
}
|
||||
|
||||
void DeferredTestReporter::ReportTestFinish(TestDetails const&, float const secondsElapsed)
|
||||
{
|
||||
DeferredTestResult& r = m_results.back();
|
||||
r.timeElapsed = secondsElapsed;
|
||||
}
|
||||
|
||||
DeferredTestReporter::DeferredTestResultList& DeferredTestReporter::GetResults()
|
||||
{
|
||||
return m_results;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef UNITTEST_DEFERREDTESTREPORTER_H
|
||||
#define UNITTEST_DEFERREDTESTREPORTER_H
|
||||
|
||||
#include "TestReporter.h"
|
||||
#include "DeferredTestResult.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
class DeferredTestReporter : public TestReporter
|
||||
{
|
||||
public:
|
||||
virtual void ReportTestStart(TestDetails const& details);
|
||||
virtual void ReportFailure(TestDetails const& details, char const* failure);
|
||||
virtual void ReportTestFinish(TestDetails const& details, float secondsElapsed);
|
||||
|
||||
typedef std::vector< DeferredTestResult > DeferredTestResultList;
|
||||
DeferredTestResultList& GetResults();
|
||||
|
||||
private:
|
||||
DeferredTestResultList m_results;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "DeferredTestResult.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
DeferredTestResult::DeferredTestResult()
|
||||
: suiteName("")
|
||||
, testName("")
|
||||
, failureFile("")
|
||||
, timeElapsed(0.0f)
|
||||
, failed(false)
|
||||
{
|
||||
}
|
||||
|
||||
DeferredTestResult::DeferredTestResult(char const* suite, char const* test)
|
||||
: suiteName(suite)
|
||||
, testName(test)
|
||||
, failureFile("")
|
||||
, timeElapsed(0.0f)
|
||||
, failed(false)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef UNITTEST_DEFERREDTESTRESULT_H
|
||||
#define UNITTEST_DEFERREDTESTRESULT_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
struct DeferredTestResult
|
||||
{
|
||||
DeferredTestResult();
|
||||
DeferredTestResult(char const* suite, char const* test);
|
||||
|
||||
std::string suiteName;
|
||||
std::string testName;
|
||||
std::string failureFile;
|
||||
|
||||
typedef std::pair< int, std::string > Failure;
|
||||
typedef std::vector< Failure > FailureVec;
|
||||
FailureVec failures;
|
||||
|
||||
float timeElapsed;
|
||||
bool failed;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //UNITTEST_DEFERREDTESTRESULT_H
|
||||
@@ -0,0 +1,143 @@
|
||||
#include "MemoryOutStream.h"
|
||||
|
||||
#ifndef UNITTEST_USE_CUSTOM_STREAMS
|
||||
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
char const* MemoryOutStream::GetText() const
|
||||
{
|
||||
m_text = this->str();
|
||||
return m_text.c_str();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename ValueType>
|
||||
void FormatToStream(MemoryOutStream& stream, char const* format, ValueType const& value)
|
||||
{
|
||||
char txt[32];
|
||||
std::sprintf(txt, format, value);
|
||||
stream << txt;
|
||||
}
|
||||
|
||||
int RoundUpToMultipleOfPow2Number (int n, int pow2Number)
|
||||
{
|
||||
return (n + (pow2Number - 1)) & ~(pow2Number - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
MemoryOutStream::MemoryOutStream(int const size)
|
||||
: m_capacity (0)
|
||||
, m_buffer (0)
|
||||
|
||||
{
|
||||
GrowBuffer(size);
|
||||
}
|
||||
|
||||
MemoryOutStream::~MemoryOutStream()
|
||||
{
|
||||
delete [] m_buffer;
|
||||
}
|
||||
|
||||
char const* MemoryOutStream::GetText() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
MemoryOutStream& MemoryOutStream::operator << (char const* txt)
|
||||
{
|
||||
int const bytesLeft = m_capacity - (int)std::strlen(m_buffer);
|
||||
int const bytesRequired = (int)std::strlen(txt) + 1;
|
||||
|
||||
if (bytesRequired > bytesLeft)
|
||||
{
|
||||
int const requiredCapacity = bytesRequired + m_capacity - bytesLeft;
|
||||
GrowBuffer(requiredCapacity);
|
||||
}
|
||||
|
||||
std::strcat(m_buffer, txt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MemoryOutStream& MemoryOutStream::operator << (int const n)
|
||||
{
|
||||
FormatToStream(*this, "%i", n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MemoryOutStream& MemoryOutStream::operator << (long const n)
|
||||
{
|
||||
FormatToStream(*this, "%li", n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MemoryOutStream& MemoryOutStream::operator << (unsigned long const n)
|
||||
{
|
||||
FormatToStream(*this, "%lu", n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MemoryOutStream& MemoryOutStream::operator << (float const f)
|
||||
{
|
||||
FormatToStream(*this, "%ff", f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MemoryOutStream& MemoryOutStream::operator << (void const* p)
|
||||
{
|
||||
FormatToStream(*this, "%p", p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MemoryOutStream& MemoryOutStream::operator << (unsigned int const s)
|
||||
{
|
||||
FormatToStream(*this, "%u", s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MemoryOutStream& MemoryOutStream::operator <<(double const d)
|
||||
{
|
||||
FormatToStream(*this, "%f", d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
int MemoryOutStream::GetCapacity() const
|
||||
{
|
||||
return m_capacity;
|
||||
}
|
||||
|
||||
|
||||
void MemoryOutStream::GrowBuffer(int const desiredCapacity)
|
||||
{
|
||||
int const newCapacity = RoundUpToMultipleOfPow2Number(desiredCapacity, GROW_CHUNK_SIZE);
|
||||
|
||||
char* buffer = new char[newCapacity];
|
||||
if (m_buffer)
|
||||
std::strcpy(buffer, m_buffer);
|
||||
else
|
||||
std::strcpy(buffer, "");
|
||||
|
||||
delete [] m_buffer;
|
||||
m_buffer = buffer;
|
||||
m_capacity = newCapacity;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef UNITTEST_MEMORYOUTSTREAM_H
|
||||
#define UNITTEST_MEMORYOUTSTREAM_H
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#ifndef UNITTEST_USE_CUSTOM_STREAMS
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
class MemoryOutStream : public std::ostringstream
|
||||
{
|
||||
public:
|
||||
MemoryOutStream() {}
|
||||
char const* GetText() const;
|
||||
|
||||
private:
|
||||
MemoryOutStream(MemoryOutStream const&);
|
||||
void operator =(MemoryOutStream const&);
|
||||
|
||||
mutable std::string m_text;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
class MemoryOutStream
|
||||
{
|
||||
public:
|
||||
explicit MemoryOutStream(int const size = 256);
|
||||
~MemoryOutStream();
|
||||
|
||||
char const* GetText() const;
|
||||
|
||||
MemoryOutStream& operator << (char const* txt);
|
||||
MemoryOutStream& operator << (int n);
|
||||
MemoryOutStream& operator << (long n);
|
||||
MemoryOutStream& operator << (unsigned long n);
|
||||
MemoryOutStream& operator << (float f);
|
||||
MemoryOutStream& operator << (double d);
|
||||
MemoryOutStream& operator << (void const* p);
|
||||
MemoryOutStream& operator << (unsigned int s);
|
||||
|
||||
enum { GROW_CHUNK_SIZE = 32 };
|
||||
int GetCapacity() const;
|
||||
|
||||
private:
|
||||
void operator= (MemoryOutStream const&);
|
||||
void GrowBuffer(int capacity);
|
||||
|
||||
int m_capacity;
|
||||
char* m_buffer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "SignalTranslator.h"
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
sigjmp_buf* SignalTranslator::s_jumpTarget = 0;
|
||||
|
||||
namespace {
|
||||
|
||||
void SignalHandler (int sig)
|
||||
{
|
||||
siglongjmp(*SignalTranslator::s_jumpTarget, sig );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
SignalTranslator::SignalTranslator ()
|
||||
{
|
||||
m_oldJumpTarget = s_jumpTarget;
|
||||
s_jumpTarget = &m_currentJumpTarget;
|
||||
|
||||
struct sigaction action;
|
||||
action.sa_flags = 0;
|
||||
action.sa_handler = SignalHandler;
|
||||
sigemptyset( &action.sa_mask );
|
||||
|
||||
sigaction( SIGSEGV, &action, &m_old_SIGSEGV_action );
|
||||
sigaction( SIGFPE , &action, &m_old_SIGFPE_action );
|
||||
sigaction( SIGTRAP, &action, &m_old_SIGTRAP_action );
|
||||
sigaction( SIGBUS , &action, &m_old_SIGBUS_action );
|
||||
sigaction( SIGILL , &action, &m_old_SIGBUS_action );
|
||||
}
|
||||
|
||||
SignalTranslator::~SignalTranslator()
|
||||
{
|
||||
sigaction( SIGILL , &m_old_SIGBUS_action , 0 );
|
||||
sigaction( SIGBUS , &m_old_SIGBUS_action , 0 );
|
||||
sigaction( SIGTRAP, &m_old_SIGTRAP_action, 0 );
|
||||
sigaction( SIGFPE , &m_old_SIGFPE_action , 0 );
|
||||
sigaction( SIGSEGV, &m_old_SIGSEGV_action, 0 );
|
||||
|
||||
s_jumpTarget = m_oldJumpTarget;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef UNITTEST_SIGNALTRANSLATOR_H
|
||||
#define UNITTEST_SIGNALTRANSLATOR_H
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
class SignalTranslator
|
||||
{
|
||||
public:
|
||||
SignalTranslator();
|
||||
~SignalTranslator();
|
||||
|
||||
static sigjmp_buf* s_jumpTarget;
|
||||
|
||||
private:
|
||||
sigjmp_buf m_currentJumpTarget;
|
||||
sigjmp_buf* m_oldJumpTarget;
|
||||
|
||||
struct sigaction m_old_SIGFPE_action;
|
||||
struct sigaction m_old_SIGTRAP_action;
|
||||
struct sigaction m_old_SIGSEGV_action;
|
||||
struct sigaction m_old_SIGBUS_action;
|
||||
struct sigaction m_old_SIGABRT_action;
|
||||
struct sigaction m_old_SIGALRM_action;
|
||||
};
|
||||
|
||||
#ifdef SOLARIS
|
||||
#define UNITTEST_EXTENSION
|
||||
#else
|
||||
#define UNITTEST_EXTENSION __extension__
|
||||
#endif
|
||||
|
||||
#define UNITTEST_THROW_SIGNALS \
|
||||
UnitTest::SignalTranslator sig; \
|
||||
if (UNITTEST_EXTENSION sigsetjmp(*UnitTest::SignalTranslator::s_jumpTarget, 1) != 0) \
|
||||
throw ("Unhandled system exception");
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "TimeHelpers.h"
|
||||
#include <unistd.h>
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
Timer::Timer()
|
||||
{
|
||||
m_startTime.tv_sec = 0;
|
||||
m_startTime.tv_usec = 0;
|
||||
}
|
||||
|
||||
void Timer::Start()
|
||||
{
|
||||
gettimeofday(&m_startTime, 0);
|
||||
}
|
||||
|
||||
|
||||
int Timer::GetTimeInMs() const
|
||||
{
|
||||
struct timeval currentTime;
|
||||
gettimeofday(¤tTime, 0);
|
||||
int const dsecs = currentTime.tv_sec - m_startTime.tv_sec;
|
||||
int const dus = currentTime.tv_usec - m_startTime.tv_usec;
|
||||
return dsecs*1000 + dus/1000;
|
||||
}
|
||||
|
||||
|
||||
void TimeHelpers::SleepMs (int ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef UNITTEST_TIMEHELPERS_H
|
||||
#define UNITTEST_TIMEHELPERS_H
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
Timer();
|
||||
void Start();
|
||||
int GetTimeInMs() const;
|
||||
|
||||
private:
|
||||
struct timeval m_startTime;
|
||||
};
|
||||
|
||||
|
||||
namespace TimeHelpers
|
||||
{
|
||||
void SleepMs (int ms);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "AssertException.h"
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
void ReportAssert(char const* description, char const* filename, int const lineNumber)
|
||||
{
|
||||
throw AssertException(description, filename, lineNumber);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef UNITTEST_ASSERT_H
|
||||
#define UNITTEST_ASSERT_H
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
void ReportAssert(char const* description, char const* filename, int lineNumber);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,62 @@
|
||||
#include "Config.h"
|
||||
#include "Test.h"
|
||||
#include "TestList.h"
|
||||
#include "TestResults.h"
|
||||
#include "AssertException.h"
|
||||
#include "MemoryOutStream.h"
|
||||
|
||||
#ifdef UNITTEST_POSIX
|
||||
#include "Posix/SignalTranslator.h"
|
||||
#endif
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
TestList& Test::GetTestList()
|
||||
{
|
||||
static TestList s_list;
|
||||
return s_list;
|
||||
}
|
||||
|
||||
Test::Test(char const* testName, char const* suiteName, char const* filename, int const lineNumber)
|
||||
: m_details(testName, suiteName, filename, lineNumber)
|
||||
, next(0)
|
||||
, m_timeConstraintExempt(false)
|
||||
{
|
||||
}
|
||||
|
||||
Test::~Test()
|
||||
{
|
||||
}
|
||||
|
||||
void Test::Run(TestResults& testResults) const
|
||||
{
|
||||
try
|
||||
{
|
||||
#ifdef UNITTEST_POSIX
|
||||
UNITTEST_THROW_SIGNALS
|
||||
#endif
|
||||
RunImpl(testResults);
|
||||
}
|
||||
catch (AssertException const& e)
|
||||
{
|
||||
testResults.OnTestFailure( TestDetails(m_details.testName, m_details.suiteName, e.Filename(), e.LineNumber()), e.what());
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
stream << "Unhandled exception: " << e.what();
|
||||
testResults.OnTestFailure(m_details, stream.GetText());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
testResults.OnTestFailure(m_details, "Unhandled exception: Crash!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Test::RunImpl(TestResults&) const
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef UNITTEST_TEST_H
|
||||
#define UNITTEST_TEST_H
|
||||
|
||||
#include "TestDetails.h"
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
class TestResults;
|
||||
class TestList;
|
||||
|
||||
class Test
|
||||
{
|
||||
public:
|
||||
Test(char const* testName, char const* suiteName = "DefaultSuite", char const* filename = "", int lineNumber = 0);
|
||||
virtual ~Test();
|
||||
void Run(TestResults& testResults) const;
|
||||
|
||||
TestDetails const m_details;
|
||||
Test* next;
|
||||
mutable bool m_timeConstraintExempt;
|
||||
|
||||
static TestList& GetTestList();
|
||||
|
||||
private:
|
||||
virtual void RunImpl(TestResults& testResults_) const;
|
||||
|
||||
Test(Test const&);
|
||||
Test& operator =(Test const&);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "TestDetails.h"
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
TestDetails::TestDetails(char const* testName_, char const* suiteName_, char const* filename_, int lineNumber_)
|
||||
: suiteName(suiteName_)
|
||||
, testName(testName_)
|
||||
, filename(filename_)
|
||||
, lineNumber(lineNumber_)
|
||||
{
|
||||
}
|
||||
|
||||
TestDetails::TestDetails(const TestDetails& details, int lineNumber_)
|
||||
: suiteName(details.suiteName)
|
||||
, testName(details.testName)
|
||||
, filename(details.filename)
|
||||
, lineNumber(lineNumber_)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef UNITTEST_TESTDETAILS_H
|
||||
#define UNITTEST_TESTDETAILS_H
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
class TestDetails
|
||||
{
|
||||
public:
|
||||
TestDetails(char const* testName, char const* suiteName, char const* filename, int lineNumber);
|
||||
TestDetails(const TestDetails& details, int lineNumber);
|
||||
|
||||
char const* const suiteName;
|
||||
char const* const testName;
|
||||
char const* const filename;
|
||||
int const lineNumber;
|
||||
|
||||
TestDetails(TestDetails const&); // Why is it public? --> http://gcc.gnu.org/bugs.html#cxx_rvalbind
|
||||
private:
|
||||
TestDetails& operator=(TestDetails const&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "TestList.h"
|
||||
#include "Test.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
TestList::TestList()
|
||||
: m_head(0)
|
||||
, m_tail(0)
|
||||
{
|
||||
}
|
||||
|
||||
void TestList::Add(Test* test)
|
||||
{
|
||||
if (m_tail == 0)
|
||||
{
|
||||
assert(m_head == 0);
|
||||
m_head = test;
|
||||
m_tail = test;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tail->next = test;
|
||||
m_tail = test;
|
||||
}
|
||||
}
|
||||
|
||||
const Test* TestList::GetHead() const
|
||||
{
|
||||
return m_head;
|
||||
}
|
||||
|
||||
ListAdder::ListAdder(TestList& list, Test* test)
|
||||
{
|
||||
list.Add(test);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef UNITTEST_TESTLIST_H
|
||||
#define UNITTEST_TESTLIST_H
|
||||
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
class Test;
|
||||
|
||||
class TestList
|
||||
{
|
||||
public:
|
||||
TestList();
|
||||
void Add (Test* test);
|
||||
|
||||
const Test* GetHead() const;
|
||||
|
||||
private:
|
||||
Test* m_head;
|
||||
Test* m_tail;
|
||||
};
|
||||
|
||||
|
||||
class ListAdder
|
||||
{
|
||||
public:
|
||||
ListAdder(TestList& list, Test* test);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifndef UNITTEST_TESTMACROS_H
|
||||
#define UNITTEST_TESTMACROS_H
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#ifndef UNITTEST_POSIX
|
||||
#define UNITTEST_THROW_SIGNALS
|
||||
#else
|
||||
#include "Posix/SignalTranslator.h"
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#error UnitTest++ redefines TEST
|
||||
#endif
|
||||
|
||||
#define SUITE(Name) \
|
||||
namespace Name { \
|
||||
namespace UnitTestSuite { \
|
||||
inline char const* GetSuiteName () { \
|
||||
return #Name ; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
namespace Name
|
||||
|
||||
#define TEST_EX(Name, List) \
|
||||
class Test##Name : public UnitTest::Test \
|
||||
{ \
|
||||
public: \
|
||||
Test##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \
|
||||
private: \
|
||||
virtual void RunImpl(UnitTest::TestResults& testResults_) const; \
|
||||
} test##Name##Instance; \
|
||||
\
|
||||
UnitTest::ListAdder adder##Name (List, &test##Name##Instance); \
|
||||
\
|
||||
void Test##Name::RunImpl(UnitTest::TestResults& testResults_) const
|
||||
|
||||
|
||||
#define TEST(Name) TEST_EX(Name, UnitTest::Test::GetTestList())
|
||||
|
||||
|
||||
#define TEST_FIXTURE_EX(Fixture, Name, List) \
|
||||
class Fixture##Name##Helper : public Fixture \
|
||||
{ \
|
||||
public: \
|
||||
Fixture##Name##Helper(UnitTest::TestDetails const& details) : m_details(details) {} \
|
||||
void RunTest(UnitTest::TestResults& testResults_); \
|
||||
UnitTest::TestDetails const& m_details; \
|
||||
private: \
|
||||
Fixture##Name##Helper(Fixture##Name##Helper const&); \
|
||||
Fixture##Name##Helper& operator =(Fixture##Name##Helper const&); \
|
||||
}; \
|
||||
\
|
||||
class Test##Fixture##Name : public UnitTest::Test \
|
||||
{ \
|
||||
public: \
|
||||
Test##Fixture##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \
|
||||
private: \
|
||||
virtual void RunImpl(UnitTest::TestResults& testResults_) const; \
|
||||
} test##Fixture##Name##Instance; \
|
||||
\
|
||||
UnitTest::ListAdder adder##Fixture##Name (List, &test##Fixture##Name##Instance); \
|
||||
\
|
||||
void Test##Fixture##Name::RunImpl(UnitTest::TestResults& testResults_) const \
|
||||
{ \
|
||||
bool ctorOk = false; \
|
||||
try { \
|
||||
Fixture##Name##Helper fixtureHelper(m_details); \
|
||||
ctorOk = true; \
|
||||
try { \
|
||||
UNITTEST_THROW_SIGNALS; \
|
||||
fixtureHelper.RunTest(testResults_); \
|
||||
} catch (UnitTest::AssertException const& e) { \
|
||||
testResults_.OnTestFailure(UnitTest::TestDetails(m_details.testName, m_details.suiteName, e.Filename(), e.LineNumber()), e.what()); \
|
||||
} catch (std::exception const& e) { \
|
||||
UnitTest::MemoryOutStream stream; \
|
||||
stream << "Unhandled exception: " << e.what(); \
|
||||
testResults_.OnTestFailure(m_details, stream.GetText()); \
|
||||
} catch (...) { testResults_.OnTestFailure(m_details, "Unhandled exception: Crash!"); } \
|
||||
} \
|
||||
catch (...) { \
|
||||
if (ctorOk) \
|
||||
{ \
|
||||
testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
|
||||
"Unhandled exception while destroying fixture " #Fixture); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
|
||||
"Unhandled exception while constructing fixture " #Fixture); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
void Fixture##Name##Helper::RunTest(UnitTest::TestResults& testResults_)
|
||||
|
||||
#define TEST_FIXTURE(Fixture,Name) TEST_FIXTURE_EX(Fixture, Name, UnitTest::Test::GetTestList())
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "TestReporter.h"
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
|
||||
TestReporter::~TestReporter()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef UNITTEST_TESTREPORTER_H
|
||||
#define UNITTEST_TESTREPORTER_H
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
class TestDetails;
|
||||
|
||||
class TestReporter
|
||||
{
|
||||
public:
|
||||
virtual ~TestReporter();
|
||||
|
||||
virtual void ReportTestStart(TestDetails const& test) = 0;
|
||||
virtual void ReportFailure(TestDetails const& test, char const* failure) = 0;
|
||||
virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed) = 0;
|
||||
virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "TestReporterStdout.h"
|
||||
#include <cstdio>
|
||||
|
||||
#include "TestDetails.h"
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
void TestReporterStdout::ReportFailure(TestDetails const& details, char const* failure)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
char const* const errorFormat = "%s:%d: error: Failure in %s: %s\n";
|
||||
#else
|
||||
char const* const errorFormat = "%s(%d): error: Failure in %s: %s\n";
|
||||
#endif
|
||||
std::printf(errorFormat, details.filename, details.lineNumber, details.testName, failure);
|
||||
}
|
||||
|
||||
void TestReporterStdout::ReportTestStart(TestDetails const& /*test*/)
|
||||
{
|
||||
}
|
||||
|
||||
void TestReporterStdout::ReportTestFinish(TestDetails const& /*test*/, float)
|
||||
{
|
||||
}
|
||||
|
||||
void TestReporterStdout::ReportSummary(int const totalTestCount, int const failedTestCount,
|
||||
int const failureCount, float secondsElapsed)
|
||||
{
|
||||
if (failureCount > 0)
|
||||
std::printf("FAILURE: %d out of %d tests failed (%d failures).\n", failedTestCount, totalTestCount, failureCount);
|
||||
else
|
||||
std::printf("Success: %d tests passed.\n", totalTestCount);
|
||||
std::printf("Test time: %.2f seconds.\n", secondsElapsed);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef UNITTEST_TESTREPORTERSTDOUT_H
|
||||
#define UNITTEST_TESTREPORTERSTDOUT_H
|
||||
|
||||
#include "TestReporter.h"
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
class TestReporterStdout : public TestReporter
|
||||
{
|
||||
private:
|
||||
virtual void ReportTestStart(TestDetails const& test);
|
||||
virtual void ReportFailure(TestDetails const& test, char const* failure);
|
||||
virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed);
|
||||
virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "TestResults.h"
|
||||
#include "TestReporter.h"
|
||||
|
||||
#include "TestDetails.h"
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
TestResults::TestResults(TestReporter* testReporter)
|
||||
: m_testReporter(testReporter)
|
||||
, m_totalTestCount(0)
|
||||
, m_failedTestCount(0)
|
||||
, m_failureCount(0)
|
||||
, m_currentTestFailed(false)
|
||||
{
|
||||
}
|
||||
|
||||
void TestResults::OnTestStart(TestDetails const& test)
|
||||
{
|
||||
++m_totalTestCount;
|
||||
m_currentTestFailed = false;
|
||||
if (m_testReporter)
|
||||
m_testReporter->ReportTestStart(test);
|
||||
}
|
||||
|
||||
void TestResults::OnTestFailure(TestDetails const& test, char const* failure)
|
||||
{
|
||||
++m_failureCount;
|
||||
if (!m_currentTestFailed)
|
||||
{
|
||||
++m_failedTestCount;
|
||||
m_currentTestFailed = true;
|
||||
}
|
||||
|
||||
if (m_testReporter)
|
||||
m_testReporter->ReportFailure(test, failure);
|
||||
}
|
||||
|
||||
void TestResults::OnTestFinish(TestDetails const& test, float secondsElapsed)
|
||||
{
|
||||
if (m_testReporter)
|
||||
m_testReporter->ReportTestFinish(test, secondsElapsed);
|
||||
}
|
||||
|
||||
int TestResults::GetTotalTestCount() const
|
||||
{
|
||||
return m_totalTestCount;
|
||||
}
|
||||
|
||||
int TestResults::GetFailedTestCount() const
|
||||
{
|
||||
return m_failedTestCount;
|
||||
}
|
||||
|
||||
int TestResults::GetFailureCount() const
|
||||
{
|
||||
return m_failureCount;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef UNITTEST_TESTRESULTS_H
|
||||
#define UNITTEST_TESTRESULTS_H
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
class TestReporter;
|
||||
class TestDetails;
|
||||
|
||||
class TestResults
|
||||
{
|
||||
public:
|
||||
explicit TestResults(TestReporter* reporter = 0);
|
||||
|
||||
void OnTestStart(TestDetails const& test);
|
||||
void OnTestFailure(TestDetails const& test, char const* failure);
|
||||
void OnTestFinish(TestDetails const& test, float secondsElapsed);
|
||||
|
||||
int GetTotalTestCount() const;
|
||||
int GetFailedTestCount() const;
|
||||
int GetFailureCount() const;
|
||||
|
||||
private:
|
||||
TestReporter* m_testReporter;
|
||||
int m_totalTestCount;
|
||||
int m_failedTestCount;
|
||||
int m_failureCount;
|
||||
|
||||
bool m_currentTestFailed;
|
||||
|
||||
TestResults(TestResults const&);
|
||||
TestResults& operator =(TestResults const&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "TestRunner.h"
|
||||
#include "TestResults.h"
|
||||
#include "Test.h"
|
||||
#include "TestList.h"
|
||||
#include "TestReporter.h"
|
||||
#include "TestReporterStdout.h"
|
||||
#include "TimeHelpers.h"
|
||||
#include "MemoryOutStream.h"
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
|
||||
int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int const maxTestTimeInMs )
|
||||
{
|
||||
TestResults result(&reporter);
|
||||
|
||||
Timer overallTimer;
|
||||
overallTimer.Start();
|
||||
|
||||
Test const* curTest = list.GetHead();
|
||||
while (curTest != 0)
|
||||
{
|
||||
if (suiteName == 0 || !std::strcmp(curTest->m_details.suiteName, suiteName))
|
||||
{
|
||||
Timer testTimer;
|
||||
testTimer.Start();
|
||||
result.OnTestStart(curTest->m_details);
|
||||
|
||||
curTest->Run(result);
|
||||
|
||||
int const testTimeInMs = testTimer.GetTimeInMs();
|
||||
if (maxTestTimeInMs > 0 && testTimeInMs > maxTestTimeInMs && !curTest->m_timeConstraintExempt)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
stream << "Global time constraint failed. Expected under " << maxTestTimeInMs <<
|
||||
"ms but took " << testTimeInMs << "ms.";
|
||||
result.OnTestFailure(curTest->m_details, stream.GetText());
|
||||
}
|
||||
result.OnTestFinish(curTest->m_details, testTimeInMs/1000.0f);
|
||||
}
|
||||
|
||||
curTest = curTest->next;
|
||||
}
|
||||
|
||||
float const secondsElapsed = overallTimer.GetTimeInMs() / 1000.0f;
|
||||
reporter.ReportSummary(result.GetTotalTestCount(), result.GetFailedTestCount(), result.GetFailureCount(), secondsElapsed);
|
||||
|
||||
return result.GetFailureCount();
|
||||
}
|
||||
|
||||
|
||||
int RunAllTests()
|
||||
{
|
||||
TestReporterStdout reporter;
|
||||
return RunAllTests(reporter, Test::GetTestList(), 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef UNITTEST_TESTRUNNER_H
|
||||
#define UNITTEST_TESTRUNNER_H
|
||||
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
class TestReporter;
|
||||
class TestList;
|
||||
|
||||
|
||||
int RunAllTests();
|
||||
int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int maxTestTimeInMs = 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef UNITTEST_TESTSUITE_H
|
||||
#define UNITTEST_TESTSUITE_H
|
||||
|
||||
namespace UnitTestSuite {
|
||||
|
||||
inline char const* GetSuiteName ()
|
||||
{
|
||||
return "DefaultSuite";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "TimeConstraint.h"
|
||||
#include "TestResults.h"
|
||||
#include "MemoryOutStream.h"
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
|
||||
TimeConstraint::TimeConstraint(int ms, TestResults& result, TestDetails const& details)
|
||||
: m_result(result)
|
||||
, m_details(details)
|
||||
, m_maxMs(ms)
|
||||
{
|
||||
m_timer.Start();
|
||||
}
|
||||
|
||||
TimeConstraint::~TimeConstraint()
|
||||
{
|
||||
int const totalTimeInMs = m_timer.GetTimeInMs();
|
||||
if (totalTimeInMs > m_maxMs)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
stream << "Time constraint failed. Expected to run test under " << m_maxMs <<
|
||||
"ms but took " << totalTimeInMs << "ms.";
|
||||
m_result.OnTestFailure(m_details, stream.GetText());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef UNITTEST_TIMECONSTRAINT_H
|
||||
#define UNITTEST_TIMECONSTRAINT_H
|
||||
|
||||
#include "TimeHelpers.h"
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
class TestResults;
|
||||
class TestDetails;
|
||||
|
||||
class TimeConstraint
|
||||
{
|
||||
public:
|
||||
TimeConstraint(int ms, TestResults& result, TestDetails const& details);
|
||||
~TimeConstraint();
|
||||
|
||||
private:
|
||||
void operator=(TimeConstraint const&);
|
||||
TimeConstraint(TimeConstraint const&);
|
||||
|
||||
Timer m_timer;
|
||||
TestResults& m_result;
|
||||
TestDetails const& m_details;
|
||||
int const m_maxMs;
|
||||
};
|
||||
|
||||
#define UNITTEST_TIME_CONSTRAINT(ms) \
|
||||
UnitTest::TimeConstraint unitTest__timeConstraint__(ms, testResults_, UnitTest::TestDetails(m_details, __LINE__))
|
||||
|
||||
#define UNITTEST_TIME_CONSTRAINT_EXEMPT() do { m_timeConstraintExempt = true; } while (0)
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
#include "Config.h"
|
||||
|
||||
#if defined UNITTEST_POSIX
|
||||
#include "Posix/TimeHelpers.h"
|
||||
#else
|
||||
#include "Win32/TimeHelpers.h"
|
||||
#endif
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef UNITTESTCPP_H
|
||||
#define UNITTESTCPP_H
|
||||
|
||||
#include "Config.h"
|
||||
#include "Test.h"
|
||||
#include "TestList.h"
|
||||
#include "TestSuite.h"
|
||||
#include "TestResults.h"
|
||||
|
||||
#include <new>
|
||||
#include "TestMacros.h"
|
||||
|
||||
#include "CheckMacros.h"
|
||||
#include "TestRunner.h"
|
||||
#include "TimeConstraint.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "TimeHelpers.h"
|
||||
#include <windows.h>
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
Timer::Timer()
|
||||
: m_startTime(0)
|
||||
{
|
||||
m_threadId = ::GetCurrentThread();
|
||||
DWORD_PTR systemMask;
|
||||
::GetProcessAffinityMask(GetCurrentProcess(), &m_processAffinityMask, &systemMask);
|
||||
|
||||
::SetThreadAffinityMask(m_threadId, 1);
|
||||
::QueryPerformanceFrequency(reinterpret_cast< LARGE_INTEGER* >(&m_frequency));
|
||||
::SetThreadAffinityMask(m_threadId, m_processAffinityMask);
|
||||
}
|
||||
|
||||
void Timer::Start()
|
||||
{
|
||||
m_startTime = GetTime();
|
||||
}
|
||||
|
||||
int Timer::GetTimeInMs() const
|
||||
{
|
||||
__int64 const elapsedTime = GetTime() - m_startTime;
|
||||
double const seconds = double(elapsedTime) / double(m_frequency);
|
||||
return int(seconds * 1000.0f);
|
||||
}
|
||||
|
||||
__int64 Timer::GetTime() const
|
||||
{
|
||||
LARGE_INTEGER curTime;
|
||||
::SetThreadAffinityMask(m_threadId, 1);
|
||||
::QueryPerformanceCounter(&curTime);
|
||||
::SetThreadAffinityMask(m_threadId, m_processAffinityMask);
|
||||
return curTime.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TimeHelpers::SleepMs(int const ms)
|
||||
{
|
||||
::Sleep(ms);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef UNITTEST_TIMEHELPERS_H
|
||||
#define UNITTEST_TIMEHELPERS_H
|
||||
|
||||
#include "../Config.h"
|
||||
|
||||
|
||||
#ifdef UNITTEST_MINGW
|
||||
#ifndef __int64
|
||||
#define __int64 long long
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
Timer();
|
||||
void Start();
|
||||
int GetTimeInMs() const;
|
||||
|
||||
private:
|
||||
__int64 GetTime() const;
|
||||
|
||||
void* m_threadId;
|
||||
|
||||
#if defined(_WIN64)
|
||||
unsigned __int64 m_processAffinityMask;
|
||||
#else
|
||||
unsigned long m_processAffinityMask;
|
||||
#endif
|
||||
|
||||
__int64 m_startTime;
|
||||
__int64 m_frequency;
|
||||
};
|
||||
|
||||
|
||||
namespace TimeHelpers
|
||||
{
|
||||
void SleepMs (int ms);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,126 @@
|
||||
#include "XmlTestReporter.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
using std::ostringstream;
|
||||
using std::ostream;
|
||||
|
||||
namespace {
|
||||
|
||||
void ReplaceChar(string& str, char const c, string const& replacement)
|
||||
{
|
||||
for (size_t pos = str.find(c); pos != string::npos; pos = str.find(c, pos + 1))
|
||||
str.replace(pos, 1, replacement);
|
||||
}
|
||||
|
||||
string XmlEscape(string const& value)
|
||||
{
|
||||
string escaped = value;
|
||||
|
||||
ReplaceChar(escaped, '&', "&");
|
||||
ReplaceChar(escaped, '<', "<");
|
||||
ReplaceChar(escaped, '>', ">");
|
||||
ReplaceChar(escaped, '\'', "'");
|
||||
ReplaceChar(escaped, '\"', """);
|
||||
|
||||
return escaped;
|
||||
}
|
||||
|
||||
string BuildFailureMessage(string const& file, int const line, string const& message)
|
||||
{
|
||||
ostringstream failureMessage;
|
||||
failureMessage << file << "(" << line << ") : " << message;
|
||||
return failureMessage.str();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace UnitTest {
|
||||
|
||||
XmlTestReporter::XmlTestReporter(ostream& ostream)
|
||||
: m_ostream(ostream)
|
||||
{
|
||||
}
|
||||
|
||||
void XmlTestReporter::ReportSummary(int const totalTestCount, int const failedTestCount,
|
||||
int const failureCount, float const secondsElapsed)
|
||||
{
|
||||
AddXmlElement(m_ostream, NULL);
|
||||
|
||||
BeginResults(m_ostream, totalTestCount, failedTestCount, failureCount, secondsElapsed);
|
||||
|
||||
DeferredTestResultList const& results = GetResults();
|
||||
for (DeferredTestResultList::const_iterator i = results.begin(); i != results.end(); ++i)
|
||||
{
|
||||
BeginTest(m_ostream, *i);
|
||||
|
||||
if (i->failed)
|
||||
AddFailure(m_ostream, *i);
|
||||
|
||||
EndTest(m_ostream, *i);
|
||||
}
|
||||
|
||||
EndResults(m_ostream);
|
||||
}
|
||||
|
||||
void XmlTestReporter::AddXmlElement(ostream& os, char const* encoding)
|
||||
{
|
||||
os << "<?xml version=\"1.0\"";
|
||||
|
||||
if (encoding != NULL)
|
||||
os << " encoding=\"" << encoding << "\"";
|
||||
|
||||
os << "?>";
|
||||
}
|
||||
|
||||
void XmlTestReporter::BeginResults(std::ostream& os, int const totalTestCount, int const failedTestCount,
|
||||
int const failureCount, float const secondsElapsed)
|
||||
{
|
||||
os << "<unittest-results"
|
||||
<< " tests=\"" << totalTestCount << "\""
|
||||
<< " failedtests=\"" << failedTestCount << "\""
|
||||
<< " failures=\"" << failureCount << "\""
|
||||
<< " time=\"" << secondsElapsed << "\""
|
||||
<< ">";
|
||||
}
|
||||
|
||||
void XmlTestReporter::EndResults(std::ostream& os)
|
||||
{
|
||||
os << "</unittest-results>";
|
||||
}
|
||||
|
||||
void XmlTestReporter::BeginTest(std::ostream& os, DeferredTestResult const& result)
|
||||
{
|
||||
os << "<test"
|
||||
<< " suite=\"" << result.suiteName << "\""
|
||||
<< " name=\"" << result.testName << "\""
|
||||
<< " time=\"" << result.timeElapsed << "\"";
|
||||
}
|
||||
|
||||
void XmlTestReporter::EndTest(std::ostream& os, DeferredTestResult const& result)
|
||||
{
|
||||
if (result.failed)
|
||||
os << "</test>";
|
||||
else
|
||||
os << "/>";
|
||||
}
|
||||
|
||||
void XmlTestReporter::AddFailure(std::ostream& os, DeferredTestResult const& result)
|
||||
{
|
||||
os << ">"; // close <test> element
|
||||
|
||||
for (DeferredTestResult::FailureVec::const_iterator it = result.failures.begin();
|
||||
it != result.failures.end();
|
||||
++it)
|
||||
{
|
||||
string const escapedMessage = XmlEscape(it->second);
|
||||
string const message = BuildFailureMessage(result.failureFile, it->first, escapedMessage);
|
||||
|
||||
os << "<failure" << " message=\"" << message << "\"" << "/>";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef UNITTEST_XMLTESTREPORTER_H
|
||||
#define UNITTEST_XMLTESTREPORTER_H
|
||||
|
||||
#include "DeferredTestReporter.h"
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
class XmlTestReporter : public DeferredTestReporter
|
||||
{
|
||||
public:
|
||||
explicit XmlTestReporter(std::ostream& ostream);
|
||||
|
||||
virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
|
||||
|
||||
private:
|
||||
XmlTestReporter(XmlTestReporter const&);
|
||||
XmlTestReporter& operator=(XmlTestReporter const&);
|
||||
|
||||
void AddXmlElement(std::ostream& os, char const* encoding);
|
||||
void BeginResults(std::ostream& os, int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
|
||||
void EndResults(std::ostream& os);
|
||||
void BeginTest(std::ostream& os, DeferredTestResult const& result);
|
||||
void AddFailure(std::ostream& os, DeferredTestResult const& result);
|
||||
void EndTest(std::ostream& os, DeferredTestResult const& result);
|
||||
|
||||
std::ostream& m_ostream;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "../TestReporterStdout.h"
|
||||
|
||||
|
||||
int main(int, char const *[])
|
||||
{
|
||||
return UnitTest::RunAllTests();
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#ifndef UNITTEST_RECORDINGREPORTER_H
|
||||
#define UNITTEST_RECORDINGREPORTER_H
|
||||
|
||||
#include "../TestReporter.h"
|
||||
#include <cstring>
|
||||
|
||||
#include "../TestDetails.h"
|
||||
|
||||
struct RecordingReporter : public UnitTest::TestReporter
|
||||
{
|
||||
private:
|
||||
enum { kMaxStringLength = 256 };
|
||||
|
||||
public:
|
||||
RecordingReporter()
|
||||
: testRunCount(0)
|
||||
, testFailedCount(0)
|
||||
, lastFailedLine(0)
|
||||
, testFinishedCount(0)
|
||||
, lastFinishedTestTime(0)
|
||||
, summaryTotalTestCount(0)
|
||||
, summaryFailedTestCount(0)
|
||||
, summaryFailureCount(0)
|
||||
, summarySecondsElapsed(0)
|
||||
{
|
||||
lastStartedSuite[0] = '\0';
|
||||
lastStartedTest[0] = '\0';
|
||||
lastFailedFile[0] = '\0';
|
||||
lastFailedSuite[0] = '\0';
|
||||
lastFailedTest[0] = '\0';
|
||||
lastFailedMessage[0] = '\0';
|
||||
lastFinishedSuite[0] = '\0';
|
||||
lastFinishedTest[0] = '\0';
|
||||
}
|
||||
|
||||
virtual void ReportTestStart(UnitTest::TestDetails const& test)
|
||||
{
|
||||
++testRunCount;
|
||||
std::strcpy(lastStartedSuite, test.suiteName);
|
||||
std::strcpy(lastStartedTest, test.testName);
|
||||
}
|
||||
|
||||
virtual void ReportFailure(UnitTest::TestDetails const& test, char const* failure)
|
||||
{
|
||||
++testFailedCount;
|
||||
std::strcpy(lastFailedFile, test.filename);
|
||||
lastFailedLine = test.lineNumber;
|
||||
std::strcpy(lastFailedSuite, test.suiteName);
|
||||
std::strcpy(lastFailedTest, test.testName);
|
||||
std::strcpy(lastFailedMessage, failure);
|
||||
}
|
||||
|
||||
virtual void ReportTestFinish(UnitTest::TestDetails const& test, float testDuration)
|
||||
{
|
||||
++testFinishedCount;
|
||||
std::strcpy(lastFinishedSuite, test.suiteName);
|
||||
std::strcpy(lastFinishedTest, test.testName);
|
||||
lastFinishedTestTime = testDuration;
|
||||
}
|
||||
|
||||
virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed)
|
||||
{
|
||||
summaryTotalTestCount = totalTestCount;
|
||||
summaryFailedTestCount = failedTestCount;
|
||||
summaryFailureCount = failureCount;
|
||||
summarySecondsElapsed = secondsElapsed;
|
||||
}
|
||||
|
||||
int testRunCount;
|
||||
char lastStartedSuite[kMaxStringLength];
|
||||
char lastStartedTest[kMaxStringLength];
|
||||
|
||||
int testFailedCount;
|
||||
char lastFailedFile[kMaxStringLength];
|
||||
int lastFailedLine;
|
||||
char lastFailedSuite[kMaxStringLength];
|
||||
char lastFailedTest[kMaxStringLength];
|
||||
char lastFailedMessage[kMaxStringLength];
|
||||
|
||||
int testFinishedCount;
|
||||
char lastFinishedSuite[kMaxStringLength];
|
||||
char lastFinishedTest[kMaxStringLength];
|
||||
float lastFinishedTestTime;
|
||||
|
||||
int summaryTotalTestCount;
|
||||
int summaryFailedTestCount;
|
||||
int summaryFailureCount;
|
||||
float summarySecondsElapsed;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "../AssertException.h"
|
||||
#include "../ReportAssert.h"
|
||||
|
||||
using namespace UnitTest;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(ReportAssertThrowsAssertException)
|
||||
{
|
||||
bool caught = false;
|
||||
|
||||
try
|
||||
{
|
||||
ReportAssert("", "", 0);
|
||||
}
|
||||
catch(AssertException const&)
|
||||
{
|
||||
caught = true;
|
||||
}
|
||||
|
||||
CHECK (true == caught);
|
||||
}
|
||||
|
||||
TEST(ReportAssertSetsCorrectInfoInException)
|
||||
{
|
||||
const int lineNumber = 12345;
|
||||
const char* description = "description";
|
||||
const char* filename = "filename";
|
||||
|
||||
try
|
||||
{
|
||||
ReportAssert(description, filename, lineNumber);
|
||||
}
|
||||
catch(AssertException const& e)
|
||||
{
|
||||
CHECK_EQUAL(description, e.what());
|
||||
CHECK_EQUAL(filename, e.Filename());
|
||||
CHECK_EQUAL(lineNumber, e.LineNumber());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,710 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "RecordingReporter.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(CheckSucceedsOnTrue)
|
||||
{
|
||||
bool failure = true;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK (true);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (!failure);
|
||||
}
|
||||
|
||||
TEST(CheckFailsOnFalse)
|
||||
{
|
||||
bool failure = false;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK (false);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (failure);
|
||||
}
|
||||
|
||||
TEST(FailureReportsCorrectTestName)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK (false);
|
||||
}
|
||||
|
||||
CHECK_EQUAL (m_details.testName, reporter.lastFailedTest);
|
||||
}
|
||||
|
||||
TEST(CheckFailureIncludesCheckContents)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
const bool yaddayadda = false;
|
||||
CHECK (yaddayadda);
|
||||
}
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "yaddayadda"));
|
||||
}
|
||||
|
||||
int ThrowingFunction()
|
||||
{
|
||||
throw "Doh";
|
||||
}
|
||||
|
||||
TEST(CheckFailsOnException)
|
||||
{
|
||||
bool failure = false;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK (ThrowingFunction() == 1);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (failure);
|
||||
}
|
||||
|
||||
TEST(CheckFailureBecauseOfExceptionIncludesCheckContents)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK (ThrowingFunction() == 1);
|
||||
}
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "ThrowingFunction() == 1"));
|
||||
}
|
||||
|
||||
TEST(CheckEqualSucceedsOnEqual)
|
||||
{
|
||||
bool failure = true;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK_EQUAL (1, 1);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (!failure);
|
||||
}
|
||||
|
||||
TEST(CheckEqualFailsOnNotEqual)
|
||||
{
|
||||
bool failure = false;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK_EQUAL (1, 2);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (failure);
|
||||
}
|
||||
|
||||
TEST(CheckEqualFailsOnException)
|
||||
{
|
||||
bool failure = false;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK_EQUAL (ThrowingFunction(), 1);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (failure);
|
||||
}
|
||||
|
||||
TEST(CheckEqualFailureContainsCorrectDetails)
|
||||
{
|
||||
int line = 0;
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
UnitTest::TestDetails const m_details("testName", "suiteName", "filename", -1);
|
||||
CHECK_EQUAL (1, 123); line = __LINE__;
|
||||
}
|
||||
|
||||
CHECK_EQUAL("testName", reporter.lastFailedTest);
|
||||
CHECK_EQUAL("suiteName", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL ("filename", reporter.lastFailedFile);
|
||||
CHECK_EQUAL (line, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
TEST(CheckEqualFailureBecauseOfExceptionContainsCorrectDetails)
|
||||
{
|
||||
int line = 0;
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
UnitTest::TestDetails const m_details("testName", "suiteName", "filename", -1);
|
||||
CHECK_EQUAL (ThrowingFunction(), 123); line = __LINE__;
|
||||
}
|
||||
|
||||
CHECK_EQUAL("testName", reporter.lastFailedTest);
|
||||
CHECK_EQUAL("suiteName", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL ("filename", reporter.lastFailedFile);
|
||||
CHECK_EQUAL (line, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
TEST(CheckEqualFailureBecauseOfExceptionIncludesCheckContents)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK_EQUAL (ThrowingFunction(), 123);
|
||||
}
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "ThrowingFunction()"));
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "123"));
|
||||
}
|
||||
|
||||
int g_sideEffect = 0;
|
||||
int FunctionWithSideEffects()
|
||||
{
|
||||
++g_sideEffect;
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(CheckEqualDoesNotHaveSideEffectsWhenPassing)
|
||||
{
|
||||
g_sideEffect = 0;
|
||||
{
|
||||
UnitTest::TestResults testResults_;
|
||||
CHECK_EQUAL (1, FunctionWithSideEffects());
|
||||
}
|
||||
CHECK_EQUAL (1, g_sideEffect);
|
||||
}
|
||||
|
||||
TEST(CheckEqualDoesNotHaveSideEffectsWhenFailing)
|
||||
{
|
||||
g_sideEffect = 0;
|
||||
{
|
||||
UnitTest::TestResults testResults_;
|
||||
CHECK_EQUAL (2, FunctionWithSideEffects());
|
||||
}
|
||||
CHECK_EQUAL (1, g_sideEffect);
|
||||
}
|
||||
|
||||
|
||||
TEST(CheckCloseSucceedsOnEqual)
|
||||
{
|
||||
bool failure = true;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK_CLOSE (1.0f, 1.001f, 0.01f);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (!failure);
|
||||
}
|
||||
|
||||
TEST(CheckCloseFailsOnNotEqual)
|
||||
{
|
||||
bool failure = false;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK_CLOSE (1.0f, 1.1f, 0.01f);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (failure);
|
||||
}
|
||||
|
||||
TEST(CheckCloseFailsOnException)
|
||||
{
|
||||
bool failure = false;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK_CLOSE ((float)ThrowingFunction(), 1.0001f, 0.1f);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (failure);
|
||||
}
|
||||
|
||||
TEST(CheckCloseFailureContainsCorrectDetails)
|
||||
{
|
||||
int line = 0;
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
UnitTest::TestDetails m_details("test", "suite", "filename", -1);
|
||||
CHECK_CLOSE (1.0f, 1.1f, 0.01f); line = __LINE__;
|
||||
}
|
||||
|
||||
CHECK_EQUAL("test", reporter.lastFailedTest);
|
||||
CHECK_EQUAL("suite", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL ("filename", reporter.lastFailedFile);
|
||||
CHECK_EQUAL (line, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
TEST(CheckCloseFailureBecauseOfExceptionContainsCorrectDetails)
|
||||
{
|
||||
int line = 0;
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
UnitTest::TestDetails m_details("closeTest", "closeSuite", "filename", -1);
|
||||
CHECK_CLOSE ((float)ThrowingFunction(), 1.0001f, 0.1f); line = __LINE__;
|
||||
}
|
||||
|
||||
CHECK_EQUAL("closeTest", reporter.lastFailedTest);
|
||||
CHECK_EQUAL("closeSuite", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL ("filename", reporter.lastFailedFile);
|
||||
CHECK_EQUAL (line, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
TEST(CheckCloseFailureBecauseOfExceptionIncludesCheckContents)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
CHECK_CLOSE ((float)ThrowingFunction(), 1.0001f, 0.1f);
|
||||
}
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "(float)ThrowingFunction()"));
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "1.0001f"));
|
||||
}
|
||||
|
||||
TEST(CheckCloseDoesNotHaveSideEffectsWhenPassing)
|
||||
{
|
||||
g_sideEffect = 0;
|
||||
{
|
||||
UnitTest::TestResults testResults_;
|
||||
CHECK_CLOSE (1, FunctionWithSideEffects(), 0.1f);
|
||||
}
|
||||
CHECK_EQUAL (1, g_sideEffect);
|
||||
}
|
||||
|
||||
TEST(CheckCloseDoesNotHaveSideEffectsWhenFailing)
|
||||
{
|
||||
g_sideEffect = 0;
|
||||
{
|
||||
UnitTest::TestResults testResults_;
|
||||
CHECK_CLOSE (2, FunctionWithSideEffects(), 0.1f);
|
||||
}
|
||||
CHECK_EQUAL (1, g_sideEffect);
|
||||
}
|
||||
|
||||
|
||||
class ThrowingObject
|
||||
{
|
||||
public:
|
||||
float operator[](int) const
|
||||
{
|
||||
throw "Test throw";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEST(CheckArrayCloseSucceedsOnEqual)
|
||||
{
|
||||
bool failure = true;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
const float data[4] = { 0, 1, 2, 3 };
|
||||
CHECK_ARRAY_CLOSE (data, data, 4, 0.01f);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (!failure);
|
||||
}
|
||||
|
||||
TEST(CheckArrayCloseFailsOnNotEqual)
|
||||
{
|
||||
bool failure = false;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
int const data1[4] = { 0, 1, 2, 3 };
|
||||
int const data2[4] = { 0, 1, 3, 3 };
|
||||
CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (failure);
|
||||
}
|
||||
|
||||
TEST(CheckArrayCloseFailureIncludesCheckExpectedAndActual)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
int const data1[4] = { 0, 1, 2, 3 };
|
||||
int const data2[4] = { 0, 1, 3, 3 };
|
||||
CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f);
|
||||
}
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]"));
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]"));
|
||||
}
|
||||
|
||||
TEST(CheckArrayCloseFailureContainsCorrectDetails)
|
||||
{
|
||||
int line = 0;
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
UnitTest::TestDetails m_details("arrayCloseTest", "arrayCloseSuite", "filename", -1);
|
||||
int const data1[4] = { 0, 1, 2, 3 };
|
||||
int const data2[4] = { 0, 1, 3, 3 };
|
||||
CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); line = __LINE__;
|
||||
}
|
||||
|
||||
CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest);
|
||||
CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL ("filename", reporter.lastFailedFile);
|
||||
CHECK_EQUAL (line, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
TEST(CheckArrayCloseFailureBecauseOfExceptionContainsCorrectDetails)
|
||||
{
|
||||
int line = 0;
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
UnitTest::TestDetails m_details("arrayCloseTest", "arrayCloseSuite", "filename", -1);
|
||||
int const data[4] = { 0, 1, 2, 3 };
|
||||
CHECK_ARRAY_CLOSE (data, ThrowingObject(), 4, 0.01f); line = __LINE__;
|
||||
}
|
||||
|
||||
CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest);
|
||||
CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL ("filename", reporter.lastFailedFile);
|
||||
CHECK_EQUAL (line, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
TEST(CheckArrayCloseFailureIncludesTolerance)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
float const data1[4] = { 0, 1, 2, 3 };
|
||||
float const data2[4] = { 0, 1, 3, 3 };
|
||||
CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f);
|
||||
}
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "0.01"));
|
||||
}
|
||||
|
||||
|
||||
TEST(CheckArrayCloseFailsOnException)
|
||||
{
|
||||
bool failure = false;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
const float data[4] = { 0, 1, 2, 3 };
|
||||
ThrowingObject obj;
|
||||
CHECK_ARRAY_CLOSE (data, obj, 3, 0.01f);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (failure);
|
||||
}
|
||||
|
||||
TEST(CheckArrayCloseFailureOnExceptionIncludesCheckContents)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
const float data[4] = { 0, 1, 2, 3 };
|
||||
ThrowingObject obj;
|
||||
CHECK_ARRAY_CLOSE (data, obj, 3, 0.01f);
|
||||
}
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "data"));
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "obj"));
|
||||
}
|
||||
|
||||
|
||||
TEST(CheckArrayEqualSuceedsOnEqual)
|
||||
{
|
||||
bool failure = true;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
const float data[4] = { 0, 1, 2, 3 };
|
||||
CHECK_ARRAY_EQUAL (data, data, 4);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (!failure);
|
||||
}
|
||||
|
||||
TEST(CheckArrayEqualFailsOnNotEqual)
|
||||
{
|
||||
bool failure = false;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
int const data1[4] = { 0, 1, 2, 3 };
|
||||
int const data2[4] = { 0, 1, 3, 3 };
|
||||
CHECK_ARRAY_EQUAL (data1, data2, 4);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (failure);
|
||||
}
|
||||
|
||||
TEST(CheckArrayEqualFailureIncludesCheckExpectedAndActual)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
int const data1[4] = { 0, 1, 2, 3 };
|
||||
int const data2[4] = { 0, 1, 3, 3 };
|
||||
CHECK_ARRAY_EQUAL (data1, data2, 4);
|
||||
}
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]"));
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]"));
|
||||
}
|
||||
|
||||
TEST(CheckArrayEqualFailureContainsCorrectInfo)
|
||||
{
|
||||
int line = 0;
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
int const data1[4] = { 0, 1, 2, 3 };
|
||||
int const data2[4] = { 0, 1, 3, 3 };
|
||||
CHECK_ARRAY_EQUAL (data1, data2, 4); line = __LINE__;
|
||||
}
|
||||
|
||||
CHECK_EQUAL ("CheckArrayEqualFailureContainsCorrectInfo", reporter.lastFailedTest);
|
||||
CHECK_EQUAL (__FILE__, reporter.lastFailedFile);
|
||||
CHECK_EQUAL (line, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
TEST(CheckArrayEqualFailsOnException)
|
||||
{
|
||||
bool failure = false;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
const float data[4] = { 0, 1, 2, 3 };
|
||||
ThrowingObject obj;
|
||||
CHECK_ARRAY_EQUAL (data, obj, 3);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (failure);
|
||||
}
|
||||
|
||||
TEST(CheckArrayEqualFailureOnExceptionIncludesCheckContents)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
const float data[4] = { 0, 1, 2, 3 };
|
||||
ThrowingObject obj;
|
||||
CHECK_ARRAY_EQUAL (data, obj, 3);
|
||||
}
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "data"));
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "obj"));
|
||||
}
|
||||
|
||||
float const* FunctionWithSideEffects2()
|
||||
{
|
||||
++g_sideEffect;
|
||||
static float const data[] = {1,2,3,4};
|
||||
return data;
|
||||
}
|
||||
|
||||
TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenPassing)
|
||||
{
|
||||
g_sideEffect = 0;
|
||||
{
|
||||
UnitTest::TestResults testResults_;
|
||||
const float data[] = { 0, 1, 2, 3 };
|
||||
CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f);
|
||||
}
|
||||
CHECK_EQUAL (1, g_sideEffect);
|
||||
}
|
||||
|
||||
TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenFailing)
|
||||
{
|
||||
g_sideEffect = 0;
|
||||
{
|
||||
UnitTest::TestResults testResults_;
|
||||
const float data[] = { 0, 1, 3, 3 };
|
||||
CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f);
|
||||
}
|
||||
CHECK_EQUAL (1, g_sideEffect);
|
||||
}
|
||||
|
||||
class ThrowingObject2D
|
||||
{
|
||||
public:
|
||||
float* operator[](int) const
|
||||
{
|
||||
throw "Test throw";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEST(CheckArray2DCloseSucceedsOnEqual)
|
||||
{
|
||||
bool failure = true;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
const float data[2][2] = { {0, 1}, {2, 3} };
|
||||
CHECK_ARRAY2D_CLOSE (data, data, 2, 2, 0.01f);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (!failure);
|
||||
}
|
||||
|
||||
TEST(CheckArray2DCloseFailsOnNotEqual)
|
||||
{
|
||||
bool failure = false;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
int const data1[2][2] = { {0, 1}, {2, 3} };
|
||||
int const data2[2][2] = { {0, 1}, {3, 3} };
|
||||
CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (failure);
|
||||
}
|
||||
|
||||
TEST(CheckArray2DCloseFailureIncludesCheckExpectedAndActual)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
int const data1[2][2] = { {0, 1}, {2, 3} };
|
||||
int const data2[2][2] = { {0, 1}, {3, 3} };
|
||||
CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f);
|
||||
}
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "xpected [ [ 0 1 ] [ 2 3 ] ]"));
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "was [ [ 0 1 ] [ 3 3 ] ]"));
|
||||
}
|
||||
|
||||
TEST(CheckArray2DCloseFailureContainsCorrectDetails)
|
||||
{
|
||||
int line = 0;
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
UnitTest::TestDetails m_details("array2DCloseTest", "array2DCloseSuite", "filename", -1);
|
||||
int const data1[2][2] = { {0, 1}, {2, 3} };
|
||||
int const data2[2][2] = { {0, 1}, {3, 3} };
|
||||
CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); line = __LINE__;
|
||||
}
|
||||
|
||||
CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest);
|
||||
CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL ("filename", reporter.lastFailedFile);
|
||||
CHECK_EQUAL (line, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
TEST(CheckArray2DCloseFailureBecauseOfExceptionContainsCorrectDetails)
|
||||
{
|
||||
int line = 0;
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
UnitTest::TestDetails m_details("array2DCloseTest", "array2DCloseSuite", "filename", -1);
|
||||
const float data[2][2] = { {0, 1}, {2, 3} };
|
||||
CHECK_ARRAY2D_CLOSE (data, ThrowingObject2D(), 2, 2, 0.01f); line = __LINE__;
|
||||
}
|
||||
|
||||
CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest);
|
||||
CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL ("filename", reporter.lastFailedFile);
|
||||
CHECK_EQUAL (line, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
TEST(CheckArray2DCloseFailureIncludesTolerance)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
float const data1[2][2] = { {0, 1}, {2, 3} };
|
||||
float const data2[2][2] = { {0, 1}, {3, 3} };
|
||||
CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f);
|
||||
}
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "0.01"));
|
||||
}
|
||||
|
||||
TEST(CheckArray2DCloseFailsOnException)
|
||||
{
|
||||
bool failure = false;
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
const float data[2][2] = { {0, 1}, {2, 3} };
|
||||
ThrowingObject2D obj;
|
||||
CHECK_ARRAY2D_CLOSE (data, obj, 2, 2, 0.01f);
|
||||
failure = (testResults_.GetFailureCount() > 0);
|
||||
}
|
||||
|
||||
CHECK (failure);
|
||||
}
|
||||
|
||||
TEST(CheckArray2DCloseFailureOnExceptionIncludesCheckContents)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
const float data[2][2] = { {0, 1}, {2, 3} };
|
||||
ThrowingObject2D obj;
|
||||
CHECK_ARRAY2D_CLOSE (data, obj, 2, 2, 0.01f);
|
||||
}
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "data"));
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "obj"));
|
||||
}
|
||||
|
||||
float const* const* FunctionWithSideEffects3()
|
||||
{
|
||||
++g_sideEffect;
|
||||
static float const data1[] = {0,1};
|
||||
static float const data2[] = {2,3};
|
||||
static const float* const data[] = {data1, data2};
|
||||
return data;
|
||||
}
|
||||
|
||||
TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenPassing)
|
||||
{
|
||||
g_sideEffect = 0;
|
||||
{
|
||||
UnitTest::TestResults testResults_;
|
||||
const float data[2][2] = { {0, 1}, {2, 3} };
|
||||
CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f);
|
||||
}
|
||||
CHECK_EQUAL (1, g_sideEffect);
|
||||
}
|
||||
|
||||
TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenFailing)
|
||||
{
|
||||
g_sideEffect = 0;
|
||||
{
|
||||
UnitTest::TestResults testResults_;
|
||||
const float data[2][2] = { {0, 1}, {3, 3} };
|
||||
CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f);
|
||||
}
|
||||
CHECK_EQUAL (1, g_sideEffect);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "RecordingReporter.h"
|
||||
|
||||
using namespace UnitTest;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
TEST(CheckEqualWithUnsignedLong)
|
||||
{
|
||||
TestResults results;
|
||||
unsigned long something = 2;
|
||||
CHECK_EQUAL( something, something );
|
||||
}
|
||||
|
||||
TEST(CheckEqualsWithStringsFailsOnDifferentStrings)
|
||||
{
|
||||
char txt1[] = "Hello";
|
||||
char txt2[] = "Hallo";
|
||||
TestResults results;
|
||||
CheckEqual(results, txt1, txt2, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (1, results.GetFailureCount());
|
||||
}
|
||||
|
||||
char txt1[] = "Hello"; // non-const on purpose so no folding of duplicate data
|
||||
char txt2[] = "Hello";
|
||||
|
||||
TEST(CheckEqualsWithStringsWorksOnContentsNonConstNonConst)
|
||||
{
|
||||
char const* const p1 = txt1;
|
||||
char const* const p2 = txt2;
|
||||
TestResults results;
|
||||
CheckEqual(results, p1, p2, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (0, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckEqualsWithStringsWorksOnContentsConstConst)
|
||||
{
|
||||
char* const p1 = txt1;
|
||||
char* const p2 = txt2;
|
||||
TestResults results;
|
||||
CheckEqual(results, p1, p2, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (0, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckEqualsWithStringsWorksOnContentsNonConstConst)
|
||||
{
|
||||
char* const p1 = txt1;
|
||||
char const* const p2 = txt2;
|
||||
TestResults results;
|
||||
CheckEqual(results, p1, p2, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (0, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckEqualsWithStringsWorksOnContentsConstNonConst)
|
||||
{
|
||||
char const* const p1 = txt1;
|
||||
char* const p2 = txt2;
|
||||
TestResults results;
|
||||
CheckEqual(results, p1, p2, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (0, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckEqualsWithStringsWorksOnContentsWithALiteral)
|
||||
{
|
||||
char const* const p1 = txt1;
|
||||
TestResults results;
|
||||
CheckEqual(results, "Hello", p1, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (0, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckEqualFailureIncludesCheckExpectedAndActual)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults results(&reporter);
|
||||
const int something = 2;
|
||||
CheckEqual (results, 1, something, TestDetails("", "", "", 0));
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "xpected 1"));
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "was 2"));
|
||||
}
|
||||
|
||||
TEST(CheckEqualFailureIncludesDetails)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults results(&reporter);
|
||||
TestDetails const details("mytest", "mysuite", "file.h", 101);
|
||||
|
||||
CheckEqual (results, 1, 2, details);
|
||||
|
||||
CHECK_EQUAL("mytest", reporter.lastFailedTest);
|
||||
CHECK_EQUAL("mysuite", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL("file.h", reporter.lastFailedFile);
|
||||
CHECK_EQUAL(101, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
TEST(CheckCloseTrue)
|
||||
{
|
||||
TestResults results;
|
||||
CheckClose(results, 3.001f, 3.0f, 0.1f, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (0, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckCloseFalse)
|
||||
{
|
||||
TestResults results;
|
||||
CheckClose(results, 3.12f, 3.0f, 0.1f, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (1, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckCloseWithZeroEpsilonWorksForSameNumber)
|
||||
{
|
||||
TestResults results;
|
||||
CheckClose(results, 0.1f, 0.1f, 0, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (0, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckCloseWithNaNFails)
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned int bitpattern;
|
||||
float nan;
|
||||
};
|
||||
bitpattern = 0xFFFFFFFF;
|
||||
TestResults results;
|
||||
CheckClose(results, 3.0f, nan, 0.1f, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (1, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckCloseWithNaNAgainstItselfFails)
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned int bitpattern;
|
||||
float nan;
|
||||
};
|
||||
bitpattern = 0xFFFFFFFF;
|
||||
TestResults results;
|
||||
CheckClose(results, nan, nan, 0.1f, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (1, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckCloseFailureIncludesCheckExpectedAndActual)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults results(&reporter);
|
||||
const float expected = 0.9f;
|
||||
const float actual = 1.1f;
|
||||
CheckClose (results, expected, actual, 0.01f, TestDetails("", "", "", 0));
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "xpected 0.9"));
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "was 1.1"));
|
||||
}
|
||||
|
||||
TEST(CheckCloseFailureIncludesTolerance)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults results(&reporter);
|
||||
CheckClose (results, 2, 3, 0.01f, TestDetails("", "", "", 0));
|
||||
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "0.01"));
|
||||
}
|
||||
|
||||
TEST(CheckCloseFailureIncludesDetails)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults results(&reporter);
|
||||
TestDetails const details("mytest", "mysuite", "header.h", 10);
|
||||
|
||||
CheckClose (results, 2, 3, 0.01f, details);
|
||||
|
||||
CHECK_EQUAL("mytest", reporter.lastFailedTest);
|
||||
CHECK_EQUAL("mysuite", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL("header.h", reporter.lastFailedFile);
|
||||
CHECK_EQUAL(10, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
|
||||
TEST(CheckArrayEqualTrue)
|
||||
{
|
||||
TestResults results;
|
||||
|
||||
int const array[3] = { 1, 2, 3 };
|
||||
CheckArrayEqual(results, array, array, 3, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (0, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckArrayEqualFalse)
|
||||
{
|
||||
TestResults results;
|
||||
|
||||
int const array1[3] = { 1, 2, 3 };
|
||||
int const array2[3] = { 1, 2, 2 };
|
||||
CheckArrayEqual(results, array1, array2, 3, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (1, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckArrayCloseTrue)
|
||||
{
|
||||
TestResults results;
|
||||
|
||||
float const array1[3] = { 1.0f, 1.5f, 2.0f };
|
||||
float const array2[3] = { 1.01f, 1.51f, 2.01f };
|
||||
CheckArrayClose(results, array1, array2, 3, 0.02f, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (0, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckArrayCloseFalse)
|
||||
{
|
||||
TestResults results;
|
||||
|
||||
float const array1[3] = { 1.0f, 1.5f, 2.0f };
|
||||
float const array2[3] = { 1.01f, 1.51f, 2.01f };
|
||||
CheckArrayClose(results, array1, array2, 3, 0.001f, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (1, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckArrayCloseFailureIncludesDetails)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults results(&reporter);
|
||||
TestDetails const details("arrayCloseTest", "arrayCloseSuite", "file", 1337);
|
||||
|
||||
float const array1[3] = { 1.0f, 1.5f, 2.0f };
|
||||
float const array2[3] = { 1.01f, 1.51f, 2.01f };
|
||||
CheckArrayClose(results, array1, array2, 3, 0.001f, details);
|
||||
|
||||
CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest);
|
||||
CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL("file", reporter.lastFailedFile);
|
||||
CHECK_EQUAL(1337, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
|
||||
TEST(CheckArray2DCloseTrue)
|
||||
{
|
||||
TestResults results;
|
||||
|
||||
float const array1[3][3] = { { 1.0f, 1.5f, 2.0f },
|
||||
{ 2.0f, 2.5f, 3.0f },
|
||||
{ 3.0f, 3.5f, 4.0f } };
|
||||
float const array2[3][3] = { { 1.01f, 1.51f, 2.01f },
|
||||
{ 2.01f, 2.51f, 3.01f },
|
||||
{ 3.01f, 3.51f, 4.01f } };
|
||||
CheckArray2DClose(results, array1, array2, 3, 3, 0.02f, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (0, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckArray2DCloseFalse)
|
||||
{
|
||||
TestResults results;
|
||||
|
||||
float const array1[3][3] = { { 1.0f, 1.5f, 2.0f },
|
||||
{ 2.0f, 2.5f, 3.0f },
|
||||
{ 3.0f, 3.5f, 4.0f } };
|
||||
float const array2[3][3] = { { 1.01f, 1.51f, 2.01f },
|
||||
{ 2.01f, 2.51f, 3.01f },
|
||||
{ 3.01f, 3.51f, 4.01f } };
|
||||
CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, TestDetails("", "", "", 0));
|
||||
CHECK_EQUAL (1, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckCloseWithDoublesSucceeds)
|
||||
{
|
||||
CHECK_CLOSE(0.5, 0.5, 0.0001);
|
||||
}
|
||||
|
||||
TEST(CheckArray2DCloseFailureIncludesDetails)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults results(&reporter);
|
||||
TestDetails const details("array2DCloseTest", "array2DCloseSuite", "file", 1234);
|
||||
|
||||
float const array1[3][3] = { { 1.0f, 1.5f, 2.0f },
|
||||
{ 2.0f, 2.5f, 3.0f },
|
||||
{ 3.0f, 3.5f, 4.0f } };
|
||||
float const array2[3][3] = { { 1.01f, 1.51f, 2.01f },
|
||||
{ 2.01f, 2.51f, 3.01f },
|
||||
{ 3.01f, 3.51f, 4.01f } };
|
||||
CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, details);
|
||||
|
||||
CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest);
|
||||
CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL("file", reporter.lastFailedFile);
|
||||
CHECK_EQUAL(1234, reporter.lastFailedLine);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "../DeferredTestReporter.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
struct MockDeferredTestReporter : public DeferredTestReporter
|
||||
{
|
||||
virtual void ReportSummary(int, int, int, float)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct DeferredTestReporterFixture
|
||||
{
|
||||
DeferredTestReporterFixture()
|
||||
: testName("UniqueTestName")
|
||||
, testSuite("UniqueTestSuite")
|
||||
, fileName("filename.h")
|
||||
, lineNumber(12)
|
||||
, details(testName.c_str(), testSuite.c_str(), fileName.c_str(), lineNumber)
|
||||
{
|
||||
}
|
||||
|
||||
MockDeferredTestReporter reporter;
|
||||
std::string const testName;
|
||||
std::string const testSuite;
|
||||
std::string const fileName;
|
||||
int const lineNumber;
|
||||
TestDetails const details;
|
||||
};
|
||||
|
||||
TEST_FIXTURE(DeferredTestReporterFixture, ReportTestStartCreatesANewDeferredTest)
|
||||
{
|
||||
reporter.ReportTestStart(details);
|
||||
CHECK_EQUAL(1, (int)reporter.GetResults().size());
|
||||
}
|
||||
|
||||
TEST_FIXTURE(DeferredTestReporterFixture, ReportTestStartCapturesTestNameAndSuite)
|
||||
{
|
||||
reporter.ReportTestStart(details);
|
||||
|
||||
DeferredTestResult const& result = reporter.GetResults().at(0);
|
||||
CHECK_EQUAL(testName.c_str(), result.testName);
|
||||
CHECK_EQUAL(testSuite.c_str(), result.suiteName);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(DeferredTestReporterFixture, ReportTestEndCapturesTestTime)
|
||||
{
|
||||
float const elapsed = 123.45f;
|
||||
reporter.ReportTestStart(details);
|
||||
reporter.ReportTestFinish(details, elapsed);
|
||||
|
||||
DeferredTestResult const& result = reporter.GetResults().at(0);
|
||||
CHECK_CLOSE(elapsed, result.timeElapsed, 0.0001f);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetails)
|
||||
{
|
||||
char const* failure = "failure";
|
||||
|
||||
reporter.ReportTestStart(details);
|
||||
reporter.ReportFailure(details, failure);
|
||||
|
||||
DeferredTestResult const& result = reporter.GetResults().at(0);
|
||||
CHECK(result.failed == true);
|
||||
CHECK_EQUAL(fileName.c_str(), result.failureFile);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetailsForMultipleFailures)
|
||||
{
|
||||
char const* failure1 = "failure 1";
|
||||
char const* failure2 = "failure 2";
|
||||
|
||||
reporter.ReportTestStart(details);
|
||||
reporter.ReportFailure(details, failure1);
|
||||
reporter.ReportFailure(details, failure2);
|
||||
|
||||
DeferredTestResult const& result = reporter.GetResults().at(0);
|
||||
CHECK_EQUAL(2u, result.failures.size());
|
||||
CHECK_EQUAL(failure1, result.failures[0].second);
|
||||
CHECK_EQUAL(failure2, result.failures[1].second);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(DeferredTestReporterFixture, DeferredTestReporterTakesCopyOfFailureMessage)
|
||||
{
|
||||
reporter.ReportTestStart(details);
|
||||
|
||||
char failureMessage[128];
|
||||
char const* goodStr = "Real failure message";
|
||||
char const* badStr = "Bogus failure message";
|
||||
|
||||
std::strcpy(failureMessage, goodStr);
|
||||
reporter.ReportFailure(details, failureMessage);
|
||||
std::strcpy(failureMessage, badStr);
|
||||
|
||||
DeferredTestResult const& result = reporter.GetResults().at(0);
|
||||
DeferredTestResult::Failure const& failure = result.failures.at(0);
|
||||
CHECK_EQUAL(goodStr, failure.second);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
#include "../UnitTest++.h"
|
||||
|
||||
#include "../MemoryOutStream.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace UnitTest;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST (DefaultIsEmptyString)
|
||||
{
|
||||
MemoryOutStream const stream;
|
||||
CHECK (stream.GetText() != 0);
|
||||
CHECK_EQUAL ("", stream.GetText());
|
||||
}
|
||||
|
||||
TEST (StreamingTextCopiesCharacters)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
stream << "Lalala";
|
||||
CHECK_EQUAL ("Lalala", stream.GetText());
|
||||
}
|
||||
|
||||
TEST (StreamingMultipleTimesConcatenatesResult)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
stream << "Bork" << "Foo" << "Bar";
|
||||
CHECK_EQUAL ("BorkFooBar", stream.GetText());
|
||||
}
|
||||
|
||||
TEST (StreamingIntWritesCorrectCharacters)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
stream << (int)123;
|
||||
CHECK_EQUAL ("123", stream.GetText());
|
||||
}
|
||||
|
||||
TEST (StreamingUnsignedIntWritesCorrectCharacters)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
stream << (unsigned int)123;
|
||||
CHECK_EQUAL ("123", stream.GetText());
|
||||
}
|
||||
|
||||
TEST (StreamingLongWritesCorrectCharacters)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
stream << (long)(-123);
|
||||
CHECK_EQUAL ("-123", stream.GetText());
|
||||
}
|
||||
|
||||
TEST (StreamingUnsignedLongWritesCorrectCharacters)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
stream << (unsigned long)123;
|
||||
CHECK_EQUAL ("123", stream.GetText());
|
||||
}
|
||||
|
||||
TEST (StreamingFloatWritesCorrectCharacters)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
stream << 3.1415f;
|
||||
CHECK (std::strstr(stream.GetText(), "3.1415"));
|
||||
}
|
||||
|
||||
TEST (StreamingDoubleWritesCorrectCharacters)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
stream << 3.1415;
|
||||
CHECK (std::strstr(stream.GetText(), "3.1415"));
|
||||
}
|
||||
|
||||
TEST (StreamingPointerWritesCorrectCharacters)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
int* p = (int*)0x1234;
|
||||
stream << p;
|
||||
CHECK (std::strstr(stream.GetText(), "1234"));
|
||||
}
|
||||
|
||||
TEST (StreamingSizeTWritesCorrectCharacters)
|
||||
{
|
||||
MemoryOutStream stream;
|
||||
size_t const s = 53124;
|
||||
stream << s;
|
||||
CHECK_EQUAL ("53124", stream.GetText());
|
||||
}
|
||||
|
||||
#ifdef UNITTEST_USE_CUSTOM_STREAMS
|
||||
|
||||
TEST (StreamInitialCapacityIsCorrect)
|
||||
{
|
||||
MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE);
|
||||
CHECK_EQUAL ((int)MemoryOutStream::GROW_CHUNK_SIZE, stream.GetCapacity());
|
||||
}
|
||||
|
||||
TEST (StreamInitialCapacityIsMultipleOfGrowChunkSize)
|
||||
{
|
||||
MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE + 1);
|
||||
CHECK_EQUAL ((int)MemoryOutStream::GROW_CHUNK_SIZE * 2, stream.GetCapacity());
|
||||
}
|
||||
|
||||
|
||||
TEST (ExceedingCapacityGrowsBuffer)
|
||||
{
|
||||
MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE);
|
||||
stream << "012345678901234567890123456789";
|
||||
char const* const oldBuffer = stream.GetText();
|
||||
stream << "0123456789";
|
||||
CHECK (oldBuffer != stream.GetText());
|
||||
}
|
||||
|
||||
TEST (ExceedingCapacityGrowsBufferByGrowChunk)
|
||||
{
|
||||
MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE);
|
||||
stream << "0123456789012345678901234567890123456789";
|
||||
CHECK_EQUAL (MemoryOutStream::GROW_CHUNK_SIZE * 2, stream.GetCapacity());
|
||||
}
|
||||
|
||||
TEST (WritingStringLongerThanCapacityFitsInNewBuffer)
|
||||
{
|
||||
MemoryOutStream stream(8);
|
||||
stream << "0123456789ABCDEF";
|
||||
CHECK_EQUAL ("0123456789ABCDEF", stream.GetText());
|
||||
}
|
||||
|
||||
TEST (WritingIntLongerThanCapacityFitsInNewBuffer)
|
||||
{
|
||||
MemoryOutStream stream(8);
|
||||
stream << "aaaa" << 123456;;
|
||||
CHECK_EQUAL ("aaaa123456", stream.GetText());
|
||||
}
|
||||
|
||||
TEST (WritingFloatLongerThanCapacityFitsInNewBuffer)
|
||||
{
|
||||
MemoryOutStream stream(8);
|
||||
stream << "aaaa" << 123456.0f;;
|
||||
CHECK_EQUAL ("aaaa123456.000000f", stream.GetText());
|
||||
}
|
||||
|
||||
TEST (WritingSizeTLongerThanCapacityFitsInNewBuffer)
|
||||
{
|
||||
MemoryOutStream stream(8);
|
||||
stream << "aaaa" << size_t(32145);
|
||||
CHECK_EQUAL ("aaaa32145", stream.GetText());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "../TestReporter.h"
|
||||
#include "../TimeHelpers.h"
|
||||
|
||||
using namespace UnitTest;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST (PassingTestHasNoFailures)
|
||||
{
|
||||
class PassingTest : public Test
|
||||
{
|
||||
public:
|
||||
PassingTest() : Test("passing") {}
|
||||
virtual void RunImpl(TestResults& testResults_) const
|
||||
{
|
||||
CHECK(true);
|
||||
}
|
||||
};
|
||||
|
||||
TestResults results;
|
||||
PassingTest().Run(results);
|
||||
CHECK_EQUAL(0, results.GetFailureCount());
|
||||
}
|
||||
|
||||
|
||||
TEST (FailingTestHasFailures)
|
||||
{
|
||||
class FailingTest : public Test
|
||||
{
|
||||
public:
|
||||
FailingTest() : Test("failing") {}
|
||||
virtual void RunImpl(TestResults& testResults_) const
|
||||
{
|
||||
CHECK(false);
|
||||
}
|
||||
};
|
||||
|
||||
TestResults results;
|
||||
FailingTest().Run(results);
|
||||
CHECK_EQUAL(1, results.GetFailureCount());
|
||||
}
|
||||
|
||||
|
||||
TEST (ThrowingTestsAreReportedAsFailures)
|
||||
{
|
||||
class CrashingTest : public Test
|
||||
{
|
||||
public:
|
||||
CrashingTest() : Test("throwing") {}
|
||||
virtual void RunImpl(TestResults&) const
|
||||
{
|
||||
throw "Blah";
|
||||
}
|
||||
};
|
||||
|
||||
TestResults results;
|
||||
CrashingTest().Run(results);
|
||||
CHECK_EQUAL(1, results.GetFailureCount());
|
||||
}
|
||||
|
||||
|
||||
#ifndef UNITTEST_MINGW
|
||||
TEST (CrashingTestsAreReportedAsFailures)
|
||||
{
|
||||
class CrashingTest : public Test
|
||||
{
|
||||
public:
|
||||
CrashingTest() : Test("crashing") {}
|
||||
virtual void RunImpl(TestResults&) const
|
||||
{
|
||||
reinterpret_cast< void (*)() >(0)();
|
||||
}
|
||||
};
|
||||
|
||||
TestResults results;
|
||||
CrashingTest().Run(results);
|
||||
CHECK_EQUAL(1, results.GetFailureCount());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST (TestWithUnspecifiedSuiteGetsDefaultSuite)
|
||||
{
|
||||
Test test("test");
|
||||
CHECK(test.m_details.suiteName != NULL);
|
||||
CHECK_EQUAL("DefaultSuite", test.m_details.suiteName);
|
||||
}
|
||||
|
||||
TEST (TestReflectsSpecifiedSuiteName)
|
||||
{
|
||||
Test test("test", "testSuite");
|
||||
CHECK(test.m_details.suiteName != NULL);
|
||||
CHECK_EQUAL("testSuite", test.m_details.suiteName);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "../TestList.h"
|
||||
|
||||
using namespace UnitTest;
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
TEST (TestListIsEmptyByDefault)
|
||||
{
|
||||
TestList list;
|
||||
CHECK (list.GetHead() == 0);
|
||||
}
|
||||
|
||||
TEST (AddingTestSetsHeadToTest)
|
||||
{
|
||||
Test test("test");
|
||||
TestList list;
|
||||
list.Add(&test);
|
||||
|
||||
CHECK (list.GetHead() == &test);
|
||||
CHECK (test.next == 0);
|
||||
}
|
||||
|
||||
TEST (AddingSecondTestAddsItToEndOfList)
|
||||
{
|
||||
Test test1("test1");
|
||||
Test test2("test2");
|
||||
|
||||
TestList list;
|
||||
list.Add(&test1);
|
||||
list.Add(&test2);
|
||||
|
||||
CHECK (list.GetHead() == &test1);
|
||||
CHECK (test1.next == &test2);
|
||||
CHECK (test2.next == 0);
|
||||
}
|
||||
|
||||
TEST (ListAdderAddsTestToList)
|
||||
{
|
||||
TestList list;
|
||||
|
||||
Test test("");
|
||||
ListAdder adder(list, &test);
|
||||
|
||||
CHECK (list.GetHead() == &test);
|
||||
CHECK (test.next == 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "../TestMacros.h"
|
||||
#include "../TestList.h"
|
||||
#include "../TestResults.h"
|
||||
#include "../TestReporter.h"
|
||||
#include "RecordingReporter.h"
|
||||
|
||||
using namespace UnitTest;
|
||||
|
||||
namespace {
|
||||
|
||||
TestList list1;
|
||||
TEST_EX(DummyTest, list1)
|
||||
{
|
||||
(void)testResults_;
|
||||
}
|
||||
|
||||
TEST (TestsAreAddedToTheListThroughMacro)
|
||||
{
|
||||
CHECK (list1.GetHead() != 0);
|
||||
CHECK (list1.GetHead()->next == 0);
|
||||
}
|
||||
|
||||
struct ThrowingThingie
|
||||
{
|
||||
ThrowingThingie() : dummy(false)
|
||||
{
|
||||
if (!dummy)
|
||||
throw "Oops";
|
||||
}
|
||||
bool dummy;
|
||||
};
|
||||
|
||||
TestList list2;
|
||||
TEST_FIXTURE_EX(ThrowingThingie,DummyTestName,list2)
|
||||
{
|
||||
(void)testResults_;
|
||||
}
|
||||
|
||||
TEST (ExceptionsInFixtureAreReportedAsHappeningInTheFixture)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults result(&reporter);
|
||||
list2.GetHead()->Run(result);
|
||||
|
||||
CHECK (strstr(reporter.lastFailedMessage, "xception"));
|
||||
CHECK (strstr(reporter.lastFailedMessage, "fixture"));
|
||||
CHECK (strstr(reporter.lastFailedMessage, "ThrowingThingie"));
|
||||
}
|
||||
|
||||
struct DummyFixture
|
||||
{
|
||||
int x;
|
||||
};
|
||||
|
||||
// We're really testing the macros so we just want them to compile and link
|
||||
SUITE(TestSuite1)
|
||||
{
|
||||
|
||||
TEST(SimilarlyNamedTestsInDifferentSuitesWork)
|
||||
{
|
||||
(void)testResults_;
|
||||
}
|
||||
|
||||
TEST_FIXTURE(DummyFixture,SimilarlyNamedFixtureTestsInDifferentSuitesWork)
|
||||
{
|
||||
(void)testResults_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SUITE(TestSuite2)
|
||||
{
|
||||
|
||||
TEST(SimilarlyNamedTestsInDifferentSuitesWork)
|
||||
{
|
||||
(void)testResults_;
|
||||
}
|
||||
|
||||
TEST_FIXTURE(DummyFixture,SimilarlyNamedFixtureTestsInDifferentSuitesWork)
|
||||
{
|
||||
(void)testResults_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TestList macroTestList1;
|
||||
TEST_EX(MacroTestHelper1,macroTestList1)
|
||||
{
|
||||
(void)testResults_;
|
||||
}
|
||||
|
||||
TEST(TestAddedWithTEST_EXMacroGetsDefaultSuite)
|
||||
{
|
||||
CHECK(macroTestList1.GetHead() != NULL);
|
||||
CHECK_EQUAL ("MacroTestHelper1", macroTestList1.GetHead()->m_details.testName);
|
||||
CHECK_EQUAL ("DefaultSuite", macroTestList1.GetHead()->m_details.suiteName);
|
||||
}
|
||||
|
||||
TestList macroTestList2;
|
||||
TEST_FIXTURE_EX(DummyFixture,MacroTestHelper2,macroTestList2)
|
||||
{
|
||||
(void)testResults_;
|
||||
}
|
||||
|
||||
TEST(TestAddedWithTEST_FIXTURE_EXMacroGetsDefaultSuite)
|
||||
{
|
||||
CHECK(macroTestList2.GetHead() != NULL);
|
||||
CHECK_EQUAL ("MacroTestHelper2", macroTestList2.GetHead()->m_details.testName);
|
||||
CHECK_EQUAL ("DefaultSuite", macroTestList2.GetHead()->m_details.suiteName);
|
||||
}
|
||||
|
||||
struct FixtureCtorThrows
|
||||
{
|
||||
FixtureCtorThrows() { throw "exception"; }
|
||||
};
|
||||
|
||||
TestList throwingFixtureTestList1;
|
||||
TEST_FIXTURE_EX(FixtureCtorThrows, FixtureCtorThrowsTestName, throwingFixtureTestList1)
|
||||
{
|
||||
(void)testResults_;
|
||||
}
|
||||
|
||||
TEST(FixturesWithThrowingCtorsAreFailures)
|
||||
{
|
||||
CHECK(throwingFixtureTestList1.GetHead() != NULL);
|
||||
RecordingReporter reporter;
|
||||
TestResults result(&reporter);
|
||||
throwingFixtureTestList1.GetHead()->Run(result);
|
||||
|
||||
int const failureCount = result.GetFailedTestCount();
|
||||
CHECK_EQUAL(1, failureCount);
|
||||
CHECK(strstr(reporter.lastFailedMessage, "while constructing fixture"));
|
||||
}
|
||||
|
||||
struct FixtureDtorThrows
|
||||
{
|
||||
~FixtureDtorThrows() { throw "exception"; }
|
||||
};
|
||||
|
||||
TestList throwingFixtureTestList2;
|
||||
TEST_FIXTURE_EX(FixtureDtorThrows, FixtureDtorThrowsTestName, throwingFixtureTestList2)
|
||||
{
|
||||
(void)testResults_;
|
||||
}
|
||||
|
||||
TEST(FixturesWithThrowingDtorsAreFailures)
|
||||
{
|
||||
CHECK(throwingFixtureTestList2.GetHead() != NULL);
|
||||
RecordingReporter reporter;
|
||||
TestResults result(&reporter);
|
||||
throwingFixtureTestList2.GetHead()->Run(result);
|
||||
|
||||
int const failureCount = result.GetFailedTestCount();
|
||||
CHECK_EQUAL(1, failureCount);
|
||||
CHECK(strstr(reporter.lastFailedMessage, "while destroying fixture"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// We're really testing if it's possible to use the same suite in two files
|
||||
// to compile and link successfuly (TestTestSuite.cpp has suite with the same name)
|
||||
// Note: we are outside of the anonymous namespace
|
||||
SUITE(SameTestSuite)
|
||||
{
|
||||
TEST(DummyTest1)
|
||||
{
|
||||
(void)testResults_;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "../TestResults.h"
|
||||
#include "RecordingReporter.h"
|
||||
|
||||
using namespace UnitTest;
|
||||
|
||||
namespace {
|
||||
|
||||
TestDetails const details("testname", "suitename", "filename", 123);
|
||||
|
||||
|
||||
TEST(StartsWithNoTestsRun)
|
||||
{
|
||||
TestResults results;
|
||||
CHECK_EQUAL (0, results.GetTotalTestCount());
|
||||
}
|
||||
|
||||
TEST(RecordsNumbersOfTests)
|
||||
{
|
||||
TestResults results;
|
||||
results.OnTestStart(details);
|
||||
results.OnTestStart(details);
|
||||
results.OnTestStart(details);
|
||||
CHECK_EQUAL(3, results.GetTotalTestCount());
|
||||
}
|
||||
|
||||
TEST(StartsWithNoTestsFailing)
|
||||
{
|
||||
TestResults results;
|
||||
CHECK_EQUAL (0, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(RecordsNumberOfFailures)
|
||||
{
|
||||
TestResults results;
|
||||
results.OnTestFailure(details, "");
|
||||
results.OnTestFailure(details, "");
|
||||
CHECK_EQUAL(2, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(RecordsNumberOfFailedTests)
|
||||
{
|
||||
TestResults results;
|
||||
|
||||
results.OnTestStart(details);
|
||||
results.OnTestFailure(details, "");
|
||||
results.OnTestFinish(details, 0);
|
||||
|
||||
results.OnTestStart(details);
|
||||
results.OnTestFailure(details, "");
|
||||
results.OnTestFailure(details, "");
|
||||
results.OnTestFailure(details, "");
|
||||
results.OnTestFinish(details, 0);
|
||||
|
||||
CHECK_EQUAL (2, results.GetFailedTestCount());
|
||||
}
|
||||
|
||||
TEST(NotifiesReporterOfTestStartWithCorrectInfo)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults results(&reporter);
|
||||
results.OnTestStart(details);
|
||||
|
||||
CHECK_EQUAL (1, reporter.testRunCount);
|
||||
CHECK_EQUAL ("suitename", reporter.lastStartedSuite);
|
||||
CHECK_EQUAL ("testname", reporter.lastStartedTest);
|
||||
}
|
||||
|
||||
TEST(NotifiesReporterOfTestFailureWithCorrectInfo)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults results(&reporter);
|
||||
|
||||
results.OnTestFailure(details, "failurestring");
|
||||
CHECK_EQUAL (1, reporter.testFailedCount);
|
||||
CHECK_EQUAL ("filename", reporter.lastFailedFile);
|
||||
CHECK_EQUAL (123, reporter.lastFailedLine);
|
||||
CHECK_EQUAL ("suitename", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL ("testname", reporter.lastFailedTest);
|
||||
CHECK_EQUAL ("failurestring", reporter.lastFailedMessage);
|
||||
}
|
||||
|
||||
TEST(NotifiesReporterOfCheckFailureWithCorrectInfo)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults results(&reporter);
|
||||
|
||||
results.OnTestFailure(details, "failurestring");
|
||||
CHECK_EQUAL (1, reporter.testFailedCount);
|
||||
|
||||
CHECK_EQUAL ("filename", reporter.lastFailedFile);
|
||||
CHECK_EQUAL (123, reporter.lastFailedLine);
|
||||
CHECK_EQUAL ("testname", reporter.lastFailedTest);
|
||||
CHECK_EQUAL ("suitename", reporter.lastFailedSuite);
|
||||
CHECK_EQUAL ("failurestring", reporter.lastFailedMessage);
|
||||
}
|
||||
|
||||
TEST(NotifiesReporterOfTestEnd)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults results(&reporter);
|
||||
|
||||
results.OnTestFinish(details, 0.1234f);
|
||||
CHECK_EQUAL (1, reporter.testFinishedCount);
|
||||
CHECK_EQUAL ("testname", reporter.lastFinishedTest);
|
||||
CHECK_EQUAL ("suitename", reporter.lastFinishedSuite);
|
||||
CHECK_CLOSE (0.1234f, reporter.lastFinishedTestTime, 0.0001f);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "RecordingReporter.h"
|
||||
#include "../ReportAssert.h"
|
||||
#include "../TestList.h"
|
||||
#include "../TimeHelpers.h"
|
||||
#include "../TimeConstraint.h"
|
||||
|
||||
using namespace UnitTest;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct MockTest : public Test
|
||||
{
|
||||
MockTest(char const* testName, bool const success_, bool const assert_, int const count_ = 1)
|
||||
: Test(testName)
|
||||
, success(success_)
|
||||
, asserted(assert_)
|
||||
, count(count_)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void RunImpl(TestResults& testResults_) const
|
||||
{
|
||||
for (int i=0; i < count; ++i)
|
||||
{
|
||||
if (asserted)
|
||||
ReportAssert("desc", "file", 0);
|
||||
else if (!success)
|
||||
testResults_.OnTestFailure(m_details, "message");
|
||||
}
|
||||
}
|
||||
|
||||
bool const success;
|
||||
bool const asserted;
|
||||
int const count;
|
||||
};
|
||||
|
||||
|
||||
struct TestRunnerFixture
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestList list;
|
||||
};
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, TestStartIsReportedCorrectly)
|
||||
{
|
||||
MockTest test("goodtest", true, false);
|
||||
list.Add(&test);
|
||||
|
||||
RunAllTests(reporter, list, 0);
|
||||
CHECK_EQUAL(1, reporter.testRunCount);
|
||||
CHECK_EQUAL("goodtest", reporter.lastStartedTest);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, TestFinishIsReportedCorrectly)
|
||||
{
|
||||
MockTest test("goodtest", true, false);
|
||||
list.Add(&test);
|
||||
|
||||
RunAllTests(reporter, list, 0);
|
||||
CHECK_EQUAL(1, reporter.testFinishedCount);
|
||||
CHECK_EQUAL("goodtest", reporter.lastFinishedTest);
|
||||
}
|
||||
|
||||
class SlowTest : public Test
|
||||
{
|
||||
public:
|
||||
SlowTest() : Test("slow", "somesuite", "filename", 123) {}
|
||||
virtual void RunImpl(TestResults&) const
|
||||
{
|
||||
TimeHelpers::SleepMs(20);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, TestFinishIsCalledWithCorrectTime)
|
||||
{
|
||||
SlowTest test;
|
||||
list.Add(&test);
|
||||
|
||||
RunAllTests(reporter, list, 0);
|
||||
CHECK (reporter.lastFinishedTestTime >= 0.005f && reporter.lastFinishedTestTime <= 0.050f);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, FailureCountIsZeroWhenNoTestsAreRun)
|
||||
{
|
||||
CHECK_EQUAL(0, RunAllTests(reporter, list, 0));
|
||||
CHECK_EQUAL(0, reporter.testRunCount);
|
||||
CHECK_EQUAL(0, reporter.testFailedCount);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, CallsReportFailureOncePerFailingTest)
|
||||
{
|
||||
MockTest test1("test", false, false);
|
||||
list.Add(&test1);
|
||||
MockTest test2("test", true, false);
|
||||
list.Add(&test2);
|
||||
MockTest test3("test", false, false);
|
||||
list.Add(&test3);
|
||||
|
||||
CHECK_EQUAL(2, RunAllTests(reporter, list, 0));
|
||||
CHECK_EQUAL(2, reporter.testFailedCount);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, TestsThatAssertAreReportedAsFailing)
|
||||
{
|
||||
MockTest test("test", true, true);
|
||||
list.Add(&test);
|
||||
|
||||
RunAllTests(reporter, list, 0);
|
||||
CHECK_EQUAL(1, reporter.testFailedCount);
|
||||
}
|
||||
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfTestCount)
|
||||
{
|
||||
MockTest test1("test", true, false);
|
||||
MockTest test2("test", true, false);
|
||||
MockTest test3("test", true, false);
|
||||
list.Add(&test1);
|
||||
list.Add(&test2);
|
||||
list.Add(&test3);
|
||||
|
||||
RunAllTests(reporter, list, 0);
|
||||
CHECK_EQUAL(3, reporter.summaryTotalTestCount);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailedTests)
|
||||
{
|
||||
MockTest test1("test", false, false, 2);
|
||||
MockTest test2("test", true, false);
|
||||
MockTest test3("test", false, false, 3);
|
||||
list.Add(&test1);
|
||||
list.Add(&test2);
|
||||
list.Add(&test3);
|
||||
|
||||
RunAllTests(reporter, list, 0);
|
||||
CHECK_EQUAL(2, reporter.summaryFailedTestCount);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailures)
|
||||
{
|
||||
MockTest test1("test", false, false, 2);
|
||||
MockTest test2("test", true, false);
|
||||
MockTest test3("test", false, false, 3);
|
||||
list.Add(&test1);
|
||||
list.Add(&test2);
|
||||
list.Add(&test3);
|
||||
|
||||
RunAllTests(reporter, list, 0);
|
||||
CHECK_EQUAL(5, reporter.summaryFailureCount);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, SlowTestPassesForHighTimeThreshold)
|
||||
{
|
||||
SlowTest test;
|
||||
list.Add(&test);
|
||||
RunAllTests(reporter, list, 0);
|
||||
CHECK_EQUAL (0, reporter.testFailedCount);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, SlowTestFailsForLowTimeThreshold)
|
||||
{
|
||||
SlowTest test;
|
||||
list.Add(&test);
|
||||
RunAllTests(reporter, list, 0, 3);
|
||||
CHECK_EQUAL (1, reporter.testFailedCount);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, SlowTestHasCorrectFailureInformation)
|
||||
{
|
||||
SlowTest test;
|
||||
list.Add(&test);
|
||||
RunAllTests(reporter, list, 0, 3);
|
||||
CHECK_EQUAL (test.m_details.testName, reporter.lastFailedTest);
|
||||
CHECK (std::strstr(test.m_details.filename, reporter.lastFailedFile));
|
||||
CHECK_EQUAL (test.m_details.lineNumber, reporter.lastFailedLine);
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "Global time constraint failed"));
|
||||
CHECK (std::strstr(reporter.lastFailedMessage, "3ms"));
|
||||
}
|
||||
|
||||
TEST_FIXTURE(TestRunnerFixture, SlowTestWithTimeExemptionPasses)
|
||||
{
|
||||
class SlowExemptedTest : public Test
|
||||
{
|
||||
public:
|
||||
SlowExemptedTest() : Test("slowexempted", "", 0) {}
|
||||
virtual void RunImpl(TestResults&) const
|
||||
{
|
||||
UNITTEST_TIME_CONSTRAINT_EXEMPT();
|
||||
TimeHelpers::SleepMs(20);
|
||||
}
|
||||
};
|
||||
|
||||
SlowExemptedTest test;
|
||||
list.Add(&test);
|
||||
RunAllTests(reporter, list, 0, 3);
|
||||
CHECK_EQUAL (0, reporter.testFailedCount);
|
||||
}
|
||||
|
||||
struct TestSuiteFixture
|
||||
{
|
||||
TestSuiteFixture()
|
||||
: test1("TestInDefaultSuite")
|
||||
, test2("TestInOtherSuite", "OtherSuite")
|
||||
, test3("SecondTestInDefaultSuite")
|
||||
{
|
||||
list.Add(&test1);
|
||||
list.Add(&test2);
|
||||
}
|
||||
|
||||
Test test1;
|
||||
Test test2;
|
||||
Test test3;
|
||||
RecordingReporter reporter;
|
||||
TestList list;
|
||||
};
|
||||
|
||||
TEST_FIXTURE(TestSuiteFixture, TestRunnerRunsAllSuitesIfNullSuiteIsPassed)
|
||||
{
|
||||
RunAllTests(reporter, list, 0);
|
||||
CHECK_EQUAL(2, reporter.summaryTotalTestCount);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(TestSuiteFixture,TestRunnerRunsOnlySpecifiedSuite)
|
||||
{
|
||||
RunAllTests(reporter, list, "OtherSuite");
|
||||
CHECK_EQUAL(1, reporter.summaryTotalTestCount);
|
||||
CHECK_EQUAL("TestInOtherSuite", reporter.lastFinishedTest);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "../UnitTest++.h"
|
||||
|
||||
// We're really testing if it's possible to use the same suite in two files
|
||||
// to compile and link successfuly (TestTestSuite.cpp has suite with the same name)
|
||||
// Note: we are outside of the anonymous namespace
|
||||
SUITE(SameTestSuite)
|
||||
{
|
||||
TEST(DummyTest2)
|
||||
{
|
||||
(void)testResults_;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "../TestResults.h"
|
||||
#include "../TimeHelpers.h"
|
||||
#include "RecordingReporter.h"
|
||||
|
||||
using namespace UnitTest;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
TEST(TimeConstraintSucceedsWithFastTest)
|
||||
{
|
||||
TestResults result;
|
||||
{
|
||||
TimeConstraint t(200, result, TestDetails("", "", "", 0));
|
||||
TimeHelpers::SleepMs(5);
|
||||
}
|
||||
CHECK_EQUAL(0, result.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(TimeConstraintFailsWithSlowTest)
|
||||
{
|
||||
TestResults result;
|
||||
{
|
||||
TimeConstraint t(10, result, TestDetails("", "", "", 0));
|
||||
TimeHelpers::SleepMs(20);
|
||||
}
|
||||
CHECK_EQUAL(1, result.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(TimeConstraintFailureIncludesCorrectData)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults result(&reporter);
|
||||
{
|
||||
TestDetails const details("testname", "suitename", "filename", 10);
|
||||
TimeConstraint t(10, result, details);
|
||||
TimeHelpers::SleepMs(20);
|
||||
}
|
||||
CHECK(std::strstr(reporter.lastFailedFile, "filename"));
|
||||
CHECK_EQUAL(10, reporter.lastFailedLine);
|
||||
CHECK(std::strstr(reporter.lastFailedTest, "testname"));
|
||||
}
|
||||
|
||||
TEST(TimeConstraintFailureIncludesTimeoutInformation)
|
||||
{
|
||||
RecordingReporter reporter;
|
||||
TestResults result(&reporter);
|
||||
{
|
||||
TimeConstraint t(10, result, TestDetails("", "", "", 0));
|
||||
TimeHelpers::SleepMs(20);
|
||||
}
|
||||
CHECK(std::strstr(reporter.lastFailedMessage, "ime constraint"));
|
||||
CHECK(std::strstr(reporter.lastFailedMessage, "under 10ms"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "../TimeHelpers.h"
|
||||
|
||||
#include "RecordingReporter.h"
|
||||
|
||||
namespace {
|
||||
|
||||
TEST (TimeConstraintMacroQualifiesNamespace)
|
||||
{
|
||||
// If this compiles without a "using namespace UnitTest;", all is well.
|
||||
UNITTEST_TIME_CONSTRAINT(1);
|
||||
}
|
||||
|
||||
TEST (TimeConstraintMacroUsesCorrectInfo)
|
||||
{
|
||||
int testLine = 0;
|
||||
RecordingReporter reporter;
|
||||
{
|
||||
UnitTest::TestResults testResults_(&reporter);
|
||||
UNITTEST_TIME_CONSTRAINT(10); testLine = __LINE__;
|
||||
UnitTest::TimeHelpers::SleepMs(20);
|
||||
}
|
||||
CHECK_EQUAL (1, reporter.testFailedCount);
|
||||
CHECK (std::strstr(reporter.lastFailedFile, __FILE__));
|
||||
CHECK_EQUAL (testLine, reporter.lastFailedLine);
|
||||
CHECK (std::strstr(reporter.lastFailedTest, "TimeConstraintMacroUsesCorrectInfo"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "../ReportAssert.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
// These are sample tests that show the different features of the framework
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(ValidCheckSucceeds)
|
||||
{
|
||||
bool const b = true;
|
||||
CHECK(b);
|
||||
}
|
||||
|
||||
TEST(CheckWorksWithPointers)
|
||||
{
|
||||
void* p = (void *)0x100;
|
||||
CHECK(p);
|
||||
CHECK(p != 0);
|
||||
}
|
||||
|
||||
TEST(ValidCheckEqualSucceeds)
|
||||
{
|
||||
int const x = 3;
|
||||
int const y = 3;
|
||||
CHECK_EQUAL(x, y);
|
||||
}
|
||||
|
||||
TEST(CheckEqualWorksWithPointers)
|
||||
{
|
||||
void* p = (void *)0;
|
||||
CHECK_EQUAL ((void*)0, p);
|
||||
}
|
||||
|
||||
TEST(ValidCheckCloseSucceeds)
|
||||
{
|
||||
CHECK_CLOSE(2.0f, 2.001f, 0.01f);
|
||||
CHECK_CLOSE(2.001f, 2.0f, 0.01f);
|
||||
}
|
||||
|
||||
TEST(ArrayCloseSucceeds)
|
||||
{
|
||||
float const a1[] = {1, 2, 3};
|
||||
float const a2[] = {1, 2.01f, 3};
|
||||
CHECK_ARRAY_CLOSE (a1, a2, 3, 0.1f);
|
||||
}
|
||||
|
||||
TEST (CheckArrayCloseWorksWithVectors)
|
||||
{
|
||||
std::vector< float > a(4);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
a[i] = (float)i;
|
||||
|
||||
CHECK_ARRAY_CLOSE (a, a, (int)a.size(), 0.0001f);
|
||||
}
|
||||
|
||||
TEST(CheckThrowMacroSucceedsOnCorrectException)
|
||||
{
|
||||
struct TestException {};
|
||||
CHECK_THROW(throw TestException(), TestException);
|
||||
}
|
||||
|
||||
TEST(CheckAssertSucceeds)
|
||||
{
|
||||
CHECK_ASSERT(UnitTest::ReportAssert("desc", "file", 0));
|
||||
}
|
||||
|
||||
TEST(CheckThrowMacroFailsOnMissingException)
|
||||
{
|
||||
class NoThrowTest : public UnitTest::Test
|
||||
{
|
||||
public:
|
||||
NoThrowTest() : Test("nothrow") {}
|
||||
void DontThrow() const
|
||||
{
|
||||
}
|
||||
|
||||
virtual void RunImpl(UnitTest::TestResults& testResults_) const
|
||||
{
|
||||
CHECK_THROW(DontThrow(), int);
|
||||
}
|
||||
};
|
||||
|
||||
UnitTest::TestResults results;
|
||||
|
||||
NoThrowTest const test;
|
||||
test.Run(results);
|
||||
CHECK_EQUAL(1, results.GetFailureCount());
|
||||
}
|
||||
|
||||
TEST(CheckThrowMacroFailsOnWrongException)
|
||||
{
|
||||
class WrongThrowTest : public UnitTest::Test
|
||||
{
|
||||
public:
|
||||
WrongThrowTest() : Test("wrongthrow") {}
|
||||
virtual void RunImpl(UnitTest::TestResults& testResults_) const
|
||||
{
|
||||
CHECK_THROW(throw "oops", int);
|
||||
}
|
||||
};
|
||||
|
||||
UnitTest::TestResults results;
|
||||
|
||||
WrongThrowTest const test;
|
||||
test.Run(results);
|
||||
CHECK_EQUAL(1, results.GetFailureCount());
|
||||
}
|
||||
|
||||
struct SimpleFixture
|
||||
{
|
||||
SimpleFixture()
|
||||
{
|
||||
++instanceCount;
|
||||
}
|
||||
~SimpleFixture()
|
||||
{
|
||||
--instanceCount;
|
||||
}
|
||||
|
||||
static int instanceCount;
|
||||
};
|
||||
|
||||
int SimpleFixture::instanceCount = 0;
|
||||
|
||||
TEST_FIXTURE(SimpleFixture, DefaultFixtureCtorIsCalled)
|
||||
{
|
||||
CHECK(SimpleFixture::instanceCount > 0);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(SimpleFixture, OnlyOneFixtureAliveAtATime)
|
||||
{
|
||||
CHECK_EQUAL(1, SimpleFixture::instanceCount);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
#include "../UnitTest++.h"
|
||||
#include "../XmlTestReporter.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace UnitTest;
|
||||
using std::ostringstream;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
#ifdef UNITTEST_USE_CUSTOM_STREAMS
|
||||
|
||||
// Overload to let MemoryOutStream accept std::string
|
||||
MemoryOutStream& operator<<(MemoryOutStream& s, const std::string& value)
|
||||
{
|
||||
s << value.c_str();
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct XmlTestReporterFixture
|
||||
{
|
||||
XmlTestReporterFixture()
|
||||
: reporter(output)
|
||||
{
|
||||
}
|
||||
|
||||
ostringstream output;
|
||||
XmlTestReporter reporter;
|
||||
};
|
||||
|
||||
TEST_FIXTURE(XmlTestReporterFixture, MultipleCharactersAreEscaped)
|
||||
{
|
||||
TestDetails const details("TestName", "suite", "filename.h", 4321);
|
||||
|
||||
reporter.ReportTestStart(details);
|
||||
reporter.ReportFailure(details, "\"\"\'\'&&<<>>");
|
||||
reporter.ReportTestFinish(details, 0.1f);
|
||||
reporter.ReportSummary(1, 2, 3, 0.1f);
|
||||
|
||||
char const* expected =
|
||||
"<?xml version=\"1.0\"?>"
|
||||
"<unittest-results tests=\"1\" failedtests=\"2\" failures=\"3\" time=\"0.1\">"
|
||||
"<test suite=\"suite\" name=\"TestName\" time=\"0.1\">"
|
||||
"<failure message=\"filename.h(4321) : "
|
||||
"""''&&<<>>\"/>"
|
||||
"</test>"
|
||||
"</unittest-results>";
|
||||
|
||||
CHECK_EQUAL(expected, output.str());
|
||||
}
|
||||
|
||||
TEST_FIXTURE(XmlTestReporterFixture, OutputIsCachedUntilReportSummaryIsCalled)
|
||||
{
|
||||
TestDetails const details("", "", "", 0);
|
||||
|
||||
reporter.ReportTestStart(details);
|
||||
reporter.ReportFailure(details, "message");
|
||||
reporter.ReportTestFinish(details, 1.0F);
|
||||
CHECK(output.str().empty());
|
||||
|
||||
reporter.ReportSummary(1, 1, 1, 1.0f);
|
||||
CHECK(!output.str().empty());
|
||||
}
|
||||
|
||||
TEST_FIXTURE(XmlTestReporterFixture, EmptyReportSummaryFormat)
|
||||
{
|
||||
reporter.ReportSummary(0, 0, 0, 0.1f);
|
||||
|
||||
const char *expected =
|
||||
"<?xml version=\"1.0\"?>"
|
||||
"<unittest-results tests=\"0\" failedtests=\"0\" failures=\"0\" time=\"0.1\">"
|
||||
"</unittest-results>";
|
||||
|
||||
CHECK_EQUAL(expected, output.str());
|
||||
}
|
||||
|
||||
TEST_FIXTURE(XmlTestReporterFixture, SingleSuccessfulTestReportSummaryFormat)
|
||||
{
|
||||
TestDetails const details("TestName", "DefaultSuite", "", 0);
|
||||
|
||||
reporter.ReportTestStart(details);
|
||||
reporter.ReportSummary(1, 0, 0, 0.1f);
|
||||
|
||||
const char *expected =
|
||||
"<?xml version=\"1.0\"?>"
|
||||
"<unittest-results tests=\"1\" failedtests=\"0\" failures=\"0\" time=\"0.1\">"
|
||||
"<test suite=\"DefaultSuite\" name=\"TestName\" time=\"0\"/>"
|
||||
"</unittest-results>";
|
||||
|
||||
CHECK_EQUAL(expected, output.str());
|
||||
}
|
||||
|
||||
TEST_FIXTURE(XmlTestReporterFixture, SingleFailedTestReportSummaryFormat)
|
||||
{
|
||||
TestDetails const details("A Test", "suite", "A File", 4321);
|
||||
|
||||
reporter.ReportTestStart(details);
|
||||
reporter.ReportFailure(details, "A Failure");
|
||||
reporter.ReportSummary(1, 1, 1, 0.1f);
|
||||
|
||||
const char *expected =
|
||||
"<?xml version=\"1.0\"?>"
|
||||
"<unittest-results tests=\"1\" failedtests=\"1\" failures=\"1\" time=\"0.1\">"
|
||||
"<test suite=\"suite\" name=\"A Test\" time=\"0\">"
|
||||
"<failure message=\"A File(4321) : A Failure\"/>"
|
||||
"</test>"
|
||||
"</unittest-results>";
|
||||
|
||||
CHECK_EQUAL(expected, output.str());
|
||||
}
|
||||
|
||||
TEST_FIXTURE(XmlTestReporterFixture, FailureMessageIsXMLEscaped)
|
||||
{
|
||||
TestDetails const details("TestName", "suite", "filename.h", 4321);
|
||||
|
||||
reporter.ReportTestStart(details);
|
||||
reporter.ReportFailure(details, "\"\'&<>");
|
||||
reporter.ReportTestFinish(details, 0.1f);
|
||||
reporter.ReportSummary(1, 1, 1, 0.1f);
|
||||
|
||||
char const* expected =
|
||||
"<?xml version=\"1.0\"?>"
|
||||
"<unittest-results tests=\"1\" failedtests=\"1\" failures=\"1\" time=\"0.1\">"
|
||||
"<test suite=\"suite\" name=\"TestName\" time=\"0.1\">"
|
||||
"<failure message=\"filename.h(4321) : "'&<>\"/>"
|
||||
"</test>"
|
||||
"</unittest-results>";
|
||||
|
||||
CHECK_EQUAL(expected, output.str());
|
||||
}
|
||||
|
||||
TEST_FIXTURE(XmlTestReporterFixture, OneFailureAndOneSuccess)
|
||||
{
|
||||
TestDetails const failedDetails("FailedTest", "suite", "fail.h", 1);
|
||||
reporter.ReportTestStart(failedDetails);
|
||||
reporter.ReportFailure(failedDetails, "expected 1 but was 2");
|
||||
reporter.ReportTestFinish(failedDetails, 0.1f);
|
||||
|
||||
TestDetails const succeededDetails("SucceededTest", "suite", "", 0);
|
||||
reporter.ReportTestStart(succeededDetails);
|
||||
reporter.ReportTestFinish(succeededDetails, 1.0f);
|
||||
reporter.ReportSummary(2, 1, 1, 1.1f);
|
||||
|
||||
char const* expected =
|
||||
"<?xml version=\"1.0\"?>"
|
||||
"<unittest-results tests=\"2\" failedtests=\"1\" failures=\"1\" time=\"1.1\">"
|
||||
"<test suite=\"suite\" name=\"FailedTest\" time=\"0.1\">"
|
||||
"<failure message=\"fail.h(1) : expected 1 but was 2\"/>"
|
||||
"</test>"
|
||||
"<test suite=\"suite\" name=\"SucceededTest\" time=\"1\"/>"
|
||||
"</unittest-results>";
|
||||
|
||||
CHECK_EQUAL(expected, output.str());
|
||||
}
|
||||
|
||||
TEST_FIXTURE(XmlTestReporterFixture, MultipleFailures)
|
||||
{
|
||||
TestDetails const failedDetails1("FailedTest", "suite", "fail.h", 1);
|
||||
TestDetails const failedDetails2("FailedTest", "suite", "fail.h", 31);
|
||||
|
||||
reporter.ReportTestStart(failedDetails1);
|
||||
reporter.ReportFailure(failedDetails1, "expected 1 but was 2");
|
||||
reporter.ReportFailure(failedDetails2, "expected one but was two");
|
||||
reporter.ReportTestFinish(failedDetails1, 0.1f);
|
||||
|
||||
reporter.ReportSummary(1, 1, 2, 1.1f);
|
||||
|
||||
char const* expected =
|
||||
"<?xml version=\"1.0\"?>"
|
||||
"<unittest-results tests=\"1\" failedtests=\"1\" failures=\"2\" time=\"1.1\">"
|
||||
"<test suite=\"suite\" name=\"FailedTest\" time=\"0.1\">"
|
||||
"<failure message=\"fail.h(1) : expected 1 but was 2\"/>"
|
||||
"<failure message=\"fail.h(31) : expected one but was two\"/>"
|
||||
"</test>"
|
||||
"</unittest-results>";
|
||||
|
||||
CHECK_EQUAL(expected, output.str());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user