From abf9ffc9820fc8e1b27320316118034a8e4750c6 Mon Sep 17 00:00:00 2001 From: Andy Sawyer Date: Mon, 1 Sep 2014 18:09:37 +0100 Subject: [PATCH 1/2] A bunch of Catch::toString tests --- projects/SelfTest/ToStringPair.cpp | 51 +++++++++++++++++++ projects/SelfTest/ToStringVector.cpp | 72 +++++++++++++++++++++++++++ projects/SelfTest/ToStringWhich.cpp | 74 ++++++++++++++++++++++++++++ projects/SelfTest/makefile | 5 +- 4 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 projects/SelfTest/ToStringPair.cpp create mode 100644 projects/SelfTest/ToStringVector.cpp create mode 100644 projects/SelfTest/ToStringWhich.cpp 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..f9f4beb5 --- /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 { + std::string toString( const has_toString& ) { + return "toString( has_toString )"; + } + 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)) From fdbbb2c9bd6901c4fbb2e36868da6ac3e295f2b8 Mon Sep 17 00:00:00 2001 From: Andy Sawyer Date: Mon, 1 Sep 2014 18:27:29 +0100 Subject: [PATCH 2/2] Updated CMakeLists.txt for toString work --- projects/CMake/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) 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