diff --git a/projects/CMake/CMakeLists.txt b/projects/CMake/CMakeLists.txt index c31ec32b..952ba43e 100644 --- a/projects/CMake/CMakeLists.txt +++ b/projects/CMake/CMakeLists.txt @@ -21,6 +21,10 @@ set(SOURCES ${SELF_TEST_DIR}/TestMain.cpp ${SELF_TEST_DIR}/TrickyTests.cpp ${SELF_TEST_DIR}/VariadicMacrosTests.cpp + ${SELF_TEST_DIR}/EnumToString.cpp + ${SELF_TEST_DIR}/ToStringPair.cpp + ${SELF_TEST_DIR}/ToStringVector.cpp + ${SELF_TEST_DIR}/ToStringWhich.cpp ) # configure the executable diff --git a/projects/SelfTest/ToStringPair.cpp b/projects/SelfTest/ToStringPair.cpp new file mode 100644 index 00000000..2de4a55a --- /dev/null +++ b/projects/SelfTest/ToStringPair.cpp @@ -0,0 +1,51 @@ +#include "catch.hpp" + +// === Pair === +namespace Catch { + // Note: If we put this in the right place in catch_tostring, then + // we can make it an overload of Catch::toString + template + struct StringMaker > { + static std::string convert( const std::pair& pair ) { + std::ostringstream oss; + oss << "{ " + << toString( pair.first ) + << ", " + << toString( pair.second ) + << " }"; + return oss.str(); + } + }; +} + +TEST_CASE( "std::pair -> toString", "[toString][pair]" ) +{ + std::pair value( 34, "xyzzy" ); + REQUIRE( Catch::toString( value ) == "{ 34, \"xyzzy\" }" ); +} + +TEST_CASE( "std::pair -> toString", "[toString][pair]" ) +{ + std::pair value( 34, "xyzzy" ); + REQUIRE( Catch::toString(value) == "{ 34, \"xyzzy\" }" ); +} + +TEST_CASE( "std::vector > -> toString", "[toString][pair]" ) +{ + std::vector > pr; + pr.push_back( std::make_pair("green", 55 ) ); + REQUIRE( Catch::toString( pr ) == "{ { \"green\", 55 } }" ); +} + +// This is pretty contrived - I figure if this works, anything will... +TEST_CASE( "pair > -> toString", "[toString][pair]" ) +{ + typedef std::pair left_t; + typedef std::pair right_t; + + left_t left( 42, "Arthur" ); + right_t right( "Ford", 24 ); + + std::pair pair( left, right ); + REQUIRE( Catch::toString( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }" ); +} diff --git a/projects/SelfTest/ToStringVector.cpp b/projects/SelfTest/ToStringVector.cpp new file mode 100644 index 00000000..f3b036e5 --- /dev/null +++ b/projects/SelfTest/ToStringVector.cpp @@ -0,0 +1,72 @@ +#include "catch.hpp" +#include + + +// vedctor +TEST_CASE( "vector -> toString", "[toString][vector]" ) +{ + std::vector vv; + REQUIRE( Catch::toString(vv) == "{ }" ); + vv.push_back( 42 ); + REQUIRE( Catch::toString(vv) == "{ 42 }" ); + vv.push_back( 512 ); + REQUIRE( Catch::toString(vv) == "{ 42, 512 }" ); +} + +TEST_CASE( "vector -> toString", "[toString][vector]" ) +{ + std::vector vv; + REQUIRE( Catch::toString(vv) == "{ }" ); + vv.push_back( "hello" ); + REQUIRE( Catch::toString(vv) == "{ \"hello\" }" ); + vv.push_back( "world" ); + REQUIRE( Catch::toString(vv) == "{ \"hello\", \"world\" }" ); +} + +#if defined(CATCH_CPP11_OR_GREATER) +/* + Note: These tests *can* be made to work with C++ < 11, but the + allocator is a lot more work... +*/ +namespace { + /* Minimal Allocator */ + template + struct minimal_allocator { + typedef T value_type; + typedef std::size_t size_type; + T *allocate( size_type n ) + { + return static_cast( ::operator new( n * sizeof(T) ) ); + } + void deallocate( T *p, size_type /*n*/ ) + { + ::operator delete( static_cast(p) ); + } + template + bool operator==( const minimal_allocator& ) const { return true; } + template + bool operator!=( const minimal_allocator& ) const { return false; } + }; +} + +TEST_CASE( "vector -> toString", "[toString][vector,allocator]" ) +{ + std::vector > vv; + REQUIRE( Catch::toString(vv) == "{ }" ); + vv.push_back( 42 ); + REQUIRE( Catch::toString(vv) == "{ 42 }" ); + vv.push_back( 512 ); + REQUIRE( Catch::toString(vv) == "{ 42, 512 }" ); +} + +TEST_CASE( "vec> -> toString", "[toString][vector,allocator]" ) +{ + typedef std::vector > inner; + typedef std::vector vector; + vector v; + REQUIRE( Catch::toString(v) == "{ }" ); + v.push_back( inner { "hello" } ); + v.push_back( inner { "world" } ); + REQUIRE( Catch::toString(v) == "{ { \"hello\" }, { \"world\" } }" ); +} +#endif diff --git a/projects/SelfTest/ToStringWhich.cpp b/projects/SelfTest/ToStringWhich.cpp new file mode 100644 index 00000000..785c65b7 --- /dev/null +++ b/projects/SelfTest/ToStringWhich.cpp @@ -0,0 +1,74 @@ +#include "catch.hpp" +/* + Demonstrate which version of toString/StringMaker is being used + for various types +*/ + + +struct has_toString { }; +struct has_maker {}; +struct has_maker_and_toString {}; + +namespace Catch { + inline std::string toString( const has_toString& ) { + return "toString( has_toString )"; + } + inline std::string toString( const has_maker_and_toString& ) { + return "toString( has_maker_and_toString )"; + } + template<> + struct StringMaker { + static std::string convert( const has_maker& ) { + return "StringMaker"; + } + }; + template<> + struct StringMaker { + static std::string convert( const has_maker_and_toString& ) { + return "StringMaker"; + } + }; +} + +// Call the overload +TEST_CASE( "toString( has_toString )", "[toString]" ) +{ + has_toString item; + REQUIRE( Catch::toString( item ) == "toString( has_toString )" ); +} + +// Call the overload +TEST_CASE( "toString( has_maker )", "[toString]" ) +{ + has_maker item; + REQUIRE( Catch::toString( item ) == "StringMaker" ); +} + +// Call the overload +TEST_CASE( "toString( has_maker_and_toString )", "[toString]" ) +{ + has_maker_and_toString item; + REQUIRE( Catch::toString( item ) == "toString( has_maker_and_toString )" ); +} + +// Vectors... +TEST_CASE( "toString( vectors v(1); + // This invokes template toString which actually gives us '{ ? }' + REQUIRE( Catch::toString( v ) == "{ {?} }" ); +} + +TEST_CASE( "toString( vectors v(1); + REQUIRE( Catch::toString( v ) == "{ StringMaker }" ); +} + + +TEST_CASE( "toString( vectors v(1); + // Note: This invokes the template toString -> StringMaker + REQUIRE( Catch::toString( v ) == "{ StringMaker }" ); +} diff --git a/projects/SelfTest/makefile b/projects/SelfTest/makefile index e9f64855..0a29372c 100644 --- a/projects/SelfTest/makefile +++ b/projects/SelfTest/makefile @@ -9,7 +9,10 @@ SOURCES = ApproxTests.cpp \ TrickyTests.cpp \ BDDTests.cpp \ VariadicMacrosTests.cpp \ - EnumToString.cpp + EnumToString.cpp \ + ToStringPair.cpp \ + ToStringVector.cpp \ + ToStringWhich.cpp OBJECTS = $(patsubst %.cpp, %.o, $(SOURCES)) diff --git a/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj b/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj index fe93974e..1ba0395b 100644 --- a/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj +++ b/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj @@ -8,6 +8,9 @@ /* Begin PBXBuildFile section */ 263F7A4719B6FCBF009474C2 /* EnumToString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4619B6FCBF009474C2 /* EnumToString.cpp */; }; + 263F7A4B19B6FE1E009474C2 /* ToStringPair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4819B6FE1E009474C2 /* ToStringPair.cpp */; }; + 263F7A4C19B6FE1E009474C2 /* ToStringVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4919B6FE1E009474C2 /* ToStringVector.cpp */; }; + 263F7A4D19B6FE1E009474C2 /* ToStringWhich.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4A19B6FE1E009474C2 /* ToStringWhich.cpp */; }; 2656C2211925E7330040DB02 /* catch_test_spec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2656C2201925E7330040DB02 /* catch_test_spec.cpp */; }; 266B06B816F3A60A004ED264 /* VariadicMacrosTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B06B616F3A60A004ED264 /* VariadicMacrosTests.cpp */; }; 266ECD74170F3C620030D735 /* BDDTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266ECD73170F3C620030D735 /* BDDTests.cpp */; }; @@ -69,6 +72,9 @@ 262E739A1846759000CAC268 /* catch_common.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_common.hpp; sourceTree = ""; }; 263F7A4519A66608009474C2 /* catch_fatal_condition.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_fatal_condition.hpp; sourceTree = ""; }; 263F7A4619B6FCBF009474C2 /* EnumToString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = EnumToString.cpp; path = ../../../SelfTest/EnumToString.cpp; sourceTree = ""; }; + 263F7A4819B6FE1E009474C2 /* ToStringPair.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ToStringPair.cpp; path = ../../../SelfTest/ToStringPair.cpp; sourceTree = ""; }; + 263F7A4919B6FE1E009474C2 /* ToStringVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ToStringVector.cpp; path = ../../../SelfTest/ToStringVector.cpp; sourceTree = ""; }; + 263F7A4A19B6FE1E009474C2 /* ToStringWhich.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ToStringWhich.cpp; path = ../../../SelfTest/ToStringWhich.cpp; sourceTree = ""; }; 263FD06017AF8DF200988A20 /* catch_timer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_timer.hpp; sourceTree = ""; }; 263FD06117AF8DF200988A20 /* catch_timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_timer.h; sourceTree = ""; }; 2656C21F1925E5100040DB02 /* catch_test_spec_parser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_test_spec_parser.hpp; sourceTree = ""; }; @@ -249,6 +255,9 @@ 4A6D0C40149B3DAB00DB3EAA /* Tests */ = { isa = PBXGroup; children = ( + 263F7A4819B6FE1E009474C2 /* ToStringPair.cpp */, + 263F7A4919B6FE1E009474C2 /* ToStringVector.cpp */, + 263F7A4A19B6FE1E009474C2 /* ToStringWhich.cpp */, 263F7A4619B6FCBF009474C2 /* EnumToString.cpp */, 266ECD73170F3C620030D735 /* BDDTests.cpp */, 4A6D0C36149B3D9E00DB3EAA /* TrickyTests.cpp */, @@ -531,7 +540,10 @@ 4A6D0C3D149B3D9E00DB3EAA /* MiscTests.cpp in Sources */, 4A6D0C3E149B3D9E00DB3EAA /* TestMain.cpp in Sources */, 4A6D0C3F149B3D9E00DB3EAA /* TrickyTests.cpp in Sources */, + 263F7A4D19B6FE1E009474C2 /* ToStringWhich.cpp in Sources */, + 263F7A4B19B6FE1E009474C2 /* ToStringPair.cpp in Sources */, 4AEE032016142F910071E950 /* catch_common.cpp in Sources */, + 263F7A4C19B6FE1E009474C2 /* ToStringVector.cpp in Sources */, 4AEE032316142FC70071E950 /* catch_debugger.cpp in Sources */, 4AEE032516142FF10071E950 /* catch_stream.cpp in Sources */, 4AEE0328161434FD0071E950 /* catch_xmlwriter.cpp in Sources */,