jeremy-rifkin / libassert

The most over-engineered C++ assertion library
MIT License
530 stars 35 forks source link

Broken gtest support #87

Closed yfinkelstein closed 6 months ago

yfinkelstein commented 6 months ago

There are 2 issues in version 0.5.0:

  1. The header files tokenizer.hpp and utils.hpp included from assert-gtest.hpp are missing - they are not exported in conan package
  2. Worse - there is compilation error:

ASSERT(1 + 1 == 3, "my assert");

error: void value not ignored as it ought to be
  195 |     ASSERT(1 + 1 == 3, "my assert");
      |     ^

A more detailed info provided by clangd:

Cannot initialize return object of type 'int' with an rvalue of type 'void'. 
clang(init_conversion_failed)

macro ASSERT
provided by <libassert/assert-gtest.hpp>

#define ASSERT(...)                        \
    do {                                   \
        try {                              \
            LIBASSERT_ASSERT(__VA_ARGS__); \
            SUCCEED();                     \
        } catch (std::exception & e) {     \
            FAIL() << e.what();            \
        }                                  \
    } while (false)

// Expands to
do {
    try {
        do {
            auto libassert_decomposer = libassert ::detail ::expression_decomposer(
                libassert ::detail ::expression_decomposer{} << 1 + 1 == 3);
            if (__builtin_expect_with_probability((!static_cast<bool>(libassert_decomposer.get_value())),
                    (0),
                    1)) {
                libassert ::ERROR_ASSERTION_FAILURE_IN_CONSTEXPR_CONTEXT();
                using libassert_params_t = libassert ::detail ::assert_static_parameters;
                const libassert_params_t *libassert_params = []() -> const libassert_params_t * {
                    static constexpr std ::string_view libassert_arg_strings[] = {"\"my assert\"", "", ""};
                    static constexpr libassert_params_t _libassert_params = {
                        "ASSERT",
                        libassert ::assert_type ::assertion,
                        "1 + 1 == 3",
                        {},
                        {libassert_arg_strings, sizeof(libassert_arg_strings) / sizeof(std ::string_view)},
                    };
                    return &_libassert_params;
                }();
                if constexpr (sizeof libassert_decomposer > 32) {
                    libassert ::detail ::process_assert_fail(libassert_decomposer,
                        libassert_params,
                        "my assert",
                        libassert ::detail ::pretty_function_name_wrapper{__extension__ __PRETTY_FUNCTION__});
                } else {
                    libassert ::detail ::process_assert_fail_n(std ::move(libassert_decomposer),
                        libassert_params,
                        "my assert",
                        libassert ::detail ::pretty_function_name_wrapper{__extension__ __PRETTY_FUNCTION__});
                }
            }
        } while (false);
        ::testing ::internal ::AssertHelper(::testing ::TestPartResult ::kSuccess,
            "/home/yfinkelstein/baydb/storage_server/src/tests/test-fiber-uring-grpc.cpp",
            195,
            "Succeeded") = ::testing ::Message();
    } catch (std ::exception& e) {
        return ::testing ::internal ::AssertHelper(::testing ::TestPartResult ::kFatalFailure,
                   "/home/yfinkelstein/baydb/storage_server/src/tests/test-fiber-uring-grpc.cpp",
                   195,
                   "Failed") = ::testing ::Message() << e.what();
    }
} while (false)
yfinkelstein commented 6 months ago

The problem is with return under catch and the bottom of the above. Just remove this return and it compiles

yfinkelstein commented 6 months ago

Looks like the return comes from gtest FAIL(). This compiles and works as expected: EXPECT(1 + 1 == 3, "my assert");

yfinkelstein commented 6 months ago

gtest macro chain: FAIL() -> GTEST_FAIL()->GTEST_FATALFAILURE("Failed") -> return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)

yfinkelstein commented 6 months ago

Ouh, this is because I was having this ASSERT outside of the gtest unit test code! It does work inside of unit test body. So, it's just not intended to be used like that. Just add a disclosure. Not a bug as such.

By missing headers in conan pckage is a real problem

jeremy-rifkin commented 6 months ago

Hello, thanks for opening this issue! The missing includes in the gtest header are a copy-paste mistake on my part, I’ll fix this asap.

jeremy-rifkin commented 6 months ago

Fixed on main, will do a 2.0.1 patch at some point soon