diff --git a/Makefile b/Makefile index 4f2ea9d..dfae28a 100644 --- a/Makefile +++ b/Makefile @@ -1,96 +1,96 @@ -CXX = g++ -CXXFLAGS ?= -g -Wall -W -ansi # -pedantic -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 = 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 diff --git a/TestUnitTestPP_vs6.dsp b/TestUnitTestPP_vs6.dsp new file mode 100644 index 0000000..1ac1a36 --- /dev/null +++ b/TestUnitTestPP_vs6.dsp @@ -0,0 +1,169 @@ +# Microsoft Developer Studio Project File - Name="TestUnitTestPP_vs6" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** 編集しないでください ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=TestUnitTestPP_vs6 - Win32 Debug +!MESSAGE これは有効なメイクファイルではありません。 このプロジェクトをビルドするためには NMAKE を使用してください。 +!MESSAGE [メイクファイルのエクスポート] コマンドを使用して実行してください +!MESSAGE +!MESSAGE NMAKE /f "TestUnitTestPP_vs6.mak". +!MESSAGE +!MESSAGE NMAKE の実行時に構成を指定できます +!MESSAGE コマンド ライン上でマクロの設定を定義します。例: +!MESSAGE +!MESSAGE NMAKE /f "TestUnitTestPP_vs6.mak" CFG="TestUnitTestPP_vs6 - Win32 Debug" +!MESSAGE +!MESSAGE 選択可能なビルド モード: +!MESSAGE +!MESSAGE "TestUnitTestPP_vs6 - Win32 Release" ("Win32 (x86) Console Application" 用) +!MESSAGE "TestUnitTestPP_vs6 - Win32 Debug" ("Win32 (x86) Console Application" 用) +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "TestUnitTestPP_vs6 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x411 /d "NDEBUG" +# ADD RSC /l 0x411 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "TestUnitTestPP_vs6 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x411 /d "_DEBUG" +# ADD RSC /l 0x411 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "TestUnitTestPP_vs6 - Win32 Release" +# Name "TestUnitTestPP_vs6 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\src\tests\Main.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestAssertHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestCheckMacros.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestChecks.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestCurrentTest.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestDeferredTestReporter.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestMemoryOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestTest.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestTestList.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestTestMacros.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestTestResults.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestTestRunner.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestTestSuite.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestTimeConstraint.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestTimeConstraintMacro.cpp +# End Source File +# Begin Source File + +SOURCE=".\src\tests\TestUnitTest++.cpp" +# End Source File +# Begin Source File + +SOURCE=.\src\tests\TestXmlTestReporter.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\src\tests\RecordingReporter.h +# End Source File +# Begin Source File + +SOURCE=.\src\tests\ScopedCurrentTest.h +# End Source File +# End Group +# End Target +# End Project diff --git a/UnitTestPP_vs6.dsp b/UnitTestPP_vs6.dsp new file mode 100644 index 0000000..ee8ce7d --- /dev/null +++ b/UnitTestPP_vs6.dsp @@ -0,0 +1,260 @@ +# Microsoft Developer Studio Project File - Name="UnitTestPP_vs6" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** 編集しないでください ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=UnitTestPP_vs6 - Win32 Debug +!MESSAGE これは有効なメイクファイルではありません。 このプロジェクトをビルドするためには NMAKE を使用してください。 +!MESSAGE [メイクファイルのエクスポート] コマンドを使用して実行してください +!MESSAGE +!MESSAGE NMAKE /f "UnitTestPP_vs6.mak". +!MESSAGE +!MESSAGE NMAKE の実行時に構成を指定できます +!MESSAGE コマンド ライン上でマクロの設定を定義します。例: +!MESSAGE +!MESSAGE NMAKE /f "UnitTestPP_vs6.mak" CFG="UnitTestPP_vs6 - Win32 Debug" +!MESSAGE +!MESSAGE 選択可能なビルド モード: +!MESSAGE +!MESSAGE "UnitTestPP_vs6 - Win32 Release" ("Win32 (x86) Static Library" 用) +!MESSAGE "UnitTestPP_vs6 - Win32 Debug" ("Win32 (x86) Static Library" 用) +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "UnitTestPP_vs6 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x411 /d "NDEBUG" +# ADD RSC /l 0x411 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "UnitTestPP_vs6 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x411 /d "_DEBUG" +# ADD RSC /l 0x411 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "UnitTestPP_vs6 - Win32 Release" +# Name "UnitTestPP_vs6 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\src\AssertException.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\Checks.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\CurrentTest.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\DeferredTestReporter.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\DeferredTestResult.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\MemoryOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\ReportAssert.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\Test.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\TestDetails.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\TestList.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\TestReporter.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\TestReporterStdout.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\TestResults.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\TestRunner.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\TimeConstraint.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\XmlTestReporter.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\src\AssertException.h +# End Source File +# Begin Source File + +SOURCE=.\src\CheckMacros.h +# End Source File +# Begin Source File + +SOURCE=.\src\Checks.h +# End Source File +# Begin Source File + +SOURCE=.\src\Config.h +# End Source File +# Begin Source File + +SOURCE=.\src\CurrentTest.h +# End Source File +# Begin Source File + +SOURCE=.\src\DeferredTestReporter.h +# End Source File +# Begin Source File + +SOURCE=.\src\DeferredTestResult.h +# End Source File +# Begin Source File + +SOURCE=.\src\ExecuteTest.h +# End Source File +# Begin Source File + +SOURCE=.\src\MemoryOutStream.h +# End Source File +# Begin Source File + +SOURCE=.\src\ReportAssert.h +# End Source File +# Begin Source File + +SOURCE=.\src\Test.h +# End Source File +# Begin Source File + +SOURCE=.\src\TestDetails.h +# End Source File +# Begin Source File + +SOURCE=.\src\TestList.h +# End Source File +# Begin Source File + +SOURCE=.\src\TestMacros.h +# End Source File +# Begin Source File + +SOURCE=.\src\TestReporter.h +# End Source File +# Begin Source File + +SOURCE=.\src\TestReporterStdout.h +# End Source File +# Begin Source File + +SOURCE=.\src\TestResults.h +# End Source File +# Begin Source File + +SOURCE=.\src\TestRunner.h +# End Source File +# Begin Source File + +SOURCE=.\src\TestSuite.h +# End Source File +# Begin Source File + +SOURCE=.\src\TimeConstraint.h +# End Source File +# Begin Source File + +SOURCE=.\src\TimeHelpers.h +# End Source File +# Begin Source File + +SOURCE=".\src\UnitTest++.h" +# End Source File +# Begin Source File + +SOURCE=.\src\XmlTestReporter.h +# End Source File +# End Group +# Begin Group "Win32" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\Win32\TimeHelpers.cpp +# End Source File +# Begin Source File + +SOURCE=.\src\Win32\TimeHelpers.h +# End Source File +# End Group +# End Target +# End Project diff --git a/UnitTestPP_vs6.dsw b/UnitTestPP_vs6.dsw new file mode 100644 index 0000000..58e105a --- /dev/null +++ b/UnitTestPP_vs6.dsw @@ -0,0 +1,44 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# 警告: このワークスペース ファイル を編集または削除しないでください! + +############################################################################### + +Project: "TestUnitTestPP_vs6"=".\TestUnitTestPP_vs6.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name UnitTestPP_vs6 + End Project Dependency +}}} + +############################################################################### + +Project: "UnitTestPP_vs6"=".\UnitTestPP_vs6.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/docs/UnitTest++.html b/docs/UnitTest++.html index 9eb872d..4af04ec 100644 --- a/docs/UnitTest++.html +++ b/docs/UnitTest++.html @@ -1,260 +1,260 @@ - - - UnitTest++ in brief - - -

