1 //
2 //  Copyright 2019 The Abseil Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      https://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #include "absl/flags/flag.h"
17 
18 #include <stdint.h>
19 
20 #include <cmath>
21 #include <string>
22 #include <vector>
23 
24 #include "gtest/gtest.h"
25 #include "absl/base/attributes.h"
26 #include "absl/flags/config.h"
27 #include "absl/flags/declare.h"
28 #include "absl/flags/internal/commandlineflag.h"
29 #include "absl/flags/internal/flag.h"
30 #include "absl/flags/internal/registry.h"
31 #include "absl/flags/usage_config.h"
32 #include "absl/strings/match.h"
33 #include "absl/strings/numbers.h"
34 #include "absl/strings/str_cat.h"
35 #include "absl/strings/str_split.h"
36 #include "absl/strings/string_view.h"
37 
38 ABSL_DECLARE_FLAG(int64_t, mistyped_int_flag);
39 ABSL_DECLARE_FLAG(std::vector<std::string>, mistyped_string_flag);
40 
41 namespace {
42 
43 namespace flags = absl::flags_internal;
44 
TestHelpMsg()45 std::string TestHelpMsg() { return "dynamic help"; }
46 template <typename T>
TestMakeDflt()47 void* TestMakeDflt() {
48   return new T{};
49 }
TestCallback()50 void TestCallback() {}
51 
52 template <typename T>
TestConstructionFor()53 bool TestConstructionFor() {
54   constexpr flags::FlagHelpArg help_arg{flags::FlagHelpMsg("literal help"),
55                                         flags::FlagHelpKind::kLiteral};
56   constexpr flags::Flag<T> f1("f1", "file", help_arg, &TestMakeDflt<T>);
57   EXPECT_EQ(f1.Name(), "f1");
58   EXPECT_EQ(f1.Help(), "literal help");
59   EXPECT_EQ(f1.Filename(), "file");
60 
61   ABSL_CONST_INIT static flags::Flag<T> f2(
62       "f2", "file",
63       {flags::FlagHelpMsg(&TestHelpMsg), flags::FlagHelpKind::kGenFunc},
64       &TestMakeDflt<T>);
65   flags::FlagRegistrar<T, false>(&f2).OnUpdate(TestCallback);
66 
67   EXPECT_EQ(f2.Name(), "f2");
68   EXPECT_EQ(f2.Help(), "dynamic help");
69   EXPECT_EQ(f2.Filename(), "file");
70 
71   return true;
72 }
73 
74 struct UDT {
75   UDT() = default;
76   UDT(const UDT&) = default;
77 };
AbslParseFlag(absl::string_view,UDT *,std::string *)78 bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; }
AbslUnparseFlag(const UDT &)79 std::string AbslUnparseFlag(const UDT&) { return ""; }
80 
81 class FlagTest : public testing::Test {
82  protected:
SetUpTestSuite()83   static void SetUpTestSuite() {
84     // Install a function to normalize filenames before this test is run.
85     absl::FlagsUsageConfig default_config;
86     default_config.normalize_filename = &FlagTest::NormalizeFileName;
87     absl::SetFlagsUsageConfig(default_config);
88   }
89 
90  private:
NormalizeFileName(absl::string_view fname)91   static std::string NormalizeFileName(absl::string_view fname) {
92 #ifdef _WIN32
93     std::string normalized(fname);
94     std::replace(normalized.begin(), normalized.end(), '\\', '/');
95     fname = normalized;
96 #endif
97     return std::string(fname);
98   }
99 };
100 
TEST_F(FlagTest,TestConstruction)101 TEST_F(FlagTest, TestConstruction) {
102   TestConstructionFor<bool>();
103   TestConstructionFor<int16_t>();
104   TestConstructionFor<uint16_t>();
105   TestConstructionFor<int32_t>();
106   TestConstructionFor<uint32_t>();
107   TestConstructionFor<int64_t>();
108   TestConstructionFor<uint64_t>();
109   TestConstructionFor<double>();
110   TestConstructionFor<float>();
111   TestConstructionFor<std::string>();
112 
113   TestConstructionFor<UDT>();
114 }
115 
116 // --------------------------------------------------------------------
117 
118 }  // namespace
119 
120 ABSL_DECLARE_FLAG(bool, test_flag_01);
121 ABSL_DECLARE_FLAG(int, test_flag_02);
122 ABSL_DECLARE_FLAG(int16_t, test_flag_03);
123 ABSL_DECLARE_FLAG(uint16_t, test_flag_04);
124 ABSL_DECLARE_FLAG(int32_t, test_flag_05);
125 ABSL_DECLARE_FLAG(uint32_t, test_flag_06);
126 ABSL_DECLARE_FLAG(int64_t, test_flag_07);
127 ABSL_DECLARE_FLAG(uint64_t, test_flag_08);
128 ABSL_DECLARE_FLAG(double, test_flag_09);
129 ABSL_DECLARE_FLAG(float, test_flag_10);
130 ABSL_DECLARE_FLAG(std::string, test_flag_11);
131 
132 namespace {
133 
134 #if !ABSL_FLAGS_STRIP_NAMES
135 
TEST_F(FlagTest,TestFlagDeclaration)136 TEST_F(FlagTest, TestFlagDeclaration) {
137   // test that we can access flag objects.
138   EXPECT_EQ(FLAGS_test_flag_01.Name(), "test_flag_01");
139   EXPECT_EQ(FLAGS_test_flag_02.Name(), "test_flag_02");
140   EXPECT_EQ(FLAGS_test_flag_03.Name(), "test_flag_03");
141   EXPECT_EQ(FLAGS_test_flag_04.Name(), "test_flag_04");
142   EXPECT_EQ(FLAGS_test_flag_05.Name(), "test_flag_05");
143   EXPECT_EQ(FLAGS_test_flag_06.Name(), "test_flag_06");
144   EXPECT_EQ(FLAGS_test_flag_07.Name(), "test_flag_07");
145   EXPECT_EQ(FLAGS_test_flag_08.Name(), "test_flag_08");
146   EXPECT_EQ(FLAGS_test_flag_09.Name(), "test_flag_09");
147   EXPECT_EQ(FLAGS_test_flag_10.Name(), "test_flag_10");
148   EXPECT_EQ(FLAGS_test_flag_11.Name(), "test_flag_11");
149 }
150 #endif  // !ABSL_FLAGS_STRIP_NAMES
151 
152 // --------------------------------------------------------------------
153 
154 }  // namespace
155 
156 ABSL_FLAG(bool, test_flag_01, true, "test flag 01");
157 ABSL_FLAG(int, test_flag_02, 1234, "test flag 02");
158 ABSL_FLAG(int16_t, test_flag_03, -34, "test flag 03");
159 ABSL_FLAG(uint16_t, test_flag_04, 189, "test flag 04");
160 ABSL_FLAG(int32_t, test_flag_05, 10765, "test flag 05");
161 ABSL_FLAG(uint32_t, test_flag_06, 40000, "test flag 06");
162 ABSL_FLAG(int64_t, test_flag_07, -1234567, "test flag 07");
163 ABSL_FLAG(uint64_t, test_flag_08, 9876543, "test flag 08");
164 ABSL_FLAG(double, test_flag_09, -9.876e-50, "test flag 09");
165 ABSL_FLAG(float, test_flag_10, 1.234e12f, "test flag 10");
166 ABSL_FLAG(std::string, test_flag_11, "", "test flag 11");
167 
168 namespace {
169 
170 #if !ABSL_FLAGS_STRIP_NAMES
TEST_F(FlagTest,TestFlagDefinition)171 TEST_F(FlagTest, TestFlagDefinition) {
172   absl::string_view expected_file_name = "absl/flags/flag_test.cc";
173 
174   EXPECT_EQ(FLAGS_test_flag_01.Name(), "test_flag_01");
175   EXPECT_EQ(FLAGS_test_flag_01.Help(), "test flag 01");
176   EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_01.Filename(), expected_file_name))
177       << FLAGS_test_flag_01.Filename();
178 
179   EXPECT_EQ(FLAGS_test_flag_02.Name(), "test_flag_02");
180   EXPECT_EQ(FLAGS_test_flag_02.Help(), "test flag 02");
181   EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_02.Filename(), expected_file_name))
182       << FLAGS_test_flag_02.Filename();
183 
184   EXPECT_EQ(FLAGS_test_flag_03.Name(), "test_flag_03");
185   EXPECT_EQ(FLAGS_test_flag_03.Help(), "test flag 03");
186   EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_03.Filename(), expected_file_name))
187       << FLAGS_test_flag_03.Filename();
188 
189   EXPECT_EQ(FLAGS_test_flag_04.Name(), "test_flag_04");
190   EXPECT_EQ(FLAGS_test_flag_04.Help(), "test flag 04");
191   EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_04.Filename(), expected_file_name))
192       << FLAGS_test_flag_04.Filename();
193 
194   EXPECT_EQ(FLAGS_test_flag_05.Name(), "test_flag_05");
195   EXPECT_EQ(FLAGS_test_flag_05.Help(), "test flag 05");
196   EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_05.Filename(), expected_file_name))
197       << FLAGS_test_flag_05.Filename();
198 
199   EXPECT_EQ(FLAGS_test_flag_06.Name(), "test_flag_06");
200   EXPECT_EQ(FLAGS_test_flag_06.Help(), "test flag 06");
201   EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_06.Filename(), expected_file_name))
202       << FLAGS_test_flag_06.Filename();
203 
204   EXPECT_EQ(FLAGS_test_flag_07.Name(), "test_flag_07");
205   EXPECT_EQ(FLAGS_test_flag_07.Help(), "test flag 07");
206   EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_07.Filename(), expected_file_name))
207       << FLAGS_test_flag_07.Filename();
208 
209   EXPECT_EQ(FLAGS_test_flag_08.Name(), "test_flag_08");
210   EXPECT_EQ(FLAGS_test_flag_08.Help(), "test flag 08");
211   EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_08.Filename(), expected_file_name))
212       << FLAGS_test_flag_08.Filename();
213 
214   EXPECT_EQ(FLAGS_test_flag_09.Name(), "test_flag_09");
215   EXPECT_EQ(FLAGS_test_flag_09.Help(), "test flag 09");
216   EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_09.Filename(), expected_file_name))
217       << FLAGS_test_flag_09.Filename();
218 
219   EXPECT_EQ(FLAGS_test_flag_10.Name(), "test_flag_10");
220   EXPECT_EQ(FLAGS_test_flag_10.Help(), "test flag 10");
221   EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_10.Filename(), expected_file_name))
222       << FLAGS_test_flag_10.Filename();
223 
224   EXPECT_EQ(FLAGS_test_flag_11.Name(), "test_flag_11");
225   EXPECT_EQ(FLAGS_test_flag_11.Help(), "test flag 11");
226   EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_11.Filename(), expected_file_name))
227       << FLAGS_test_flag_11.Filename();
228 }
229 #endif  // !ABSL_FLAGS_STRIP_NAMES
230 
231 // --------------------------------------------------------------------
232 
TEST_F(FlagTest,TestDefault)233 TEST_F(FlagTest, TestDefault) {
234   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), true);
235   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 1234);
236   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), -34);
237   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_04), 189);
238   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_05), 10765);
239   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_06), 40000);
240   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_07), -1234567);
241   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_08), 9876543);
242   EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_09), -9.876e-50, 1e-55);
243   EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_10), 1.234e12f, 1e5f);
244   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_11), "");
245 }
246 
247 // --------------------------------------------------------------------
248 
TEST_F(FlagTest,TestGetSet)249 TEST_F(FlagTest, TestGetSet) {
250   absl::SetFlag(&FLAGS_test_flag_01, false);
251   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), false);
252 
253   absl::SetFlag(&FLAGS_test_flag_02, 321);
254   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 321);
255 
256   absl::SetFlag(&FLAGS_test_flag_03, 67);
257   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), 67);
258 
259   absl::SetFlag(&FLAGS_test_flag_04, 1);
260   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_04), 1);
261 
262   absl::SetFlag(&FLAGS_test_flag_05, -908);
263   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_05), -908);
264 
265   absl::SetFlag(&FLAGS_test_flag_06, 4001);
266   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_06), 4001);
267 
268   absl::SetFlag(&FLAGS_test_flag_07, -23456);
269   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_07), -23456);
270 
271   absl::SetFlag(&FLAGS_test_flag_08, 975310);
272   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_08), 975310);
273 
274   absl::SetFlag(&FLAGS_test_flag_09, 1.00001);
275   EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_09), 1.00001, 1e-10);
276 
277   absl::SetFlag(&FLAGS_test_flag_10, -3.54f);
278   EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_10), -3.54f, 1e-6f);
279 
280   absl::SetFlag(&FLAGS_test_flag_11, "asdf");
281   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_11), "asdf");
282 }
283 
284 // --------------------------------------------------------------------
285 
GetDflt1()286 int GetDflt1() { return 1; }
287 
288 }  // namespace
289 
290 ABSL_FLAG(int, test_flag_12, GetDflt1(), "test flag 12");
291 ABSL_FLAG(std::string, test_flag_13, absl::StrCat("AAA", "BBB"),
292           "test flag 13");
293 
294 namespace {
295 
TEST_F(FlagTest,TestNonConstexprDefault)296 TEST_F(FlagTest, TestNonConstexprDefault) {
297   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), 1);
298   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_13), "AAABBB");
299 }
300 
301 // --------------------------------------------------------------------
302 
303 }  // namespace
304 
305 ABSL_FLAG(bool, test_flag_14, true, absl::StrCat("test ", "flag ", "14"));
306 
307 namespace {
308 
309 #if !ABSL_FLAGS_STRIP_HELP
TEST_F(FlagTest,TestNonConstexprHelp)310 TEST_F(FlagTest, TestNonConstexprHelp) {
311   EXPECT_EQ(FLAGS_test_flag_14.Help(), "test flag 14");
312 }
313 #endif  //! ABSL_FLAGS_STRIP_HELP
314 
315 // --------------------------------------------------------------------
316 
317 int cb_test_value = -1;
318 void TestFlagCB();
319 
320 }  // namespace
321 
322 ABSL_FLAG(int, test_flag_with_cb, 100, "").OnUpdate(TestFlagCB);
323 
__anon9b92d3290602() 324 ABSL_FLAG(int, test_flag_with_lambda_cb, 200, "").OnUpdate([]() {
325   cb_test_value = absl::GetFlag(FLAGS_test_flag_with_lambda_cb) +
326                   absl::GetFlag(FLAGS_test_flag_with_cb);
327 });
328 
329 namespace {
330 
TestFlagCB()331 void TestFlagCB() { cb_test_value = absl::GetFlag(FLAGS_test_flag_with_cb); }
332 
333 // Tests side-effects of callback invocation.
TEST_F(FlagTest,CallbackInvocation)334 TEST_F(FlagTest, CallbackInvocation) {
335   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_cb), 100);
336   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_lambda_cb), 200);
337   EXPECT_EQ(cb_test_value, 300);
338 
339   absl::SetFlag(&FLAGS_test_flag_with_cb, 1);
340   EXPECT_EQ(cb_test_value, 1);
341 
342   absl::SetFlag(&FLAGS_test_flag_with_lambda_cb, 3);
343   EXPECT_EQ(cb_test_value, 4);
344 }
345 
346 // --------------------------------------------------------------------
347 
348 struct CustomUDT {
CustomUDT__anon9b92d3290711::CustomUDT349   CustomUDT() : a(1), b(1) {}
CustomUDT__anon9b92d3290711::CustomUDT350   CustomUDT(int a_, int b_) : a(a_), b(b_) {}
351 
operator ==(const CustomUDT & f1,const CustomUDT & f2)352   friend bool operator==(const CustomUDT& f1, const CustomUDT& f2) {
353     return f1.a == f2.a && f1.b == f2.b;
354   }
355 
356   int a;
357   int b;
358 };
AbslParseFlag(absl::string_view in,CustomUDT * f,std::string *)359 bool AbslParseFlag(absl::string_view in, CustomUDT* f, std::string*) {
360   std::vector<absl::string_view> parts =
361       absl::StrSplit(in, ':', absl::SkipWhitespace());
362 
363   if (parts.size() != 2) return false;
364 
365   if (!absl::SimpleAtoi(parts[0], &f->a)) return false;
366 
367   if (!absl::SimpleAtoi(parts[1], &f->b)) return false;
368 
369   return true;
370 }
AbslUnparseFlag(const CustomUDT & f)371 std::string AbslUnparseFlag(const CustomUDT& f) {
372   return absl::StrCat(f.a, ":", f.b);
373 }
374 
375 }  // namespace
376 
377 ABSL_FLAG(CustomUDT, test_flag_15, CustomUDT(), "test flag 15");
378 
379 namespace {
380 
TEST_F(FlagTest,TestCustomUDT)381 TEST_F(FlagTest, TestCustomUDT) {
382   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_15), CustomUDT(1, 1));
383   absl::SetFlag(&FLAGS_test_flag_15, CustomUDT(2, 3));
384   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_15), CustomUDT(2, 3));
385 }
386 
387 // MSVC produces link error on the type mismatch.
388 // Linux does not have build errors and validations work as expected.
389 #if !defined(_WIN32) && GTEST_HAS_DEATH_TEST
390 
391 using FlagDeathTest = FlagTest;
392 
TEST_F(FlagDeathTest,TestTypeMismatchValidations)393 TEST_F(FlagDeathTest, TestTypeMismatchValidations) {
394   EXPECT_DEBUG_DEATH(
395       static_cast<void>(absl::GetFlag(FLAGS_mistyped_int_flag)),
396       "Flag 'mistyped_int_flag' is defined as one type and declared "
397       "as another");
398   EXPECT_DEATH(absl::SetFlag(&FLAGS_mistyped_int_flag, 1),
399                "Flag 'mistyped_int_flag' is defined as one type and declared "
400                "as another");
401 
402   EXPECT_DEATH(static_cast<void>(absl::GetFlag(FLAGS_mistyped_string_flag)),
403                "Flag 'mistyped_string_flag' is defined as one type and "
404                "declared as another");
405   EXPECT_DEATH(
406       absl::SetFlag(&FLAGS_mistyped_string_flag, std::vector<std::string>{}),
407       "Flag 'mistyped_string_flag' is defined as one type and declared as "
408       "another");
409 }
410 
411 #endif
412 
413 // --------------------------------------------------------------------
414 
415 // A contrived type that offers implicit and explicit conversion from specific
416 // source types.
417 struct ConversionTestVal {
418   ConversionTestVal() = default;
ConversionTestVal__anon9b92d3290811::ConversionTestVal419   explicit ConversionTestVal(int a_in) : a(a_in) {}
420 
421   enum class ViaImplicitConv { kTen = 10, kEleven };
422   // NOLINTNEXTLINE
ConversionTestVal__anon9b92d3290811::ConversionTestVal423   ConversionTestVal(ViaImplicitConv from) : a(static_cast<int>(from)) {}
424 
425   int a;
426 };
427 
AbslParseFlag(absl::string_view in,ConversionTestVal * val_out,std::string *)428 bool AbslParseFlag(absl::string_view in, ConversionTestVal* val_out,
429                    std::string*) {
430   if (!absl::SimpleAtoi(in, &val_out->a)) {
431     return false;
432   }
433   return true;
434 }
AbslUnparseFlag(const ConversionTestVal & val)435 std::string AbslUnparseFlag(const ConversionTestVal& val) {
436   return absl::StrCat(val.a);
437 }
438 
439 }  // namespace
440 
441 // Flag default values can be specified with a value that converts to the flag
442 // value type implicitly.
443 ABSL_FLAG(ConversionTestVal, test_flag_16,
444           ConversionTestVal::ViaImplicitConv::kTen, "test flag 16");
445 
446 namespace {
447 
TEST_F(FlagTest,CanSetViaImplicitConversion)448 TEST_F(FlagTest, CanSetViaImplicitConversion) {
449   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_16).a, 10);
450   absl::SetFlag(&FLAGS_test_flag_16,
451                 ConversionTestVal::ViaImplicitConv::kEleven);
452   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_16).a, 11);
453 }
454 
455 // --------------------------------------------------------------------
456 
457 struct NonDfltConstructible {
458  public:
459   // This constructor tests that we can initialize the flag with int value
NonDfltConstructible__anon9b92d3290911::NonDfltConstructible460   NonDfltConstructible(int i) : value(i) {}  // NOLINT
461 
462   // This constructor tests that we can't initialize the flag with char value
463   // but can with explicitly constructed NonDfltConstructible.
NonDfltConstructible__anon9b92d3290911::NonDfltConstructible464   explicit NonDfltConstructible(char c) : value(100 + static_cast<int>(c)) {}
465 
466   int value;
467 };
468 
AbslParseFlag(absl::string_view in,NonDfltConstructible * ndc_out,std::string *)469 bool AbslParseFlag(absl::string_view in, NonDfltConstructible* ndc_out,
470                    std::string*) {
471   return absl::SimpleAtoi(in, &ndc_out->value);
472 }
AbslUnparseFlag(const NonDfltConstructible & ndc)473 std::string AbslUnparseFlag(const NonDfltConstructible& ndc) {
474   return absl::StrCat(ndc.value);
475 }
476 
477 }  // namespace
478 
479 ABSL_FLAG(NonDfltConstructible, ndc_flag1, NonDfltConstructible('1'),
480           "Flag with non default constructible type");
481 ABSL_FLAG(NonDfltConstructible, ndc_flag2, 0,
482           "Flag with non default constructible type");
483 
484 namespace {
485 
TEST_F(FlagTest,TestNonDefaultConstructibleType)486 TEST_F(FlagTest, TestNonDefaultConstructibleType) {
487   EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, '1' + 100);
488   EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 0);
489 
490   absl::SetFlag(&FLAGS_ndc_flag1, NonDfltConstructible('A'));
491   absl::SetFlag(&FLAGS_ndc_flag2, 25);
492 
493   EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, 'A' + 100);
494   EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 25);
495 }
496 
497 // --------------------------------------------------------------------
498 
499 }  // namespace
500 
501 ABSL_RETIRED_FLAG(bool, old_bool_flag, true, "old descr");
502 ABSL_RETIRED_FLAG(int, old_int_flag, (int)std::sqrt(10), "old descr");
503 ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr"));
504 
505 namespace {
506 
TEST_F(FlagTest,TestRetiredFlagRegistration)507 TEST_F(FlagTest, TestRetiredFlagRegistration) {
508   bool is_bool = false;
509   EXPECT_TRUE(flags::IsRetiredFlag("old_bool_flag", &is_bool));
510   EXPECT_TRUE(is_bool);
511   EXPECT_TRUE(flags::IsRetiredFlag("old_int_flag", &is_bool));
512   EXPECT_FALSE(is_bool);
513   EXPECT_TRUE(flags::IsRetiredFlag("old_str_flag", &is_bool));
514   EXPECT_FALSE(is_bool);
515   EXPECT_FALSE(flags::IsRetiredFlag("some_other_flag", &is_bool));
516 }
517 
518 }  // namespace
519