Как протестировать макрос, который убивает процесс?
У меня есть вот такой макрос (упрощенный)
struct check_error{
check_error() = default;
void check(const char* file, const int line, const char* condition) {
std::cerr << file << "(" << line << ") - " << "Check error: " << #expr;
__debugbreak(); // Вызывает падение процесса в MSVC.
// __builtin_trap(); // Вызывает падение процесса в clang и gnu.
}
};
#define MI_CHECK(condition) \
if (!condition) check_error().check(__FILE__, __LINE__, #condition)
Далее с помощью gtest я пытаюсь протестировать этот макрос.
Но дело в том, что я не могу протестировать этот макрос обычным способом
int foo() { return 1; }
int boo() { return 0; }
TEST(Check, Test1){
EXPECT_DEATH(MI_CHECK(foo() < boo()), "Check error: foo() < boo()"); // gtest выдает ошибку
EXPECT_DEATH(MI_CHECK(1 < 0), "Check error: 1 < 0"); // OK
}
Потому что EXPECT_DEATH почему-то не поддерживает строки, в которых есть символы ( и ).
Ошибка, если кому-то интересно:
error: Failed
Syntax error at index 20 in simple regular expression "Check failed: a < b (2 vs. 1)": '(' is unsupported.
C:\Work\MI\build\_deps\googletest-src\googletest\src/gtest-port.cc(837): error: Failed
Syntax error at index 28 in simple regular expression "Check failed: a < b (2 vs. 1)": ')' is unsupported.
Running main() from C:\Work\MI\build\_deps\googletest-src\googletest\src\gtest_main.cc
C:\Work\MI\src\Common\MI.Check_unittest.cpp(85): error: Death test: switch (0) case 0: default: if (::mi::internal::check_op_result true_if_passed = ::mi::internal::CheckLTImpl((a), (b), "a" " " "<" " " "b")) ; else ::mi::internal::check_error("C:\\Work\\MI\\src\\Common\\MI.Check_unittest.cpp", 85).check_op(&true_if_passed).stream()
Result: died but not with expected error.
Expected: contains regular expression "Check failed: a < b (2 vs. 1)"
Actual msg:
[ DEATH ] [FATAL] at [31.5.2022 - 12:25:34] in ["MI.Check_unittest.cpp"(85)] - Check failed: a < b (2 vs. 1).
Tут есть похожий макрос CHECK, для тестирования которого разработчики заменяют EXPECT_DEATH на EXPECT_CHECK.
Вот его реализация:
#define EXPECT_CHECK(msg, check_expr) \
do { \
ScopedCheckExpectation check_exp(__FILE__, __LINE__, msg); \
check_expr; \
} while (0)
У них используется супер-пупер-гиго-нано-мега умный и волшебный класс ScopedCheckExpectation, осознать реализацию которого я не в силе :(.
Как я понял, он каким-то образом отслеживает падение процесса и при таком случае проверяет сообщение в std::cerr.
Может кто-нибудь привести пример такого класса, но с более простой реализацией?
Или, может, есть другой, более простой способ протестировать этот макрос?