UnitTest++ in brief

-

Introduction

-

This little document serves as bare-bones documentation for UnitTest++.

- -

For background, goals and license details, see:

- - - -

The documentation, while sparse, aims to be practical, so it should give you enough info to get started using UnitTest++ as fast as possible.

- -

Building UnitTest++

-

Building UnitTest++ will be specific to each platform and build environment, but it should be straightforward.

- -

Building with Visual Studio

-

If you are using Visual Studio, go for either of the provided .sln files, depending on version. There are no prefabricated solutions for versions earlier than VS.NET 2003, but we have had reports of people building UnitTest++ with at least VS.NET 2002.

- -

Building with Make

-

The bundled makefile is written to build with g++. It also needs sed installed in the path, and to be able to use the mv and rm shell commands. The makefile should be usable on most Posix-like platforms.

- -

Do "make all" to generate a library and test executable. A final build step runs all unit tests to make sure that the result works as expected.

- -

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.

- -

Getting started

-

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

- -
-  // test.cpp
-  #include <UnitTest++.h>
-
-  TEST(FailSpectacularly)
-  {
-    CHECK(false);
-  }
-
-  int main()
-  {
-    return UnitTest::RunAllTests();
-  }
-
- -

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.

- -

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

- -
-  .\test.cpp(5): error: Failure in FailSpectacularly: false
-  FAILED: 1 out of 1 tests failed (1 failures).
-  Test time: 0.00 seconds.
-
- -

