flag_test.cc
Go to the documentation of this file.
00001 //
00002 //  Copyright 2019 The Abseil Authors.
00003 //
00004 // Licensed under the Apache License, Version 2.0 (the "License");
00005 // you may not use this file except in compliance with the License.
00006 // You may obtain a copy of the License at
00007 //
00008 //      https://www.apache.org/licenses/LICENSE-2.0
00009 //
00010 // Unless required by applicable law or agreed to in writing, software
00011 // distributed under the License is distributed on an "AS IS" BASIS,
00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 // See the License for the specific language governing permissions and
00014 // limitations under the License.
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 }  // namespace
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   // test that we can access flag objects.
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 }  // namespace
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 }  // namespace
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 }  // namespace
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 }  // namespace
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 // Tests side-effects of callback invocation.
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 }  // namespace
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 // MSVC produces link error on the type mismatch.
00353 // Linux does not have build errors and validations work as expected.
00354 #if 0  // !defined(_WIN32) && GTEST_HAS_DEATH_TEST
00355 
00356 TEST(Flagtest, TestTypeMismatchValidations) {
00357   // For builtin types, GetFlag() only does validation in debug mode.
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 // A contrived type that offers implicit and explicit conversion from specific
00380 // source types.
00381 struct ConversionTestVal {
00382   ConversionTestVal() = default;
00383   explicit ConversionTestVal(int a_in) : a(a_in) {}
00384 
00385   enum class ViaImplicitConv { kTen = 10, kEleven };
00386   // NOLINTNEXTLINE
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 }  // namespace
00404 
00405 // Flag default values can be specified with a value that converts to the flag
00406 // value type implicitly.
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   // This constructor tests that we can initialize the flag with int value
00424   NonDfltConstructible(int i) : value(i) {}  // NOLINT
00425 
00426   // This constructor tests that we can't initialize the flag with char value
00427   // but can with explicitly constructed NonDfltConstructible.
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 }  // namespace
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 }  // namespace
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 }  // namespace


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:14