Compare commits

...

5 Commits

Author SHA1 Message Date
Kirtikumar Anandrao Ramchandani
d21bca2e90
Merge a6d3656c49a74af4ea1794ebd0d6d62387be2b8a into a0f06a70e3da7afa88da9527c43951bca1f7cef2 2026-07-29 15:06:03 -04:00
Abseil Team
a0f06a70e3 Make GoogleTest handle std::monostate and valueless_by_exception() for std::variant similarly to how it handles std::nullopt
Fixes: #2066
PiperOrigin-RevId: 955981465
Change-Id: I6b34dc2e634d4b727a50fb3e21e5d8e25c39a13b
2026-07-29 11:08:13 -07:00
Copybara-Service
3ff51c3e80 Merge pull request #5041 from alvinjaison:fix/get-test-suite-shuffle-index
PiperOrigin-RevId: 955317170
Change-Id: I40e01cdafe58768ccdb743dcf38717e48edcde41
2026-07-28 09:58:12 -07:00
Alvin Jaison
1269db9643 Fix GetTestSuite(i) ignoring shuffle order UnitTestImpl::GetTestSuite(int i) computes the shuffled index from test_suite_indices_ but then accesses test_suites_ using the raw parameter 'i' instead of the computed 'index'. This causes the public API UnitTest::GetTestSuite(i) to return test suites in original registration order rather than the active shuffle order. The mutable variant GetMutableSuiteCase(i) correctly uses 'index', and the equivalent function TestSuite::GetTestInfo(i) also uses 'index'. This was a copy-paste typo introduced in commit bd851333 (Sep 2009) when the shuffle feature was first added. The bug is observable from within TestEventListener callbacks during test execution when --gtest_shuffle is active. 2026-07-24 16:11:55 +01:00
KirtiRamchandani
a6d3656c49 Run environments for selected disabled tests 2026-06-01 23:00:01 +05:30
5 changed files with 75 additions and 21 deletions

View File