UnitTest++ attempts to report every failure in an IDE-friendly format, depending on platform (e.g. you can double-click it in Visual Studio's error list.) The exit code will be the number of failed tests, so that a failed test run always returns a non-zero exit code.

- -

Test macros

-

To add a test, simply put the following code in a .cpp file of your choice:

- -
-  TEST(YourTestName)
-  {
-  }
-
- -

The TEST macro contains enough machinery to turn this slightly odd-looking syntax into legal C++, and automatically register the test in a global list. This test list forms the basis of what is executed by RunAllTests().

- -

If you want to re-use a set of test data for more than one test, or provide setup/teardown for tests, you can use the TEST_FIXTURE macro instead. The macro requires that you pass it a class name that it will instantiate, so any setup and teardown code should be in its constructor and destructor.

- -
-  struct SomeFixture
-  {
-    SomeFixture() { /* some setup */ }
-    ~SomeFixture() { /* some teardown */ }
-
-    int testData;
-  };
- 
-  TEST_FIXTURE(SomeFixture, YourTestName)
-  {
-    int temp = testData;
-  }
-
- -

Note how members of the fixture are used as if they are a part of the test, since the macro-generated test class derives from the provided fixture class.

- -

Suite macros

-

Tests can be grouped into suites, using the SUITE macro. A suite serves as a namespace for test names, so that the same test name can be used in two difference contexts.

- -
-  SUITE(YourSuiteName)
-  {
-    TEST(YourTestName)
-    {
-    }
-
-    TEST(YourOtherTestName)
-    {
-    }
-  }
-
- -

This will place the tests into a C++ namespace called YourSuiteName, and make the suite name available to UnitTest++. RunAllTests() can be called for a specific suite name, so you can use this to build named groups of tests to be run together.

- -

Simple check macros

-

In test cases, we want to check the results of our system under test. UnitTest++ provides a number of check macros that handle comparison and proper failure reporting.

- -

The most basic variety is the boolean CHECK macro:

- -
-  CHECK(false); // fails
-
- -

It will fail if the boolean expression evaluates to false.

- -

For equality checks, it's generally better to use CHECK_EQUAL:

- -
-  CHECK_EQUAL(10, 20); // fails
-  CHECK_EQUAL("foo", "bar"); // fails
-
- -

Note how CHECK_EQUAL is overloaded for C strings, so you don't have to resort to strcmp or similar. There is no facility for case-insensitive comparison or string searches, so you may have to drop down to a plain boolean CHECK with help from the CRT:

- -
-  CHECK(std::strstr("zaza", "az") != 0); // succeeds
-
- -

For floating-point comparison, equality isn't necessarily well-defined, so you should prefer the CHECK_CLOSE macro:

- -
-  CHECK_CLOSE(3.14, 3.1415, 0.01); // succeeds
-
- -

All of the macros are tailored to avoid unintended side-effects, for example:

- -
-  TEST(CheckMacrosHaveNoSideEffects)
-  {
-    int i = 4;
-    CHECK_EQUAL(5, ++i); // succeeds
-    CHECK_EQUAL(5, i); // succeeds
-  }
-
- -

The check macros guarantee that the ++i expression isn't repeated internally, as demonstrated above.

- -

Array check macros

-

There is a set of check macros for array comparison as well:

- -
-  const float oned[2] = { 10, 20 };
-  CHECK_ARRAY_EQUAL(oned, oned, 2); // succeeds
-  CHECK_ARRAY_CLOSE(oned, oned, 2, 0.00); // succeeds
-
-  const float twod[2][3] = { {0, 1, 2}, {2, 3, 4} };
-  CHECK_ARRAY2D_CLOSE(twod, twod, 2, 3, 0.00); // succeeds
-
- -

The array equal macro compares elements using operator==, so CHECK_ARRAY_EQUAL won't work for an array of C strings, for example.

- -

The array close macros are similar to the regular CHECK_CLOSE macro, and are really only useful for scalar types, that can be compared in terms of a difference between two array elements.

- -

Note that the one-dimensional array macros work for std::vector as well, as it can be indexed just as a C array.

- -

Exception check macros

-

Finally, there's a CHECK_THROW macro, which asserts that its enclosed expression throws the specified type:

- -
-  struct TestException {};
-  CHECK_THROW(throw TestException(), TestException); // succeeds
-
- -

UnitTest++ natively catches exceptions if your test code doesn't. So if your code under test throws any exception UnitTest++ will fail the test and report either using the what() method for std::exception derivatives or just a plain message for unknown exception types.

- -

Should your test or code raise an irrecoverable error (an Access Violation on Win32, for example, or a signal on Linux), UnitTest++ will attempt to map them to an exception and fail the test, just as for other unhandled exceptions.

- -

Time constraints

-

UnitTest++ can fail a test if it takes too long to complete, using so-called time constraints.

- -

They come in two flavors; local and global time constraints.

- -

Local time constraints are limited to the current scope, like so:

- -
-  TEST(YourTimedTest)
-  {
-     // Lengthy setup...
-
-     {
-        UNITTEST_TIME_CONSTRAINT(50);
-
-        // Do time-critical stuff
-     }
-
-     // Lengthy teardown...
-  }
-
- -

The test will fail if the "Do time-critical stuff" block takes longer than 50 ms to complete. The time-consuming setup and teardown are not measured, since the time constraint is scope-bound. It's perfectly valid to have multiple local time constraints in the same test, as long as there is only one per block.

- -

A global time constraint, on the other hand, requires that all of the tests in a test run are faster than a specified amount of time. This allows you, when you run a suite of tests, to ask UnitTest++ to fail it entirely if any test exceeds the global constraint. The max time is passed as a parameter to an overload of RunAllTests().

- -

If you want to use a global time constraint, but have one test that is notoriously slow, you can exempt it from inspection by using the UNITTEST_TIME_CONSTRAINT_EXEMPT macro anywhere inside the test body.

- -
-  TEST(NotoriouslySlowTest)
-  {
-     UNITTEST_TIME_CONSTRAINT_EXEMPT();
-
-     // Oh boy, this is going to take a while
-     ...
-  }
-
- -

Test runners

-

The RunAllTests() function has an overload that lets you customize the behavior of the runner, such as global time constraints, custom reporters, which suite to run, etc.

- -
-  int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int const maxTestTimeInMs);
-
- -

