blob: 9a922efdaddc18bb0ac3ff648713b9fdf8661920 [file] [log] [blame]
Craig Silverstein917f4e72011-07-29 04:26:49 +00001// Copyright (c) 2005, Google Inc.
Craig Silversteinb9f23482007-03-22 00:15:41 +00002// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30// ---
Craig Silversteinb9f23482007-03-22 00:15:41 +000031//
32// For now, this unit test does not cover all features of
Craig Silversteine0b71e52008-09-19 19:32:05 +000033// gflags.cc
Craig Silversteinb9f23482007-03-22 00:15:41 +000034
Craig Silverstein917f4e72011-07-29 04:26:49 +000035#include <gflags/gflags.h>
36
Andreas Schuh752c6322016-03-01 21:34:24 +000037#include "config.h"
38#include "util.h"
39
Craig Silverstein917f4e72011-07-29 04:26:49 +000040#include <math.h> // for isinf() and isnan()
Craig Silversteinb9f23482007-03-22 00:15:41 +000041#include <stdio.h>
Craig Silverstein917f4e72011-07-29 04:26:49 +000042#include <stdlib.h>
Craig Silversteinb9f23482007-03-22 00:15:41 +000043#include <string.h>
Andreas Schuh8566bcf2014-03-19 14:24:52 +000044#ifdef HAVE_UNISTD_H
Andreas Schuh8477f312014-03-15 14:15:33 +000045# include <unistd.h> // for unlink()
46#endif
Craig Silversteinb9f23482007-03-22 00:15:41 +000047#include <vector>
48#include <string>
Craig Silverstein917f4e72011-07-29 04:26:49 +000049TEST_INIT
50EXPECT_DEATH_INIT
Craig Silverstein31c8edc2010-01-05 02:25:45 +000051
Craig Silverstein67914682008-08-21 00:50:59 +000052// I don't actually use this header file, but #include it under the
53// old location to make sure that the include-header-forwarding
Craig Silversteinab3d7652009-11-10 16:33:51 +000054// works. But don't bother on windows; the windows port is so new
55// it never had the old location-names.
Craig Silverstein31c8edc2010-01-05 02:25:45 +000056#ifndef _MSC_VER
Andreas Schuh126f36b2013-08-01 01:47:13 +010057#include <gflags/gflags_completions.h>
58void (*unused_fn)() = &GFLAGS_NAMESPACE::HandleCommandLineCompletions;
Craig Silversteinab3d7652009-11-10 16:33:51 +000059#endif
Craig Silversteinb9f23482007-03-22 00:15:41 +000060
Craig Silverstein917f4e72011-07-29 04:26:49 +000061using std::string;
62using std::vector;
Andreas Schuh126f36b2013-08-01 01:47:13 +010063using GFLAGS_NAMESPACE::int32;
64using GFLAGS_NAMESPACE::FlagRegisterer;
65using GFLAGS_NAMESPACE::StringFromEnv;
66using GFLAGS_NAMESPACE::RegisterFlagValidator;
67using GFLAGS_NAMESPACE::CommandLineFlagInfo;
68using GFLAGS_NAMESPACE::GetAllFlags;
Craig Silversteinb9f23482007-03-22 00:15:41 +000069
Andreas Schuh0d9486f2014-03-17 21:15:52 +000070DEFINE_string(test_tmpdir, "", "Dir we use for temp files");
71DEFINE_string(srcdir, StringFromEnv("SRCDIR", "."), "Source-dir root, needed to find gflags_unittest_flagfile");
Craig Silversteinb9f23482007-03-22 00:15:41 +000072
Craig Silverstein917f4e72011-07-29 04:26:49 +000073DECLARE_string(tryfromenv); // in gflags.cc
74
Craig Silversteinc23c6c62011-11-03 23:25:32 +000075DEFINE_bool(test_bool, false, "tests bool-ness");
Craig Silversteinb9f23482007-03-22 00:15:41 +000076DEFINE_int32(test_int32, -1, "");
77DEFINE_int64(test_int64, -2, "");
Allan L. Bazineteaf05342016-04-05 10:50:21 -070078DEFINE_uint32(test_uint32, 1, "");
Craig Silversteinb9f23482007-03-22 00:15:41 +000079DEFINE_uint64(test_uint64, 2, "");
80DEFINE_double(test_double, -1.0, "");
81DEFINE_string(test_string, "initial", "");
82
83//
84// The below ugliness gets some additional code coverage in the -helpxml
85// and -helpmatch test cases having to do with string lengths and formatting
86//
87DEFINE_bool(test_bool_with_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_long_name,
88 false,
89 "extremely_extremely_extremely_extremely_extremely_extremely_extremely_extremely_long_meaning");
90
91DEFINE_string(test_str1, "initial", "");
92DEFINE_string(test_str2, "initial", "");
93DEFINE_string(test_str3, "initial", "");
94
95// This is used to test setting tryfromenv manually
96DEFINE_string(test_tryfromenv, "initial", "");
97
Craig Silversteinc79c32d2008-07-22 23:29:39 +000098// Don't try this at home!
99static int changeable_var = 12;
100DEFINE_int32(changeable_var, ++changeable_var, "");
101
102static int changeable_bool_var = 8008;
103DEFINE_bool(changeable_bool_var, ++changeable_bool_var == 8009, "");
104
105static int changeable_string_var = 0;
Craig Silverstein917f4e72011-07-29 04:26:49 +0000106static string ChangeableString() {
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000107 char r[] = {static_cast<char>('0' + ++changeable_string_var), '\0'};
Craig Silversteinc79c32d2008-07-22 23:29:39 +0000108 return r;
109}
110DEFINE_string(changeable_string_var, ChangeableString(), "");
111
Craig Silversteinb9f23482007-03-22 00:15:41 +0000112// These are never used in this unittest, but can be used by
Craig Silversteine0b71e52008-09-19 19:32:05 +0000113// gflags_unittest.sh when it needs to specify flags
114// that are legal for gflags_unittest but don't need to
Craig Silversteinb9f23482007-03-22 00:15:41 +0000115// be a particular value.
116DEFINE_bool(unused_bool, true, "unused bool-ness");
117DEFINE_int32(unused_int32, -1001, "");
118DEFINE_int64(unused_int64, -2001, "");
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700119DEFINE_uint32(unused_uint32, 1000, "");
Craig Silversteinb9f23482007-03-22 00:15:41 +0000120DEFINE_uint64(unused_uint64, 2000, "");
121DEFINE_double(unused_double, -1000.0, "");
122DEFINE_string(unused_string, "unused", "");
123
Craig Silverstein585a44a2007-10-18 20:08:26 +0000124// These flags are used by gflags_unittest.sh
125DEFINE_bool(changed_bool1, false, "changed");
126DEFINE_bool(changed_bool2, false, "changed");
Craig Silverstein82335562011-08-04 00:02:39 +0000127DEFINE_bool(long_helpstring, false,
128 "This helpstring goes on forever and ever and ever and ever and "
129 "ever and ever and ever and ever and ever and ever and ever and "
130 "ever and ever and ever and ever and ever and ever and ever and "
131 "ever and ever and ever and ever and ever and ever and ever and "
132 "ever and ever and ever and ever and ever and ever and ever and "
133 "ever and ever and ever and ever and ever and ever and ever and "
134 "ever and ever and ever and ever and ever and ever and ever and "
135 "ever and ever and ever and ever and ever and ever and ever and "
136 "ever and ever and ever and ever and ever and ever and ever and "
137 "ever and ever and ever and ever and ever and ever and ever and "
138 "ever. This is the end of a long helpstring");
139
Craig Silverstein585a44a2007-10-18 20:08:26 +0000140
Craig Silversteinc79c32d2008-07-22 23:29:39 +0000141static bool AlwaysFail(const char* flag, bool value) { return value == false; }
142DEFINE_bool(always_fail, false, "will fail to validate when you set it");
Andreas Schuh45a53de2013-04-20 18:35:34 +0000143DEFINE_validator(always_fail, AlwaysFail);
Craig Silversteinc79c32d2008-07-22 23:29:39 +0000144
Craig Silverstein917f4e72011-07-29 04:26:49 +0000145// See the comment by GetAllFlags in gflags.h
Craig Silversteinab3d7652009-11-10 16:33:51 +0000146static bool DeadlockIfCantLockInValidators(const char* flag, bool value) {
147 if (!value) {
148 return true;
149 }
Craig Silverstein917f4e72011-07-29 04:26:49 +0000150 vector<CommandLineFlagInfo> dummy;
Craig Silversteinab3d7652009-11-10 16:33:51 +0000151 GetAllFlags(&dummy);
152 return true;
153}
154DEFINE_bool(deadlock_if_cant_lock,
155 false,
156 "will deadlock if set to true and "
157 "if locking of registry in validators fails.");
Andreas Schuh45a53de2013-04-20 18:35:34 +0000158DEFINE_validator(deadlock_if_cant_lock, DeadlockIfCantLockInValidators);
Craig Silverstein917f4e72011-07-29 04:26:49 +0000159
160#define MAKEFLAG(x) DEFINE_int32(test_flag_num##x, x, "Test flag")
161
162// Define 10 flags
163#define MAKEFLAG10(x) \
164 MAKEFLAG(x##0); \
165 MAKEFLAG(x##1); \
166 MAKEFLAG(x##2); \
167 MAKEFLAG(x##3); \
168 MAKEFLAG(x##4); \
169 MAKEFLAG(x##5); \
170 MAKEFLAG(x##6); \
171 MAKEFLAG(x##7); \
172 MAKEFLAG(x##8); \
173 MAKEFLAG(x##9)
174
175// Define 100 flags
176#define MAKEFLAG100(x) \
177 MAKEFLAG10(x##0); \
178 MAKEFLAG10(x##1); \
179 MAKEFLAG10(x##2); \
180 MAKEFLAG10(x##3); \
181 MAKEFLAG10(x##4); \
182 MAKEFLAG10(x##5); \
183 MAKEFLAG10(x##6); \
184 MAKEFLAG10(x##7); \
185 MAKEFLAG10(x##8); \
186 MAKEFLAG10(x##9)
187
188// Define a bunch of command-line flags. Each occurrence of the MAKEFLAG100
189// macro defines 100 integer flags. This lets us test the effect of having
190// many flags on startup time.
191MAKEFLAG100(1);
192MAKEFLAG100(2);
193MAKEFLAG100(3);
194MAKEFLAG100(4);
195MAKEFLAG100(5);
196MAKEFLAG100(6);
197MAKEFLAG100(7);
198MAKEFLAG100(8);
199MAKEFLAG100(9);
200MAKEFLAG100(10);
201MAKEFLAG100(11);
202MAKEFLAG100(12);
203MAKEFLAG100(13);
204MAKEFLAG100(14);
205MAKEFLAG100(15);
206
207#undef MAKEFLAG100
208#undef MAKEFLAG10
209#undef MAKEFLAG
Craig Silversteinab3d7652009-11-10 16:33:51 +0000210
211// This is a pseudo-flag -- we want to register a flag with a filename
Craig Silversteine0b71e52008-09-19 19:32:05 +0000212// at the top level, but there is no way to do this except by faking
213// the filename.
214namespace fLI {
215 static const int32 FLAGS_nonotldflag1 = 12;
216 int32 FLAGS_tldflag1 = FLAGS_nonotldflag1;
217 int32 FLAGS_notldflag1 = FLAGS_nonotldflag1;
218 static FlagRegisterer o_tldflag1(
dreamer.dead46ea10f2016-07-29 21:02:29 +0300219 "tldflag1",
Craig Silversteine0b71e52008-09-19 19:32:05 +0000220 "should show up in --helpshort", "gflags_unittest.cc",
Craig Silversteinc23c6c62011-11-03 23:25:32 +0000221 &FLAGS_tldflag1, &FLAGS_notldflag1);
Craig Silversteine0b71e52008-09-19 19:32:05 +0000222}
223using fLI::FLAGS_tldflag1;
224
225namespace fLI {
226 static const int32 FLAGS_nonotldflag2 = 23;
227 int32 FLAGS_tldflag2 = FLAGS_nonotldflag2;
228 int32 FLAGS_notldflag2 = FLAGS_nonotldflag2;
229 static FlagRegisterer o_tldflag2(
dreamer.dead46ea10f2016-07-29 21:02:29 +0300230 "tldflag2",
Craig Silversteine0b71e52008-09-19 19:32:05 +0000231 "should show up in --helpshort", "gflags_unittest.",
Craig Silversteinc23c6c62011-11-03 23:25:32 +0000232 &FLAGS_tldflag2, &FLAGS_notldflag2);
Craig Silversteine0b71e52008-09-19 19:32:05 +0000233}
234using fLI::FLAGS_tldflag2;
235
Andreas Schuh126f36b2013-08-01 01:47:13 +0100236namespace GFLAGS_NAMESPACE {
Craig Silversteinb9f23482007-03-22 00:15:41 +0000237
Craig Silverstein917f4e72011-07-29 04:26:49 +0000238namespace {
Craig Silversteinb9f23482007-03-22 00:15:41 +0000239
240
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000241static string TmpFile(const string& basename) {
242#ifdef _MSC_VER
243 return FLAGS_test_tmpdir + "\\" + basename;
244#else
245 return FLAGS_test_tmpdir + "/" + basename;
246#endif
247}
248
249// Returns the definition of the --flagfile flag to be used in the tests.
Craig Silverstein917f4e72011-07-29 04:26:49 +0000250// Must be called after ParseCommandLineFlags().
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000251static const char* GetFlagFileFlag() {
252#ifdef _MSC_VER
Andreas Schuh126f36b2013-08-01 01:47:13 +0100253 static const string flagfile = FLAGS_srcdir + "\\gflags_unittest_flagfile";
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000254#else
Andreas Schuh126f36b2013-08-01 01:47:13 +0100255 static const string flagfile = FLAGS_srcdir + "/gflags_unittest_flagfile";
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000256#endif
257 static const string flagfile_flag = string("--flagfile=") + flagfile;
258 return flagfile_flag.c_str();
259}
260
261
Craig Silversteinc79c32d2008-07-22 23:29:39 +0000262// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a
263// compiler error iff T1 and T2 are different types.
264template <typename T1, typename T2>
265struct CompileAssertTypesEqual;
266
267template <typename T>
268struct CompileAssertTypesEqual<T, T> {
269};
270
271
272template <typename Expected, typename Actual>
273void AssertIsType(Actual& x) {
274 CompileAssertTypesEqual<Expected, Actual>();
275}
276
277// Verify all the flags are the right type.
278TEST(FlagTypes, FlagTypes) {
279 AssertIsType<bool>(FLAGS_test_bool);
280 AssertIsType<int32>(FLAGS_test_int32);
281 AssertIsType<int64>(FLAGS_test_int64);
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700282 AssertIsType<uint32>(FLAGS_test_uint32);
Craig Silversteinc79c32d2008-07-22 23:29:39 +0000283 AssertIsType<uint64>(FLAGS_test_uint64);
284 AssertIsType<double>(FLAGS_test_double);
285 AssertIsType<string>(FLAGS_test_string);
286}
287
Craig Silverstein917f4e72011-07-29 04:26:49 +0000288#ifdef GTEST_HAS_DEATH_TEST
Craig Silversteinb9f23482007-03-22 00:15:41 +0000289// Death tests for "help" options.
290//
Craig Silverstein917f4e72011-07-29 04:26:49 +0000291// The help system automatically calls gflags_exitfunc(1) when you specify any of
Craig Silversteinb9f23482007-03-22 00:15:41 +0000292// the help-related flags ("-helpmatch", "-helpxml") so we can't test
293// those mainline.
294
295// Tests that "-helpmatch" causes the process to die.
296TEST(ReadFlagsFromStringDeathTest, HelpMatch) {
297 EXPECT_DEATH(ReadFlagsFromString("-helpmatch=base", GetArgv0(), true),
298 "");
299}
300
301
302// Tests that "-helpxml" causes the process to die.
303TEST(ReadFlagsFromStringDeathTest, HelpXml) {
304 EXPECT_DEATH(ReadFlagsFromString("-helpxml", GetArgv0(), true),
305 "");
306}
Craig Silverstein917f4e72011-07-29 04:26:49 +0000307#endif
Craig Silversteinb9f23482007-03-22 00:15:41 +0000308
309
310// A subroutine needed for testing reading flags from a string.
311void TestFlagString(const string& flags,
312 const string& expected_string,
313 bool expected_bool,
314 int32 expected_int32,
315 double expected_double) {
316 EXPECT_TRUE(ReadFlagsFromString(flags,
317 GetArgv0(),
318 // errors are fatal
319 true));
320
321 EXPECT_EQ(expected_string, FLAGS_test_string);
322 EXPECT_EQ(expected_bool, FLAGS_test_bool);
323 EXPECT_EQ(expected_int32, FLAGS_test_int32);
324 EXPECT_DOUBLE_EQ(expected_double, FLAGS_test_double);
325}
326
327
328// Tests reading flags from a string.
329TEST(FlagFileTest, ReadFlagsFromString) {
330 TestFlagString(
331 // Flag string
332 "-test_string=continued\n"
333 "# some comments are in order\n"
334 "# some\n"
335 " # comments\n"
336 "#are\n"
337 " #trickier\n"
338 "# than others\n"
339 "-test_bool=true\n"
340 " -test_int32=1\n"
341 "-test_double=0.0\n",
342 // Expected values
343 "continued",
344 true,
345 1,
346 0.0);
347
348 TestFlagString(
349 // Flag string
350 "# let's make sure it can update values\n"
351 "-test_string=initial\n"
352 "-test_bool=false\n"
353 "-test_int32=123\n"
354 "-test_double=123.0\n",
355 // Expected values
356 "initial",
357 false,
358 123,
359 123.0);
Todd Lipcon14c0e932016-10-12 10:23:42 -0700360
361 // Test that flags can use dashes instead of underscores.
362 TestFlagString(
363 // Flag string
364 "-test-string=initial\n"
365 "--test-bool=false\n"
366 "--test-int32=123\n"
367 "--test-double=123.0\n",
368 // Expected values
369 "initial",
370 false,
371 123,
372 123.0);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000373}
374
375// Tests the filename part of the flagfile
376TEST(FlagFileTest, FilenamesOurfileLast) {
377 FLAGS_test_string = "initial";
378 FLAGS_test_bool = false;
379 FLAGS_test_int32 = -1;
380 FLAGS_test_double = -1.0;
381 TestFlagString(
382 // Flag string
383 "-test_string=continued\n"
384 "# some comments are in order\n"
385 "# some\n"
386 " # comments\n"
387 "#are\n"
388 " #trickier\n"
389 "# than others\n"
390 "not_our_filename\n"
391 "-test_bool=true\n"
392 " -test_int32=1\n"
393 "gflags_unittest\n"
394 "-test_double=1000.0\n",
395 // Expected values
396 "continued",
397 false,
398 -1,
399 1000.0);
400}
401
402TEST(FlagFileTest, FilenamesOurfileFirst) {
403 FLAGS_test_string = "initial";
404 FLAGS_test_bool = false;
405 FLAGS_test_int32 = -1;
406 FLAGS_test_double = -1.0;
407 TestFlagString(
408 // Flag string
409 "-test_string=continued\n"
410 "# some comments are in order\n"
411 "# some\n"
412 " # comments\n"
413 "#are\n"
414 " #trickier\n"
415 "# than others\n"
416 "gflags_unittest\n"
417 "-test_bool=true\n"
418 " -test_int32=1\n"
419 "not_our_filename\n"
420 "-test_double=1000.0\n",
421 // Expected values
422 "continued",
423 true,
424 1,
425 -1.0);
426}
427
Andreas Schuhddc53572014-03-19 17:32:23 +0000428#if defined(HAVE_FNMATCH_H) || defined(HAVE_SHLWAPI_H) // otherwise glob isn't supported
Craig Silversteinb9f23482007-03-22 00:15:41 +0000429TEST(FlagFileTest, FilenamesOurfileGlob) {
430 FLAGS_test_string = "initial";
431 FLAGS_test_bool = false;
432 FLAGS_test_int32 = -1;
433 FLAGS_test_double = -1.0;
434 TestFlagString(
435 // Flag string
436 "-test_string=continued\n"
437 "# some comments are in order\n"
438 "# some\n"
439 " # comments\n"
440 "#are\n"
441 " #trickier\n"
442 "# than others\n"
443 "*flags*\n"
444 "-test_bool=true\n"
445 " -test_int32=1\n"
446 "flags\n"
447 "-test_double=1000.0\n",
448 // Expected values
449 "continued",
450 true,
451 1,
452 -1.0);
453}
454
455TEST(FlagFileTest, FilenamesOurfileInBigList) {
456 FLAGS_test_string = "initial";
457 FLAGS_test_bool = false;
458 FLAGS_test_int32 = -1;
459 FLAGS_test_double = -1.0;
460 TestFlagString(
461 // Flag string
462 "-test_string=continued\n"
463 "# some comments are in order\n"
464 "# some\n"
465 " # comments\n"
466 "#are\n"
467 " #trickier\n"
468 "# than others\n"
469 "*first* *flags* *third*\n"
470 "-test_bool=true\n"
471 " -test_int32=1\n"
472 "flags\n"
473 "-test_double=1000.0\n",
474 // Expected values
475 "continued",
476 true,
477 1,
478 -1.0);
479}
Andreas Schuhddc53572014-03-19 17:32:23 +0000480#endif // defined(HAVE_FNMATCH_H) || defined(HAVE_SHLWAPI_H)
Craig Silversteinb9f23482007-03-22 00:15:41 +0000481
482// Tests that a failed flag-from-string read keeps flags at default values
483TEST(FlagFileTest, FailReadFlagsFromString) {
484 FLAGS_test_int32 = 119;
485 string flags("# let's make sure it can update values\n"
486 "-test_string=non_initial\n"
487 "-test_bool=false\n"
488 "-test_int32=123\n"
489 "-test_double=illegal\n");
490
491 EXPECT_FALSE(ReadFlagsFromString(flags,
492 GetArgv0(),
493 // errors are fatal
494 false));
495
496 EXPECT_EQ(119, FLAGS_test_int32);
497 EXPECT_EQ("initial", FLAGS_test_string);
498}
499
500// Tests that flags can be set to ordinary values.
501TEST(SetFlagValueTest, OrdinaryValues) {
502 EXPECT_EQ("initial", FLAGS_test_str1);
503
504 SetCommandLineOptionWithMode("test_str1", "second", SET_FLAG_IF_DEFAULT);
505 EXPECT_EQ("second", FLAGS_test_str1); // set; was default
506
507 SetCommandLineOptionWithMode("test_str1", "third", SET_FLAG_IF_DEFAULT);
508 EXPECT_EQ("second", FLAGS_test_str1); // already set once
509
510 FLAGS_test_str1 = "initial";
511 SetCommandLineOptionWithMode("test_str1", "third", SET_FLAG_IF_DEFAULT);
512 EXPECT_EQ("initial", FLAGS_test_str1); // still already set before
513
514 SetCommandLineOptionWithMode("test_str1", "third", SET_FLAGS_VALUE);
515 EXPECT_EQ("third", FLAGS_test_str1); // changed value
516
517 SetCommandLineOptionWithMode("test_str1", "fourth", SET_FLAGS_DEFAULT);
518 EXPECT_EQ("third", FLAGS_test_str1);
519 // value not changed (already set before)
520
521 EXPECT_EQ("initial", FLAGS_test_str2);
522
523 SetCommandLineOptionWithMode("test_str2", "second", SET_FLAGS_DEFAULT);
524 EXPECT_EQ("second", FLAGS_test_str2); // changed (was default)
525
526 FLAGS_test_str2 = "extra";
527 EXPECT_EQ("extra", FLAGS_test_str2);
528
529 FLAGS_test_str2 = "second";
530 SetCommandLineOptionWithMode("test_str2", "third", SET_FLAGS_DEFAULT);
531 EXPECT_EQ("third", FLAGS_test_str2); // still changed (was equal to default)
532
533 SetCommandLineOptionWithMode("test_str2", "fourth", SET_FLAG_IF_DEFAULT);
534 EXPECT_EQ("fourth", FLAGS_test_str2); // changed (was default)
535
536 EXPECT_EQ("initial", FLAGS_test_str3);
537
538 SetCommandLineOptionWithMode("test_str3", "second", SET_FLAGS_DEFAULT);
539 EXPECT_EQ("second", FLAGS_test_str3); // changed
540
541 FLAGS_test_str3 = "third";
542 SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAGS_DEFAULT);
543 EXPECT_EQ("third", FLAGS_test_str3); // not changed (was set)
544
545 SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAG_IF_DEFAULT);
546 EXPECT_EQ("third", FLAGS_test_str3); // not changed (was set)
547
548 SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAGS_VALUE);
549 EXPECT_EQ("fourth", FLAGS_test_str3); // changed value
550}
551
552
553// Tests that flags can be set to exceptional values.
Craig Silverstein688ea022009-09-11 00:15:50 +0000554// Note: apparently MINGW doesn't parse inf and nan correctly:
555// http://www.mail-archive.com/bug-gnulib@gnu.org/msg09573.html
556// This url says FreeBSD also has a problem, but I didn't see that.
Craig Silversteinb9f23482007-03-22 00:15:41 +0000557TEST(SetFlagValueTest, ExceptionalValues) {
Craig Silverstein688ea022009-09-11 00:15:50 +0000558#if defined(isinf) && !defined(__MINGW32__)
Craig Silversteinb9f23482007-03-22 00:15:41 +0000559 EXPECT_EQ("test_double set to inf\n",
560 SetCommandLineOption("test_double", "inf"));
Craig Silverstein2b66a842007-06-12 23:59:42 +0000561 EXPECT_INF(FLAGS_test_double);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000562
563 EXPECT_EQ("test_double set to inf\n",
564 SetCommandLineOption("test_double", "INF"));
Craig Silverstein2b66a842007-06-12 23:59:42 +0000565 EXPECT_INF(FLAGS_test_double);
Craig Silverstein67914682008-08-21 00:50:59 +0000566#endif
Craig Silversteinb9f23482007-03-22 00:15:41 +0000567
568 // set some bad values
569 EXPECT_EQ("",
570 SetCommandLineOption("test_double", "0.1xxx"));
571 EXPECT_EQ("",
572 SetCommandLineOption("test_double", " "));
573 EXPECT_EQ("",
574 SetCommandLineOption("test_double", ""));
Craig Silverstein688ea022009-09-11 00:15:50 +0000575#if defined(isinf) && !defined(__MINGW32__)
Craig Silversteinb9f23482007-03-22 00:15:41 +0000576 EXPECT_EQ("test_double set to -inf\n",
577 SetCommandLineOption("test_double", "-inf"));
Craig Silverstein2b66a842007-06-12 23:59:42 +0000578 EXPECT_INF(FLAGS_test_double);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000579 EXPECT_GT(0, FLAGS_test_double);
Craig Silverstein67914682008-08-21 00:50:59 +0000580#endif
Craig Silversteinb9f23482007-03-22 00:15:41 +0000581
Craig Silverstein688ea022009-09-11 00:15:50 +0000582#if defined(isnan) && !defined(__MINGW32__)
Craig Silversteinb9f23482007-03-22 00:15:41 +0000583 EXPECT_EQ("test_double set to nan\n",
584 SetCommandLineOption("test_double", "NaN"));
Craig Silverstein2b66a842007-06-12 23:59:42 +0000585 EXPECT_NAN(FLAGS_test_double);
Craig Silverstein67914682008-08-21 00:50:59 +0000586#endif
Craig Silversteinb9f23482007-03-22 00:15:41 +0000587}
588
589// Tests that integer flags can be specified in many ways
590TEST(SetFlagValueTest, DifferentRadices) {
591 EXPECT_EQ("test_int32 set to 12\n",
592 SetCommandLineOption("test_int32", "12"));
593
594 EXPECT_EQ("test_int32 set to 16\n",
595 SetCommandLineOption("test_int32", "0x10"));
596
597 EXPECT_EQ("test_int32 set to 34\n",
598 SetCommandLineOption("test_int32", "0X22"));
599
600 // Leading 0 is *not* octal; it's still decimal
601 EXPECT_EQ("test_int32 set to 10\n",
602 SetCommandLineOption("test_int32", "010"));
603}
604
605// Tests what happens when you try to set a flag to an illegal value
606TEST(SetFlagValueTest, IllegalValues) {
607 FLAGS_test_bool = true;
608 FLAGS_test_int32 = 119;
609 FLAGS_test_int64 = 1191;
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700610 FLAGS_test_uint32 = 11911;
611 FLAGS_test_uint64 = 119111;
Craig Silversteinb9f23482007-03-22 00:15:41 +0000612
613 EXPECT_EQ("",
614 SetCommandLineOption("test_bool", "12"));
615
616 EXPECT_EQ("",
dreamer.deadfa266382016-07-20 12:18:08 +0300617 SetCommandLineOption("test_uint32", "-1970"));
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700618
619 EXPECT_EQ("",
Craig Silversteinb9f23482007-03-22 00:15:41 +0000620 SetCommandLineOption("test_int32", "7000000000000"));
621
Craig Silversteinb9f23482007-03-22 00:15:41 +0000622 EXPECT_EQ("",
623 SetCommandLineOption("test_uint64", "-1"));
Craig Silversteinb9f23482007-03-22 00:15:41 +0000624
625 EXPECT_EQ("",
626 SetCommandLineOption("test_int64", "not a number!"));
627
628 // Test the empty string with each type of input
629 EXPECT_EQ("", SetCommandLineOption("test_bool", ""));
630 EXPECT_EQ("", SetCommandLineOption("test_int32", ""));
631 EXPECT_EQ("", SetCommandLineOption("test_int64", ""));
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700632 EXPECT_EQ("", SetCommandLineOption("test_uint32", ""));
Craig Silversteinb9f23482007-03-22 00:15:41 +0000633 EXPECT_EQ("", SetCommandLineOption("test_uint64", ""));
634 EXPECT_EQ("", SetCommandLineOption("test_double", ""));
635 EXPECT_EQ("test_string set to \n", SetCommandLineOption("test_string", ""));
636
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000637 EXPECT_TRUE(FLAGS_test_bool);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000638 EXPECT_EQ(119, FLAGS_test_int32);
639 EXPECT_EQ(1191, FLAGS_test_int64);
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700640 EXPECT_EQ(11911, FLAGS_test_uint32);
641 EXPECT_EQ(119111, FLAGS_test_uint64);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000642}
643
644
Craig Silversteinc79c32d2008-07-22 23:29:39 +0000645// Tests that we only evaluate macro args once
646TEST(MacroArgs, EvaluateOnce) {
647 EXPECT_EQ(13, FLAGS_changeable_var);
648 // Make sure we don't ++ the value somehow, when evaluating the flag.
649 EXPECT_EQ(13, FLAGS_changeable_var);
650 // Make sure the macro only evaluated this var once.
651 EXPECT_EQ(13, changeable_var);
652 // Make sure the actual value and default value are the same
653 SetCommandLineOptionWithMode("changeable_var", "21", SET_FLAG_IF_DEFAULT);
654 EXPECT_EQ(21, FLAGS_changeable_var);
655}
656
657TEST(MacroArgs, EvaluateOnceBool) {
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000658 EXPECT_TRUE(FLAGS_changeable_bool_var);
659 EXPECT_TRUE(FLAGS_changeable_bool_var);
Craig Silversteinc79c32d2008-07-22 23:29:39 +0000660 EXPECT_EQ(8009, changeable_bool_var);
661 SetCommandLineOptionWithMode("changeable_bool_var", "false",
662 SET_FLAG_IF_DEFAULT);
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000663 EXPECT_FALSE(FLAGS_changeable_bool_var);
Craig Silversteinc79c32d2008-07-22 23:29:39 +0000664}
665
666TEST(MacroArgs, EvaluateOnceStrings) {
667 EXPECT_EQ("1", FLAGS_changeable_string_var);
668 EXPECT_EQ("1", FLAGS_changeable_string_var);
669 EXPECT_EQ(1, changeable_string_var);
670 SetCommandLineOptionWithMode("changeable_string_var", "different",
671 SET_FLAG_IF_DEFAULT);
672 EXPECT_EQ("different", FLAGS_changeable_string_var);
673}
674
Craig Silversteinb9f23482007-03-22 00:15:41 +0000675// Tests that the FooFromEnv does the right thing
676TEST(FromEnvTest, LegalValues) {
677 setenv("BOOL_VAL1", "true", 1);
678 setenv("BOOL_VAL2", "false", 1);
679 setenv("BOOL_VAL3", "1", 1);
680 setenv("BOOL_VAL4", "F", 1);
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000681 EXPECT_TRUE(BoolFromEnv("BOOL_VAL1", false));
682 EXPECT_FALSE(BoolFromEnv("BOOL_VAL2", true));
683 EXPECT_TRUE(BoolFromEnv("BOOL_VAL3", false));
684 EXPECT_FALSE(BoolFromEnv("BOOL_VAL4", true));
685 EXPECT_TRUE(BoolFromEnv("BOOL_VAL_UNKNOWN", true));
686 EXPECT_FALSE(BoolFromEnv("BOOL_VAL_UNKNOWN", false));
Craig Silversteinb9f23482007-03-22 00:15:41 +0000687
688 setenv("INT_VAL1", "1", 1);
689 setenv("INT_VAL2", "-1", 1);
690 EXPECT_EQ(1, Int32FromEnv("INT_VAL1", 10));
691 EXPECT_EQ(-1, Int32FromEnv("INT_VAL2", 10));
692 EXPECT_EQ(10, Int32FromEnv("INT_VAL_UNKNOWN", 10));
693
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700694 setenv("INT_VAL3", "4294967295", 1);
695 EXPECT_EQ(1, Uint32FromEnv("INT_VAL1", 10));
696 EXPECT_EQ(4294967295L, Uint32FromEnv("INT_VAL3", 30));
697 EXPECT_EQ(10, Uint32FromEnv("INT_VAL_UNKNOWN", 10));
698
699 setenv("INT_VAL4", "1099511627776", 1);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000700 EXPECT_EQ(1, Int64FromEnv("INT_VAL1", 20));
701 EXPECT_EQ(-1, Int64FromEnv("INT_VAL2", 20));
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700702 EXPECT_EQ(1099511627776LL, Int64FromEnv("INT_VAL4", 20));
Craig Silversteinb9f23482007-03-22 00:15:41 +0000703 EXPECT_EQ(20, Int64FromEnv("INT_VAL_UNKNOWN", 20));
704
705 EXPECT_EQ(1, Uint64FromEnv("INT_VAL1", 30));
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700706 EXPECT_EQ(1099511627776ULL, Uint64FromEnv("INT_VAL4", 30));
Craig Silversteinb9f23482007-03-22 00:15:41 +0000707 EXPECT_EQ(30, Uint64FromEnv("INT_VAL_UNKNOWN", 30));
708
709 // I pick values here that can be easily represented exactly in floating-point
710 setenv("DOUBLE_VAL1", "0.0", 1);
711 setenv("DOUBLE_VAL2", "1.0", 1);
712 setenv("DOUBLE_VAL3", "-1.0", 1);
713 EXPECT_EQ(0.0, DoubleFromEnv("DOUBLE_VAL1", 40.0));
714 EXPECT_EQ(1.0, DoubleFromEnv("DOUBLE_VAL2", 40.0));
715 EXPECT_EQ(-1.0, DoubleFromEnv("DOUBLE_VAL3", 40.0));
716 EXPECT_EQ(40.0, DoubleFromEnv("DOUBLE_VAL_UNKNOWN", 40.0));
717
718 setenv("STRING_VAL1", "", 1);
719 setenv("STRING_VAL2", "my happy string!", 1);
720 EXPECT_STREQ("", StringFromEnv("STRING_VAL1", "unknown"));
721 EXPECT_STREQ("my happy string!", StringFromEnv("STRING_VAL2", "unknown"));
722 EXPECT_STREQ("unknown", StringFromEnv("STRING_VAL_UNKNOWN", "unknown"));
723}
724
Craig Silverstein917f4e72011-07-29 04:26:49 +0000725#ifdef GTEST_HAS_DEATH_TEST
Craig Silversteinb9f23482007-03-22 00:15:41 +0000726// Tests that the FooFromEnv dies on parse-error
Craig Silversteine0b71e52008-09-19 19:32:05 +0000727TEST(FromEnvDeathTest, IllegalValues) {
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000728 setenv("BOOL_BAD1", "so true!", 1);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000729 setenv("BOOL_BAD2", "", 1);
730 EXPECT_DEATH(BoolFromEnv("BOOL_BAD1", false), "error parsing env variable");
731 EXPECT_DEATH(BoolFromEnv("BOOL_BAD2", true), "error parsing env variable");
732
733 setenv("INT_BAD1", "one", 1);
734 setenv("INT_BAD2", "100000000000000000", 1);
735 setenv("INT_BAD3", "0xx10", 1);
736 setenv("INT_BAD4", "", 1);
737 EXPECT_DEATH(Int32FromEnv("INT_BAD1", 10), "error parsing env variable");
738 EXPECT_DEATH(Int32FromEnv("INT_BAD2", 10), "error parsing env variable");
739 EXPECT_DEATH(Int32FromEnv("INT_BAD3", 10), "error parsing env variable");
740 EXPECT_DEATH(Int32FromEnv("INT_BAD4", 10), "error parsing env variable");
741
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700742 EXPECT_DEATH(Uint32FromEnv("INT_BAD1", 10), "error parsing env variable");
743 EXPECT_DEATH(Uint32FromEnv("INT_BAD2", 10), "error parsing env variable");
744 EXPECT_DEATH(Uint32FromEnv("INT_BAD3", 10), "error parsing env variable");
745 EXPECT_DEATH(Uint32FromEnv("INT_BAD4", 10), "error parsing env variable");
746
Craig Silversteinb9f23482007-03-22 00:15:41 +0000747 setenv("BIGINT_BAD1", "18446744073709551616000", 1);
748 EXPECT_DEATH(Int64FromEnv("INT_BAD1", 20), "error parsing env variable");
749 EXPECT_DEATH(Int64FromEnv("INT_BAD3", 20), "error parsing env variable");
750 EXPECT_DEATH(Int64FromEnv("INT_BAD4", 20), "error parsing env variable");
751 EXPECT_DEATH(Int64FromEnv("BIGINT_BAD1", 200), "error parsing env variable");
752
753 setenv("BIGINT_BAD2", "-1", 1);
754 EXPECT_DEATH(Uint64FromEnv("INT_BAD1", 30), "error parsing env variable");
755 EXPECT_DEATH(Uint64FromEnv("INT_BAD3", 30), "error parsing env variable");
756 EXPECT_DEATH(Uint64FromEnv("INT_BAD4", 30), "error parsing env variable");
757 EXPECT_DEATH(Uint64FromEnv("BIGINT_BAD1", 30), "error parsing env variable");
758 // TODO(csilvers): uncomment this when we disallow negative numbers for uint64
759#if 0
760 EXPECT_DEATH(Uint64FromEnv("BIGINT_BAD2", 30), "error parsing env variable");
761#endif
762
763 setenv("DOUBLE_BAD1", "0.0.0", 1);
764 setenv("DOUBLE_BAD2", "", 1);
765 EXPECT_DEATH(DoubleFromEnv("DOUBLE_BAD1", 40.0), "error parsing env variable");
766 EXPECT_DEATH(DoubleFromEnv("DOUBLE_BAD2", 40.0), "error parsing env variable");
767}
Craig Silverstein917f4e72011-07-29 04:26:49 +0000768#endif
769
Craig Silversteinb9f23482007-03-22 00:15:41 +0000770
771// Tests that FlagSaver can save the states of string flags.
772TEST(FlagSaverTest, CanSaveStringFlagStates) {
773 // 1. Initializes the flags.
774
775 // State of flag test_str1:
776 // default value - "initial"
777 // current value - "initial"
778 // not set - true
779
780 SetCommandLineOptionWithMode("test_str2", "second", SET_FLAGS_VALUE);
781 // State of flag test_str2:
782 // default value - "initial"
783 // current value - "second"
784 // not set - false
785
786 SetCommandLineOptionWithMode("test_str3", "second", SET_FLAGS_DEFAULT);
787 // State of flag test_str3:
788 // default value - "second"
789 // current value - "second"
790 // not set - true
791
792 // 2. Saves the flag states.
793
794 {
795 FlagSaver fs;
796
797 // 3. Modifies the flag states.
798
799 SetCommandLineOptionWithMode("test_str1", "second", SET_FLAGS_VALUE);
800 EXPECT_EQ("second", FLAGS_test_str1);
801 // State of flag test_str1:
802 // default value - "second"
803 // current value - "second"
804 // not set - true
805
806 SetCommandLineOptionWithMode("test_str2", "third", SET_FLAGS_DEFAULT);
807 EXPECT_EQ("second", FLAGS_test_str2);
808 // State of flag test_str2:
809 // default value - "third"
810 // current value - "second"
811 // not set - false
812
813 SetCommandLineOptionWithMode("test_str3", "third", SET_FLAGS_VALUE);
814 EXPECT_EQ("third", FLAGS_test_str3);
815 // State of flag test_str1:
816 // default value - "second"
817 // current value - "third"
818 // not set - false
819
820 // 4. Restores the flag states.
821 }
822
823 // 5. Verifies that the states were restored.
824
825 // Verifies that the value of test_str1 was restored.
826 EXPECT_EQ("initial", FLAGS_test_str1);
827 // Verifies that the "not set" attribute of test_str1 was restored to true.
828 SetCommandLineOptionWithMode("test_str1", "second", SET_FLAG_IF_DEFAULT);
829 EXPECT_EQ("second", FLAGS_test_str1);
830
831 // Verifies that the value of test_str2 was restored.
832 EXPECT_EQ("second", FLAGS_test_str2);
833 // Verifies that the "not set" attribute of test_str2 was restored to false.
834 SetCommandLineOptionWithMode("test_str2", "fourth", SET_FLAG_IF_DEFAULT);
835 EXPECT_EQ("second", FLAGS_test_str2);
836
837 // Verifies that the value of test_str3 was restored.
838 EXPECT_EQ("second", FLAGS_test_str3);
839 // Verifies that the "not set" attribute of test_str3 was restored to true.
840 SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAG_IF_DEFAULT);
841 EXPECT_EQ("fourth", FLAGS_test_str3);
842}
843
844
845// Tests that FlagSaver can save the values of various-typed flags.
846TEST(FlagSaverTest, CanSaveVariousTypedFlagValues) {
847 // Initializes the flags.
848 FLAGS_test_bool = false;
849 FLAGS_test_int32 = -1;
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700850 FLAGS_test_uint32 = 2;
851 FLAGS_test_int64 = -3;
852 FLAGS_test_uint64 = 4;
853 FLAGS_test_double = 5.0;
Craig Silversteinb9f23482007-03-22 00:15:41 +0000854 FLAGS_test_string = "good";
855
856 // Saves the flag states.
857 {
858 FlagSaver fs;
859
860 // Modifies the flags.
861 FLAGS_test_bool = true;
862 FLAGS_test_int32 = -5;
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700863 FLAGS_test_uint32 = 6;
864 FLAGS_test_int64 = -7;
865 FLAGS_test_uint64 = 8;
Craig Silversteinb9f23482007-03-22 00:15:41 +0000866 FLAGS_test_double = 8.0;
867 FLAGS_test_string = "bad";
868
869 // Restores the flag states.
870 }
871
872 // Verifies the flag values were restored.
873 EXPECT_FALSE(FLAGS_test_bool);
874 EXPECT_EQ(-1, FLAGS_test_int32);
Allan L. Bazineteaf05342016-04-05 10:50:21 -0700875 EXPECT_EQ(2, FLAGS_test_uint32);
876 EXPECT_EQ(-3, FLAGS_test_int64);
877 EXPECT_EQ(4, FLAGS_test_uint64);
dreamer.deadfa266382016-07-20 12:18:08 +0300878 EXPECT_DOUBLE_EQ(5.0, FLAGS_test_double);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000879 EXPECT_EQ("good", FLAGS_test_string);
880}
881
882TEST(GetAllFlagsTest, BaseTest) {
883 vector<CommandLineFlagInfo> flags;
884 GetAllFlags(&flags);
885 bool found_test_bool = false;
886 vector<CommandLineFlagInfo>::const_iterator i;
887 for (i = flags.begin(); i != flags.end(); ++i) {
888 if (i->name == "test_bool") {
889 found_test_bool = true;
890 EXPECT_EQ(i->type, "bool");
891 EXPECT_EQ(i->default_value, "false");
Craig Silverstein17a627a2011-11-03 23:18:00 +0000892 EXPECT_EQ(i->flag_ptr, &FLAGS_test_bool);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000893 break;
894 }
895 }
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000896 EXPECT_TRUE(found_test_bool);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000897}
898
899TEST(ShowUsageWithFlagsTest, BaseTest) {
900 // TODO(csilvers): test this by allowing output other than to stdout.
901 // Not urgent since this functionality is tested via
902 // gflags_unittest.sh, though only through use of --help.
903}
904
905TEST(ShowUsageWithFlagsRestrictTest, BaseTest) {
906 // TODO(csilvers): test this by allowing output other than to stdout.
907 // Not urgent since this functionality is tested via
908 // gflags_unittest.sh, though only through use of --helpmatch.
909}
910
911// Note: all these argv-based tests depend on SetArgv being called
Craig Silverstein917f4e72011-07-29 04:26:49 +0000912// before ParseCommandLineFlags() in main(), below.
Craig Silversteinb9f23482007-03-22 00:15:41 +0000913TEST(GetArgvsTest, BaseTest) {
914 vector<string> argvs = GetArgvs();
915 EXPECT_EQ(4, argvs.size());
916 EXPECT_EQ("/test/argv/for/gflags_unittest", argvs[0]);
917 EXPECT_EQ("argv 2", argvs[1]);
918 EXPECT_EQ("3rd argv", argvs[2]);
919 EXPECT_EQ("argv #4", argvs[3]);
920}
921
922TEST(GetArgvTest, BaseTest) {
923 EXPECT_STREQ("/test/argv/for/gflags_unittest "
924 "argv 2 3rd argv argv #4", GetArgv());
925}
926
927TEST(GetArgv0Test, BaseTest) {
928 EXPECT_STREQ("/test/argv/for/gflags_unittest", GetArgv0());
929}
930
931TEST(GetArgvSumTest, BaseTest) {
932 // This number is just the sum of the ASCII values of all the chars
933 // in GetArgv().
934 EXPECT_EQ(4904, GetArgvSum());
935}
936
937TEST(ProgramInvocationNameTest, BaseTest) {
938 EXPECT_STREQ("/test/argv/for/gflags_unittest",
939 ProgramInvocationName());
940}
941
942TEST(ProgramInvocationShortNameTest, BaseTest) {
943 EXPECT_STREQ("gflags_unittest", ProgramInvocationShortName());
944}
945
Craig Silverstein917f4e72011-07-29 04:26:49 +0000946TEST(ProgramUsageTest, BaseTest) { // Depends on 1st arg to ParseCommandLineFlags()
Craig Silversteinb9f23482007-03-22 00:15:41 +0000947 EXPECT_STREQ("/test/argv/for/gflags_unittest: "
948 "<useless flag> [...]\nDoes something useless.\n",
949 ProgramUsage());
950}
951
952TEST(GetCommandLineOptionTest, NameExistsAndIsDefault) {
953 string value("will be changed");
Craig Silverstein690172b2007-04-20 21:16:33 +0000954 bool r = GetCommandLineOption("test_bool", &value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000955 EXPECT_TRUE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000956 EXPECT_EQ("false", value);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000957
Craig Silverstein690172b2007-04-20 21:16:33 +0000958 r = GetCommandLineOption("test_int32", &value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000959 EXPECT_TRUE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000960 EXPECT_EQ("-1", value);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000961}
962
963TEST(GetCommandLineOptionTest, NameExistsAndWasAssigned) {
964 FLAGS_test_int32 = 400;
965 string value("will be changed");
Craig Silverstein690172b2007-04-20 21:16:33 +0000966 const bool r = GetCommandLineOption("test_int32", &value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000967 EXPECT_TRUE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000968 EXPECT_EQ("400", value);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000969}
970
971TEST(GetCommandLineOptionTest, NameExistsAndWasSet) {
972 SetCommandLineOption("test_int32", "700");
973 string value("will be changed");
Craig Silverstein690172b2007-04-20 21:16:33 +0000974 const bool r = GetCommandLineOption("test_int32", &value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000975 EXPECT_TRUE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000976 EXPECT_EQ("700", value);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000977}
978
979TEST(GetCommandLineOptionTest, NameExistsAndWasNotSet) {
980 // This doesn't set the flag's value, but rather its default value.
981 // is_default is still true, but the 'default' value returned has changed!
982 SetCommandLineOptionWithMode("test_int32", "800", SET_FLAGS_DEFAULT);
983 string value("will be changed");
Craig Silverstein690172b2007-04-20 21:16:33 +0000984 const bool r = GetCommandLineOption("test_int32", &value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000985 EXPECT_TRUE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000986 EXPECT_EQ("800", value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000987 EXPECT_TRUE(GetCommandLineFlagInfoOrDie("test_int32").is_default);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000988}
989
990TEST(GetCommandLineOptionTest, NameExistsAndWasConditionallySet) {
991 SetCommandLineOptionWithMode("test_int32", "900", SET_FLAG_IF_DEFAULT);
992 string value("will be changed");
Craig Silverstein690172b2007-04-20 21:16:33 +0000993 const bool r = GetCommandLineOption("test_int32", &value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +0000994 EXPECT_TRUE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000995 EXPECT_EQ("900", value);
Craig Silversteinb9f23482007-03-22 00:15:41 +0000996}
997
998TEST(GetCommandLineOptionTest, NameDoesNotExist) {
999 string value("will not be changed");
Craig Silverstein690172b2007-04-20 21:16:33 +00001000 const bool r = GetCommandLineOption("test_int3210", &value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001001 EXPECT_FALSE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001002 EXPECT_EQ("will not be changed", value);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001003}
1004
1005TEST(GetCommandLineFlagInfoTest, FlagExists) {
1006 CommandLineFlagInfo info;
1007 bool r = GetCommandLineFlagInfo("test_int32", &info);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001008 EXPECT_TRUE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001009 EXPECT_EQ("test_int32", info.name);
1010 EXPECT_EQ("int32", info.type);
1011 EXPECT_EQ("", info.description);
Craig Silverstein690172b2007-04-20 21:16:33 +00001012 EXPECT_EQ("-1", info.current_value);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001013 EXPECT_EQ("-1", info.default_value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001014 EXPECT_TRUE(info.is_default);
1015 EXPECT_FALSE(info.has_validator_fn);
Craig Silverstein17a627a2011-11-03 23:18:00 +00001016 EXPECT_EQ(&FLAGS_test_int32, info.flag_ptr);
Craig Silverstein690172b2007-04-20 21:16:33 +00001017
1018 FLAGS_test_bool = true;
Craig Silversteinb9f23482007-03-22 00:15:41 +00001019 r = GetCommandLineFlagInfo("test_bool", &info);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001020 EXPECT_TRUE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001021 EXPECT_EQ("test_bool", info.name);
1022 EXPECT_EQ("bool", info.type);
1023 EXPECT_EQ("tests bool-ness", info.description);
Craig Silverstein690172b2007-04-20 21:16:33 +00001024 EXPECT_EQ("true", info.current_value);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001025 EXPECT_EQ("false", info.default_value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001026 EXPECT_FALSE(info.is_default);
1027 EXPECT_FALSE(info.has_validator_fn);
Craig Silverstein17a627a2011-11-03 23:18:00 +00001028 EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
Craig Silverstein690172b2007-04-20 21:16:33 +00001029
1030 FLAGS_test_bool = false;
1031 r = GetCommandLineFlagInfo("test_bool", &info);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001032 EXPECT_TRUE(r);
Craig Silverstein690172b2007-04-20 21:16:33 +00001033 EXPECT_EQ("test_bool", info.name);
1034 EXPECT_EQ("bool", info.type);
1035 EXPECT_EQ("tests bool-ness", info.description);
1036 EXPECT_EQ("false", info.current_value);
1037 EXPECT_EQ("false", info.default_value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001038 EXPECT_FALSE(info.is_default); // value is same, but flag *was* modified
1039 EXPECT_FALSE(info.has_validator_fn);
Craig Silverstein17a627a2011-11-03 23:18:00 +00001040 EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001041}
1042
1043TEST(GetCommandLineFlagInfoTest, FlagDoesNotExist) {
1044 CommandLineFlagInfo info;
Craig Silverstein690172b2007-04-20 21:16:33 +00001045 // Set to some random values that GetCommandLineFlagInfo should not change
1046 info.name = "name";
1047 info.type = "type";
1048 info.current_value = "curr";
1049 info.default_value = "def";
1050 info.filename = "/";
1051 info.is_default = false;
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001052 info.has_validator_fn = true;
Craig Silverstein17a627a2011-11-03 23:18:00 +00001053 info.flag_ptr = NULL;
Craig Silversteinb9f23482007-03-22 00:15:41 +00001054 bool r = GetCommandLineFlagInfo("test_int3210", &info);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001055 EXPECT_FALSE(r);
Craig Silverstein690172b2007-04-20 21:16:33 +00001056 EXPECT_EQ("name", info.name);
1057 EXPECT_EQ("type", info.type);
1058 EXPECT_EQ("", info.description);
1059 EXPECT_EQ("curr", info.current_value);
1060 EXPECT_EQ("def", info.default_value);
1061 EXPECT_EQ("/", info.filename);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001062 EXPECT_FALSE(info.is_default);
1063 EXPECT_TRUE(info.has_validator_fn);
Craig Silverstein17a627a2011-11-03 23:18:00 +00001064 EXPECT_EQ(NULL, info.flag_ptr);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001065}
1066
Craig Silverstein290da382007-03-28 21:54:07 +00001067TEST(GetCommandLineFlagInfoOrDieTest, FlagExistsAndIsDefault) {
1068 CommandLineFlagInfo info;
1069 info = GetCommandLineFlagInfoOrDie("test_int32");
1070 EXPECT_EQ("test_int32", info.name);
1071 EXPECT_EQ("int32", info.type);
1072 EXPECT_EQ("", info.description);
Craig Silverstein690172b2007-04-20 21:16:33 +00001073 EXPECT_EQ("-1", info.current_value);
Craig Silverstein290da382007-03-28 21:54:07 +00001074 EXPECT_EQ("-1", info.default_value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001075 EXPECT_TRUE(info.is_default);
Craig Silverstein17a627a2011-11-03 23:18:00 +00001076 EXPECT_EQ(&FLAGS_test_int32, info.flag_ptr);
Craig Silverstein290da382007-03-28 21:54:07 +00001077 info = GetCommandLineFlagInfoOrDie("test_bool");
1078 EXPECT_EQ("test_bool", info.name);
1079 EXPECT_EQ("bool", info.type);
1080 EXPECT_EQ("tests bool-ness", info.description);
Craig Silverstein690172b2007-04-20 21:16:33 +00001081 EXPECT_EQ("false", info.current_value);
Craig Silverstein290da382007-03-28 21:54:07 +00001082 EXPECT_EQ("false", info.default_value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001083 EXPECT_TRUE(info.is_default);
1084 EXPECT_FALSE(info.has_validator_fn);
Craig Silverstein17a627a2011-11-03 23:18:00 +00001085 EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
Craig Silverstein290da382007-03-28 21:54:07 +00001086}
1087
1088TEST(GetCommandLineFlagInfoOrDieTest, FlagExistsAndWasAssigned) {
1089 FLAGS_test_int32 = 400;
1090 CommandLineFlagInfo info;
1091 info = GetCommandLineFlagInfoOrDie("test_int32");
1092 EXPECT_EQ("test_int32", info.name);
1093 EXPECT_EQ("int32", info.type);
1094 EXPECT_EQ("", info.description);
Craig Silverstein690172b2007-04-20 21:16:33 +00001095 EXPECT_EQ("400", info.current_value);
Craig Silverstein290da382007-03-28 21:54:07 +00001096 EXPECT_EQ("-1", info.default_value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001097 EXPECT_FALSE(info.is_default);
Craig Silverstein17a627a2011-11-03 23:18:00 +00001098 EXPECT_EQ(&FLAGS_test_int32, info.flag_ptr);
Craig Silverstein290da382007-03-28 21:54:07 +00001099 FLAGS_test_bool = true;
1100 info = GetCommandLineFlagInfoOrDie("test_bool");
1101 EXPECT_EQ("test_bool", info.name);
1102 EXPECT_EQ("bool", info.type);
1103 EXPECT_EQ("tests bool-ness", info.description);
Craig Silverstein690172b2007-04-20 21:16:33 +00001104 EXPECT_EQ("true", info.current_value);
Craig Silverstein290da382007-03-28 21:54:07 +00001105 EXPECT_EQ("false", info.default_value);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001106 EXPECT_FALSE(info.is_default);
1107 EXPECT_FALSE(info.has_validator_fn);
Craig Silverstein17a627a2011-11-03 23:18:00 +00001108 EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
Craig Silverstein290da382007-03-28 21:54:07 +00001109}
1110
Craig Silverstein917f4e72011-07-29 04:26:49 +00001111#ifdef GTEST_HAS_DEATH_TEST
Craig Silversteine0b71e52008-09-19 19:32:05 +00001112TEST(GetCommandLineFlagInfoOrDieDeathTest, FlagDoesNotExist) {
Craig Silverstein290da382007-03-28 21:54:07 +00001113 EXPECT_DEATH(GetCommandLineFlagInfoOrDie("test_int3210"),
1114 ".*: flag test_int3210 does not exist");
1115}
Craig Silverstein917f4e72011-07-29 04:26:49 +00001116#endif
Craig Silverstein290da382007-03-28 21:54:07 +00001117
Craig Silversteinb9f23482007-03-22 00:15:41 +00001118
1119// These are lightly tested because they're deprecated. Basically,
1120// the tests are meant to cover how existing users use these functions,
1121// but not necessarily how new users could use them.
1122TEST(DeprecatedFunctionsTest, CommandlineFlagsIntoString) {
1123 string s = CommandlineFlagsIntoString();
1124 EXPECT_NE(string::npos, s.find("--test_bool="));
1125}
1126
1127TEST(DeprecatedFunctionsTest, AppendFlagsIntoFile) {
1128 FLAGS_test_int32 = 10; // just to make the test more interesting
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001129 string filename(TmpFile("flagfile"));
Craig Silversteinb9f23482007-03-22 00:15:41 +00001130 unlink(filename.c_str()); // just to be safe
1131 const bool r = AppendFlagsIntoFile(filename, "not the real argv0");
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001132 EXPECT_TRUE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001133
Andreas Schuh8d3797c2014-03-17 21:19:35 +00001134 FILE* fp;
1135 EXPECT_EQ(0, SafeFOpen(&fp, filename.c_str(), "r"));
Craig Silversteinb9f23482007-03-22 00:15:41 +00001136 EXPECT_TRUE(fp != NULL);
1137 char line[8192];
Craig Silverstein24b4c592011-01-25 00:36:41 +00001138 EXPECT_TRUE(fgets(line, sizeof(line)-1, fp) != NULL); // get the first line
1139 // First line should be progname.
Craig Silversteinb9f23482007-03-22 00:15:41 +00001140 EXPECT_STREQ("not the real argv0\n", line);
1141
1142 bool found_bool = false, found_int32 = false;
1143 while (fgets(line, sizeof(line)-1, fp)) {
1144 line[sizeof(line)-1] = '\0'; // just to be safe
1145 if (strcmp(line, "--test_bool=false\n") == 0)
1146 found_bool = true;
1147 if (strcmp(line, "--test_int32=10\n") == 0)
1148 found_int32 = true;
1149 }
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001150 EXPECT_TRUE(found_int32);
1151 EXPECT_TRUE(found_bool);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001152 fclose(fp);
1153}
1154
1155TEST(DeprecatedFunctionsTest, ReadFromFlagsFile) {
1156 FLAGS_test_int32 = -10; // just to make the test more interesting
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001157 string filename(TmpFile("flagfile2"));
Craig Silversteinb9f23482007-03-22 00:15:41 +00001158 unlink(filename.c_str()); // just to be safe
1159 bool r = AppendFlagsIntoFile(filename, GetArgv0());
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001160 EXPECT_TRUE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001161
1162 FLAGS_test_int32 = -11;
1163 r = ReadFromFlagsFile(filename, GetArgv0(), true);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001164 EXPECT_TRUE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001165 EXPECT_EQ(-10, FLAGS_test_int32);
Craig Silverstein917f4e72011-07-29 04:26:49 +00001166} // unnamed namespace
Craig Silversteinb9f23482007-03-22 00:15:41 +00001167
1168TEST(DeprecatedFunctionsTest, ReadFromFlagsFileFailure) {
1169 FLAGS_test_int32 = -20;
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001170 string filename(TmpFile("flagfile3"));
Andreas Schuh8d3797c2014-03-17 21:19:35 +00001171 FILE* fp;
1172 EXPECT_EQ(0, SafeFOpen(&fp, filename.c_str(), "w"));
Craig Silversteinb9f23482007-03-22 00:15:41 +00001173 EXPECT_TRUE(fp != NULL);
1174 // Note the error in the bool assignment below...
1175 fprintf(fp, "%s\n--test_int32=-21\n--test_bool=not_a_bool!\n", GetArgv0());
1176 fclose(fp);
1177
1178 FLAGS_test_int32 = -22;
1179 const bool r = ReadFromFlagsFile(filename, GetArgv0(), false);
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001180 EXPECT_FALSE(r);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001181 EXPECT_EQ(-22, FLAGS_test_int32); // the -21 from the flagsfile didn't take
1182}
1183
Craig Silverstein0baf4ab2011-01-14 21:58:28 +00001184TEST(FlagsSetBeforeInitTest, TryFromEnv) {
Craig Silversteinb9f23482007-03-22 00:15:41 +00001185 EXPECT_EQ("pre-set", FLAGS_test_tryfromenv);
1186}
1187
Craig Silversteineb208392007-08-15 19:44:54 +00001188// The following test case verifies that ParseCommandLineFlags() and
1189// ParseCommandLineNonHelpFlags() uses the last definition of a flag
1190// in case it's defined more than once.
1191
Craig Silverstein917f4e72011-07-29 04:26:49 +00001192DEFINE_int32(test_flag, -1, "used for testing gflags.cc");
Craig Silversteineb208392007-08-15 19:44:54 +00001193
Craig Silversteineb208392007-08-15 19:44:54 +00001194// Parses and returns the --test_flag flag.
1195// If with_help is true, calls ParseCommandLineFlags; otherwise calls
1196// ParseCommandLineNonHelpFlags.
1197int32 ParseTestFlag(bool with_help, int argc, const char** const_argv) {
1198 FlagSaver fs; // Restores the flags before returning.
1199
1200 // Makes a copy of the input array s.t. it can be reused
1201 // (ParseCommandLineFlags() will alter the array).
1202 char** const argv_save = new char*[argc + 1];
1203 char** argv = argv_save;
1204 memcpy(argv, const_argv, sizeof(*argv)*(argc + 1));
1205
1206 if (with_help) {
1207 ParseCommandLineFlags(&argc, &argv, true);
1208 } else {
1209 ParseCommandLineNonHelpFlags(&argc, &argv, true);
1210 }
1211
1212 delete[] argv_save;
1213 return FLAGS_test_flag;
1214}
1215
1216TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
1217 WhenFlagIsDefinedTwiceOnCommandLine) {
1218 const char* argv[] = {
1219 "my_test",
1220 "--test_flag=1",
1221 "--test_flag=2",
1222 NULL,
1223 };
1224
Craig Silverstein917f4e72011-07-29 04:26:49 +00001225 EXPECT_EQ(2, ParseTestFlag(true, arraysize(argv) - 1, argv));
1226 EXPECT_EQ(2, ParseTestFlag(false, arraysize(argv) - 1, argv));
Craig Silversteineb208392007-08-15 19:44:54 +00001227}
1228
1229TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
1230 WhenFlagIsDefinedTwiceInFlagFile) {
1231 const char* argv[] = {
1232 "my_test",
1233 GetFlagFileFlag(),
1234 NULL,
1235 };
1236
Craig Silverstein917f4e72011-07-29 04:26:49 +00001237 EXPECT_EQ(2, ParseTestFlag(true, arraysize(argv) - 1, argv));
1238 EXPECT_EQ(2, ParseTestFlag(false, arraysize(argv) - 1, argv));
Craig Silversteineb208392007-08-15 19:44:54 +00001239}
1240
1241TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
1242 WhenFlagIsDefinedInCommandLineAndThenFlagFile) {
1243 const char* argv[] = {
1244 "my_test",
1245 "--test_flag=0",
1246 GetFlagFileFlag(),
1247 NULL,
1248 };
1249
Craig Silverstein917f4e72011-07-29 04:26:49 +00001250 EXPECT_EQ(2, ParseTestFlag(true, arraysize(argv) - 1, argv));
1251 EXPECT_EQ(2, ParseTestFlag(false, arraysize(argv) - 1, argv));
Craig Silversteineb208392007-08-15 19:44:54 +00001252}
1253
1254TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
1255 WhenFlagIsDefinedInFlagFileAndThenCommandLine) {
1256 const char* argv[] = {
1257 "my_test",
1258 GetFlagFileFlag(),
1259 "--test_flag=3",
1260 NULL,
1261 };
1262
Craig Silverstein917f4e72011-07-29 04:26:49 +00001263 EXPECT_EQ(3, ParseTestFlag(true, arraysize(argv) - 1, argv));
1264 EXPECT_EQ(3, ParseTestFlag(false, arraysize(argv) - 1, argv));
Craig Silversteineb208392007-08-15 19:44:54 +00001265}
1266
1267TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
1268 WhenFlagIsDefinedInCommandLineAndFlagFileAndThenCommandLine) {
1269 const char* argv[] = {
1270 "my_test",
1271 "--test_flag=0",
1272 GetFlagFileFlag(),
1273 "--test_flag=3",
1274 NULL,
1275 };
1276
Craig Silverstein917f4e72011-07-29 04:26:49 +00001277 EXPECT_EQ(3, ParseTestFlag(true, arraysize(argv) - 1, argv));
1278 EXPECT_EQ(3, ParseTestFlag(false, arraysize(argv) - 1, argv));
Craig Silversteineb208392007-08-15 19:44:54 +00001279}
1280
Craig Silverstein83911c12008-03-27 20:11:07 +00001281TEST(ParseCommandLineFlagsAndDashArgs, TwoDashArgFirst) {
1282 const char* argv[] = {
1283 "my_test",
1284 "--",
1285 "--test_flag=0",
1286 NULL,
1287 };
1288
Craig Silverstein917f4e72011-07-29 04:26:49 +00001289 EXPECT_EQ(-1, ParseTestFlag(true, arraysize(argv) - 1, argv));
1290 EXPECT_EQ(-1, ParseTestFlag(false, arraysize(argv) - 1, argv));
Craig Silverstein83911c12008-03-27 20:11:07 +00001291}
1292
1293TEST(ParseCommandLineFlagsAndDashArgs, TwoDashArgMiddle) {
1294 const char* argv[] = {
1295 "my_test",
1296 "--test_flag=7",
1297 "--",
1298 "--test_flag=0",
1299 NULL,
1300 };
1301
Craig Silverstein917f4e72011-07-29 04:26:49 +00001302 EXPECT_EQ(7, ParseTestFlag(true, arraysize(argv) - 1, argv));
1303 EXPECT_EQ(7, ParseTestFlag(false, arraysize(argv) - 1, argv));
Craig Silverstein83911c12008-03-27 20:11:07 +00001304}
1305
1306TEST(ParseCommandLineFlagsAndDashArgs, OneDashArg) {
1307 const char* argv[] = {
1308 "my_test",
1309 "-",
1310 "--test_flag=0",
1311 NULL,
1312 };
1313
Craig Silverstein917f4e72011-07-29 04:26:49 +00001314 EXPECT_EQ(0, ParseTestFlag(true, arraysize(argv) - 1, argv));
1315 EXPECT_EQ(0, ParseTestFlag(false, arraysize(argv) - 1, argv));
Craig Silverstein83911c12008-03-27 20:11:07 +00001316}
1317
Craig Silverstein917f4e72011-07-29 04:26:49 +00001318#ifdef GTEST_HAS_DEATH_TEST
Craig Silversteine0b71e52008-09-19 19:32:05 +00001319TEST(ParseCommandLineFlagsUnknownFlagDeathTest,
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001320 FlagIsCompletelyUnknown) {
1321 const char* argv[] = {
1322 "my_test",
1323 "--this_flag_does_not_exist",
1324 NULL,
1325 };
1326
Craig Silverstein917f4e72011-07-29 04:26:49 +00001327 EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001328 "unknown command line flag.*");
Craig Silverstein917f4e72011-07-29 04:26:49 +00001329 EXPECT_DEATH(ParseTestFlag(false, arraysize(argv) - 1, argv),
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001330 "unknown command line flag.*");
1331}
1332
Craig Silversteine0b71e52008-09-19 19:32:05 +00001333TEST(ParseCommandLineFlagsUnknownFlagDeathTest,
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001334 BoolFlagIsCompletelyUnknown) {
1335 const char* argv[] = {
1336 "my_test",
1337 "--nothis_flag_does_not_exist",
1338 NULL,
1339 };
1340
Craig Silverstein917f4e72011-07-29 04:26:49 +00001341 EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001342 "unknown command line flag.*");
Craig Silverstein917f4e72011-07-29 04:26:49 +00001343 EXPECT_DEATH(ParseTestFlag(false, arraysize(argv) - 1, argv),
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001344 "unknown command line flag.*");
1345}
1346
Craig Silversteine0b71e52008-09-19 19:32:05 +00001347TEST(ParseCommandLineFlagsUnknownFlagDeathTest,
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001348 FlagIsNotABool) {
1349 const char* argv[] = {
1350 "my_test",
1351 "--notest_string",
1352 NULL,
1353 };
1354
Craig Silverstein917f4e72011-07-29 04:26:49 +00001355 EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001356 "boolean value .* specified for .* command line flag");
Craig Silverstein917f4e72011-07-29 04:26:49 +00001357 EXPECT_DEATH(ParseTestFlag(false, arraysize(argv) - 1, argv),
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001358 "boolean value .* specified for .* command line flag");
1359}
Craig Silverstein917f4e72011-07-29 04:26:49 +00001360#endif
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001361
1362TEST(ParseCommandLineFlagsWrongFields,
1363 DescriptionIsInvalid) {
1364 // These must not be automatic variables, since command line flags
1365 // aren't unregistered and gUnit uses FlagSaver to save and restore
1366 // command line flags' values. If these are on the stack, then when
1367 // later tests attempt to save and restore their values, the stack
1368 // addresses of these variables will be overwritten... Stack smash!
1369 static bool current_storage;
1370 static bool defvalue_storage;
dreamer.dead46ea10f2016-07-29 21:02:29 +03001371 FlagRegisterer fr("flag_name", NULL, "filename",
Craig Silversteinc23c6c62011-11-03 23:25:32 +00001372 &current_storage, &defvalue_storage);
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001373 CommandLineFlagInfo fi;
1374 EXPECT_TRUE(GetCommandLineFlagInfo("flag_name", &fi));
1375 EXPECT_EQ("", fi.description);
Craig Silverstein17a627a2011-11-03 23:18:00 +00001376 EXPECT_EQ(&current_storage, fi.flag_ptr);
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001377}
1378
1379static bool ValidateTestFlagIs5(const char* flagname, int32 flagval) {
1380 if (flagval == 5)
1381 return true;
1382 printf("%s isn't 5!\n", flagname);
1383 return false;
1384}
1385
1386static bool ValidateTestFlagIs10(const char* flagname, int32 flagval) {
1387 return flagval == 10;
1388}
1389
1390
1391TEST(FlagsValidator, ValidFlagViaArgv) {
1392 const char* argv[] = {
1393 "my_test",
1394 "--test_flag=5",
1395 NULL,
1396 };
1397 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
Craig Silverstein917f4e72011-07-29 04:26:49 +00001398 EXPECT_EQ(5, ParseTestFlag(true, arraysize(argv) - 1, argv));
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001399 // Undo the flag validator setting
1400 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1401}
1402
1403TEST(FlagsValidator, ValidFlagViaSetDefault) {
1404 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1405 // SetCommandLineOptionWithMode returns the empty string on error.
1406 EXPECT_NE("", SetCommandLineOptionWithMode("test_flag", "5",
1407 SET_FLAG_IF_DEFAULT));
1408 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1409}
1410
1411TEST(FlagsValidator, ValidFlagViaSetValue) {
1412 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1413 FLAGS_test_flag = 100; // doesn't trigger the validator
1414 // SetCommandLineOptionWithMode returns the empty string on error.
1415 EXPECT_NE("", SetCommandLineOptionWithMode("test_flag", "5",
1416 SET_FLAGS_VALUE));
1417 EXPECT_NE("", SetCommandLineOptionWithMode("test_flag", "5",
1418 SET_FLAGS_DEFAULT));
1419 EXPECT_NE("", SetCommandLineOption("test_flag", "5"));
1420 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1421}
1422
Craig Silverstein917f4e72011-07-29 04:26:49 +00001423#ifdef GTEST_HAS_DEATH_TEST
Craig Silversteine0b71e52008-09-19 19:32:05 +00001424TEST(FlagsValidatorDeathTest, InvalidFlagViaArgv) {
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001425 const char* argv[] = {
1426 "my_test",
1427 "--test_flag=50",
1428 NULL,
1429 };
1430 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
Craig Silverstein917f4e72011-07-29 04:26:49 +00001431 EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001432 "ERROR: failed validation of new value '50' for flag 'test_flag'");
1433 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1434}
Craig Silverstein917f4e72011-07-29 04:26:49 +00001435#endif
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001436
1437TEST(FlagsValidator, InvalidFlagViaSetDefault) {
1438 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1439 // SetCommandLineOptionWithMode returns the empty string on error.
1440 EXPECT_EQ("", SetCommandLineOptionWithMode("test_flag", "50",
1441 SET_FLAG_IF_DEFAULT));
1442 EXPECT_EQ(-1, FLAGS_test_flag); // the setting-to-50 should have failed
1443 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1444}
1445
1446TEST(FlagsValidator, InvalidFlagViaSetValue) {
1447 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1448 FLAGS_test_flag = 100; // doesn't trigger the validator
1449 // SetCommandLineOptionWithMode returns the empty string on error.
1450 EXPECT_EQ("", SetCommandLineOptionWithMode("test_flag", "50",
1451 SET_FLAGS_VALUE));
1452 EXPECT_EQ("", SetCommandLineOptionWithMode("test_flag", "50",
1453 SET_FLAGS_DEFAULT));
1454 EXPECT_EQ("", SetCommandLineOption("test_flag", "50"));
1455 EXPECT_EQ(100, FLAGS_test_flag); // the setting-to-50 should have failed
1456 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1457}
1458
Craig Silverstein917f4e72011-07-29 04:26:49 +00001459#ifdef GTEST_HAS_DEATH_TEST
Craig Silversteine0b71e52008-09-19 19:32:05 +00001460TEST(FlagsValidatorDeathTest, InvalidFlagNeverSet) {
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001461 // If a flag keeps its default value, and that default value is
1462 // invalid, we should die at argv-parse time.
1463 const char* argv[] = {
1464 "my_test",
1465 NULL,
1466 };
1467 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
Craig Silverstein917f4e72011-07-29 04:26:49 +00001468 EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001469 "ERROR: --test_flag must be set on the commandline");
1470}
Craig Silverstein917f4e72011-07-29 04:26:49 +00001471#endif
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001472
1473TEST(FlagsValidator, InvalidFlagPtr) {
1474 int32 dummy;
1475 EXPECT_FALSE(RegisterFlagValidator(NULL, &ValidateTestFlagIs5));
1476 EXPECT_FALSE(RegisterFlagValidator(&dummy, &ValidateTestFlagIs5));
1477}
1478
1479TEST(FlagsValidator, RegisterValidatorTwice) {
1480 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1481 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1482 EXPECT_FALSE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs10));
1483 EXPECT_FALSE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs10));
1484 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1485 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1486 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs10));
1487 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1488}
1489
1490TEST(FlagsValidator, CommandLineFlagInfo) {
1491 CommandLineFlagInfo info;
1492 info = GetCommandLineFlagInfoOrDie("test_flag");
1493 EXPECT_FALSE(info.has_validator_fn);
1494
1495 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1496 info = GetCommandLineFlagInfoOrDie("test_flag");
1497 EXPECT_TRUE(info.has_validator_fn);
1498
1499 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1500 info = GetCommandLineFlagInfoOrDie("test_flag");
1501 EXPECT_FALSE(info.has_validator_fn);
1502}
1503
1504TEST(FlagsValidator, FlagSaver) {
1505 {
1506 FlagSaver fs;
1507 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
Craig Silverstein31c8edc2010-01-05 02:25:45 +00001508 EXPECT_EQ("", SetCommandLineOption("test_flag", "50")); // fails validation
Craig Silversteinc79c32d2008-07-22 23:29:39 +00001509 }
1510 EXPECT_NE("", SetCommandLineOption("test_flag", "50")); // validator is gone
1511
1512 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1513 {
1514 FlagSaver fs;
1515 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1516 EXPECT_NE("", SetCommandLineOption("test_flag", "50")); // no validator
1517 }
1518 EXPECT_EQ("", SetCommandLineOption("test_flag", "50")); // validator is back
1519}
1520
1521
Craig Silverstein917f4e72011-07-29 04:26:49 +00001522} // unnamed namespace
1523
Sergey Sharybin4f100cb2015-12-31 17:09:59 +05001524static int main(int argc, char **argv) {
Andreas Schuh8a563cf2014-03-14 20:32:37 +00001525
1526 // Run unit tests only if called without arguments, otherwise this program
1527 // is used by an "external" usage test
1528 const bool run_tests = (argc == 1);
1529
Craig Silverstein917f4e72011-07-29 04:26:49 +00001530 // We need to call SetArgv before parsing flags, so our "test" argv will
Craig Silversteinb9f23482007-03-22 00:15:41 +00001531 // win out over this executable's real argv. That makes running this
1532 // test with a real --help flag kinda annoying, unfortunately.
1533 const char* test_argv[] = { "/test/argv/for/gflags_unittest",
1534 "argv 2", "3rd argv", "argv #4" };
Craig Silverstein917f4e72011-07-29 04:26:49 +00001535 SetArgv(arraysize(test_argv), test_argv);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001536
1537 // The first arg is the usage message, also important for testing.
1538 string usage_message = (string(GetArgv0()) +
1539 ": <useless flag> [...]\nDoes something useless.\n");
1540
Craig Silverstein0baf4ab2011-01-14 21:58:28 +00001541 // We test setting tryfromenv manually, and making sure
1542 // ParseCommandLineFlags still evaluates it.
Craig Silversteinb9f23482007-03-22 00:15:41 +00001543 FLAGS_tryfromenv = "test_tryfromenv";
1544 setenv("FLAGS_test_tryfromenv", "pre-set", 1);
1545
Craig Silverstein585a44a2007-10-18 20:08:26 +00001546 // Modify flag values from declared default value in two ways.
1547 // The recommended way:
1548 SetCommandLineOptionWithMode("changed_bool1", "true", SET_FLAGS_DEFAULT);
Craig Silverstein917f4e72011-07-29 04:26:49 +00001549
Craig Silverstein585a44a2007-10-18 20:08:26 +00001550 // The non-recommended way:
1551 FLAGS_changed_bool2 = true;
1552
Andreas Schuh8ac4bc42016-02-29 16:12:33 +00001553 SetUsageMessage(usage_message);
Craig Silversteinb4bf72b2011-03-03 22:26:24 +00001554 SetVersionString("test_version");
Craig Silversteinb9f23482007-03-22 00:15:41 +00001555 ParseCommandLineFlags(&argc, &argv, true);
Craig Silverstein917f4e72011-07-29 04:26:49 +00001556 MakeTmpdir(&FLAGS_test_tmpdir);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001557
Andreas Schuh8a563cf2014-03-14 20:32:37 +00001558 int exit_status = 0;
1559 if (run_tests) {
1560 fprintf(stdout, "Running the unit tests now...\n\n"); fflush(stdout);
1561 exit_status = RUN_ALL_TESTS();
1562 } else fprintf(stderr, "\n\nPASS\n");
Craig Silverstein917f4e72011-07-29 04:26:49 +00001563 ShutDownCommandLineFlags();
1564 return exit_status;
Craig Silversteinb9f23482007-03-22 00:15:41 +00001565}
1566
Andreas Schuh126f36b2013-08-01 01:47:13 +01001567} // GFLAGS_NAMESPACE
Craig Silversteinb9f23482007-03-22 00:15:41 +00001568
1569int main(int argc, char** argv) {
Andreas Schuh126f36b2013-08-01 01:47:13 +01001570 return GFLAGS_NAMESPACE::main(argc, argv);
Craig Silversteinb9f23482007-03-22 00:15:41 +00001571}
Craig Silverstein917f4e72011-07-29 04:26:49 +00001572