Compare commits

...

5 Commits

Author SHA1 Message Date
Kirtikumar Anandrao Ramchandani
1697e1e952
Merge 3df62357ab54be772d421c2dd0767c56b5b5247c 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
3df62357ab Strip help flag during flag parsing 2026-06-01 15:31:36 +05:30
5 changed files with 65 additions and 22 deletions

View File

@ -945,13 +945,13 @@ template <typename T>
class [[nodiscard]] UniversalPrinter<std::optional<T>> { class [[nodiscard]] UniversalPrinter<std::optional<T>> {
public: public:
static void Print(const std::optional<T>& value, ::std::ostream* os) { static void Print(const std::optional<T>& value, ::std::ostream* os) {
*os << '(';
if (!value) { if (!value) {
*os << "nullopt"; UniversalPrint(std::nullopt, os);
} else { } else {
*os << '(';
UniversalPrint(*value, os); UniversalPrint(*value, os);
*os << ')';
} }
*os << ')';
} }
}; };
@ -961,27 +961,38 @@ class [[nodiscard]] UniversalPrinter<std::nullopt_t> {
static void Print(std::nullopt_t, ::std::ostream* os) { *os << "(nullopt)"; } 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 // Printer for std::variant
template <typename... T> template <typename... T>
class [[nodiscard]] UniversalPrinter<std::variant<T...>> { class [[nodiscard]] UniversalPrinter<std::variant<T...>> {
public: public:
static void Print(const std::variant<T...>& value, ::std::ostream* os) { static void Print(const std::variant<T...>& value, ::std::ostream* os) {
*os << '('; if (value.valueless_by_exception()) {
std::visit(Visitor{os, value.index()}, value); *os << "(valueless)";
*os << ')'; } else {
} *os << '(';
std::visit(UniversalPrinterVisitor{os, value.index()}, value);
private: *os << ')';
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' // 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. // total_test_suite_count() - 1. If i is not in that range, returns NULL.
const TestSuite* GetTestSuite(int i) const { const TestSuite* GetTestSuite(int i) const {
const int index = GetElementOr(test_suite_indices_, i, -1); 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 // Legacy API is deprecated but still available

View File

@ -6885,9 +6885,12 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
LoadFlagsFromFile(flagfile_value); LoadFlagsFromFile(flagfile_value);
remove_flag = true; remove_flag = true;
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM #endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM
} else if (arg_string == "--help" || HasGoogleTestFlagPrefix(arg)) { } else if (arg_string == "--help") {
// Both help flag and unrecognized Google Test flags (excluding g_help_flag = true;
// internal ones) trigger help display. remove_flag = true;
} else if (HasGoogleTestFlagPrefix(arg)) {
// Unrecognized Google Test flags (excluding internal ones) trigger help
// display, but remain available for other flag parsers.
g_help_flag = true; g_help_flag = true;
} }

View File

@ -2030,6 +2030,26 @@ TEST(PrintOneofTest, Basic) {
PrintToString(Type(NonPrintable{}))); 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 #if GTEST_INTERNAL_HAS_COMPARE_LIB
TEST(PrintOrderingTest, Basic) { TEST(PrintOrderingTest, Basic) {
EXPECT_EQ("(less)", PrintToString(std::strong_ordering::less)); EXPECT_EQ("(less)", PrintToString(std::strong_ordering::less));

View File

@ -5993,6 +5993,15 @@ TEST_F(ParseFlagsTest, UnrecognizedFlag) {
GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags, false); GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags, false);
} }
// Tests having a --help flag on the command line.
TEST_F(ParseFlagsTest, HelpFlag) {
const char* argv[] = {"foo.exe", "--help", "bar", nullptr};
const char* argv2[] = {"foo.exe", "bar", nullptr};
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), true);
}
// Tests having a --gtest_list_tests flag // Tests having a --gtest_list_tests flag
TEST_F(ParseFlagsTest, ListTestsFlag) { TEST_F(ParseFlagsTest, ListTestsFlag) {
const char* argv[] = {"foo.exe", "--gtest_list_tests", nullptr}; const char* argv[] = {"foo.exe", "--gtest_list_tests", nullptr};