If you attempt to pass custom parameters to RunAllTests(), note that the list parameter should have the value Test::GetTestList().

- -

The parameterless RunAllTests() is a simple wrapper for this one, with sensible defaults.

- -

Example setup

-

How to create a new test project varies depending on your environment, but here are some directions on common file structure and usage.

- -

The general idea is that you keep one Main.cpp file with the entry-point which calls RunAllTests().

- -

Then you can simply compile and link new .cpp files at will, typically one per test suite.

- -
-   + ShaverTests/
-   |
-   +- Main.cpp
-   |
-   +- TestBrush.cpp   
-   +- TestEngine.cpp
-   +- TestRazor.cpp   
-
- -

Each of the Test*.cpp files will contain one or more TEST macro incantations with the associated test code. There are no source-level dependencies between Main.cpp and Test*.cpp, as the TEST macro handles the registration and setup necessary for RunAllTests() to find all tests compiled into the same final executable.

- -

UnitTest++ does not require this structure, even if this is how the library itself does it. As long as your test project contains one or more TESTs and calls RunAllTests() at one point or another, it will be handled by UnitTest++.

- -

It's common to make the generated executable start as a post-build step, so that merely building your test project will run the tests as well. Since the exit code is the count of failures, a failed test will generally break the build, as most build engines will fail a build if any step returns a non-zero exit code.

