First commit for GitHub

This commit is contained in:
Phil Nash 2010-11-09 23:24:00 +00:00
commit d80260001b
27 changed files with 2471 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
Test/build
*.pbxuser
*.mode1v3

23
LICENSE_1_0.txt Normal file
View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

0
README Normal file
View File

37
Test/ClassTests.cpp Normal file
View File

@ -0,0 +1,37 @@
/*
* ClassTests.cpp
* Catch - Test
*
* Created by Phil on 09/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#include "catch.hpp"
namespace
{
class TestClass
{
std::string s;
public:
TestClass()
: s( "hello" )
{}
void succeedingCase()
{
EXPECT( s == "hello" );
}
void failingCase()
{
EXPECT( s == "world" );
}
};
}
METHOD_AS_TEST_CASE( TestClass::succeedingCase, "succeeding/TestClass/succeedingCase", "A method based test run that succeeds" );
METHOD_AS_TEST_CASE( TestClass::failingCase, "failing/TestClass/failingCase", "A method based test run that fails" );

185
Test/ConditionTests.cpp Normal file
View File

@ -0,0 +1,185 @@
/*
* ConditionTests.cpp
* Catch - Test
*
* Created by Phil on 08/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#include "catch.hpp"
#include <string>
struct TestData
{
TestData()
: int_seven( 7 ),
str_hello( "hello" ),
float_nine_point_one( 9.1f ),
double_pi( 3.1415926535 )
{}
int int_seven;
std::string str_hello;
float float_nine_point_one;
double double_pi;
};
// These tests all use the CHECK macro, which continues if the specific test fails.
// This allows us to see all results, even if an earlier check fails - which is
// particularly important for the "should fail" checks
// Equality tests
TEST_CASE( "succeeding/conditions/equality", "Equality checks that should succeed" )
{
TestData data;
CHECK( data.int_seven == 7 );
CHECK( data.float_nine_point_one == Approx( 9.1f ) );
CHECK( data.double_pi == Approx( 3.1415926535 ) );
CHECK( data.str_hello == "hello" );
CHECK( data.str_hello.size() == 5 );
double x = 1.1 + 0.1 + 0.1;
CHECK( x == Approx( 1.3 ) );
}
TEST_CASE( "failing/conditions/equality", "Equality checks that should fail" )
{
TestData data;
CHECK( data.int_seven == 6 );
CHECK( data.int_seven == 8 );
CHECK( data.int_seven == 0 );
CHECK( data.float_nine_point_one == Approx( 9.11f ) );
CHECK( data.float_nine_point_one == Approx( 9.0f ) );
CHECK( data.float_nine_point_one == 1 );
CHECK( data.float_nine_point_one == 0 );
CHECK( data.double_pi == Approx( 3.1415 ) );
CHECK( data.str_hello == "goodbye" );
CHECK( data.str_hello == "hell" );
CHECK( data.str_hello == "hello1" );
CHECK( data.str_hello.size() == 6 );
double x = 1.1 + 0.1 + 0.1;
CHECK( x == Approx( 1.301 ) );
}
TEST_CASE( "succeeding/conditions/inequality", "Inequality checks that should succeed" )
{
TestData data;
CHECK( data.int_seven != 6 );
CHECK( data.int_seven != 8 );
CHECK( data.float_nine_point_one != Approx( 9.11f ) );
CHECK( data.float_nine_point_one != Approx( 9.0f ) );
CHECK( data.float_nine_point_one != 1 );
CHECK( data.float_nine_point_one != 0 );
CHECK( data.double_pi != Approx( 3.1415 ) );
CHECK( data.str_hello != "goodbye" );
CHECK( data.str_hello != "hell" );
CHECK( data.str_hello != "hello1" );
CHECK( data.str_hello.size() != 6 );
}
TEST_CASE( "failing/conditions/inequality", "Inequality checks that should fails" )
{
TestData data;
CHECK( data.int_seven != 7 );
CHECK( data.float_nine_point_one != Approx( 9.1f ) );
CHECK( data.double_pi != Approx( 3.1415926535 ) );
CHECK( data.str_hello != "hello" );
CHECK( data.str_hello.size() != 5 );
}
// Ordering comparison tests
TEST_CASE( "succeeding/conditions/ordered", "Ordering comparison checks that should succeed" )
{
TestData data;
CHECK( data.int_seven < 8 );
CHECK( data.int_seven > 6 );
CHECK( data.int_seven > 0 );
CHECK( data.int_seven > -1 );
CHECK( data.int_seven >= 7 );
CHECK( data.int_seven >= 6 );
CHECK( data.int_seven <= 7 );
CHECK( data.int_seven <= 8 );
CHECK( data.float_nine_point_one > 9 );
CHECK( data.float_nine_point_one < 10 );
CHECK( data.float_nine_point_one < 9.2 );
CHECK( data.str_hello <= "hello" );
CHECK( data.str_hello >= "hello" );
CHECK( data.str_hello < "hellp" );
CHECK( data.str_hello < "z" );
CHECK( data.str_hello > "hellm" );
CHECK( data.str_hello > "a" );
}
TEST_CASE( "failing/conditions/ordered", "Ordering comparison checks that should fail" )
{
TestData data;
CHECK( data.int_seven > 7 );
CHECK( data.int_seven < 7 );
CHECK( data.int_seven > 8 );
CHECK( data.int_seven < 6 );
CHECK( data.int_seven < 0 );
CHECK( data.int_seven < -1 );
CHECK( data.int_seven >= 8 );
CHECK( data.int_seven <= 6 );
CHECK( data.float_nine_point_one < 9 );
CHECK( data.float_nine_point_one > 10 );
CHECK( data.float_nine_point_one > 9.2 );
CHECK( data.str_hello > "hello" );
CHECK( data.str_hello < "hello" );
CHECK( data.str_hello > "hellp" );
CHECK( data.str_hello > "z" );
CHECK( data.str_hello < "hellm" );
CHECK( data.str_hello < "a" );
CHECK( data.str_hello >= "z" );
CHECK( data.str_hello <= "a" );
}
// Not (!) tests
TEST_CASE( "succeeding/conditions/not", "'Not' checks that should succeed" )
{
bool falseValue = false;
CHECK( !false );
CHECK_NOT( false );
CHECK( !falseValue );
CHECK_NOT( falseValue );
CHECK( !(1 == 2) );
CHECK_NOT( 1 == 2 );
}
TEST_CASE( "failing/conditions/not", "'Not' checks that should fail" )
{
bool trueValue = true;
CHECK( !true );
CHECK_NOT( true );
CHECK( !trueValue );
CHECK_NOT( trueValue );
CHECK( !(1 == 1) );
CHECK_NOT( 1 == 1 );
}

58
Test/ExceptionTests.cpp Normal file
View File

@ -0,0 +1,58 @@
/*
* ExceptionTests.cpp
* Catch - Test
*
* Created by Phil on 09/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#include "catch.hpp"
#include <string>
namespace
{
int thisThrows()
{
throw std::domain_error( "expected exception" );
}
int thisDoesntThrow()
{
return 0;
}
}
TEST_CASE( "succeeding/exceptions/explicit", "When checked exceptions are thrown they can be expected or unexpected" )
{
CHECK_THROWS_AS( thisThrows(), std::domain_error );
CHECK_NOTHROW( thisDoesntThrow() );
EXPECT_THROWS( thisThrows() );
}
TEST_CASE( "failing/exceptions/explicit", "When checked exceptions are thrown they can be expected or unexpected" )
{
CHECK_THROWS_AS( thisThrows(), std::string );
CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error );
CHECK_NOTHROW( thisThrows() );
}
TEST_CASE( "failing/exceptions/implicit", "When unchecked exceptions are thrown they are always failures" )
{
throw std::domain_error( "unexpected exception" );
}
TEST_CASE( "succeeding/exceptions/implicit", "When unchecked exceptions are thrown, but caught, they do not affect the test" )
{
try
{
throw std::domain_error( "unexpected exception" );
}
catch(...)
{
}
}

24
Test/MessageTests.cpp Normal file
View File

@ -0,0 +1,24 @@
/*
* MessageTests.cpp
* Catch - Test
*
* Created by Phil on 09/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#include "catch.hpp"
TEST_CASE( "succeeding/message", "INFO and WARN do not abort tests" )
{
INFO( "this is a message" ); // This should output the message but continue
WARN( "this is a warning" ); // This should output the message but continue
}
TEST_CASE( "failing/message", "FAIL aborts the test" )
{
FAIL( "This is a failure" ); // This should output the message and abort
}

79
Test/Test.1 Normal file
View File

@ -0,0 +1,79 @@
.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
.\"See Also:
.\"man mdoc.samples for a complete listing of options
.\"man mdoc for the short list of editing options
.\"/usr/share/misc/mdoc.template
.Dd 02/11/2010 \" DATE
.Dt Test 1 \" Program name and manual section number
.Os Darwin
.Sh NAME \" Section Header - required - don't modify
.Nm Test,
.\" The following lines are read in generating the apropos(man -k) database. Use only key
.\" words here as the database is built based on the words here and in the .ND line.
.Nm Other_name_for_same_program(),
.Nm Yet another name for the same program.
.\" Use .Nm macro to designate other names for the documented program.
.Nd This line parsed for whatis database.
.Sh SYNOPSIS \" Section Header - required - don't modify
.Nm
.Op Fl abcd \" [-abcd]
.Op Fl a Ar path \" [-a path]
.Op Ar file \" [file]
.Op Ar \" [file ...]
.Ar arg0 \" Underlined argument - use .Ar anywhere to underline
arg2 ... \" Arguments
.Sh DESCRIPTION \" Section Header - required - don't modify
Use the .Nm macro to refer to your program throughout the man page like such:
.Nm
Underlining is accomplished with the .Ar macro like this:
.Ar underlined text .
.Pp \" Inserts a space
A list of items with descriptions:
.Bl -tag -width -indent \" Begins a tagged list
.It item a \" Each item preceded by .It macro
Description of item a
.It item b
Description of item b
.El \" Ends the list
.Pp
A list of flags and their descriptions:
.Bl -tag -width -indent \" Differs from above in tag removed
.It Fl a \"-a flag as a list item
Description of -a flag
.It Fl b
Description of -b flag
.El \" Ends the list
.Pp
.\" .Sh ENVIRONMENT \" May not be needed
.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1
.\" .It Ev ENV_VAR_1
.\" Description of ENV_VAR_1
.\" .It Ev ENV_VAR_2
.\" Description of ENV_VAR_2
.\" .El
.Sh FILES \" File used or created by the topic of the man page
.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact
.It Pa /usr/share/file_name
FILE_1 description
.It Pa /Users/joeuser/Library/really_long_file_name
FILE_2 description
.El \" Ends the list
.\" .Sh DIAGNOSTICS \" May not be needed
.\" .Bl -diag
.\" .It Diagnostic Tag
.\" Diagnostic informtion here.
.\" .It Diagnostic Tag
.\" Diagnostic informtion here.
.\" .El
.Sh SEE ALSO
.\" List links in ascending order by section, alphabetically within a section.
.\" Please do not reference files that do not exist without filing a bug report
.Xr a 1 ,
.Xr b 1 ,
.Xr c 1 ,
.Xr a 2 ,
.Xr b 2 ,
.Xr a 3 ,
.Xr b 3
.\" .Sh BUGS \" Document known, unremedied bugs
.\" .Sh HISTORY \" Document history if command behaves in a unique manner

View File

@ -0,0 +1,271 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 45;
objects = {
/* Begin PBXBuildFile section */
4AFC340C128099F5003A0C29 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AFC340B128099F5003A0C29 /* main.cpp */; };
4AFC38CD12887D80003A0C29 /* ConditionTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AFC38CC12887D80003A0C29 /* ConditionTests.cpp */; };
4AFC3A9912893C56003A0C29 /* ExceptionTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AFC3A9812893C56003A0C29 /* ExceptionTests.cpp */; };
4AFC3AA912893E54003A0C29 /* MessageTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AFC3AA812893E54003A0C29 /* MessageTests.cpp */; };
4AFC3B0B12894114003A0C29 /* ClassTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AFC3B0A12894114003A0C29 /* ClassTests.cpp */; };
4AFC3B671289C7E3003A0C29 /* TrickyTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AFC3B661289C7E3003A0C29 /* TrickyTests.cpp */; };
8DD76F6A0486A84900D96B5E /* Test.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859E8B029090EE04C91782 /* Test.1 */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
8DD76F6A0486A84900D96B5E /* Test.1 in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
4AFC340B128099F5003A0C29 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
4AFC341512809A36003A0C29 /* catch_capture.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_capture.hpp; path = ../internal/catch_capture.hpp; sourceTree = SOURCE_ROOT; };
4AFC341612809A36003A0C29 /* catch_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = catch_common.h; path = ../internal/catch_common.h; sourceTree = SOURCE_ROOT; };
4AFC341712809A36003A0C29 /* catch_registry.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_registry.hpp; path = ../internal/catch_registry.hpp; sourceTree = SOURCE_ROOT; };
4AFC341812809A36003A0C29 /* catch_reporter_registry.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_reporter_registry.hpp; path = ../internal/catch_reporter_registry.hpp; sourceTree = SOURCE_ROOT; };
4AFC341912809A36003A0C29 /* catch_resultinfo.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_resultinfo.hpp; path = ../internal/catch_resultinfo.hpp; sourceTree = SOURCE_ROOT; };
4AFC341A12809A36003A0C29 /* catch_runner_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_runner_impl.hpp; path = ../internal/catch_runner_impl.hpp; sourceTree = SOURCE_ROOT; };
4AFC341B12809A36003A0C29 /* catch_testcaseinfo.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_testcaseinfo.hpp; path = ../internal/catch_testcaseinfo.hpp; sourceTree = SOURCE_ROOT; };
4AFC341C12809A45003A0C29 /* catch_default_main.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_default_main.hpp; path = ../catch_default_main.hpp; sourceTree = SOURCE_ROOT; };
4AFC341D12809A45003A0C29 /* catch_reporter_basic.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_reporter_basic.hpp; path = ../catch_reporter_basic.hpp; sourceTree = SOURCE_ROOT; };
4AFC341E12809A45003A0C29 /* catch_reporter_xml.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_reporter_xml.hpp; path = ../catch_reporter_xml.hpp; sourceTree = SOURCE_ROOT; };
4AFC341F12809A45003A0C29 /* catch_list.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_list.hpp; path = ../internal/catch_list.hpp; sourceTree = SOURCE_ROOT; };
4AFC342012809A45003A0C29 /* catch.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch.hpp; path = ../catch.hpp; sourceTree = SOURCE_ROOT; };
4AFC346412809D41003A0C29 /* catch_commandline.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_commandline.hpp; path = ../internal/catch_commandline.hpp; sourceTree = SOURCE_ROOT; };
4AFC359B1281F00B003A0C29 /* catch_section.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_section.hpp; path = ../internal/catch_section.hpp; sourceTree = SOURCE_ROOT; };
4AFC38161284B387003A0C29 /* catch_runner.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_runner.hpp; path = ../catch_runner.hpp; sourceTree = SOURCE_ROOT; };
4AFC384F1287E33E003A0C29 /* catch_runnerconfig.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_runnerconfig.hpp; path = ../catch_runnerconfig.hpp; sourceTree = SOURCE_ROOT; };
4AFC38CC12887D80003A0C29 /* ConditionTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConditionTests.cpp; sourceTree = "<group>"; };
4AFC3A9812893C56003A0C29 /* ExceptionTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExceptionTests.cpp; sourceTree = "<group>"; };
4AFC3AA812893E54003A0C29 /* MessageTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MessageTests.cpp; sourceTree = "<group>"; };
4AFC3B0A12894114003A0C29 /* ClassTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClassTests.cpp; sourceTree = "<group>"; };
4AFC3B661289C7E3003A0C29 /* TrickyTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrickyTests.cpp; sourceTree = "<group>"; };
8DD76F6C0486A84900D96B5E /* Test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Test; sourceTree = BUILT_PRODUCTS_DIR; };
C6859E8B029090EE04C91782 /* Test.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = Test.1; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F660486A84900D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* Test */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
C6859E8C029090F304C91782 /* Documentation */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = Test;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
4AFC341312809A12003A0C29 /* Catch */,
4AFC340B128099F5003A0C29 /* main.cpp */,
4AFC38CC12887D80003A0C29 /* ConditionTests.cpp */,
4AFC3A9812893C56003A0C29 /* ExceptionTests.cpp */,
4AFC3AA812893E54003A0C29 /* MessageTests.cpp */,
4AFC3B0A12894114003A0C29 /* ClassTests.cpp */,
4AFC3B661289C7E3003A0C29 /* TrickyTests.cpp */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76F6C0486A84900D96B5E /* Test */,
);
name = Products;
sourceTree = "<group>";
};
4AFC341312809A12003A0C29 /* Catch */ = {
isa = PBXGroup;
children = (
4AFC342012809A45003A0C29 /* catch.hpp */,
4AFC341C12809A45003A0C29 /* catch_default_main.hpp */,
4AFC341D12809A45003A0C29 /* catch_reporter_basic.hpp */,
4AFC341E12809A45003A0C29 /* catch_reporter_xml.hpp */,
4AFC38161284B387003A0C29 /* catch_runner.hpp */,
4AFC341412809A1B003A0C29 /* Internal */,
);
name = Catch;
sourceTree = "<group>";
};
4AFC341412809A1B003A0C29 /* Internal */ = {
isa = PBXGroup;
children = (
4AFC341F12809A45003A0C29 /* catch_list.hpp */,
4AFC359B1281F00B003A0C29 /* catch_section.hpp */,
4AFC346412809D41003A0C29 /* catch_commandline.hpp */,
4AFC341512809A36003A0C29 /* catch_capture.hpp */,
4AFC341612809A36003A0C29 /* catch_common.h */,
4AFC341712809A36003A0C29 /* catch_registry.hpp */,
4AFC341812809A36003A0C29 /* catch_reporter_registry.hpp */,
4AFC341912809A36003A0C29 /* catch_resultinfo.hpp */,
4AFC341A12809A36003A0C29 /* catch_runner_impl.hpp */,
4AFC341B12809A36003A0C29 /* catch_testcaseinfo.hpp */,
4AFC384F1287E33E003A0C29 /* catch_runnerconfig.hpp */,
);
name = Internal;
sourceTree = "<group>";
};
C6859E8C029090F304C91782 /* Documentation */ = {
isa = PBXGroup;
children = (
C6859E8B029090EE04C91782 /* Test.1 */,
);
name = Documentation;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F620486A84900D96B5E /* Test */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Test" */;
buildPhases = (
8DD76F640486A84900D96B5E /* Sources */,
8DD76F660486A84900D96B5E /* Frameworks */,
8DD76F690486A84900D96B5E /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = Test;
productInstallPath = "$(HOME)/bin";
productName = Test;
productReference = 8DD76F6C0486A84900D96B5E /* Test */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "Test" */;
compatibilityVersion = "Xcode 3.1";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* Test */;
projectDirPath = "";
projectRoot = "";
targets = (
8DD76F620486A84900D96B5E /* Test */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F640486A84900D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4AFC340C128099F5003A0C29 /* main.cpp in Sources */,
4AFC38CD12887D80003A0C29 /* ConditionTests.cpp in Sources */,
4AFC3A9912893C56003A0C29 /* ExceptionTests.cpp in Sources */,
4AFC3AA912893E54003A0C29 /* MessageTests.cpp in Sources */,
4AFC3B0B12894114003A0C29 /* ClassTests.cpp in Sources */,
4AFC3B671289C7E3003A0C29 /* TrickyTests.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
1DEB923208733DC60010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = Test;
};
name = Debug;
};
1DEB923308733DC60010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_MODEL_TUNING = G5;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = Test;
};
name = Release;
};
1DEB923608733DC60010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
SDKROOT = macosx10.6;
};
name = Debug;
};
1DEB923708733DC60010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = macosx10.6;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Test" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB923208733DC60010E9CD /* Debug */,
1DEB923308733DC60010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "Test" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB923608733DC60010E9CD /* Debug */,
1DEB923708733DC60010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

34
Test/TrickyTests.cpp Normal file
View File

@ -0,0 +1,34 @@
/*
* TrickyTests.cpp
* Catch - Test
*
* Created by Phil on 09/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#include "catch.hpp"
namespace Catch
{
template<>
std::string toString<std::pair<int, int> >( const std::pair<int, int>& value )
{
std::ostringstream oss;
oss << "std::pair( " << value.first << ", " << value.second << " )";
return oss.str();
}
}
TEST_CASE( "succeeding/Tricky", "Some tricky to parse tests" )
{
std::pair<int, int> aNicePair( 1, 2 );
// !TBD: would be nice if this could compile without the extra parentheses
EXPECT( (std::pair<int, int>( 1, 2 )) == aNicePair );
}

53
Test/main.cpp Normal file
View File

@ -0,0 +1,53 @@
/*
* main.cpp
* Catch - Test
*
* Created by Phil on 22/10/2010.
* Copyright 2010 Two Blue Cubes Ltd
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#include "catch.hpp"
#include "catch_runner.hpp"
// This code runs the meta tests and verifies that the failing ones failed and the successful ones succeeded
int main (int argc, char * const argv[])
{
using namespace Catch;
ReporterConfig reporterConfig( ReporterConfig::Include::SuccessfulResults );
BasicReporter reporter (reporterConfig );
Runner runner;
runner.setReporter( &reporter );
std::ostringstream ossSucceeding;
reporterConfig.setStreamBuf( ossSucceeding.rdbuf() );
runner.runMatching( "succeeding/*" );
std::string succeedingResults = ossSucceeding.str();
std::ostringstream ossFailing;
reporterConfig.setStreamBuf( ossFailing.rdbuf() );
runner.runMatching( "failing/*" );
std::string failingResults = ossFailing.str();
int result = 0;
if( succeedingResults.find( "failed" ) != std::string::npos )
{
std::cerr << "Some tests that should have succeeded failed:\n\n" << succeedingResults;
result = 1;
}
if( failingResults.find( "succeeded" ) != std::string::npos )
{
std::cerr << "Some tests that should have failed succeeded:\n\n" << failingResults;
result = 1;
}
if( result == 0 )
{
std::cout << "All tests completed successfully" << std::endl;
}
return result;
}

65
catch.hpp Normal file
View File

@ -0,0 +1,65 @@
/*
* catch.hpp
* Catch
*
* Created by Phil on 22/10/2010.
* Copyright 2010 Two Blue Cubes Ltd
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
/* TBD:
Next:
Later:
Finish command line parser (list as xml, specify FP tolerance)
INFO() stores messages until next result
Revisit Approx()
Extra reports
Tags?
Detect caught "Catch" exception, offer continuation based iteration instead
Finish macros, listed here, later (just CHECK_NOFAIL now)
*/
#ifndef TWOBLUECUBES_CATCH_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_HPP_INCLUDED
#include "internal/catch_registry.hpp"
#include "internal/catch_capture.hpp"
#include "internal/catch_section.hpp"
//////
#define EXPECT( pred ) _CATCH_TEST( pred, false, true, "EXPECT" )
#define EXPECT_NOT( pred ) _CATCH_TEST( pred, true, true, "EXPECT_NOT" )
#define EXPECT_THROWS( expr ) _CATCH_THROWS( expr, ..., false, true, "EXPECT_THROWS" )
#define EXPECT_THROWS_AS( expr, exceptionType ) _CATCH_THROWS_AS( expr, exceptionType, false, true, "EXPECT_THROWS_AS" )
#define CHECK( pred ) _CATCH_TEST( pred, false, false, "CHECK" )
#define CHECK_NOT( pred ) _CATCH_TEST( pred, true, false, "CHECK_NOT" )
#define CHECK_THROWS( expr ) _CATCH_THROWS( expr, ..., false. false, "CHECK_THROWS" )
#define CHECK_THROWS_AS( expr, exceptionType ) _CATCH_THROWS_AS( expr, exceptionType, false, false, "CHECK_THROWS_AS" )
#define CHECK_NOTHROW( expr ) _CATCH_THROWS_AS( expr, Catch::DummyExceptionType_DontUse, true, false, "CHECK_NOTHROW" )
#define INFO( reason ) _CATCH_MSG( reason, Catch::ResultWas::Info, false, "INFO" )
#define WARN( reason ) _CATCH_MSG( reason, Catch::ResultWas::Warning, false, "WARN" )
#define FAIL( reason ) _CATCH_MSG( reason, Catch::ResultWas::ExplicitFailure, true, "FAIL" )
#define SECTION( name, description ) CATCH_SECTION( name, description )
#define TEST_CASE( name, description ) CATCH_TEST_CASE( name, description )
#define METHOD_AS_TEST_CASE( method, name, description ) CATCH_METHOD_AS_TEST_CASE( method, name, description )
#define REGISTER_REPORTER( name, reporterType ) CATCH_REGISTER_REPORTER( name, reporterType )
///////////////
// Still to be implemented
#define CHECK_NOFAIL( pred ) // !TBD - reports violation, but doesn't fail Test
using Catch::Approx;
#endif // TWOBLUECUBES_CATCH_HPP_INCLUDED

23
catch_default_main.hpp Normal file
View File

@ -0,0 +1,23 @@
/*
* catch_default_main.hpp
* Catch
*
* Created by Phil on 01/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
#include "catch_runner.hpp"
#include "catch.hpp"
int main (int argc, char * const argv[])
{
return Catch::Main( argc, argv );
}
#endif // TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED

99
catch_reporter_basic.hpp Normal file
View File

@ -0,0 +1,99 @@
/*
* catch_reporter_basic.hpp
* Catch
*
* Created by Phil on 28/10/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_REPORTER_BASIC_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_BASIC_HPP_INCLUDED
#include "internal/catch_capture.hpp"
#include "internal/catch_reporter_registry.hpp"
namespace Catch
{
class BasicReporter : public ITestReporter
{
public:
///////////////////////////////////////////////////////////////////////////
BasicReporter( const ReporterConfig& config )
: m_config( config )
{
}
///////////////////////////////////////////////////////////////////////////
static std::string getDescription()
{
return "Reports test results as lines of text";
}
private: // ITestReporter
///////////////////////////////////////////////////////////////////////////
virtual void StartTestCase( const TestCaseInfo& testInfo )
{
m_config.stream() << std::endl << "[Running: " << testInfo.getName() << "]" << std::endl;
}
///////////////////////////////////////////////////////////////////////////
virtual void Result( const ResultInfo& resultInfo )
{
if( !m_config.includeSuccessfulResults() && resultInfo.ok() )
return;
if( !resultInfo.getFilename().empty() )
m_config.stream() << resultInfo.getFilename() << "(" << resultInfo.getLine() << "): ";
if( resultInfo.hasExpression() )
{
m_config.stream() << resultInfo.getExpression();
if( resultInfo.ok() )
m_config.stream() << " succeeded";
else
m_config.stream() << " failed";
}
switch( resultInfo.getResultType() )
{
case ResultWas::ThrewException:
if( resultInfo.hasExpression() )
m_config.stream() << " with unexpected";
else
m_config.stream() << "Unexpected";
m_config.stream() << " exception with message: '" << resultInfo.getMessage() << "'";
break;
case ResultWas::Info:
m_config.stream() << "info: '" << resultInfo.getMessage() << "'";
break;
case ResultWas::Warning:
m_config.stream() << "warning: '" << resultInfo.getMessage() << "'";
break;
case ResultWas::ExplicitFailure:
m_config.stream() << "failed with message: '" << resultInfo.getMessage() << "'";
break;
}
if( resultInfo.hasExpression() )
{
m_config.stream() << " for: " << resultInfo.getExpandedExpression();
}
m_config.stream() << std::endl;
}
///////////////////////////////////////////////////////////////////////////
virtual void EndTestCase( const TestCaseInfo& testInfo )
{
m_config.stream() << "[Finished: " << testInfo.getName() << "]" << std::endl;
}
private:
const ReporterConfig& m_config;
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_REPORTER_BASIC_HPP_INCLUDED

98
catch_reporter_xml.hpp Normal file
View File

@ -0,0 +1,98 @@
/*
* catch_reporter_xml.hpp
* Catch
*
* Created by Phil on 28/10/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
#include "internal/catch_capture.hpp"
#include "internal/catch_reporter_registry.hpp"
#include <iostream>
namespace Catch
{
class XmlReporter : public Catch::ITestReporter
{
public:
///////////////////////////////////////////////////////////////////////////
XmlReporter( const ReporterConfig& config = ReporterConfig() )
: m_config( config )
{
}
///////////////////////////////////////////////////////////////////////////
static std::string getDescription()
{
return "Reports test results as an XML document";
}
private: // ITestReporter
///////////////////////////////////////////////////////////////////////////
virtual void StartTestCase( const Catch::TestCaseInfo& testInfo )
{
m_config.stream() << "<TestCase name='" << testInfo.getName() << "'>\n";
m_currentTestSuccess = true;
}
///////////////////////////////////////////////////////////////////////////
virtual void Result( const Catch::ResultInfo& resultInfo )
{
if( !m_config.includeSuccessfulResults() && resultInfo.ok() )
return;
if( resultInfo.hasExpression() )
{
m_config.stream() << "\t<Expression success='" << (resultInfo.ok() ? "true" : "false") << "' "
<< "filename='" << resultInfo.getFilename() << "' line='" << resultInfo.getLine() << "'>\n"
<< "\t\t<Original>" << resultInfo.getExpression() << "</Original>\n"
<< "\t\t<Expanded>" << resultInfo.getExpandedExpression() << "</Expanded>\n";
m_currentTestSuccess |= resultInfo.ok();
}
switch( resultInfo.getResultType() )
{
case ResultWas::ThrewException:
if( resultInfo.hasExpression() )
m_config.stream() << "\t";
m_config.stream() << "\t<Exception>" << resultInfo.getMessage() << "</Exception>\n";
m_currentTestSuccess = false;
break;
case ResultWas::Info:
m_config.stream() << "\t<Info>" << resultInfo.getMessage() << "</Info>\n";
break;
case ResultWas::Warning:
m_config.stream() << "\t<Warning>" << resultInfo.getMessage() << "</Warning>\n";
break;
case ResultWas::ExplicitFailure:
m_config.stream() << "\t<Failure>" << resultInfo.getMessage() << "</Failure>\n";
m_currentTestSuccess = false;
break;
}
if( resultInfo.hasExpression() )
{
m_config.stream() << "\t</Expression>\n";
}
}
///////////////////////////////////////////////////////////////////////////
virtual void EndTestCase( const Catch::TestCaseInfo& testInfo )
{
m_config.stream() << "\t<OverallResult success='" << (m_currentTestSuccess ? "true" : "false" ) << "/>\n";
m_config.stream() << "</TestCase>" << std::endl;
}
private:
const ReporterConfig& m_config;
bool m_currentTestSuccess;
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED

82
catch_runner.hpp Normal file
View File

@ -0,0 +1,82 @@
/*
* catch_runner.hpp
* Catch
*
* Created by Phil on 31/10/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
#include "internal/catch_commandline.hpp"
#include "internal/catch_list.hpp"
#include "catch_reporter_basic.hpp"
#include "catch_reporter_xml.hpp"
namespace Catch
{
inline int Main( int argc, char * const argv[] )
{
ReporterRegistry::instance().registerReporter<BasicReporter>( "basic" );
ReporterRegistry::instance().registerReporter<XmlReporter>( "xml" );
RunnerConfig config;
ArgParser( argc, argv, config );
if( !config.m_message.empty() )
{
std::cerr << config.m_message << std::endl;
return std::numeric_limits<int>::max();
}
// Handle list request
if( config.listWhat() != RunnerConfig::listNone )
return List( config );
// Open output file, if specified
std::ofstream ofs;
if( !config.getFilename().empty() )
{
ofs.open( config.getFilename().c_str() );
if( ofs.fail() )
{
std::cerr << "Unable to open file: '" << config.getFilename() << "'" << std::endl;
return std::numeric_limits<int>::max();
}
config.getReporterConfig().setStreamBuf( ofs.rdbuf() );
}
Runner runner;
runner.setReporter( config.getReporter() );
// Run test specs specified on the command line - or default to all
if( config.m_testSpecs.size() == 0 )
{
runner.runAll();
}
else
{
// !TBD We should get all the testcases upfront, report any missing,
// then just run them
std::vector<std::string>::const_iterator it = config.m_testSpecs.begin();
std::vector<std::string>::const_iterator itEnd = config.m_testSpecs.end();
for(; it != itEnd; ++it )
{
if( runner.runMatching( *it ) == 0 )
{
// Use reporter?
std::cerr << "\n[Unable to match any test cases with: " << *it << "]" << std::endl;
}
}
}
return runner.getFailures();
}
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED

126
catch_runnerconfig.hpp Normal file
View File

@ -0,0 +1,126 @@
/*
* catch_runnerconfig.hpp
* Catch
*
* Created by Phil on 08/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_RUNNERCONFIG_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_RUNNERCONFIG_HPP_INCLUDED
#include "catch_reporter_registry.hpp"
#include <vector>
#include <string>
namespace Catch
{
class RunnerConfig
{
public:
enum ListInfo
{
listNone = 0,
listReports = 1,
listTests = 2,
listAll = 3,
listWhatMask = 0xf,
listAsText = 0x10,
listAsXml = 0x11,
listAsMask = 0xf0
};
RunnerConfig()
: m_listSpec( listNone ),
m_reporter( NULL )
{}
void setReporterInfo( const std::string& reporterName )
{
if( m_reporter.get() )
return setError( "Only one reporter may be specified" );
setReporter( ReporterRegistry::instance().create( reporterName, m_reporterConfig ) );
}
void addTestSpec( const std::string& testSpec )
{
m_testSpecs.push_back( testSpec );
}
void setListSpec( ListInfo listSpec )
{
m_listSpec = listSpec;
}
void setFilename( const std::string& filename )
{
m_filename = filename;
}
std::string getFilename()
{
return m_filename;
}
void setError( const std::string& errorMessage )
{
m_message = errorMessage + "\n\n" + "Usage: ...";
}
void setReporter( ITestReporter* reporter )
{
m_reporter = std::auto_ptr<ITestReporter>( reporter );
}
ITestReporter* getReporter()
{
if( !m_reporter.get() )
setReporter( ReporterRegistry::instance().create( "basic", m_reporterConfig ) );
return m_reporter.get();
}
const ITestReporter* getReporter() const
{
return const_cast<RunnerConfig*>( this )->getReporter();
}
ListInfo listWhat() const
{
return (ListInfo)( m_listSpec & listWhatMask );
}
ListInfo listAs() const
{
return (ListInfo)( m_listSpec & listAsMask );
}
ReporterConfig& getReporterConfig()
{
return m_reporterConfig;
}
void setIncludeAll( bool includeAll )
{
m_reporterConfig.setIncludeWhat( includeAll ? ReporterConfig::Include::SuccessfulResults : ReporterConfig::Include::FailedOnly );
}
std::auto_ptr<ITestReporter> m_reporter;
std::string m_filename;
ReporterConfig m_reporterConfig;
std::string m_message;
ListInfo m_listSpec;
std::vector<std::string> m_testSpecs;
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_RUNNERCONFIG_HPP_INCLUDED

279
internal/catch_capture.hpp Normal file
View File

@ -0,0 +1,279 @@
/*
* catch_capture.hpp
* Catch
*
* Created by Phil on 18/10/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
#include "catch_resultinfo.hpp"
#include <sstream>
#include "math.h"
namespace Catch
{
template<typename T>
std::string toString( const T& value )
{
std::ostringstream oss;
oss << value;
return oss.str();
}
class TestFailureException
{
};
class DummyExceptionType_DontUse
{
};
class MutableResultInfo : public ResultInfo
{
public:
MutableResultInfo()
{}
MutableResultInfo( const std::string& expr, bool isNot, const std::string& filename, size_t line, const std::string& macroName )
: ResultInfo( ( isNot ? "!" : "" ) + expr, ResultWas::Unknown, isNot, filename, line, macroName )
{
}
void setResultType( ResultWas::OfType result )
{
// Flip bool results if isNot is set
if( m_isNot && result == ResultWas::Ok )
m_result = ResultWas::ExpressionFailed;
else if( m_isNot && result == ResultWas::ExpressionFailed )
m_result = ResultWas::Ok;
else
m_result = result;
}
void setMessage( const std::string& message )
{
m_message = message;
}
private:
friend class ResultBuilder;
void setLhs( const std::string& lhs )
{
m_lhs = lhs;
}
MutableResultInfo& setRhs( const std::string& op, const std::string& rhs )
{
m_op = op;
m_rhs = rhs;
return *this;
}
};
class ResultBuilder
{
public:
ResultBuilder( const char* expr, bool isNot, const std::string& filename, size_t line, const std::string& macroName )
: m_result( expr, isNot, filename, line, macroName )
{}
template<typename T>
ResultBuilder& operator->*(const T & operand)
{
m_result.setLhs( toString( operand ) );
return *this;
}
template<typename RhsT>
MutableResultInfo& operator == ( const RhsT& rhs )
{
return m_result.setRhs( "==", toString( rhs ) );
}
template<typename RhsT>
MutableResultInfo& operator != ( const RhsT& rhs )
{
return m_result.setRhs( "!=", toString( rhs ) );
}
template<typename RhsT>
MutableResultInfo& operator < ( const RhsT& rhs )
{
return m_result.setRhs( "<", toString( rhs ) );
}
template<typename RhsT>
MutableResultInfo& operator > ( const RhsT& rhs )
{
return m_result.setRhs( ">", toString( rhs ) );
}
template<typename RhsT>
MutableResultInfo& operator <= ( const RhsT& rhs )
{
return m_result.setRhs( "<=", toString( rhs ) );
}
template<typename RhsT>
MutableResultInfo& operator >= ( const RhsT& rhs )
{
return m_result.setRhs( ">=", toString( rhs ) );
}
operator MutableResultInfo&()
{
return m_result;
}
private:
MutableResultInfo m_result;
};
class TestCaseInfo;
struct IResultListener
{
virtual ~IResultListener(){}
virtual void testEnded( const ResultInfo& result ) = 0;
};
class ResultsCapture
{
private:
ResultsCapture()
: m_listener( 0 )
{
}
static ResultsCapture& instance()
{
static ResultsCapture instance;
return instance;
}
public:
static IResultListener* setListener( IResultListener* listener )
{
IResultListener* prevListener = instance().m_listener;
instance().m_listener = listener;
return prevListener;
}
static void acceptExpression( const MutableResultInfo& resultInfo )
{
instance().currentResult = resultInfo;
}
static void acceptResult( bool result, bool stopOnFail )
{
acceptResult( result ? ResultWas::Ok : ResultWas::ExpressionFailed, stopOnFail );
}
static void acceptResult( ResultWas::OfType result, bool stopOnFail )
{
if( !acceptResult( result ) && stopOnFail )
{
throw TestFailureException();
}
}
static bool acceptResult( ResultWas::OfType result )
{
MutableResultInfo& currentResult = instance().currentResult;
currentResult.setResultType( result );
if( instance().m_listener )
{
instance().m_listener->testEnded( currentResult );
}
bool ok = currentResult.ok();
instance().currentResult = MutableResultInfo();
return ok;
}
static bool acceptResult( bool expressionResult )
{
return acceptResult( expressionResult ? ResultWas::Ok : ResultWas::ExpressionFailed );
}
static void acceptMessage( const std::string& msg )
{
instance().currentResult.setMessage( msg );
}
private:
MutableResultInfo currentResult;
IResultListener* m_listener;
};
// !TBD Need to clean this all up
#define CATCH_absTol 1e-10
#define CATCH_relTol 1e-10
class Approx
{
public:
// !TBD more generic
Approx( double d )
: m_d( d )
{
}
template<typename T>
friend bool operator == ( const T& lhs, const Approx& rhs )
{
// !TBD Use proper tolerance
// From: http://realtimecollisiondetection.net/blog/?p=89
// see also: http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
return fabs( lhs - rhs.m_d ) <= std::max( CATCH_absTol, CATCH_relTol * std::max( fabs(lhs), fabs(rhs.m_d) ) );
}
template<typename T>
friend bool operator != ( const T& lhs, const Approx& rhs )
{
return ! operator==( lhs, rhs );
}
double m_d;
};
template<>
inline std::string toString<Approx>( const Approx& value )
{
std::ostringstream oss;
oss << "Approx( " << value.m_d << ")";
return oss.str();
}
} // end namespace Catch
#define _CATCH_TEST( expr, isNot, stopOnFailure, macroName ) \
Catch::ResultsCapture::acceptExpression( Catch::ResultBuilder( #expr, isNot, __FILE__, __LINE__, macroName )->*expr ); \
Catch::ResultsCapture::acceptResult( expr, stopOnFailure );
#define _CATCH_THROWS( expr, exceptionType, nothrow, stopOnFailure, macroName ) \
Catch::ResultsCapture::acceptExpression( Catch::ResultBuilder( #expr, false, __FILE__, __LINE__, macroName ) ); \
try \
{ \
expr; \
Catch::ResultsCapture::acceptResult( nothrow, stopOnFailure ); \
} \
catch( exceptionType ) \
{ \
Catch::ResultsCapture::acceptResult( !(nothrow), stopOnFailure ); \
}
#define _CATCH_THROWS_AS( expr, exceptionType, nothrow, stopOnFailure, macroName ) \
_CATCH_THROWS( expr, exceptionType, nothrow, stopOnFailure, macroName ) \
catch( ... ) \
{ \
Catch::ResultsCapture::acceptResult( false, stopOnFailure ); \
}
#define _CATCH_MSG( reason, resultType, stopOnFailure, macroName ) \
Catch::ResultsCapture::acceptExpression( Catch::MutableResultInfo( "", false, __FILE__, __LINE__, macroName ) ); \
Catch::ResultsCapture::acceptMessage( reason ); \
Catch::ResultsCapture::acceptResult( resultType, stopOnFailure );
#endif // TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED

View File

@ -0,0 +1,174 @@
/*
* catch_commandline.hpp
* Catch
*
* Created by Phil on 02/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
#include "catch_runnerconfig.hpp"
#include "catch_runner_impl.hpp"
namespace Catch
{
// -l --list:tests [xml] lists available tests (optionally in xml)
// -l --list:reports [xml] lists available reports (optionally in xml)
// -l --list:all [xml] lists available tests and reports (optionally in xml)
// -t --test "testspec" (any number)
// -r --report <type>
// -o --output filename to write to
// -s --success report successful cases too
class ArgParser
{
enum Mode
{
modeNone,
modeList,
modeTest,
modeReport,
modeOutput,
modeSuccess,
modeError
};
public:
ArgParser( int argc, char * const argv[], RunnerConfig& config )
: m_mode( modeNone ),
m_config( config )
{
for(size_t i=1; i < argc; ++i )
{
if( argv[i][0] == '-' )
{
std::string cmd = ( argv[i] );
if( cmd == "-l" || cmd == "--list" )
changeMode( cmd, modeList );
else if( cmd == "-t" || cmd == "--test" )
changeMode( cmd, modeTest );
else if( cmd == "-r" || cmd == "--report" )
changeMode( cmd, modeReport );
else if( cmd == "-o" || cmd == "--output" )
changeMode( cmd, modeOutput );
else if( cmd == "-s" || cmd == "--success" )
changeMode( cmd, modeSuccess );
}
else
{
m_args.push_back( argv[i] );
}
if( m_mode == modeError )
return;
}
changeMode( "", modeNone );
}
private:
std::string argsAsString()
{
std::ostringstream oss;
std::vector<std::string>::const_iterator it = m_args.begin();
std::vector<std::string>::const_iterator itEnd = m_args.end();
for( bool first = true; it != itEnd; ++it, first = false )
{
if( !first )
oss << " ";
oss << *it;
}
return oss.str();
}
void changeMode( const std::string& cmd, Mode mode )
{
m_command = cmd;
switch( m_mode )
{
case modeNone:
if( m_args.size() > 0 )
return setErrorMode( "Unexpected arguments before " + m_command + ": " + argsAsString() );
break;
case modeList:
if( m_args.size() > 2 )
{
return setErrorMode( m_command + " expected upto 2 arguments but recieved: " + argsAsString() );
}
else
{
RunnerConfig::ListInfo listSpec = RunnerConfig::listAll;
if( m_args.size() >= 1 )
{
if( m_args[0] == "tests" )
listSpec = RunnerConfig::listTests;
else if( m_args[0] == "reports" )
listSpec = RunnerConfig::listReports;
else
return setErrorMode( m_command + " expected [tests] or [reports] but recieved: [" + m_args[0] + "]" );
}
if( m_args.size() >= 2 )
{
if( m_args[1] == "xml" )
listSpec = (RunnerConfig::ListInfo)( listSpec | RunnerConfig::listAsXml );
else if( m_args[1] == "text" )
listSpec = (RunnerConfig::ListInfo)( listSpec | RunnerConfig::listAsText );
else
return setErrorMode( m_command + " expected [xml] or [text] but recieved: [" + m_args[1] + "]" );
}
m_config.m_listSpec = (RunnerConfig::ListInfo)( m_config.m_listSpec | listSpec );
}
break;
case modeTest:
if( m_args.size() == 0 )
return setErrorMode( m_command + " expected at least 1 argument but recieved none" );
{
std::vector<std::string>::const_iterator it = m_args.begin();
std::vector<std::string>::const_iterator itEnd = m_args.end();
for(; it != itEnd; ++it )
m_config.addTestSpec( *it );
}
break;
case modeReport:
if( m_args.size() != 1 )
return setErrorMode( m_command + " expected one argument, recieved: " + argsAsString() );
m_config.setReporterInfo( m_args[0] );
break;
case modeOutput:
if( m_args.size() == 0 )
return setErrorMode( m_command + " expected filename" );
m_config.setFilename( m_args[0] );
break;
case modeSuccess:
if( m_args.size() != 0 )
return setErrorMode( m_command + " does not accept arguments" );
m_config.setIncludeAll( true );
break;
}
m_args.clear();
m_mode = mode;
}
void setErrorMode( const std::string& errorMessage )
{
m_mode = modeError;
m_command = "";
m_config.setError( errorMessage );
}
private:
Mode m_mode;
std::string m_command;
std::vector<std::string> m_args;
RunnerConfig& m_config;
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED

20
internal/catch_common.h Normal file
View File

@ -0,0 +1,20 @@
/*
* catch_common.h
* Catch
*
* Created by Phil on 29/10/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
#define _CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
#define _CATCH_UNIQUE_NAME_LINE( name, line ) _CATCH_UNIQUE_NAME_LINE2( name, line )
#define _CATCH_UNIQUE_NAME( name ) _CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
#endif // TWOBLUECUBES_CATCH_COMMON_H_INCLUDED

66
internal/catch_list.hpp Normal file
View File

@ -0,0 +1,66 @@
/*
* catch_list.hpp
* Catch
*
* Created by Phil on 5/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
#include "catch_commandline.hpp"
namespace Catch
{
inline int List( const RunnerConfig& config )
{
if( config.listWhat() & RunnerConfig::listReports )
{
std::cout << "Available reports:\n";
ReporterRegistry::FactoryMap::const_iterator it = ReporterRegistry::instance().m_factories.begin();
ReporterRegistry::FactoryMap::const_iterator itEnd = ReporterRegistry::instance().m_factories.end();
for(; it != itEnd; ++it )
{
// !TBD: consider listAs()
std::cout << "\t" << it->first << " '" << it->second->getDescription() << "'\n";
}
std::cout << std::endl;
}
if( config.listWhat() & RunnerConfig::listTests )
{
std::cout << "Available tests:\n";
std::vector<TestCaseInfo>::const_iterator it = TestRegistry::instance().getAllTests().begin();
std::vector<TestCaseInfo>::const_iterator itEnd = TestRegistry::instance().getAllTests().end();
for(; it != itEnd; ++it )
{
// !TBD: consider listAs()
std::cout << "\t" << it->getName() << " '" << it->getDescription() << "'\n";
}
std::cout << std::endl;
}
if( ( config.listWhat() & RunnerConfig::listAll ) == 0 )
{
std::cerr << "Unknown list type" << std::endl;
return std::numeric_limits<int>::max();
}
if( config.getReporter() )
{
std::cerr << "Reporters ignored when listing" << std::endl;
}
if( config.m_testSpecs.size() == 0 )
{
std::cerr << "Test specs ignored when listing" << std::endl;
}
return 0;
}
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED

116
internal/catch_registry.hpp Normal file
View File

@ -0,0 +1,116 @@
/*
* catch_registry.hpp
* Catch
*
* Created by Phil on 18/10/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_REGISTRY_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REGISTRY_HPP_INCLUDED
#include "catch_testcaseinfo.hpp"
#include "catch_common.h"
#include <vector>
#include <stdexcept>
namespace Catch
{
class TestRegistry
{
public:
static TestRegistry& instance()
{
static TestRegistry reg;
return reg;
}
void registerTest( const TestCaseInfo& testInfo )
{
m_functions.push_back( testInfo );
}
std::vector<TestCaseInfo> getAllTests() const
{
return m_functions;
}
private:
std::vector<TestCaseInfo> m_functions;
};
typedef void(*TestFunction)();
struct FreeFunctionTestCase : TestCase
{
FreeFunctionTestCase( TestFunction fun )
: fun( fun )
{}
virtual void invoke() const
{
fun();
}
virtual TestCase* clone() const
{
return new FreeFunctionTestCase( fun );
}
private:
TestFunction fun;
};
template<typename C>
struct MethodTestCase : TestCase
{
MethodTestCase( void (C::*method)() )
: method( method )
{}
virtual void invoke() const
{
C obj;
(obj.*method)();
}
virtual TestCase* clone() const
{
return new MethodTestCase<C>( method );
}
private:
void (C::*method)();
};
struct AutoReg
{
AutoReg( TestFunction function, const std::string& name, const std::string& description )
{
TestRegistry::instance().registerTest( TestCaseInfo( new FreeFunctionTestCase( function ), name, description ) );
}
template<typename C>
AutoReg( void (C::*method)(), const std::string& name, const std::string& description )
{
TestRegistry::instance().registerTest( TestCaseInfo( new MethodTestCase<C>( method ), name, description ) );
}
};
} // end namespace Catch
#define CATCH_TEST_CASE( Name, Desc ) \
static void _CATCH_UNIQUE_NAME( __catchTestFunction )(); \
namespace{ Catch::AutoReg _CATCH_UNIQUE_NAME( autoRegistrar )( &_CATCH_UNIQUE_NAME( __catchTestFunction ), Name, Desc ); }\
static void _CATCH_UNIQUE_NAME( __catchTestFunction )()
#define CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
namespace{ Catch::AutoReg _CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, Name, Desc ); }
#endif // TWOBLUECUBES_CATCH_REGISTRY_HPP_INCLUDED

View File

@ -0,0 +1,166 @@
/*
* catch_registry.hpp
* Catch
*
* Created by Phil on 29/10/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
#include "catch_testcaseinfo.hpp"
#include "catch_resultinfo.hpp"
#include "catch_common.h"
#include <map>
#include <iostream>
#include <fstream>
namespace Catch
{
class ReporterConfig
{
private:
ReporterConfig( const ReporterConfig& other );
ReporterConfig& operator = ( const ReporterConfig& other );
public:
struct Include { enum What
{
FailedOnly,
SuccessfulResults
}; };
public:
///////////////////////////////////////////////////////////////////////////
explicit ReporterConfig( Include::What includeWhat = Include::FailedOnly )
: m_includeWhat( includeWhat ),
m_os( std::cout.rdbuf() )
{
}
///////////////////////////////////////////////////////////////////////////
bool includeSuccessfulResults() const
{
return m_includeWhat == Include::SuccessfulResults;
}
///////////////////////////////////////////////////////////////////////////
void setIncludeWhat(Include::What includeWhat )
{
m_includeWhat = includeWhat;
}
///////////////////////////////////////////////////////////////////////////
std::ostream& stream() const
{
return m_os;
}
///////////////////////////////////////////////////////////////////////////
void setStreamBuf( std::streambuf* buf )
{
m_os.rdbuf( buf );
}
private:
Include::What m_includeWhat;
mutable std::ostream m_os;
};
struct ITestReporter
{
virtual ~ITestReporter(){}
// !TBD
// StartTesting
// EndTesting
// StartGroup
// EndGroup
// StartSection
// EndSection
virtual void StartTestCase( const TestCaseInfo& testInfo ) = 0;
virtual void Result( const ResultInfo& result ) = 0;
virtual void EndTestCase( const TestCaseInfo& testInfo ) = 0;
};
struct IReporterFactory
{
virtual ~IReporterFactory(){}
virtual ITestReporter* create( const ReporterConfig& config ) = 0;
virtual std::string getDescription() const = 0;
};
template<typename T>
class ReporterFactory : public IReporterFactory
{
virtual ITestReporter* create( const ReporterConfig& config )
{
return new T( config );
}
virtual std::string getDescription() const
{
return T::getDescription();
}
};
class ReporterRegistry
{
public:
static ReporterRegistry& instance()
{
static ReporterRegistry instance;
return instance;
}
~ReporterRegistry()
{
FactoryMap::const_iterator it = m_factories.begin();
FactoryMap::const_iterator itEnd = m_factories.end();
for(; it != itEnd; ++it )
{
delete it->second;
}
}
ITestReporter* create( const std::string& name, const ReporterConfig& config )
{
FactoryMap::const_iterator it = m_factories.find( name );
if( it == m_factories.end() )
return NULL;
return it->second->create( config );
}
template<typename T>
void registerReporter( const std::string& name )
{
m_factories.insert( std::make_pair( name, new ReporterFactory<T>() ) );
}
// private: // !TBD
typedef std::map<std::string, IReporterFactory*> FactoryMap;
FactoryMap m_factories;
};
template<typename T>
struct ReporterRegistrar
{
ReporterRegistrar( const std::string& name )
{
ReporterRegistry::instance().registerReporter<T>( name );
}
};
}
#define CATCH_REGISTER_REPORTER( name, reporterType ) Catch::ReporterRegistrar<reporterType> _CATCH_UNIQUE_NAME( __catchReporterReg )( name );
#endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED

View File

@ -0,0 +1,122 @@
/*
* catch_resultinfo.hpp
* Catch
*
* Created by Phil on 28/10/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_RESULT_INFO_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_RESULT_INFO_HPP_INCLUDED
#include <string>
namespace Catch
{
struct ResultWas{ enum OfType
{
Unknown = -1,
Ok = 0,
ExpressionFailed = 1,
Info = 2,
Warning = 3,
ExplicitFailure = 4,
Exception = 0x100,
ThrewException = Exception | 1,
DidntThrowException = Exception | 2
}; };
class ResultInfo
{
public:
ResultInfo()
: m_result( ResultWas::Unknown ),
m_isNot( false ),
m_line( 0 )
{}
ResultInfo( const std::string& expr, ResultWas::OfType result, bool isNot, const std::string& filename, size_t line, const std::string& macroName )
: m_expr( expr ),
m_result( result ),
m_isNot( isNot ),
m_op( m_expr[0] == '!' ? "!" : "" ),
m_filename( filename ),
m_line( line ),
m_macroName( macroName )
{
}
bool ok() const
{
return m_result == ResultWas::Ok;
}
ResultWas::OfType getResultType() const
{
return m_result;
}
bool hasExpression() const
{
return !m_expr.empty();
}
bool hasMessage() const
{
return !m_message.empty();
}
std::string getExpression() const
{
return m_expr;
}
std::string getExpandedExpression() const
{
if( m_op == "" || m_isNot )
return m_lhs.empty() ? m_expr : m_op + m_lhs;
else if( m_op != "!" )
return m_lhs + " " + m_op + " " + m_rhs;
else
return "{can't expand - use " + m_macroName + "_NOT( " + m_expr.substr(1) + " ) instead of " + m_macroName + "( " + m_expr + " ) for better diagnostics}";
}
std::string getMessage() const
{
return m_message;
}
std::string getFilename() const
{
return m_filename;
}
size_t getLine() const
{
return m_line;
}
std::string getTestMacroName() const
{
return m_macroName;
}
protected:
std::string m_macroName;
std::string m_filename;
size_t m_line;
std::string m_expr, m_lhs, m_rhs, m_op;
std::string m_message;
ResultWas::OfType m_result;
bool m_isNot;
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_RESULT_INFO_HPP_INCLUDED

View File

@ -0,0 +1,145 @@
/*
* catch_runner.hpp
* Catch
*
* Created by Phil on 22/10/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_INTERNAL_CATCH_RUNNER_HPP_INCLUDED
#define TWOBLUECUBES_INTERNAL_CATCH_RUNNER_HPP_INCLUDED
#include "catch_reporter_registry.hpp"
#include "catch_registry.hpp"
#include "catch_capture.hpp"
namespace Catch
{
class TestSpec
{
public:
TestSpec( const std::string& rawSpec )
: m_rawSpec( rawSpec ),
m_isWildcarded( false )
{
if( m_rawSpec[m_rawSpec.size()-1] == '*' )
{
m_rawSpec = m_rawSpec.substr( 0, m_rawSpec.size()-1 );
m_isWildcarded = true;
}
}
bool matches( const std::string& testName ) const
{
if( !m_isWildcarded )
return m_rawSpec == testName;
else
return testName.size() >= m_rawSpec.size() && testName.substr( 0, m_rawSpec.size() ) == m_rawSpec;
}
private:
std::string m_rawSpec;
bool m_isWildcarded;
};
class Runner : public IResultListener
{
public:
Runner()
: m_successes( 0 ),
m_failures( 0 ),
m_reporter( 0 )
{
}
void setReporter( ITestReporter* reporter )
{
m_reporter = reporter;
}
void runAll()
{
std::vector<TestCaseInfo> allTests = TestRegistry::instance().getAllTests();
for( size_t i=0; i < allTests.size(); ++i )
{
runTest( allTests[i] );
}
}
size_t runMatching( const std::string& rawTestSpec )
{
TestSpec testSpec( rawTestSpec );
std::vector<TestCaseInfo> allTests = TestRegistry::instance().getAllTests();
size_t testsRun = 0;
for( size_t i=0; i < allTests.size(); ++i )
{
if( testSpec.matches( allTests[i].getName() ) )
{
runTest( allTests[i] );
testsRun++;
}
}
return testsRun;
}
void runTest( const TestCaseInfo& testInfo )
{
IResultListener* prevListener = ResultsCapture::setListener( this );
m_reporter->StartTestCase( testInfo );
try
{
testInfo.invoke();
}
catch( TestFailureException& ex )
{
// This just means the test was aborted due to failure
}
catch( std::exception& ex )
{
ResultsCapture::acceptMessage( ex.what() );
ResultsCapture::acceptResult( ResultWas::ThrewException );
}
catch(...)
{
ResultsCapture::acceptMessage( "unknown exception" );
ResultsCapture::acceptResult( ResultWas::ThrewException );
}
m_reporter->EndTestCase( testInfo );
ResultsCapture::setListener( prevListener );
}
size_t getSuccessCount() const
{
return m_successes;
}
size_t getFailures() const
{
return m_failures;
}
private: // IResultListener
virtual void testEnded( const ResultInfo& result )
{
if( result.ok() )
m_successes++;
else
m_failures++;
m_reporter->Result( result );
}
private:
size_t m_successes;
size_t m_failures;
ITestReporter* m_reporter;
};
}
#endif // TWOBLUECUBES_INTERNAL_CATCH_RUNNER_HPP_INCLUDED

View File

@ -0,0 +1,39 @@
/*
* catch_section.hpp
* Catch
*
* Created by Phil on 03/11/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
#include <string>
namespace Catch
{
class Section
{
public:
Section( const std::string& name, const std::string& description )
{
// !TBD notify the runner
}
operator bool()
{
// !TBD get this from runner
return true;
}
};
} // end namespace Catch
#define CATCH_SECTION( name, desc ) if( Catch::Section __catchSection = Catch::Section( name, desc ) )
#endif // TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED

View File

@ -0,0 +1,84 @@
/*
* catch_testcaseinfo.hpp
* Catch
*
* Created by Phil on 29/10/2010.
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_TESTCASEINFO_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_TESTCASEINFO_HPP_INCLUDED
#include <map>
#include <string>
namespace Catch
{
struct TestCase
{
virtual ~TestCase(){}
virtual void invoke() const = 0;
virtual TestCase* clone() const = 0;
};
class TestCaseInfo
{
public:
TestCaseInfo( TestCase* testCase, const std::string& name, const std::string& description )
: test( testCase ),
name( name ),
description( description )
{
}
TestCaseInfo()
: test( NULL )
{
}
TestCaseInfo( const TestCaseInfo& other )
: test( other.test->clone() ),
name( other.name ),
description( other.description )
{
}
TestCaseInfo& operator = ( const TestCaseInfo& other )
{
test = other.test->clone();
name = other.name;
description = description;
return *this;
}
~TestCaseInfo()
{
delete test;
}
void invoke() const
{
test->invoke();
}
const std::string& getName() const
{
return name;
}
const std::string& getDescription() const
{
return description;
}
private:
TestCase* test;
std::string name;
std::string description;
};
}
#endif // TWOBLUECUBES_CATCH_TESTCASEINFO_HPP_INCLUDED