From 4a764bc3158911ee4cb6cc92a8192cb28b3f22ff Mon Sep 17 00:00:00 2001 From: apio Date: Thu, 11 May 2023 16:56:28 +0200 Subject: [PATCH] tests+libluna: Start testing Format.cpp --- libluna/src/Format.cpp | 7 +- tests/CMakeLists.txt | 1 + tests/libluna/TestFormat.cpp | 140 +++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 tests/libluna/TestFormat.cpp diff --git a/libluna/src/Format.cpp b/libluna/src/Format.cpp index d2a9564e..81b3bfc2 100644 --- a/libluna/src/Format.cpp +++ b/libluna/src/Format.cpp @@ -223,6 +223,9 @@ static Result output_integer(char specifier, conv_state& vstate, format_st usize base = 10; bool uppercase = false; + // When 0 is printed with an explicit precision 0, the output is empty. + if ((vstate.flags & FLAG_USE_PRECISION) && vstate.precision == 0 && value == 0) return {}; + switch (specifier) { case 'p': @@ -438,6 +441,7 @@ Result cstyle_format(const char* format, callback_t callback, void* arg, } else if (specifier == 'c') { + // FIXME: If FLAG_LONG is set, we should use a wint_t. const char c = (char)va_arg(ap, int); TRY(start_pad(vstate, state, 1)); @@ -448,6 +452,7 @@ Result cstyle_format(const char* format, callback_t callback, void* arg, } else if (specifier == 's') { + // FIXME: If FLAG_LONG is set, we should use a wide string. const char* str = va_arg(ap, const char*); if (str == nullptr) { @@ -467,7 +472,7 @@ Result cstyle_format(const char* format, callback_t callback, void* arg, while (*str && (!use_precision || precision)) { TRY(format_putchar(*str, state)); - precision--; + if (use_precision) precision--; str++; } TRY(end_pad(vstate, state, len)); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index df154734..9e593cfc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,6 +16,7 @@ if(BUILD_TESTS) luna_test(libluna/TestVector.cpp TestVector) luna_test(libluna/TestBase64.cpp TestBase64) luna_test(libluna/TestUtf8.cpp TestUtf8) +luna_test(libluna/TestFormat.cpp TestFormat) luna_app(run-tests.cpp run-tests) endif() diff --git a/tests/libluna/TestFormat.cpp b/tests/libluna/TestFormat.cpp new file mode 100644 index 00000000..05bda4c5 --- /dev/null +++ b/tests/libluna/TestFormat.cpp @@ -0,0 +1,140 @@ +#include +#include + +TestResult test_no_format() +{ + auto fmt = TRY(String::format("Hello, world!"_sv)); + + validate(fmt.view() == "Hello, world!"); + + test_success; +} + +TestResult test_basic_string_format() +{ + auto fmt = TRY(String::format("%s"_sv, "Hello, world!")); + + validate(fmt.view() == "Hello, world!"); + + test_success; +} + +TestResult test_string_format_with_extra_chars() +{ + auto fmt = TRY(String::format("Hello, %s!"_sv, "world")); + + validate(fmt.view() == "Hello, world!"); + + test_success; +} + +TestResult test_string_format_with_width() +{ + auto fmt = TRY(String::format("Hello,%6s!"_sv, "world")); + + validate(fmt.view() == "Hello, world!"); + + test_success; +} + +TestResult test_string_format_left_align() +{ + auto fmt = TRY(String::format("Hello, %-7s"_sv, "world!")); + + validate(fmt.view() == "Hello, world! "); + + test_success; +} + +TestResult test_string_format_precision() +{ + auto fmt = TRY(String::format("Hello, %.5s!"_sv, "world! this is some extra stuff we don't need")); + + validate(fmt.view() == "Hello, world!"); + + test_success; +} + +TestResult test_basic_signed_integer_format() +{ + auto fmt = TRY(String::format("%d"_sv, 42)); + + validate(fmt.view() == "42"); + + test_success; +} + +TestResult test_negative_signed_integer_format() +{ + auto fmt = TRY(String::format("%d"_sv, -653)); + + validate(fmt.view() == "-653"); + + test_success; +} + +TestResult test_positive_signed_integer_format() +{ + auto fmt = TRY(String::format("%+d"_sv, 653)); + + validate(fmt.view() == "+653"); + + test_success; +} + +TestResult test_format_zero_with_explicit_zero_precision() +{ + auto fmt = TRY(String::format("%.0d"_sv, 0)); + + validate(fmt.is_empty()); + + test_success; +} + +TestResult test_octal_format() +{ + auto fmt = TRY(String::format("%o"_sv, 34)); + + validate(fmt.view() == "42"); + + test_success; +} + +TestResult test_hex_format() +{ + auto fmt = TRY(String::format("%x"_sv, 43707)); + + validate(fmt.view() == "aabb"); + + test_success; +} + +TestResult test_uppercase_hex_format() +{ + auto fmt = TRY(String::format("%X"_sv, 43707)); + + validate(fmt.view() == "AABB"); + + test_success; +} + +Result test_main() +{ + test_prelude; + + run_test(test_no_format); + run_test(test_basic_string_format); + run_test(test_string_format_with_extra_chars); + run_test(test_string_format_with_width); + run_test(test_string_format_left_align); + run_test(test_string_format_precision); + run_test(test_basic_signed_integer_format); + run_test(test_negative_signed_integer_format); + run_test(test_positive_signed_integer_format); + run_test(test_format_zero_with_explicit_zero_precision); + run_test(test_octal_format); + run_test(test_hex_format); + run_test(test_uppercase_hex_format); + + return {}; +}