#include #include #include #include #include SCENARIO("String initialization and construction", "[string]") { GIVEN("Nothing") { WHEN("constructing an empty string") { auto str = kstd::string{}; THEN("the size is zero and therefore the string is empty") { REQUIRE(str.empty()); REQUIRE(str.size() == 0); } THEN("the string is empty") { REQUIRE(str.view() == std::string_view{}); } } } GIVEN("A string view") { auto view = std::string_view{"Blub Blub"}; WHEN("constructing a string from string_view") { auto str = kstd::string{view}; THEN("the string is not empty and has the same size as the view") { REQUIRE(!str.empty()); REQUIRE(str.size() == view.size()); } THEN("the string contains the same characters as the view") { REQUIRE(str.view() == view); } } } GIVEN("A C-style string") { auto c_str = "Blub Blub"; WHEN("constructing a string from the C-style string") { auto str = kstd::string{c_str}; THEN("the string is not empty and has the same size as the C-style string") { REQUIRE(!str.empty()); REQUIRE(str.size() == strlen(c_str)); } THEN("the string contains the same characters as the C-style string") { REQUIRE(str.view() == c_str); } } } GIVEN("A character") { auto ch = 'x'; WHEN("constructing a string from the character") { auto str = kstd::string{ch}; THEN("the string is not empty and has size 1") { REQUIRE(!str.empty()); REQUIRE(str.size() == 1); } THEN("the string contains the same character as the given character") { REQUIRE(str.view() == std::string_view{&ch, 1}); } } } GIVEN("Another string") { auto other = kstd::string{"Blub Blub"}; WHEN("copy constructing a new string") { auto str = kstd::string{other}; THEN("the new string contains the same characters as the original") { REQUIRE(str.view() == other.view()); } } auto str = kstd::string{"Blub"}; WHEN("copy assigning another string") { auto other = kstd::string{"Blub Blub"}; str = other; THEN("the string contains the same characters as the assigned string") { REQUIRE(str.view() == other.view()); } } } GIVEN("A string") { auto str = kstd::string{"Hello"}; WHEN("copy assigning a string view") { auto view = std::string_view{"Hello, world!"}; str = view; THEN("the string contains the same characters as the assigned view") { REQUIRE(str.view() == view); } } } GIVEN("A string") { auto str = kstd::string{"Hello"}; WHEN("copy assigning a C-style string") { auto c_str = "Hello, world!"; str = c_str; THEN("the string contains the same characters as the assigned C-style string") { REQUIRE(str.view() == c_str); } } } } SCENARIO("String concatenation", "[string]") { GIVEN("Two strings") { auto str1 = kstd::string{"Blub"}; auto str2 = kstd::string{" Blub"}; WHEN("appending the second string to the first string") { str1.append(str2); THEN("the first string contains the characters of both strings concatenated") { REQUIRE(str1.view() == "Blub Blub"); } THEN("the size of the first string is the sum of the sizes of both strings") { REQUIRE(str1.size() == str2.size() + 4); } } WHEN("using operator+= to append the second string to the first string") { str1 += str2; THEN("the first string contains the characters of both strings concatenated") { REQUIRE(str1.view() == "Blub Blub"); } THEN("the size of the first string is the sum of the sizes of both strings") { REQUIRE(str1.size() == str2.size() + 4); } } WHEN("using operator+ to concatenate the two strings into a new string") { auto str3 = str1 + str2; THEN("the new string contains the characters of both strings concatenated") { REQUIRE(str3.view() == "Blub Blub"); } THEN("the size of the new string is the sum of the sizes of both strings") { REQUIRE(str3.size() == str1.size() + str2.size()); } } } GIVEN("A string and a string view") { auto str = kstd::string{"Blub"}; auto view = std::string_view{" Blub"}; WHEN("appending the string view to the string") { str.append(view); THEN("the string contains the characters of both the original string and the appended view concatenated") { REQUIRE(str.view() == "Blub Blub"); } THEN("the size of the string is the sum of the sizes of the original string and the appended view") { REQUIRE(str.size() == view.size() + 4); } } } GIVEN("A string and a character") { auto str = kstd::string{"Blub"}; auto ch = '!'; WHEN("appending the character to the string") { str.push_back(ch); THEN("the string contains the original characters followed by the appended character") { REQUIRE(str.view() == "Blub!"); } THEN("the size of the string is one more than the original size") { REQUIRE(str.size() == 5); } } WHEN("using operator+= to append the character to the string") { str += ch; THEN("the string contains the original characters followed by the appended character") { REQUIRE(str.view() == "Blub!"); } THEN("the size of the string is one more than the original size") { REQUIRE(str.size() == 5); } } } } SCENARIO("String conversion and comparison", "[string]") { GIVEN("An unsigned integer") { auto value1 = 12345u; auto value2 = 0u; WHEN("converting the unsigned integer to a string") { auto str1 = kstd::to_string(value1); auto str2 = kstd::to_string(value2); THEN("the string contains the decimal representation of the unsigned integer") { REQUIRE(str1.view() == "12345"); REQUIRE(str2.view() == "0"); } } } GIVEN("Two strings with the same characters") { auto str1 = kstd::string{"Blub Blub"}; auto str2 = kstd::string{"Blub Blub"}; THEN("the strings are equal") { REQUIRE(str1 == str2); } THEN("the strings are not unequal") { REQUIRE(!(str1 != str2)); } } GIVEN("A string and a string view with the same characters") { auto str = kstd::string{"Blub Blub"}; auto view = std::string_view{"Blub Blub"}; THEN("the string and the string view are equal") { REQUIRE(str == view); REQUIRE(view == str); } THEN("the string and the string view are not unequal") { REQUIRE(!(str != view)); REQUIRE(!(view != str)); } } } SCENARIO("String clearing", "[string]") { GIVEN("A non-empty string") { auto str = kstd::string{"Blub Blub"}; WHEN("clearing the string") { str.clear(); THEN("the string is empty and has size zero") { REQUIRE(str.empty()); REQUIRE(str.size() == 0); } THEN("the string contains no characters") { REQUIRE(str.view() == std::string_view{}); } } } } SCENARIO("String iteration", "[string]") { GIVEN("A string") { auto str = kstd::string{"Blub"}; WHEN("iterating over the characters of the string as string_view using a range-based for loop") { kstd::string result; for (auto ch : str.view()) { result.push_back(ch); } THEN("the iterated characters are the same as the characters in the string") { REQUIRE(result == str); } } WHEN("using std::ranges::for_each to iterate over the characters of the string") { kstd::string result; std::ranges::for_each(str, [&result](auto ch) { result.push_back(ch); }); THEN("the iterated characters are the same as the characters in the string") { REQUIRE(result == str); } } WHEN("using front and back to access the first and last characters of the string") { THEN("front returns the first character of the string") { REQUIRE(str.front() == 'B'); } THEN("back returns the last character of the string") { REQUIRE(str.back() == 'b'); } } GIVEN("A non-empty string") { auto str = kstd::string{"Hello"}; WHEN("using const end()") { auto it = str.end(); // calls const end() THEN("it points past the last character") { REQUIRE(*std::prev(it) == 'o'); REQUIRE(std::distance(str.begin(), it) == str.size()); } } } GIVEN("A const string") { auto const str = kstd::string{"Blub"}; WHEN("iterating over the characters of the string as string_view using a range-based for loop") { kstd::string result; for (auto ch : str.view()) { result.push_back(ch); } THEN("the iterated characters are the same as the characters in the string") { REQUIRE(result == str.view()); } } WHEN("using front and back to access the first and last characters of the string") { THEN("front returns the first character of the string") { REQUIRE(str.front() == 'B'); } THEN("back returns the last character of the string") { REQUIRE(str.back() == 'b'); } } } GIVEN("An empty string") { auto str = kstd::string{}; WHEN("iterating over the characters of an empty string") { kstd::string result; for (auto ch : str.view()) { result.push_back(ch); } THEN("no characters are iterated and the result is an empty string") { REQUIRE(result.empty()); REQUIRE(result.size() == 0); REQUIRE(result.view() == std::string_view{}); } } } }