diff --git a/Makefile b/Makefile index dfae28a..205dedc 100644 --- a/Makefile +++ b/Makefile @@ -1,96 +1,100 @@ -CXX = g++ -CXXFLAGS ?= -g -Wall -W -Winline -ansi -LDFLAGS ?= -SED = sed -MV = mv -RM = rm - -.SUFFIXES: .o .cpp - -lib = libUnitTest++.a -test = TestUnitTest++ - -src = src/AssertException.cpp \ - src/Test.cpp \ - src/Checks.cpp \ - src/TestRunner.cpp \ - src/TestResults.cpp \ - src/TestReporter.cpp \ - src/TestReporterStdout.cpp \ - src/ReportAssert.cpp \ - src/TestList.cpp \ - src/TimeConstraint.cpp \ - src/TestDetails.cpp \ - src/MemoryOutStream.cpp \ - src/DeferredTestReporter.cpp \ - src/DeferredTestResult.cpp \ - src/XmlTestReporter.cpp \ - src/CurrentTest.cpp - -ifeq ($(MSYSTEM), MINGW32) - src += src/Win32/TimeHelpers.cpp -else - src += src/Posix/SignalTranslator.cpp \ - src/Posix/TimeHelpers.cpp -endif - -test_src = src/tests/Main.cpp \ - src/tests/TestAssertHandler.cpp \ - src/tests/TestChecks.cpp \ - src/tests/TestUnitTest++.cpp \ - src/tests/TestTest.cpp \ - src/tests/TestTestResults.cpp \ - src/tests/TestTestRunner.cpp \ - src/tests/TestCheckMacros.cpp \ - src/tests/TestTestList.cpp \ - src/tests/TestTestMacros.cpp \ - src/tests/TestTimeConstraint.cpp \ - src/tests/TestTimeConstraintMacro.cpp \ - src/tests/TestMemoryOutStream.cpp \ - src/tests/TestDeferredTestReporter.cpp \ - src/tests/TestXmlTestReporter.cpp \ - src/tests/TestCurrentTest.cpp - -objects = $(patsubst %.cpp, %.o, $(src)) -test_objects = $(patsubst %.cpp, %.o, $(test_src)) -dependencies = $(subst .o,.d,$(objects)) -test_dependencies = $(subst .o,.d,$(test_objects)) - -define make-depend - $(CXX) $(CXXFLAGS) -M $1 | \ - $(SED) -e 's,\($(notdir $2)\) *:,$(dir $2)\1: ,' > $3.tmp - $(SED) -e 's/#.*//' \ - -e 's/^[^:]*: *//' \ - -e 's/ *\\$$//' \ - -e '/^$$/ d' \ - -e 's/$$/ :/' $3.tmp >> $3.tmp - $(MV) $3.tmp $3 -endef - - -all: $(test) - - -$(lib): $(objects) - @echo Creating $(lib) library... - @ar cr $(lib) $(objects) - -$(test): $(lib) $(test_objects) - @echo Linking $(test)... - @$(CXX) $(LDFLAGS) -o $(test) $(test_objects) $(lib) - @echo Running unit tests... - @./$(test) - -clean: - -@$(RM) $(objects) $(test_objects) $(dependencies) $(test_dependencies) $(test) $(lib) 2> /dev/null - -%.o : %.cpp - @echo $< - @$(call make-depend,$<,$@,$(subst .o,.d,$@)) - @$(CXX) $(CXXFLAGS) -c $< -o $(patsubst %.cpp, %.o, $<) - - -ifneq "$(MAKECMDGOALS)" "clean" --include $(dependencies) --include $(test_dependencies) -endif +CXX = g++ +CXXFLAGS ?= -g -Wall -W -Winline -ansi +LDFLAGS ?= +SED = sed +MV = mv +RM = rm + +.SUFFIXES: .o .cpp + +lib = libunittestpp.a +test = test-unittestpp + +src = src/AssertException.cpp \ + src/Test.cpp \ + src/Checks.cpp \ + src/TestRunner.cpp \ + src/TestResults.cpp \ + src/TestReporter.cpp \ + src/TestReporterStdout.cpp \ + src/ReportAssert.cpp \ + src/TestList.cpp \ + src/TimeConstraint.cpp \ + src/TestDetails.cpp \ + src/MemoryOutStream.cpp \ + src/DeferredTestReporter.cpp \ + src/DeferredTestResult.cpp \ + src/XmlTestReporter.cpp \ + src/CurrentTest.cpp \ + src/CompositeTestReporter.cpp + +ifeq ($(MSYSTEM), MINGW32) + src += src/Win32/TimeHelpers.cpp +else + src += src/Posix/SignalTranslator.cpp \ + src/Posix/TimeHelpers.cpp +endif + +test_src = src/tests/Main.cpp \ + src/tests/TestAssertHandler.cpp \ + src/tests/TestChecks.cpp \ + src/tests/TestUnitTestPP.cpp \ + src/tests/TestTest.cpp \ + src/tests/TestTestResults.cpp \ + src/tests/TestTestRunner.cpp \ + src/tests/TestCheckMacros.cpp \ + src/tests/TestTestList.cpp \ + src/tests/TestTestMacros.cpp \ + src/tests/TestTimeConstraint.cpp \ + src/tests/TestTimeConstraintMacro.cpp \ + src/tests/TestMemoryOutStream.cpp \ + src/tests/TestDeferredTestReporter.cpp \ + src/tests/TestXmlTestReporter.cpp \ + src/tests/TestCurrentTest.cpp \ + src/tests/TestCompositeTestReporter.cpp + +objects = $(patsubst %.cpp, %.o, $(src)) +test_objects = $(patsubst %.cpp, %.o, $(test_src)) +dependencies = $(subst .o,.d,$(objects)) +test_dependencies = $(subst .o,.d,$(test_objects)) + +define make-depend + $(CXX) $(CXXFLAGS) -M $1 | \ + $(SED) -e 's,\($(notdir $2)\) *:,$(dir $2)\1: ,' > $3.tmp + $(SED) -e 's/#.*//' \ + -e 's/^[^:]*: *//' \ + -e 's/ *\\$$//' \ + -e '/^$$/ d' \ + -e 's/$$/ :/' $3.tmp >> $3.tmp + $(MV) $3.tmp $3 +endef + + +all: $(test) + + +$(lib): $(objects) + @mkdir -p lib/win32_gcc_debug + @echo Creating $(lib) library... + @ar cr lib/win32_gcc_debug/$(lib) $(objects) + +$(test): $(lib) $(test_objects) + @mkdir -p bin/win32_gcc_static_debug + @echo Linking $(test)... + @$(CXX) $(LDFLAGS) -o bin/win32_gcc_static_debug/$(test) $(test_objects) lib/win32_gcc_debug/$(lib) + @echo Running unit tests... + @bin/win32_gcc_static_debug/$(test) + +clean: + -@$(RM) $(objects) $(test_objects) $(dependencies) $(test_dependencies) $(test) $(lib) 2> /dev/null + +%.o : %.cpp + @echo $< + @$(call make-depend,$<,$@,$(subst .o,.d,$@)) + @$(CXX) $(CXXFLAGS) -c $< -o $(patsubst %.cpp, %.o, $<) + + +ifneq "$(MAKECMDGOALS)" "clean" +-include $(dependencies) +-include $(test_dependencies) +endif diff --git a/README b/README index d1cd35c..1389cc6 100644 --- a/README +++ b/README @@ -52,7 +52,7 @@ Version 1.2 (2006-10-29) - Added named test suites - Added CHECK_ARRAY2D_CLOSE - Posix library name is libUnitTest++.a now -- Floating point numbers are postfixed with f in the failure reports +- Floating point numbers are postfixed with 'f' in the failure reports Version 1.1 (2006-04-18) - CHECK macros do not have side effects even if one of the parameters changes state diff --git a/TestUnitTest++.vsnet2003.vcproj b/TestUnitTest++.vsnet2003.vcproj index 6dcd025..fbc4154 100644 --- a/TestUnitTest++.vsnet2003.vcproj +++ b/TestUnitTest++.vsnet2003.vcproj @@ -163,7 +163,7 @@ RelativePath=".\src\tests\TestTimeConstraintMacro.cpp"> + RelativePath=".\src\tests\TestUnitTestPP.cpp"> diff --git a/TestUnitTest++.vsnet2005.vcproj b/TestUnitTest++.vsnet2005.vcproj index 25d5ba6..aa8f95b 100644 --- a/TestUnitTest++.vsnet2005.vcproj +++ b/TestUnitTest++.vsnet2005.vcproj @@ -243,7 +243,7 @@ > + RelativePath=".\src\unittestpp.h"> diff --git a/UnitTest++.vsnet2005.vcproj b/UnitTest++.vsnet2005.vcproj index 4efb687..9c56365 100644 --- a/UnitTest++.vsnet2005.vcproj +++ b/UnitTest++.vsnet2005.vcproj @@ -301,7 +301,7 @@ > Packaging

