Skip to content

Instantly share code, notes, and snippets.

@DigitalInBlue
Last active August 13, 2020 14:31
Show Gist options
  • Save DigitalInBlue/e9f143a8d1f6a6670995ff9fcaef9721 to your computer and use it in GitHub Desktop.
Save DigitalInBlue/e9f143a8d1f6a6670995ff9fcaef9721 to your computer and use it in GitHub Desktop.
An extension for GoogleTest (GTest). `EXPECT_NO_DEATH` is the opposite of EXPECT_DEATH. It passes if the statement does not abort, assert, or otherwise die.
// This is free and unencumbered software released into the public domain.
//
// Anyone is free to copy, modify, publish, use, compile, sell, or
// distribute this software, either in source code form or as a compiled
// binary, for any purpose, commercial or non-commercial, and by any
// means.
//
// In jurisdictions that recognize copyright laws, the author or authors
// of this software dedicate any and all copyright interest in the
// software to the public domain. We make this dedication for the benefit
// of the public at large and to the detriment of our heirs and
// successors. We intend this dedication to be an overt act of
// relinquishment in perpetuity of all present and future rights to this
// software under copyright law.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// For more information, please refer to <https://unlicense.org>
//
#include <gtest/gtest.h>
# define EXPECT_NO_DEATH(statement, regex) \
EXPECT_NO_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
# define EXPECT_NO_EXIT(statement, predicate, regex) \
GTEST_NO_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
# define GTEST_NO_DEATH_TEST_(statement, predicate, regex, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
const ::testing::internal::RE& gtest_regex = (regex); \
::testing::internal::DeathTest* gtest_dt; \
if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \
__FILE__, __LINE__, &gtest_dt)) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
if (gtest_dt != NULL) { \
::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
gtest_dt_ptr(gtest_dt); \
switch (gtest_dt->AssumeRole()) { \
case ::testing::internal::DeathTest::OVERSEE_TEST: \
if (gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
break; \
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
::testing::internal::DeathTest::ReturnSentinel \
gtest_sentinel(gtest_dt); \
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
gtest_dt->Abort(::testing::internal::DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT); \
break; \
} \
default: \
break; \
} \
} \
} else \
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
fail(::testing::internal::DeathTest::LastMessage())
# define ASSERT_NO_EXIT(statement, predicate, regex) \
GTEST_NO_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
#define ASSERT_NO_DEATH(statement, regex) \
ASSERT_NO_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
@bogiokas
Copy link

bogiokas commented Apr 2, 2020

Comparing this code to the definition of GTEST_DEATH_TEST_ in gtest, the corresponding code to line 31 is:
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE);
Is this change intentional?

@DigitalInBlue
Copy link
Author

It's been a while since I wrote this. Frankly, I don't remember if this was an intentional change or if perhaps the GoogleTest project has changed. Were there any issues with this macro's functionality?

@Neofish22
Copy link

Hi. Just dropped this into a work project and works perfectly. Is it ok with you for me to use it in a commercial environment? If so, could you add a licence please? If not, thanks anyway because I can learn from it!

@DigitalInBlue
Copy link
Author

I'll give it a fully public license with no restrictions. (I know I don't need to manage more licenses in my commercial projects!) I may also do a pull request into GTest itself to see if they want to adopt it.

@Neofish22
Copy link

Neofish22 commented Aug 13, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment