From 9f19bc074d7bc8750f165e7040c3d95e15e0d8bd Mon Sep 17 00:00:00 2001 From: Mateusz Masiarz Date: Fri, 6 Sep 2024 23:48:16 +0200 Subject: [PATCH] Fix abbreviated translators (#2) * Fix abbreviated translators * Add translation tests * Change formatting --- tester.cc | 47 +++++++++++++++++++++++++++++++++++++++++++++++ tests.hh | 44 ++++++++++++++++++++++++++++++++++++++++++++ translations.hh | 14 +++++++++----- 3 files changed, 100 insertions(+), 5 deletions(-) diff --git a/tester.cc b/tester.cc index f01b931..7746c2f 100644 --- a/tester.cc +++ b/tester.cc @@ -93,5 +93,52 @@ main () ++index; } + index = 0; + for (const auto &test_case : test_translation_cases) + { + // Prevent the compiler from optimizing the test + std::string first_copy (test_case.first.size (), '\0'); + std::memcpy (first_copy.data (), test_case.first.data (), + test_case.first.size ()); + std::string second_copy (test_case.second.size (), '\0'); + std::memcpy (second_copy.data (), test_case.second.data (), + test_case.second.size ()); + + auto result = oicompare::compare ( + first_copy.c_str (), first_copy.c_str () + first_copy.size (), + second_copy.c_str (), second_copy.c_str () + second_copy.size ()); + + // Replace stdout. + fflush (stdout); + int stdout_fd = dup (fileno (stdout)); + std::FILE *capture_file = tmpfile (); + dup2 (fileno (capture_file), fileno (stdout)); + + // Print the result. + test_case.translator (result); + + // Restore stdout. + fflush (stdout); + dup2 (stdout_fd, fileno (stdout)); + close (stdout_fd); + + char buffer[1024]; + std::string result_str; + rewind (capture_file); + while (fgets (buffer, sizeof (buffer), capture_file) != nullptr) + result_str += buffer; + fclose (capture_file); + + if (result_str != test_case.result) + { + fmt::println ("Test {} failed", index); + fmt::println ("Expected: {}", test_case.result); + fmt::println ("Got: {}", result_str); + return 1; + } + + ++index; + } + return 0; } \ No newline at end of file diff --git a/tests.hh b/tests.hh index bd4f3e8..127056e 100644 --- a/tests.hh +++ b/tests.hh @@ -4,6 +4,7 @@ #include #include "oicompare.hh" +#include "translations.hh" namespace oicompare::tests { @@ -53,6 +54,14 @@ struct test_case std::string_view second; }; +struct test_translation_case +{ + oicompare::translations::translation translator; + std::string_view first; + std::string_view second; + std::string_view result; +}; + #define REP10(X) X X X X X X X X X X #define REP100(X) REP10 (REP10 (X)) @@ -102,6 +111,41 @@ constexpr auto test_cases = std::array{ REP100 ("A"sv) "B"sv, REP100 ("A"sv) " B"sv}, }; +constexpr auto test_translation_cases = std::array{ + test_translation_case{ + translations::english_translation::print, + ""sv, ""sv, "OK\n"sv}, + test_translation_case{ + translations::english_translation::print, + "ABC"sv, "ABC"sv, "OK\n"sv}, + test_translation_case{ + translations::english_translation::print, + "ABC\nDEF\n"sv, "ABC\nABC\n"sv, + "WRONG: line 2: expected \"DEF\", got \"ABC\"\n"sv}, + test_translation_case{ + translations::english_translation::print, + "ABC"sv, "AB"sv, "WRONG\n"sv}, + test_translation_case{translations::english_translation< + translations::kind::abbreviated>::print, + "25"sv, "2"sv, + "WRONG: line 1: expected \"25\", got \"2\"\n"sv}, + test_translation_case{ + translations::english_translation< + translations::kind::abbreviated>::print, + "10001"sv REP100 ("0"sv), "10000"sv REP100 ("0"sv), + "WRONG: line 1: expected \"1000100000000000000000000000000000000000000000000000000000000000000000000000000000000…\", got \"1000000000000000000000000000000000000000000000000000000000000000000000000000000000000…\"\n"sv}, + test_translation_case{ + translations::english_translation< + translations::kind::abbreviated>::print, + "1"sv REP100 ("0"sv) "0"sv REP100 ("0"sv), + "1"sv REP100 ("0"sv) "1"sv REP100 ("0"sv), + "WRONG: line 1: expected \"1000000000000000000000000000000000000000000000000000000000000000000000000000000…000…\", got \"1000000000000000000000000000000000000000000000000000000000000000000000000000000…010…\"\n"sv}, + test_translation_case{ + translations::english_translation< + translations::kind::abbreviated>::print, + "1"sv REP100 ("0"sv) "0"sv, "1"sv REP100 ("0"sv) "1"sv, + "WRONG: line 1: expected \"10000000000000000000000000000000000000000000000000000000000000000000000000000000000…00\", got \"10000000000000000000000000000000000000000000000000000000000000000000000000000000000…01\"\n"sv}}; + #undef REP100 #undef REP10 diff --git a/translations.hh b/translations.hh index 012410d..7e32905 100644 --- a/translations.hh +++ b/translations.hh @@ -12,6 +12,7 @@ #include #include "oicompare.hh" +#include "print_format.hh" namespace oicompare::translations { @@ -108,7 +109,7 @@ template <> struct represent_word using namespace std::string_view_literals; assert (!word.empty ()); - assert (first_difference < word.size ()); + assert (first_difference <= word.size ()); std::size_t used_chars = char_length ('"') + char_length (word[first_difference]); @@ -134,8 +135,10 @@ template <> struct represent_word assert (used_chars <= abbreviated_max); - auto append_char_helper - = [&] (char ch) constexpr { out = append_char (std::move (out), ch); }; + auto append_char_helper = [&](char ch) constexpr + { + out = append_char (std::move (out), ch); + }; *out++ = '"'; @@ -188,7 +191,8 @@ template <> struct represent_word append_char_helper (word[first_difference - 1]); } - append_char_helper (word[first_difference]); + if (first_difference < word.size ()) + append_char_helper (word[first_difference]); if (first_difference < word.size () - 1) { @@ -243,7 +247,7 @@ template struct english_translation { using namespace std::string_view_literals; - return print_format ([&] (auto &ctx) { + return print_format ([&token, mismatch] (auto &ctx) { auto out = ctx.out (); switch (token.type) {