Skip to content

Commit

Permalink
test: Prove+document ConstevalFormatString/tinyformat parity
Browse files Browse the repository at this point in the history
Co-Authored-By: Lőrinc <[email protected]>
Co-Authored-By: MarcoFalke <*~=`'#}+{/-|&$^[email protected]>
Co-Authored-By: Ryan Ofsky <[email protected]>
  • Loading branch information
4 people committed Dec 6, 2024
1 parent b81a465 commit 533013c
Showing 1 changed file with 23 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/test/util_string_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,27 @@ using util::detail::CheckNumFormatSpecifiers;

BOOST_AUTO_TEST_SUITE(util_string_tests)

template <unsigned NumArgs>
void TfmFormatZeroes(const std::string& fmt)
{
std::apply([&](auto... args) {
(void)tfm::format(fmt, args...);
}, std::array<int, NumArgs>{});
}

// Helper to allow compile-time sanity checks while providing the number of
// args directly. Normally PassFmt<sizeof...(Args)> would be used.
template <unsigned NumArgs>
void PassFmt(ConstevalFormatString<NumArgs> fmt)
{
// Execute compile-time check again at run-time to get code coverage stats
BOOST_CHECK_NO_THROW(CheckNumFormatSpecifiers<NumArgs>(fmt.fmt));

// If ConstevalFormatString didn't throw above, make sure tinyformat doesn't
// throw either for the same format string and parameter count combination.
// Proves that we have some extent of protection from runtime errors
// (tinyformat may still throw for some type mismatches).
BOOST_CHECK_NO_THROW(TfmFormatZeroes<NumArgs>(fmt.fmt));
}
template <unsigned WrongNumArgs>
void FailFmtWithError(const char* wrong_fmt, std::string_view error)
Expand Down Expand Up @@ -111,6 +125,15 @@ BOOST_AUTO_TEST_CASE(ConstevalFormatString_NumSpec)
FailFmtWithError<2>("%1$*2$", err_term);
FailFmtWithError<2>("%1$.*2$", err_term);
FailFmtWithError<2>("%1$9.*2$", err_term);

// Ensure that tinyformat throws if format string contains wrong number
// of specifiers. PassFmt relies on this to verify tinyformat successfully
// formats the strings, and will need to be updated if tinyformat is changed
// not to throw on failure.
BOOST_CHECK_EXCEPTION(TfmFormatZeroes<2>("%s"), tfm::format_error,
HasReason{"tinyformat: Not enough conversion specifiers in format string"});
BOOST_CHECK_EXCEPTION(TfmFormatZeroes<1>("%s %s"), tfm::format_error,
HasReason{"tinyformat: Too many conversion specifiers in format string"});
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 533013c

Please sign in to comment.