From cd1dd2037cbe1d5f1362202d3127640406b468b8 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Apr 2026 15:38:08 +0200 Subject: kstd: add basic format and format_to tests --- libs/kstd/CMakeLists.txt | 1 + libs/kstd/include/kstd/bits/format/vformat.hpp | 6 +- libs/kstd/include/kstd/string | 20 +++++ libs/kstd/tests/src/format.cpp | 116 +++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 libs/kstd/tests/src/format.cpp (limited to 'libs') diff --git a/libs/kstd/CMakeLists.txt b/libs/kstd/CMakeLists.txt index f7c771b..ced3138 100644 --- a/libs/kstd/CMakeLists.txt +++ b/libs/kstd/CMakeLists.txt @@ -44,6 +44,7 @@ if(CMAKE_CROSSCOMPILING) else() add_executable("kstd_tests" "tests/src/flat_map.cpp" + "tests/src/format.cpp" "tests/src/vector.cpp" "tests/src/observer_ptr.cpp" "tests/src/os_panic.cpp" diff --git a/libs/kstd/include/kstd/bits/format/vformat.hpp b/libs/kstd/include/kstd/bits/format/vformat.hpp index 69c7f33..4fec7dd 100644 --- a/libs/kstd/include/kstd/bits/format/vformat.hpp +++ b/libs/kstd/include/kstd/bits/format/vformat.hpp @@ -52,7 +52,7 @@ namespace kstd auto push(std::string_view text) -> void override { - m_output = std::ranges::copy(text, m_output); + m_output = std::ranges::copy(text, m_output).out; } auto push(char character) -> void override @@ -75,7 +75,7 @@ namespace kstd auto format(format_string...> format, ArgumentTypes &&... args) -> string { auto buffer = bits::format::string_writer{}; - bits::format::vformat_to(buffer, format.str_view, std::forward(args)...); + bits::format::vformat_to(buffer, format.str_view, make_format_args(std::forward(args)...).args); return buffer.release(); } @@ -90,7 +90,7 @@ namespace kstd ArgumentTypes &&... args) -> Output { auto buffer = bits::format::iterator_writer{iterator}; - bits::format::vformat_to(buffer, format.str_view, std::forward(args)...); + bits::format::vformat_to(buffer, format.str_view, make_format_args(std::forward(args)...).args); return buffer.iterator(); } diff --git a/libs/kstd/include/kstd/string b/libs/kstd/include/kstd/string index 4ce19ce..58c4a08 100644 --- a/libs/kstd/include/kstd/string +++ b/libs/kstd/include/kstd/string @@ -347,6 +347,26 @@ namespace kstd return !(lhs == rhs); } + [[nodiscard]] constexpr auto inline operator==(string const & lhs, char const * rhs) -> bool + { + return lhs.view() == std::string_view{rhs}; + } + + [[nodiscard]] constexpr auto inline operator!=(string const & lhs, char const * rhs) -> bool + { + return !(lhs == rhs); + } + + [[nodiscard]] constexpr auto inline operator==(char const * lhs, string const & rhs) -> bool + { + return std::string_view{lhs} == rhs.view(); + } + + [[nodiscard]] constexpr auto inline operator!=(char const * lhs, string const & rhs) -> bool + { + return !(lhs == rhs); + } + template<> struct formatter : formatter { diff --git a/libs/kstd/tests/src/format.cpp b/libs/kstd/tests/src/format.cpp new file mode 100644 index 0000000..4915e50 --- /dev/null +++ b/libs/kstd/tests/src/format.cpp @@ -0,0 +1,116 @@ +#include +#include +#include + +#include + +#include +#include + +SCENARIO("Formatting to a new string", "[format]") +{ + GIVEN("a format string without any placeholders") + { + auto const & fmt = "This is a test"; + + WHEN("calling format with without any arguments.") + { + auto result = kstd::format(fmt); + + THEN("the result is the unmodified string") + { + REQUIRE(result == "This is a test"); + } + } + + WHEN("calling format with additional arguments") + { + auto result = kstd::format(fmt, 1, 2, 3); + + THEN("the result is the unmodified string") + { + REQUIRE(result == "This is a test"); + } + } + } + + GIVEN("a format string with placeholders") + { + auto const & fmt = "Here are some placeholders: {} {} {}"; + + WHEN("calling format with the same number of arguments as there are placeholders") + { + auto result = kstd::format(fmt, 1, true, -100); + + THEN("the result is the formatted string") + { + REQUIRE(result == "Here are some placeholders: 1 true -100"); + } + } + + WHEN("calling format with too many arguments") + { + auto result = kstd::format(fmt, 2, false, -200, 4, 5, 6); + + THEN("the result is the formatted string") + { + REQUIRE(result == "Here are some placeholders: 2 false -200"); + } + } + } +} + +SCENARIO("Formatting to an output iterator", "[format]") +{ + auto buffer = std::ostringstream{}; + + GIVEN("a format string without any placeholders") + { + auto const & fmt = "This is a test"; + + WHEN("calling format with without any arguments.") + { + kstd::format_to(std::ostream_iterator{buffer}, fmt); + + THEN("the unmodified string is written to the iterator") + { + REQUIRE(buffer.str() == "This is a test"); + } + } + + WHEN("calling format with additional arguments") + { + kstd::format_to(std::ostream_iterator{buffer}, fmt, 1, 2, 3); + + THEN("the unmodified string is written to the iterator") + { + REQUIRE(buffer.str() == "This is a test"); + } + } + } + + GIVEN("a format string with placeholders") + { + auto const & fmt = "Here are some placeholders: {} {} {}"; + + WHEN("calling format with the same number of arguments as there are placeholders") + { + kstd::format_to(std::ostream_iterator{buffer}, fmt, 1, true, -100); + + THEN("the formatted string is written to the iterator") + { + REQUIRE(buffer.str() == "Here are some placeholders: 1 true -100"); + } + } + + WHEN("calling format with too many arguments") + { + kstd::format_to(std::ostream_iterator{buffer}, fmt, 2, false, -200, 4, 5, 6); + + THEN("the formatted string is written to the iterator") + { + REQUIRE(buffer.str() == "Here are some placeholders: 2 false -200"); + } + } + } +} \ No newline at end of file -- cgit v1.2.3