00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "absl/flags/flag.h"
00017
00018 #include "gtest/gtest.h"
00019 #include "absl/strings/match.h"
00020 #include "absl/strings/numbers.h"
00021 #include "absl/strings/str_cat.h"
00022 #include "absl/strings/str_split.h"
00023
00024 ABSL_DECLARE_FLAG(int64_t, mistyped_int_flag);
00025 ABSL_DECLARE_FLAG(std::vector<std::string>, mistyped_string_flag);
00026
00027 namespace {
00028
00029 namespace flags = absl::flags_internal;
00030
00031 std::string TestHelpMsg() { return "help"; }
00032 template <typename T>
00033 void* TestMakeDflt() {
00034 return new T{};
00035 }
00036 void TestCallback() {}
00037
00038 template <typename T>
00039 bool TestConstructionFor() {
00040 constexpr flags::Flag<T> f1("f1", &TestHelpMsg, "file",
00041 &absl::flags_internal::FlagMarshallingOps<T>,
00042 &TestMakeDflt<T>);
00043 EXPECT_EQ(f1.Name(), "f1");
00044 EXPECT_EQ(f1.Help(), "help");
00045 EXPECT_EQ(f1.Filename(), "file");
00046
00047 ABSL_CONST_INIT static flags::Flag<T> f2(
00048 "f2", &TestHelpMsg, "file", &absl::flags_internal::FlagMarshallingOps<T>,
00049 &TestMakeDflt<T>);
00050 flags::FlagRegistrar<T, false>(&f2).OnUpdate(TestCallback);
00051
00052 EXPECT_EQ(f2.Name(), "f2");
00053 EXPECT_EQ(f2.Help(), "help");
00054 EXPECT_EQ(f2.Filename(), "file");
00055
00056 return true;
00057 }
00058
00059 struct UDT {
00060 UDT() = default;
00061 UDT(const UDT&) = default;
00062 };
00063 bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; }
00064 std::string AbslUnparseFlag(const UDT&) { return ""; }
00065
00066 TEST(FlagTest, TestConstruction) {
00067 TestConstructionFor<bool>();
00068 TestConstructionFor<int16_t>();
00069 TestConstructionFor<uint16_t>();
00070 TestConstructionFor<int32_t>();
00071 TestConstructionFor<uint32_t>();
00072 TestConstructionFor<int64_t>();
00073 TestConstructionFor<uint64_t>();
00074 TestConstructionFor<double>();
00075 TestConstructionFor<float>();
00076 TestConstructionFor<std::string>();
00077
00078 TestConstructionFor<UDT>();
00079 }
00080
00081
00082
00083 }
00084
00085 ABSL_DECLARE_FLAG(bool, test_flag_01);
00086 ABSL_DECLARE_FLAG(int, test_flag_02);
00087 ABSL_DECLARE_FLAG(int16_t, test_flag_03);
00088 ABSL_DECLARE_FLAG(uint16_t, test_flag_04);
00089 ABSL_DECLARE_FLAG(int32_t, test_flag_05);
00090 ABSL_DECLARE_FLAG(uint32_t, test_flag_06);
00091 ABSL_DECLARE_FLAG(int64_t, test_flag_07);
00092 ABSL_DECLARE_FLAG(uint64_t, test_flag_08);
00093 ABSL_DECLARE_FLAG(double, test_flag_09);
00094 ABSL_DECLARE_FLAG(float, test_flag_10);
00095 ABSL_DECLARE_FLAG(std::string, test_flag_11);
00096
00097 namespace {
00098
00099 #if !ABSL_FLAGS_STRIP_NAMES
00100
00101 TEST(FlagTest, TestFlagDeclaration) {
00102
00103 EXPECT_EQ(FLAGS_test_flag_01.Name(), "test_flag_01");
00104 EXPECT_EQ(FLAGS_test_flag_02.Name(), "test_flag_02");
00105 EXPECT_EQ(FLAGS_test_flag_03.Name(), "test_flag_03");
00106 EXPECT_EQ(FLAGS_test_flag_04.Name(), "test_flag_04");
00107 EXPECT_EQ(FLAGS_test_flag_05.Name(), "test_flag_05");
00108 EXPECT_EQ(FLAGS_test_flag_06.Name(), "test_flag_06");
00109 EXPECT_EQ(FLAGS_test_flag_07.Name(), "test_flag_07");
00110 EXPECT_EQ(FLAGS_test_flag_08.Name(), "test_flag_08");
00111 EXPECT_EQ(FLAGS_test_flag_09.Name(), "test_flag_09");
00112 EXPECT_EQ(FLAGS_test_flag_10.Name(), "test_flag_10");
00113 EXPECT_EQ(FLAGS_test_flag_11.Name(), "test_flag_11");
00114 }
00115 #endif // !ABSL_FLAGS_STRIP_NAMES
00116
00117
00118
00119 }
00120
00121 ABSL_FLAG(bool, test_flag_01, true, "test flag 01");
00122 ABSL_FLAG(int, test_flag_02, 1234, "test flag 02");
00123 ABSL_FLAG(int16_t, test_flag_03, -34, "test flag 03");
00124 ABSL_FLAG(uint16_t, test_flag_04, 189, "test flag 04");
00125 ABSL_FLAG(int32_t, test_flag_05, 10765, "test flag 05");
00126 ABSL_FLAG(uint32_t, test_flag_06, 40000, "test flag 06");
00127 ABSL_FLAG(int64_t, test_flag_07, -1234567, "test flag 07");
00128 ABSL_FLAG(uint64_t, test_flag_08, 9876543, "test flag 08");
00129 ABSL_FLAG(double, test_flag_09, -9.876e-50, "test flag 09");
00130 ABSL_FLAG(float, test_flag_10, 1.234e12f, "test flag 10");
00131 ABSL_FLAG(std::string, test_flag_11, "", "test flag 11");
00132
00133 namespace {
00134
00135 #if !ABSL_FLAGS_STRIP_NAMES
00136 TEST(FlagTest, TestFlagDefinition) {
00137 absl::string_view expected_file_name = "absl/flags/flag_test.cc";
00138
00139 EXPECT_EQ(FLAGS_test_flag_01.Name(), "test_flag_01");
00140 EXPECT_EQ(FLAGS_test_flag_01.Help(), "test flag 01");
00141 EXPECT_TRUE(
00142 absl::EndsWith(FLAGS_test_flag_01.Filename(), expected_file_name));
00143
00144 EXPECT_EQ(FLAGS_test_flag_02.Name(), "test_flag_02");
00145 EXPECT_EQ(FLAGS_test_flag_02.Help(), "test flag 02");
00146 EXPECT_TRUE(
00147 absl::EndsWith(FLAGS_test_flag_02.Filename(), expected_file_name));
00148
00149 EXPECT_EQ(FLAGS_test_flag_03.Name(), "test_flag_03");
00150 EXPECT_EQ(FLAGS_test_flag_03.Help(), "test flag 03");
00151 EXPECT_TRUE(
00152 absl::EndsWith(FLAGS_test_flag_03.Filename(), expected_file_name));
00153
00154 EXPECT_EQ(FLAGS_test_flag_04.Name(), "test_flag_04");
00155 EXPECT_EQ(FLAGS_test_flag_04.Help(), "test flag 04");
00156 EXPECT_TRUE(
00157 absl::EndsWith(FLAGS_test_flag_04.Filename(), expected_file_name));
00158
00159 EXPECT_EQ(FLAGS_test_flag_05.Name(), "test_flag_05");
00160 EXPECT_EQ(FLAGS_test_flag_05.Help(), "test flag 05");
00161 EXPECT_TRUE(
00162 absl::EndsWith(FLAGS_test_flag_05.Filename(), expected_file_name));
00163
00164 EXPECT_EQ(FLAGS_test_flag_06.Name(), "test_flag_06");
00165 EXPECT_EQ(FLAGS_test_flag_06.Help(), "test flag 06");
00166 EXPECT_TRUE(
00167 absl::EndsWith(FLAGS_test_flag_06.Filename(), expected_file_name));
00168
00169 EXPECT_EQ(FLAGS_test_flag_07.Name(), "test_flag_07");
00170 EXPECT_EQ(FLAGS_test_flag_07.Help(), "test flag 07");
00171 EXPECT_TRUE(
00172 absl::EndsWith(FLAGS_test_flag_07.Filename(), expected_file_name));
00173
00174 EXPECT_EQ(FLAGS_test_flag_08.Name(), "test_flag_08");
00175 EXPECT_EQ(FLAGS_test_flag_08.Help(), "test flag 08");
00176 EXPECT_TRUE(
00177 absl::EndsWith(FLAGS_test_flag_08.Filename(), expected_file_name));
00178
00179 EXPECT_EQ(FLAGS_test_flag_09.Name(), "test_flag_09");
00180 EXPECT_EQ(FLAGS_test_flag_09.Help(), "test flag 09");
00181 EXPECT_TRUE(
00182 absl::EndsWith(FLAGS_test_flag_09.Filename(), expected_file_name));
00183
00184 EXPECT_EQ(FLAGS_test_flag_10.Name(), "test_flag_10");
00185 EXPECT_EQ(FLAGS_test_flag_10.Help(), "test flag 10");
00186 EXPECT_TRUE(
00187 absl::EndsWith(FLAGS_test_flag_10.Filename(), expected_file_name));
00188
00189 EXPECT_EQ(FLAGS_test_flag_11.Name(), "test_flag_11");
00190 EXPECT_EQ(FLAGS_test_flag_11.Help(), "test flag 11");
00191 EXPECT_TRUE(
00192 absl::EndsWith(FLAGS_test_flag_11.Filename(), expected_file_name));
00193 }
00194 #endif // !ABSL_FLAGS_STRIP_NAMES
00195
00196
00197
00198 TEST(FlagTest, TestDefault) {
00199 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), true);
00200 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 1234);
00201 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), -34);
00202 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_04), 189);
00203 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_05), 10765);
00204 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_06), 40000);
00205 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_07), -1234567);
00206 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_08), 9876543);
00207 EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_09), -9.876e-50, 1e-55);
00208 EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_10), 1.234e12f, 1e5f);
00209 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_11), "");
00210 }
00211
00212
00213
00214 TEST(FlagTest, TestGetSet) {
00215 absl::SetFlag(&FLAGS_test_flag_01, false);
00216 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), false);
00217
00218 absl::SetFlag(&FLAGS_test_flag_02, 321);
00219 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 321);
00220
00221 absl::SetFlag(&FLAGS_test_flag_03, 67);
00222 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), 67);
00223
00224 absl::SetFlag(&FLAGS_test_flag_04, 1);
00225 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_04), 1);
00226
00227 absl::SetFlag(&FLAGS_test_flag_05, -908);
00228 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_05), -908);
00229
00230 absl::SetFlag(&FLAGS_test_flag_06, 4001);
00231 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_06), 4001);
00232
00233 absl::SetFlag(&FLAGS_test_flag_07, -23456);
00234 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_07), -23456);
00235
00236 absl::SetFlag(&FLAGS_test_flag_08, 975310);
00237 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_08), 975310);
00238
00239 absl::SetFlag(&FLAGS_test_flag_09, 1.00001);
00240 EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_09), 1.00001, 1e-10);
00241
00242 absl::SetFlag(&FLAGS_test_flag_10, -3.54f);
00243 EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_10), -3.54f, 1e-6f);
00244
00245 absl::SetFlag(&FLAGS_test_flag_11, "asdf");
00246 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_11), "asdf");
00247 }
00248
00249
00250
00251 int GetDflt1() { return 1; }
00252
00253 }
00254
00255 ABSL_FLAG(int, test_flag_12, GetDflt1(), "test flag 12");
00256 ABSL_FLAG(std::string, test_flag_13, absl::StrCat("AAA", "BBB"),
00257 "test flag 13");
00258
00259 namespace {
00260
00261 TEST(FlagTest, TestNonConstexprDefault) {
00262 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), 1);
00263 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_13), "AAABBB");
00264 }
00265
00266
00267
00268 }
00269
00270 ABSL_FLAG(bool, test_flag_14, true, absl::StrCat("test ", "flag ", "14"));
00271
00272 namespace {
00273
00274 #if !ABSL_FLAGS_STRIP_HELP
00275 TEST(FlagTest, TestNonConstexprHelp) {
00276 EXPECT_EQ(FLAGS_test_flag_14.Help(), "test flag 14");
00277 }
00278 #endif //! ABSL_FLAGS_STRIP_HELP
00279
00280
00281
00282 int cb_test_value = -1;
00283 void TestFlagCB();
00284
00285 }
00286
00287 ABSL_FLAG(int, test_flag_with_cb, 100, "").OnUpdate(TestFlagCB);
00288
00289 ABSL_FLAG(int, test_flag_with_lambda_cb, 200, "").OnUpdate([]() {
00290 cb_test_value = absl::GetFlag(FLAGS_test_flag_with_lambda_cb) +
00291 absl::GetFlag(FLAGS_test_flag_with_cb);
00292 });
00293
00294 namespace {
00295
00296 void TestFlagCB() { cb_test_value = absl::GetFlag(FLAGS_test_flag_with_cb); }
00297
00298
00299 TEST(FlagTest, CallbackInvocation) {
00300 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_cb), 100);
00301 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_lambda_cb), 200);
00302 EXPECT_EQ(cb_test_value, 300);
00303
00304 absl::SetFlag(&FLAGS_test_flag_with_cb, 1);
00305 EXPECT_EQ(cb_test_value, 1);
00306
00307 absl::SetFlag(&FLAGS_test_flag_with_lambda_cb, 3);
00308 EXPECT_EQ(cb_test_value, 4);
00309 }
00310
00311
00312
00313 struct CustomUDT {
00314 CustomUDT() : a(1), b(1) {}
00315 CustomUDT(int a_, int b_) : a(a_), b(b_) {}
00316
00317 friend bool operator==(const CustomUDT& f1, const CustomUDT& f2) {
00318 return f1.a == f2.a && f1.b == f2.b;
00319 }
00320
00321 int a;
00322 int b;
00323 };
00324 bool AbslParseFlag(absl::string_view in, CustomUDT* f, std::string*) {
00325 std::vector<absl::string_view> parts =
00326 absl::StrSplit(in, ':', absl::SkipWhitespace());
00327
00328 if (parts.size() != 2) return false;
00329
00330 if (!absl::SimpleAtoi(parts[0], &f->a)) return false;
00331
00332 if (!absl::SimpleAtoi(parts[1], &f->b)) return false;
00333
00334 return true;
00335 }
00336 std::string AbslUnparseFlag(const CustomUDT& f) {
00337 return absl::StrCat(f.a, ":", f.b);
00338 }
00339
00340 }
00341
00342 ABSL_FLAG(CustomUDT, test_flag_15, CustomUDT(), "test flag 15");
00343
00344 namespace {
00345
00346 TEST(FlagTest, TestCustomUDT) {
00347 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_15), CustomUDT(1, 1));
00348 absl::SetFlag(&FLAGS_test_flag_15, CustomUDT(2, 3));
00349 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_15), CustomUDT(2, 3));
00350 }
00351
00352
00353
00354 #if 0 // !defined(_WIN32) && GTEST_HAS_DEATH_TEST
00355
00356 TEST(Flagtest, TestTypeMismatchValidations) {
00357
00358 EXPECT_DEBUG_DEATH(
00359 absl::GetFlag(FLAGS_mistyped_int_flag),
00360 "Flag 'mistyped_int_flag' is defined as one type and declared "
00361 "as another");
00362 EXPECT_DEATH(absl::SetFlag(&FLAGS_mistyped_int_flag, 0),
00363 "Flag 'mistyped_int_flag' is defined as one type and declared "
00364 "as another");
00365
00366 EXPECT_DEATH(absl::GetFlag(FLAGS_mistyped_string_flag),
00367 "Flag 'mistyped_string_flag' is defined as one type and "
00368 "declared as another");
00369 EXPECT_DEATH(
00370 absl::SetFlag(&FLAGS_mistyped_string_flag, std::vector<std::string>{}),
00371 "Flag 'mistyped_string_flag' is defined as one type and declared as "
00372 "another");
00373 }
00374
00375 #endif
00376
00377
00378
00379
00380
00381 struct ConversionTestVal {
00382 ConversionTestVal() = default;
00383 explicit ConversionTestVal(int a_in) : a(a_in) {}
00384
00385 enum class ViaImplicitConv { kTen = 10, kEleven };
00386
00387 ConversionTestVal(ViaImplicitConv from) : a(static_cast<int>(from)) {}
00388
00389 int a;
00390 };
00391
00392 bool AbslParseFlag(absl::string_view in, ConversionTestVal* val_out,
00393 std::string*) {
00394 if (!absl::SimpleAtoi(in, &val_out->a)) {
00395 return false;
00396 }
00397 return true;
00398 }
00399 std::string AbslUnparseFlag(const ConversionTestVal& val) {
00400 return absl::StrCat(val.a);
00401 }
00402
00403 }
00404
00405
00406
00407 ABSL_FLAG(ConversionTestVal, test_flag_16,
00408 ConversionTestVal::ViaImplicitConv::kTen, "test flag 16");
00409
00410 namespace {
00411
00412 TEST(FlagTest, CanSetViaImplicitConversion) {
00413 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_16).a, 10);
00414 absl::SetFlag(&FLAGS_test_flag_16,
00415 ConversionTestVal::ViaImplicitConv::kEleven);
00416 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_16).a, 11);
00417 }
00418
00419
00420
00421 struct NonDfltConstructible {
00422 public:
00423
00424 NonDfltConstructible(int i) : value(i) {}
00425
00426
00427
00428 explicit NonDfltConstructible(char c) : value(100 + static_cast<int>(c)) {}
00429
00430 int value;
00431 };
00432
00433 bool AbslParseFlag(absl::string_view in, NonDfltConstructible* ndc_out,
00434 std::string*) {
00435 return absl::SimpleAtoi(in, &ndc_out->value);
00436 }
00437 std::string AbslUnparseFlag(const NonDfltConstructible& ndc) {
00438 return absl::StrCat(ndc.value);
00439 }
00440
00441 }
00442
00443 ABSL_FLAG(NonDfltConstructible, ndc_flag1, NonDfltConstructible('1'),
00444 "Flag with non default constructible type");
00445 ABSL_FLAG(NonDfltConstructible, ndc_flag2, 0,
00446 "Flag with non default constructible type");
00447
00448 namespace {
00449
00450 TEST(FlagTest, TestNonDefaultConstructibleType) {
00451 EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, '1' + 100);
00452 EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 0);
00453
00454 absl::SetFlag(&FLAGS_ndc_flag1, NonDfltConstructible('A'));
00455 absl::SetFlag(&FLAGS_ndc_flag2, 25);
00456
00457 EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, 'A' + 100);
00458 EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 25);
00459 }
00460
00461
00462
00463 }
00464
00465 ABSL_RETIRED_FLAG(bool, old_bool_flag, true, "old descr");
00466 ABSL_RETIRED_FLAG(int, old_int_flag, (int)std::sqrt(10), "old descr");
00467 ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr"));
00468
00469 namespace {
00470
00471 TEST(FlagTest, TestRetiredFlagRegistration) {
00472 bool is_bool = false;
00473 EXPECT_TRUE(flags::IsRetiredFlag("old_bool_flag", &is_bool));
00474 EXPECT_TRUE(is_bool);
00475 EXPECT_TRUE(flags::IsRetiredFlag("old_int_flag", &is_bool));
00476 EXPECT_FALSE(is_bool);
00477 EXPECT_TRUE(flags::IsRetiredFlag("old_str_flag", &is_bool));
00478 EXPECT_FALSE(is_bool);
00479 EXPECT_FALSE(flags::IsRetiredFlag("some_other_flag", &is_bool));
00480 }
00481
00482 }