initial commit

This commit is contained in:
swaits committed 2011-01-24 14:16:14 -08:00
commit 279ceb25dd
73 files changed
+7181

No files matched your search

+32
View File
@@ -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;
}
}
+28
View File
@@ -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
+102
View File
@@ -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
+48
View File
@@ -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);
}
}
+146
View File
@@ -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
+25
View File
@@ -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
+28
View File
@@ -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;
}
+28
View File
@@ -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
+26
View File
@@ -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)
{
}
}
+29
View File
@@ -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
+143
View File
@@ -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
+67
View File
@@ -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
+46
View File
@@ -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;
}
}
+42
View File
@@ -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
+33
View File
@@ -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(&currentTime, 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);
}
}
+28
View File
@@ -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
+10
View File
@@ -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);
}
}
+10
View File
@@ -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
+62
View File
@@ -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
{
}
}
+34
View File
@@ -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
+22
View File
@@ -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_)
{
}
}
+24
View File
@@ -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
+39
View File
@@ -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);
}
}
+32
View File
@@ -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
+99
View File
@@ -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
+10
View File
@@ -0,0 +1,10 @@
#include "TestReporter.h"
namespace UnitTest {
TestReporter::~TestReporter()
{
}
}
+20
View File
@@ -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
+36
View File
@@ -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);
}
}
+19
View File
@@ -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
+60
View File
@@ -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;
}
}
+36
View File
@@ -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
+60
View File
@@ -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);
}
}
+17
View File
@@ -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
+14
View File
@@ -0,0 +1,14 @@
#ifndef UNITTEST_TESTSUITE_H
#define UNITTEST_TESTSUITE_H
namespace UnitTestSuite {
inline char const* GetSuiteName ()
{
return "DefaultSuite";
}
}
#endif
+28
View File
@@ -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());
}
}
}
+34
View File
@@ -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
+7
View File
@@ -0,0 +1,7 @@
#include "Config.h"
#if defined UNITTEST_POSIX
#include "Posix/TimeHelpers.h"
#else
#include "Win32/TimeHelpers.h"
#endif
+17
View File
@@ -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
+46
View File
@@ -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);
}
}
+48
View File
@@ -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
+126
View File
@@ -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, '&', "&amp;");
ReplaceChar(escaped, '<', "&lt;");
ReplaceChar(escaped, '>', "&gt;");
ReplaceChar(escaped, '\'', "&apos;");
ReplaceChar(escaped, '\"', "&quot;");
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 << "\"" << "/>";
}
}
}
+34
View File
@@ -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
+8
View File
@@ -0,0 +1,8 @@
#include "../UnitTest++.h"
#include "../TestReporterStdout.h"
int main(int, char const *[])
{
return UnitTest::RunAllTests();
}
+92
View File
@@ -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());
}
}
}
+710
View File
@@ -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);
}
}
+290
View File
@@ -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
}
+97
View File
@@ -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);
}
}
+50
View File
@@ -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);
}
}
+171
View File
@@ -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_;
}
}
+111
View File
@@ -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);
}
}
+233
View File
@@ -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);
}
}
+13
View File
@@ -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"));
}
}
+137
View File
@@ -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) : "
"&quot;&quot;&apos;&apos;&amp;&amp;&lt;&lt;&gt;&gt;\"/>"
"</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) : &quot;&apos;&amp;&lt;&gt;\"/>"
"</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());
}
}