You'll probably want to keep the generated library in a shared space in source control, so you can reuse it for multiple test projects. A redistributable package of UnitTest++ would consist of the generated library file, and all of the header files in UnitTest++/src/ and its per-platform subfolders. The tests directory only contains the unit tests for the library, and need not be included.

Using UnitTest++

-

The source code for UnitTest++ comes with a full test suite written using UnitTest++. This is a great place to learn techniques for testing. There is one sample .cpp file: UnitTest++/src/tests/TestUnitTest++.cpp. It covers most of UnitTest++'s features in an easy-to-grasp context, so start there if you want a quick overview of typical usage.

+

The source code for UnitTest++ comes with a full test suite written using UnitTest++. This is a great place to learn techniques for testing. There is one sample .cpp file: UnitTest++/src/tests/TestUnitTestPP.cpp. It covers most of UnitTest++'s features in an easy-to-grasp context, so start there if you want a quick overview of typical usage.

Getting started

Listed below is a minimal C++ program to run a failing test through UnitTest++.

   // test.cpp
-  #include <UnitTest++.h>
+  #include <unittestpp.h>
 
   TEST(FailSpectacularly)
   {
@@ -51,7 +51,7 @@ 

Getting started

}
-

UnitTest++.h is a facade header for UnitTest++, so including that should get you all features of the library. All classes and free functions are placed in namespace UnitTest, so you need to either qualify their full names (as with RunAllTests() in the example) or add a using namespace UnitTest; statement in your .cpp files. Note that any mention of UnitTest++ functions and classes in this document assume that the UnitTest namespace has been opened.

+

unittestpp.h is a facade header for UnitTest++, so including that should get you all features of the library. All classes and free functions are placed in namespace UnitTest, so you need to either qualify their full names (as with RunAllTests() in the example) or add a using namespace UnitTest; statement in your .cpp files. Note that any mention of UnitTest++ functions and classes in this document assume that the UnitTest namespace has been opened.

Compiling and linking this program with UnitTest++'s static library into an executable, and running it, will produce the following output (details may vary):

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