xref: /aosp_15_r20/external/abseil-cpp/absl/flags/parse_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker //
2*9356374aSAndroid Build Coastguard Worker // Copyright 2019 The Abseil Authors.
3*9356374aSAndroid Build Coastguard Worker //
4*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*9356374aSAndroid Build Coastguard Worker //
8*9356374aSAndroid Build Coastguard Worker //      https://www.apache.org/licenses/LICENSE-2.0
9*9356374aSAndroid Build Coastguard Worker //
10*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*9356374aSAndroid Build Coastguard Worker // limitations under the License.
15*9356374aSAndroid Build Coastguard Worker 
16*9356374aSAndroid Build Coastguard Worker #include "absl/flags/parse.h"
17*9356374aSAndroid Build Coastguard Worker 
18*9356374aSAndroid Build Coastguard Worker #include <stdlib.h>
19*9356374aSAndroid Build Coastguard Worker 
20*9356374aSAndroid Build Coastguard Worker #include <fstream>
21*9356374aSAndroid Build Coastguard Worker #include <iostream>
22*9356374aSAndroid Build Coastguard Worker #include <string>
23*9356374aSAndroid Build Coastguard Worker #include <vector>
24*9356374aSAndroid Build Coastguard Worker 
25*9356374aSAndroid Build Coastguard Worker #include "gmock/gmock.h"
26*9356374aSAndroid Build Coastguard Worker #include "gtest/gtest.h"
27*9356374aSAndroid Build Coastguard Worker #include "absl/base/internal/scoped_set_env.h"
28*9356374aSAndroid Build Coastguard Worker #include "absl/flags/config.h"
29*9356374aSAndroid Build Coastguard Worker #include "absl/flags/flag.h"
30*9356374aSAndroid Build Coastguard Worker #include "absl/flags/internal/parse.h"
31*9356374aSAndroid Build Coastguard Worker #include "absl/flags/internal/usage.h"
32*9356374aSAndroid Build Coastguard Worker #include "absl/flags/reflection.h"
33*9356374aSAndroid Build Coastguard Worker #include "absl/log/log.h"
34*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_cat.h"
35*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
36*9356374aSAndroid Build Coastguard Worker #include "absl/strings/substitute.h"
37*9356374aSAndroid Build Coastguard Worker #include "absl/types/span.h"
38*9356374aSAndroid Build Coastguard Worker 
39*9356374aSAndroid Build Coastguard Worker #ifdef _WIN32
40*9356374aSAndroid Build Coastguard Worker #include <windows.h>
41*9356374aSAndroid Build Coastguard Worker #endif
42*9356374aSAndroid Build Coastguard Worker 
43*9356374aSAndroid Build Coastguard Worker // Define 125 similar flags to test kMaxHints for flag suggestions.
44*9356374aSAndroid Build Coastguard Worker #define FLAG_MULT(x) F3(x)
45*9356374aSAndroid Build Coastguard Worker #define TEST_FLAG_HEADER FLAG_HEADER_
46*9356374aSAndroid Build Coastguard Worker 
47*9356374aSAndroid Build Coastguard Worker #define F(name) ABSL_FLAG(int, name, 0, "")
48*9356374aSAndroid Build Coastguard Worker 
49*9356374aSAndroid Build Coastguard Worker #define F1(name) \
50*9356374aSAndroid Build Coastguard Worker   F(name##1);    \
51*9356374aSAndroid Build Coastguard Worker   F(name##2);    \
52*9356374aSAndroid Build Coastguard Worker   F(name##3);    \
53*9356374aSAndroid Build Coastguard Worker   F(name##4);    \
54*9356374aSAndroid Build Coastguard Worker   F(name##5)
55*9356374aSAndroid Build Coastguard Worker /**/
56*9356374aSAndroid Build Coastguard Worker #define F2(name) \
57*9356374aSAndroid Build Coastguard Worker   F1(name##1);   \
58*9356374aSAndroid Build Coastguard Worker   F1(name##2);   \
59*9356374aSAndroid Build Coastguard Worker   F1(name##3);   \
60*9356374aSAndroid Build Coastguard Worker   F1(name##4);   \
61*9356374aSAndroid Build Coastguard Worker   F1(name##5)
62*9356374aSAndroid Build Coastguard Worker /**/
63*9356374aSAndroid Build Coastguard Worker #define F3(name) \
64*9356374aSAndroid Build Coastguard Worker   F2(name##1);   \
65*9356374aSAndroid Build Coastguard Worker   F2(name##2);   \
66*9356374aSAndroid Build Coastguard Worker   F2(name##3);   \
67*9356374aSAndroid Build Coastguard Worker   F2(name##4);   \
68*9356374aSAndroid Build Coastguard Worker   F2(name##5)
69*9356374aSAndroid Build Coastguard Worker /**/
70*9356374aSAndroid Build Coastguard Worker 
71*9356374aSAndroid Build Coastguard Worker FLAG_MULT(TEST_FLAG_HEADER);
72*9356374aSAndroid Build Coastguard Worker 
73*9356374aSAndroid Build Coastguard Worker namespace {
74*9356374aSAndroid Build Coastguard Worker 
75*9356374aSAndroid Build Coastguard Worker using absl::base_internal::ScopedSetEnv;
76*9356374aSAndroid Build Coastguard Worker 
77*9356374aSAndroid Build Coastguard Worker struct UDT {
78*9356374aSAndroid Build Coastguard Worker   UDT() = default;
79*9356374aSAndroid Build Coastguard Worker   UDT(const UDT&) = default;
80*9356374aSAndroid Build Coastguard Worker   UDT& operator=(const UDT&) = default;
UDT__anoncae3bc710111::UDT81*9356374aSAndroid Build Coastguard Worker   UDT(int v) : value(v) {}  // NOLINT
82*9356374aSAndroid Build Coastguard Worker 
83*9356374aSAndroid Build Coastguard Worker   int value;
84*9356374aSAndroid Build Coastguard Worker };
85*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view in,UDT * udt,std::string * err)86*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view in, UDT* udt, std::string* err) {
87*9356374aSAndroid Build Coastguard Worker   if (in == "A") {
88*9356374aSAndroid Build Coastguard Worker     udt->value = 1;
89*9356374aSAndroid Build Coastguard Worker     return true;
90*9356374aSAndroid Build Coastguard Worker   }
91*9356374aSAndroid Build Coastguard Worker   if (in == "AAA") {
92*9356374aSAndroid Build Coastguard Worker     udt->value = 10;
93*9356374aSAndroid Build Coastguard Worker     return true;
94*9356374aSAndroid Build Coastguard Worker   }
95*9356374aSAndroid Build Coastguard Worker 
96*9356374aSAndroid Build Coastguard Worker   *err = "Use values A, AAA instead";
97*9356374aSAndroid Build Coastguard Worker   return false;
98*9356374aSAndroid Build Coastguard Worker }
AbslUnparseFlag(const UDT & udt)99*9356374aSAndroid Build Coastguard Worker std::string AbslUnparseFlag(const UDT& udt) {
100*9356374aSAndroid Build Coastguard Worker   return udt.value == 1 ? "A" : "AAA";
101*9356374aSAndroid Build Coastguard Worker }
102*9356374aSAndroid Build Coastguard Worker 
GetTestTmpDirEnvVar(const char * const env_var_name)103*9356374aSAndroid Build Coastguard Worker std::string GetTestTmpDirEnvVar(const char* const env_var_name) {
104*9356374aSAndroid Build Coastguard Worker #ifdef _WIN32
105*9356374aSAndroid Build Coastguard Worker   char buf[MAX_PATH];
106*9356374aSAndroid Build Coastguard Worker   auto get_res = GetEnvironmentVariableA(env_var_name, buf, sizeof(buf));
107*9356374aSAndroid Build Coastguard Worker   if (get_res >= sizeof(buf) || get_res == 0) {
108*9356374aSAndroid Build Coastguard Worker     return "";
109*9356374aSAndroid Build Coastguard Worker   }
110*9356374aSAndroid Build Coastguard Worker 
111*9356374aSAndroid Build Coastguard Worker   return std::string(buf, get_res);
112*9356374aSAndroid Build Coastguard Worker #else
113*9356374aSAndroid Build Coastguard Worker   const char* val = ::getenv(env_var_name);
114*9356374aSAndroid Build Coastguard Worker   if (val == nullptr) {
115*9356374aSAndroid Build Coastguard Worker     return "";
116*9356374aSAndroid Build Coastguard Worker   }
117*9356374aSAndroid Build Coastguard Worker 
118*9356374aSAndroid Build Coastguard Worker   return val;
119*9356374aSAndroid Build Coastguard Worker #endif
120*9356374aSAndroid Build Coastguard Worker }
121*9356374aSAndroid Build Coastguard Worker 
GetTestTempDir()122*9356374aSAndroid Build Coastguard Worker const std::string& GetTestTempDir() {
123*9356374aSAndroid Build Coastguard Worker   static std::string* temp_dir_name = []() -> std::string* {
124*9356374aSAndroid Build Coastguard Worker     std::string* res = new std::string(GetTestTmpDirEnvVar("TEST_TMPDIR"));
125*9356374aSAndroid Build Coastguard Worker 
126*9356374aSAndroid Build Coastguard Worker     if (res->empty()) {
127*9356374aSAndroid Build Coastguard Worker       *res = GetTestTmpDirEnvVar("TMPDIR");
128*9356374aSAndroid Build Coastguard Worker     }
129*9356374aSAndroid Build Coastguard Worker 
130*9356374aSAndroid Build Coastguard Worker     if (res->empty()) {
131*9356374aSAndroid Build Coastguard Worker #ifdef _WIN32
132*9356374aSAndroid Build Coastguard Worker       char temp_path_buffer[MAX_PATH];
133*9356374aSAndroid Build Coastguard Worker 
134*9356374aSAndroid Build Coastguard Worker       auto len = GetTempPathA(MAX_PATH, temp_path_buffer);
135*9356374aSAndroid Build Coastguard Worker       if (len < MAX_PATH && len != 0) {
136*9356374aSAndroid Build Coastguard Worker         std::string temp_dir_name = temp_path_buffer;
137*9356374aSAndroid Build Coastguard Worker         if (!absl::EndsWith(temp_dir_name, "\\")) {
138*9356374aSAndroid Build Coastguard Worker           temp_dir_name.push_back('\\');
139*9356374aSAndroid Build Coastguard Worker         }
140*9356374aSAndroid Build Coastguard Worker         absl::StrAppend(&temp_dir_name, "parse_test.", GetCurrentProcessId());
141*9356374aSAndroid Build Coastguard Worker         if (CreateDirectoryA(temp_dir_name.c_str(), nullptr)) {
142*9356374aSAndroid Build Coastguard Worker           *res = temp_dir_name;
143*9356374aSAndroid Build Coastguard Worker         }
144*9356374aSAndroid Build Coastguard Worker       }
145*9356374aSAndroid Build Coastguard Worker #else
146*9356374aSAndroid Build Coastguard Worker       char temp_dir_template[] = "/tmp/parse_test.XXXXXX";
147*9356374aSAndroid Build Coastguard Worker       if (auto* unique_name = ::mkdtemp(temp_dir_template)) {
148*9356374aSAndroid Build Coastguard Worker         *res = unique_name;
149*9356374aSAndroid Build Coastguard Worker       }
150*9356374aSAndroid Build Coastguard Worker #endif
151*9356374aSAndroid Build Coastguard Worker     }
152*9356374aSAndroid Build Coastguard Worker 
153*9356374aSAndroid Build Coastguard Worker     if (res->empty()) {
154*9356374aSAndroid Build Coastguard Worker       LOG(FATAL) << "Failed to make temporary directory for data files";
155*9356374aSAndroid Build Coastguard Worker     }
156*9356374aSAndroid Build Coastguard Worker 
157*9356374aSAndroid Build Coastguard Worker #ifdef _WIN32
158*9356374aSAndroid Build Coastguard Worker     *res += "\\";
159*9356374aSAndroid Build Coastguard Worker #else
160*9356374aSAndroid Build Coastguard Worker     *res += "/";
161*9356374aSAndroid Build Coastguard Worker #endif
162*9356374aSAndroid Build Coastguard Worker 
163*9356374aSAndroid Build Coastguard Worker     return res;
164*9356374aSAndroid Build Coastguard Worker   }();
165*9356374aSAndroid Build Coastguard Worker 
166*9356374aSAndroid Build Coastguard Worker   return *temp_dir_name;
167*9356374aSAndroid Build Coastguard Worker }
168*9356374aSAndroid Build Coastguard Worker 
169*9356374aSAndroid Build Coastguard Worker struct FlagfileData {
170*9356374aSAndroid Build Coastguard Worker   const absl::string_view file_name;
171*9356374aSAndroid Build Coastguard Worker   const absl::Span<const char* const> file_lines;
172*9356374aSAndroid Build Coastguard Worker };
173*9356374aSAndroid Build Coastguard Worker 
174*9356374aSAndroid Build Coastguard Worker // clang-format off
175*9356374aSAndroid Build Coastguard Worker constexpr const char* const ff1_data[] = {
176*9356374aSAndroid Build Coastguard Worker     "# comment    ",
177*9356374aSAndroid Build Coastguard Worker     "  # comment  ",
178*9356374aSAndroid Build Coastguard Worker     "",
179*9356374aSAndroid Build Coastguard Worker     "     ",
180*9356374aSAndroid Build Coastguard Worker     "--int_flag=-1",
181*9356374aSAndroid Build Coastguard Worker     "  --string_flag=q2w2  ",
182*9356374aSAndroid Build Coastguard Worker     "  ##   ",
183*9356374aSAndroid Build Coastguard Worker     "  --double_flag=0.1",
184*9356374aSAndroid Build Coastguard Worker     "--bool_flag=Y  "
185*9356374aSAndroid Build Coastguard Worker };
186*9356374aSAndroid Build Coastguard Worker 
187*9356374aSAndroid Build Coastguard Worker constexpr const char* const ff2_data[] = {
188*9356374aSAndroid Build Coastguard Worker     "# Setting legacy flag",
189*9356374aSAndroid Build Coastguard Worker     "--legacy_int=1111",
190*9356374aSAndroid Build Coastguard Worker     "--legacy_bool",
191*9356374aSAndroid Build Coastguard Worker     "--nobool_flag",
192*9356374aSAndroid Build Coastguard Worker     "--legacy_str=aqsw",
193*9356374aSAndroid Build Coastguard Worker     "--int_flag=100",
194*9356374aSAndroid Build Coastguard Worker     "   ## ============="
195*9356374aSAndroid Build Coastguard Worker };
196*9356374aSAndroid Build Coastguard Worker // clang-format on
197*9356374aSAndroid Build Coastguard Worker 
198*9356374aSAndroid Build Coastguard Worker // Builds flagfile flag in the flagfile_flag buffer and returns it. This
199*9356374aSAndroid Build Coastguard Worker // function also creates a temporary flagfile based on FlagfileData input.
200*9356374aSAndroid Build Coastguard Worker // We create a flagfile in a temporary directory with the name specified in
201*9356374aSAndroid Build Coastguard Worker // FlagfileData and populate it with lines specified in FlagfileData. If $0 is
202*9356374aSAndroid Build Coastguard Worker // referenced in any of the lines in FlagfileData they are replaced with
203*9356374aSAndroid Build Coastguard Worker // temporary directory location. This way we can test inclusion of one flagfile
204*9356374aSAndroid Build Coastguard Worker // from another flagfile.
GetFlagfileFlag(const std::vector<FlagfileData> & ffd,std::string & flagfile_flag)205*9356374aSAndroid Build Coastguard Worker const char* GetFlagfileFlag(const std::vector<FlagfileData>& ffd,
206*9356374aSAndroid Build Coastguard Worker                             std::string& flagfile_flag) {
207*9356374aSAndroid Build Coastguard Worker   flagfile_flag = "--flagfile=";
208*9356374aSAndroid Build Coastguard Worker   absl::string_view separator;
209*9356374aSAndroid Build Coastguard Worker   for (const auto& flagfile_data : ffd) {
210*9356374aSAndroid Build Coastguard Worker     std::string flagfile_name =
211*9356374aSAndroid Build Coastguard Worker         absl::StrCat(GetTestTempDir(), flagfile_data.file_name);
212*9356374aSAndroid Build Coastguard Worker 
213*9356374aSAndroid Build Coastguard Worker     std::ofstream flagfile_out(flagfile_name);
214*9356374aSAndroid Build Coastguard Worker     for (auto line : flagfile_data.file_lines) {
215*9356374aSAndroid Build Coastguard Worker       flagfile_out << absl::Substitute(line, GetTestTempDir()) << "\n";
216*9356374aSAndroid Build Coastguard Worker     }
217*9356374aSAndroid Build Coastguard Worker 
218*9356374aSAndroid Build Coastguard Worker     absl::StrAppend(&flagfile_flag, separator, flagfile_name);
219*9356374aSAndroid Build Coastguard Worker     separator = ",";
220*9356374aSAndroid Build Coastguard Worker   }
221*9356374aSAndroid Build Coastguard Worker 
222*9356374aSAndroid Build Coastguard Worker   return flagfile_flag.c_str();
223*9356374aSAndroid Build Coastguard Worker }
224*9356374aSAndroid Build Coastguard Worker 
225*9356374aSAndroid Build Coastguard Worker }  // namespace
226*9356374aSAndroid Build Coastguard Worker 
227*9356374aSAndroid Build Coastguard Worker ABSL_FLAG(int, int_flag, 1, "");
228*9356374aSAndroid Build Coastguard Worker ABSL_FLAG(double, double_flag, 1.1, "");
229*9356374aSAndroid Build Coastguard Worker ABSL_FLAG(std::string, string_flag, "a", "");
230*9356374aSAndroid Build Coastguard Worker ABSL_FLAG(bool, bool_flag, false, "");
231*9356374aSAndroid Build Coastguard Worker ABSL_FLAG(UDT, udt_flag, -1, "");
232*9356374aSAndroid Build Coastguard Worker ABSL_RETIRED_FLAG(int, legacy_int, 1, "");
233*9356374aSAndroid Build Coastguard Worker ABSL_RETIRED_FLAG(bool, legacy_bool, false, "");
234*9356374aSAndroid Build Coastguard Worker ABSL_RETIRED_FLAG(std::string, legacy_str, "l", "");
235*9356374aSAndroid Build Coastguard Worker 
236*9356374aSAndroid Build Coastguard Worker namespace {
237*9356374aSAndroid Build Coastguard Worker 
238*9356374aSAndroid Build Coastguard Worker namespace flags = absl::flags_internal;
239*9356374aSAndroid Build Coastguard Worker using testing::AllOf;
240*9356374aSAndroid Build Coastguard Worker using testing::ElementsAreArray;
241*9356374aSAndroid Build Coastguard Worker using testing::HasSubstr;
242*9356374aSAndroid Build Coastguard Worker 
243*9356374aSAndroid Build Coastguard Worker class ParseTest : public testing::Test {
244*9356374aSAndroid Build Coastguard Worker  public:
~ParseTest()245*9356374aSAndroid Build Coastguard Worker   ~ParseTest() override { flags::SetFlagsHelpMode(flags::HelpMode::kNone); }
246*9356374aSAndroid Build Coastguard Worker 
SetUp()247*9356374aSAndroid Build Coastguard Worker   void SetUp() override {
248*9356374aSAndroid Build Coastguard Worker #if ABSL_FLAGS_STRIP_NAMES
249*9356374aSAndroid Build Coastguard Worker     GTEST_SKIP() << "This test requires flag names to be present";
250*9356374aSAndroid Build Coastguard Worker #endif
251*9356374aSAndroid Build Coastguard Worker   }
252*9356374aSAndroid Build Coastguard Worker 
253*9356374aSAndroid Build Coastguard Worker  private:
254*9356374aSAndroid Build Coastguard Worker   absl::FlagSaver flag_saver_;
255*9356374aSAndroid Build Coastguard Worker };
256*9356374aSAndroid Build Coastguard Worker 
257*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
258*9356374aSAndroid Build Coastguard Worker 
259*9356374aSAndroid Build Coastguard Worker template <int N>
InvokeParseAbslOnlyImpl(const char * (& in_argv)[N])260*9356374aSAndroid Build Coastguard Worker flags::HelpMode InvokeParseAbslOnlyImpl(const char* (&in_argv)[N]) {
261*9356374aSAndroid Build Coastguard Worker   std::vector<char*> positional_args;
262*9356374aSAndroid Build Coastguard Worker   std::vector<absl::UnrecognizedFlag> unrecognized_flags;
263*9356374aSAndroid Build Coastguard Worker 
264*9356374aSAndroid Build Coastguard Worker   return flags::ParseAbseilFlagsOnlyImpl(N, const_cast<char**>(in_argv),
265*9356374aSAndroid Build Coastguard Worker                                          positional_args, unrecognized_flags,
266*9356374aSAndroid Build Coastguard Worker                                          flags::UsageFlagsAction::kHandleUsage);
267*9356374aSAndroid Build Coastguard Worker }
268*9356374aSAndroid Build Coastguard Worker 
269*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
270*9356374aSAndroid Build Coastguard Worker 
271*9356374aSAndroid Build Coastguard Worker template <int N>
InvokeParseAbslOnly(const char * (& in_argv)[N])272*9356374aSAndroid Build Coastguard Worker void InvokeParseAbslOnly(const char* (&in_argv)[N]) {
273*9356374aSAndroid Build Coastguard Worker   std::vector<char*> positional_args;
274*9356374aSAndroid Build Coastguard Worker   std::vector<absl::UnrecognizedFlag> unrecognized_flags;
275*9356374aSAndroid Build Coastguard Worker 
276*9356374aSAndroid Build Coastguard Worker   absl::ParseAbseilFlagsOnly(2, const_cast<char**>(in_argv), positional_args,
277*9356374aSAndroid Build Coastguard Worker                              unrecognized_flags);
278*9356374aSAndroid Build Coastguard Worker }
279*9356374aSAndroid Build Coastguard Worker 
280*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
281*9356374aSAndroid Build Coastguard Worker 
282*9356374aSAndroid Build Coastguard Worker template <int N>
InvokeParseCommandLineImpl(const char * (& in_argv)[N])283*9356374aSAndroid Build Coastguard Worker std::vector<char*> InvokeParseCommandLineImpl(const char* (&in_argv)[N]) {
284*9356374aSAndroid Build Coastguard Worker   return flags::ParseCommandLineImpl(
285*9356374aSAndroid Build Coastguard Worker       N, const_cast<char**>(in_argv), flags::UsageFlagsAction::kHandleUsage,
286*9356374aSAndroid Build Coastguard Worker       flags::OnUndefinedFlag::kAbortIfUndefined, std::cerr);
287*9356374aSAndroid Build Coastguard Worker }
288*9356374aSAndroid Build Coastguard Worker 
289*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
290*9356374aSAndroid Build Coastguard Worker 
291*9356374aSAndroid Build Coastguard Worker template <int N>
InvokeParse(const char * (& in_argv)[N])292*9356374aSAndroid Build Coastguard Worker std::vector<char*> InvokeParse(const char* (&in_argv)[N]) {
293*9356374aSAndroid Build Coastguard Worker   return absl::ParseCommandLine(N, const_cast<char**>(in_argv));
294*9356374aSAndroid Build Coastguard Worker }
295*9356374aSAndroid Build Coastguard Worker 
296*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
297*9356374aSAndroid Build Coastguard Worker 
298*9356374aSAndroid Build Coastguard Worker template <int N>
TestParse(const char * (& in_argv)[N],int int_flag_value,double double_flag_val,absl::string_view string_flag_val,bool bool_flag_val,int exp_position_args=0)299*9356374aSAndroid Build Coastguard Worker void TestParse(const char* (&in_argv)[N], int int_flag_value,
300*9356374aSAndroid Build Coastguard Worker                double double_flag_val, absl::string_view string_flag_val,
301*9356374aSAndroid Build Coastguard Worker                bool bool_flag_val, int exp_position_args = 0) {
302*9356374aSAndroid Build Coastguard Worker   auto out_args = InvokeParse(in_argv);
303*9356374aSAndroid Build Coastguard Worker 
304*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(out_args.size(), 1 + exp_position_args);
305*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args[0], "testbin");
306*9356374aSAndroid Build Coastguard Worker 
307*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), int_flag_value);
308*9356374aSAndroid Build Coastguard Worker   EXPECT_NEAR(absl::GetFlag(FLAGS_double_flag), double_flag_val, 0.0001);
309*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), string_flag_val);
310*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::GetFlag(FLAGS_bool_flag), bool_flag_val);
311*9356374aSAndroid Build Coastguard Worker }
312*9356374aSAndroid Build Coastguard Worker 
313*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
314*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestEmptyArgv)315*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestEmptyArgv) {
316*9356374aSAndroid Build Coastguard Worker   const char* in_argv[] = {"testbin"};
317*9356374aSAndroid Build Coastguard Worker 
318*9356374aSAndroid Build Coastguard Worker   auto out_args = InvokeParse(in_argv);
319*9356374aSAndroid Build Coastguard Worker 
320*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(out_args.size(), 1);
321*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args[0], "testbin");
322*9356374aSAndroid Build Coastguard Worker }
323*9356374aSAndroid Build Coastguard Worker 
324*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
325*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestValidIntArg)326*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestValidIntArg) {
327*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
328*9356374aSAndroid Build Coastguard Worker       "testbin",
329*9356374aSAndroid Build Coastguard Worker       "--int_flag=10",
330*9356374aSAndroid Build Coastguard Worker   };
331*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, 10, 1.1, "a", false);
332*9356374aSAndroid Build Coastguard Worker 
333*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
334*9356374aSAndroid Build Coastguard Worker       "testbin",
335*9356374aSAndroid Build Coastguard Worker       "-int_flag=020",
336*9356374aSAndroid Build Coastguard Worker   };
337*9356374aSAndroid Build Coastguard Worker   TestParse(in_args2, 20, 1.1, "a", false);
338*9356374aSAndroid Build Coastguard Worker 
339*9356374aSAndroid Build Coastguard Worker   const char* in_args3[] = {
340*9356374aSAndroid Build Coastguard Worker       "testbin",
341*9356374aSAndroid Build Coastguard Worker       "--int_flag",
342*9356374aSAndroid Build Coastguard Worker       "-30",
343*9356374aSAndroid Build Coastguard Worker   };
344*9356374aSAndroid Build Coastguard Worker   TestParse(in_args3, -30, 1.1, "a", false);
345*9356374aSAndroid Build Coastguard Worker 
346*9356374aSAndroid Build Coastguard Worker   const char* in_args4[] = {
347*9356374aSAndroid Build Coastguard Worker       "testbin",
348*9356374aSAndroid Build Coastguard Worker       "-int_flag",
349*9356374aSAndroid Build Coastguard Worker       "0x21",
350*9356374aSAndroid Build Coastguard Worker   };
351*9356374aSAndroid Build Coastguard Worker   TestParse(in_args4, 33, 1.1, "a", false);
352*9356374aSAndroid Build Coastguard Worker }
353*9356374aSAndroid Build Coastguard Worker 
354*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
355*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestValidDoubleArg)356*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestValidDoubleArg) {
357*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
358*9356374aSAndroid Build Coastguard Worker       "testbin",
359*9356374aSAndroid Build Coastguard Worker       "--double_flag=2.3",
360*9356374aSAndroid Build Coastguard Worker   };
361*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, 1, 2.3, "a", false);
362*9356374aSAndroid Build Coastguard Worker 
363*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
364*9356374aSAndroid Build Coastguard Worker       "testbin",
365*9356374aSAndroid Build Coastguard Worker       "--double_flag=0x1.2",
366*9356374aSAndroid Build Coastguard Worker   };
367*9356374aSAndroid Build Coastguard Worker   TestParse(in_args2, 1, 1.125, "a", false);
368*9356374aSAndroid Build Coastguard Worker 
369*9356374aSAndroid Build Coastguard Worker   const char* in_args3[] = {
370*9356374aSAndroid Build Coastguard Worker       "testbin",
371*9356374aSAndroid Build Coastguard Worker       "--double_flag",
372*9356374aSAndroid Build Coastguard Worker       "99.7",
373*9356374aSAndroid Build Coastguard Worker   };
374*9356374aSAndroid Build Coastguard Worker   TestParse(in_args3, 1, 99.7, "a", false);
375*9356374aSAndroid Build Coastguard Worker 
376*9356374aSAndroid Build Coastguard Worker   const char* in_args4[] = {
377*9356374aSAndroid Build Coastguard Worker       "testbin",
378*9356374aSAndroid Build Coastguard Worker       "--double_flag",
379*9356374aSAndroid Build Coastguard Worker       "0x20.1",
380*9356374aSAndroid Build Coastguard Worker   };
381*9356374aSAndroid Build Coastguard Worker   TestParse(in_args4, 1, 32.0625, "a", false);
382*9356374aSAndroid Build Coastguard Worker }
383*9356374aSAndroid Build Coastguard Worker 
384*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
385*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestValidStringArg)386*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestValidStringArg) {
387*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
388*9356374aSAndroid Build Coastguard Worker       "testbin",
389*9356374aSAndroid Build Coastguard Worker       "--string_flag=aqswde",
390*9356374aSAndroid Build Coastguard Worker   };
391*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, 1, 1.1, "aqswde", false);
392*9356374aSAndroid Build Coastguard Worker 
393*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
394*9356374aSAndroid Build Coastguard Worker       "testbin",
395*9356374aSAndroid Build Coastguard Worker       "-string_flag=a=b=c",
396*9356374aSAndroid Build Coastguard Worker   };
397*9356374aSAndroid Build Coastguard Worker   TestParse(in_args2, 1, 1.1, "a=b=c", false);
398*9356374aSAndroid Build Coastguard Worker 
399*9356374aSAndroid Build Coastguard Worker   const char* in_args3[] = {
400*9356374aSAndroid Build Coastguard Worker       "testbin",
401*9356374aSAndroid Build Coastguard Worker       "--string_flag",
402*9356374aSAndroid Build Coastguard Worker       "zaxscd",
403*9356374aSAndroid Build Coastguard Worker   };
404*9356374aSAndroid Build Coastguard Worker   TestParse(in_args3, 1, 1.1, "zaxscd", false);
405*9356374aSAndroid Build Coastguard Worker 
406*9356374aSAndroid Build Coastguard Worker   const char* in_args4[] = {
407*9356374aSAndroid Build Coastguard Worker       "testbin",
408*9356374aSAndroid Build Coastguard Worker       "-string_flag",
409*9356374aSAndroid Build Coastguard Worker       "--int_flag",
410*9356374aSAndroid Build Coastguard Worker   };
411*9356374aSAndroid Build Coastguard Worker   TestParse(in_args4, 1, 1.1, "--int_flag", false);
412*9356374aSAndroid Build Coastguard Worker 
413*9356374aSAndroid Build Coastguard Worker   const char* in_args5[] = {
414*9356374aSAndroid Build Coastguard Worker       "testbin",
415*9356374aSAndroid Build Coastguard Worker       "--string_flag",
416*9356374aSAndroid Build Coastguard Worker       "--no_a_flag=11",
417*9356374aSAndroid Build Coastguard Worker   };
418*9356374aSAndroid Build Coastguard Worker   TestParse(in_args5, 1, 1.1, "--no_a_flag=11", false);
419*9356374aSAndroid Build Coastguard Worker }
420*9356374aSAndroid Build Coastguard Worker 
421*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
422*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestValidBoolArg)423*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestValidBoolArg) {
424*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
425*9356374aSAndroid Build Coastguard Worker       "testbin",
426*9356374aSAndroid Build Coastguard Worker       "--bool_flag",
427*9356374aSAndroid Build Coastguard Worker   };
428*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, 1, 1.1, "a", true);
429*9356374aSAndroid Build Coastguard Worker 
430*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
431*9356374aSAndroid Build Coastguard Worker       "testbin",
432*9356374aSAndroid Build Coastguard Worker       "--nobool_flag",
433*9356374aSAndroid Build Coastguard Worker   };
434*9356374aSAndroid Build Coastguard Worker   TestParse(in_args2, 1, 1.1, "a", false);
435*9356374aSAndroid Build Coastguard Worker 
436*9356374aSAndroid Build Coastguard Worker   const char* in_args3[] = {
437*9356374aSAndroid Build Coastguard Worker       "testbin",
438*9356374aSAndroid Build Coastguard Worker       "--bool_flag=true",
439*9356374aSAndroid Build Coastguard Worker   };
440*9356374aSAndroid Build Coastguard Worker   TestParse(in_args3, 1, 1.1, "a", true);
441*9356374aSAndroid Build Coastguard Worker 
442*9356374aSAndroid Build Coastguard Worker   const char* in_args4[] = {
443*9356374aSAndroid Build Coastguard Worker       "testbin",
444*9356374aSAndroid Build Coastguard Worker       "-bool_flag=false",
445*9356374aSAndroid Build Coastguard Worker   };
446*9356374aSAndroid Build Coastguard Worker   TestParse(in_args4, 1, 1.1, "a", false);
447*9356374aSAndroid Build Coastguard Worker }
448*9356374aSAndroid Build Coastguard Worker 
449*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
450*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestValidUDTArg)451*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestValidUDTArg) {
452*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
453*9356374aSAndroid Build Coastguard Worker       "testbin",
454*9356374aSAndroid Build Coastguard Worker       "--udt_flag=A",
455*9356374aSAndroid Build Coastguard Worker   };
456*9356374aSAndroid Build Coastguard Worker   InvokeParse(in_args1);
457*9356374aSAndroid Build Coastguard Worker 
458*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::GetFlag(FLAGS_udt_flag).value, 1);
459*9356374aSAndroid Build Coastguard Worker 
460*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {"testbin", "--udt_flag", "AAA"};
461*9356374aSAndroid Build Coastguard Worker   InvokeParse(in_args2);
462*9356374aSAndroid Build Coastguard Worker 
463*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::GetFlag(FLAGS_udt_flag).value, 10);
464*9356374aSAndroid Build Coastguard Worker }
465*9356374aSAndroid Build Coastguard Worker 
466*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
467*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestValidMultipleArg)468*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestValidMultipleArg) {
469*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
470*9356374aSAndroid Build Coastguard Worker       "testbin",           "--bool_flag",       "--int_flag=2",
471*9356374aSAndroid Build Coastguard Worker       "--double_flag=0.1", "--string_flag=asd",
472*9356374aSAndroid Build Coastguard Worker   };
473*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, 2, 0.1, "asd", true);
474*9356374aSAndroid Build Coastguard Worker 
475*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
476*9356374aSAndroid Build Coastguard Worker       "testbin", "--string_flag=", "--nobool_flag", "--int_flag",
477*9356374aSAndroid Build Coastguard Worker       "-011",    "--double_flag",  "-1e-2",
478*9356374aSAndroid Build Coastguard Worker   };
479*9356374aSAndroid Build Coastguard Worker   TestParse(in_args2, -11, -0.01, "", false);
480*9356374aSAndroid Build Coastguard Worker 
481*9356374aSAndroid Build Coastguard Worker   const char* in_args3[] = {
482*9356374aSAndroid Build Coastguard Worker       "testbin",          "--int_flag",         "-0", "--string_flag", "\"\"",
483*9356374aSAndroid Build Coastguard Worker       "--bool_flag=true", "--double_flag=1e18",
484*9356374aSAndroid Build Coastguard Worker   };
485*9356374aSAndroid Build Coastguard Worker   TestParse(in_args3, 0, 1e18, "\"\"", true);
486*9356374aSAndroid Build Coastguard Worker }
487*9356374aSAndroid Build Coastguard Worker 
488*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
489*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestPositionalArgs)490*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestPositionalArgs) {
491*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
492*9356374aSAndroid Build Coastguard Worker       "testbin",
493*9356374aSAndroid Build Coastguard Worker       "p1",
494*9356374aSAndroid Build Coastguard Worker       "p2",
495*9356374aSAndroid Build Coastguard Worker   };
496*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, 1, 1.1, "a", false, 2);
497*9356374aSAndroid Build Coastguard Worker 
498*9356374aSAndroid Build Coastguard Worker   auto out_args1 = InvokeParse(in_args1);
499*9356374aSAndroid Build Coastguard Worker 
500*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args1[1], "p1");
501*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args1[2], "p2");
502*9356374aSAndroid Build Coastguard Worker 
503*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
504*9356374aSAndroid Build Coastguard Worker       "testbin",
505*9356374aSAndroid Build Coastguard Worker       "--int_flag=2",
506*9356374aSAndroid Build Coastguard Worker       "p1",
507*9356374aSAndroid Build Coastguard Worker   };
508*9356374aSAndroid Build Coastguard Worker   TestParse(in_args2, 2, 1.1, "a", false, 1);
509*9356374aSAndroid Build Coastguard Worker 
510*9356374aSAndroid Build Coastguard Worker   auto out_args2 = InvokeParse(in_args2);
511*9356374aSAndroid Build Coastguard Worker 
512*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args2[1], "p1");
513*9356374aSAndroid Build Coastguard Worker 
514*9356374aSAndroid Build Coastguard Worker   const char* in_args3[] = {"testbin", "p1",          "--int_flag=3",
515*9356374aSAndroid Build Coastguard Worker                             "p2",      "--bool_flag", "true"};
516*9356374aSAndroid Build Coastguard Worker   TestParse(in_args3, 3, 1.1, "a", true, 3);
517*9356374aSAndroid Build Coastguard Worker 
518*9356374aSAndroid Build Coastguard Worker   auto out_args3 = InvokeParse(in_args3);
519*9356374aSAndroid Build Coastguard Worker 
520*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args3[1], "p1");
521*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args3[2], "p2");
522*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args3[3], "true");
523*9356374aSAndroid Build Coastguard Worker 
524*9356374aSAndroid Build Coastguard Worker   const char* in_args4[] = {
525*9356374aSAndroid Build Coastguard Worker       "testbin",
526*9356374aSAndroid Build Coastguard Worker       "--",
527*9356374aSAndroid Build Coastguard Worker       "p1",
528*9356374aSAndroid Build Coastguard Worker       "p2",
529*9356374aSAndroid Build Coastguard Worker   };
530*9356374aSAndroid Build Coastguard Worker   TestParse(in_args4, 3, 1.1, "a", true, 2);
531*9356374aSAndroid Build Coastguard Worker 
532*9356374aSAndroid Build Coastguard Worker   auto out_args4 = InvokeParse(in_args4);
533*9356374aSAndroid Build Coastguard Worker 
534*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args4[1], "p1");
535*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args4[2], "p2");
536*9356374aSAndroid Build Coastguard Worker 
537*9356374aSAndroid Build Coastguard Worker   const char* in_args5[] = {
538*9356374aSAndroid Build Coastguard Worker       "testbin", "p1", "--int_flag=4", "--", "--bool_flag", "false", "p2",
539*9356374aSAndroid Build Coastguard Worker   };
540*9356374aSAndroid Build Coastguard Worker   TestParse(in_args5, 4, 1.1, "a", true, 4);
541*9356374aSAndroid Build Coastguard Worker 
542*9356374aSAndroid Build Coastguard Worker   auto out_args5 = InvokeParse(in_args5);
543*9356374aSAndroid Build Coastguard Worker 
544*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args5[1], "p1");
545*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args5[2], "--bool_flag");
546*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args5[3], "false");
547*9356374aSAndroid Build Coastguard Worker   EXPECT_STREQ(out_args5[4], "p2");
548*9356374aSAndroid Build Coastguard Worker }
549*9356374aSAndroid Build Coastguard Worker 
550*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
551*9356374aSAndroid Build Coastguard Worker 
552*9356374aSAndroid Build Coastguard Worker using ParseDeathTest = ParseTest;
553*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseDeathTest,TestUndefinedArg)554*9356374aSAndroid Build Coastguard Worker TEST_F(ParseDeathTest, TestUndefinedArg) {
555*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
556*9356374aSAndroid Build Coastguard Worker       "testbin",
557*9356374aSAndroid Build Coastguard Worker       "--undefined_flag",
558*9356374aSAndroid Build Coastguard Worker   };
559*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
560*9356374aSAndroid Build Coastguard Worker                             "Unknown command line flag 'undefined_flag'");
561*9356374aSAndroid Build Coastguard Worker 
562*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
563*9356374aSAndroid Build Coastguard Worker       "testbin",
564*9356374aSAndroid Build Coastguard Worker       "--noprefixed_flag",
565*9356374aSAndroid Build Coastguard Worker   };
566*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args2),
567*9356374aSAndroid Build Coastguard Worker                             "Unknown command line flag 'noprefixed_flag'");
568*9356374aSAndroid Build Coastguard Worker 
569*9356374aSAndroid Build Coastguard Worker   const char* in_args3[] = {
570*9356374aSAndroid Build Coastguard Worker       "testbin",
571*9356374aSAndroid Build Coastguard Worker       "--Int_flag=1",
572*9356374aSAndroid Build Coastguard Worker   };
573*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args3),
574*9356374aSAndroid Build Coastguard Worker                             "Unknown command line flag 'Int_flag'");
575*9356374aSAndroid Build Coastguard Worker }
576*9356374aSAndroid Build Coastguard Worker 
577*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
578*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseDeathTest,TestInvalidBoolFlagFormat)579*9356374aSAndroid Build Coastguard Worker TEST_F(ParseDeathTest, TestInvalidBoolFlagFormat) {
580*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
581*9356374aSAndroid Build Coastguard Worker       "testbin",
582*9356374aSAndroid Build Coastguard Worker       "--bool_flag=",
583*9356374aSAndroid Build Coastguard Worker   };
584*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(
585*9356374aSAndroid Build Coastguard Worker       InvokeParse(in_args1),
586*9356374aSAndroid Build Coastguard Worker       "Missing the value after assignment for the boolean flag 'bool_flag'");
587*9356374aSAndroid Build Coastguard Worker 
588*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
589*9356374aSAndroid Build Coastguard Worker       "testbin",
590*9356374aSAndroid Build Coastguard Worker       "--nobool_flag=true",
591*9356374aSAndroid Build Coastguard Worker   };
592*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args2),
593*9356374aSAndroid Build Coastguard Worker                "Negative form with assignment is not valid for the boolean "
594*9356374aSAndroid Build Coastguard Worker                "flag 'bool_flag'");
595*9356374aSAndroid Build Coastguard Worker }
596*9356374aSAndroid Build Coastguard Worker 
597*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
598*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseDeathTest,TestInvalidNonBoolFlagFormat)599*9356374aSAndroid Build Coastguard Worker TEST_F(ParseDeathTest, TestInvalidNonBoolFlagFormat) {
600*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
601*9356374aSAndroid Build Coastguard Worker       "testbin",
602*9356374aSAndroid Build Coastguard Worker       "--nostring_flag",
603*9356374aSAndroid Build Coastguard Worker   };
604*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
605*9356374aSAndroid Build Coastguard Worker                "Negative form is not valid for the flag 'string_flag'");
606*9356374aSAndroid Build Coastguard Worker 
607*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
608*9356374aSAndroid Build Coastguard Worker       "testbin",
609*9356374aSAndroid Build Coastguard Worker       "--int_flag",
610*9356374aSAndroid Build Coastguard Worker   };
611*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args2),
612*9356374aSAndroid Build Coastguard Worker                "Missing the value for the flag 'int_flag'");
613*9356374aSAndroid Build Coastguard Worker }
614*9356374aSAndroid Build Coastguard Worker 
615*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
616*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseDeathTest,TestInvalidUDTFlagFormat)617*9356374aSAndroid Build Coastguard Worker TEST_F(ParseDeathTest, TestInvalidUDTFlagFormat) {
618*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
619*9356374aSAndroid Build Coastguard Worker       "testbin",
620*9356374aSAndroid Build Coastguard Worker       "--udt_flag=1",
621*9356374aSAndroid Build Coastguard Worker   };
622*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
623*9356374aSAndroid Build Coastguard Worker                "Illegal value '1' specified for flag 'udt_flag'; Use values A, "
624*9356374aSAndroid Build Coastguard Worker                "AAA instead");
625*9356374aSAndroid Build Coastguard Worker 
626*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
627*9356374aSAndroid Build Coastguard Worker       "testbin",
628*9356374aSAndroid Build Coastguard Worker       "--udt_flag",
629*9356374aSAndroid Build Coastguard Worker       "AA",
630*9356374aSAndroid Build Coastguard Worker   };
631*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args2),
632*9356374aSAndroid Build Coastguard Worker                "Illegal value 'AA' specified for flag 'udt_flag'; Use values "
633*9356374aSAndroid Build Coastguard Worker                "A, AAA instead");
634*9356374aSAndroid Build Coastguard Worker }
635*9356374aSAndroid Build Coastguard Worker 
636*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
637*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseDeathTest,TestFlagSuggestions)638*9356374aSAndroid Build Coastguard Worker TEST_F(ParseDeathTest, TestFlagSuggestions) {
639*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
640*9356374aSAndroid Build Coastguard Worker       "testbin",
641*9356374aSAndroid Build Coastguard Worker       "--legacy_boo",
642*9356374aSAndroid Build Coastguard Worker   };
643*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(
644*9356374aSAndroid Build Coastguard Worker       InvokeParse(in_args1),
645*9356374aSAndroid Build Coastguard Worker       "Unknown command line flag 'legacy_boo'. Did you mean: legacy_bool ?");
646*9356374aSAndroid Build Coastguard Worker 
647*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {"testbin", "--foo", "--undefok=foo1"};
648*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(
649*9356374aSAndroid Build Coastguard Worker       InvokeParse(in_args2),
650*9356374aSAndroid Build Coastguard Worker       "Unknown command line flag 'foo'. Did you mean: foo1 \\(undefok\\)?");
651*9356374aSAndroid Build Coastguard Worker 
652*9356374aSAndroid Build Coastguard Worker   const char* in_args3[] = {
653*9356374aSAndroid Build Coastguard Worker       "testbin",
654*9356374aSAndroid Build Coastguard Worker       "--nolegacy_ino",
655*9356374aSAndroid Build Coastguard Worker   };
656*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args3),
657*9356374aSAndroid Build Coastguard Worker                             "Unknown command line flag 'nolegacy_ino'. Did "
658*9356374aSAndroid Build Coastguard Worker                             "you mean: nolegacy_bool, legacy_int ?");
659*9356374aSAndroid Build Coastguard Worker }
660*9356374aSAndroid Build Coastguard Worker 
661*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
662*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,GetHints)663*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, GetHints) {
664*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(absl::flags_internal::GetMisspellingHints("legacy_boo"),
665*9356374aSAndroid Build Coastguard Worker               testing::ContainerEq(std::vector<std::string>{"legacy_bool"}));
666*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(absl::flags_internal::GetMisspellingHints("nolegacy_itn"),
667*9356374aSAndroid Build Coastguard Worker               testing::ContainerEq(std::vector<std::string>{"legacy_int"}));
668*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(absl::flags_internal::GetMisspellingHints("nolegacy_int1"),
669*9356374aSAndroid Build Coastguard Worker               testing::ContainerEq(std::vector<std::string>{"legacy_int"}));
670*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(absl::flags_internal::GetMisspellingHints("nolegacy_int"),
671*9356374aSAndroid Build Coastguard Worker               testing::ContainerEq(std::vector<std::string>{"legacy_int"}));
672*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(absl::flags_internal::GetMisspellingHints("nolegacy_ino"),
673*9356374aSAndroid Build Coastguard Worker               testing::ContainerEq(
674*9356374aSAndroid Build Coastguard Worker                   std::vector<std::string>{"nolegacy_bool", "legacy_int"}));
675*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(
676*9356374aSAndroid Build Coastguard Worker       absl::flags_internal::GetMisspellingHints("FLAG_HEADER_000").size(), 100);
677*9356374aSAndroid Build Coastguard Worker }
678*9356374aSAndroid Build Coastguard Worker 
679*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
680*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestLegacyFlags)681*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestLegacyFlags) {
682*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
683*9356374aSAndroid Build Coastguard Worker       "testbin",
684*9356374aSAndroid Build Coastguard Worker       "--legacy_int=11",
685*9356374aSAndroid Build Coastguard Worker   };
686*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, 1, 1.1, "a", false);
687*9356374aSAndroid Build Coastguard Worker 
688*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
689*9356374aSAndroid Build Coastguard Worker       "testbin",
690*9356374aSAndroid Build Coastguard Worker       "--legacy_bool",
691*9356374aSAndroid Build Coastguard Worker   };
692*9356374aSAndroid Build Coastguard Worker   TestParse(in_args2, 1, 1.1, "a", false);
693*9356374aSAndroid Build Coastguard Worker 
694*9356374aSAndroid Build Coastguard Worker   const char* in_args3[] = {
695*9356374aSAndroid Build Coastguard Worker       "testbin",       "--legacy_int", "22",           "--int_flag=2",
696*9356374aSAndroid Build Coastguard Worker       "--legacy_bool", "true",         "--legacy_str", "--string_flag=qwe",
697*9356374aSAndroid Build Coastguard Worker   };
698*9356374aSAndroid Build Coastguard Worker   TestParse(in_args3, 2, 1.1, "a", false, 1);
699*9356374aSAndroid Build Coastguard Worker }
700*9356374aSAndroid Build Coastguard Worker 
701*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
702*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestSimpleValidFlagfile)703*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestSimpleValidFlagfile) {
704*9356374aSAndroid Build Coastguard Worker   std::string flagfile_flag;
705*9356374aSAndroid Build Coastguard Worker 
706*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
707*9356374aSAndroid Build Coastguard Worker       "testbin",
708*9356374aSAndroid Build Coastguard Worker       GetFlagfileFlag({{"parse_test.ff1", absl::MakeConstSpan(ff1_data)}},
709*9356374aSAndroid Build Coastguard Worker                       flagfile_flag),
710*9356374aSAndroid Build Coastguard Worker   };
711*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, -1, 0.1, "q2w2  ", true);
712*9356374aSAndroid Build Coastguard Worker 
713*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
714*9356374aSAndroid Build Coastguard Worker       "testbin",
715*9356374aSAndroid Build Coastguard Worker       GetFlagfileFlag({{"parse_test.ff2", absl::MakeConstSpan(ff2_data)}},
716*9356374aSAndroid Build Coastguard Worker                       flagfile_flag),
717*9356374aSAndroid Build Coastguard Worker   };
718*9356374aSAndroid Build Coastguard Worker   TestParse(in_args2, 100, 0.1, "q2w2  ", false);
719*9356374aSAndroid Build Coastguard Worker }
720*9356374aSAndroid Build Coastguard Worker 
721*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
722*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestValidMultiFlagfile)723*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestValidMultiFlagfile) {
724*9356374aSAndroid Build Coastguard Worker   std::string flagfile_flag;
725*9356374aSAndroid Build Coastguard Worker 
726*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
727*9356374aSAndroid Build Coastguard Worker       "testbin",
728*9356374aSAndroid Build Coastguard Worker       GetFlagfileFlag({{"parse_test.ff2", absl::MakeConstSpan(ff2_data)},
729*9356374aSAndroid Build Coastguard Worker                        {"parse_test.ff1", absl::MakeConstSpan(ff1_data)}},
730*9356374aSAndroid Build Coastguard Worker                       flagfile_flag),
731*9356374aSAndroid Build Coastguard Worker   };
732*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, -1, 0.1, "q2w2  ", true);
733*9356374aSAndroid Build Coastguard Worker }
734*9356374aSAndroid Build Coastguard Worker 
735*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
736*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestFlagfileMixedWithRegularFlags)737*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestFlagfileMixedWithRegularFlags) {
738*9356374aSAndroid Build Coastguard Worker   std::string flagfile_flag;
739*9356374aSAndroid Build Coastguard Worker 
740*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
741*9356374aSAndroid Build Coastguard Worker       "testbin", "--int_flag=3",
742*9356374aSAndroid Build Coastguard Worker       GetFlagfileFlag({{"parse_test.ff1", absl::MakeConstSpan(ff1_data)}},
743*9356374aSAndroid Build Coastguard Worker                       flagfile_flag),
744*9356374aSAndroid Build Coastguard Worker       "-double_flag=0.2"};
745*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, -1, 0.2, "q2w2  ", true);
746*9356374aSAndroid Build Coastguard Worker }
747*9356374aSAndroid Build Coastguard Worker 
748*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
749*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestFlagfileInFlagfile)750*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestFlagfileInFlagfile) {
751*9356374aSAndroid Build Coastguard Worker   std::string flagfile_flag;
752*9356374aSAndroid Build Coastguard Worker 
753*9356374aSAndroid Build Coastguard Worker   constexpr const char* const ff3_data[] = {
754*9356374aSAndroid Build Coastguard Worker       "--flagfile=$0/parse_test.ff1",
755*9356374aSAndroid Build Coastguard Worker       "--flagfile=$0/parse_test.ff2",
756*9356374aSAndroid Build Coastguard Worker   };
757*9356374aSAndroid Build Coastguard Worker 
758*9356374aSAndroid Build Coastguard Worker   GetFlagfileFlag({{"parse_test.ff2", absl::MakeConstSpan(ff2_data)},
759*9356374aSAndroid Build Coastguard Worker                    {"parse_test.ff1", absl::MakeConstSpan(ff1_data)}},
760*9356374aSAndroid Build Coastguard Worker                       flagfile_flag);
761*9356374aSAndroid Build Coastguard Worker 
762*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
763*9356374aSAndroid Build Coastguard Worker       "testbin",
764*9356374aSAndroid Build Coastguard Worker       GetFlagfileFlag({{"parse_test.ff3", absl::MakeConstSpan(ff3_data)}},
765*9356374aSAndroid Build Coastguard Worker                       flagfile_flag),
766*9356374aSAndroid Build Coastguard Worker   };
767*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, 100, 0.1, "q2w2  ", false);
768*9356374aSAndroid Build Coastguard Worker }
769*9356374aSAndroid Build Coastguard Worker 
770*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
771*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseDeathTest,TestInvalidFlagfiles)772*9356374aSAndroid Build Coastguard Worker TEST_F(ParseDeathTest, TestInvalidFlagfiles) {
773*9356374aSAndroid Build Coastguard Worker   std::string flagfile_flag;
774*9356374aSAndroid Build Coastguard Worker 
775*9356374aSAndroid Build Coastguard Worker   constexpr const char* const ff4_data[] = {
776*9356374aSAndroid Build Coastguard Worker     "--unknown_flag=10"
777*9356374aSAndroid Build Coastguard Worker   };
778*9356374aSAndroid Build Coastguard Worker 
779*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
780*9356374aSAndroid Build Coastguard Worker       "testbin",
781*9356374aSAndroid Build Coastguard Worker       GetFlagfileFlag({{"parse_test.ff4",
782*9356374aSAndroid Build Coastguard Worker                         absl::MakeConstSpan(ff4_data)}}, flagfile_flag),
783*9356374aSAndroid Build Coastguard Worker   };
784*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
785*9356374aSAndroid Build Coastguard Worker                "Unknown command line flag 'unknown_flag'");
786*9356374aSAndroid Build Coastguard Worker 
787*9356374aSAndroid Build Coastguard Worker   constexpr const char* const ff5_data[] = {
788*9356374aSAndroid Build Coastguard Worker     "--int_flag 10",
789*9356374aSAndroid Build Coastguard Worker   };
790*9356374aSAndroid Build Coastguard Worker 
791*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
792*9356374aSAndroid Build Coastguard Worker       "testbin",
793*9356374aSAndroid Build Coastguard Worker       GetFlagfileFlag({{"parse_test.ff5",
794*9356374aSAndroid Build Coastguard Worker                         absl::MakeConstSpan(ff5_data)}}, flagfile_flag),
795*9356374aSAndroid Build Coastguard Worker   };
796*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args2),
797*9356374aSAndroid Build Coastguard Worker                "Unknown command line flag 'int_flag 10'");
798*9356374aSAndroid Build Coastguard Worker 
799*9356374aSAndroid Build Coastguard Worker   constexpr const char* const ff6_data[] = {
800*9356374aSAndroid Build Coastguard Worker       "--int_flag=10", "--", "arg1", "arg2", "arg3",
801*9356374aSAndroid Build Coastguard Worker   };
802*9356374aSAndroid Build Coastguard Worker 
803*9356374aSAndroid Build Coastguard Worker   const char* in_args3[] = {
804*9356374aSAndroid Build Coastguard Worker       "testbin",
805*9356374aSAndroid Build Coastguard Worker       GetFlagfileFlag({{"parse_test.ff6", absl::MakeConstSpan(ff6_data)}},
806*9356374aSAndroid Build Coastguard Worker                       flagfile_flag),
807*9356374aSAndroid Build Coastguard Worker   };
808*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args3),
809*9356374aSAndroid Build Coastguard Worker                "Flagfile can't contain position arguments or --");
810*9356374aSAndroid Build Coastguard Worker 
811*9356374aSAndroid Build Coastguard Worker   const char* in_args4[] = {
812*9356374aSAndroid Build Coastguard Worker       "testbin",
813*9356374aSAndroid Build Coastguard Worker       "--flagfile=invalid_flag_file",
814*9356374aSAndroid Build Coastguard Worker   };
815*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args4),
816*9356374aSAndroid Build Coastguard Worker                             "Can't open flagfile invalid_flag_file");
817*9356374aSAndroid Build Coastguard Worker 
818*9356374aSAndroid Build Coastguard Worker   constexpr const char* const ff7_data[] = {
819*9356374aSAndroid Build Coastguard Worker       "--int_flag=10",
820*9356374aSAndroid Build Coastguard Worker       "*bin*",
821*9356374aSAndroid Build Coastguard Worker       "--str_flag=aqsw",
822*9356374aSAndroid Build Coastguard Worker   };
823*9356374aSAndroid Build Coastguard Worker 
824*9356374aSAndroid Build Coastguard Worker   const char* in_args5[] = {
825*9356374aSAndroid Build Coastguard Worker       "testbin",
826*9356374aSAndroid Build Coastguard Worker       GetFlagfileFlag({{"parse_test.ff7", absl::MakeConstSpan(ff7_data)}},
827*9356374aSAndroid Build Coastguard Worker                       flagfile_flag),
828*9356374aSAndroid Build Coastguard Worker   };
829*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args5),
830*9356374aSAndroid Build Coastguard Worker                "Unexpected line in the flagfile .*: \\*bin\\*");
831*9356374aSAndroid Build Coastguard Worker }
832*9356374aSAndroid Build Coastguard Worker 
833*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
834*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestReadingRequiredFlagsFromEnv)835*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestReadingRequiredFlagsFromEnv) {
836*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {"testbin",
837*9356374aSAndroid Build Coastguard Worker                             "--fromenv=int_flag,bool_flag,string_flag"};
838*9356374aSAndroid Build Coastguard Worker 
839*9356374aSAndroid Build Coastguard Worker   ScopedSetEnv set_int_flag("FLAGS_int_flag", "33");
840*9356374aSAndroid Build Coastguard Worker   ScopedSetEnv set_bool_flag("FLAGS_bool_flag", "True");
841*9356374aSAndroid Build Coastguard Worker   ScopedSetEnv set_string_flag("FLAGS_string_flag", "AQ12");
842*9356374aSAndroid Build Coastguard Worker 
843*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, 33, 1.1, "AQ12", true);
844*9356374aSAndroid Build Coastguard Worker }
845*9356374aSAndroid Build Coastguard Worker 
846*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
847*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseDeathTest,TestReadingUnsetRequiredFlagsFromEnv)848*9356374aSAndroid Build Coastguard Worker TEST_F(ParseDeathTest, TestReadingUnsetRequiredFlagsFromEnv) {
849*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {"testbin", "--fromenv=int_flag"};
850*9356374aSAndroid Build Coastguard Worker 
851*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
852*9356374aSAndroid Build Coastguard Worker                "FLAGS_int_flag not found in environment");
853*9356374aSAndroid Build Coastguard Worker }
854*9356374aSAndroid Build Coastguard Worker 
855*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
856*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseDeathTest,TestRecursiveFlagsFromEnv)857*9356374aSAndroid Build Coastguard Worker TEST_F(ParseDeathTest, TestRecursiveFlagsFromEnv) {
858*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {"testbin", "--fromenv=tryfromenv"};
859*9356374aSAndroid Build Coastguard Worker 
860*9356374aSAndroid Build Coastguard Worker   ScopedSetEnv set_tryfromenv("FLAGS_tryfromenv", "int_flag");
861*9356374aSAndroid Build Coastguard Worker 
862*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
863*9356374aSAndroid Build Coastguard Worker                             "Infinite recursion on flag tryfromenv");
864*9356374aSAndroid Build Coastguard Worker }
865*9356374aSAndroid Build Coastguard Worker 
866*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
867*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestReadingOptionalFlagsFromEnv)868*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestReadingOptionalFlagsFromEnv) {
869*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
870*9356374aSAndroid Build Coastguard Worker       "testbin", "--tryfromenv=int_flag,bool_flag,string_flag,other_flag"};
871*9356374aSAndroid Build Coastguard Worker 
872*9356374aSAndroid Build Coastguard Worker   ScopedSetEnv set_int_flag("FLAGS_int_flag", "17");
873*9356374aSAndroid Build Coastguard Worker   ScopedSetEnv set_bool_flag("FLAGS_bool_flag", "Y");
874*9356374aSAndroid Build Coastguard Worker 
875*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, 17, 1.1, "a", true);
876*9356374aSAndroid Build Coastguard Worker }
877*9356374aSAndroid Build Coastguard Worker 
878*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
879*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestReadingFlagsFromEnvMoxedWithRegularFlags)880*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestReadingFlagsFromEnvMoxedWithRegularFlags) {
881*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
882*9356374aSAndroid Build Coastguard Worker       "testbin",
883*9356374aSAndroid Build Coastguard Worker       "--bool_flag=T",
884*9356374aSAndroid Build Coastguard Worker       "--tryfromenv=int_flag,bool_flag",
885*9356374aSAndroid Build Coastguard Worker       "--int_flag=-21",
886*9356374aSAndroid Build Coastguard Worker   };
887*9356374aSAndroid Build Coastguard Worker 
888*9356374aSAndroid Build Coastguard Worker   ScopedSetEnv set_int_flag("FLAGS_int_flag", "-15");
889*9356374aSAndroid Build Coastguard Worker   ScopedSetEnv set_bool_flag("FLAGS_bool_flag", "F");
890*9356374aSAndroid Build Coastguard Worker 
891*9356374aSAndroid Build Coastguard Worker   TestParse(in_args1, -21, 1.1, "a", false);
892*9356374aSAndroid Build Coastguard Worker }
893*9356374aSAndroid Build Coastguard Worker 
894*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
895*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseDeathTest,TestSimpleHelpFlagHandling)896*9356374aSAndroid Build Coastguard Worker TEST_F(ParseDeathTest, TestSimpleHelpFlagHandling) {
897*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
898*9356374aSAndroid Build Coastguard Worker       "testbin",
899*9356374aSAndroid Build Coastguard Worker       "--help",
900*9356374aSAndroid Build Coastguard Worker   };
901*9356374aSAndroid Build Coastguard Worker 
902*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(InvokeParseAbslOnlyImpl(in_args1), flags::HelpMode::kImportant);
903*9356374aSAndroid Build Coastguard Worker   EXPECT_EXIT(InvokeParse(in_args1), testing::ExitedWithCode(1), "");
904*9356374aSAndroid Build Coastguard Worker 
905*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {
906*9356374aSAndroid Build Coastguard Worker       "testbin",
907*9356374aSAndroid Build Coastguard Worker       "--help",
908*9356374aSAndroid Build Coastguard Worker       "--int_flag=3",
909*9356374aSAndroid Build Coastguard Worker   };
910*9356374aSAndroid Build Coastguard Worker 
911*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(InvokeParseAbslOnlyImpl(in_args2), flags::HelpMode::kImportant);
912*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 3);
913*9356374aSAndroid Build Coastguard Worker 
914*9356374aSAndroid Build Coastguard Worker   const char* in_args3[] = {"testbin", "--help", "some_positional_arg"};
915*9356374aSAndroid Build Coastguard Worker 
916*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(InvokeParseAbslOnlyImpl(in_args3), flags::HelpMode::kImportant);
917*9356374aSAndroid Build Coastguard Worker }
918*9356374aSAndroid Build Coastguard Worker 
919*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
920*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestSubstringHelpFlagHandling)921*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestSubstringHelpFlagHandling) {
922*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
923*9356374aSAndroid Build Coastguard Worker       "testbin",
924*9356374aSAndroid Build Coastguard Worker       "--help=abcd",
925*9356374aSAndroid Build Coastguard Worker   };
926*9356374aSAndroid Build Coastguard Worker 
927*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(InvokeParseAbslOnlyImpl(in_args1), flags::HelpMode::kMatch);
928*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(flags::GetFlagsHelpMatchSubstr(), "abcd");
929*9356374aSAndroid Build Coastguard Worker }
930*9356374aSAndroid Build Coastguard Worker 
931*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
932*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseDeathTest,TestVersionHandling)933*9356374aSAndroid Build Coastguard Worker TEST_F(ParseDeathTest, TestVersionHandling) {
934*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
935*9356374aSAndroid Build Coastguard Worker       "testbin",
936*9356374aSAndroid Build Coastguard Worker       "--version",
937*9356374aSAndroid Build Coastguard Worker   };
938*9356374aSAndroid Build Coastguard Worker 
939*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(InvokeParseAbslOnlyImpl(in_args1), flags::HelpMode::kVersion);
940*9356374aSAndroid Build Coastguard Worker }
941*9356374aSAndroid Build Coastguard Worker 
942*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
943*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,TestCheckArgsHandling)944*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, TestCheckArgsHandling) {
945*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {"testbin", "--only_check_args", "--int_flag=211"};
946*9356374aSAndroid Build Coastguard Worker 
947*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(InvokeParseAbslOnlyImpl(in_args1), flags::HelpMode::kOnlyCheckArgs);
948*9356374aSAndroid Build Coastguard Worker   EXPECT_EXIT(InvokeParseAbslOnly(in_args1), testing::ExitedWithCode(0), "");
949*9356374aSAndroid Build Coastguard Worker   EXPECT_EXIT(InvokeParse(in_args1), testing::ExitedWithCode(0), "");
950*9356374aSAndroid Build Coastguard Worker 
951*9356374aSAndroid Build Coastguard Worker   const char* in_args2[] = {"testbin", "--only_check_args", "--unknown_flag=a"};
952*9356374aSAndroid Build Coastguard Worker 
953*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(InvokeParseAbslOnlyImpl(in_args2), flags::HelpMode::kOnlyCheckArgs);
954*9356374aSAndroid Build Coastguard Worker   EXPECT_EXIT(InvokeParseAbslOnly(in_args2), testing::ExitedWithCode(0), "");
955*9356374aSAndroid Build Coastguard Worker   EXPECT_EXIT(InvokeParse(in_args2), testing::ExitedWithCode(1), "");
956*9356374aSAndroid Build Coastguard Worker }
957*9356374aSAndroid Build Coastguard Worker 
958*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
959*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,WasPresentOnCommandLine)960*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, WasPresentOnCommandLine) {
961*9356374aSAndroid Build Coastguard Worker   const char* in_args1[] = {
962*9356374aSAndroid Build Coastguard Worker       "testbin",        "arg1", "--bool_flag",
963*9356374aSAndroid Build Coastguard Worker       "--int_flag=211", "arg2", "--double_flag=1.1",
964*9356374aSAndroid Build Coastguard Worker       "--string_flag",  "asd",  "--",
965*9356374aSAndroid Build Coastguard Worker       "--some_flag",    "arg4",
966*9356374aSAndroid Build Coastguard Worker   };
967*9356374aSAndroid Build Coastguard Worker 
968*9356374aSAndroid Build Coastguard Worker   InvokeParse(in_args1);
969*9356374aSAndroid Build Coastguard Worker 
970*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(flags::WasPresentOnCommandLine("bool_flag"));
971*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(flags::WasPresentOnCommandLine("int_flag"));
972*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(flags::WasPresentOnCommandLine("double_flag"));
973*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(flags::WasPresentOnCommandLine("string_flag"));
974*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(flags::WasPresentOnCommandLine("some_flag"));
975*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(flags::WasPresentOnCommandLine("another_flag"));
976*9356374aSAndroid Build Coastguard Worker }
977*9356374aSAndroid Build Coastguard Worker 
978*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
979*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,ParseAbseilFlagsOnlySuccess)980*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, ParseAbseilFlagsOnlySuccess) {
981*9356374aSAndroid Build Coastguard Worker   const char* in_args[] = {
982*9356374aSAndroid Build Coastguard Worker       "testbin",
983*9356374aSAndroid Build Coastguard Worker       "arg1",
984*9356374aSAndroid Build Coastguard Worker       "--bool_flag",
985*9356374aSAndroid Build Coastguard Worker       "--int_flag=211",
986*9356374aSAndroid Build Coastguard Worker       "arg2",
987*9356374aSAndroid Build Coastguard Worker       "--double_flag=1.1",
988*9356374aSAndroid Build Coastguard Worker       "--undef_flag1",
989*9356374aSAndroid Build Coastguard Worker       "--undef_flag2=123",
990*9356374aSAndroid Build Coastguard Worker       "--string_flag",
991*9356374aSAndroid Build Coastguard Worker       "asd",
992*9356374aSAndroid Build Coastguard Worker       "--",
993*9356374aSAndroid Build Coastguard Worker       "--some_flag",
994*9356374aSAndroid Build Coastguard Worker       "arg4",
995*9356374aSAndroid Build Coastguard Worker   };
996*9356374aSAndroid Build Coastguard Worker 
997*9356374aSAndroid Build Coastguard Worker   std::vector<char*> positional_args;
998*9356374aSAndroid Build Coastguard Worker   std::vector<absl::UnrecognizedFlag> unrecognized_flags;
999*9356374aSAndroid Build Coastguard Worker 
1000*9356374aSAndroid Build Coastguard Worker   absl::ParseAbseilFlagsOnly(13, const_cast<char**>(in_args), positional_args,
1001*9356374aSAndroid Build Coastguard Worker                              unrecognized_flags);
1002*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(positional_args,
1003*9356374aSAndroid Build Coastguard Worker               ElementsAreArray(
1004*9356374aSAndroid Build Coastguard Worker                   {absl::string_view("testbin"), absl::string_view("arg1"),
1005*9356374aSAndroid Build Coastguard Worker                    absl::string_view("arg2"), absl::string_view("--some_flag"),
1006*9356374aSAndroid Build Coastguard Worker                    absl::string_view("arg4")}));
1007*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(unrecognized_flags,
1008*9356374aSAndroid Build Coastguard Worker               ElementsAreArray(
1009*9356374aSAndroid Build Coastguard Worker                   {absl::UnrecognizedFlag(absl::UnrecognizedFlag::kFromArgv,
1010*9356374aSAndroid Build Coastguard Worker                                           "undef_flag1"),
1011*9356374aSAndroid Build Coastguard Worker                    absl::UnrecognizedFlag(absl::UnrecognizedFlag::kFromArgv,
1012*9356374aSAndroid Build Coastguard Worker                                           "undef_flag2")}));
1013*9356374aSAndroid Build Coastguard Worker }
1014*9356374aSAndroid Build Coastguard Worker 
1015*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
1016*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseDeathTest,ParseAbseilFlagsOnlyFailure)1017*9356374aSAndroid Build Coastguard Worker TEST_F(ParseDeathTest, ParseAbseilFlagsOnlyFailure) {
1018*9356374aSAndroid Build Coastguard Worker   const char* in_args[] = {
1019*9356374aSAndroid Build Coastguard Worker       "testbin",
1020*9356374aSAndroid Build Coastguard Worker       "--int_flag=21.1",
1021*9356374aSAndroid Build Coastguard Worker   };
1022*9356374aSAndroid Build Coastguard Worker 
1023*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(
1024*9356374aSAndroid Build Coastguard Worker       InvokeParseAbslOnly(in_args),
1025*9356374aSAndroid Build Coastguard Worker       "Illegal value '21.1' specified for flag 'int_flag'");
1026*9356374aSAndroid Build Coastguard Worker }
1027*9356374aSAndroid Build Coastguard Worker 
1028*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
1029*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,UndefOkFlagsAreIgnored)1030*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, UndefOkFlagsAreIgnored) {
1031*9356374aSAndroid Build Coastguard Worker   const char* in_args[] = {
1032*9356374aSAndroid Build Coastguard Worker       "testbin",           "--undef_flag1",
1033*9356374aSAndroid Build Coastguard Worker       "--undef_flag2=123", "--undefok=undef_flag2",
1034*9356374aSAndroid Build Coastguard Worker       "--undef_flag3",     "value",
1035*9356374aSAndroid Build Coastguard Worker   };
1036*9356374aSAndroid Build Coastguard Worker 
1037*9356374aSAndroid Build Coastguard Worker   std::vector<char*> positional_args;
1038*9356374aSAndroid Build Coastguard Worker   std::vector<absl::UnrecognizedFlag> unrecognized_flags;
1039*9356374aSAndroid Build Coastguard Worker 
1040*9356374aSAndroid Build Coastguard Worker   absl::ParseAbseilFlagsOnly(6, const_cast<char**>(in_args), positional_args,
1041*9356374aSAndroid Build Coastguard Worker                              unrecognized_flags);
1042*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(positional_args, ElementsAreArray({absl::string_view("testbin"),
1043*9356374aSAndroid Build Coastguard Worker                                                  absl::string_view("value")}));
1044*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(unrecognized_flags,
1045*9356374aSAndroid Build Coastguard Worker               ElementsAreArray(
1046*9356374aSAndroid Build Coastguard Worker                   {absl::UnrecognizedFlag(absl::UnrecognizedFlag::kFromArgv,
1047*9356374aSAndroid Build Coastguard Worker                                           "undef_flag1"),
1048*9356374aSAndroid Build Coastguard Worker                    absl::UnrecognizedFlag(absl::UnrecognizedFlag::kFromArgv,
1049*9356374aSAndroid Build Coastguard Worker                                           "undef_flag3")}));
1050*9356374aSAndroid Build Coastguard Worker }
1051*9356374aSAndroid Build Coastguard Worker 
1052*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
1053*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseTest,AllUndefOkFlagsAreIgnored)1054*9356374aSAndroid Build Coastguard Worker TEST_F(ParseTest, AllUndefOkFlagsAreIgnored) {
1055*9356374aSAndroid Build Coastguard Worker   const char* in_args[] = {
1056*9356374aSAndroid Build Coastguard Worker       "testbin",
1057*9356374aSAndroid Build Coastguard Worker       "--undef_flag1",
1058*9356374aSAndroid Build Coastguard Worker       "--undef_flag2=123",
1059*9356374aSAndroid Build Coastguard Worker       "--undefok=undef_flag2,undef_flag1,undef_flag3",
1060*9356374aSAndroid Build Coastguard Worker       "--undef_flag3",
1061*9356374aSAndroid Build Coastguard Worker       "value",
1062*9356374aSAndroid Build Coastguard Worker       "--",
1063*9356374aSAndroid Build Coastguard Worker       "--undef_flag4",
1064*9356374aSAndroid Build Coastguard Worker   };
1065*9356374aSAndroid Build Coastguard Worker 
1066*9356374aSAndroid Build Coastguard Worker   std::vector<char*> positional_args;
1067*9356374aSAndroid Build Coastguard Worker   std::vector<absl::UnrecognizedFlag> unrecognized_flags;
1068*9356374aSAndroid Build Coastguard Worker 
1069*9356374aSAndroid Build Coastguard Worker   absl::ParseAbseilFlagsOnly(8, const_cast<char**>(in_args), positional_args,
1070*9356374aSAndroid Build Coastguard Worker                              unrecognized_flags);
1071*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(positional_args,
1072*9356374aSAndroid Build Coastguard Worker               ElementsAreArray({absl::string_view("testbin"),
1073*9356374aSAndroid Build Coastguard Worker                                 absl::string_view("value"),
1074*9356374aSAndroid Build Coastguard Worker                                 absl::string_view("--undef_flag4")}));
1075*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(unrecognized_flags, testing::IsEmpty());
1076*9356374aSAndroid Build Coastguard Worker }
1077*9356374aSAndroid Build Coastguard Worker 
1078*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
1079*9356374aSAndroid Build Coastguard Worker 
TEST_F(ParseDeathTest,ExitOnUnrecognizedFlagPrintsHelp)1080*9356374aSAndroid Build Coastguard Worker TEST_F(ParseDeathTest, ExitOnUnrecognizedFlagPrintsHelp) {
1081*9356374aSAndroid Build Coastguard Worker   const char* in_args[] = {
1082*9356374aSAndroid Build Coastguard Worker       "testbin",
1083*9356374aSAndroid Build Coastguard Worker       "--undef_flag1",
1084*9356374aSAndroid Build Coastguard Worker       "--help=int_flag",
1085*9356374aSAndroid Build Coastguard Worker   };
1086*9356374aSAndroid Build Coastguard Worker 
1087*9356374aSAndroid Build Coastguard Worker   EXPECT_EXIT(InvokeParseCommandLineImpl(in_args), testing::ExitedWithCode(1),
1088*9356374aSAndroid Build Coastguard Worker               AllOf(HasSubstr("Unknown command line flag 'undef_flag1'"),
1089*9356374aSAndroid Build Coastguard Worker                     HasSubstr("Try --helpfull to get a list of all flags")));
1090*9356374aSAndroid Build Coastguard Worker }
1091*9356374aSAndroid Build Coastguard Worker 
1092*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
1093*9356374aSAndroid Build Coastguard Worker 
1094*9356374aSAndroid Build Coastguard Worker }  // namespace
1095