Packaging
You'll probably want to keep the generated library in a shared space in source control, so you can reuse it for multiple test projects. A redistributable package of UnitTest++ would consist of the generated library file, and all of the header files in UnitTest++/src/
and its per-platform subfolders. The tests
directory only contains the unit tests for the library, and need not be included.
Using UnitTest++
-The source code for UnitTest++ comes with a full test suite written using UnitTest++. This is a great place to learn techniques for testing. There is one sample .cpp file: UnitTest++/src/tests/TestUnitTest++.cpp
. It covers most of UnitTest++'s features in an easy-to-grasp context, so start there if you want a quick overview of typical usage.
+The source code for UnitTest++ comes with a full test suite written using UnitTest++. This is a great place to learn techniques for testing. There is one sample .cpp file: UnitTest++/src/tests/TestUnitTestPP.cpp
. It covers most of UnitTest++'s features in an easy-to-grasp context, so start there if you want a quick overview of typical usage.
Getting started
Listed below is a minimal C++ program to run a failing test through UnitTest++.
// test.cpp
- #include <UnitTest++.h>
+ #include <unittestpp.h>
TEST(FailSpectacularly)
{
@@ -51,7 +51,7 @@ Getting started
}
-UnitTest++.h
is a facade header for UnitTest++, so including that should get you all features of the library. All classes and free functions are placed in namespace UnitTest
, so you need to either qualify their full names (as with RunAllTests()
in the example) or add a using namespace UnitTest;
statement in your .cpp files. Note that any mention of UnitTest++ functions and classes in this document assume that the UnitTest
namespace has been opened.
+unittestpp.h
is a facade header for UnitTest++, so including that should get you all features of the library. All classes and free functions are placed in namespace UnitTest
, so you need to either qualify their full names (as with RunAllTests()
in the example) or add a using namespace UnitTest;
statement in your .cpp files. Note that any mention of UnitTest++ functions and classes in this document assume that the UnitTest
namespace has been opened.
Compiling and linking this program with UnitTest++'s static library into an executable, and running it, will produce the following output (details may vary):
diff --git a/src/AssertException.cpp b/src/AssertException.cpp
index cd3c51c..634eb07 100644
--- a/src/AssertException.cpp
+++ b/src/AssertException.cpp
@@ -1,34 +1,17 @@
#include "AssertException.h"
-#include
+
+#ifndef UNITTEST_NO_EXCEPTIONS
namespace UnitTest {
-AssertException::AssertException(char const* description, char const* filename, int lineNumber)
- : m_lineNumber(lineNumber)
+AssertException::AssertException()
{
- using namespace std;
-
- strcpy(m_description, description);
- 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;
-}
-
-}
+#endif
diff --git a/src/AssertException.h b/src/AssertException.h
index 9c268fc..74291db 100644
--- a/src/AssertException.h
+++ b/src/AssertException.h
@@ -1,28 +1,23 @@
#ifndef UNITTEST_ASSERTEXCEPTION_H
#define UNITTEST_ASSERTEXCEPTION_H
-#include
+#include "../config.h"
+#ifndef UNITTEST_NO_EXCEPTIONS
+#include "HelperMacros.h"
+#include
namespace UnitTest {
-class AssertException : public std::exception
+class UNITTEST_LINKAGE AssertException : public std::exception
{
public:
- AssertException(char const* description, char const* filename, int lineNumber);
+ AssertException();
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
+
+#endif
diff --git a/src/CheckMacros.h b/src/CheckMacros.h
index 1eaa792..1e73699 100644
--- a/src/CheckMacros.h
+++ b/src/CheckMacros.h
@@ -1,11 +1,14 @@
#ifndef UNITTEST_CHECKMACROS_H
#define UNITTEST_CHECKMACROS_H
+#include "HelperMacros.h"
+#include "ExceptionMacros.h"
#include "Checks.h"
#include "AssertException.h"
#include "MemoryOutStream.h"
#include "TestDetails.h"
#include "CurrentTest.h"
+#include "ReportAssertImpl.h"
#ifdef CHECK
#error UnitTest++ redefines CHECK
@@ -32,91 +35,103 @@
#endif
#define CHECK(value) \
- do \
- { \
- try { \
- if (!UnitTest::Check(value)) \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), #value); \
- } \
- catch (...) { \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
- "Unhandled exception in CHECK(" #value ")"); \
- } \
- } while (0)
+ UNITTEST_MULTILINE_MACRO_BEGIN \
+ UT_TRY \
+ ({ \
+ if (!UnitTest::Check(value)) \
+ UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), #value); \
+ }) \
+ UT_CATCH_ALL \
+ ({ \
+ UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
+ "Unhandled exception in CHECK(" #value ")"); \
+ }) \
+ UNITTEST_MULTILINE_MACRO_END
#define CHECK_EQUAL(expected, actual) \
- do \
- { \
- try { \
+ UNITTEST_MULTILINE_MACRO_BEGIN \
+ UT_TRY \
+ ({ \
UnitTest::CheckEqual(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
- } \
- catch (...) { \
+ }) \
+ UT_CATCH_ALL \
+ ({ \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
"Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \
- } \
- } while (0)
+ }) \
+ UNITTEST_MULTILINE_MACRO_END
#define CHECK_CLOSE(expected, actual, tolerance) \
- do \
- { \
- try { \
+ UNITTEST_MULTILINE_MACRO_BEGIN \
+ UT_TRY \
+ ({ \
UnitTest::CheckClose(*UnitTest::CurrentTest::Results(), expected, actual, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
- } \
- catch (...) { \
+ }) \
+ UT_CATCH_ALL \
+ ({ \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
"Unhandled exception in CHECK_CLOSE(" #expected ", " #actual ")"); \
- } \
- } while (0)
+ }) \
+ UNITTEST_MULTILINE_MACRO_END
#define CHECK_ARRAY_EQUAL(expected, actual, count) \
- do \
- { \
- try { \
+ UNITTEST_MULTILINE_MACRO_BEGIN \
+ UT_TRY \
+ ({ \
UnitTest::CheckArrayEqual(*UnitTest::CurrentTest::Results(), expected, actual, count, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
- } \
- catch (...) { \
+ }) \
+ UT_CATCH_ALL \
+ ({ \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
"Unhandled exception in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"); \
- } \
- } while (0)
+ }) \
+ UNITTEST_MULTILINE_MACRO_END
#define CHECK_ARRAY_CLOSE(expected, actual, count, tolerance) \
- do \
- { \
- try { \
+ UNITTEST_MULTILINE_MACRO_BEGIN \
+ UT_TRY \
+ ({ \
UnitTest::CheckArrayClose(*UnitTest::CurrentTest::Results(), expected, actual, count, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
- } \
- catch (...) { \
+ }) \
+ UT_CATCH_ALL \
+ ({ \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
"Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
- } \
- } while (0)
+ }) \
+ UNITTEST_MULTILINE_MACRO_END
#define CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, tolerance) \
- do \
- { \
- try { \
+ UNITTEST_MULTILINE_MACRO_BEGIN \
+ UT_TRY \
+ ({ \
UnitTest::CheckArray2DClose(*UnitTest::CurrentTest::Results(), expected, actual, rows, columns, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
- } \
- catch (...) { \
+ }) \
+ UT_CATCH_ALL \
+ ({ \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
"Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
- } \
- } while (0)
+ }) \
+ UNITTEST_MULTILINE_MACRO_END
+// CHECK_THROW and CHECK_ASSERT only exist when UNITTEST_NO_EXCEPTIONS isn't defined (see config.h)
+#ifndef UNITTEST_NO_EXCEPTIONS
#define CHECK_THROW(expression, ExpectedExceptionType) \
- do \
- { \
+ UNITTEST_MULTILINE_MACRO_BEGIN \
bool caught_ = false; \
try { expression; } \
catch (ExpectedExceptionType const&) { caught_ = true; } \
- catch (...) {} \
+ catch (...) {} \
if (!caught_) \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), "Expected exception: \"" #ExpectedExceptionType "\" not thrown"); \
- } while(0)
+ UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), "Expected exception: \"" #ExpectedExceptionType "\" not thrown"); \
+ UNITTEST_MULTILINE_MACRO_END
-#define CHECK_ASSERT(expression) \
- CHECK_THROW(expression, UnitTest::AssertException);
+#define CHECK_ASSERT(expression) \
+ UNITTEST_MULTILINE_MACRO_BEGIN \
+ UnitTest::Detail::ExpectAssert(true); \
+ CHECK_THROW(expression, UnitTest::AssertException); \
+ UnitTest::Detail::ExpectAssert(false); \
+ UNITTEST_MULTILINE_MACRO_END
+#endif
#endif
diff --git a/src/Checks.h b/src/Checks.h
index e3ec7b2..c323244 100644
--- a/src/Checks.h
+++ b/src/Checks.h
@@ -1,7 +1,7 @@
#ifndef UNITTEST_CHECKS_H
#define UNITTEST_CHECKS_H
-#include "Config.h"
+#include "../config.h"
#include "TestResults.h"
#include "MemoryOutStream.h"
@@ -27,13 +27,13 @@ void CheckEqual(TestResults& results, Expected const& expected, Actual const& ac
}
}
-void CheckEqual(TestResults& results, char const* expected, char const* actual, TestDetails const& details);
+UNITTEST_LINKAGE void CheckEqual(TestResults& results, char const* expected, char const* actual, TestDetails const& details);
-void CheckEqual(TestResults& results, char* expected, char* actual, TestDetails const& details);
+UNITTEST_LINKAGE void CheckEqual(TestResults& results, char* expected, char* actual, TestDetails const& details);
-void CheckEqual(TestResults& results, char* expected, char const* actual, TestDetails const& details);
+UNITTEST_LINKAGE void CheckEqual(TestResults& results, char* expected, char const* actual, TestDetails const& details);
-void CheckEqual(TestResults& results, char const* expected, char* actual, TestDetails const& details);
+UNITTEST_LINKAGE 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)
diff --git a/src/CompositeTestReporter.cpp b/src/CompositeTestReporter.cpp
new file mode 100644
index 0000000..2a3d22e
--- /dev/null
+++ b/src/CompositeTestReporter.cpp
@@ -0,0 +1,67 @@
+#include "CompositeTestReporter.h"
+#include
+
+namespace UnitTest {
+
+CompositeTestReporter::CompositeTestReporter()
+ : m_reporterCount(0)
+{
+}
+
+int CompositeTestReporter::GetReporterCount() const
+{
+ return m_reporterCount;
+}
+
+bool CompositeTestReporter::AddReporter(TestReporter* reporter)
+{
+ if (m_reporterCount == kMaxReporters)
+ return false;
+
+ m_reporters[m_reporterCount++] = reporter;
+ return true;
+}
+
+bool CompositeTestReporter::RemoveReporter(TestReporter* reporter)
+{
+ for (int index = 0; index < m_reporterCount; ++index)
+ {
+ if (m_reporters[index] == reporter)
+ {
+ m_reporters[index] = m_reporters[m_reporterCount - 1];
+ --m_reporterCount;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void CompositeTestReporter::ReportFailure(TestDetails const& details, char const* failure)
+{
+ for (int index = 0; index < m_reporterCount; ++index)
+ m_reporters[index]->ReportFailure(details, failure);
+}
+
+void CompositeTestReporter::ReportTestStart(TestDetails const& test)
+{
+ for (int index = 0; index < m_reporterCount; ++index)
+ m_reporters[index]->ReportTestStart(test);
+}
+
+void CompositeTestReporter::ReportTestFinish(TestDetails const& test, float secondsElapsed)
+{
+ for (int index = 0; index < m_reporterCount; ++index)
+ m_reporters[index]->ReportTestFinish(test, secondsElapsed);
+}
+
+void CompositeTestReporter::ReportSummary(int totalTestCount,
+ int failedTestCount,
+ int failureCount,
+ float secondsElapsed)
+{
+ for (int index = 0; index < m_reporterCount; ++index)
+ m_reporters[index]->ReportSummary(totalTestCount, failedTestCount, failureCount, secondsElapsed);
+}
+
+}
diff --git a/src/CompositeTestReporter.h b/src/CompositeTestReporter.h
new file mode 100644
index 0000000..a4806f4
--- /dev/null
+++ b/src/CompositeTestReporter.h
@@ -0,0 +1,34 @@
+#ifndef UNITTEST_COMPOSITETESTREPORTER_H
+#define UNITTEST_COMPOSITETESTREPORTER_H
+
+#include "TestReporter.h"
+
+namespace UnitTest {
+
+class UNITTEST_LINKAGE CompositeTestReporter : public TestReporter
+{
+public:
+ CompositeTestReporter();
+
+ int GetReporterCount() const;
+ bool AddReporter(TestReporter* reporter);
+ bool RemoveReporter(TestReporter* reporter);
+
+ 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);
+
+private:
+ enum { kMaxReporters = 16 };
+ TestReporter* m_reporters[kMaxReporters];
+ int m_reporterCount;
+
+ // revoked
+ CompositeTestReporter(const CompositeTestReporter&);
+ CompositeTestReporter& operator =(const CompositeTestReporter&);
+};
+
+}
+
+#endif
diff --git a/src/Config.h b/src/Config.h
deleted file mode 100644
index cb43d91..0000000
--- a/src/Config.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#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
-
- #if (_MSC_VER == 1200) // VC6
- #pragma warning(disable:4786)
- #pragma warning(disable:4290)
- #endif
-#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, which can be expensive.
-// uncomment this line to use the custom MemoryOutStream (no deps on std::ostringstream).
-
-//#define UNITTEST_USE_CUSTOM_STREAMS
-
-#endif
diff --git a/src/CurrentTest.cpp b/src/CurrentTest.cpp
index 941fb9b..19eb9bf 100644
--- a/src/CurrentTest.cpp
+++ b/src/CurrentTest.cpp
@@ -3,13 +3,13 @@
namespace UnitTest {
-TestResults*& CurrentTest::Results()
+UNITTEST_LINKAGE TestResults*& CurrentTest::Results()
{
static TestResults* testResults = NULL;
return testResults;
}
-const TestDetails*& CurrentTest::Details()
+UNITTEST_LINKAGE const TestDetails*& CurrentTest::Details()
{
static const TestDetails* testDetails = NULL;
return testDetails;
diff --git a/src/CurrentTest.h b/src/CurrentTest.h
index 3b77ca5..0d62fdc 100644
--- a/src/CurrentTest.h
+++ b/src/CurrentTest.h
@@ -1,6 +1,8 @@
#ifndef UNITTEST_CURRENTTESTRESULTS_H
#define UNITTEST_CURRENTTESTRESULTS_H
+#include "HelperMacros.h"
+
namespace UnitTest {
class TestResults;
@@ -8,8 +10,8 @@ class TestDetails;
namespace CurrentTest
{
- TestResults*& Results();
- const TestDetails*& Details();
+ UNITTEST_LINKAGE TestResults*& Results();
+ UNITTEST_LINKAGE const TestDetails*& Details();
}
}
diff --git a/src/DeferredTestReporter.cpp b/src/DeferredTestReporter.cpp
index ae77b03..83dee1a 100644
--- a/src/DeferredTestReporter.cpp
+++ b/src/DeferredTestReporter.cpp
@@ -1,28 +1,33 @@
-#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 secondsElapsed)
-{
- DeferredTestResult& r = m_results.back();
- r.timeElapsed = secondsElapsed;
-}
-
-DeferredTestReporter::DeferredTestResultList& DeferredTestReporter::GetResults()
-{
- return m_results;
-}
+#include "../config.h"
+#ifndef UNITTEST_NO_DEFERRED_REPORTER
+
+#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(DeferredTestFailure(details.lineNumber, failure));
+ r.failureFile = details.filename;
+}
+
+void DeferredTestReporter::ReportTestFinish(TestDetails const&, float secondsElapsed)
+{
+ DeferredTestResult& r = m_results.back();
+ r.timeElapsed = secondsElapsed;
+}
+
+DeferredTestReporter::DeferredTestResultList& DeferredTestReporter::GetResults()
+{
+ return m_results;
+}
+
+#endif
diff --git a/src/DeferredTestReporter.h b/src/DeferredTestReporter.h
index 615a24e..d4947f4 100644
--- a/src/DeferredTestReporter.h
+++ b/src/DeferredTestReporter.h
@@ -1,29 +1,35 @@
-#ifndef UNITTEST_DEFERREDTESTREPORTER_H
-#define UNITTEST_DEFERREDTESTREPORTER_H
-
-#include "TestReporter.h"
-#include "DeferredTestResult.h"
-#include "Config.h"
-
-#include
-
-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
+#ifndef UNITTEST_DEFERREDTESTREPORTER_H
+#define UNITTEST_DEFERREDTESTREPORTER_H
+
+#include "../config.h"
+
+#ifndef UNITTEST_NO_DEFERRED_REPORTER
+
+#include "TestReporter.h"
+#include "DeferredTestResult.h"
+
+#include
+
+UNITTEST_STDVECTOR_LINKAGE(UnitTest::DeferredTestResult);
+
+namespace UnitTest
+{
+
+class UNITTEST_LINKAGE 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
+#endif
diff --git a/src/DeferredTestResult.cpp b/src/DeferredTestResult.cpp
index c2daa25..cbf0a8a 100644
--- a/src/DeferredTestResult.cpp
+++ b/src/DeferredTestResult.cpp
@@ -1,25 +1,46 @@
-#include "DeferredTestResult.h"
-#include "Config.h"
-
-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)
-{
-}
-
-}
+#include "../config.h"
+#ifndef UNITTEST_NO_DEFERRED_REPORTER
+
+#include "DeferredTestResult.h"
+#include
+
+namespace UnitTest
+{
+
+DeferredTestFailure::DeferredTestFailure()
+ : lineNumber(-1)
+{
+ failureStr[0] = '\0';
+}
+
+DeferredTestFailure::DeferredTestFailure(int lineNumber_, const char* failureStr_)
+ : lineNumber(lineNumber_)
+{
+ std::strcpy(failureStr, failureStr_);
+}
+
+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)
+{
+}
+
+DeferredTestResult::~DeferredTestResult()
+{
+}
+
+}
+
+#endif
diff --git a/src/DeferredTestResult.h b/src/DeferredTestResult.h
index d0a1dab..e580d0c 100644
--- a/src/DeferredTestResult.h
+++ b/src/DeferredTestResult.h
@@ -1,32 +1,52 @@
-#ifndef UNITTEST_DEFERREDTESTRESULT_H
-#define UNITTEST_DEFERREDTESTRESULT_H
-
-#include "Config.h"
-
-#include
-#include
-
-namespace UnitTest
-{
-
-struct DeferredTestResult
-{
- DeferredTestResult();
- DeferredTestResult(char const* suite, char const* test);
- ~DeferredTestResult();
-
- 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
+#ifndef UNITTEST_DEFERREDTESTRESULT_H
+#define UNITTEST_DEFERREDTESTRESULT_H
+
+#include "../config.h"
+#ifndef UNITTEST_NO_DEFERRED_REPORTER
+
+#include "HelperMacros.h"
+#include
+#include
+
+namespace UnitTest
+{
+
+class UNITTEST_LINKAGE DeferredTestFailure
+{
+public:
+ DeferredTestFailure();
+ DeferredTestFailure(int lineNumber_, const char* failureStr_);
+
+ int lineNumber;
+ char failureStr[1024];
+};
+
+}
+
+UNITTEST_STDVECTOR_LINKAGE(UnitTest::DeferredTestFailure);
+
+namespace UnitTest
+{
+
+class UNITTEST_LINKAGE DeferredTestResult
+{
+public:
+ DeferredTestResult();
+ DeferredTestResult(char const* suite, char const* test);
+ ~DeferredTestResult();
+
+ std::string suiteName;
+ std::string testName;
+ std::string failureFile;
+
+ typedef std::vector< DeferredTestFailure > FailureVec;
+ FailureVec failures;
+
+ float timeElapsed;
+ bool failed;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/ExceptionMacros.h b/src/ExceptionMacros.h
new file mode 100644
index 0000000..4ddf5ec
--- /dev/null
+++ b/src/ExceptionMacros.h
@@ -0,0 +1,18 @@
+#ifndef UNITTEST_EXCEPTIONMACROS_H
+#define UNITTEST_EXCEPTIONMACROS_H
+
+#include "../config.h"
+
+#ifndef UNITTEST_NO_EXCEPTIONS
+ #define UT_TRY(x) try x
+ #define UT_THROW(x) throw x
+ #define UT_CATCH(ExceptionType, ExceptionName, CatchBody) catch(ExceptionType& ExceptionName) CatchBody
+ #define UT_CATCH_ALL(CatchBody) catch(...) CatchBody
+#else
+ #define UT_TRY(x) x
+ #define UT_THROW(x)
+ #define UT_CATCH(ExceptionType, ExceptionName, CatchBody)
+ #define UT_CATCH_ALL(CatchBody)
+#endif
+
+#endif
diff --git a/src/ExecuteTest.h b/src/ExecuteTest.h
index 3ccd426..2f47013 100644
--- a/src/ExecuteTest.h
+++ b/src/ExecuteTest.h
@@ -1,11 +1,18 @@
#ifndef UNITTEST_EXECUTE_TEST_H
#define UNITTEST_EXECUTE_TEST_H
+#include "../config.h"
+#include "ExceptionMacros.h"
#include "TestDetails.h"
+#include "TestResults.h"
#include "MemoryOutStream.h"
#include "AssertException.h"
#include "CurrentTest.h"
+#ifdef UNITTEST_NO_EXCEPTIONS
+ #include "ReportAssertImpl.h"
+#endif
+
#ifdef UNITTEST_POSIX
#include "Posix/SignalTranslator.h"
#endif
@@ -13,32 +20,38 @@
namespace UnitTest {
template< typename T >
-void ExecuteTest(T& testObject, TestDetails const& details)
+void ExecuteTest(T& testObject, TestDetails const& details, bool isMockTest)
{
- CurrentTest::Details() = &details;
+ if (isMockTest == false)
+ CurrentTest::Details() = &details;
- try
+#ifdef UNITTEST_NO_EXCEPTIONS
+ if (UNITTEST_SET_ASSERT_JUMP_TARGET() == 0)
{
-#ifdef UNITTEST_POSIX
- UNITTEST_THROW_SIGNALS
#endif
- testObject.RunImpl();
- }
- catch (AssertException const& e)
- {
- CurrentTest::Results()->OnTestFailure(
- TestDetails(details.testName, details.suiteName, e.Filename(), e.LineNumber()), e.what());
- }
- catch (std::exception const& e)
- {
- MemoryOutStream stream;
- stream << "Unhandled exception: " << e.what();
- CurrentTest::Results()->OnTestFailure(details, stream.GetText());
- }
- catch (...)
- {
- CurrentTest::Results()->OnTestFailure(details, "Unhandled exception: Crash!");
+#ifndef UNITTEST_POSIX
+ UT_TRY({ testObject.RunImpl(); })
+#else
+ UT_TRY
+ ({
+ UNITTEST_THROW_SIGNALS_POSIX_ONLY
+ testObject.RunImpl();
+ })
+#endif
+ UT_CATCH(AssertException, e, { (void)e; })
+ UT_CATCH(std::exception, e,
+ {
+ MemoryOutStream stream;
+ stream << "Unhandled exception: " << e.what();
+ CurrentTest::Results()->OnTestFailure(details, stream.GetText());
+ })
+ UT_CATCH_ALL
+ ({
+ CurrentTest::Results()->OnTestFailure(details, "Unhandled exception: test crashed");
+ })
+#ifdef UNITTEST_NO_EXCEPTIONS
}
+#endif
}
}
diff --git a/src/HelperMacros.h b/src/HelperMacros.h
new file mode 100644
index 0000000..68792da
--- /dev/null
+++ b/src/HelperMacros.h
@@ -0,0 +1,52 @@
+#ifndef UNITTEST_HELPERMACROS_H
+#define UNITTEST_HELPERMACROS_H
+
+#include "../config.h"
+
+#define UNITTEST_MULTILINE_MACRO_BEGIN do {
+
+#ifdef UNITTEST_WIN32
+ #define UNITTEST_MULTILINE_MACRO_END \
+ } __pragma(warning(push)) __pragma(warning(disable:4127)) while (0) __pragma(warning(pop))
+#else
+ #define UNITTEST_MULTILINE_MACRO_END } while(0)
+#endif
+
+
+#ifdef UNITTEST_WIN32_DLL
+ #define UNITTEST_IMPORT __declspec(dllimport)
+ #define UNITTEST_EXPORT __declspec(dllexport)
+
+ #ifdef UNITTEST_DLL_EXPORT
+ #define UNITTEST_LINKAGE UNITTEST_EXPORT
+ #define UNITTEST_IMPEXP_TEMPLATE
+ #else
+ #define UNITTEST_LINKAGE UNITTEST_IMPORT
+ #define UNITTEST_IMPEXP_TEMPLATE extern
+ #endif
+
+ #define UNITTEST_STDVECTOR_LINKAGE(T) \
+ __pragma(warning(push)) \
+ __pragma(warning(disable:4231)) \
+ UNITTEST_IMPEXP_TEMPLATE template class UNITTEST_LINKAGE std::allocator< T >; \
+ UNITTEST_IMPEXP_TEMPLATE template class UNITTEST_LINKAGE std::vector< T >; \
+ __pragma(warning(pop))
+#else
+ #define UNITTEST_IMPORT
+ #define UNITTEST_EXPORT
+ #define UNITTEST_LINKAGE
+ #define UNITTEST_IMPEXP_TEMPLATE
+ #define UNITTEST_STDVECTOR_LINKAGE(T)
+#endif
+
+#ifdef UNITTEST_WIN32
+ #define UNITTEST_JMPBUF jmp_buf
+ #define UNITTEST_SETJMP setjmp
+ #define UNITTEST_LONGJMP longjmp
+#elif defined UNITTEST_POSIX
+ #define UNITTEST_JMPBUF std::jmp_buf
+ #define UNITTEST_SETJMP setjmp
+ #define UNITTEST_LONGJMP std::longjmp
+#endif
+
+#endif
diff --git a/src/MemoryOutStream.cpp b/src/MemoryOutStream.cpp
index c82740d..1e1e97d 100644
--- a/src/MemoryOutStream.cpp
+++ b/src/MemoryOutStream.cpp
@@ -1,23 +1,25 @@
#include "MemoryOutStream.h"
-#ifndef UNITTEST_USE_CUSTOM_STREAMS
-
+#ifdef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM
namespace UnitTest {
char const* MemoryOutStream::GetText() const
{
- m_text = this->str();
- return m_text.c_str();
+ m_text = this->str();
+ return m_text.c_str();
}
-
+void MemoryOutStream::Clear()
+{
+ this->str(std::string());
+ m_text = this->str();
}
+}
#else
-
#include
#include
@@ -56,12 +58,17 @@ MemoryOutStream::~MemoryOutStream()
delete [] m_buffer;
}
+void MemoryOutStream::Clear()
+{
+ m_buffer[0] = '\0';
+}
+
char const* MemoryOutStream::GetText() const
{
return m_buffer;
}
-MemoryOutStream& MemoryOutStream::operator << (char const* txt)
+MemoryOutStream& MemoryOutStream::operator <<(char const* txt)
{
using namespace std;
@@ -78,37 +85,59 @@ MemoryOutStream& MemoryOutStream::operator << (char const* txt)
return *this;
}
-MemoryOutStream& MemoryOutStream::operator << (int const n)
+MemoryOutStream& MemoryOutStream::operator <<(int const n)
{
FormatToStream(*this, "%i", n);
return *this;
}
-MemoryOutStream& MemoryOutStream::operator << (long const n)
+MemoryOutStream& MemoryOutStream::operator <<(long const n)
{
FormatToStream(*this, "%li", n);
return *this;
}
-MemoryOutStream& MemoryOutStream::operator << (unsigned long const n)
+MemoryOutStream& MemoryOutStream::operator <<(unsigned long const n)
{
FormatToStream(*this, "%lu", n);
return *this;
}
-MemoryOutStream& MemoryOutStream::operator << (float const f)
+MemoryOutStream& MemoryOutStream::operator <<(long long const n)
+{
+#ifdef UNITTEST_WIN32
+ FormatToStream(*this, "%I64d", n);
+#else
+ FormatToStream(*this, "%lld", n);
+#endif
+
+ return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator <<(unsigned long long const n)
+{
+#ifdef UNITTEST_WIN32
+ FormatToStream(*this, "%I64u", n);
+#else
+ FormatToStream(*this, "%llu", n);
+#endif
+
+ return *this;
+}
+
+MemoryOutStream& MemoryOutStream::operator <<(float const f)
{
FormatToStream(*this, "%ff", f);
return *this;
}
-MemoryOutStream& MemoryOutStream::operator << (void const* p)
+MemoryOutStream& MemoryOutStream::operator <<(void const* p)
{
FormatToStream(*this, "%p", p);
return *this;
}
-MemoryOutStream& MemoryOutStream::operator << (unsigned int const s)
+MemoryOutStream& MemoryOutStream::operator <<(unsigned int const s)
{
FormatToStream(*this, "%u", s);
return *this;
diff --git a/src/MemoryOutStream.h b/src/MemoryOutStream.h
index 37a4afd..380826a 100644
--- a/src/MemoryOutStream.h
+++ b/src/MemoryOutStream.h
@@ -1,68 +1,73 @@
-#ifndef UNITTEST_MEMORYOUTSTREAM_H
-#define UNITTEST_MEMORYOUTSTREAM_H
-
-#include "Config.h"
-
-#ifndef UNITTEST_USE_CUSTOM_STREAMS
-
-#include
-
-namespace UnitTest
-{
-
-class MemoryOutStream : public std::ostringstream
-{
-public:
- MemoryOutStream() {}
- ~MemoryOutStream() {}
- char const* GetText() const;
-
-private:
- MemoryOutStream(MemoryOutStream const&);
- void operator =(MemoryOutStream const&);
-
- mutable std::string m_text;
-};
-
-}
-
-#else
-
-#include
-
-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
+#ifndef UNITTEST_MEMORYOUTSTREAM_H
+#define UNITTEST_MEMORYOUTSTREAM_H
+
+#include "../config.h"
+#include "HelperMacros.h"
+
+#ifdef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM
+
+#include
+
+namespace UnitTest
+{
+
+class UNITTEST_LINKAGE MemoryOutStream : public std::ostringstream
+{
+public:
+ MemoryOutStream() {}
+ ~MemoryOutStream() {}
+ void Clear();
+ char const* GetText() const;
+
+private:
+ MemoryOutStream(MemoryOutStream const&);
+ void operator =(MemoryOutStream const&);
+
+ mutable std::string m_text;
+};
+
+}
+
+#else
+
+#include
+
+namespace UnitTest
+{
+
+class UNITTEST_LINKAGE MemoryOutStream
+{
+public:
+ explicit MemoryOutStream(int const size = 256);
+ ~MemoryOutStream();
+
+ void Clear();
+ char const* GetText() const;
+
+ MemoryOutStream& operator <<(char const* txt);
+ MemoryOutStream& operator <<(int n);
+ MemoryOutStream& operator <<(long n);
+ MemoryOutStream& operator <<(long long n);
+ MemoryOutStream& operator <<(unsigned long n);
+ MemoryOutStream& operator <<(unsigned long 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
diff --git a/src/Posix/SignalTranslator.h b/src/Posix/SignalTranslator.h
index f3c3563..2152b9c 100644
--- a/src/Posix/SignalTranslator.h
+++ b/src/Posix/SignalTranslator.h
@@ -32,7 +32,7 @@ class SignalTranslator
#define UNITTEST_EXTENSION __extension__
#endif
-#define UNITTEST_THROW_SIGNALS \
+#define UNITTEST_THROW_SIGNALS_POSIX_ONLY \
UnitTest::SignalTranslator sig; \
if (UNITTEST_EXTENSION sigsetjmp(*UnitTest::SignalTranslator::s_jumpTarget, 1) != 0) \
throw ("Unhandled system exception");
diff --git a/src/Posix/TimeHelpers.cpp b/src/Posix/TimeHelpers.cpp
index 65c6393..35e8136 100644
--- a/src/Posix/TimeHelpers.cpp
+++ b/src/Posix/TimeHelpers.cpp
@@ -1,33 +1,33 @@
-#include "TimeHelpers.h"
-#include
-
-namespace UnitTest {
-
-Timer::Timer()
-{
- m_startTime.tv_sec = 0;
- m_startTime.tv_usec = 0;
-}
-
-void Timer::Start()
-{
- gettimeofday(&m_startTime, 0);
-}
-
-double Timer::GetTimeInMs() const
-{
- struct timeval currentTime;
- gettimeofday(¤tTime, 0);
-
- double const dsecs = currentTime.tv_sec - m_startTime.tv_sec;
- double const dus = currentTime.tv_usec - m_startTime.tv_usec;
-
- return (dsecs * 1000.0) + (dus / 1000.0);
-}
-
-void TimeHelpers::SleepMs(int ms)
-{
- usleep(ms * 1000);
-}
-
-}
+#include "TimeHelpers.h"
+#include
+
+namespace UnitTest {
+
+Timer::Timer()
+{
+ m_startTime.tv_sec = 0;
+ m_startTime.tv_usec = 0;
+}
+
+void Timer::Start()
+{
+ gettimeofday(&m_startTime, 0);
+}
+
+double Timer::GetTimeInMs() const
+{
+ struct timeval currentTime;
+ gettimeofday(¤tTime, 0);
+
+ double const dsecs = currentTime.tv_sec - m_startTime.tv_sec;
+ double const dus = currentTime.tv_usec - m_startTime.tv_usec;
+
+ return (dsecs * 1000.0) + (dus / 1000.0);
+}
+
+void TimeHelpers::SleepMs(int ms)
+{
+ usleep(ms * 1000);
+}
+
+}
diff --git a/src/Posix/TimeHelpers.h b/src/Posix/TimeHelpers.h
index 528e62e..5a5bd79 100644
--- a/src/Posix/TimeHelpers.h
+++ b/src/Posix/TimeHelpers.h
@@ -1,28 +1,28 @@
-#ifndef UNITTEST_TIMEHELPERS_H
-#define UNITTEST_TIMEHELPERS_H
-
-#include
-
-namespace UnitTest {
-
-class Timer
-{
-public:
- Timer();
- void Start();
- double GetTimeInMs() const;
-
-private:
- struct timeval m_startTime;
-};
-
-
-namespace TimeHelpers
-{
-void SleepMs (int ms);
-}
-
-
-}
-
-#endif
+#ifndef UNITTEST_TIMEHELPERS_H
+#define UNITTEST_TIMEHELPERS_H
+
+#include
+
+namespace UnitTest {
+
+class Timer
+{
+public:
+ Timer();
+ void Start();
+ double GetTimeInMs() const;
+
+private:
+ struct timeval m_startTime;
+};
+
+
+namespace TimeHelpers
+{
+ void SleepMs(int ms);
+}
+
+
+}
+
+#endif
diff --git a/src/ReportAssert.cpp b/src/ReportAssert.cpp
index c91f4f6..c38a518 100644
--- a/src/ReportAssert.cpp
+++ b/src/ReportAssert.cpp
@@ -1,11 +1,70 @@
-#include "ReportAssert.h"
-#include "AssertException.h"
-
-namespace UnitTest {
-
-void ReportAssert(char const* description, char const* filename, int lineNumber)
-{
- throw AssertException(description, filename, lineNumber);
-}
-
-}
+#include "ReportAssert.h"
+#include "ReportAssertImpl.h"
+#include "AssertException.h"
+#include "CurrentTest.h"
+#include "TestResults.h"
+#include "TestDetails.h"
+
+#ifdef UNITTEST_NO_EXCEPTIONS
+ #include "ReportAssertImpl.h"
+#endif
+
+namespace UnitTest {
+
+namespace
+{
+ bool& AssertExpectedFlag()
+ {
+ static bool s_assertExpected = false;
+ return s_assertExpected;
+ }
+}
+
+UNITTEST_LINKAGE void ReportAssert(char const* description, char const* filename, int lineNumber)
+{
+ Detail::ReportAssertEx(CurrentTest::Results(), CurrentTest::Details(),
+ description, filename, lineNumber);
+}
+
+namespace Detail {
+
+#ifdef UNITTEST_NO_EXCEPTIONS
+UNITTEST_JMPBUF* GetAssertJmpBuf()
+{
+ static UNITTEST_JMPBUF s_jmpBuf;
+ return &s_jmpBuf;
+}
+#endif
+
+UNITTEST_LINKAGE void ReportAssertEx(TestResults* testResults,
+ const TestDetails* testDetails,
+ char const* description,
+ char const* filename,
+ int lineNumber)
+{
+ if (AssertExpectedFlag() == false)
+ {
+ TestDetails assertDetails(testDetails->testName, testDetails->suiteName, filename, lineNumber);
+ testResults->OnTestFailure(assertDetails, description);
+ }
+
+ ExpectAssert(false);
+
+#ifndef UNITTEST_NO_EXCEPTIONS
+ throw AssertException();
+#else
+ UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET();
+#endif
+}
+
+UNITTEST_LINKAGE void ExpectAssert(bool expected)
+{
+ AssertExpectedFlag() = expected;
+}
+
+UNITTEST_LINKAGE bool AssertExpected()
+{
+ return AssertExpectedFlag();
+}
+
+}}
diff --git a/src/ReportAssert.h b/src/ReportAssert.h
index a000e15..7bdf7bb 100644
--- a/src/ReportAssert.h
+++ b/src/ReportAssert.h
@@ -1,10 +1,12 @@
#ifndef UNITTEST_ASSERT_H
#define UNITTEST_ASSERT_H
+#include "HelperMacros.h"
+
namespace UnitTest {
-void ReportAssert(char const* description, char const* filename, int lineNumber);
-
+UNITTEST_LINKAGE void ReportAssert(char const* description, char const* filename, int lineNumber);
+
}
#endif
diff --git a/src/ReportAssertImpl.h b/src/ReportAssertImpl.h
new file mode 100644
index 0000000..aefc78d
--- /dev/null
+++ b/src/ReportAssertImpl.h
@@ -0,0 +1,46 @@
+#ifndef UNITTEST_REPORTASSERTIMPL_H
+#define UNITTEST_REPORTASSERTIMPL_H
+
+#include "../config.h"
+#include "HelperMacros.h"
+
+#ifdef UNITTEST_NO_EXCEPTIONS
+ #include
+#endif
+
+namespace UnitTest {
+
+class TestResults;
+class TestDetails;
+
+namespace Detail {
+
+UNITTEST_LINKAGE void ExpectAssert(bool expected);
+
+UNITTEST_LINKAGE void ReportAssertEx(TestResults* testResults,
+ const TestDetails* testDetails,
+ char const* description,
+ char const* filename,
+ int lineNumber);
+
+UNITTEST_LINKAGE bool AssertExpected();
+
+#ifdef UNITTEST_NO_EXCEPTIONS
+ UNITTEST_LINKAGE UNITTEST_JMPBUF* GetAssertJmpBuf();
+
+ #ifdef UNITTEST_WIN32
+ #define UNITTEST_SET_ASSERT_JUMP_TARGET() \
+ __pragma(warning(push)) __pragma(warning(disable:4611)) \
+ UNITTEST_SETJMP(*UnitTest::Detail::GetAssertJmpBuf()) \
+ __pragma(warning(pop))
+ #else
+ #define UNITTEST_SET_ASSERT_JUMP_TARGET() UNITTEST_SETJMP(*UnitTest::Detail::GetAssertJmpBuf())
+ #endif
+
+ #define UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET() UNITTEST_LONGJMP(*UnitTest::Detail::GetAssertJmpBuf(), 1)
+#endif
+
+}
+}
+
+#endif
diff --git a/src/Test.cpp b/src/Test.cpp
index 6b63041..eaab9aa 100644
--- a/src/Test.cpp
+++ b/src/Test.cpp
@@ -1,4 +1,4 @@
-#include "Config.h"
+#include "../config.h"
#include "Test.h"
#include "TestList.h"
#include "TestResults.h"
@@ -20,8 +20,9 @@ TestList& Test::GetTestList()
Test::Test(char const* testName, char const* suiteName, char const* filename, int lineNumber)
: m_details(testName, suiteName, filename, lineNumber)
- , next(0)
+ , m_nextTest(0)
, m_timeConstraintExempt(false)
+ , m_isMockTest(false)
{
}
@@ -31,7 +32,7 @@ Test::~Test()
void Test::Run()
{
- ExecuteTest(*this, m_details);
+ ExecuteTest(*this, m_details, m_isMockTest);
}
void Test::RunImpl() const
diff --git a/src/Test.h b/src/Test.h
index 436dbc1..1e1dbb2 100644
--- a/src/Test.h
+++ b/src/Test.h
@@ -8,7 +8,7 @@ namespace UnitTest {
class TestResults;
class TestList;
-class Test
+class UNITTEST_LINKAGE Test
{
public:
explicit Test(char const* testName, char const* suiteName = "DefaultSuite", char const* filename = "", int lineNumber = 0);
@@ -16,8 +16,9 @@ class Test
void Run();
TestDetails const m_details;
- Test* next;
+ Test* m_nextTest;
mutable bool m_timeConstraintExempt;
+ mutable bool m_isMockTest;
static TestList& GetTestList();
diff --git a/src/TestDetails.h b/src/TestDetails.h
index c3f5e46..898f7f3 100644
--- a/src/TestDetails.h
+++ b/src/TestDetails.h
@@ -1,9 +1,11 @@
#ifndef UNITTEST_TESTDETAILS_H
#define UNITTEST_TESTDETAILS_H
+#include "HelperMacros.h"
+
namespace UnitTest {
-class TestDetails
+class UNITTEST_LINKAGE TestDetails
{
public:
TestDetails(char const* testName, char const* suiteName, char const* filename, int lineNumber);
diff --git a/src/TestList.cpp b/src/TestList.cpp
index 4f58034..38fbfec 100644
--- a/src/TestList.cpp
+++ b/src/TestList.cpp
@@ -21,7 +21,7 @@ void TestList::Add(Test* test)
}
else
{
- m_tail->next = test;
+ m_tail->m_nextTest = test;
m_tail = test;
}
}
diff --git a/src/TestList.h b/src/TestList.h
index ff560bc..ed190c2 100644
--- a/src/TestList.h
+++ b/src/TestList.h
@@ -1,12 +1,13 @@
#ifndef UNITTEST_TESTLIST_H
#define UNITTEST_TESTLIST_H
+#include "HelperMacros.h"
namespace UnitTest {
class Test;
-class TestList
+class UNITTEST_LINKAGE TestList
{
public:
TestList();
@@ -20,7 +21,7 @@ class TestList
};
-class ListAdder
+class UNITTEST_LINKAGE ListAdder
{
public:
ListAdder(TestList& list, Test* test);
diff --git a/src/TestMacros.h b/src/TestMacros.h
index 8d29f04..931d8e7 100644
--- a/src/TestMacros.h
+++ b/src/TestMacros.h
@@ -1,14 +1,16 @@
#ifndef UNITTEST_TESTMACROS_H
#define UNITTEST_TESTMACROS_H
-#include "Config.h"
+#include "../config.h"
+#include "TestSuite.h"
+#include "ExceptionMacros.h"
#include "ExecuteTest.h"
#include "AssertException.h"
#include "TestDetails.h"
#include "MemoryOutStream.h"
#ifndef UNITTEST_POSIX
- #define UNITTEST_THROW_SIGNALS
+ #define UNITTEST_THROW_SIGNALS_POSIX_ONLY
#else
#include "Posix/SignalTranslator.h"
#endif
@@ -76,23 +78,25 @@
\
void Test##Fixture##Name::RunImpl() const \
{ \
- bool ctorOk = false; \
- try { \
+ volatile bool ctorOk = false; \
+ UT_TRY \
+ ({ \
Fixture##Name##Helper fixtureHelper(m_details); \
ctorOk = true; \
- UnitTest::ExecuteTest(fixtureHelper, m_details); \
- } \
- catch (UnitTest::AssertException const& e) \
- { \
- UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details.testName, m_details.suiteName, e.Filename(), e.LineNumber()), e.what()); \
- } \
- catch (std::exception const& e) \
- { \
+ UnitTest::ExecuteTest(fixtureHelper, m_details, false); \
+ }) \
+ UT_CATCH (UnitTest::AssertException, e, \
+ { \
+ (void)e; \
+ }) \
+ UT_CATCH (std::exception, e, \
+ { \
UnitTest::MemoryOutStream stream; \
stream << "Unhandled exception: " << e.what(); \
UnitTest::CurrentTest::Results()->OnTestFailure(m_details, stream.GetText()); \
- } \
- catch (...) { \
+ }) \
+ UT_CATCH_ALL \
+ ({ \
if (ctorOk) \
{ \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
@@ -103,7 +107,7 @@
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \
"Unhandled exception while constructing fixture " #Fixture); \
} \
- } \
+ }) \
} \
void Fixture##Name##Helper::RunImpl()
diff --git a/src/TestReporter.cpp b/src/TestReporter.cpp
index c783af1..78c765f 100644
--- a/src/TestReporter.cpp
+++ b/src/TestReporter.cpp
@@ -2,7 +2,6 @@
namespace UnitTest {
-
TestReporter::~TestReporter()
{
}
diff --git a/src/TestReporter.h b/src/TestReporter.h
index e0aa76f..99bfaa6 100644
--- a/src/TestReporter.h
+++ b/src/TestReporter.h
@@ -1,11 +1,13 @@
#ifndef UNITTEST_TESTREPORTER_H
#define UNITTEST_TESTREPORTER_H
+#include "HelperMacros.h"
+
namespace UnitTest {
class TestDetails;
-class TestReporter
+class UNITTEST_LINKAGE TestReporter
{
public:
virtual ~TestReporter();
diff --git a/src/TestReporterStdout.cpp b/src/TestReporterStdout.cpp
index 563113c..cd2c131 100644
--- a/src/TestReporterStdout.cpp
+++ b/src/TestReporterStdout.cpp
@@ -1,46 +1,46 @@
-#include "TestReporterStdout.h"
-#include
-
-#include "TestDetails.h"
-
-// cstdio doesn't pull in namespace std on VC6, so we do it here.
-#if defined(_MSC_VER) && (_MSC_VER == 1200)
- namespace std {}
-#endif
-
-namespace UnitTest {
-
-void TestReporterStdout::ReportFailure(TestDetails const& details, char const* failure)
-{
-#if defined(__APPLE__) || defined(__GNUG__)
- 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
-
- using namespace 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)
-{
- using namespace std;
-
- if (failureCount > 0)
- printf("FAILURE: %d out of %d tests failed (%d failures).\n", failedTestCount, totalTestCount, failureCount);
- else
- printf("Success: %d tests passed.\n", totalTestCount);
-
- printf("Test time: %.2f seconds.\n", secondsElapsed);
-}
-
-}
+#include "TestReporterStdout.h"
+#include
+
+#include "TestDetails.h"
+
+// cstdio doesn't pull in namespace std on VC6, so we do it here.
+#if defined(UNITTEST_WIN32) && (_MSC_VER == 1200)
+ namespace std {}
+#endif
+
+namespace UnitTest {
+
+void TestReporterStdout::ReportFailure(TestDetails const& details, char const* failure)
+{
+#if defined(__APPLE__) || defined(__GNUG__)
+ 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
+
+ using namespace 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)
+{
+ using namespace std;
+
+ if (failureCount > 0)
+ printf("FAILURE: %d out of %d tests failed (%d failures).\n", failedTestCount, totalTestCount, failureCount);
+ else
+ printf("Success: %d tests passed.\n", totalTestCount);
+
+ printf("Test time: %.2f seconds.\n", secondsElapsed);
+}
+
+}
diff --git a/src/TestReporterStdout.h b/src/TestReporterStdout.h
index c722947..4f52f8a 100644
--- a/src/TestReporterStdout.h
+++ b/src/TestReporterStdout.h
@@ -5,7 +5,7 @@
namespace UnitTest {
-class TestReporterStdout : public TestReporter
+class UNITTEST_LINKAGE TestReporterStdout : public TestReporter
{
private:
virtual void ReportTestStart(TestDetails const& test);
diff --git a/src/TestResults.h b/src/TestResults.h
index c9dc146..d4006a0 100644
--- a/src/TestResults.h
+++ b/src/TestResults.h
@@ -1,12 +1,14 @@
#ifndef UNITTEST_TESTRESULTS_H
#define UNITTEST_TESTRESULTS_H
+#include "HelperMacros.h"
+
namespace UnitTest {
class TestReporter;
class TestDetails;
-class TestResults
+class UNITTEST_LINKAGE TestResults
{
public:
explicit TestResults(TestReporter* reporter = 0);
diff --git a/src/TestRunner.cpp b/src/TestRunner.cpp
index 466265d..108348e 100644
--- a/src/TestRunner.cpp
+++ b/src/TestRunner.cpp
@@ -1,76 +1,82 @@
-#include "TestRunner.h"
-#include "TestResults.h"
-#include "TestReporter.h"
-#include "TestReporterStdout.h"
-#include "TimeHelpers.h"
-#include "MemoryOutStream.h"
-
-#include
-
-
-namespace UnitTest {
-
-int RunAllTests()
-{
- TestReporterStdout reporter;
- TestRunner runner(reporter);
- return runner.RunTestsIf(Test::GetTestList(), NULL, True(), 0);
-}
-
-
-TestRunner::TestRunner(TestReporter& reporter)
- : m_reporter(&reporter)
- , m_result(new TestResults(&reporter))
- , m_timer(new Timer)
-{
- m_timer->Start();
-}
-
-TestRunner::~TestRunner()
-{
- delete m_result;
- delete m_timer;
-}
-
-int TestRunner::Finish() const
-{
- float const secondsElapsed = m_timer->GetTimeInMs() / 1000.0f;
- m_reporter->ReportSummary(m_result->GetTotalTestCount(),
- m_result->GetFailedTestCount(),
- m_result->GetFailureCount(),
- secondsElapsed);
-
- return m_result->GetFailureCount();
-}
-
-bool TestRunner::IsTestInSuite(const Test* const curTest, char const* suiteName) const
-{
- using namespace std;
- return (suiteName == NULL) || !strcmp(curTest->m_details.suiteName, suiteName);
-}
-
-void TestRunner::RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const
-{
- CurrentTest::Results() = result;
-
- Timer testTimer;
- testTimer.Start();
-
- result->OnTestStart(curTest->m_details);
-
- curTest->Run();
-
- 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);
-}
-
-}
+#include "TestRunner.h"
+#include "TestResults.h"
+#include "TestReporter.h"
+#include "TestReporterStdout.h"
+#include "TimeHelpers.h"
+#include "MemoryOutStream.h"
+
+#include
+
+
+namespace UnitTest {
+
+int RunAllTests()
+{
+ TestReporterStdout reporter;
+ TestRunner runner(reporter);
+ return runner.RunTestsIf(Test::GetTestList(), NULL, True(), 0);
+}
+
+
+TestRunner::TestRunner(TestReporter& reporter)
+ : m_reporter(&reporter)
+ , m_result(new TestResults(&reporter))
+ , m_timer(new Timer)
+{
+ m_timer->Start();
+}
+
+TestRunner::~TestRunner()
+{
+ delete m_result;
+ delete m_timer;
+}
+
+TestResults* TestRunner::GetTestResults()
+{
+ return m_result;
+}
+
+int TestRunner::Finish() const
+{
+ float const secondsElapsed = static_cast(m_timer->GetTimeInMs() / 1000.0);
+ m_reporter->ReportSummary(m_result->GetTotalTestCount(),
+ m_result->GetFailedTestCount(),
+ m_result->GetFailureCount(),
+ secondsElapsed);
+
+ return m_result->GetFailureCount();
+}
+
+bool TestRunner::IsTestInSuite(const Test* const curTest, char const* suiteName) const
+{
+ using namespace std;
+ return (suiteName == NULL) || !strcmp(curTest->m_details.suiteName, suiteName);
+}
+
+void TestRunner::RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const
+{
+ if (curTest->m_isMockTest == false)
+ CurrentTest::Results() = result;
+
+ Timer testTimer;
+ testTimer.Start();
+
+ result->OnTestStart(curTest->m_details);
+
+ curTest->Run();
+
+ double 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, static_cast< float >(testTimeInMs / 1000.0));
+}
+
+}
diff --git a/src/TestRunner.h b/src/TestRunner.h
index 672355d..0253ae2 100644
--- a/src/TestRunner.h
+++ b/src/TestRunner.h
@@ -1,59 +1,61 @@
-#ifndef UNITTEST_TESTRUNNER_H
-#define UNITTEST_TESTRUNNER_H
-
-#include "Test.h"
-#include "TestList.h"
-#include "CurrentTest.h"
-
-namespace UnitTest {
-
-class TestReporter;
-class TestResults;
-class Timer;
-
-int RunAllTests();
-
-struct True
-{
- bool operator()(const Test* const) const
- {
- return true;
- }
-};
-
-class TestRunner
-{
-public:
- explicit TestRunner(TestReporter& reporter);
- ~TestRunner();
-
- template
- int RunTestsIf(TestList const& list, char const* suiteName,
- const Predicate& predicate, int maxTestTimeInMs) const
- {
- Test* curTest = list.GetHead();
-
- while (curTest != 0)
- {
- if (IsTestInSuite(curTest, suiteName) && predicate(curTest))
- RunTest(m_result, curTest, maxTestTimeInMs);
-
- curTest = curTest->next;
- }
-
- return Finish();
- }
-
-private:
- TestReporter* m_reporter;
- TestResults* m_result;
- Timer* m_timer;
-
- int Finish() const;
- bool IsTestInSuite(const Test* const curTest, char const* suiteName) const;
- void RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const;
-};
-
-}
-
-#endif
+#ifndef UNITTEST_TESTRUNNER_H
+#define UNITTEST_TESTRUNNER_H
+
+#include "Test.h"
+#include "TestList.h"
+#include "CurrentTest.h"
+
+namespace UnitTest {
+
+class TestReporter;
+class TestResults;
+class Timer;
+
+UNITTEST_LINKAGE int RunAllTests();
+
+struct True
+{
+ bool operator()(const Test* const) const
+ {
+ return true;
+ }
+};
+
+class UNITTEST_LINKAGE TestRunner
+{
+public:
+ explicit TestRunner(TestReporter& reporter);
+ ~TestRunner();
+
+ template< class Predicate >
+ int RunTestsIf(TestList const& list, char const* suiteName,
+ const Predicate& predicate, int maxTestTimeInMs) const
+ {
+ Test* curTest = list.GetHead();
+
+ while (curTest != 0)
+ {
+ if (IsTestInSuite(curTest, suiteName) && predicate(curTest))
+ RunTest(m_result, curTest, maxTestTimeInMs);
+
+ curTest = curTest->m_nextTest;
+ }
+
+ return Finish();
+ }
+
+ TestResults* GetTestResults();
+
+private:
+ TestReporter* m_reporter;
+ TestResults* m_result;
+ Timer* m_timer;
+
+ int Finish() const;
+ bool IsTestInSuite(const Test* const curTest, char const* suiteName) const;
+ void RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const;
+};
+
+}
+
+#endif
diff --git a/src/TestSuite.h b/src/TestSuite.h
index dd3717e..02067fd 100644
--- a/src/TestSuite.h
+++ b/src/TestSuite.h
@@ -1,14 +1,12 @@
-#ifndef UNITTEST_TESTSUITE_H
-#define UNITTEST_TESTSUITE_H
-
-namespace UnitTestSuite {
-
- inline char const* GetSuiteName ()
- {
- return "DefaultSuite";
- }
-
-}
-
-#endif
-
+#ifndef UNITTEST_TESTSUITE_H
+#define UNITTEST_TESTSUITE_H
+
+namespace UnitTestSuite
+{
+ inline char const* GetSuiteName ()
+ {
+ return "DefaultSuite";
+ }
+}
+
+#endif
diff --git a/src/TimeConstraint.cpp b/src/TimeConstraint.cpp
index b313be7..89f1b87 100644
--- a/src/TimeConstraint.cpp
+++ b/src/TimeConstraint.cpp
@@ -1,29 +1,29 @@
-#include "TimeConstraint.h"
-#include "TestResults.h"
-#include "MemoryOutStream.h"
-#include "CurrentTest.h"
-
-namespace UnitTest {
-
-
-TimeConstraint::TimeConstraint(int ms, TestDetails const& details)
- : 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.";
-
- UnitTest::CurrentTest::Results()->OnTestFailure(m_details, stream.GetText());
- }
-}
-
-}
+#include "TimeConstraint.h"
+#include "TestResults.h"
+#include "MemoryOutStream.h"
+#include "CurrentTest.h"
+
+namespace UnitTest {
+
+
+TimeConstraint::TimeConstraint(int ms, TestDetails const& details)
+ : m_details(details)
+ , m_maxMs(ms)
+{
+ m_timer.Start();
+}
+
+TimeConstraint::~TimeConstraint()
+{
+ double 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.";
+
+ CurrentTest::Results()->OnTestFailure(m_details, stream.GetText());
+ }
+}
+
+}
diff --git a/src/TimeConstraint.h b/src/TimeConstraint.h
index 2034837..fe14461 100644
--- a/src/TimeConstraint.h
+++ b/src/TimeConstraint.h
@@ -2,13 +2,14 @@
#define UNITTEST_TIMECONSTRAINT_H
#include "TimeHelpers.h"
+#include "HelperMacros.h"
namespace UnitTest {
class TestResults;
class TestDetails;
-class TimeConstraint
+class UNITTEST_LINKAGE TimeConstraint
{
public:
TimeConstraint(int ms, TestDetails const& details);
@@ -26,7 +27,10 @@ class TimeConstraint
#define UNITTEST_TIME_CONSTRAINT(ms) \
UnitTest::TimeConstraint unitTest__timeConstraint__(ms, UnitTest::TestDetails(m_details, __LINE__))
-#define UNITTEST_TIME_CONSTRAINT_EXEMPT() do { m_timeConstraintExempt = true; } while (0)
+#define UNITTEST_TIME_CONSTRAINT_EXEMPT() \
+ UNITTEST_MULTILINE_MACRO_BEGIN \
+ m_timeConstraintExempt = true; \
+ UNITTEST_MULTILINE_MACRO_END
}
diff --git a/src/TimeHelpers.h b/src/TimeHelpers.h
index cbc3ff4..24f0efd 100644
--- a/src/TimeHelpers.h
+++ b/src/TimeHelpers.h
@@ -1,4 +1,4 @@
-#include "Config.h"
+#include "../config.h"
#if defined UNITTEST_POSIX
#include "Posix/TimeHelpers.h"
diff --git a/src/UnitTest++.h b/src/UnitTest++.h
deleted file mode 100644
index bacc4cf..0000000
--- a/src/UnitTest++.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef UNITTESTCPP_H
-#define UNITTESTCPP_H
-
-//lint -esym(1509,*Fixture)
-
-#include "Config.h"
-#include "Test.h"
-#include "TestList.h"
-#include "TestSuite.h"
-#include "TestResults.h"
-
-#include "TestMacros.h"
-
-#include "CheckMacros.h"
-#include "TestRunner.h"
-#include "TimeConstraint.h"
-
-#endif
diff --git a/src/Win32/TimeHelpers.cpp b/src/Win32/TimeHelpers.cpp
index 69d0d88..1b39cab 100644
--- a/src/Win32/TimeHelpers.cpp
+++ b/src/Win32/TimeHelpers.cpp
@@ -1,47 +1,49 @@
-#include "TimeHelpers.h"
-#include
-
-namespace UnitTest {
-
-Timer::Timer()
- : m_threadHandle(::GetCurrentThread())
- , m_startTime(0)
-{
-#if defined(_MSC_VER) && (_MSC_VER == 1200) // VC6 doesn't have DWORD_PTR?
- typedef unsigned long DWORD_PTR;
-#endif
-
- DWORD_PTR systemMask;
- ::GetProcessAffinityMask(GetCurrentProcess(), &m_processAffinityMask, &systemMask);
- ::SetThreadAffinityMask(m_threadHandle, 1);
- ::QueryPerformanceFrequency(reinterpret_cast< LARGE_INTEGER* >(&m_frequency));
- ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask);
-}
-
-void Timer::Start()
-{
- m_startTime = GetTime();
-}
-
-double Timer::GetTimeInMs() const
-{
- __int64 const elapsedTime = GetTime() - m_startTime;
- double const seconds = double(elapsedTime) / double(m_frequency);
- return seconds * 1000.0;
-}
-
-__int64 Timer::GetTime() const
-{
- LARGE_INTEGER curTime;
- ::SetThreadAffinityMask(m_threadHandle, 1);
- ::QueryPerformanceCounter(&curTime);
- ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask);
- return curTime.QuadPart;
-}
-
-void TimeHelpers::SleepMs(int const ms)
-{
- ::Sleep(ms);
-}
-
-}
+#include "TimeHelpers.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+namespace UnitTest {
+
+Timer::Timer()
+ : m_threadHandle(::GetCurrentThread())
+ , m_startTime(0)
+{
+#if defined(UNITTEST_WIN32) && (_MSC_VER == 1200) // VC6 doesn't have DWORD_PTR
+ typedef unsigned long DWORD_PTR;
+#endif
+
+ DWORD_PTR systemMask;
+ ::GetProcessAffinityMask(GetCurrentProcess(), &m_processAffinityMask, &systemMask);
+ ::SetThreadAffinityMask(m_threadHandle, 1);
+ ::QueryPerformanceFrequency(reinterpret_cast< LARGE_INTEGER* >(&m_frequency));
+ ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask);
+}
+
+void Timer::Start()
+{
+ m_startTime = GetTime();
+}
+
+double Timer::GetTimeInMs() const
+{
+ __int64 const elapsedTime = GetTime() - m_startTime;
+ double const seconds = double(elapsedTime) / double(m_frequency);
+ return seconds * 1000.0;
+}
+
+__int64 Timer::GetTime() const
+{
+ LARGE_INTEGER curTime;
+ ::SetThreadAffinityMask(m_threadHandle, 1);
+ ::QueryPerformanceCounter(&curTime);
+ ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask);
+ return curTime.QuadPart;
+}
+
+void TimeHelpers::SleepMs(int ms)
+{
+ ::Sleep(ms);
+}
+
+}
diff --git a/src/Win32/TimeHelpers.h b/src/Win32/TimeHelpers.h
index 088de24..80c9118 100644
--- a/src/Win32/TimeHelpers.h
+++ b/src/Win32/TimeHelpers.h
@@ -1,48 +1,45 @@
-#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();
- double GetTimeInMs() const;
-
-private:
- __int64 GetTime() const;
-
- void* m_threadHandle;
-
-#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
+#ifndef UNITTEST_TIMEHELPERS_H
+#define UNITTEST_TIMEHELPERS_H
+
+#include "../../config.h"
+#include "../HelperMacros.h"
+
+#ifdef UNITTEST_MINGW
+ #ifndef __int64
+ #define __int64 long long
+ #endif
+#endif
+
+namespace UnitTest {
+
+class UNITTEST_LINKAGE Timer
+{
+public:
+ Timer();
+ void Start();
+ double GetTimeInMs() const;
+
+private:
+ __int64 GetTime() const;
+
+ void* m_threadHandle;
+
+#if defined(_WIN64)
+ unsigned __int64 m_processAffinityMask;
+#else
+ unsigned long m_processAffinityMask;
+#endif
+
+ __int64 m_startTime;
+ __int64 m_frequency;
+};
+
+
+namespace TimeHelpers
+{
+ UNITTEST_LINKAGE void SleepMs(int ms);
+}
+
+}
+
+#endif
diff --git a/src/XmlTestReporter.cpp b/src/XmlTestReporter.cpp
index 436ceeb..09f0f24 100644
--- a/src/XmlTestReporter.cpp
+++ b/src/XmlTestReporter.cpp
@@ -1,5 +1,7 @@
+#include "../config.h"
+#ifndef UNITTEST_NO_DEFERRED_REPORTER
+
#include "XmlTestReporter.h"
-#include "Config.h"
#include
#include
@@ -117,11 +119,13 @@ void XmlTestReporter::AddFailure(std::ostream& os, DeferredTestResult const& res
it != result.failures.end();
++it)
{
- string const escapedMessage = XmlEscape(it->second);
- string const message = BuildFailureMessage(result.failureFile, it->first, escapedMessage);
+ string const escapedMessage = XmlEscape(std::string(it->failureStr));
+ string const message = BuildFailureMessage(result.failureFile, it->lineNumber, escapedMessage);
os << "";
}
}
}
+
+#endif
diff --git a/src/XmlTestReporter.h b/src/XmlTestReporter.h
index c775b5a..2adf298 100644
--- a/src/XmlTestReporter.h
+++ b/src/XmlTestReporter.h
@@ -1,6 +1,9 @@
#ifndef UNITTEST_XMLTESTREPORTER_H
#define UNITTEST_XMLTESTREPORTER_H
+#include "../config.h"
+#ifndef UNITTEST_NO_DEFERRED_REPORTER
+
#include "DeferredTestReporter.h"
#include
@@ -8,7 +11,7 @@
namespace UnitTest
{
-class XmlTestReporter : public DeferredTestReporter
+class UNITTEST_LINKAGE XmlTestReporter : public DeferredTestReporter
{
public:
explicit XmlTestReporter(std::ostream& ostream);
@@ -32,3 +35,4 @@ class XmlTestReporter : public DeferredTestReporter
}
#endif
+#endif
diff --git a/src/tests/Main.cpp b/src/tests/Main.cpp
index b4fae78..963ad7b 100644
--- a/src/tests/Main.cpp
+++ b/src/tests/Main.cpp
@@ -1,6 +1,4 @@
-#include "../UnitTest++.h"
-#include "../TestReporterStdout.h"
-
+#include "../../unittestpp.h"
int main(int, char const *[])
{
diff --git a/src/tests/TestAssertHandler.cpp b/src/tests/TestAssertHandler.cpp
index 0c594cd..3b28c5f 100644
--- a/src/tests/TestAssertHandler.cpp
+++ b/src/tests/TestAssertHandler.cpp
@@ -1,44 +1,136 @@
-#include "../UnitTest++.h"
-#include "../AssertException.h"
+#include "../../config.h"
+#include "../../unittestpp.h"
+
#include "../ReportAssert.h"
+#include "../ReportAssertImpl.h"
+#include "../AssertException.h"
+
+#include "RecordingReporter.h"
+#include
using namespace UnitTest;
namespace {
+TEST(CanSetAssertExpected)
+{
+ Detail::ExpectAssert(true);
+ CHECK(Detail::AssertExpected());
+
+ Detail::ExpectAssert(false);
+ CHECK(!Detail::AssertExpected());
+}
+
+#ifndef UNITTEST_NO_EXCEPTIONS
+
TEST(ReportAssertThrowsAssertException)
{
bool caught = false;
try
{
- ReportAssert("", "", 0);
+ TestResults testResults;
+ TestDetails testDetails("", "", "", 0);
+ Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0);
}
catch(AssertException const&)
{
caught = true;
}
- CHECK (true == caught);
+ CHECK(true == caught);
}
-TEST(ReportAssertSetsCorrectInfoInException)
+TEST(ReportAssertClearsExpectAssertFlag)
+{
+ RecordingReporter reporter;
+ TestResults testResults(&reporter);
+ TestDetails testDetails("", "", "", 0);
+
+ try
+ {
+ Detail::ExpectAssert(true);
+ Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0);
+ }
+ catch(AssertException const&)
+ {
+ }
+
+ CHECK(Detail::AssertExpected() == false);
+ CHECK_EQUAL(0, reporter.testFailedCount);
+}
+
+TEST(ReportAssertWritesFailureToResultsAndDetailsWhenAssertIsNotExpected)
{
const int lineNumber = 12345;
const char* description = "description";
const char* filename = "filename";
+ RecordingReporter reporter;
+ TestResults testResults(&reporter);
+ TestDetails testDetails("", "", "", 0);
+
try
{
- ReportAssert(description, filename, lineNumber);
+ Detail::ReportAssertEx(&testResults, &testDetails, description, filename, lineNumber);
}
- catch(AssertException const& e)
+ catch(AssertException const&)
{
- CHECK_EQUAL(description, e.what());
- CHECK_EQUAL(filename, e.Filename());
- CHECK_EQUAL(lineNumber, e.LineNumber());
}
+
+ CHECK_EQUAL(description, reporter.lastFailedMessage);
+ CHECK_EQUAL(filename, reporter.lastFailedFile);
+ CHECK_EQUAL(lineNumber, reporter.lastFailedLine);
+}
+
+TEST(ReportAssertReportsNoErrorsWhenAssertIsExpected)
+{
+ Detail::ExpectAssert(true);
+
+ RecordingReporter reporter;
+ TestResults testResults(&reporter);
+ TestDetails testDetails("", "", "", 0);
+
+ try
+ {
+ Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0);
+ }
+ catch(AssertException const&)
+ {
+ }
+
+ CHECK_EQUAL(0, reporter.testFailedCount);
+}
+
+TEST(CheckAssertMacroSetsAssertExpectationToFalseAfterRunning)
+{
+ Detail::ExpectAssert(true);
+ CHECK_ASSERT(ReportAssert("", "", 0));
+ CHECK(!Detail::AssertExpected());
+ Detail::ExpectAssert(false);
+}
+
+#else
+
+TEST(SetAssertJumpTargetReturnsFalseWhenSettingJumpTarget)
+{
+ CHECK(UNITTEST_SET_ASSERT_JUMP_TARGET() == false);
+}
+
+TEST(JumpToAssertJumpTarget_JumpsToSetPoint_ReturnsTrue)
+{
+ const volatile bool taken = !!UNITTEST_SET_ASSERT_JUMP_TARGET();
+
+ volatile bool set = false;
+ if (taken == false)
+ {
+ UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET();
+ set = true;
+ }
+
+ CHECK(set == false);
}
+#endif
}
diff --git a/src/tests/TestCheckMacros.cpp b/src/tests/TestCheckMacros.cpp
index 6ea1105..6b9fb66 100644
--- a/src/tests/TestCheckMacros.cpp
+++ b/src/tests/TestCheckMacros.cpp
@@ -1,4 +1,4 @@
-#include "../UnitTest++.h"
+#include "../../unittestpp.h"
#include "../CurrentTest.h"
#include "RecordingReporter.h"
#include "ScopedCurrentTest.h"
@@ -62,37 +62,6 @@ TEST(CheckFailureIncludesCheckContents)
CHECK(strstr(reporter.lastFailedMessage, "yaddayadda"));
}
-int ThrowingFunction()
-{
- throw "Doh";
-}
-
-TEST(CheckFailsOnException)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK(ThrowingFunction() == 1);
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
-TEST(CheckFailureBecauseOfExceptionIncludesCheckContents)
-{
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK(ThrowingFunction() == 1);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction() == 1"));
-}
-
TEST(CheckEqualSucceedsOnEqual)
{
bool failure = true;
@@ -121,20 +90,6 @@ TEST(CheckEqualFailsOnNotEqual)
CHECK(failure);
}
-TEST(CheckEqualFailsOnException)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK_EQUAL(ThrowingFunction(), 1);
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
TEST(CheckEqualFailureContainsCorrectDetails)
{
int line = 0;
@@ -153,37 +108,6 @@ TEST(CheckEqualFailureContainsCorrectDetails)
CHECK_EQUAL(line, reporter.lastFailedLine);
}
-TEST(CheckEqualFailureBecauseOfExceptionContainsCorrectDetails)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1);
- ScopedCurrentTest scopedResults(testResults, &testDetails);
-
- 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);
- ScopedCurrentTest scopedResults(testResults);
- CHECK_EQUAL(ThrowingFunction(), 123);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction()"));
- CHECK(strstr(reporter.lastFailedMessage, "123"));
-}
-
int g_sideEffect = 0;
int FunctionWithSideEffects()
{
@@ -242,20 +166,6 @@ TEST(CheckCloseFailsOnNotEqual)
CHECK(failure);
}
-TEST(CheckCloseFailsOnException)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
- CHECK_CLOSE ((float)ThrowingFunction(), 1.0001f, 0.1f);
- failure = (testResults.GetFailureCount() > 0);
- }
-
- CHECK(failure);
-}
-
TEST(CheckCloseFailureContainsCorrectDetails)
{
int line = 0;
@@ -274,36 +184,6 @@ TEST(CheckCloseFailureContainsCorrectDetails)
CHECK_EQUAL(line, reporter.lastFailedLine);
}
-TEST(CheckCloseFailureBecauseOfExceptionContainsCorrectDetails)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- UnitTest::TestDetails testDetails("closeTest", "closeSuite", "filename", -1);
- ScopedCurrentTest scopedResults(testResults, &testDetails);
- 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);
- ScopedCurrentTest scopedResults(testResults);
- CHECK_CLOSE ((float)ThrowingFunction(), 1.0001f, 0.1f);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "(float)ThrowingFunction()"));
- CHECK(strstr(reporter.lastFailedMessage, "1.0001f"));
-}
-
TEST(CheckCloseDoesNotHaveSideEffectsWhenPassing)
{
g_sideEffect = 0;
@@ -326,17 +206,6 @@ TEST(CheckCloseDoesNotHaveSideEffectsWhenFailing)
CHECK_EQUAL(1, g_sideEffect);
}
-
-class ThrowingObject
-{
-public:
- float operator[](int) const
- {
- throw "Test throw";
- }
-};
-
-
TEST(CheckArrayCloseSucceedsOnEqual)
{
bool failure = true;
@@ -406,25 +275,6 @@ TEST(CheckArrayCloseFailureContainsCorrectDetails)
CHECK_EQUAL(line, reporter.lastFailedLine);
}
-TEST(CheckArrayCloseFailureBecauseOfExceptionContainsCorrectDetails)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1);
- ScopedCurrentTest scopedResults(testResults, &testDetails);
-
- 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;
@@ -440,42 +290,6 @@ TEST(CheckArrayCloseFailureIncludesTolerance)
CHECK(strstr(reporter.lastFailedMessage, "0.01"));
}
-
-TEST(CheckArrayCloseFailsOnException)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- 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);
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[4] = { 0, 1, 2, 3 };
- ThrowingObject obj;
- CHECK_ARRAY_CLOSE (data, obj, 3, 0.01f);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "data"));
- CHECK(strstr(reporter.lastFailedMessage, "obj"));
-}
-
-
TEST(CheckArrayEqualSuceedsOnEqual)
{
bool failure = true;
@@ -545,40 +359,6 @@ TEST(CheckArrayEqualFailureContainsCorrectInfo)
CHECK_EQUAL(line, reporter.lastFailedLine);
}
-TEST(CheckArrayEqualFailsOnException)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- 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);
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[4] = { 0, 1, 2, 3 };
- ThrowingObject obj;
- CHECK_ARRAY_EQUAL (data, obj, 3);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "data"));
- CHECK(strstr(reporter.lastFailedMessage, "obj"));
-}
-
float const* FunctionWithSideEffects2()
{
++g_sideEffect;
@@ -613,16 +393,6 @@ TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenFailing)
CHECK_EQUAL(1, g_sideEffect);
}
-class ThrowingObject2D
-{
-public:
- float* operator[](int) const
- {
- throw "Test throw";
- }
-};
-
-
TEST(CheckArray2DCloseSucceedsOnEqual)
{
bool failure = true;
@@ -695,25 +465,6 @@ TEST(CheckArray2DCloseFailureContainsCorrectDetails)
CHECK_EQUAL(line, reporter.lastFailedLine);
}
-TEST(CheckArray2DCloseFailureBecauseOfExceptionContainsCorrectDetails)
-{
- int line = 0;
- RecordingReporter reporter;
- {
- UnitTest::TestResults testResults(&reporter);
- UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1);
- ScopedCurrentTest scopedResults(testResults, &testDetails);
-
- 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;
@@ -729,40 +480,6 @@ TEST(CheckArray2DCloseFailureIncludesTolerance)
CHECK(strstr(reporter.lastFailedMessage, "0.01"));
}
-TEST(CheckArray2DCloseFailsOnException)
-{
- bool failure = false;
- {
- RecordingReporter reporter;
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- 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);
- ScopedCurrentTest scopedResults(testResults);
-
- const float data[2][2] = { {0, 1}, {2, 3} };
- ThrowingObject2D obj;
- CHECK_ARRAY2D_CLOSE (data, obj, 2, 2, 0.01f);
- }
-
- CHECK(strstr(reporter.lastFailedMessage, "data"));
- CHECK(strstr(reporter.lastFailedMessage, "obj"));
-}
-
float const* const* FunctionWithSideEffects3()
{
++g_sideEffect;
diff --git a/src/tests/TestChecks.cpp b/src/tests/TestChecks.cpp
index cee9a3f..10b3071 100644
--- a/src/tests/TestChecks.cpp
+++ b/src/tests/TestChecks.cpp
@@ -1,6 +1,8 @@
-#include "../UnitTest++.h"
+#include "../../unittestpp.h"
#include "RecordingReporter.h"
+#include
+
using namespace UnitTest;
@@ -119,25 +121,21 @@ TEST(CheckCloseWithZeroEpsilonWorksForSameNumber)
TEST(CheckCloseWithNaNFails)
{
- union
- {
- unsigned int bitpattern;
- float nan;
- };
- bitpattern = 0xFFFFFFFF;
- TestResults results;
+ const unsigned int bitpattern = 0xFFFFFFFF;
+ float nan;
+ std::memcpy(&nan, &bitpattern, sizeof(bitpattern));
+
+ 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;
+ const unsigned int bitpattern = 0xFFFFFFFF;
+ float nan;
+ std::memcpy(&nan, &bitpattern, sizeof(bitpattern));
+
TestResults results;
CheckClose(results, nan, nan, 0.1f, TestDetails("", "", "", 0));
CHECK_EQUAL(1, results.GetFailureCount());
diff --git a/src/tests/TestCompositeTestReporter.cpp b/src/tests/TestCompositeTestReporter.cpp
new file mode 100644
index 0000000..d302577
--- /dev/null
+++ b/src/tests/TestCompositeTestReporter.cpp
@@ -0,0 +1,176 @@
+#include "../../unittestpp.h"
+#include "../CompositeTestReporter.h"
+
+using namespace UnitTest;
+
+namespace {
+
+TEST(ZeroReportersByDefault)
+{
+ CHECK_EQUAL(0, CompositeTestReporter().GetReporterCount());
+}
+
+struct MockReporter : TestReporter
+{
+ MockReporter()
+ : testStartCalled(false)
+ , testStartDetails(NULL)
+ , failureCalled(false)
+ , failureDetails(NULL)
+ , failureStr(NULL)
+ , testFinishCalled(false)
+ , testFinishDetails(NULL)
+ , testFinishSecondsElapsed(-1.0f)
+ , summaryCalled(false)
+ , summaryTotalTestCount(-1)
+ , summaryFailureCount(-1)
+ , summarySecondsElapsed(-1.0f)
+ {
+ }
+
+ virtual void ReportTestStart(TestDetails const& test)
+ {
+ testStartCalled = true;
+ testStartDetails = &test;
+ }
+
+ virtual void ReportFailure(TestDetails const& test, char const* failure)
+ {
+ failureCalled = true;
+ failureDetails = &test;
+ failureStr = failure;
+ }
+
+ virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed)
+ {
+ testFinishCalled = true;
+ testFinishDetails = &test;
+ testFinishSecondsElapsed = secondsElapsed;
+ }
+
+ virtual void ReportSummary(int totalTestCount,
+ int failedTestCount,
+ int failureCount,
+ float secondsElapsed)
+ {
+ summaryCalled = true;
+ summaryTotalTestCount = totalTestCount;
+ summaryFailedTestCount = failedTestCount;
+ summaryFailureCount = failureCount;
+ summarySecondsElapsed = secondsElapsed;
+ }
+
+ bool testStartCalled;
+ TestDetails const* testStartDetails;
+
+ bool failureCalled;
+ TestDetails const* failureDetails;
+ const char* failureStr;
+
+ bool testFinishCalled;
+ TestDetails const* testFinishDetails;
+ float testFinishSecondsElapsed;
+
+ bool summaryCalled;
+ int summaryTotalTestCount;
+ int summaryFailedTestCount;
+ int summaryFailureCount;
+ float summarySecondsElapsed;
+};
+
+TEST(AddReporter)
+{
+ MockReporter r;
+ CompositeTestReporter c;
+
+ CHECK(c.AddReporter(&r));
+ CHECK_EQUAL(1, c.GetReporterCount());
+}
+
+TEST(RemoveReporter)
+{
+ MockReporter r;
+ CompositeTestReporter c;
+
+ c.AddReporter(&r);
+ CHECK(c.RemoveReporter(&r));
+ CHECK_EQUAL(0, c.GetReporterCount());
+}
+
+struct Fixture
+{
+ Fixture()
+ {
+ c.AddReporter(&r0);
+ c.AddReporter(&r1);
+ }
+
+ MockReporter r0, r1;
+ CompositeTestReporter c;
+};
+
+TEST_FIXTURE(Fixture, ReportTestStartCallsReportTestStartOnAllAggregates)
+{
+ TestDetails t("", "", "", 0);
+ c.ReportTestStart(t);
+
+ CHECK(r0.testStartCalled);
+ CHECK_EQUAL(&t, r0.testStartDetails);
+ CHECK(r1.testStartCalled);
+ CHECK_EQUAL(&t, r1.testStartDetails);
+}
+
+TEST_FIXTURE(Fixture, ReportFailureCallsReportFailureOnAllAggregates)
+{
+ TestDetails t("", "", "", 0);
+ const char* failStr = "fail";
+ c.ReportFailure(t, failStr);
+
+ CHECK(r0.failureCalled);
+ CHECK_EQUAL(&t, r0.failureDetails);
+ CHECK_EQUAL(failStr, r0.failureStr);
+
+ CHECK(r1.failureCalled);
+ CHECK_EQUAL(&t, r1.failureDetails);
+ CHECK_EQUAL(failStr, r1.failureStr);
+}
+
+TEST_FIXTURE(Fixture, ReportTestFinishCallsReportTestFinishOnAllAggregates)
+{
+ TestDetails t("", "", "", 0);
+ const float s = 1.2345f;
+ c.ReportTestFinish(t, s);
+
+ CHECK(r0.testFinishCalled);
+ CHECK_EQUAL(&t, r0.testFinishDetails);
+ CHECK_CLOSE(s, r0.testFinishSecondsElapsed, 0.00001f);
+
+ CHECK(r1.testFinishCalled);
+ CHECK_EQUAL(&t, r1.testFinishDetails);
+ CHECK_CLOSE(s, r1.testFinishSecondsElapsed, 0.00001f);
+}
+
+TEST_FIXTURE(Fixture, ReportSummaryCallsReportSummaryOnAllAggregates)
+{
+ TestDetails t("", "", "", 0);
+ const int testCount = 3;
+ const int failedTestCount = 4;
+ const int failureCount = 5;
+ const float secondsElapsed = 3.14159f;
+
+ c.ReportSummary(testCount, failedTestCount, failureCount, secondsElapsed);
+
+ CHECK(r0.summaryCalled);
+ CHECK_EQUAL(testCount, r0.summaryTotalTestCount);
+ CHECK_EQUAL(failedTestCount, r0.summaryFailedTestCount);
+ CHECK_EQUAL(failureCount, r0.summaryFailureCount);
+ CHECK_CLOSE(secondsElapsed, r0.summarySecondsElapsed, 0.00001f);
+
+ CHECK(r1.summaryCalled);
+ CHECK_EQUAL(testCount, r1.summaryTotalTestCount);
+ CHECK_EQUAL(failedTestCount, r1.summaryFailedTestCount);
+ CHECK_EQUAL(failureCount, r1.summaryFailureCount);
+ CHECK_CLOSE(secondsElapsed, r1.summarySecondsElapsed, 0.00001f);
+}
+
+}
diff --git a/src/tests/TestCurrentTest.cpp b/src/tests/TestCurrentTest.cpp
index 882b3e4..766539f 100644
--- a/src/tests/TestCurrentTest.cpp
+++ b/src/tests/TestCurrentTest.cpp
@@ -1,4 +1,4 @@
-#include "../UnitTest++.h"
+#include "../../unittestpp.h"
#include "../CurrentTest.h"
#include "ScopedCurrentTest.h"
diff --git a/src/tests/TestDeferredTestReporter.cpp b/src/tests/TestDeferredTestReporter.cpp
index 5560692..7550ab4 100644
--- a/src/tests/TestDeferredTestReporter.cpp
+++ b/src/tests/TestDeferredTestReporter.cpp
@@ -1,6 +1,9 @@
-#include "../UnitTest++.h"
+#include "../../config.h"
+
+#ifndef UNITTEST_NO_DEFERRED_REPORTER
+
+#include "../../unittestpp.h"
#include "../DeferredTestReporter.h"
-#include "../Config.h"
#include
namespace UnitTest
@@ -9,7 +12,7 @@ namespace UnitTest
namespace
{
-#ifdef UNITTEST_USE_CUSTOM_STREAMS
+#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM
MemoryOutStream& operator <<(MemoryOutStream& lhs, const std::string& rhs)
{
lhs << rhs.c_str();
@@ -91,8 +94,8 @@ TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetailsForMul
DeferredTestResult const& result = reporter.GetResults().at(0);
CHECK_EQUAL(2, (int)result.failures.size());
- CHECK_EQUAL(failure1, result.failures[0].second);
- CHECK_EQUAL(failure2, result.failures[1].second);
+ CHECK_EQUAL(failure1, result.failures[0].failureStr);
+ CHECK_EQUAL(failure2, result.failures[1].failureStr);
}
TEST_FIXTURE(DeferredTestReporterFixture, DeferredTestReporterTakesCopyOfFailureMessage)
@@ -110,8 +113,10 @@ TEST_FIXTURE(DeferredTestReporterFixture, DeferredTestReporterTakesCopyOfFailure
strcpy(failureMessage, badStr);
DeferredTestResult const& result = reporter.GetResults().at(0);
- DeferredTestResult::Failure const& failure = result.failures.at(0);
- CHECK_EQUAL(goodStr, failure.second);
+ DeferredTestFailure const& failure = result.failures.at(0);
+ CHECK_EQUAL(goodStr, failure.failureStr);
}
}}
+
+#endif
diff --git a/src/tests/TestExceptions.cpp b/src/tests/TestExceptions.cpp
new file mode 100644
index 0000000..6f55c9a
--- /dev/null
+++ b/src/tests/TestExceptions.cpp
@@ -0,0 +1,293 @@
+#include "../../config.h"
+#ifndef UNITTEST_NO_EXCEPTIONS
+
+#include "../../unittestpp.h"
+#include "../CurrentTest.h"
+#include "RecordingReporter.h"
+#include "ScopedCurrentTest.h"
+
+using namespace std;
+
+namespace {
+
+int ThrowingFunction()
+{
+ throw "Doh";
+}
+
+TEST(CheckFailsOnException)
+{
+ bool failure = false;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK(ThrowingFunction() == 1);
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(failure);
+}
+
+TEST(CheckFailureBecauseOfExceptionIncludesCheckContents)
+{
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK(ThrowingFunction() == 1);
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction() == 1"));
+}
+
+TEST(CheckEqualFailsOnException)
+{
+ bool failure = false;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK_EQUAL(ThrowingFunction(), 1);
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(failure);
+}
+
+TEST(CheckEqualFailureBecauseOfExceptionContainsCorrectDetails)
+{
+ int line = 0;
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+
+ 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);
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK_EQUAL(ThrowingFunction(), 123);
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction()"));
+ CHECK(strstr(reporter.lastFailedMessage, "123"));
+}
+
+TEST(CheckCloseFailsOnException)
+{
+ bool failure = false;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK_CLOSE((float)ThrowingFunction(), 1.0001f, 0.1f);
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(failure);
+}
+
+TEST(CheckCloseFailureBecauseOfExceptionContainsCorrectDetails)
+{
+ int line = 0;
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ UnitTest::TestDetails testDetails("closeTest", "closeSuite", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+ 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);
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK_CLOSE((float)ThrowingFunction(), 1.0001f, 0.1f);
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "(float)ThrowingFunction()"));
+ CHECK(strstr(reporter.lastFailedMessage, "1.0001f"));
+}
+
+class ThrowingObject
+{
+public:
+ float operator[](int) const
+ {
+ throw "Test throw";
+ }
+};
+
+TEST(CheckArrayCloseFailureBecauseOfExceptionContainsCorrectDetails)
+{
+ int line = 0;
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+
+ 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(CheckArrayCloseFailsOnException)
+{
+ bool failure = false;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ 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);
+ ScopedCurrentTest scopedResults(testResults);
+
+ const float data[4] = { 0, 1, 2, 3 };
+ ThrowingObject obj;
+ CHECK_ARRAY_CLOSE(data, obj, 3, 0.01f);
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "data"));
+ CHECK(strstr(reporter.lastFailedMessage, "obj"));
+}
+
+TEST(CheckArrayEqualFailsOnException)
+{
+ bool failure = false;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ 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);
+ ScopedCurrentTest scopedResults(testResults);
+
+ const float data[4] = { 0, 1, 2, 3 };
+ ThrowingObject obj;
+ CHECK_ARRAY_EQUAL (data, obj, 3);
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "data"));
+ CHECK(strstr(reporter.lastFailedMessage, "obj"));
+}
+
+class ThrowingObject2D
+{
+public:
+ float* operator[](int) const
+ {
+ throw "Test throw";
+ }
+};
+
+TEST(CheckArray2DCloseFailureBecauseOfExceptionContainsCorrectDetails)
+{
+ int line = 0;
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+
+ 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(CheckArray2DCloseFailsOnException)
+{
+ bool failure = false;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ 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);
+ ScopedCurrentTest scopedResults(testResults);
+
+ const float data[2][2] = { {0, 1}, {2, 3} };
+ ThrowingObject2D obj;
+ CHECK_ARRAY2D_CLOSE(data, obj, 2, 2, 0.01f);
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "data"));
+ CHECK(strstr(reporter.lastFailedMessage, "obj"));
+}
+
+}
+
+#endif
diff --git a/src/tests/TestMemoryOutStream.cpp b/src/tests/TestMemoryOutStream.cpp
index c5a4227..f83b10c 100644
--- a/src/tests/TestMemoryOutStream.cpp
+++ b/src/tests/TestMemoryOutStream.cpp
@@ -1,7 +1,9 @@
-#include "../UnitTest++.h"
+#include "../../unittestpp.h"
#include "../MemoryOutStream.h"
#include
+#include
+#include
using namespace UnitTest;
using namespace std;
@@ -57,6 +59,20 @@ TEST(StreamingUnsignedLongWritesCorrectCharacters)
CHECK_EQUAL("123", stream.GetText());
}
+TEST(StreamingLongLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (long long)8589934590ll;
+ CHECK_EQUAL("8589934590", stream.GetText());
+}
+
+TEST(StreamingUnsignedLongLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (unsigned long long)8589934590ull;
+ CHECK_EQUAL("8589934590", stream.GetText());
+}
+
TEST(StreamingFloatWritesCorrectCharacters)
{
MemoryOutStream stream;
@@ -87,7 +103,15 @@ TEST(StreamingSizeTWritesCorrectCharacters)
CHECK_EQUAL("53124", stream.GetText());
}
-#ifdef UNITTEST_USE_CUSTOM_STREAMS
+TEST(ClearEmptiesMemoryOutStreamContents)
+{
+ MemoryOutStream stream;
+ stream << "Hello world";
+ stream.Clear();
+ CHECK_EQUAL("", stream.GetText());
+}
+
+#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM
TEST(StreamInitialCapacityIsCorrect)
{
diff --git a/src/tests/TestTest.cpp b/src/tests/TestTest.cpp
index d3c3d4c..2ae2192 100644
--- a/src/tests/TestTest.cpp
+++ b/src/tests/TestTest.cpp
@@ -1,4 +1,4 @@
-#include "../UnitTest++.h"
+#include "../../unittestpp.h"
#include "../TestReporter.h"
#include "../TimeHelpers.h"
#include "ScopedCurrentTest.h"
@@ -50,7 +50,7 @@ TEST(FailingTestHasFailures)
CHECK_EQUAL(1, results.GetFailureCount());
}
-
+#ifndef UNITTEST_NO_EXCEPTIONS
TEST(ThrowingTestsAreReportedAsFailures)
{
class CrashingTest : public Test
@@ -72,7 +72,6 @@ TEST(ThrowingTestsAreReportedAsFailures)
CHECK_EQUAL(1, results.GetFailureCount());
}
-
#ifndef UNITTEST_MINGW
TEST(CrashingTestsAreReportedAsFailures)
{
@@ -95,6 +94,7 @@ TEST(CrashingTestsAreReportedAsFailures)
CHECK_EQUAL(1, results.GetFailureCount());
}
#endif
+#endif
TEST(TestWithUnspecifiedSuiteGetsDefaultSuite)
{
diff --git a/src/tests/TestTestList.cpp b/src/tests/TestTestList.cpp
index 6c1fba1..fdeba34 100644
--- a/src/tests/TestTestList.cpp
+++ b/src/tests/TestTestList.cpp
@@ -1,4 +1,4 @@
-#include "../UnitTest++.h"
+#include "../../unittestpp.h"
#include "../TestList.h"
using namespace UnitTest;
@@ -6,23 +6,23 @@ using namespace UnitTest;
namespace {
-TEST (TestListIsEmptyByDefault)
+TEST(TestListIsEmptyByDefault)
{
TestList list;
- CHECK (list.GetHead() == 0);
+ CHECK(list.GetHead() == 0);
}
-TEST (AddingTestSetsHeadToTest)
+TEST(AddingTestSetsHeadToTest)
{
Test test("test");
TestList list;
list.Add(&test);
- CHECK (list.GetHead() == &test);
- CHECK (test.next == 0);
+ CHECK(list.GetHead() == &test);
+ CHECK(test.m_nextTest == 0);
}
-TEST (AddingSecondTestAddsItToEndOfList)
+TEST(AddingSecondTestAddsItToEndOfList)
{
Test test1("test1");
Test test2("test2");
@@ -31,20 +31,20 @@ TEST (AddingSecondTestAddsItToEndOfList)
list.Add(&test1);
list.Add(&test2);
- CHECK (list.GetHead() == &test1);
- CHECK (test1.next == &test2);
- CHECK (test2.next == 0);
+ CHECK(list.GetHead() == &test1);
+ CHECK(test1.m_nextTest == &test2);
+ CHECK(test2.m_nextTest == 0);
}
-TEST (ListAdderAddsTestToList)
+TEST(ListAdderAddsTestToList)
{
TestList list;
Test test("");
ListAdder adder(list, &test);
- CHECK (list.GetHead() == &test);
- CHECK (test.next == 0);
+ CHECK(list.GetHead() == &test);
+ CHECK(test.m_nextTest == 0);
}
}
diff --git a/src/tests/TestTestMacros.cpp b/src/tests/TestTestMacros.cpp
index 8bed9dc..b057e4f 100644
--- a/src/tests/TestTestMacros.cpp
+++ b/src/tests/TestTestMacros.cpp
@@ -1,4 +1,4 @@
-#include "../UnitTest++.h"
+#include "../../unittestpp.h"
#include "../TestMacros.h"
#include "../TestList.h"
#include "../TestResults.h"
@@ -8,6 +8,7 @@
#include "ScopedCurrentTest.h"
using namespace UnitTest;
+using namespace std;
namespace {
@@ -19,9 +20,11 @@ TEST_EX(DummyTest, list1)
TEST (TestsAreAddedToTheListThroughMacro)
{
CHECK(list1.GetHead() != 0);
- CHECK(list1.GetHead()->next == 0);
+ CHECK(list1.GetHead()->m_nextTest == 0);
}
+#ifndef UNITTEST_NO_EXCEPTIONS
+
struct ThrowingThingie
{
ThrowingThingie() : dummy(false)
@@ -52,6 +55,8 @@ TEST (ExceptionsInFixtureAreReportedAsHappeningInTheFixture)
CHECK(strstr(reporter.lastFailedMessage, "ThrowingThingie"));
}
+#endif
+
struct DummyFixture
{
int x;
@@ -104,6 +109,8 @@ TEST(TestAddedWithTEST_FIXTURE_EXMacroGetsDefaultSuite)
CHECK_EQUAL ("DefaultSuite", macroTestList2.GetHead()->m_details.suiteName);
}
+#ifndef UNITTEST_NO_EXCEPTIONS
+
struct FixtureCtorThrows
{
FixtureCtorThrows() { throw "exception"; }
@@ -185,6 +192,8 @@ TEST(CorrectlyReportsFixturesWithCtorsThatAssert)
CHECK(strstr(reporter.lastFailedMessage, "assert failure"));
}
+#endif
+
}
// We're really testing if it's possible to use the same suite in two files
diff --git a/src/tests/TestTestResults.cpp b/src/tests/TestTestResults.cpp
index 5bdea72..15fff1e 100644
--- a/src/tests/TestTestResults.cpp
+++ b/src/tests/TestTestResults.cpp
@@ -1,4 +1,4 @@
-#include "../UnitTest++.h"
+#include "../../unittestpp.h"
#include "../TestResults.h"
#include "RecordingReporter.h"
diff --git a/src/tests/TestTestRunner.cpp b/src/tests/TestTestRunner.cpp
index fc89b00..0aeec11 100644
--- a/src/tests/TestTestRunner.cpp
+++ b/src/tests/TestTestRunner.cpp
@@ -1,15 +1,33 @@
-#include "../UnitTest++.h"
+#include "../../unittestpp.h"
#include "RecordingReporter.h"
#include "../ReportAssert.h"
#include "../TestList.h"
#include "../TimeHelpers.h"
#include "../TimeConstraint.h"
+#include "../ReportAssertImpl.h"
using namespace UnitTest;
namespace
{
+struct TestRunnerFixture
+{
+ TestRunnerFixture()
+ : runner(reporter)
+ {
+ s_testRunnerFixtureTestResults = runner.GetTestResults();
+ }
+
+ static TestResults* s_testRunnerFixtureTestResults;
+
+ RecordingReporter reporter;
+ TestList list;
+ TestRunner runner;
+};
+
+TestResults* TestRunnerFixture::s_testRunnerFixtureTestResults = NULL;
+
struct MockTest : public Test
{
MockTest(char const* testName, bool const success_, bool const assert_, int const count_ = 1)
@@ -18,16 +36,19 @@ struct MockTest : public Test
, asserted(assert_)
, count(count_)
{
+ m_isMockTest = true;
}
- virtual void RunImpl(TestResults& testResults_) const
+ virtual void RunImpl() const
{
+ TestResults* testResults = TestRunnerFixture::s_testRunnerFixtureTestResults;
+
for (int i=0; i < count; ++i)
{
if (asserted)
- ReportAssert("desc", "file", 0);
+ Detail::ReportAssertEx(testResults, &m_details, "desc", "file", 0);
else if (!success)
- testResults_.OnTestFailure(m_details, "message");
+ testResults->OnTestFailure(m_details, "message");
}
}
@@ -36,19 +57,6 @@ struct MockTest : public Test
int const count;
};
-
-struct TestRunnerFixture
-{
- TestRunnerFixture()
- : runner(reporter)
- {
- }
-
- RecordingReporter reporter;
- TestList list;
- TestRunner runner;
-};
-
TEST_FIXTURE(TestRunnerFixture, TestStartIsReportedCorrectly)
{
MockTest test("goodtest", true, false);
@@ -73,7 +81,7 @@ class SlowTest : public Test
{
public:
SlowTest() : Test("slow", "somesuite", "filename", 123) {}
- virtual void RunImpl(TestResults&) const
+ virtual void RunImpl() const
{
TimeHelpers::SleepMs(20);
}
@@ -104,7 +112,7 @@ TEST_FIXTURE(TestRunnerFixture, CallsReportFailureOncePerFailingTest)
MockTest test3("test", false, false);
list.Add(&test3);
- CHECK_EQUAL(2, runner.RunTestsIf(list, NULL, True(), 0));
+ CHECK_EQUAL(2, runner.RunTestsIf(list, NULL, True(), 0));
CHECK_EQUAL(2, reporter.testFailedCount);
}
@@ -117,6 +125,13 @@ TEST_FIXTURE(TestRunnerFixture, TestsThatAssertAreReportedAsFailing)
CHECK_EQUAL(1, reporter.testFailedCount);
}
+TEST_FIXTURE(TestRunnerFixture, AssertingTestAbortsAsSoonAsAssertIsHit)
+{
+ MockTest test("test", false, true, 3);
+ list.Add(&test);
+ runner.RunTestsIf(list, NULL, True(), 0);
+ CHECK_EQUAL(1, reporter.summaryFailureCount);
+}
TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfTestCount)
{
@@ -198,7 +213,7 @@ TEST_FIXTURE(TestRunnerFixture, SlowTestWithTimeExemptionPasses)
{
public:
SlowExemptedTest() : Test("slowexempted", "", 0) {}
- virtual void RunImpl(TestResults&) const
+ virtual void RunImpl() const
{
UNITTEST_TIME_CONSTRAINT_EXEMPT();
TimeHelpers::SleepMs(20);
diff --git a/src/tests/TestTestSuite.cpp b/src/tests/TestTestSuite.cpp
index 8353e83..07e51cd 100644
--- a/src/tests/TestTestSuite.cpp
+++ b/src/tests/TestTestSuite.cpp
@@ -1,4 +1,4 @@
-#include "../UnitTest++.h"
+#include "../../unittestpp.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)
diff --git a/src/tests/TestTimeConstraint.cpp b/src/tests/TestTimeConstraint.cpp
index 10adb36..96f880c 100644
--- a/src/tests/TestTimeConstraint.cpp
+++ b/src/tests/TestTimeConstraint.cpp
@@ -1,4 +1,4 @@
-#include "../UnitTest++.h"
+#include "../../unittestpp.h"
#include "../TestResults.h"
#include "../TimeHelpers.h"
#include "RecordingReporter.h"
diff --git a/src/tests/TestTimeConstraintMacro.cpp b/src/tests/TestTimeConstraintMacro.cpp
index 785c6ce..76f15c3 100644
--- a/src/tests/TestTimeConstraintMacro.cpp
+++ b/src/tests/TestTimeConstraintMacro.cpp
@@ -1,65 +1,65 @@
-#include "../UnitTest++.h"
-#include "../TimeHelpers.h"
-
-#include "RecordingReporter.h"
-#include "ScopedCurrentTest.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);
- ScopedCurrentTest scopedResults(testResults);
-
- UNITTEST_TIME_CONSTRAINT(10); testLine = __LINE__;
- UnitTest::TimeHelpers::SleepMs(20);
- }
-
- using namespace std;
-
- CHECK_EQUAL(1, reporter.testFailedCount);
- CHECK(strstr(reporter.lastFailedFile, __FILE__));
- CHECK_EQUAL(testLine, reporter.lastFailedLine);
- CHECK(strstr(reporter.lastFailedTest, "TimeConstraintMacroUsesCorrectInfo"));
-}
-
-TEST(TimeConstraintMacroComparesAgainstPreciseActual)
-{
- int testLine = 0;
- RecordingReporter reporter;
-
- {
- UnitTest::TestResults testResults(&reporter);
- ScopedCurrentTest scopedResults(testResults);
-
- UNITTEST_TIME_CONSTRAINT(1); testLine = __LINE__;
-
- // start a new timer and run until we're as little over the 1 msec
- // threshold as we can achieve; this should guarantee that the "test"
- // runs in some very small amount of time > 1 msec
- UnitTest::Timer myTimer;
- myTimer.Start();
-
- while (myTimer.GetTimeInMs() < 1.001)
- UnitTest::TimeHelpers::SleepMs(0);
- }
-
- using namespace std;
-
- CHECK_EQUAL(1, reporter.testFailedCount);
- CHECK(strstr(reporter.lastFailedFile, __FILE__));
- CHECK_EQUAL(testLine, reporter.lastFailedLine);
- CHECK(strstr(reporter.lastFailedTest, "TimeConstraintMacroComparesAgainstPreciseActual"));
-}
-
-}
+#include "../../unittestpp.h"
+#include "../TimeHelpers.h"
+
+#include "RecordingReporter.h"
+#include "ScopedCurrentTest.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);
+ ScopedCurrentTest scopedResults(testResults);
+
+ UNITTEST_TIME_CONSTRAINT(10); testLine = __LINE__;
+ UnitTest::TimeHelpers::SleepMs(20);
+ }
+
+ using namespace std;
+
+ CHECK_EQUAL(1, reporter.testFailedCount);
+ CHECK(strstr(reporter.lastFailedFile, __FILE__));
+ CHECK_EQUAL(testLine, reporter.lastFailedLine);
+ CHECK(strstr(reporter.lastFailedTest, "TimeConstraintMacroUsesCorrectInfo"));
+}
+
+TEST(TimeConstraintMacroComparesAgainstPreciseActual)
+{
+ int testLine = 0;
+ RecordingReporter reporter;
+
+ {
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ UNITTEST_TIME_CONSTRAINT(1); testLine = __LINE__;
+
+ // start a new timer and run until we're as little over the 1 msec
+ // threshold as we can achieve; this should guarantee that the "test"
+ // runs in some very small amount of time > 1 msec
+ UnitTest::Timer myTimer;
+ myTimer.Start();
+
+ while (myTimer.GetTimeInMs() < 1.001)
+ UnitTest::TimeHelpers::SleepMs(0);
+ }
+
+ using namespace std;
+
+ CHECK_EQUAL(1, reporter.testFailedCount);
+ CHECK(strstr(reporter.lastFailedFile, __FILE__));
+ CHECK_EQUAL(testLine, reporter.lastFailedLine);
+ CHECK(strstr(reporter.lastFailedTest, "TimeConstraintMacroComparesAgainstPreciseActual"));
+}
+
+}
diff --git a/src/tests/TestUnitTest++.cpp b/src/tests/TestUnitTestPP.cpp
similarity index 85%
rename from src/tests/TestUnitTest++.cpp
rename to src/tests/TestUnitTestPP.cpp
index 62c0033..e6a00bf 100644
--- a/src/tests/TestUnitTest++.cpp
+++ b/src/tests/TestUnitTestPP.cpp
@@ -1,9 +1,6 @@
-#include "../UnitTest++.h"
-#include "../ReportAssert.h"
+#include "../../unittestpp.h"
#include "ScopedCurrentTest.h"
-#include
-
// These are sample tests that show the different features of the framework
namespace {
@@ -47,14 +44,7 @@ TEST(ArrayCloseSucceeds)
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);
-}
+#ifndef UNITTEST_NO_EXCEPTIONS
TEST(CheckThrowMacroSucceedsOnCorrectException)
{
@@ -117,6 +107,8 @@ TEST(CheckThrowMacroFailsOnWrongException)
CHECK_EQUAL(1, results.GetFailureCount());
}
+#endif
+
struct SimpleFixture
{
SimpleFixture()
diff --git a/src/tests/TestXmlTestReporter.cpp b/src/tests/TestXmlTestReporter.cpp
index 959a83a..dde5759 100644
--- a/src/tests/TestXmlTestReporter.cpp
+++ b/src/tests/TestXmlTestReporter.cpp
@@ -1,4 +1,7 @@
-#include "../UnitTest++.h"
+#include "../../config.h"
+#ifndef UNITTEST_NO_DEFERRED_REPORTER
+
+#include "../../unittestpp.h"
#include "../XmlTestReporter.h"
#include
@@ -9,7 +12,7 @@ using std::ostringstream;
namespace
{
-#ifdef UNITTEST_USE_CUSTOM_STREAMS
+#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM
// Overload to let MemoryOutStream accept std::string
MemoryOutStream& operator<<(MemoryOutStream& s, const std::string& value)
@@ -70,9 +73,9 @@ TEST_FIXTURE(XmlTestReporterFixture, EmptyReportSummaryFormat)
reporter.ReportSummary(0, 0, 0, 0.1f);
const char *expected =
-""
-""
-"";
+ ""
+ ""
+ "";
CHECK_EQUAL(expected, output.str());
}
@@ -85,10 +88,10 @@ TEST_FIXTURE(XmlTestReporterFixture, SingleSuccessfulTestReportSummaryFormat)
reporter.ReportSummary(1, 0, 0, 0.1f);
const char *expected =
-""
-""
-""
-"";
+ ""
+ ""
+ ""
+ "";
CHECK_EQUAL(expected, output.str());
}
@@ -181,3 +184,5 @@ TEST_FIXTURE(XmlTestReporterFixture, MultipleFailures)
}
}
+
+#endif
diff --git a/src/tests/test-unittestpp_vs2005.vcproj b/src/tests/test-unittestpp_vs2005.vcproj
new file mode 100644
index 0000000..50d9fa3
--- /dev/null
+++ b/src/tests/test-unittestpp_vs2005.vcproj
@@ -0,0 +1,580 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tests/test-unittestpp_vs2008.vcproj b/src/tests/test-unittestpp_vs2008.vcproj
new file mode 100644
index 0000000..e6cfbee
--- /dev/null
+++ b/src/tests/test-unittestpp_vs2008.vcproj
@@ -0,0 +1,569 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/unittestpp_vs2005.vcproj b/src/unittestpp_vs2005.vcproj
new file mode 100644
index 0000000..b69882c
--- /dev/null
+++ b/src/unittestpp_vs2005.vcproj
@@ -0,0 +1,614 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/unittestpp_vs2008.vcproj b/src/unittestpp_vs2008.vcproj
new file mode 100644
index 0000000..b695cab
--- /dev/null
+++ b/src/unittestpp_vs2008.vcproj
@@ -0,0 +1,607 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/unittestpp.h b/unittestpp.h
new file mode 100644
index 0000000..b66b2c4
--- /dev/null
+++ b/unittestpp.h
@@ -0,0 +1,11 @@
+#ifndef UNITTESTPP_H
+#define UNITTESTPP_H
+
+#include "config.h"
+#include "src/TestMacros.h"
+#include "src/CheckMacros.h"
+#include "src/TestRunner.h"
+#include "src/TimeConstraint.h"
+#include "src/ReportAssert.h"
+
+#endif
diff --git a/unittestpp_vs2005.sln b/unittestpp_vs2005.sln
new file mode 100644
index 0000000..3bb7617
--- /dev/null
+++ b/unittestpp_vs2005.sln
@@ -0,0 +1,49 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittestpp_vs2005", "src\unittestpp_vs2005.vcproj", "{64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-unittestpp_vs2005", "src\tests\test-unittestpp_vs2005.vcproj", "{9CCC3439-309E-4E85-B3B8-CE704D385D48}"
+ ProjectSection(ProjectDependencies) = postProject
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6} = {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ win32_dll_vc80_debug|Win32 = win32_dll_vc80_debug|Win32
+ win32_dll_vc80_release|Win32 = win32_dll_vc80_release|Win32
+ win32_static_vc80_md_debug|Win32 = win32_static_vc80_md_debug|Win32
+ win32_static_vc80_md_release|Win32 = win32_static_vc80_md_release|Win32
+ win32_static_vc80_mt_debug|Win32 = win32_static_vc80_mt_debug|Win32
+ win32_static_vc80_mt_release|Win32 = win32_static_vc80_mt_release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc80_debug|Win32.ActiveCfg = win32_dll_vc80_debug|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc80_debug|Win32.Build.0 = win32_dll_vc80_debug|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc80_release|Win32.ActiveCfg = win32_dll_vc80_release|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc80_release|Win32.Build.0 = win32_dll_vc80_release|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_md_debug|Win32.ActiveCfg = win32_static_vc80_md_debug|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_md_debug|Win32.Build.0 = win32_static_vc80_md_debug|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_md_release|Win32.ActiveCfg = win32_static_vc80_md_release|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_md_release|Win32.Build.0 = win32_static_vc80_md_release|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_mt_debug|Win32.ActiveCfg = win32_static_vc80_mt_debug|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_mt_debug|Win32.Build.0 = win32_static_vc80_mt_debug|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_mt_release|Win32.ActiveCfg = win32_static_vc80_mt_release|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc80_mt_release|Win32.Build.0 = win32_static_vc80_mt_release|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc80_debug|Win32.ActiveCfg = win32_dll_vc80_debug|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc80_debug|Win32.Build.0 = win32_dll_vc80_debug|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc80_release|Win32.ActiveCfg = win32_dll_vc80_release|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc80_release|Win32.Build.0 = win32_dll_vc80_release|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_md_debug|Win32.ActiveCfg = win32_static_vc80_md_debug|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_md_debug|Win32.Build.0 = win32_static_vc80_md_debug|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_md_release|Win32.ActiveCfg = win32_static_vc80_md_release|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_md_release|Win32.Build.0 = win32_static_vc80_md_release|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_mt_debug|Win32.ActiveCfg = win32_static_vc80_mt_debug|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_mt_debug|Win32.Build.0 = win32_static_vc80_mt_debug|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_mt_release|Win32.ActiveCfg = win32_static_vc80_mt_release|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc80_mt_release|Win32.Build.0 = win32_static_vc80_mt_release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/unittestpp_vs2008.sln b/unittestpp_vs2008.sln
new file mode 100644
index 0000000..f7004a4
--- /dev/null
+++ b/unittestpp_vs2008.sln
@@ -0,0 +1,49 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittestpp_vs2008", "src\unittestpp_vs2008.vcproj", "{64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-unittestpp_vs2008", "src\tests\test-unittestpp_vs2008.vcproj", "{9CCC3439-309E-4E85-B3B8-CE704D385D48}"
+ ProjectSection(ProjectDependencies) = postProject
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6} = {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ win32_dll_vc90_debug|Win32 = win32_dll_vc90_debug|Win32
+ win32_dll_vc90_release|Win32 = win32_dll_vc90_release|Win32
+ win32_static_vc90_md_debug|Win32 = win32_static_vc90_md_debug|Win32
+ win32_static_vc90_md_release|Win32 = win32_static_vc90_md_release|Win32
+ win32_static_vc90_mt_debug|Win32 = win32_static_vc90_mt_debug|Win32
+ win32_static_vc90_mt_release|Win32 = win32_static_vc90_mt_release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc90_debug|Win32.ActiveCfg = win32_dll_vc90_debug|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc90_debug|Win32.Build.0 = win32_dll_vc90_debug|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc90_release|Win32.ActiveCfg = win32_dll_vc90_release|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_dll_vc90_release|Win32.Build.0 = win32_dll_vc90_release|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_md_debug|Win32.ActiveCfg = win32_static_vc90_md_debug|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_md_debug|Win32.Build.0 = win32_static_vc90_md_debug|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_md_release|Win32.ActiveCfg = win32_static_vc90_md_release|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_md_release|Win32.Build.0 = win32_static_vc90_md_release|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_mt_debug|Win32.ActiveCfg = win32_static_vc90_mt_debug|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_mt_debug|Win32.Build.0 = win32_static_vc90_mt_debug|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_mt_release|Win32.ActiveCfg = win32_static_vc90_mt_release|Win32
+ {64A4FEFE-0461-4E95-8CC1-91EF5F57DBC6}.win32_static_vc90_mt_release|Win32.Build.0 = win32_static_vc90_mt_release|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc90_debug|Win32.ActiveCfg = win32_dll_vc90_debug|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc90_debug|Win32.Build.0 = win32_dll_vc90_debug|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc90_release|Win32.ActiveCfg = win32_dll_vc90_release|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_dll_vc90_release|Win32.Build.0 = win32_dll_vc90_release|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_md_debug|Win32.ActiveCfg = win32_static_vc90_md_debug|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_md_debug|Win32.Build.0 = win32_static_vc90_md_debug|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_md_release|Win32.ActiveCfg = win32_static_vc90_md_release|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_md_release|Win32.Build.0 = win32_static_vc90_md_release|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_mt_debug|Win32.ActiveCfg = win32_static_vc90_mt_debug|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_mt_debug|Win32.Build.0 = win32_static_vc90_mt_debug|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_mt_release|Win32.ActiveCfg = win32_static_vc90_mt_release|Win32
+ {9CCC3439-309E-4E85-B3B8-CE704D385D48}.win32_static_vc90_mt_release|Win32.Build.0 = win32_static_vc90_mt_release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal