mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 12:17:11 +01:00 
			
		
		
		
	Provide useful and unambigous stringification for static arrays
This commit is contained in:
		| @@ -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 | ||||||
|   | |||||||
| @@ -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" | ||||||
|   | |||||||
| @@ -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 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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}"/> | ||||||
|   | |||||||
| @@ -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> | ||||||
|   | |||||||
| @@ -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" } })"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Martin Hořeňovský
					Martin Hořeňovský