diff options
| author | Phil Nash | 2017-06-29 11:18:14 +0100 |
|---|---|---|
| committer | Phil Nash | 2017-06-29 11:18:14 +0100 |
| commit | 78e799443531a84c5f337109d462af53249ed49c (patch) | |
| tree | a7dffa857b65d022145b258a7b7a3b110f902409 /projects/SelfTest/StringRef.tests.cpp | |
| parent | cb0a5194af7e092fde6f1f7deffb2758e28e65fe (diff) | |
| download | catch3-78e799443531a84c5f337109d462af53249ed49c.tar.gz | |
Added string classes
Diffstat (limited to 'projects/SelfTest/StringRef.tests.cpp')
| -rw-r--r-- | projects/SelfTest/StringRef.tests.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/projects/SelfTest/StringRef.tests.cpp b/projects/SelfTest/StringRef.tests.cpp new file mode 100644 index 00000000..e5da3f2a --- /dev/null +++ b/projects/SelfTest/StringRef.tests.cpp @@ -0,0 +1,151 @@ +#include "../include/internal/catch_stringref.h" +#include "../include/internal/catch_string.h" + +#include "catch.hpp" + +namespace Catch { + + // Implementation of test accessors + struct StringRefTestAccess { + static auto isOwned( StringRef const& stringRef ) -> bool { + return stringRef.isOwned(); + } + static auto isSubstring( StringRef const& stringRef ) -> bool { + return stringRef.isSubstring(); + } + static auto data( StringRef const& stringRef ) -> char const* { + return stringRef.data(); + } + }; + + auto isOwned( StringRef const& stringRef ) -> bool { + return StringRefTestAccess::isOwned( stringRef ); + } + auto isSubstring( StringRef const& stringRef ) -> bool { + return StringRefTestAccess::isSubstring( stringRef ); + } + auto data( StringRef const& stringRef ) -> char const* { + return StringRefTestAccess::data( stringRef ); + } +} // namespace Catch2 + +namespace Catch { + inline auto toString( Catch::StringRef const& stringRef ) -> std::string { + return std::string( data( stringRef ), stringRef.size() ); + } +} // namespace Catch + +TEST_CASE( "StringRef", "[Strings]" ) { + + using Catch::StringRef; + using Catch::String; + + SECTION( "Empty string" ) { + StringRef empty; + REQUIRE( empty.empty() ); + REQUIRE( empty.size() == 0 ); + REQUIRE( std::strcmp( empty.c_str(), "" ) == 0 ); + } + + SECTION( "From string literal" ) { + StringRef s = "hello"; + REQUIRE( s.empty() == false ); + REQUIRE( s.size() == 5 ); + REQUIRE( isSubstring( s ) == false ); + + auto rawChars = data( s ); + REQUIRE( std::strcmp( rawChars, "hello" ) == 0 ); + + SECTION( "c_str() does not cause copy" ) { + REQUIRE( isOwned( s ) == false ); + + REQUIRE( s.c_str() == rawChars ); + + REQUIRE( isOwned( s ) == false ); + } + } + SECTION( "From sub-string" ) { + StringRef original = StringRef( "original string" ).substr(0, 8); + REQUIRE( original == "original" ); + REQUIRE( isSubstring( original ) ); + REQUIRE( isOwned( original ) == false ); + + original.c_str(); // Forces it to take ownership + + REQUIRE( isSubstring( original ) == false ); + REQUIRE( isOwned( original ) ); + + } + + + SECTION( "Substrings" ) { + StringRef s = "hello world!"; + StringRef ss = s.substr(0, 5); + + SECTION( "zero-based substring" ) { + REQUIRE( ss.empty() == false ); + REQUIRE( ss.size() == 5 ); + REQUIRE( std::strcmp( ss.c_str(), "hello" ) == 0 ); + REQUIRE( ss == "hello" ); + } + SECTION( "c_str() causes copy" ) { + REQUIRE( isSubstring( ss ) ); + REQUIRE( isOwned( ss ) == false ); + + auto rawChars = data( ss ); + REQUIRE( rawChars == data( s ) ); // same pointer value + REQUIRE( ss.c_str() != rawChars ); + + REQUIRE( isSubstring( ss ) == false ); + REQUIRE( isOwned( ss ) ); + + REQUIRE( data( ss ) != data( s ) ); // different pointer value + } + + SECTION( "non-zero-based substring") { + ss = s.substr( 6, 6 ); + REQUIRE( ss.size() == 6 ); + REQUIRE( std::strcmp( ss.c_str(), "world!" ) == 0 ); + } + + SECTION( "Pointer values of full refs should match" ) { + StringRef s2 = s; + REQUIRE( s.c_str() == s2.c_str() ); + } + + SECTION( "Pointer values of substring refs should not match" ) { + REQUIRE( s.c_str() != ss.c_str() ); + } + } + + SECTION( "Comparisons" ) { + REQUIRE( StringRef("hello") == StringRef("hello") ); + REQUIRE( StringRef("hello") != StringRef("cello") ); + } + + SECTION( "From string" ) { + String str = "hot potato"; + auto originalPointer = str.c_str(); + + SECTION( "Copied" ) { + // After a String is "copied" to a StringRef + // It has only copied the pointer and size + // - it does not take ownership + StringRef copied = str; + REQUIRE( copied == "hot potato" ); + REQUIRE( str == "hot potato" ); + REQUIRE( isOwned( copied ) == false ); + REQUIRE( data( copied ) == originalPointer ); + } + SECTION( "Moved" ) { + // After a String is *moved* to a StringRef + // The StringRef takes ownership of the underlying data + // and the String is left in an empty state + StringRef copied = std::move( str ); + REQUIRE( copied == "hot potato" ); + REQUIRE( isOwned( copied ) ); + REQUIRE( str.empty() ); + REQUIRE( data( copied ) == originalPointer ); + } + } +} |