- - + + + UnitTest++ in brief + + +

UnitTest++ in brief

+

Introduction

+

This little document serves as bare-bones documentation for UnitTest++.

+ +

For background, goals and license details, see:

+ + + +

The documentation, while sparse, aims to be practical, so it should give you enough info to get started using UnitTest++ as fast as possible.

+ +

Building UnitTest++

+

Building UnitTest++ will be specific to each platform and build environment, but it should be straightforward.

+ +

Building with Visual Studio

+

If you are using Visual Studio, go for either of the provided .sln files, depending on version. There are no prefabricated solutions for versions earlier than VS.NET 2003, but we have had reports of people building UnitTest++ with at least VS.NET 2002.

+ +

Building with Make

+

The bundled makefile is written to build with g++. It also needs sed installed in the path, and to be able to use the mv and rm shell commands. The makefile should be usable on most Posix-like platforms.

+ +

Do "make all" to generate a library and test executable. A final build step runs all unit tests to make sure that the result works as expected.

+ +

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.

+ +

Getting started

+

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

+ +
+  // test.cpp
+  #include <UnitTest++.h>
+
+  TEST(FailSpectacularly)
+  {
+    CHECK(false);
+  }
+
+  int main()
+  {
+    return UnitTest::RunAllTests();
+  }
+
+ +

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.

+ +

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

+ +
+  .\test.cpp(5): error: Failure in FailSpectacularly: false
+  FAILED: 1 out of 1 tests failed (1 failures).
+  Test time: 0.00 seconds.
+
+ +

