mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
test: Prove+document ConstevalFormatString/tinyformat parity
Co-Authored-By: Lőrinc <pap.lorinc@gmail.com> Co-Authored-By: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Co-Authored-By: Ryan Ofsky <ryan@ofsky.org>
This commit is contained in:
parent
b81a465995
commit
533013cba2
1 changed files with 23 additions and 0 deletions
|
@ -12,6 +12,14 @@ using util::detail::CheckNumFormatSpecifiers;
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(util_string_tests)
|
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
|
// Helper to allow compile-time sanity checks while providing the number of
|
||||||
// args directly. Normally PassFmt<sizeof...(Args)> would be used.
|
// args directly. Normally PassFmt<sizeof...(Args)> would be used.
|
||||||
template <unsigned NumArgs>
|
template <unsigned NumArgs>
|
||||||
|
@ -19,6 +27,12 @@ void PassFmt(ConstevalFormatString<NumArgs> fmt)
|
||||||
{
|
{
|
||||||
// Execute compile-time check again at run-time to get code coverage stats
|
// Execute compile-time check again at run-time to get code coverage stats
|
||||||
BOOST_CHECK_NO_THROW(CheckNumFormatSpecifiers<NumArgs>(fmt.fmt));
|
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>
|
template <unsigned WrongNumArgs>
|
||||||
void FailFmtWithError(const char* wrong_fmt, std::string_view error)
|
void FailFmtWithError(const char* wrong_fmt, std::string_view error)
|
||||||
|
@ -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$.*2$", err_term);
|
FailFmtWithError<2>("%1$.*2$", err_term);
|
||||||
FailFmtWithError<2>("%1$9.*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()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
Loading…
Add table
Reference in a new issue