diff options
-rw-r--r-- | absl/flags/internal/parse.h | 14 | ||||
-rw-r--r-- | absl/flags/parse.cc | 8 | ||||
-rw-r--r-- | absl/flags/parse_test.cc | 17 |
3 files changed, 31 insertions, 8 deletions
diff --git a/absl/flags/internal/parse.h b/absl/flags/internal/parse.h index e4352049..10c531b8 100644 --- a/absl/flags/internal/parse.h +++ b/absl/flags/internal/parse.h @@ -16,6 +16,8 @@ #ifndef ABSL_FLAGS_INTERNAL_PARSE_H_ #define ABSL_FLAGS_INTERNAL_PARSE_H_ +#include <iostream> +#include <ostream> #include <string> #include <vector> @@ -40,9 +42,15 @@ enum class OnUndefinedFlag { kAbortIfUndefined }; -std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], - UsageFlagsAction usage_flag_action, - OnUndefinedFlag undef_flag_action); +// This is not a public interface. This interface exists to expose the ability +// to change help output stream in case of parsing errors. This is used by +// internal unit tests to validate expected outputs. +// When this was written, `EXPECT_EXIT` only supported matchers on stderr, +// but not on stdout. +std::vector<char*> ParseCommandLineImpl( + int argc, char* argv[], UsageFlagsAction usage_flag_action, + OnUndefinedFlag undef_flag_action, + std::ostream& error_help_output = std::cout); // -------------------------------------------------------------------- // Inspect original command line diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc index d3609c13..172fe901 100644 --- a/absl/flags/parse.cc +++ b/absl/flags/parse.cc @@ -22,6 +22,7 @@ #include <cstdlib> #include <fstream> #include <iostream> +#include <ostream> #include <string> #include <tuple> #include <utility> @@ -693,7 +694,8 @@ std::vector<std::string> GetMisspellingHints(const absl::string_view flag) { std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], UsageFlagsAction usage_flag_action, - OnUndefinedFlag undef_flag_action) { + OnUndefinedFlag undef_flag_action, + std::ostream& error_help_output) { std::vector<char*> positional_args; std::vector<UnrecognizedFlag> unrecognized_flags; @@ -707,8 +709,8 @@ std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], if (undef_flag_action == OnUndefinedFlag::kAbortIfUndefined) { if (!unrecognized_flags.empty()) { - flags_internal::HandleUsageFlags(std::cerr, ProgramUsageMessage()); - std::exit(1); + flags_internal::HandleUsageFlags(error_help_output, + ProgramUsageMessage()); std::exit(1); } } } diff --git a/absl/flags/parse_test.cc b/absl/flags/parse_test.cc index f3987bb7..cd32efc8 100644 --- a/absl/flags/parse_test.cc +++ b/absl/flags/parse_test.cc @@ -18,6 +18,7 @@ #include <stdlib.h> #include <fstream> +#include <iostream> #include <string> #include <vector> @@ -235,7 +236,9 @@ ABSL_RETIRED_FLAG(std::string, legacy_str, "l", ""); namespace { namespace flags = absl::flags_internal; +using testing::AllOf; using testing::ElementsAreArray; +using testing::HasSubstr; class ParseTest : public testing::Test { public: @@ -271,6 +274,15 @@ void InvokeParseAbslOnly(const char* (&in_argv)[N]) { // -------------------------------------------------------------------- template <int N> +std::vector<char*> InvokeParseCommandLineImpl(const char* (&in_argv)[N]) { + return flags::ParseCommandLineImpl( + N, const_cast<char**>(in_argv), flags::UsageFlagsAction::kHandleUsage, + flags::OnUndefinedFlag::kAbortIfUndefined, std::cerr); +} + +// -------------------------------------------------------------------- + +template <int N> std::vector<char*> InvokeParse(const char* (&in_argv)[N]) { return absl::ParseCommandLine(N, const_cast<char**>(in_argv)); } @@ -1066,8 +1078,9 @@ TEST_F(ParseDeathTest, ExitOnUnrecognizedFlagPrintsHelp) { "--help=int_flag", }; - EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args), - "Try --helpfull to get a list of all flags"); + EXPECT_EXIT(InvokeParseCommandLineImpl(in_args), testing::ExitedWithCode(1), + AllOf(HasSubstr("Unknown command line flag 'undef_flag1'"), + HasSubstr("Try --helpfull to get a list of all flags"))); } // -------------------------------------------------------------------- |