UnitTest++ attempts to report every failure in an IDE-friendly format, depending on platform (e.g. you can double-click it in Visual Studio's error list.) The exit code will be the number of failed tests, so that a failed test run always returns a non-zero exit code.

+ +

Test macros

+

To add a test, simply put the following code in a .cpp file of your choice:

+ +
+  TEST(YourTestName)
+  {
+  }
+
+ +

The TEST macro contains enough machinery to turn this slightly odd-looking syntax into legal C++, and automatically register the test in a global list. This test list forms the basis of what is executed by RunAllTests().

+ +

If you want to re-use a set of test data for more than one test, or provide setup/teardown for tests, you can use the TEST_FIXTURE macro instead. The macro requires that you pass it a class name that it will instantiate, so any setup and teardown code should be in its constructor and destructor.

+ +
+  struct SomeFixture
+  {
+    SomeFixture() { /* some setup */ }
+    ~SomeFixture() { /* some teardown */ }
+
+    int testData;
+  };
+ 
+  TEST_FIXTURE(SomeFixture, YourTestName)
+  {
+    int temp = testData;
+  }
+
+ +

Note how members of the fixture are used as if they are a part of the test, since the macro-generated test class derives from the provided fixture class.

+ +

Suite macros

+

Tests can be grouped into suites, using the SUITE macro. A suite serves as a namespace for test names, so that the same test name can be used in two difference contexts.

+ +
+  SUITE(YourSuiteName)
+  {
+    TEST(YourTestName)
+    {
+    }
+
+    TEST(YourOtherTestName)
+    {
+    }
+  }
+
+ +

This will place the tests into a C++ namespace called YourSuiteName, and make the suite name available to UnitTest++. RunAllTests() can be called for a specific suite name, so you can use this to build named groups of tests to be run together.

+ +

Simple check macros

+

In test cases, we want to check the results of our system under test. UnitTest++ provides a number of check macros that handle comparison and proper failure reporting.

+ +

The most basic variety is the boolean CHECK macro:

+ +
+  CHECK(false); // fails
+
+ +

It will fail if the boolean expression evaluates to false.

+ +

For equality checks, it's generally better to use CHECK_EQUAL:

+ +
+  CHECK_EQUAL(10, 20); // fails
+  CHECK_EQUAL("foo", "bar"); // fails
+
+ +

Note how CHECK_EQUAL is overloaded for C strings, so you don't have to resort to strcmp or similar. There is no facility for case-insensitive comparison or string searches, so you may have to drop down to a plain boolean CHECK with help from the CRT:

+ +
+  CHECK(std::strstr("zaza", "az") != 0); // succeeds
+
+ +

For floating-point comparison, equality isn't necessarily well-defined, so you should prefer the CHECK_CLOSE macro:

+ +
+  CHECK_CLOSE(3.14, 3.1415, 0.01); // succeeds
+
+ +

All of the macros are tailored to avoid unintended side-effects, for example:

+ +
+  TEST(CheckMacrosHaveNoSideEffects)
+  {
+    int i = 4;
+    CHECK_EQUAL(5, ++i); // succeeds
+    CHECK_EQUAL(5, i); // succeeds
+  }
+
+ +

The check macros guarantee that the ++i expression isn't repeated internally, as demonstrated above.

+ +

Array check macros

+

There is a set of check macros for array comparison as well:

+ +
+  const float oned[2] = { 10, 20 };
+  CHECK_ARRAY_EQUAL(oned, oned, 2); // succeeds
+  CHECK_ARRAY_CLOSE(oned, oned, 2, 0.00); // succeeds
+
+  const float twod[2][3] = { {0, 1, 2}, {2, 3, 4} };
+  CHECK_ARRAY2D_CLOSE(twod, twod, 2, 3, 0.00); // succeeds
+
+ +

The array equal macro compares elements using operator==, so CHECK_ARRAY_EQUAL won't work for an array of C strings, for example.

+ +

The array close macros are similar to the regular CHECK_CLOSE macro, and are really only useful for scalar types, that can be compared in terms of a difference between two array elements.

+ +

Note that the one-dimensional array macros work for std::vector as well, as it can be indexed just as a C array.

+ +

Exception check macros

+

Finally, there's a CHECK_THROW macro, which asserts that its enclosed expression throws the specified type:

+ +
+  struct TestException {};
+  CHECK_THROW(throw TestException(), TestException); // succeeds
+
+ +

UnitTest++ natively catches exceptions if your test code doesn't. So if your code under test throws any exception UnitTest++ will fail the test and report either using the what() method for std::exception derivatives or just a plain message for unknown exception types.

+ +

Should your test or code raise an irrecoverable error (an Access Violation on Win32, for example, or a signal on Linux), UnitTest++ will attempt to map them to an exception and fail the test, just as for other unhandled exceptions.

+ +

Time constraints

+

UnitTest++ can fail a test if it takes too long to complete, using so-called time constraints.

+ +

They come in two flavors; local and global time constraints.

+ +

Local time constraints are limited to the current scope, like so:

+ +
+  TEST(YourTimedTest)
+  {
+     // Lengthy setup...
+
+     {
+        UNITTEST_TIME_CONSTRAINT(50);
+
+        // Do time-critical stuff
+     }
+
+     // Lengthy teardown...
+  }
+
+ +

The test will fail if the "Do time-critical stuff" block takes longer than 50 ms to complete. The time-consuming setup and teardown are not measured, since the time constraint is scope-bound. It's perfectly valid to have multiple local time constraints in the same test, as long as there is only one per block.

+ +

A global time constraint, on the other hand, requires that all of the tests in a test run are faster than a specified amount of time. This allows you, when you run a suite of tests, to ask UnitTest++ to fail it entirely if any test exceeds the global constraint. The max time is passed as a parameter to an overload of RunAllTests().

+ +

If you want to use a global time constraint, but have one test that is notoriously slow, you can exempt it from inspection by using the UNITTEST_TIME_CONSTRAINT_EXEMPT macro anywhere inside the test body.

+ +
+  TEST(NotoriouslySlowTest)
+  {
+     UNITTEST_TIME_CONSTRAINT_EXEMPT();
+
+     // Oh boy, this is going to take a while
+     ...
+  }
+
+ +

Test runners

+

The RunAllTests() function has an overload that lets you customize the behavior of the runner, such as global time constraints, custom reporters, which suite to run, etc.

+ +
+  int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int const maxTestTimeInMs);
+
+ +

