summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/unittest-cpp/tests
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-05-27 15:00:06 +0200
committer Miodrag Milanovic <mmicko@gmail.com>2015-05-27 15:00:06 +0200
commitee4adf600bdd3aa60cc0e92a39f2111be0a90bc6 (patch)
tree5ecb86b72eef1c19ad3ab6c7ba8d8b2a964e0cb9 /3rdparty/unittest-cpp/tests
parent55fa9840f263361efc73126c3f41be606fea7168 (diff)
Added library for supporting unit tests (nw)
Diffstat (limited to '3rdparty/unittest-cpp/tests')
-rw-r--r--3rdparty/unittest-cpp/tests/Main.cpp6
-rw-r--r--3rdparty/unittest-cpp/tests/RecordingReporter.h98
-rw-r--r--3rdparty/unittest-cpp/tests/ScopedCurrentTest.h37
-rw-r--r--3rdparty/unittest-cpp/tests/TestAssertHandler.cpp136
-rw-r--r--3rdparty/unittest-cpp/tests/TestCheckMacros.cpp518
-rw-r--r--3rdparty/unittest-cpp/tests/TestChecks.cpp318
-rw-r--r--3rdparty/unittest-cpp/tests/TestCompositeTestReporter.cpp176
-rw-r--r--3rdparty/unittest-cpp/tests/TestCurrentTest.cpp38
-rw-r--r--3rdparty/unittest-cpp/tests/TestDeferredTestReporter.cpp122
-rw-r--r--3rdparty/unittest-cpp/tests/TestExceptions.cpp563
-rw-r--r--3rdparty/unittest-cpp/tests/TestMemoryOutStream.cpp336
-rw-r--r--3rdparty/unittest-cpp/tests/TestTest.cpp133
-rw-r--r--3rdparty/unittest-cpp/tests/TestTestList.cpp50
-rw-r--r--3rdparty/unittest-cpp/tests/TestTestMacros.cpp221
-rw-r--r--3rdparty/unittest-cpp/tests/TestTestResults.cpp111
-rw-r--r--3rdparty/unittest-cpp/tests/TestTestRunner.cpp330
-rw-r--r--3rdparty/unittest-cpp/tests/TestTestSuite.cpp12
-rw-r--r--3rdparty/unittest-cpp/tests/TestTimeConstraint.cpp69
-rw-r--r--3rdparty/unittest-cpp/tests/TestTimeConstraintMacro.cpp88
-rw-r--r--3rdparty/unittest-cpp/tests/TestUnitTestPP.cpp148
-rw-r--r--3rdparty/unittest-cpp/tests/TestXmlTestReporter.cpp188
21 files changed, 3698 insertions, 0 deletions
diff --git a/3rdparty/unittest-cpp/tests/Main.cpp b/3rdparty/unittest-cpp/tests/Main.cpp
new file mode 100644
index 00000000000..ae9cc5494a1
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/Main.cpp
@@ -0,0 +1,6 @@
+#include "UnitTest++/UnitTestPP.h"
+
+int main(int, char const *[])
+{
+ return UnitTest::RunAllTests();
+}
diff --git a/3rdparty/unittest-cpp/tests/RecordingReporter.h b/3rdparty/unittest-cpp/tests/RecordingReporter.h
new file mode 100644
index 00000000000..ea899a238ea
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/RecordingReporter.h
@@ -0,0 +1,98 @@
+#ifndef UNITTEST_RECORDINGREPORTER_H
+#define UNITTEST_RECORDINGREPORTER_H
+
+#include "UnitTest++/TestReporter.h"
+#include <cstring>
+
+#include "UnitTest++/TestDetails.h"
+
+struct RecordingReporter : public UnitTest::TestReporter
+{
+private:
+ enum { kMaxStringLength = 256 };
+
+public:
+ RecordingReporter()
+ : testRunCount(0)
+ , testFailedCount(0)
+ , lastFailedLine(0)
+ , testFinishedCount(0)
+ , lastFinishedTestTime(0)
+ , summaryTotalTestCount(0)
+ , summaryFailedTestCount(0)
+ , summaryFailureCount(0)
+ , summarySecondsElapsed(0)
+ {
+ lastStartedSuite[0] = '\0';
+ lastStartedTest[0] = '\0';
+ lastFailedFile[0] = '\0';
+ lastFailedSuite[0] = '\0';
+ lastFailedTest[0] = '\0';
+ lastFailedMessage[0] = '\0';
+ lastFinishedSuite[0] = '\0';
+ lastFinishedTest[0] = '\0';
+ }
+
+ virtual void ReportTestStart(UnitTest::TestDetails const& test)
+ {
+ using namespace std;
+
+ ++testRunCount;
+ strcpy(lastStartedSuite, test.suiteName);
+ strcpy(lastStartedTest, test.testName);
+ }
+
+ virtual void ReportFailure(UnitTest::TestDetails const& test, char const* failure)
+ {
+ using namespace std;
+
+ ++testFailedCount;
+ strcpy(lastFailedFile, test.filename);
+ lastFailedLine = test.lineNumber;
+ strcpy(lastFailedSuite, test.suiteName);
+ strcpy(lastFailedTest, test.testName);
+ strcpy(lastFailedMessage, failure);
+ }
+
+ virtual void ReportTestFinish(UnitTest::TestDetails const& test, float testDuration)
+ {
+ using namespace std;
+
+ ++testFinishedCount;
+ strcpy(lastFinishedSuite, test.suiteName);
+ strcpy(lastFinishedTest, test.testName);
+ lastFinishedTestTime = testDuration;
+ }
+
+ virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed)
+ {
+ summaryTotalTestCount = totalTestCount;
+ summaryFailedTestCount = failedTestCount;
+ summaryFailureCount = failureCount;
+ summarySecondsElapsed = secondsElapsed;
+ }
+
+ int testRunCount;
+ char lastStartedSuite[kMaxStringLength];
+ char lastStartedTest[kMaxStringLength];
+
+ int testFailedCount;
+ char lastFailedFile[kMaxStringLength];
+ int lastFailedLine;
+ char lastFailedSuite[kMaxStringLength];
+ char lastFailedTest[kMaxStringLength];
+ char lastFailedMessage[kMaxStringLength];
+
+ int testFinishedCount;
+ char lastFinishedSuite[kMaxStringLength];
+ char lastFinishedTest[kMaxStringLength];
+ float lastFinishedTestTime;
+
+ int summaryTotalTestCount;
+ int summaryFailedTestCount;
+ int summaryFailureCount;
+ float summarySecondsElapsed;
+};
+
+
+#endif
diff --git a/3rdparty/unittest-cpp/tests/ScopedCurrentTest.h b/3rdparty/unittest-cpp/tests/ScopedCurrentTest.h
new file mode 100644
index 00000000000..60b1a8e0c1c
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/ScopedCurrentTest.h
@@ -0,0 +1,37 @@
+#ifndef UNITTEST_SCOPEDCURRENTTEST_H
+#define UNITTEST_SCOPEDCURRENTTEST_H
+
+#include "UnitTest++/CurrentTest.h"
+#include <cstddef>
+
+class ScopedCurrentTest
+{
+public:
+ ScopedCurrentTest()
+ : m_oldTestResults(UnitTest::CurrentTest::Results())
+ , m_oldTestDetails(UnitTest::CurrentTest::Details())
+ {
+ }
+
+ explicit ScopedCurrentTest(UnitTest::TestResults& newResults, const UnitTest::TestDetails* newDetails = NULL)
+ : m_oldTestResults(UnitTest::CurrentTest::Results())
+ , m_oldTestDetails(UnitTest::CurrentTest::Details())
+ {
+ UnitTest::CurrentTest::Results() = &newResults;
+
+ if (newDetails != NULL)
+ UnitTest::CurrentTest::Details() = newDetails;
+ }
+
+ ~ScopedCurrentTest()
+ {
+ UnitTest::CurrentTest::Results() = m_oldTestResults;
+ UnitTest::CurrentTest::Details() = m_oldTestDetails;
+ }
+
+private:
+ UnitTest::TestResults* m_oldTestResults;
+ const UnitTest::TestDetails* m_oldTestDetails;
+};
+
+#endif
diff --git a/3rdparty/unittest-cpp/tests/TestAssertHandler.cpp b/3rdparty/unittest-cpp/tests/TestAssertHandler.cpp
new file mode 100644
index 00000000000..c9286f38c03
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestAssertHandler.cpp
@@ -0,0 +1,136 @@
+#include "UnitTest++/Config.h"
+#include "UnitTest++/UnitTestPP.h"
+
+#include "UnitTest++/ReportAssert.h"
+#include "UnitTest++/ReportAssertImpl.h"
+#include "UnitTest++/AssertException.h"
+
+#include "RecordingReporter.h"
+#include <csetjmp>
+
+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
+ {
+ TestResults testResults;
+ TestDetails testDetails("", "", "", 0);
+ Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0);
+ }
+ catch(AssertException const&)
+ {
+ caught = true;
+ }
+
+ CHECK(true == caught);
+}
+
+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
+ {
+ Detail::ReportAssertEx(&testResults, &testDetails, description, filename, lineNumber);
+ }
+ catch(AssertException const&)
+ {
+ }
+
+ 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/3rdparty/unittest-cpp/tests/TestCheckMacros.cpp b/3rdparty/unittest-cpp/tests/TestCheckMacros.cpp
new file mode 100644
index 00000000000..45ea0e97905
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestCheckMacros.cpp
@@ -0,0 +1,518 @@
+#include "UnitTest++/UnitTestPP.h"
+#include "UnitTest++/CurrentTest.h"
+#include "RecordingReporter.h"
+#include "ScopedCurrentTest.h"
+
+using namespace std;
+
+namespace {
+
+TEST(CheckSucceedsOnTrue)
+{
+ bool failure = true;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK(true);
+
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(!failure);
+}
+
+TEST(CheckFailsOnFalse)
+{
+ bool failure = false;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK(false);
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(failure);
+}
+
+TEST(FailureReportsCorrectTestName)
+{
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK(false);
+ }
+
+ CHECK_EQUAL(m_details.testName, reporter.lastFailedTest);
+}
+
+TEST(CheckFailureIncludesCheckContents)
+{
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+ const bool yaddayadda = false;
+ CHECK(yaddayadda);
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "yaddayadda"));
+}
+
+TEST(CheckEqualSucceedsOnEqual)
+{
+ bool failure = true;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK_EQUAL(1, 1);
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(!failure);
+}
+
+TEST(CheckEqualFailsOnNotEqual)
+{
+ bool failure = false;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK_EQUAL(1, 2);
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(failure);
+}
+
+TEST(CheckEqualFailureContainsCorrectDetails)
+{
+ int line = 0;
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+
+ CHECK_EQUAL(1, 123); line = __LINE__;
+ }
+
+ CHECK_EQUAL("testName", reporter.lastFailedTest);
+ CHECK_EQUAL("suiteName", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+}
+
+int g_sideEffect = 0;
+int FunctionWithSideEffects()
+{
+ ++g_sideEffect;
+ return 1;
+}
+
+TEST(CheckEqualDoesNotHaveSideEffectsWhenPassing)
+{
+ g_sideEffect = 0;
+ {
+ UnitTest::TestResults testResults;
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK_EQUAL(1, FunctionWithSideEffects());
+ }
+ CHECK_EQUAL(1, g_sideEffect);
+}
+
+TEST(CheckEqualDoesNotHaveSideEffectsWhenFailing)
+{
+ g_sideEffect = 0;
+ {
+ UnitTest::TestResults testResults;
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK_EQUAL(2, FunctionWithSideEffects());
+ }
+ CHECK_EQUAL(1, g_sideEffect);
+}
+
+
+TEST(CheckCloseSucceedsOnEqual)
+{
+ bool failure = true;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK_CLOSE (1.0f, 1.001f, 0.01f);
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(!failure);
+}
+
+TEST(CheckCloseFailsOnNotEqual)
+{
+ bool failure = false;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK_CLOSE (1.0f, 1.1f, 0.01f);
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(failure);
+}
+
+TEST(CheckCloseFailureContainsCorrectDetails)
+{
+ int line = 0;
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ UnitTest::TestDetails testDetails("test", "suite", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+
+ CHECK_CLOSE (1.0f, 1.1f, 0.01f); line = __LINE__;
+ }
+
+ CHECK_EQUAL("test", reporter.lastFailedTest);
+ CHECK_EQUAL("suite", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+}
+
+TEST(CheckCloseDoesNotHaveSideEffectsWhenPassing)
+{
+ g_sideEffect = 0;
+ {
+ UnitTest::TestResults testResults;
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK_CLOSE (1, FunctionWithSideEffects(), 0.1f);
+ }
+ CHECK_EQUAL(1, g_sideEffect);
+}
+
+TEST(CheckCloseDoesNotHaveSideEffectsWhenFailing)
+{
+ g_sideEffect = 0;
+ {
+ UnitTest::TestResults testResults;
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK_CLOSE (2, FunctionWithSideEffects(), 0.1f);
+ }
+ CHECK_EQUAL(1, g_sideEffect);
+}
+
+TEST(CheckArrayCloseSucceedsOnEqual)
+{
+ bool failure = true;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+ const float data[4] = { 0, 1, 2, 3 };
+ CHECK_ARRAY_CLOSE (data, data, 4, 0.01f);
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(!failure);
+}
+
+TEST(CheckArrayCloseFailsOnNotEqual)
+{
+ bool failure = false;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ int const data1[4] = { 0, 1, 2, 3 };
+ int const data2[4] = { 0, 1, 3, 3 };
+ CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f);
+
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(failure);
+}
+
+TEST(CheckArrayCloseFailureIncludesCheckExpectedAndActual)
+{
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ int const data1[4] = { 0, 1, 2, 3 };
+ int const data2[4] = { 0, 1, 3, 3 };
+ CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f);
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]"));
+ CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]"));
+}
+
+TEST(CheckArrayCloseFailureContainsCorrectDetails)
+{
+ int line = 0;
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+
+ int const data1[4] = { 0, 1, 2, 3 };
+ int const data2[4] = { 0, 1, 3, 3 };
+ CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f); line = __LINE__;
+ }
+
+ CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest);
+ CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+}
+
+TEST(CheckArrayCloseFailureIncludesTolerance)
+{
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ float const data1[4] = { 0, 1, 2, 3 };
+ float const data2[4] = { 0, 1, 3, 3 };
+ CHECK_ARRAY_CLOSE (data1, data2, 4, 0.01f);
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "0.01"));
+}
+
+TEST(CheckArrayEqualSuceedsOnEqual)
+{
+ bool failure = true;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ const float data[4] = { 0, 1, 2, 3 };
+ CHECK_ARRAY_EQUAL (data, data, 4);
+
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(!failure);
+}
+
+TEST(CheckArrayEqualFailsOnNotEqual)
+{
+ bool failure = false;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ int const data1[4] = { 0, 1, 2, 3 };
+ int const data2[4] = { 0, 1, 3, 3 };
+ CHECK_ARRAY_EQUAL (data1, data2, 4);
+
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(failure);
+}
+
+TEST(CheckArrayEqualFailureIncludesCheckExpectedAndActual)
+{
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ int const data1[4] = { 0, 1, 2, 3 };
+ int const data2[4] = { 0, 1, 3, 3 };
+ CHECK_ARRAY_EQUAL (data1, data2, 4);
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]"));
+ CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]"));
+}
+
+TEST(CheckArrayEqualFailureContainsCorrectInfo)
+{
+ int line = 0;
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ int const data1[4] = { 0, 1, 2, 3 };
+ int const data2[4] = { 0, 1, 3, 3 };
+ CHECK_ARRAY_EQUAL (data1, data2, 4); line = __LINE__;
+ }
+
+ CHECK_EQUAL("CheckArrayEqualFailureContainsCorrectInfo", reporter.lastFailedTest);
+ CHECK_EQUAL(__FILE__, reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+}
+
+float const* FunctionWithSideEffects2()
+{
+ ++g_sideEffect;
+ static float const data[] = {1,2,3,4};
+ return data;
+}
+
+TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenPassing)
+{
+ g_sideEffect = 0;
+ {
+ UnitTest::TestResults testResults;
+ ScopedCurrentTest scopedResults(testResults);
+
+ const float data[] = { 0, 1, 2, 3 };
+ CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f);
+ }
+ CHECK_EQUAL(1, g_sideEffect);
+}
+
+TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenFailing)
+{
+ g_sideEffect = 0;
+ {
+ UnitTest::TestResults testResults;
+ ScopedCurrentTest scopedResults(testResults);
+
+ const float data[] = { 0, 1, 3, 3 };
+ CHECK_ARRAY_CLOSE (data, FunctionWithSideEffects2(), 4, 0.01f);
+ }
+
+ CHECK_EQUAL(1, g_sideEffect);
+}
+
+TEST(CheckArray2DCloseSucceedsOnEqual)
+{
+ bool failure = true;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ const float data[2][2] = { {0, 1}, {2, 3} };
+ CHECK_ARRAY2D_CLOSE (data, data, 2, 2, 0.01f);
+
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(!failure);
+}
+
+TEST(CheckArray2DCloseFailsOnNotEqual)
+{
+ bool failure = false;
+ {
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ int const data1[2][2] = { {0, 1}, {2, 3} };
+ int const data2[2][2] = { {0, 1}, {3, 3} };
+ CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f);
+
+ failure = (testResults.GetFailureCount() > 0);
+ }
+
+ CHECK(failure);
+}
+
+TEST(CheckArray2DCloseFailureIncludesCheckExpectedAndActual)
+{
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ int const data1[2][2] = { {0, 1}, {2, 3} };
+ int const data2[2][2] = { {0, 1}, {3, 3} };
+
+ CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f);
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "xpected [ [ 0 1 ] [ 2 3 ] ]"));
+ CHECK(strstr(reporter.lastFailedMessage, "was [ [ 0 1 ] [ 3 3 ] ]"));
+}
+
+TEST(CheckArray2DCloseFailureContainsCorrectDetails)
+{
+ int line = 0;
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+
+ int const data1[2][2] = { {0, 1}, {2, 3} };
+ int const data2[2][2] = { {0, 1}, {3, 3} };
+ CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f); line = __LINE__;
+ }
+
+ CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest);
+ CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+}
+
+TEST(CheckArray2DCloseFailureIncludesTolerance)
+{
+ RecordingReporter reporter;
+ {
+ UnitTest::TestResults testResults(&reporter);
+ ScopedCurrentTest scopedResults(testResults);
+
+ float const data1[2][2] = { {0, 1}, {2, 3} };
+ float const data2[2][2] = { {0, 1}, {3, 3} };
+ CHECK_ARRAY2D_CLOSE (data1, data2, 2, 2, 0.01f);
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "0.01"));
+}
+
+float const* const* FunctionWithSideEffects3()
+{
+ ++g_sideEffect;
+ static float const data1[] = {0,1};
+ static float const data2[] = {2,3};
+ static const float* const data[] = {data1, data2};
+ return data;
+}
+
+TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenPassing)
+{
+ g_sideEffect = 0;
+ {
+ UnitTest::TestResults testResults;
+ ScopedCurrentTest scopedResults(testResults);
+
+ const float data[2][2] = { {0, 1}, {2, 3} };
+ CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f);
+ }
+ CHECK_EQUAL(1, g_sideEffect);
+}
+
+TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenFailing)
+{
+ g_sideEffect = 0;
+ {
+ UnitTest::TestResults testResults;
+ ScopedCurrentTest scopedResults(testResults);
+
+ const float data[2][2] = { {0, 1}, {3, 3} };
+ CHECK_ARRAY2D_CLOSE (data, FunctionWithSideEffects3(), 2, 2, 0.01f);
+ }
+ CHECK_EQUAL(1, g_sideEffect);
+}
+
+}
diff --git a/3rdparty/unittest-cpp/tests/TestChecks.cpp b/3rdparty/unittest-cpp/tests/TestChecks.cpp
new file mode 100644
index 00000000000..9554b3151ea
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestChecks.cpp
@@ -0,0 +1,318 @@
+#include "UnitTest++/UnitTestPP.h"
+#include "RecordingReporter.h"
+
+#include <cstring>
+
+using namespace UnitTest;
+
+
+namespace {
+
+
+TEST(CheckEqualWithUnsignedLong)
+{
+ TestResults results;
+ unsigned long something = 2;
+ CHECK_EQUAL(something, something);
+}
+
+TEST(CheckEqualsWithStringsFailsOnDifferentStrings)
+{
+ char txt1[] = "Hello";
+ char txt2[] = "Hallo";
+ TestResults results;
+ CheckEqual(results, txt1, txt2, TestDetails("", "", "", 0));
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+
+char txt1[] = "Hello"; // non-const on purpose so no folding of duplicate data
+char txt2[] = "Hello";
+
+TEST(CheckEqualsWithStringsWorksOnContentsNonConstNonConst)
+{
+ char const* const p1 = txt1;
+ char const* const p2 = txt2;
+ TestResults results;
+ CheckEqual(results, p1, p2, TestDetails("", "", "", 0));
+ CHECK_EQUAL(0, results.GetFailureCount());
+}
+
+TEST(CheckEqualsWithStringsWorksOnContentsConstConst)
+{
+ char* const p1 = txt1;
+ char* const p2 = txt2;
+ TestResults results;
+ CheckEqual(results, p1, p2, TestDetails("", "", "", 0));
+ CHECK_EQUAL(0, results.GetFailureCount());
+}
+
+TEST(CheckEqualsWithStringsWorksOnContentsNonConstConst)
+{
+ char* const p1 = txt1;
+ char const* const p2 = txt2;
+ TestResults results;
+ CheckEqual(results, p1, p2, TestDetails("", "", "", 0));
+ CHECK_EQUAL(0, results.GetFailureCount());
+}
+
+TEST(CheckEqualsWithStringsWorksOnContentsConstNonConst)
+{
+ char const* const p1 = txt1;
+ char* const p2 = txt2;
+ TestResults results;
+ CheckEqual(results, p1, p2, TestDetails("", "", "", 0));
+ CHECK_EQUAL(0, results.GetFailureCount());
+}
+
+TEST(CheckEqualsWithStringsWorksOnContentsWithALiteral)
+{
+ char const* const p1 = txt1;
+ TestResults results;
+ CheckEqual(results, "Hello", p1, TestDetails("", "", "", 0));
+ CHECK_EQUAL(0, results.GetFailureCount());
+}
+
+TEST(CheckEqualsWithStringsWorksOnNullExpected)
+{
+ char const* const expected = "hi";
+ char const* const actual = NULL;
+ TestResults results;
+ CheckEqual(results, expected, actual, TestDetails("", "", "", 0));
+ CHECK_EQUAL (1, results.GetFailureCount());
+}
+
+TEST(CheckEqualsWithStringsWorksOnNullActual)
+{
+ char const* const expected = NULL;
+ char const* const actual = "hi";
+ TestResults results;
+ CheckEqual(results, expected, actual, TestDetails("", "", "", 0));
+ CHECK_EQUAL (1, results.GetFailureCount());
+}
+
+TEST(CheckEqualsWithStringsWorksOnNullExpectedAndActual)
+{
+ char const* const expected = NULL;
+ char const* const actual = NULL;
+ TestResults results;
+ CheckEqual(results, expected, actual, TestDetails("", "", "", 0));
+ CHECK_EQUAL (0, results.GetFailureCount());
+}
+
+TEST(CheckEqualFailureIncludesCheckExpectedAndActual)
+{
+ RecordingReporter reporter;
+ TestResults results(&reporter);
+ const int something = 2;
+ CheckEqual(results, 1, something, TestDetails("", "", "", 0));
+
+ using namespace std;
+ CHECK(strstr(reporter.lastFailedMessage, "xpected 1"));
+ CHECK(strstr(reporter.lastFailedMessage, "was 2"));
+}
+
+TEST(CheckEqualFailureIncludesDetails)
+{
+ RecordingReporter reporter;
+ TestResults results(&reporter);
+ TestDetails const details("mytest", "mysuite", "file.h", 101);
+
+ CheckEqual(results, 1, 2, details);
+
+ CHECK_EQUAL("mytest", reporter.lastFailedTest);
+ CHECK_EQUAL("mysuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("file.h", reporter.lastFailedFile);
+ CHECK_EQUAL(101, reporter.lastFailedLine);
+}
+
+TEST(CheckCloseTrue)
+{
+ TestResults results;
+ CheckClose(results, 3.001f, 3.0f, 0.1f, TestDetails("", "", "", 0));
+ CHECK_EQUAL(0, results.GetFailureCount());
+}
+
+TEST(CheckCloseFalse)
+{
+ TestResults results;
+ CheckClose(results, 3.12f, 3.0f, 0.1f, TestDetails("", "", "", 0));
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+
+TEST(CheckCloseWithZeroEpsilonWorksForSameNumber)
+{
+ TestResults results;
+ CheckClose(results, 0.1f, 0.1f, 0, TestDetails("", "", "", 0));
+ CHECK_EQUAL(0, results.GetFailureCount());
+}
+
+TEST(CheckCloseWithNaNFails)
+{
+ const unsigned int bitpattern = 0xFFFFFFFF;
+ float nan;
+ UNIITEST_NS_QUAL_STD(memcpy)(&nan, &bitpattern, sizeof(bitpattern));
+
+ TestResults results;
+ CheckClose(results, 3.0f, nan, 0.1f, TestDetails("", "", "", 0));
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+
+TEST(CheckCloseWithNaNAgainstItselfFails)
+{
+ const unsigned int bitpattern = 0xFFFFFFFF;
+ float nan;
+ UNIITEST_NS_QUAL_STD(memcpy)(&nan, &bitpattern, sizeof(bitpattern));
+
+ TestResults results;
+ CheckClose(results, nan, nan, 0.1f, TestDetails("", "", "", 0));
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+
+TEST(CheckCloseFailureIncludesCheckExpectedAndActual)
+{
+ RecordingReporter reporter;
+ TestResults results(&reporter);
+ const float expected = 0.9f;
+ const float actual = 1.1f;
+ CheckClose(results, expected, actual, 0.01f, TestDetails("", "", "", 0));
+
+ using namespace std;
+ CHECK(strstr(reporter.lastFailedMessage, "xpected 0.9"));
+ CHECK(strstr(reporter.lastFailedMessage, "was 1.1"));
+}
+
+TEST(CheckCloseFailureIncludesTolerance)
+{
+ RecordingReporter reporter;
+ TestResults results(&reporter);
+ CheckClose(results, 2, 3, 0.01f, TestDetails("", "", "", 0));
+
+ using namespace std;
+ CHECK(strstr(reporter.lastFailedMessage, "0.01"));
+}
+
+TEST(CheckCloseFailureIncludesDetails)
+{
+ RecordingReporter reporter;
+ TestResults results(&reporter);
+ TestDetails const details("mytest", "mysuite", "header.h", 10);
+
+ CheckClose(results, 2, 3, 0.01f, details);
+
+ CHECK_EQUAL("mytest", reporter.lastFailedTest);
+ CHECK_EQUAL("mysuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("header.h", reporter.lastFailedFile);
+ CHECK_EQUAL(10, reporter.lastFailedLine);
+}
+
+
+TEST(CheckArrayEqualTrue)
+{
+ TestResults results;
+
+ int const array[3] = { 1, 2, 3 };
+ CheckArrayEqual(results, array, array, 3, TestDetails("", "", "", 0));
+ CHECK_EQUAL(0, results.GetFailureCount());
+}
+
+TEST(CheckArrayEqualFalse)
+{
+ TestResults results;
+
+ int const array1[3] = { 1, 2, 3 };
+ int const array2[3] = { 1, 2, 2 };
+ CheckArrayEqual(results, array1, array2, 3, TestDetails("", "", "", 0));
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+
+TEST(CheckArrayCloseTrue)
+{
+ TestResults results;
+
+ float const array1[3] = { 1.0f, 1.5f, 2.0f };
+ float const array2[3] = { 1.01f, 1.51f, 2.01f };
+ CheckArrayClose(results, array1, array2, 3, 0.02f, TestDetails("", "", "", 0));
+ CHECK_EQUAL(0, results.GetFailureCount());
+}
+
+TEST(CheckArrayCloseFalse)
+{
+ TestResults results;
+
+ float const array1[3] = { 1.0f, 1.5f, 2.0f };
+ float const array2[3] = { 1.01f, 1.51f, 2.01f };
+ CheckArrayClose(results, array1, array2, 3, 0.001f, TestDetails("", "", "", 0));
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+
+TEST(CheckArrayCloseFailureIncludesDetails)
+{
+ RecordingReporter reporter;
+ TestResults results(&reporter);
+ TestDetails const details("arrayCloseTest", "arrayCloseSuite", "file", 1337);
+
+ float const array1[3] = { 1.0f, 1.5f, 2.0f };
+ float const array2[3] = { 1.01f, 1.51f, 2.01f };
+ CheckArrayClose(results, array1, array2, 3, 0.001f, details);
+
+ CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest);
+ CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("file", reporter.lastFailedFile);
+ CHECK_EQUAL(1337, reporter.lastFailedLine);
+}
+
+
+TEST(CheckArray2DCloseTrue)
+{
+ TestResults results;
+
+ float const array1[3][3] = { { 1.0f, 1.5f, 2.0f },
+ { 2.0f, 2.5f, 3.0f },
+ { 3.0f, 3.5f, 4.0f } };
+ float const array2[3][3] = { { 1.01f, 1.51f, 2.01f },
+ { 2.01f, 2.51f, 3.01f },
+ { 3.01f, 3.51f, 4.01f } };
+ CheckArray2DClose(results, array1, array2, 3, 3, 0.02f, TestDetails("", "", "", 0));
+ CHECK_EQUAL(0, results.GetFailureCount());
+}
+
+TEST(CheckArray2DCloseFalse)
+{
+ TestResults results;
+
+ float const array1[3][3] = { { 1.0f, 1.5f, 2.0f },
+ { 2.0f, 2.5f, 3.0f },
+ { 3.0f, 3.5f, 4.0f } };
+ float const array2[3][3] = { { 1.01f, 1.51f, 2.01f },
+ { 2.01f, 2.51f, 3.01f },
+ { 3.01f, 3.51f, 4.01f } };
+ CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, TestDetails("", "", "", 0));
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+
+TEST(CheckCloseWithDoublesSucceeds)
+{
+ CHECK_CLOSE(0.5, 0.5, 0.0001);
+}
+
+TEST(CheckArray2DCloseFailureIncludesDetails)
+{
+ RecordingReporter reporter;
+ TestResults results(&reporter);
+ TestDetails const details("array2DCloseTest", "array2DCloseSuite", "file", 1234);
+
+ float const array1[3][3] = { { 1.0f, 1.5f, 2.0f },
+ { 2.0f, 2.5f, 3.0f },
+ { 3.0f, 3.5f, 4.0f } };
+ float const array2[3][3] = { { 1.01f, 1.51f, 2.01f },
+ { 2.01f, 2.51f, 3.01f },
+ { 3.01f, 3.51f, 4.01f } };
+ CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, details);
+
+ CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest);
+ CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("file", reporter.lastFailedFile);
+ CHECK_EQUAL(1234, reporter.lastFailedLine);
+}
+
+}
diff --git a/3rdparty/unittest-cpp/tests/TestCompositeTestReporter.cpp b/3rdparty/unittest-cpp/tests/TestCompositeTestReporter.cpp
new file mode 100644
index 00000000000..9440a9ec17d
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestCompositeTestReporter.cpp
@@ -0,0 +1,176 @@
+#include "UnitTest++/UnitTestPP.h"
+#include "UnitTest++/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/3rdparty/unittest-cpp/tests/TestCurrentTest.cpp b/3rdparty/unittest-cpp/tests/TestCurrentTest.cpp
new file mode 100644
index 00000000000..7de1a7270e0
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestCurrentTest.cpp
@@ -0,0 +1,38 @@
+#include "UnitTest++/UnitTestPP.h"
+#include "UnitTest++/CurrentTest.h"
+#include "ScopedCurrentTest.h"
+
+namespace
+{
+
+TEST(CanSetandGetDetails)
+{
+ bool ok = false;
+ {
+ ScopedCurrentTest scopedTest;
+
+ const UnitTest::TestDetails* details = reinterpret_cast< const UnitTest::TestDetails* >(12345);
+ UnitTest::CurrentTest::Details() = details;
+
+ ok = (UnitTest::CurrentTest::Details() == details);
+ }
+
+ CHECK(ok);
+}
+
+TEST(CanSetAndGetResults)
+{
+ bool ok = false;
+ {
+ ScopedCurrentTest scopedTest;
+
+ UnitTest::TestResults results;
+ UnitTest::CurrentTest::Results() = &results;
+
+ ok = (UnitTest::CurrentTest::Results() == &results);
+ }
+
+ CHECK(ok);
+}
+
+}
diff --git a/3rdparty/unittest-cpp/tests/TestDeferredTestReporter.cpp b/3rdparty/unittest-cpp/tests/TestDeferredTestReporter.cpp
new file mode 100644
index 00000000000..60c347cbfc1
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestDeferredTestReporter.cpp
@@ -0,0 +1,122 @@
+#include "UnitTest++/Config.h"
+
+#ifndef UNITTEST_NO_DEFERRED_REPORTER
+
+#include "UnitTest++/UnitTestPP.h"
+#include "UnitTest++/DeferredTestReporter.h"
+#include <cstring>
+
+namespace UnitTest
+{
+
+namespace
+{
+
+#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM
+ MemoryOutStream& operator <<(MemoryOutStream& lhs, const std::string& rhs)
+ {
+ lhs << rhs.c_str();
+ return lhs;
+ }
+#endif
+
+struct MockDeferredTestReporter : public DeferredTestReporter
+{
+ virtual void ReportSummary(int, int, int, float)
+ {
+ }
+};
+
+struct DeferredTestReporterFixture
+{
+ DeferredTestReporterFixture()
+ : testName("UniqueTestName")
+ , testSuite("UniqueTestSuite")
+ , fileName("filename.h")
+ , lineNumber(12)
+ , details(testName.c_str(), testSuite.c_str(), fileName.c_str(), lineNumber)
+ {
+ }
+
+ MockDeferredTestReporter reporter;
+ std::string const testName;
+ std::string const testSuite;
+ std::string const fileName;
+ int const lineNumber;
+ TestDetails const details;
+};
+
+TEST_FIXTURE(DeferredTestReporterFixture, ReportTestStartCreatesANewDeferredTest)
+{
+ reporter.ReportTestStart(details);
+ CHECK_EQUAL(1, (int)reporter.GetResults().size());
+}
+
+TEST_FIXTURE(DeferredTestReporterFixture, ReportTestStartCapturesTestNameAndSuite)
+{
+ reporter.ReportTestStart(details);
+
+ DeferredTestResult const& result = reporter.GetResults().at(0);
+ CHECK_EQUAL(testName.c_str(), result.testName.c_str());
+ CHECK_EQUAL(testSuite.c_str(), result.suiteName.c_str());
+}
+
+TEST_FIXTURE(DeferredTestReporterFixture, ReportTestEndCapturesTestTime)
+{
+ float const elapsed = 123.45f;
+ reporter.ReportTestStart(details);
+ reporter.ReportTestFinish(details, elapsed);
+
+ DeferredTestResult const& result = reporter.GetResults().at(0);
+ CHECK_CLOSE(elapsed, result.timeElapsed, 0.0001f);
+}
+
+TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetails)
+{
+ char const* failure = "failure";
+
+ reporter.ReportTestStart(details);
+ reporter.ReportFailure(details, failure);
+
+ DeferredTestResult const& result = reporter.GetResults().at(0);
+ CHECK(result.failed == true);
+ CHECK_EQUAL(fileName.c_str(), result.failureFile.c_str());
+}
+
+TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetailsForMultipleFailures)
+{
+ char const* failure1 = "failure 1";
+ char const* failure2 = "failure 2";
+
+ reporter.ReportTestStart(details);
+ reporter.ReportFailure(details, failure1);
+ reporter.ReportFailure(details, failure2);
+
+ DeferredTestResult const& result = reporter.GetResults().at(0);
+ CHECK_EQUAL(2, (int)result.failures.size());
+ CHECK_EQUAL(failure1, result.failures[0].failureStr);
+ CHECK_EQUAL(failure2, result.failures[1].failureStr);
+}
+
+TEST_FIXTURE(DeferredTestReporterFixture, DeferredTestReporterTakesCopyOfFailureMessage)
+{
+ reporter.ReportTestStart(details);
+
+ char failureMessage[128];
+ char const* goodStr = "Real failure message";
+ char const* badStr = "Bogus failure message";
+
+ using namespace std;
+
+ strcpy(failureMessage, goodStr);
+ reporter.ReportFailure(details, failureMessage);
+ strcpy(failureMessage, badStr);
+
+ DeferredTestResult const& result = reporter.GetResults().at(0);
+ DeferredTestFailure const& failure = result.failures.at(0);
+ CHECK_EQUAL(goodStr, failure.failureStr);
+}
+
+}}
+
+#endif
diff --git a/3rdparty/unittest-cpp/tests/TestExceptions.cpp b/3rdparty/unittest-cpp/tests/TestExceptions.cpp
new file mode 100644
index 00000000000..1a0ab04ef1a
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestExceptions.cpp
@@ -0,0 +1,563 @@
+#include "UnitTest++/Config.h"
+#ifndef UNITTEST_NO_EXCEPTIONS
+
+#include "UnitTest++/UnitTestPP.h"
+#include "UnitTest++/CurrentTest.h"
+#include "RecordingReporter.h"
+#include "ScopedCurrentTest.h"
+
+#include <stdexcept>
+
+using namespace std;
+
+namespace {
+
+int ThrowingFunction()
+{
+ throw "Doh";
+}
+
+int ThrowingStdExceptionFunction()
+{
+ throw std::logic_error("Doh");
+}
+
+SUITE(CheckExceptionTests)
+{
+ struct CheckFixture
+ {
+ CheckFixture()
+ : reporter()
+ , testResults(&reporter)
+ {
+ }
+
+ void PerformCheckWithNonStdThrow()
+ {
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK(ThrowingFunction() == 1);
+ }
+
+ void PerformCheckWithStdThrow()
+ {
+ ScopedCurrentTest scopedResults(testResults);
+ CHECK(ThrowingStdExceptionFunction() == 1);
+ }
+
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults;
+ };
+
+ TEST_FIXTURE(CheckFixture, CheckFailsOnException)
+ {
+ PerformCheckWithNonStdThrow();
+ CHECK(testResults.GetFailureCount() > 0);
+ }
+
+ TEST_FIXTURE(CheckFixture, CheckFailsOnStdException)
+ {
+ PerformCheckWithStdThrow();
+ CHECK(testResults.GetFailureCount() > 0);
+ }
+
+ TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfExceptionIncludesCheckContents)
+ {
+ PerformCheckWithNonStdThrow();
+ CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction() == 1"));
+ }
+
+ TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfStdExceptionIncludesCheckContents)
+ {
+ PerformCheckWithStdThrow();
+ CHECK(strstr(reporter.lastFailedMessage, "ThrowingStdExceptionFunction() == 1"));
+ }
+
+ TEST_FIXTURE(CheckFixture, CheckFailureBecauseOfStandardExceptionIncludesWhat)
+ {
+ PerformCheckWithStdThrow();
+ CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)"));
+ }
+}
+
+SUITE(CheckEqualExceptionTests)
+{
+ struct CheckEqualFixture
+ {
+ CheckEqualFixture()
+ : reporter()
+ , testResults(&reporter)
+ , line(-1)
+ {
+ }
+
+ void PerformCheckWithNonStdThrow()
+ {
+ UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+ CHECK_EQUAL(ThrowingFunction(), 123); line = __LINE__;
+ }
+
+ void PerformCheckWithStdThrow()
+ {
+ UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+ CHECK_EQUAL(ThrowingStdExceptionFunction(), 123); line = __LINE__;
+ }
+
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults;
+ int line;
+ };
+
+ TEST_FIXTURE(CheckEqualFixture, CheckEqualFailsOnException)
+ {
+ PerformCheckWithNonStdThrow();
+ CHECK(testResults.GetFailureCount() > 0);
+ }
+
+ TEST_FIXTURE(CheckEqualFixture, CheckEqualFailsOnStdException)
+ {
+ PerformCheckWithStdThrow();
+ CHECK(testResults.GetFailureCount() > 0);
+ }
+
+ TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfExceptionContainsCorrectDetails)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK_EQUAL("testName", reporter.lastFailedTest);
+ CHECK_EQUAL("suiteName", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+ }
+
+ TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfStdExceptionContainsCorrectDetails)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK_EQUAL("testName", reporter.lastFailedTest);
+ CHECK_EQUAL("suiteName", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+ }
+
+ TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfExceptionIncludesCheckContents)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "ThrowingFunction()"));
+ CHECK(strstr(reporter.lastFailedMessage, "123"));
+ }
+
+ TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfStdExceptionIncludesCheckContents)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "ThrowingStdExceptionFunction()"));
+ CHECK(strstr(reporter.lastFailedMessage, "123"));
+ }
+
+ TEST_FIXTURE(CheckEqualFixture, CheckEqualFailureBecauseOfStandardExceptionIncludesWhat)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)"));
+ }
+}
+
+SUITE(CheckCloseExceptionTests)
+{
+ struct CheckCloseFixture
+ {
+ CheckCloseFixture()
+ : reporter()
+ , testResults(&reporter)
+ , line(-1)
+ {
+ }
+
+ void PerformCheckWithNonStdThrow()
+ {
+ UnitTest::TestDetails const testDetails("closeTest", "closeSuite", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+ CHECK_CLOSE(static_cast<float>(ThrowingFunction()), 1.0001f, 0.1f); line = __LINE__;
+ }
+
+ void PerformCheckWithStdThrow()
+ {
+ UnitTest::TestDetails const testDetails("closeTest", "closeSuite", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+ CHECK_CLOSE(static_cast<float>(ThrowingStdExceptionFunction()), 1.0001f, 0.1f); line = __LINE__;
+ }
+
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults;
+ int line;
+ };
+
+ TEST_FIXTURE(CheckCloseFixture, CheckCloseFailsOnException)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK(testResults.GetFailureCount() > 0);
+ }
+
+ TEST_FIXTURE(CheckCloseFixture, CheckCloseFailsOnStdException)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(testResults.GetFailureCount() > 0);
+ }
+
+ TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfExceptionContainsCorrectDetails)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK_EQUAL("closeTest", reporter.lastFailedTest);
+ CHECK_EQUAL("closeSuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+ }
+
+ TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfStdExceptionContainsCorrectDetails)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK_EQUAL("closeTest", reporter.lastFailedTest);
+ CHECK_EQUAL("closeSuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+ }
+
+ TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfExceptionIncludesCheckContents)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "static_cast<float>(ThrowingFunction())"));
+ CHECK(strstr(reporter.lastFailedMessage, "1.0001f"));
+ }
+
+ TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfStdExceptionIncludesCheckContents)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "static_cast<float>(ThrowingStdExceptionFunction())"));
+ CHECK(strstr(reporter.lastFailedMessage, "1.0001f"));
+ }
+
+ TEST_FIXTURE(CheckCloseFixture, CheckCloseFailureBecauseOfStandardExceptionIncludesWhat)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "exception (Doh)"));
+ }
+}
+
+class ThrowingObject
+{
+public:
+ float operator[](int) const
+ {
+ throw "Test throw";
+ }
+};
+
+class StdThrowingObject
+{
+public:
+ float operator[](int) const
+ {
+ throw std::runtime_error("Test throw");
+ }
+};
+
+SUITE(CheckArrayCloseExceptionTests)
+{
+ struct CheckArrayCloseFixture
+ {
+ CheckArrayCloseFixture()
+ : reporter()
+ , testResults(&reporter)
+ , line(-1)
+ {
+ }
+
+ void PerformCheckWithNonStdThrow()
+ {
+ UnitTest::TestDetails const 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__;
+ }
+
+ void PerformCheckWithStdThrow()
+ {
+ UnitTest::TestDetails const testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+ int const data[4] = { 0, 1, 2, 3 };
+ CHECK_ARRAY_CLOSE(data, StdThrowingObject(), 4, 0.01f); line = __LINE__;
+ }
+
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults;
+ int line;
+ };
+
+ TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureBecauseOfExceptionContainsCorrectDetails)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest);
+ CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+ }
+
+ TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureBecauseOfStdExceptionContainsCorrectDetails)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest);
+ CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+ }
+
+ TEST_FIXTURE(CheckArrayCloseFixture, CheckFailsOnException)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK(testResults.GetFailureCount() > 0);
+ }
+
+ TEST_FIXTURE(CheckArrayCloseFixture, CheckFailsOnStdException)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(testResults.GetFailureCount() > 0);
+ }
+
+ TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureOnExceptionIncludesCheckContents)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "data"));
+ CHECK(strstr(reporter.lastFailedMessage, "ThrowingObject()"));
+ }
+
+ TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureOnStdExceptionIncludesCheckContents)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "data"));
+ CHECK(strstr(reporter.lastFailedMessage, "StdThrowingObject()"));
+ }
+
+ TEST_FIXTURE(CheckArrayCloseFixture, CheckFailureOnStdExceptionIncludesWhat)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "exception (Test throw)"));
+ }
+}
+
+SUITE(CheckArrayEqualExceptionTests)
+{
+ struct CheckArrayEqualFixture
+ {
+ CheckArrayEqualFixture()
+ : reporter()
+ , testResults(&reporter)
+ , line(-1)
+ {
+ }
+
+ void PerformCheckWithNonStdThrow()
+ {
+ UnitTest::TestDetails const testDetails("arrayEqualTest", "arrayEqualSuite", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+ int const data[4] = { 0, 1, 2, 3 };
+ CHECK_ARRAY_EQUAL(data, ThrowingObject(), 4); line = __LINE__;
+ }
+
+ void PerformCheckWithStdThrow()
+ {
+ UnitTest::TestDetails const testDetails("arrayEqualTest", "arrayEqualSuite", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+ int const data[4] = { 0, 1, 2, 3 };
+ CHECK_ARRAY_EQUAL(data, StdThrowingObject(), 4); line = __LINE__;
+ }
+
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults;
+ int line;
+ };
+
+ TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureBecauseOfExceptionContainsCorrectDetails)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK_EQUAL("arrayEqualTest", reporter.lastFailedTest);
+ CHECK_EQUAL("arrayEqualSuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+ }
+
+ TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureBecauseOfStdExceptionContainsCorrectDetails)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK_EQUAL("arrayEqualTest", reporter.lastFailedTest);
+ CHECK_EQUAL("arrayEqualSuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+ }
+
+ TEST_FIXTURE(CheckArrayEqualFixture, CheckFailsOnException)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK(testResults.GetFailureCount() > 0);
+ }
+
+ TEST_FIXTURE(CheckArrayEqualFixture, CheckFailsOnStdException)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(testResults.GetFailureCount() > 0);
+ }
+
+ TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureOnExceptionIncludesCheckContents)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "data"));
+ CHECK(strstr(reporter.lastFailedMessage, "ThrowingObject()"));
+ }
+
+ TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureOnStdExceptionIncludesCheckContents)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "data"));
+ CHECK(strstr(reporter.lastFailedMessage, "StdThrowingObject()"));
+ }
+
+ TEST_FIXTURE(CheckArrayEqualFixture, CheckFailureOnStdExceptionIncludesWhat)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "exception (Test throw)"));
+ }
+}
+
+SUITE(CheckArray2DExceptionTests)
+{
+ class ThrowingObject2D
+ {
+ public:
+ float* operator[](int) const
+ {
+ throw "Test throw";
+ }
+ };
+
+ class StdThrowingObject2D
+ {
+ public:
+ float* operator[](int) const
+ {
+ throw std::runtime_error("Test throw");
+ }
+ };
+
+ struct CheckArray2DCloseFixture
+ {
+ CheckArray2DCloseFixture()
+ : reporter()
+ , testResults(&reporter)
+ , line(-1)
+ {
+ }
+
+ void PerformCheckWithNonStdThrow()
+ {
+ UnitTest::TestDetails const 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__;
+ }
+
+ void PerformCheckWithStdThrow()
+ {
+ UnitTest::TestDetails const testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1);
+ ScopedCurrentTest scopedResults(testResults, &testDetails);
+ const float data[2][2] = { {0, 1}, {2, 3} };
+ CHECK_ARRAY2D_CLOSE(data, StdThrowingObject2D(), 2, 2, 0.01f); line = __LINE__;
+ }
+
+ RecordingReporter reporter;
+ UnitTest::TestResults testResults;
+ int line;
+ };
+
+ TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureBecauseOfExceptionContainsCorrectDetails)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest);
+ CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+ }
+
+ TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureBecauseOfStdExceptionContainsCorrectDetails)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest);
+ CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite);
+ CHECK_EQUAL("filename", reporter.lastFailedFile);
+ CHECK_EQUAL(line, reporter.lastFailedLine);
+ }
+
+ TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailsOnException)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK(testResults.GetFailureCount() > 0);
+ }
+
+ TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailsOnStdException)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(testResults.GetFailureCount() > 0);
+ }
+
+ TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureOnExceptionIncludesCheckContents)
+ {
+ PerformCheckWithNonStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "data"));
+ CHECK(strstr(reporter.lastFailedMessage, "ThrowingObject2D()"));
+ }
+
+ TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureOnStdExceptionIncludesCheckContents)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "data"));
+ CHECK(strstr(reporter.lastFailedMessage, "StdThrowingObject2D()"));
+ }
+
+ TEST_FIXTURE(CheckArray2DCloseFixture, CheckFailureOnStdExceptionIncludesWhat)
+ {
+ PerformCheckWithStdThrow();
+
+ CHECK(strstr(reporter.lastFailedMessage, "exception (Test throw)"));
+ }
+}
+}
+
+#endif
diff --git a/3rdparty/unittest-cpp/tests/TestMemoryOutStream.cpp b/3rdparty/unittest-cpp/tests/TestMemoryOutStream.cpp
new file mode 100644
index 00000000000..ff1e920b2d3
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestMemoryOutStream.cpp
@@ -0,0 +1,336 @@
+#include "UnitTest++/UnitTestPP.h"
+
+#include "UnitTest++/MemoryOutStream.h"
+#include <cstring>
+#include <cstdlib>
+#include <climits>
+#include <cfloat>
+
+using namespace UnitTest;
+using namespace std;
+
+namespace {
+
+const char* const maxSignedIntegralStr(size_t nBytes)
+{
+ switch(nBytes)
+ {
+ case 8:
+ return "9223372036854775807";
+ case 4:
+ return "2147483647";
+ case 2:
+ return "32767";
+ case 1:
+ return "127";
+ default:
+ return "Unsupported signed integral size";
+ }
+}
+
+const char* const minSignedIntegralStr(size_t nBytes)
+{
+ switch(nBytes)
+ {
+ case 8:
+ return "-9223372036854775808";
+ case 4:
+ return "-2147483648";
+ case 2:
+ return "-32768";
+ case 1:
+ return "-128";
+ default:
+ return "Unsupported signed integral size";
+ }
+}
+
+const char* const maxUnsignedIntegralStr(size_t nBytes)
+{
+ switch(nBytes)
+ {
+ case 8:
+ return "18446744073709551615";
+ case 4:
+ return "4294967295";
+ case 2:
+ return "65535";
+ case 1:
+ return "255";
+ default:
+ return "Unsupported signed integral size";
+ }
+}
+
+TEST(DefaultIsEmptyString)
+{
+ MemoryOutStream const stream;
+ CHECK(stream.GetText() != 0);
+ CHECK_EQUAL("", stream.GetText());
+}
+
+TEST(StreamingTextCopiesCharacters)
+{
+ MemoryOutStream stream;
+ stream << "Lalala";
+ CHECK_EQUAL("Lalala", stream.GetText());
+}
+
+TEST(StreamingMultipleTimesConcatenatesResult)
+{
+ MemoryOutStream stream;
+ stream << "Bork" << "Foo" << "Bar";
+ CHECK_EQUAL("BorkFooBar", stream.GetText());
+}
+
+TEST(StreamingIntWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (int)123;
+ CHECK_EQUAL("123", stream.GetText());
+}
+
+TEST(StreaminMaxIntWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << INT_MAX;
+ CHECK_EQUAL(maxSignedIntegralStr(sizeof(int)), stream.GetText());
+}
+
+TEST(StreamingMinIntWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << INT_MIN;
+ CHECK_EQUAL(minSignedIntegralStr(sizeof(int)), stream.GetText());
+}
+
+TEST(StreamingUnsignedIntWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (unsigned int)123;
+ CHECK_EQUAL("123", stream.GetText());
+}
+
+TEST(StreamingMaxUnsignedIntWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (unsigned int)UINT_MAX;
+ CHECK_EQUAL(maxUnsignedIntegralStr(sizeof(unsigned int)), stream.GetText());
+}
+
+TEST(StreamingMinUnsignedIntWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (unsigned int)0;
+ CHECK_EQUAL("0", stream.GetText());
+}
+
+TEST(StreamingLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (long)(-123);
+ CHECK_EQUAL("-123", stream.GetText());
+}
+
+TEST(StreamingMaxLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (long)(LONG_MAX);
+ CHECK_EQUAL(maxSignedIntegralStr(sizeof(long)), stream.GetText());
+}
+
+TEST(StreamingMinLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (long)(LONG_MIN);
+ CHECK_EQUAL(minSignedIntegralStr(sizeof(long)), stream.GetText());
+}
+
+TEST(StreamingUnsignedLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (unsigned long)123;
+ CHECK_EQUAL("123", stream.GetText());
+}
+
+TEST(StreamingMaxUnsignedLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (unsigned long)ULONG_MAX;
+ CHECK_EQUAL(maxUnsignedIntegralStr(sizeof(unsigned long)), stream.GetText());
+}
+
+TEST(StreamingMinUnsignedLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (unsigned long)0ul;
+ CHECK_EQUAL("0", stream.GetText());
+}
+
+TEST(StreamingLongLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+#ifdef UNITTEST_COMPILER_IS_MSVC6
+ stream << (__int64)-12345i64;
+#else
+ stream << (long long)-12345ll;
+#endif
+ CHECK_EQUAL("-12345", stream.GetText());
+}
+
+#ifdef LLONG_MAX
+TEST(StreamingMaxLongLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (long long)LLONG_MAX;
+ CHECK_EQUAL(maxSignedIntegralStr(sizeof(long long)), stream.GetText());
+}
+#endif
+
+#ifdef LLONG_MIN
+TEST(StreamingMinLongLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (long long)LLONG_MIN;
+ CHECK_EQUAL(minSignedIntegralStr(sizeof(long long)), stream.GetText());
+}
+#endif
+
+TEST(StreamingUnsignedLongLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+#ifdef UNITTEST_COMPILER_IS_MSVC6
+ stream << (unsigned __int64)85899ui64;
+#else
+ stream << (unsigned long long)85899ull;
+#endif
+ CHECK_EQUAL("85899", stream.GetText());
+}
+
+#ifdef ULLONG_MAX
+TEST(StreamingMaxUnsignedLongLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << (unsigned long long)ULLONG_MAX;
+ CHECK_EQUAL(maxUnsignedIntegralStr(sizeof(unsigned long long)), stream.GetText());
+}
+#endif
+
+TEST(StreamingMinUnsignedLongLongWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+#ifdef UNITTEST_COMPILER_IS_MSVC6
+ stream << (unsigned __int64)0ui64;
+#else
+ stream << (unsigned long long)0ull;
+#endif
+ CHECK_EQUAL("0", stream.GetText());
+}
+
+TEST(StreamingFloatWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << 3.1415f;
+ CHECK(strstr(stream.GetText(), "3.1415"));
+}
+
+TEST(StreamingDoubleWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ stream << 3.1415;
+ CHECK(strstr(stream.GetText(), "3.1415"));
+}
+
+TEST(StreamingPointerWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ int* p = (int*)0x1234;
+ stream << p;
+ CHECK(strstr(stream.GetText(), "1234"));
+}
+
+TEST(StreamingSizeTWritesCorrectCharacters)
+{
+ MemoryOutStream stream;
+ size_t const s = 53124;
+ stream << s;
+ CHECK_EQUAL("53124", stream.GetText());
+}
+
+TEST(ClearEmptiesMemoryOutStreamContents)
+{
+ MemoryOutStream stream;
+ stream << "Hello world";
+ stream.Clear();
+ CHECK_EQUAL("", stream.GetText());
+}
+
+#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM
+
+TEST(StreamInitialCapacityIsCorrect)
+{
+ MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE);
+ CHECK_EQUAL((int)MemoryOutStream::GROW_CHUNK_SIZE, stream.GetCapacity());
+}
+
+TEST(StreamInitialCapacityIsMultipleOfGrowChunkSize)
+{
+ MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE + 1);
+ CHECK_EQUAL((int)MemoryOutStream::GROW_CHUNK_SIZE * 2, stream.GetCapacity());
+}
+
+
+TEST(ExceedingCapacityGrowsBuffer)
+{
+ MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE);
+ stream << "012345678901234567890123456789";
+ char const* const oldBuffer = stream.GetText();
+ stream << "0123456789";
+ CHECK(oldBuffer != stream.GetText());
+}
+
+TEST(ExceedingCapacityGrowsBufferByGrowChunk)
+{
+ MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE);
+ stream << "0123456789012345678901234567890123456789";
+ CHECK_EQUAL(MemoryOutStream::GROW_CHUNK_SIZE * 2, stream.GetCapacity());
+}
+
+TEST(WritingStringLongerThanCapacityFitsInNewBuffer)
+{
+ MemoryOutStream stream(8);
+ stream << "0123456789ABCDEF";
+ CHECK_EQUAL("0123456789ABCDEF", stream.GetText());
+}
+
+TEST(WritingIntLongerThanCapacityFitsInNewBuffer)
+{
+ MemoryOutStream stream(8);
+ stream << "aaaa" << 123456;
+ CHECK_EQUAL("aaaa123456", stream.GetText());
+}
+
+TEST(WritingFloatLongerThanCapacityFitsInNewBuffer)
+{
+ MemoryOutStream stream(8);
+ stream << "aaaa" << 123456.0f;
+ CHECK_EQUAL("aaaa123456.000000", stream.GetText());
+}
+
+TEST(WritingSizeTLongerThanCapacityFitsInNewBuffer)
+{
+ MemoryOutStream stream(8);
+ stream << "aaaa" << size_t(32145);
+ CHECK_EQUAL("aaaa32145", stream.GetText());
+}
+
+TEST(VerifyLargeDoubleCanBeStreamedWithoutCrashing)
+{
+ MemoryOutStream stream(8);
+ stream << DBL_MAX;
+ CHECK(true);
+}
+
+#endif
+
+}
diff --git a/3rdparty/unittest-cpp/tests/TestTest.cpp b/3rdparty/unittest-cpp/tests/TestTest.cpp
new file mode 100644
index 00000000000..49529eb0405
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestTest.cpp
@@ -0,0 +1,133 @@
+#include "UnitTest++/UnitTestPP.h"
+#include "UnitTest++/TestReporter.h"
+#include "UnitTest++/TimeHelpers.h"
+#include "ScopedCurrentTest.h"
+
+using namespace UnitTest;
+
+namespace {
+
+TEST(PassingTestHasNoFailures)
+{
+ class PassingTest : public Test
+ {
+ public:
+ PassingTest() : Test("passing") {}
+ virtual void RunImpl() const
+ {
+ CHECK(true);
+ }
+ };
+
+ TestResults results;
+ {
+ ScopedCurrentTest scopedResults(results);
+ PassingTest().Run();
+ }
+
+ CHECK_EQUAL(0, results.GetFailureCount());
+}
+
+
+TEST(FailingTestHasFailures)
+{
+ class FailingTest : public Test
+ {
+ public:
+ FailingTest() : Test("failing") {}
+ virtual void RunImpl() const
+ {
+ CHECK(false);
+ }
+ };
+
+ TestResults results;
+ {
+ ScopedCurrentTest scopedResults(results);
+ FailingTest().Run();
+ }
+
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+
+#ifndef UNITTEST_NO_EXCEPTIONS
+TEST(ThrowingTestsAreReportedAsFailures)
+{
+ class CrashingTest : public Test
+ {
+ public:
+ CrashingTest() : Test("throwing") {}
+ virtual void RunImpl() const
+ {
+ throw "Blah";
+ }
+ };
+
+ TestResults results;
+ {
+ ScopedCurrentTest scopedResult(results);
+ CrashingTest().Run();
+ }
+
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+
+#if !defined(UNITTEST_MINGW) && !defined(UNITTEST_WIN32)
+// Skip this test in debug because some debuggers don't like it.
+#if defined(NDEBUG)
+TEST(CrashingTestsAreReportedAsFailures)
+{
+ class CrashingTest : public Test
+ {
+ public:
+ CrashingTest() : Test("crashing") {}
+ virtual void RunImpl() const
+ {
+
+ reinterpret_cast< void (*)() >(0)();
+ }
+ };
+
+ TestResults results;
+ {
+ ScopedCurrentTest scopedResult(results);
+ CrashingTest().Run();
+ }
+
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+#endif
+#endif
+#endif
+
+TEST(TestWithUnspecifiedSuiteGetsDefaultSuite)
+{
+ Test test("test");
+ CHECK(test.m_details.suiteName != NULL);
+ CHECK_EQUAL("DefaultSuite", test.m_details.suiteName);
+}
+
+TEST(TestReflectsSpecifiedSuiteName)
+{
+ Test test("test", "testSuite");
+ CHECK(test.m_details.suiteName != NULL);
+ CHECK_EQUAL("testSuite", test.m_details.suiteName);
+}
+
+void Fail()
+{
+ CHECK(false);
+}
+
+TEST(OutOfCoreCHECKMacrosCanFailTests)
+{
+ TestResults results;
+ {
+ ScopedCurrentTest scopedResult(results);
+ Fail();
+ }
+
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+
+}
diff --git a/3rdparty/unittest-cpp/tests/TestTestList.cpp b/3rdparty/unittest-cpp/tests/TestTestList.cpp
new file mode 100644
index 00000000000..73732c5b794
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestTestList.cpp
@@ -0,0 +1,50 @@
+#include "UnitTest++/UnitTestPP.h"
+#include "UnitTest++/TestList.h"
+
+using namespace UnitTest;
+
+namespace {
+
+
+TEST(TestListIsEmptyByDefault)
+{
+ TestList list;
+ CHECK(list.GetHead() == 0);
+}
+
+TEST(AddingTestSetsHeadToTest)
+{
+ Test test("test");
+ TestList list;
+ list.Add(&test);
+
+ CHECK(list.GetHead() == &test);
+ CHECK(test.m_nextTest == 0);
+}
+
+TEST(AddingSecondTestAddsItToEndOfList)
+{
+ Test test1("test1");
+ Test test2("test2");
+
+ TestList list;
+ list.Add(&test1);
+ list.Add(&test2);
+
+ CHECK(list.GetHead() == &test1);
+ CHECK(test1.m_nextTest == &test2);
+ CHECK(test2.m_nextTest == 0);
+}
+
+TEST(ListAdderAddsTestToList)
+{
+ TestList list;
+
+ Test test("");
+ ListAdder adder(list, &test);
+
+ CHECK(list.GetHead() == &test);
+ CHECK(test.m_nextTest == 0);
+}
+
+}
diff --git a/3rdparty/unittest-cpp/tests/TestTestMacros.cpp b/3rdparty/unittest-cpp/tests/TestTestMacros.cpp
new file mode 100644
index 00000000000..4f0cfed31d7
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestTestMacros.cpp
@@ -0,0 +1,221 @@
+#include "UnitTest++/UnitTestPP.h"
+#include "UnitTest++/TestMacros.h"
+#include "UnitTest++/TestList.h"
+#include "UnitTest++/TestResults.h"
+#include "UnitTest++/TestReporter.h"
+#include "UnitTest++/ReportAssert.h"
+#include "RecordingReporter.h"
+#include "ScopedCurrentTest.h"
+
+using namespace UnitTest;
+using namespace std;
+
+namespace {
+
+TestList list1;
+TEST_EX(DummyTest, list1)
+{
+}
+
+TEST (TestsAreAddedToTheListThroughMacro)
+{
+ CHECK(list1.GetHead() != 0);
+ CHECK(list1.GetHead()->m_nextTest == 0);
+}
+
+#ifndef UNITTEST_NO_EXCEPTIONS
+
+struct ThrowingThingie
+{
+ ThrowingThingie() : dummy(false)
+ {
+ if (!dummy)
+ throw "Oops";
+ }
+
+ bool dummy;
+};
+
+TestList list2;
+TEST_FIXTURE_EX(ThrowingThingie, DummyTestName, list2)
+{
+}
+
+TEST (ExceptionsInFixtureAreReportedAsHappeningInTheFixture)
+{
+ RecordingReporter reporter;
+ TestResults result(&reporter);
+ {
+ ScopedCurrentTest scopedResults(result);
+ list2.GetHead()->Run();
+ }
+
+ CHECK(strstr(reporter.lastFailedMessage, "xception"));
+ CHECK(strstr(reporter.lastFailedMessage, "fixture"));
+ CHECK(strstr(reporter.lastFailedMessage, "ThrowingThingie"));
+}
+
+#endif
+
+struct DummyFixture
+{
+ int x;
+};
+
+// We're really testing the macros so we just want them to compile and link
+SUITE(TestSuite1)
+{
+ TEST(SimilarlyNamedTestsInDifferentSuitesWork)
+ {
+ }
+
+ TEST_FIXTURE(DummyFixture, SimilarlyNamedFixtureTestsInDifferentSuitesWork)
+ {
+ }
+}
+
+SUITE(TestSuite2)
+{
+ TEST(SimilarlyNamedTestsInDifferentSuitesWork)
+ {
+ }
+
+ TEST_FIXTURE(DummyFixture,SimilarlyNamedFixtureTestsInDifferentSuitesWork)
+ {
+ }
+}
+
+TestList macroTestList1;
+TEST_EX(MacroTestHelper1, macroTestList1)
+{
+}
+
+TEST(TestAddedWithTEST_EXMacroGetsDefaultSuite)
+{
+ CHECK(macroTestList1.GetHead() != NULL);
+ CHECK_EQUAL ("MacroTestHelper1", macroTestList1.GetHead()->m_details.testName);
+ CHECK_EQUAL ("DefaultSuite", macroTestList1.GetHead()->m_details.suiteName);
+}
+
+TestList macroTestList2;
+TEST_FIXTURE_EX(DummyFixture, MacroTestHelper2, macroTestList2)
+{
+}
+
+TEST(TestAddedWithTEST_FIXTURE_EXMacroGetsDefaultSuite)
+{
+ CHECK(macroTestList2.GetHead() != NULL);
+ CHECK_EQUAL ("MacroTestHelper2", macroTestList2.GetHead()->m_details.testName);
+ CHECK_EQUAL ("DefaultSuite", macroTestList2.GetHead()->m_details.suiteName);
+}
+
+#ifndef UNITTEST_NO_EXCEPTIONS
+
+struct FixtureCtorThrows
+{
+ FixtureCtorThrows() { throw "exception"; }
+};
+
+TestList throwingFixtureTestList1;
+TEST_FIXTURE_EX(FixtureCtorThrows, FixtureCtorThrowsTestName, throwingFixtureTestList1)
+{
+}
+
+TEST(FixturesWithThrowingCtorsAreFailures)
+{
+ CHECK(throwingFixtureTestList1.GetHead() != NULL);
+ RecordingReporter reporter;
+ TestResults result(&reporter);
+ {
+ ScopedCurrentTest scopedResult(result);
+ throwingFixtureTestList1.GetHead()->Run();
+ }
+
+ int const failureCount = result.GetFailedTestCount();
+ CHECK_EQUAL(1, failureCount);
+ CHECK(strstr(reporter.lastFailedMessage, "while constructing fixture"));
+}
+
+struct FixtureDtorThrows
+{
+ ~FixtureDtorThrows() { throw "exception"; }
+};
+
+TestList throwingFixtureTestList2;
+TEST_FIXTURE_EX(FixtureDtorThrows, FixtureDtorThrowsTestName, throwingFixtureTestList2)
+{
+}
+
+TEST(FixturesWithThrowingDtorsAreFailures)
+{
+ CHECK(throwingFixtureTestList2.GetHead() != NULL);
+
+ RecordingReporter reporter;
+ TestResults result(&reporter);
+ {
+ ScopedCurrentTest scopedResult(result);
+ throwingFixtureTestList2.GetHead()->Run();
+ }
+
+ int const failureCount = result.GetFailedTestCount();
+ CHECK_EQUAL(1, failureCount);
+ CHECK(strstr(reporter.lastFailedMessage, "while destroying fixture"));
+}
+
+const int FailingLine = 123;
+
+struct FixtureCtorAsserts
+{
+ FixtureCtorAsserts()
+ {
+ UnitTest::ReportAssert("assert failure", "file", FailingLine);
+ }
+};
+
+TestList ctorAssertFixtureTestList;
+TEST_FIXTURE_EX(FixtureCtorAsserts, CorrectlyReportsAssertFailureInCtor, ctorAssertFixtureTestList)
+{
+}
+
+TEST(CorrectlyReportsFixturesWithCtorsThatAssert)
+{
+ RecordingReporter reporter;
+ TestResults result(&reporter);
+ {
+ ScopedCurrentTest scopedResults(result);
+ ctorAssertFixtureTestList.GetHead()->Run();
+ }
+
+ const int failureCount = result.GetFailedTestCount();
+ CHECK_EQUAL(1, failureCount);
+ CHECK_EQUAL(FailingLine, reporter.lastFailedLine);
+ CHECK(strstr(reporter.lastFailedMessage, "assert failure"));
+}
+
+#endif
+
+}
+
+// We're really testing if it's possible to use the same suite in two files
+// to compile and link successfuly (TestTestSuite.cpp has suite with the same name)
+// Note: we are outside of the anonymous namespace
+SUITE(SameTestSuite)
+{
+ TEST(DummyTest1)
+ {
+ }
+}
+
+#define CUR_TEST_NAME CurrentTestDetailsContainCurrentTestInfo
+#define INNER_STRINGIFY(X) #X
+#define STRINGIFY(X) INNER_STRINGIFY(X)
+
+TEST(CUR_TEST_NAME)
+{
+ const UnitTest::TestDetails* details = CurrentTest::Details();
+ CHECK_EQUAL(STRINGIFY(CUR_TEST_NAME), details->testName);
+}
+
+#undef CUR_TEST_NAME
+#undef INNER_STRINGIFY
+#undef STRINGIFY
diff --git a/3rdparty/unittest-cpp/tests/TestTestResults.cpp b/3rdparty/unittest-cpp/tests/TestTestResults.cpp
new file mode 100644
index 00000000000..a1156874676
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestTestResults.cpp
@@ -0,0 +1,111 @@
+#include "UnitTest++/UnitTestPP.h"
+#include "UnitTest++/TestResults.h"
+#include "RecordingReporter.h"
+
+using namespace UnitTest;
+
+namespace {
+
+TestDetails const details("testname", "suitename", "filename", 123);
+
+
+TEST(StartsWithNoTestsRun)
+{
+ TestResults results;
+ CHECK_EQUAL (0, results.GetTotalTestCount());
+}
+
+TEST(RecordsNumbersOfTests)
+{
+ TestResults results;
+ results.OnTestStart(details);
+ results.OnTestStart(details);
+ results.OnTestStart(details);
+ CHECK_EQUAL(3, results.GetTotalTestCount());
+}
+
+TEST(StartsWithNoTestsFailing)
+{
+ TestResults results;
+ CHECK_EQUAL (0, results.GetFailureCount());
+}
+
+TEST(RecordsNumberOfFailures)
+{
+ TestResults results;
+ results.OnTestFailure(details, "");
+ results.OnTestFailure(details, "");
+ CHECK_EQUAL(2, results.GetFailureCount());
+}
+
+TEST(RecordsNumberOfFailedTests)
+{
+ TestResults results;
+
+ results.OnTestStart(details);
+ results.OnTestFailure(details, "");
+ results.OnTestFinish(details, 0);
+
+ results.OnTestStart(details);
+ results.OnTestFailure(details, "");
+ results.OnTestFailure(details, "");
+ results.OnTestFailure(details, "");
+ results.OnTestFinish(details, 0);
+
+ CHECK_EQUAL (2, results.GetFailedTestCount());
+}
+
+TEST(NotifiesReporterOfTestStartWithCorrectInfo)
+{
+ RecordingReporter reporter;
+ TestResults results(&reporter);
+ results.OnTestStart(details);
+
+ CHECK_EQUAL (1, reporter.testRunCount);
+ CHECK_EQUAL ("suitename", reporter.lastStartedSuite);
+ CHECK_EQUAL ("testname", reporter.lastStartedTest);
+}
+
+TEST(NotifiesReporterOfTestFailureWithCorrectInfo)
+{
+ RecordingReporter reporter;
+ TestResults results(&reporter);
+
+ results.OnTestFailure(details, "failurestring");
+ CHECK_EQUAL (1, reporter.testFailedCount);
+ CHECK_EQUAL ("filename", reporter.lastFailedFile);
+ CHECK_EQUAL (123, reporter.lastFailedLine);
+ CHECK_EQUAL ("suitename", reporter.lastFailedSuite);
+ CHECK_EQUAL ("testname", reporter.lastFailedTest);
+ CHECK_EQUAL ("failurestring", reporter.lastFailedMessage);
+}
+
+TEST(NotifiesReporterOfCheckFailureWithCorrectInfo)
+{
+ RecordingReporter reporter;
+ TestResults results(&reporter);
+
+ results.OnTestFailure(details, "failurestring");
+ CHECK_EQUAL (1, reporter.testFailedCount);
+
+ CHECK_EQUAL ("filename", reporter.lastFailedFile);
+ CHECK_EQUAL (123, reporter.lastFailedLine);
+ CHECK_EQUAL ("testname", reporter.lastFailedTest);
+ CHECK_EQUAL ("suitename", reporter.lastFailedSuite);
+ CHECK_EQUAL ("failurestring", reporter.lastFailedMessage);
+}
+
+TEST(NotifiesReporterOfTestEnd)
+{
+ RecordingReporter reporter;
+ TestResults results(&reporter);
+
+ results.OnTestFinish(details, 0.1234f);
+ CHECK_EQUAL (1, reporter.testFinishedCount);
+ CHECK_EQUAL ("testname", reporter.lastFinishedTest);
+ CHECK_EQUAL ("suitename", reporter.lastFinishedSuite);
+ CHECK_CLOSE (0.1234f, reporter.lastFinishedTestTime, 0.0001f);
+}
+
+
+}
diff --git a/3rdparty/unittest-cpp/tests/TestTestRunner.cpp b/3rdparty/unittest-cpp/tests/TestTestRunner.cpp
new file mode 100644
index 00000000000..6f7c1bb571d
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestTestRunner.cpp
@@ -0,0 +1,330 @@
+#include "UnitTest++/UnitTestPP.h"
+#include "RecordingReporter.h"
+#include "UnitTest++/ReportAssert.h"
+#include "UnitTest++/TestList.h"
+#include "UnitTest++/TimeHelpers.h"
+#include "UnitTest++/TimeConstraint.h"
+#include "UnitTest++/ReportAssertImpl.h"
+
+using namespace UnitTest;
+
+namespace
+{
+
+ struct MockTest : public Test
+ {
+ MockTest(char const* testName, bool const success_, bool const assert_, int const count_ = 1)
+ : Test(testName)
+ , success(success_)
+ , asserted(assert_)
+ , count(count_)
+ {
+ }
+
+ virtual void RunImpl() const
+ {
+ TestResults& testResults_ = *CurrentTest::Results();
+
+ for (int i=0; i < count; ++i)
+ {
+ if (asserted)
+ {
+ ReportAssert("desc", "file", 0);
+ }
+ else if (!success)
+ {
+ testResults_.OnTestFailure(m_details, "message");
+ }
+ }
+ }
+
+ bool const success;
+ bool const asserted;
+ int const count;
+ };
+
+ struct FixtureBase
+ {
+ FixtureBase()
+ : runner(reporter)
+ {
+ }
+
+ template <class Predicate>
+ int RunTestsIf(TestList const& list, char const* suiteName,
+ const Predicate& predicate, int maxTestTimeInMs)
+ {
+ TestResults* oldResults = CurrentTest::Results();
+ const TestDetails* oldDetails = CurrentTest::Details();
+ int result = runner.RunTestsIf(list, suiteName, predicate, maxTestTimeInMs);
+ CurrentTest::Results() = oldResults;
+ CurrentTest::Details() = oldDetails;
+ return result;
+ }
+
+ TestRunner runner;
+ RecordingReporter reporter;
+ };
+
+ struct TestRunnerFixture : public FixtureBase
+ {
+ TestList list;
+ };
+
+ TEST_FIXTURE(TestRunnerFixture, TestStartIsReportedCorrectly)
+ {
+ MockTest test("goodtest", true, false);
+ list.Add(&test);
+
+ RunTestsIf(list, NULL, True(), 0);
+ CHECK_EQUAL(1, reporter.testRunCount);
+ CHECK_EQUAL("goodtest", reporter.lastStartedTest);
+ }
+
+ TEST_FIXTURE(TestRunnerFixture, TestFinishIsReportedCorrectly)
+ {
+ MockTest test("goodtest", true, false);
+ list.Add(&test);
+
+ RunTestsIf(list, NULL, True(), 0);
+ CHECK_EQUAL(1, reporter.testFinishedCount);
+ CHECK_EQUAL("goodtest", reporter.lastFinishedTest);
+ }
+
+ class SlowTest : public Test
+ {
+ public:
+ SlowTest()
+ : Test("slow", "somesuite", "filename", 123)
+ {
+ }
+
+ virtual void RunImpl() const
+ {
+ TimeHelpers::SleepMs(20);
+ }
+ };
+
+ TEST_FIXTURE(TestRunnerFixture, TestFinishIsCalledWithCorrectTime)
+ {
+ SlowTest test;
+ list.Add(&test);
+
+ RunTestsIf(list, NULL, True(), 0);
+ CHECK(reporter.lastFinishedTestTime >= 0.005f && reporter.lastFinishedTestTime <= 0.050f);
+ }
+
+ TEST_FIXTURE(TestRunnerFixture, FailureCountIsZeroWhenNoTestsAreRun)
+ {
+ CHECK_EQUAL(0, RunTestsIf(list, NULL, True(), 0));
+ CHECK_EQUAL(0, reporter.testRunCount);
+ CHECK_EQUAL(0, reporter.testFailedCount);
+ }
+
+ TEST_FIXTURE(TestRunnerFixture, CallsReportFailureOncePerFailingTest)
+ {
+ MockTest test1("test", false, false);
+ list.Add(&test1);
+ MockTest test2("test", true, false);
+ list.Add(&test2);
+ MockTest test3("test", false, false);
+ list.Add(&test3);
+
+ CHECK_EQUAL(2, RunTestsIf(list, NULL, True(), 0));
+ CHECK_EQUAL(2, reporter.testFailedCount);
+ }
+
+ TEST_FIXTURE(TestRunnerFixture, TestsThatAssertAreReportedAsFailing)
+ {
+ MockTest test("test", true, true);
+ list.Add(&test);
+
+ RunTestsIf(list, NULL, True(), 0);
+ CHECK_EQUAL(1, reporter.testFailedCount);
+ }
+
+
+ TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfTestCount)
+ {
+ MockTest test1("test", true, false);
+ MockTest test2("test", true, false);
+ MockTest test3("test", true, false);
+ list.Add(&test1);
+ list.Add(&test2);
+ list.Add(&test3);
+
+ RunTestsIf(list, NULL, True(), 0);
+ CHECK_EQUAL(3, reporter.summaryTotalTestCount);
+ }
+
+ TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailedTests)
+ {
+ MockTest test1("test", false, false, 2);
+ MockTest test2("test", true, false);
+ MockTest test3("test", false, false, 3);
+ list.Add(&test1);
+ list.Add(&test2);
+ list.Add(&test3);
+
+ RunTestsIf(list, NULL, True(), 0);
+ CHECK_EQUAL(2, reporter.summaryFailedTestCount);
+ }
+
+ TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailures)
+ {
+ MockTest test1("test", false, false, 2);
+ MockTest test2("test", true, false);
+ MockTest test3("test", false, false, 3);
+ list.Add(&test1);
+ list.Add(&test2);
+ list.Add(&test3);
+
+ RunTestsIf(list, NULL, True(), 0);
+ CHECK_EQUAL(5, reporter.summaryFailureCount);
+ }
+
+ TEST_FIXTURE(TestRunnerFixture, SlowTestPassesForHighTimeThreshold)
+ {
+ SlowTest test;
+ list.Add(&test);
+
+ RunTestsIf(list, NULL, True(), 0);
+ CHECK_EQUAL(0, reporter.testFailedCount);
+ }
+
+ TEST_FIXTURE(TestRunnerFixture, SlowTestFailsForLowTimeThreshold)
+ {
+ SlowTest test;
+ list.Add(&test);
+
+ RunTestsIf(list, NULL, True(), 3);
+ CHECK_EQUAL(1, reporter.testFailedCount);
+ }
+
+ TEST_FIXTURE(TestRunnerFixture, SlowTestHasCorrectFailureInformation)
+ {
+ SlowTest test;
+ list.Add(&test);
+
+ RunTestsIf(list, NULL, True(), 3);
+
+ using namespace std;
+
+ CHECK_EQUAL(test.m_details.testName, reporter.lastFailedTest);
+ CHECK(strstr(test.m_details.filename, reporter.lastFailedFile));
+ CHECK_EQUAL(test.m_details.lineNumber, reporter.lastFailedLine);
+
+ CHECK(strstr(reporter.lastFailedMessage, "Global time constraint failed"));
+ CHECK(strstr(reporter.lastFailedMessage, "3ms"));
+ }
+
+ TEST_FIXTURE(TestRunnerFixture, SlowTestWithTimeExemptionPasses)
+ {
+ class SlowExemptedTest : public Test
+ {
+ public:
+ SlowExemptedTest() : Test("slowexempted", "", 0) {}
+ virtual void RunImpl() const
+ {
+ UNITTEST_TIME_CONSTRAINT_EXEMPT();
+ TimeHelpers::SleepMs(20);
+ }
+ };
+
+ SlowExemptedTest test;
+ list.Add(&test);
+
+ RunTestsIf(list, NULL, True(), 3);
+ CHECK_EQUAL(0, reporter.testFailedCount);
+ }
+
+ struct TestSuiteFixture : FixtureBase
+ {
+ TestSuiteFixture()
+ : test1("TestInDefaultSuite")
+ , test2("TestInOtherSuite", "OtherSuite")
+ , test3("SecondTestInDefaultSuite")
+ {
+ list.Add(&test1);
+ list.Add(&test2);
+ }
+
+ Test test1;
+ Test test2;
+ Test test3;
+ TestList list;
+ };
+
+ TEST_FIXTURE(TestSuiteFixture, TestRunnerRunsAllSuitesIfNullSuiteIsPassed)
+ {
+ RunTestsIf(list, NULL, True(), 0);
+ CHECK_EQUAL(2, reporter.summaryTotalTestCount);
+ }
+
+ TEST_FIXTURE(TestSuiteFixture,TestRunnerRunsOnlySpecifiedSuite)
+ {
+ RunTestsIf(list, "OtherSuite", True(), 0);
+ CHECK_EQUAL(1, reporter.summaryTotalTestCount);
+ CHECK_EQUAL("TestInOtherSuite", reporter.lastFinishedTest);
+ }
+
+ struct RunTestIfNameIs
+ {
+ RunTestIfNameIs(char const* name_)
+ : name(name_)
+ {
+ }
+
+ bool operator()(const Test* const test) const
+ {
+ using namespace std;
+ return (0 == strcmp(test->m_details.testName, name));
+ }
+
+ char const* name;
+ };
+
+ TEST(TestMockPredicateBehavesCorrectly)
+ {
+ RunTestIfNameIs predicate("pass");
+
+ Test pass("pass");
+ Test fail("fail");
+
+ CHECK(predicate(&pass));
+ CHECK(!predicate(&fail));
+ }
+
+ TEST_FIXTURE(TestRunnerFixture, TestRunnerRunsTestsThatPassPredicate)
+ {
+ Test should_run("goodtest");
+ list.Add(&should_run);
+
+ Test should_not_run("badtest");
+ list.Add(&should_not_run);
+
+ RunTestsIf(list, NULL, RunTestIfNameIs("goodtest"), 0);
+ CHECK_EQUAL(1, reporter.testRunCount);
+ CHECK_EQUAL("goodtest", reporter.lastStartedTest);
+ }
+
+ TEST_FIXTURE(TestRunnerFixture, TestRunnerOnlyRunsTestsInSpecifiedSuiteAndThatPassPredicate)
+ {
+ Test runningTest1("goodtest", "suite");
+ Test skippedTest2("goodtest");
+ Test skippedTest3("badtest", "suite");
+ Test skippedTest4("badtest");
+
+ list.Add(&runningTest1);
+ list.Add(&skippedTest2);
+ list.Add(&skippedTest3);
+ list.Add(&skippedTest4);
+
+ RunTestsIf(list, "suite", RunTestIfNameIs("goodtest"), 0);
+
+ CHECK_EQUAL(1, reporter.testRunCount);
+ CHECK_EQUAL("goodtest", reporter.lastStartedTest);
+ CHECK_EQUAL("suite", reporter.lastStartedSuite);
+ }
+
+} \ No newline at end of file
diff --git a/3rdparty/unittest-cpp/tests/TestTestSuite.cpp b/3rdparty/unittest-cpp/tests/TestTestSuite.cpp
new file mode 100644
index 00000000000..ff560897101
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestTestSuite.cpp
@@ -0,0 +1,12 @@
+#include "UnitTest++/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)
+// Note: we are outside of the anonymous namespace
+SUITE(SameTestSuite)
+{
+ TEST(DummyTest2)
+ {
+ }
+}
+
diff --git a/3rdparty/unittest-cpp/tests/TestTimeConstraint.cpp b/3rdparty/unittest-cpp/tests/TestTimeConstraint.cpp
new file mode 100644
index 00000000000..5cb6c16f650
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestTimeConstraint.cpp
@@ -0,0 +1,69 @@
+#include "UnitTest++/UnitTestPP.h"
+#include "UnitTest++/TestResults.h"
+#include "UnitTest++/TimeHelpers.h"
+#include "RecordingReporter.h"
+#include "ScopedCurrentTest.h"
+
+using namespace UnitTest;
+
+namespace
+{
+
+TEST(TimeConstraintSucceedsWithFastTest)
+{
+ TestResults result;
+ {
+ ScopedCurrentTest scopedResult(result);
+ TimeConstraint t(200, TestDetails("", "", "", 0));
+ TimeHelpers::SleepMs(5);
+ }
+ CHECK_EQUAL(0, result.GetFailureCount());
+}
+
+TEST(TimeConstraintFailsWithSlowTest)
+{
+ TestResults result;
+ {
+ ScopedCurrentTest scopedResult(result);
+ TimeConstraint t(10, TestDetails("", "", "", 0));
+ TimeHelpers::SleepMs(20);
+ }
+ CHECK_EQUAL(1, result.GetFailureCount());
+}
+
+TEST(TimeConstraintFailureIncludesCorrectData)
+{
+ RecordingReporter reporter;
+ TestResults result(&reporter);
+ {
+ ScopedCurrentTest scopedResult(result);
+
+ TestDetails const details("testname", "suitename", "filename", 10);
+ TimeConstraint t(10, details);
+ TimeHelpers::SleepMs(20);
+ }
+
+ using namespace std;
+
+ CHECK(strstr(reporter.lastFailedFile, "filename"));
+ CHECK_EQUAL(10, reporter.lastFailedLine);
+ CHECK(strstr(reporter.lastFailedTest, "testname"));
+}
+
+TEST(TimeConstraintFailureIncludesTimeoutInformation)
+{
+ RecordingReporter reporter;
+ TestResults result(&reporter);
+ {
+ ScopedCurrentTest scopedResult(result);
+ TimeConstraint t(10, TestDetails("", "", "", 0));
+ TimeHelpers::SleepMs(20);
+ }
+
+ using namespace std;
+
+ CHECK(strstr(reporter.lastFailedMessage, "ime constraint"));
+ CHECK(strstr(reporter.lastFailedMessage, "under 10ms"));
+}
+
+}
diff --git a/3rdparty/unittest-cpp/tests/TestTimeConstraintMacro.cpp b/3rdparty/unittest-cpp/tests/TestTimeConstraintMacro.cpp
new file mode 100644
index 00000000000..3caf15dbd86
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestTimeConstraintMacro.cpp
@@ -0,0 +1,88 @@
+#include "UnitTest++/UnitTestPP.h"
+#include "UnitTest++/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"));
+}
+
+struct EmptyFixture {};
+
+TEST_FIXTURE(EmptyFixture, TimeConstraintMacroWorksInFixtures)
+{
+ 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, "TimeConstraintMacroWorksInFixtures"));
+}
+
+}
diff --git a/3rdparty/unittest-cpp/tests/TestUnitTestPP.cpp b/3rdparty/unittest-cpp/tests/TestUnitTestPP.cpp
new file mode 100644
index 00000000000..3bd6ab7bdda
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestUnitTestPP.cpp
@@ -0,0 +1,148 @@
+#include "UnitTest++/UnitTestPP.h"
+#include "ScopedCurrentTest.h"
+
+// These are sample tests that show the different features of the framework
+
+namespace {
+
+TEST(ValidCheckSucceeds)
+{
+ bool const b = true;
+ CHECK(b);
+}
+
+TEST(CheckWorksWithPointers)
+{
+ void* p = (void *)0x100;
+ CHECK(p);
+ CHECK(p != 0);
+}
+
+TEST(ValidCheckEqualSucceeds)
+{
+ int const x = 3;
+ int const y = 3;
+ CHECK_EQUAL(x, y);
+}
+
+TEST(CheckEqualWorksWithPointers)
+{
+ void* p = (void *)0;
+ CHECK_EQUAL((void*)0, p);
+}
+
+TEST(ValidCheckCloseSucceeds)
+{
+ CHECK_CLOSE(2.0f, 2.001f, 0.01f);
+ CHECK_CLOSE(2.001f, 2.0f, 0.01f);
+}
+
+TEST(ArrayCloseSucceeds)
+{
+ float const a1[] = {1, 2, 3};
+ float const a2[] = {1, 2.01f, 3};
+ CHECK_ARRAY_CLOSE(a1, a2, 3, 0.1f);
+}
+
+#ifndef UNITTEST_NO_EXCEPTIONS
+
+TEST(CheckThrowMacroSucceedsOnCorrectException)
+{
+ struct TestException {};
+ CHECK_THROW(throw TestException(), TestException);
+}
+
+TEST(CheckAssertSucceeds)
+{
+ CHECK_ASSERT(UnitTest::ReportAssert("desc", "file", 0));
+}
+
+TEST(CheckThrowMacroFailsOnMissingException)
+{
+ class NoThrowTest : public UnitTest::Test
+ {
+ public:
+ NoThrowTest() : Test("nothrow") {}
+ void DontThrow() const
+ {
+ }
+
+ virtual void RunImpl() const
+ {
+ CHECK_THROW(DontThrow(), int);
+ }
+ };
+
+ UnitTest::TestResults results;
+ {
+ ScopedCurrentTest scopedResults(results);
+
+ NoThrowTest test;
+ test.Run();
+ }
+
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+
+TEST(CheckThrowMacroFailsOnWrongException)
+{
+ class WrongThrowTest : public UnitTest::Test
+ {
+ public:
+ WrongThrowTest() : Test("wrongthrow") {}
+ virtual void RunImpl() const
+ {
+ CHECK_THROW(throw "oops", int);
+ }
+ };
+
+ UnitTest::TestResults results;
+ {
+ ScopedCurrentTest scopedResults(results);
+
+ WrongThrowTest test;
+ test.Run();
+ }
+
+ CHECK_EQUAL(1, results.GetFailureCount());
+}
+
+#endif
+
+struct SimpleFixture
+{
+ SimpleFixture()
+ {
+ ++instanceCount;
+ }
+ ~SimpleFixture()
+ {
+ --instanceCount;
+ }
+
+ static int instanceCount;
+};
+
+int SimpleFixture::instanceCount = 0;
+
+TEST_FIXTURE(SimpleFixture, DefaultFixtureCtorIsCalled)
+{
+ CHECK(SimpleFixture::instanceCount > 0);
+}
+
+TEST_FIXTURE(SimpleFixture, OnlyOneFixtureAliveAtATime)
+{
+ CHECK_EQUAL(1, SimpleFixture::instanceCount);
+}
+
+void CheckBool(const bool b)
+{
+ CHECK(b);
+}
+
+TEST(CanCallCHECKOutsideOfTestFunction)
+{
+ CheckBool(true);
+}
+
+}
diff --git a/3rdparty/unittest-cpp/tests/TestXmlTestReporter.cpp b/3rdparty/unittest-cpp/tests/TestXmlTestReporter.cpp
new file mode 100644
index 00000000000..154ada82c79
--- /dev/null
+++ b/3rdparty/unittest-cpp/tests/TestXmlTestReporter.cpp
@@ -0,0 +1,188 @@
+#include "UnitTest++/Config.h"
+#ifndef UNITTEST_NO_DEFERRED_REPORTER
+
+#include "UnitTest++/UnitTestPP.h"
+#include "UnitTest++/XmlTestReporter.h"
+
+#include <sstream>
+
+using namespace UnitTest;
+using std::ostringstream;
+
+namespace
+{
+
+#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM
+
+// Overload to let MemoryOutStream accept std::string
+MemoryOutStream& operator<<(MemoryOutStream& s, const std::string& value)
+{
+ s << value.c_str();
+ return s;
+}
+
+#endif
+
+struct XmlTestReporterFixture
+{
+ XmlTestReporterFixture()
+ : reporter(output)
+ {
+ }
+
+ ostringstream output;
+ XmlTestReporter reporter;
+};
+
+TEST_FIXTURE(XmlTestReporterFixture, MultipleCharactersAreEscaped)
+{
+ TestDetails const details("TestName", "suite", "filename.h", 4321);
+
+ reporter.ReportTestStart(details);
+ reporter.ReportFailure(details, "\"\"\'\'&&<<>>");
+ reporter.ReportTestFinish(details, 0.1f);
+ reporter.ReportSummary(1, 2, 3, 0.1f);
+
+ char const* expected =
+ "<?xml version=\"1.0\"?>"
+ "<unittest-results tests=\"1\" failedtests=\"2\" failures=\"3\" time=\"0.1\">"
+ "<test suite=\"suite\" name=\"TestName\" time=\"0.1\">"
+ "<failure message=\"filename.h(4321) : "
+ "&quot;&quot;&apos;&apos;&amp;&amp;&lt;&lt;&gt;&gt;\"/>"
+ "</test>"
+ "</unittest-results>";
+
+ CHECK_EQUAL(expected, output.str().c_str());
+}
+
+TEST_FIXTURE(XmlTestReporterFixture, OutputIsCachedUntilReportSummaryIsCalled)
+{
+ TestDetails const details("", "", "", 0);
+
+ reporter.ReportTestStart(details);
+ reporter.ReportFailure(details, "message");
+ reporter.ReportTestFinish(details, 1.0F);
+ CHECK(output.str().empty());
+
+ reporter.ReportSummary(1, 1, 1, 1.0f);
+ CHECK(!output.str().empty());
+}
+
+TEST_FIXTURE(XmlTestReporterFixture, EmptyReportSummaryFormat)
+{
+ reporter.ReportSummary(0, 0, 0, 0.1f);
+
+ const char *expected =
+ "<?xml version=\"1.0\"?>"
+ "<unittest-results tests=\"0\" failedtests=\"0\" failures=\"0\" time=\"0.1\">"
+ "</unittest-results>";
+
+ CHECK_EQUAL(expected, output.str().c_str());
+}
+
+TEST_FIXTURE(XmlTestReporterFixture, SingleSuccessfulTestReportSummaryFormat)
+{
+ TestDetails const details("TestName", "DefaultSuite", "", 0);
+
+ reporter.ReportTestStart(details);
+ reporter.ReportSummary(1, 0, 0, 0.1f);
+
+ const char *expected =
+ "<?xml version=\"1.0\"?>"
+ "<unittest-results tests=\"1\" failedtests=\"0\" failures=\"0\" time=\"0.1\">"
+ "<test suite=\"DefaultSuite\" name=\"TestName\" time=\"0\"/>"
+ "</unittest-results>";
+
+ CHECK_EQUAL(expected, output.str().c_str());
+}
+
+TEST_FIXTURE(XmlTestReporterFixture, SingleFailedTestReportSummaryFormat)
+{
+ TestDetails const details("A Test", "suite", "A File", 4321);
+
+ reporter.ReportTestStart(details);
+ reporter.ReportFailure(details, "A Failure");
+ reporter.ReportSummary(1, 1, 1, 0.1f);
+
+ const char *expected =
+ "<?xml version=\"1.0\"?>"
+ "<unittest-results tests=\"1\" failedtests=\"1\" failures=\"1\" time=\"0.1\">"
+ "<test suite=\"suite\" name=\"A Test\" time=\"0\">"
+ "<failure message=\"A File(4321) : A Failure\"/>"
+ "</test>"
+ "</unittest-results>";
+
+ CHECK_EQUAL(expected, output.str().c_str());
+}
+
+TEST_FIXTURE(XmlTestReporterFixture, FailureMessageIsXMLEscaped)
+{
+ TestDetails const details("TestName", "suite", "filename.h", 4321);
+
+ reporter.ReportTestStart(details);
+ reporter.ReportFailure(details, "\"\'&<>");
+ reporter.ReportTestFinish(details, 0.1f);
+ reporter.ReportSummary(1, 1, 1, 0.1f);
+
+ char const* expected =
+ "<?xml version=\"1.0\"?>"
+ "<unittest-results tests=\"1\" failedtests=\"1\" failures=\"1\" time=\"0.1\">"
+ "<test suite=\"suite\" name=\"TestName\" time=\"0.1\">"
+ "<failure message=\"filename.h(4321) : &quot;&apos;&amp;&lt;&gt;\"/>"
+ "</test>"
+ "</unittest-results>";
+
+ CHECK_EQUAL(expected, output.str().c_str());
+}
+
+TEST_FIXTURE(XmlTestReporterFixture, OneFailureAndOneSuccess)
+{
+ TestDetails const failedDetails("FailedTest", "suite", "fail.h", 1);
+ reporter.ReportTestStart(failedDetails);
+ reporter.ReportFailure(failedDetails, "expected 1 but was 2");
+ reporter.ReportTestFinish(failedDetails, 0.1f);
+
+ TestDetails const succeededDetails("SucceededTest", "suite", "", 0);
+ reporter.ReportTestStart(succeededDetails);
+ reporter.ReportTestFinish(succeededDetails, 1.0f);
+ reporter.ReportSummary(2, 1, 1, 1.1f);
+
+ char const* expected =
+ "<?xml version=\"1.0\"?>"
+ "<unittest-results tests=\"2\" failedtests=\"1\" failures=\"1\" time=\"1.1\">"
+ "<test suite=\"suite\" name=\"FailedTest\" time=\"0.1\">"
+ "<failure message=\"fail.h(1) : expected 1 but was 2\"/>"
+ "</test>"
+ "<test suite=\"suite\" name=\"SucceededTest\" time=\"1\"/>"
+ "</unittest-results>";
+
+ CHECK_EQUAL(expected, output.str().c_str());
+}
+
+TEST_FIXTURE(XmlTestReporterFixture, MultipleFailures)
+{
+ TestDetails const failedDetails1("FailedTest", "suite", "fail.h", 1);
+ TestDetails const failedDetails2("FailedTest", "suite", "fail.h", 31);
+
+ reporter.ReportTestStart(failedDetails1);
+ reporter.ReportFailure(failedDetails1, "expected 1 but was 2");
+ reporter.ReportFailure(failedDetails2, "expected one but was two");
+ reporter.ReportTestFinish(failedDetails1, 0.1f);
+
+ reporter.ReportSummary(1, 1, 2, 1.1f);
+
+ char const* expected =
+ "<?xml version=\"1.0\"?>"
+ "<unittest-results tests=\"1\" failedtests=\"1\" failures=\"2\" time=\"1.1\">"
+ "<test suite=\"suite\" name=\"FailedTest\" time=\"0.1\">"
+ "<failure message=\"fail.h(1) : expected 1 but was 2\"/>"
+ "<failure message=\"fail.h(31) : expected one but was two\"/>"
+ "</test>"
+ "</unittest-results>";
+
+ CHECK_EQUAL(expected, output.str().c_str());
+}
+
+}
+
+#endif