@ -945,14 +945,14 @@ template <typename T>
class [[nodiscard]] UniversalPrinter<std::optional<T>> {
public:
static void Print(const std::optional<T>& value, ::std::ostream* os) {
*os << '(';
if (!value) {
*os << "nullopt";
UniversalPrint(std::nullopt, os);
} else {
*os << '(';
UniversalPrint(*value, os);
}
*os << ')';
}
}
};
template <>
@ -961,27 +961,38 @@ class [[nodiscard]] UniversalPrinter<std::nullopt_t> {
static void Print(std::nullopt_t, ::std::ostream* os) { *os << "(nullopt)"; }
};
struct UniversalPrinterVisitor {
template <typename T>
void operator()(const T& arg) const {
*os << "'" << GetTypeName<T>() << "(index = " << index << ")' with value ";
UniversalPrint(arg, os);
}
::std::ostream* os;
std::size_t index;
};
// Printer for std::variant
template <typename... T>
class [[nodiscard]] UniversalPrinter<std::variant<T...>> {
public:
static void Print(const std::variant<T...>& value, ::std::ostream* os) {
if (value.valueless_by_exception()) {
*os << "(valueless)";
} else {
*os << '(';
std::visit(Visitor{os, value.index()}, value);
std::visit(UniversalPrinterVisitor{os, value.index()}, value);
*os << ')';
}
private:
struct Visitor {
template <typename U>
void operator()(const U& u) const {
*os << "'" << GetTypeName<U>() << "(index = " << index
<< ")' with value ";
UniversalPrint(u, os);
}
::std::ostream* os;
std::size_t index;
};
// Printer for std::monostate
template <>
class [[nodiscard]] UniversalPrinter<std::monostate> {
public:
static void Print(std::monostate, ::std::ostream* os) {
*os << "(monostate)";
}
};
// UniversalPrintArray(begin, len, os) prints an array of 'len'

View File

@ -587,7 +587,7 @@ class GTEST_API_ UnitTestImpl {
// total_test_suite_count() - 1. If i is not in that range, returns NULL.
const TestSuite* GetTestSuite(int i) const {
const int index = GetElementOr(test_suite_indices_, i, -1);
return index < 0 ? nullptr : test_suites_[static_cast<size_t>(i)];
return index < 0 ? nullptr : test_suites_[static_cast<size_t>(index)];
}
// Legacy API is deprecated but still available

View File

@ -6004,6 +6004,8 @@ bool UnitTestImpl::RunAllTests() {
const bool has_tests_to_run =
FilterTests(should_shard ? HONOR_SHARDING_PROTOCOL
: IGNORE_SHARDING_PROTOCOL) > 0;
const bool has_tests_selected =
has_tests_to_run || reportable_disabled_test_count() > 0;
// Lists the tests and exits if the --gtest_list_tests flag was specified.
if (GTEST_FLAG_GET(list_tests)) {
@ -6058,8 +6060,11 @@ bool UnitTestImpl::RunAllTests() {
// Tells the unit test event listeners that the tests are about to start.
repeater->OnTestIterationStart(*parent_, i);
// Runs each test suite if there is at least one test to run.
if (has_tests_to_run) {
// Sets up and tears down environments if there is at least one test to run,
// or if the selected tests are all disabled. The disabled tests still do
// not run, but global tear-down can clean resources created before
// RUN_ALL_TESTS().
if (has_tests_selected) {
// Sets up all environments beforehand. If test environments aren't
// recreated for each iteration, only do so on the first iteration.
if (i == 0 || recreate_environments_when_repeating) {

View File

@ -2030,6 +2030,26 @@ TEST(PrintOneofTest, Basic) {
PrintToString(Type(NonPrintable{})));
}
TEST(PrintVariantTest, Monostate) {
EXPECT_EQ("(monostate)", PrintToString(std::monostate()));
#if GTEST_HAS_EXCEPTIONS
struct ThrowOnMove {
ThrowOnMove() = default;
ThrowOnMove(ThrowOnMove&& other) { *this = std::move(other); }
ThrowOnMove& operator=(ThrowOnMove&&) {
(void)std::vector<bool>().at(0);
return *this;
}
};
std::variant<std::monostate, ThrowOnMove> v = std::monostate();
EXPECT_EQ("('std::monostate(index = 0)' with value (monostate))",
PrintToString(v));
EXPECT_THROW(v = ThrowOnMove(), std::out_of_range);
EXPECT_EQ("(valueless)", PrintToString(v));
#endif
}
#if GTEST_INTERNAL_HAS_COMPARE_LIB
TEST(PrintOrderingTest, Basic) {
EXPECT_EQ("(less)", PrintToString(std::strong_ordering::less));

View File

@ -86,6 +86,8 @@ class MyEnvironment : public testing::Environment {
// was run.
TEST(FooTest, Bar) { test_was_run = true; }
TEST(FooTest, DISABLED_Baz) { test_was_run = true; }
// Prints the message and aborts the program if condition is false.
void Check(bool condition, const char* msg) {
if (!condition) {
@ -172,6 +174,21 @@ void TestNoTestsSkipsSetUp() {
"as the global set-up was not run.");
}
// Verifies that RUN_ALL_TESTS() still runs environment tear-down when the
// selected tests are disabled.
void TestDisabledTestsRunEnvironmentTearDown() {
MyEnvironment* const env = RegisterTestEnv();
GTEST_FLAG_SET(filter, "FooTest.DISABLED_Baz");
Check(RunAllTests(env, NO_FAILURE) != 0,
"RUN_ALL_TESTS() should return non-zero, as the global tear-down "
"should generate a failure.");
Check(!test_was_run, "The disabled test body should not run.");
Check(set_up_was_run,
"The global set-up should run, as a disabled test was selected.");
Check(tear_down_was_run,
"The global tear-down should run, as the global set-up was run.");
}
} // namespace
int main(int argc, char** argv) {
@ -181,6 +198,7 @@ int main(int argc, char** argv) {
TestTestsRun();
TestNoTestsRunSetUpFailure();
TestNoTestsSkipsSetUp();
TestDisabledTestsRunEnvironmentTearDown();
printf("PASS\n");
return 0;