If you attempt to pass custom parameters to RunAllTests(), note that the list parameter should have the value Test::GetTestList().

+ +

The parameterless RunAllTests() is a simple wrapper for this one, with sensible defaults.

+ +

Example setup

+

How to create a new test project varies depending on your environment, but here are some directions on common file structure and usage.

+ +

The general idea is that you keep one Main.cpp file with the entry-point which calls RunAllTests().

+ +

Then you can simply compile and link new .cpp files at will, typically one per test suite.

+ +
+   + ShaverTests/
+   |
+   +- Main.cpp
+   |
+   +- TestBrush.cpp   
+   +- TestEngine.cpp
+   +- TestRazor.cpp   
+
+ +

Each of the Test*.cpp files will contain one or more TEST macro incantations with the associated test code. There are no source-level dependencies between Main.cpp and Test*.cpp, as the TEST macro handles the registration and setup necessary for RunAllTests() to find all tests compiled into the same final executable.

+ +

UnitTest++ does not require this structure, even if this is how the library itself does it. As long as your test project contains one or more TESTs and calls RunAllTests() at one point or another, it will be handled by UnitTest++.

+ +

It's common to make the generated executable start as a post-build step, so that merely building your test project will run the tests as well. Since the exit code is the count of failures, a failed test will generally break the build, as most build engines will fail a build if any step returns a non-zero exit code.

