Provide useful and unambigous stringification for static arrays

This commit is contained in:
Martin Hořeňovský 2018-01-14 18:06:21 +01:00
parent f0909dfe02
commit 8d854c689b
7 changed files with 118 additions and 20 deletions

View File

@ -136,18 +136,6 @@ namespace Catch {
static std::string convert(wchar_t * str); static std::string convert(wchar_t * str);
}; };
template<typename T>
struct is_string_array : std::false_type {};
template<std::size_t N>
struct is_string_array<char[N]> : std::true_type {};
template<std::size_t N>
struct is_string_array<signed char[N]> : std::true_type {};
template<std::size_t N>
struct is_string_array<unsigned char[N]> : std::true_type {};
template<int SZ> template<int SZ>
struct StringMaker<char[SZ]> { struct StringMaker<char[SZ]> {
static std::string convert(const char* str) { static std::string convert(const char* str) {
@ -399,12 +387,20 @@ namespace Catch {
} }
template<typename R> template<typename R>
struct StringMaker<R, typename std::enable_if<is_range<R>::value && !is_string_array<R>::value>::type> { struct StringMaker<R, typename std::enable_if<is_range<R>::value && !std::is_array<R>::value>::type> {
static std::string convert( R const& range ) { static std::string convert( R const& range ) {
return rangeToString( range ); return rangeToString( range );
} }
}; };
template <typename T, int SZ>
struct StringMaker<T[SZ]> {
static std::string convert(T const(&arr)[SZ]) {
return rangeToString(arr);
}
};
} // namespace Catch } // namespace Catch
// Separate std::chrono::duration specialization // Separate std::chrono::duration specialization

View File

@ -598,6 +598,11 @@ Message from section one
Message from section two Message from section two
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), StartsWith("This String") for: "this string contains 'abc' as a substring" starts with: "This String" Matchers.tests.cpp:<line number>: failed: testStringForMatching(), StartsWith("This String") for: "this string contains 'abc' as a substring" starts with: "This String"
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), StartsWith("string", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" starts with: "string" (case insensitive) Matchers.tests.cpp:<line number>: failed: testStringForMatching(), StartsWith("string", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" starts with: "string" (case insensitive)
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify(singular) == "{ 1 }" for: "{ 1 }" == "{ 1 }"
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify(arr) == "{ 3, 2, 1 }" for: "{ 3, 2, 1 }" == "{ 3, 2, 1 }"
ToStringGeneral.tests.cpp:<line number>: passed: Catch::Detail::stringify(arr) == R"({ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } })" for: "{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
==
"{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Contains("string") for: "this string contains 'abc' as a substring" contains: "string" Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Contains("string") for: "this string contains 'abc' as a substring" contains: "string"
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Contains("string", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" contains: "string" (case insensitive) Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Contains("string", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" contains: "string" (case insensitive)
Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Contains("abc") for: "this string contains 'abc' as a substring" contains: "abc" Matchers.tests.cpp:<line number>: passed: testStringForMatching(), Contains("abc") for: "this string contains 'abc' as a substring" contains: "abc"

View File

@ -1064,6 +1064,6 @@ with expansion:
"first" == "second" "first" == "second"
=============================================================================== ===============================================================================
test cases: 196 | 145 passed | 47 failed | 4 failed as expected test cases: 197 | 146 passed | 47 failed | 4 failed as expected
assertions: 989 | 863 passed | 105 failed | 21 failed as expected assertions: 992 | 866 passed | 105 failed | 21 failed as expected

View File

@ -4749,6 +4749,47 @@ with expansion:
"this string contains 'abc' as a substring" starts with: "string" (case "this string contains 'abc' as a substring" starts with: "string" (case
insensitive) insensitive)
-------------------------------------------------------------------------------
Static arrays are convertible to string
Single item
-------------------------------------------------------------------------------
ToStringGeneral.tests.cpp:<line number>
...............................................................................
ToStringGeneral.tests.cpp:<line number>:
PASSED:
REQUIRE( Catch::Detail::stringify(singular) == "{ 1 }" )
with expansion:
"{ 1 }" == "{ 1 }"
-------------------------------------------------------------------------------
Static arrays are convertible to string
Multiple
-------------------------------------------------------------------------------
ToStringGeneral.tests.cpp:<line number>
...............................................................................
ToStringGeneral.tests.cpp:<line number>:
PASSED:
REQUIRE( Catch::Detail::stringify(arr) == "{ 3, 2, 1 }" )
with expansion:
"{ 3, 2, 1 }" == "{ 3, 2, 1 }"
-------------------------------------------------------------------------------
Static arrays are convertible to string
Non-trivial inner items
-------------------------------------------------------------------------------
ToStringGeneral.tests.cpp:<line number>
...............................................................................
ToStringGeneral.tests.cpp:<line number>:
PASSED:
REQUIRE( Catch::Detail::stringify(arr) == R"({ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } })" )
with expansion:
"{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
==
"{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
String matchers String matchers
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -8288,6 +8329,6 @@ Misc.tests.cpp:<line number>:
PASSED: PASSED:
=============================================================================== ===============================================================================
test cases: 196 | 143 passed | 49 failed | 4 failed as expected test cases: 197 | 144 passed | 49 failed | 4 failed as expected
assertions: 988 | 859 passed | 108 failed | 21 failed as expected assertions: 991 | 862 passed | 108 failed | 21 failed as expected

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact <testsuitesloose text artifact
> >
<testsuite name="<exe-name>" errors="15" failures="94" tests="989" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}"> <testsuite name="<exe-name>" errors="15" failures="94" tests="992" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/> <testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
<testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/> <testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
<testcase classname="<exe-name>.global" name="#1027" time="{duration}"/> <testcase classname="<exe-name>.global" name="#1027" time="{duration}"/>
@ -538,6 +538,9 @@ Matchers.tests.cpp:<line number>
Matchers.tests.cpp:<line number> Matchers.tests.cpp:<line number>
</failure> </failure>
</testcase> </testcase>
<testcase classname="<exe-name>.global" name="Static arrays are convertible to string/Single item" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Static arrays are convertible to string/Multiple" time="{duration}"/>
<testcase classname="<exe-name>.global" name="Static arrays are convertible to string/Non-trivial inner items" time="{duration}"/>
<testcase classname="<exe-name>.global" name="String matchers" time="{duration}"/> <testcase classname="<exe-name>.global" name="String matchers" time="{duration}"/>
<testcase classname="<exe-name>.global" name="StringRef/Empty string" time="{duration}"/> <testcase classname="<exe-name>.global" name="StringRef/Empty string" time="{duration}"/>
<testcase classname="<exe-name>.global" name="StringRef/From string literal" time="{duration}"/> <testcase classname="<exe-name>.global" name="StringRef/From string literal" time="{duration}"/>

View File

@ -5477,6 +5477,44 @@ Message from section two
</Expression> </Expression>
<OverallResult success="false"/> <OverallResult success="false"/>
</TestCase> </TestCase>
<TestCase name="Static arrays are convertible to string" tags="[toString]" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
<Section name="Single item" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
<Original>
Catch::Detail::stringify(singular) == "{ 1 }"
</Original>
<Expanded>
"{ 1 }" == "{ 1 }"
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<Section name="Multiple" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
<Original>
Catch::Detail::stringify(arr) == "{ 3, 2, 1 }"
</Original>
<Expanded>
"{ 3, 2, 1 }" == "{ 3, 2, 1 }"
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<Section name="Non-trivial inner items" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
<Original>
Catch::Detail::stringify(arr) == R"({ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } })"
</Original>
<Expanded>
"{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
==
"{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
</Expanded>
</Expression>
<OverallResults successes="1" failures="0" expectedFailures="0"/>
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="String matchers" tags="[matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <TestCase name="String matchers" tags="[matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
<Original> <Original>
@ -9219,7 +9257,7 @@ loose text artifact
</Section> </Section>
<OverallResult success="true"/> <OverallResult success="true"/>
</TestCase> </TestCase>
<OverallResults successes="859" failures="109" expectedFailures="21"/> <OverallResults successes="862" failures="109" expectedFailures="21"/>
</Group> </Group>
<OverallResults successes="859" failures="108" expectedFailures="21"/> <OverallResults successes="862" failures="108" expectedFailures="21"/>
</Catch> </Catch>

View File

@ -100,3 +100,18 @@ TEST_CASE( "std::set is convertible string", "[toString]" ) {
REQUIRE( Catch::Detail::stringify( set ) == "{ \"abc\", \"def\", \"ghi\" }" ); REQUIRE( Catch::Detail::stringify( set ) == "{ \"abc\", \"def\", \"ghi\" }" );
} }
} }
TEST_CASE("Static arrays are convertible to string", "[toString]") {
SECTION("Single item") {
int singular[1] = { 1 };
REQUIRE(Catch::Detail::stringify(singular) == "{ 1 }");
}
SECTION("Multiple") {
int arr[3] = { 3, 2, 1 };
REQUIRE(Catch::Detail::stringify(arr) == "{ 3, 2, 1 }");
}
SECTION("Non-trivial inner items") {
std::vector<std::string> arr[2] = { {"1:1", "1:2", "1:3"}, {"2:1", "2:2"} };
REQUIRE(Catch::Detail::stringify(arr) == R"({ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } })");
}
}