@@ -7,11 +7,18 @@
#include "etest/cxx_compat.h"
#include <concepts>
#include <functional>
#include <ostream>
#include <string_view>
namespace etest {
template<typename T>
concept Printable = requires(std::ostream &os, T t) {
{ os << t } -> std::same_as<std::ostream &>;
};
int run_all_tests() noexcept;
int test(std::string_view name, std::function<void()> body) noexcept;
@@ -21,6 +28,41 @@ void expect(bool, etest::source_location const &loc = etest::source_location::cu
// Hard test requirement. Stops the test (using an exception) if the check fails.
void require(bool, etest::source_location const &loc = etest::source_location::current());
// Access the internal test log.
std::ostream &log();
// Weak test requirement. Prints the types compared on failure (if printable).
template<Printable T, Printable U>
void expect_eq(T const &a, U const &b, etest::source_location const &loc = etest::source_location::current()) noexcept {
if (a != b) {
expect(false, loc);
log() << a << " !=\n" << b << "\n\n";
}
}
template<typename T, typename U>
void expect_eq(T const &a, U const &b, etest::source_location const &loc = etest::source_location::current()) noexcept {
expect(a == b, loc);
}
// Hard test requirement. Prints the types compared on failure (if printable).
template<Printable T, Printable U>
void require_eq(T const &a, U const &b, etest::source_location const &loc = etest::source_location::current()) {
if (a != b) {
try {
require(false, loc);
} catch (...) {
log() << a << " !=\n" << b << "\n\n";
throw;
}
}
}
template<typename T, typename U>
void require_eq(T const &a, U const &b, etest::source_location const &loc = etest::source_location::current()) {
require(a == b, loc);
}
} // namespace etest
#endif