+ + \ No newline at end of file diff --git a/src/DeferredTestReporter.cpp b/src/DeferredTestReporter.cpp index 93dd7d6..ae77b03 100644 --- a/src/DeferredTestReporter.cpp +++ b/src/DeferredTestReporter.cpp @@ -1,29 +1,28 @@ -#include "DeferredTestReporter.h" -#include "TestDetails.h" -#include "Config.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 "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; +} diff --git a/src/DeferredTestReporter.h b/src/DeferredTestReporter.h index d294169..615a24e 100644 --- a/src/DeferredTestReporter.h +++ b/src/DeferredTestReporter.h @@ -1,28 +1,29 @@ -#ifndef UNITTEST_DEFERREDTESTREPORTER_H -#define UNITTEST_DEFERREDTESTREPORTER_H - -#include "TestReporter.h" -#include "DeferredTestResult.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 "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 diff --git a/src/DeferredTestResult.cpp b/src/DeferredTestResult.cpp index 3cfb8ba..c2daa25 100644 --- a/src/DeferredTestResult.cpp +++ b/src/DeferredTestResult.cpp @@ -1,25 +1,25 @@ -#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 "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) +{ +} + +} diff --git a/src/DeferredTestResult.h b/src/DeferredTestResult.h index 9b06346..d0a1dab 100644 --- a/src/DeferredTestResult.h +++ b/src/DeferredTestResult.h @@ -1,29 +1,32 @@ -#ifndef UNITTEST_DEFERREDTESTRESULT_H -#define UNITTEST_DEFERREDTESTRESULT_H - -#include -#include - -namespace UnitTest -{ - -struct DeferredTestResult -{ - DeferredTestResult(); - DeferredTestResult(char const* suite, char const* test); - - std::string suiteName; - std::string testName; - std::string failureFile; - - typedef std::pair< int, std::string > Failure; - typedef std::vector< Failure > FailureVec; - FailureVec failures; - - float timeElapsed; - bool failed; -}; - -} - -#endif //UNITTEST_DEFERREDTESTRESULT_H +#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 diff --git a/src/MemoryOutStream.h b/src/MemoryOutStream.h index eb71680..37a4afd 100644 --- a/src/MemoryOutStream.h +++ b/src/MemoryOutStream.h @@ -1,67 +1,68 @@ -#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() {} - 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" + +#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 diff --git a/src/Posix/TimeHelpers.cpp b/src/Posix/TimeHelpers.cpp index 039e141..65c6393 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); -} - - -int Timer::GetTimeInMs() const -{ - struct timeval currentTime; - gettimeofday(¤tTime, 0); - int const dsecs = currentTime.tv_sec - m_startTime.tv_sec; - int const dus = currentTime.tv_usec - m_startTime.tv_usec; - return dsecs*1000 + dus/1000; -} - - -void TimeHelpers::SleepMs (int ms) -{ - usleep(ms * 1000); -} - -} +#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 290748c..528e62e 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(); - int 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 f72ea83..c91f4f6 100644 --- a/src/ReportAssert.cpp +++ b/src/ReportAssert.cpp @@ -1,10 +1,11 @@ -#include "AssertException.h" - -namespace UnitTest { - -void ReportAssert(char const* description, char const* filename, int lineNumber) -{ - throw AssertException(description, filename, lineNumber); -} - -} +#include "ReportAssert.h" +#include "AssertException.h" + +namespace UnitTest { + +void ReportAssert(char const* description, char const* filename, int lineNumber) +{ + throw AssertException(description, filename, lineNumber); +} + +} diff --git a/src/TestReporterStdout.cpp b/src/TestReporterStdout.cpp index 26cf5bb..563113c 100644 --- a/src/TestReporterStdout.cpp +++ b/src/TestReporterStdout.cpp @@ -1,41 +1,46 @@ -#include "TestReporterStdout.h" -#include - -#include "TestDetails.h" - -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(_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); +} + +} diff --git a/src/TestRunner.cpp b/src/TestRunner.cpp index 0fc3c21..466265d 100644 --- a/src/TestRunner.cpp +++ b/src/TestRunner.cpp @@ -1,76 +1,76 @@ -#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; +} + +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); +} + +} diff --git a/src/TestRunner.h b/src/TestRunner.h index 82cc827..672355d 100644 --- a/src/TestRunner.h +++ b/src/TestRunner.h @@ -1,61 +1,59 @@ -#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; + +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 diff --git a/src/TestSuite.h b/src/TestSuite.h index 70c3309..dd3717e 100644 --- a/src/TestSuite.h +++ b/src/TestSuite.h @@ -1,14 +1,14 @@ -#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 20ed5a5..b313be7 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() +{ + 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()); + } +} + +} diff --git a/src/Win32/TimeHelpers.cpp b/src/Win32/TimeHelpers.cpp index 658f002..69d0d88 100644 --- a/src/Win32/TimeHelpers.cpp +++ b/src/Win32/TimeHelpers.cpp @@ -1,50 +1,47 @@ -#include "TimeHelpers.h" -#include - -namespace UnitTest { - -Timer::Timer() - : m_startTime(0) - , m_threadHandle(::GetCurrentThread()) -{ -#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(); -} - -int Timer::GetTimeInMs() const -{ - __int64 const elapsedTime = GetTime() - m_startTime; - double const seconds = double(elapsedTime) / double(m_frequency); - return int(seconds * 1000.0f); -} - -__int64 Timer::GetTime() const -{ - LARGE_INTEGER curTime; - ::SetThreadAffinityMask(m_threadHandle, 1); - ::QueryPerformanceCounter(&curTime); - ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask); - return curTime.QuadPart; -} - - - -void TimeHelpers::SleepMs(int const ms) -{ - ::Sleep(ms); -} - -} +#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); +} + +} diff --git a/src/Win32/TimeHelpers.h b/src/Win32/TimeHelpers.h index f7503f2..088de24 100644 --- a/src/Win32/TimeHelpers.h +++ b/src/Win32/TimeHelpers.h @@ -1,48 +1,48 @@ -#ifndef UNITTEST_TIMEHELPERS_H -#define UNITTEST_TIMEHELPERS_H - -#include "../Config.h" - - -#ifdef UNITTEST_MINGW - #ifndef __int64 - #define __int64 long long - #endif -#endif - -namespace UnitTest { - -class Timer -{ -public: - Timer(); - void Start(); - int GetTimeInMs() const; - -private: - __int64 GetTime() const; - - void* m_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" + + +#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 diff --git a/src/tests/TestTimeConstraintMacro.cpp b/src/tests/TestTimeConstraintMacro.cpp index c8f0aba..785c6ce 100644 --- a/src/tests/TestTimeConstraintMacro.cpp +++ b/src/tests/TestTimeConstraintMacro.cpp @@ -1,35 +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")); -} - -} +#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")); +} + +}