aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Oesch <lukasoesch20@gmail.com>2026-03-27 19:39:55 +0100
committerLukas Oesch <lukasoesch20@gmail.com>2026-03-27 19:39:55 +0100
commit610707e896504a33fa82db4905e57a4822d3bb9d (patch)
tree693bdc43052c4f8c8aff93adde0ed91eb7672d57
parentc3e80174faa2db9e6674af995aaa95b59ec53fec (diff)
downloadteachos-610707e896504a33fa82db4905e57a4822d3bb9d.tar.xz
teachos-610707e896504a33fa82db4905e57a4822d3bb9d.zip
add string tests
-rw-r--r--libs/kstd/CMakeLists.txt1
-rw-r--r--libs/kstd/tests/src/string.cpp390
2 files changed, 391 insertions, 0 deletions
diff --git a/libs/kstd/CMakeLists.txt b/libs/kstd/CMakeLists.txt
index 06543ab..d4f415f 100644
--- a/libs/kstd/CMakeLists.txt
+++ b/libs/kstd/CMakeLists.txt
@@ -46,6 +46,7 @@ if(NOT CMAKE_CROSSCOMPILING)
add_executable("kstd_tests"
"tests/src/vector.cpp"
"tests/src/os_panic.cpp"
+ "tests/src/string.cpp"
)
target_include_directories("kstd_tests" PRIVATE
diff --git a/libs/kstd/tests/src/string.cpp b/libs/kstd/tests/src/string.cpp
new file mode 100644
index 0000000..f7f629d
--- /dev/null
+++ b/libs/kstd/tests/src/string.cpp
@@ -0,0 +1,390 @@
+#include <kstd/string>
+
+#include <catch2/catch_test_macros.hpp>
+
+#include <algorithm>
+#include <ranges>
+#include <string_view>
+
+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');
+ }
+ }
+ }
+}