72382c21fe
-- dea3e4f33f16bdb1d89cad1f8055b81c0c0cb554 by Andy Getzendanner <durandal@google.com>: Validate in log_severity_test that flags of type absl::LogSeverity are lock-free. PiperOrigin-RevId: 293454285 -- 2a0cd2d8dc193a0cbff4ffa6c5c7037745507419 by Derek Mauro <dmauro@google.com>: Update the testing instructions in CONTRIBUTING.md PiperOrigin-RevId: 293436013 -- cec91c3f635b0b4c8a60955e5926dba4ed980898 by Gennadiy Rozental <rogeeff@google.com>: Introduce struct to represent storage for flag value and normalize naming of internal structs in Flag implementation. There is no semantic changes in this CL. All the internal structs are now named as Flag... We also stop using flags_internal:: qualifications for most of them since the names are unique enough by themselves. PiperOrigin-RevId: 293251467 GitOrigin-RevId: dea3e4f33f16bdb1d89cad1f8055b81c0c0cb554 Change-Id: I161aecc9509edae3e4b77eead02df684b2ce7087
518 lines
17 KiB
C++
518 lines
17 KiB
C++
//
|
|
// Copyright 2019 The Abseil Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "absl/flags/flag.h"
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <cmath>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "gtest/gtest.h"
|
|
#include "absl/base/attributes.h"
|
|
#include "absl/flags/config.h"
|
|
#include "absl/flags/declare.h"
|
|
#include "absl/flags/internal/commandlineflag.h"
|
|
#include "absl/flags/internal/flag.h"
|
|
#include "absl/flags/internal/registry.h"
|
|
#include "absl/flags/usage_config.h"
|
|
#include "absl/strings/match.h"
|
|
#include "absl/strings/numbers.h"
|
|
#include "absl/strings/str_cat.h"
|
|
#include "absl/strings/str_split.h"
|
|
#include "absl/strings/string_view.h"
|
|
|
|
ABSL_DECLARE_FLAG(int64_t, mistyped_int_flag);
|
|
ABSL_DECLARE_FLAG(std::vector<std::string>, mistyped_string_flag);
|
|
|
|
namespace {
|
|
|
|
namespace flags = absl::flags_internal;
|
|
|
|
std::string TestHelpMsg() { return "dynamic help"; }
|
|
template <typename T>
|
|
void* TestMakeDflt() {
|
|
return new T{};
|
|
}
|
|
void TestCallback() {}
|
|
|
|
template <typename T>
|
|
bool TestConstructionFor() {
|
|
constexpr flags::FlagHelpArg help_arg{flags::FlagHelpMsg("literal help"),
|
|
flags::FlagHelpKind::kLiteral};
|
|
constexpr flags::Flag<T> f1("f1", "file", &flags::FlagMarshallingOps<T>,
|
|
help_arg, &TestMakeDflt<T>);
|
|
EXPECT_EQ(f1.Name(), "f1");
|
|
EXPECT_EQ(f1.Help(), "literal help");
|
|
EXPECT_EQ(f1.Filename(), "file");
|
|
|
|
ABSL_CONST_INIT static flags::Flag<T> f2(
|
|
"f2", "file", &flags::FlagMarshallingOps<T>,
|
|
{flags::FlagHelpMsg(&TestHelpMsg), flags::FlagHelpKind::kGenFunc},
|
|
&TestMakeDflt<T>);
|
|
flags::FlagRegistrar<T, false>(&f2).OnUpdate(TestCallback);
|
|
|
|
EXPECT_EQ(f2.Name(), "f2");
|
|
EXPECT_EQ(f2.Help(), "dynamic help");
|
|
EXPECT_EQ(f2.Filename(), "file");
|
|
|
|
return true;
|
|
}
|
|
|
|
struct UDT {
|
|
UDT() = default;
|
|
UDT(const UDT&) = default;
|
|
};
|
|
bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; }
|
|
std::string AbslUnparseFlag(const UDT&) { return ""; }
|
|
|
|
class FlagTest : public testing::Test {
|
|
protected:
|
|
static void SetUpTestSuite() {
|
|
// Install a function to normalize filenames before this test is run.
|
|
absl::FlagsUsageConfig default_config;
|
|
default_config.normalize_filename = &FlagTest::NormalizeFileName;
|
|
absl::SetFlagsUsageConfig(default_config);
|
|
}
|
|
|
|
private:
|
|
static std::string NormalizeFileName(absl::string_view fname) {
|
|
#ifdef _WIN32
|
|
std::string normalized(fname);
|
|
std::replace(normalized.begin(), normalized.end(), '\\', '/');
|
|
fname = normalized;
|
|
#endif
|
|
return std::string(fname);
|
|
}
|
|
};
|
|
|
|
TEST_F(FlagTest, TestConstruction) {
|
|
TestConstructionFor<bool>();
|
|
TestConstructionFor<int16_t>();
|
|
TestConstructionFor<uint16_t>();
|
|
TestConstructionFor<int32_t>();
|
|
TestConstructionFor<uint32_t>();
|
|
TestConstructionFor<int64_t>();
|
|
TestConstructionFor<uint64_t>();
|
|
TestConstructionFor<double>();
|
|
TestConstructionFor<float>();
|
|
TestConstructionFor<std::string>();
|
|
|
|
TestConstructionFor<UDT>();
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
} // namespace
|
|
|
|
ABSL_DECLARE_FLAG(bool, test_flag_01);
|
|
ABSL_DECLARE_FLAG(int, test_flag_02);
|
|
ABSL_DECLARE_FLAG(int16_t, test_flag_03);
|
|
ABSL_DECLARE_FLAG(uint16_t, test_flag_04);
|
|
ABSL_DECLARE_FLAG(int32_t, test_flag_05);
|
|
ABSL_DECLARE_FLAG(uint32_t, test_flag_06);
|
|
ABSL_DECLARE_FLAG(int64_t, test_flag_07);
|
|
ABSL_DECLARE_FLAG(uint64_t, test_flag_08);
|
|
ABSL_DECLARE_FLAG(double, test_flag_09);
|
|
ABSL_DECLARE_FLAG(float, test_flag_10);
|
|
ABSL_DECLARE_FLAG(std::string, test_flag_11);
|
|
|
|
namespace {
|
|
|
|
#if !ABSL_FLAGS_STRIP_NAMES
|
|
|
|
TEST_F(FlagTest, TestFlagDeclaration) {
|
|
// test that we can access flag objects.
|
|
EXPECT_EQ(FLAGS_test_flag_01.Name(), "test_flag_01");
|
|
EXPECT_EQ(FLAGS_test_flag_02.Name(), "test_flag_02");
|
|
EXPECT_EQ(FLAGS_test_flag_03.Name(), "test_flag_03");
|
|
EXPECT_EQ(FLAGS_test_flag_04.Name(), "test_flag_04");
|
|
EXPECT_EQ(FLAGS_test_flag_05.Name(), "test_flag_05");
|
|
EXPECT_EQ(FLAGS_test_flag_06.Name(), "test_flag_06");
|
|
EXPECT_EQ(FLAGS_test_flag_07.Name(), "test_flag_07");
|
|
EXPECT_EQ(FLAGS_test_flag_08.Name(), "test_flag_08");
|
|
EXPECT_EQ(FLAGS_test_flag_09.Name(), "test_flag_09");
|
|
EXPECT_EQ(FLAGS_test_flag_10.Name(), "test_flag_10");
|
|
EXPECT_EQ(FLAGS_test_flag_11.Name(), "test_flag_11");
|
|
}
|
|
#endif // !ABSL_FLAGS_STRIP_NAMES
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
} // namespace
|
|
|
|
ABSL_FLAG(bool, test_flag_01, true, "test flag 01");
|
|
ABSL_FLAG(int, test_flag_02, 1234, "test flag 02");
|
|
ABSL_FLAG(int16_t, test_flag_03, -34, "test flag 03");
|
|
ABSL_FLAG(uint16_t, test_flag_04, 189, "test flag 04");
|
|
ABSL_FLAG(int32_t, test_flag_05, 10765, "test flag 05");
|
|
ABSL_FLAG(uint32_t, test_flag_06, 40000, "test flag 06");
|
|
ABSL_FLAG(int64_t, test_flag_07, -1234567, "test flag 07");
|
|
ABSL_FLAG(uint64_t, test_flag_08, 9876543, "test flag 08");
|
|
ABSL_FLAG(double, test_flag_09, -9.876e-50, "test flag 09");
|
|
ABSL_FLAG(float, test_flag_10, 1.234e12f, "test flag 10");
|
|
ABSL_FLAG(std::string, test_flag_11, "", "test flag 11");
|
|
|
|
namespace {
|
|
|
|
#if !ABSL_FLAGS_STRIP_NAMES
|
|
TEST_F(FlagTest, TestFlagDefinition) {
|
|
absl::string_view expected_file_name = "absl/flags/flag_test.cc";
|
|
|
|
EXPECT_EQ(FLAGS_test_flag_01.Name(), "test_flag_01");
|
|
EXPECT_EQ(FLAGS_test_flag_01.Help(), "test flag 01");
|
|
EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_01.Filename(), expected_file_name))
|
|
<< FLAGS_test_flag_01.Filename();
|
|
|
|
EXPECT_EQ(FLAGS_test_flag_02.Name(), "test_flag_02");
|
|
EXPECT_EQ(FLAGS_test_flag_02.Help(), "test flag 02");
|
|
EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_02.Filename(), expected_file_name))
|
|
<< FLAGS_test_flag_02.Filename();
|
|
|
|
EXPECT_EQ(FLAGS_test_flag_03.Name(), "test_flag_03");
|
|
EXPECT_EQ(FLAGS_test_flag_03.Help(), "test flag 03");
|
|
EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_03.Filename(), expected_file_name))
|
|
<< FLAGS_test_flag_03.Filename();
|
|
|
|
EXPECT_EQ(FLAGS_test_flag_04.Name(), "test_flag_04");
|
|
EXPECT_EQ(FLAGS_test_flag_04.Help(), "test flag 04");
|
|
EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_04.Filename(), expected_file_name))
|
|
<< FLAGS_test_flag_04.Filename();
|
|
|
|
EXPECT_EQ(FLAGS_test_flag_05.Name(), "test_flag_05");
|
|
EXPECT_EQ(FLAGS_test_flag_05.Help(), "test flag 05");
|
|
EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_05.Filename(), expected_file_name))
|
|
<< FLAGS_test_flag_05.Filename();
|
|
|
|
EXPECT_EQ(FLAGS_test_flag_06.Name(), "test_flag_06");
|
|
EXPECT_EQ(FLAGS_test_flag_06.Help(), "test flag 06");
|
|
EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_06.Filename(), expected_file_name))
|
|
<< FLAGS_test_flag_06.Filename();
|
|
|
|
EXPECT_EQ(FLAGS_test_flag_07.Name(), "test_flag_07");
|
|
EXPECT_EQ(FLAGS_test_flag_07.Help(), "test flag 07");
|
|
EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_07.Filename(), expected_file_name))
|
|
<< FLAGS_test_flag_07.Filename();
|
|
|
|
EXPECT_EQ(FLAGS_test_flag_08.Name(), "test_flag_08");
|
|
EXPECT_EQ(FLAGS_test_flag_08.Help(), "test flag 08");
|
|
EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_08.Filename(), expected_file_name))
|
|
<< FLAGS_test_flag_08.Filename();
|
|
|
|
EXPECT_EQ(FLAGS_test_flag_09.Name(), "test_flag_09");
|
|
EXPECT_EQ(FLAGS_test_flag_09.Help(), "test flag 09");
|
|
EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_09.Filename(), expected_file_name))
|
|
<< FLAGS_test_flag_09.Filename();
|
|
|
|
EXPECT_EQ(FLAGS_test_flag_10.Name(), "test_flag_10");
|
|
EXPECT_EQ(FLAGS_test_flag_10.Help(), "test flag 10");
|
|
EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_10.Filename(), expected_file_name))
|
|
<< FLAGS_test_flag_10.Filename();
|
|
|
|
EXPECT_EQ(FLAGS_test_flag_11.Name(), "test_flag_11");
|
|
EXPECT_EQ(FLAGS_test_flag_11.Help(), "test flag 11");
|
|
EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_11.Filename(), expected_file_name))
|
|
<< FLAGS_test_flag_11.Filename();
|
|
}
|
|
#endif // !ABSL_FLAGS_STRIP_NAMES
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
TEST_F(FlagTest, TestDefault) {
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), true);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 1234);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), -34);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_04), 189);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_05), 10765);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_06), 40000);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_07), -1234567);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_08), 9876543);
|
|
EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_09), -9.876e-50, 1e-55);
|
|
EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_10), 1.234e12f, 1e5f);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_11), "");
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
TEST_F(FlagTest, TestGetSet) {
|
|
absl::SetFlag(&FLAGS_test_flag_01, false);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), false);
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_02, 321);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 321);
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_03, 67);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), 67);
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_04, 1);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_04), 1);
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_05, -908);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_05), -908);
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_06, 4001);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_06), 4001);
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_07, -23456);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_07), -23456);
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_08, 975310);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_08), 975310);
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_09, 1.00001);
|
|
EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_09), 1.00001, 1e-10);
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_10, -3.54f);
|
|
EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_10), -3.54f, 1e-6f);
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_11, "asdf");
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_11), "asdf");
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
int GetDflt1() { return 1; }
|
|
|
|
} // namespace
|
|
|
|
ABSL_FLAG(int, test_flag_12, GetDflt1(), "test flag 12");
|
|
ABSL_FLAG(std::string, test_flag_13, absl::StrCat("AAA", "BBB"),
|
|
"test flag 13");
|
|
|
|
namespace {
|
|
|
|
TEST_F(FlagTest, TestNonConstexprDefault) {
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), 1);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_13), "AAABBB");
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
} // namespace
|
|
|
|
ABSL_FLAG(bool, test_flag_14, true, absl::StrCat("test ", "flag ", "14"));
|
|
|
|
namespace {
|
|
|
|
#if !ABSL_FLAGS_STRIP_HELP
|
|
TEST_F(FlagTest, TestNonConstexprHelp) {
|
|
EXPECT_EQ(FLAGS_test_flag_14.Help(), "test flag 14");
|
|
}
|
|
#endif //! ABSL_FLAGS_STRIP_HELP
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
int cb_test_value = -1;
|
|
void TestFlagCB();
|
|
|
|
} // namespace
|
|
|
|
ABSL_FLAG(int, test_flag_with_cb, 100, "").OnUpdate(TestFlagCB);
|
|
|
|
ABSL_FLAG(int, test_flag_with_lambda_cb, 200, "").OnUpdate([]() {
|
|
cb_test_value = absl::GetFlag(FLAGS_test_flag_with_lambda_cb) +
|
|
absl::GetFlag(FLAGS_test_flag_with_cb);
|
|
});
|
|
|
|
namespace {
|
|
|
|
void TestFlagCB() { cb_test_value = absl::GetFlag(FLAGS_test_flag_with_cb); }
|
|
|
|
// Tests side-effects of callback invocation.
|
|
TEST_F(FlagTest, CallbackInvocation) {
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_cb), 100);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_lambda_cb), 200);
|
|
EXPECT_EQ(cb_test_value, 300);
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_with_cb, 1);
|
|
EXPECT_EQ(cb_test_value, 1);
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_with_lambda_cb, 3);
|
|
EXPECT_EQ(cb_test_value, 4);
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
struct CustomUDT {
|
|
CustomUDT() : a(1), b(1) {}
|
|
CustomUDT(int a_, int b_) : a(a_), b(b_) {}
|
|
|
|
friend bool operator==(const CustomUDT& f1, const CustomUDT& f2) {
|
|
return f1.a == f2.a && f1.b == f2.b;
|
|
}
|
|
|
|
int a;
|
|
int b;
|
|
};
|
|
bool AbslParseFlag(absl::string_view in, CustomUDT* f, std::string*) {
|
|
std::vector<absl::string_view> parts =
|
|
absl::StrSplit(in, ':', absl::SkipWhitespace());
|
|
|
|
if (parts.size() != 2) return false;
|
|
|
|
if (!absl::SimpleAtoi(parts[0], &f->a)) return false;
|
|
|
|
if (!absl::SimpleAtoi(parts[1], &f->b)) return false;
|
|
|
|
return true;
|
|
}
|
|
std::string AbslUnparseFlag(const CustomUDT& f) {
|
|
return absl::StrCat(f.a, ":", f.b);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
ABSL_FLAG(CustomUDT, test_flag_15, CustomUDT(), "test flag 15");
|
|
|
|
namespace {
|
|
|
|
TEST_F(FlagTest, TestCustomUDT) {
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_15), CustomUDT(1, 1));
|
|
absl::SetFlag(&FLAGS_test_flag_15, CustomUDT(2, 3));
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_15), CustomUDT(2, 3));
|
|
}
|
|
|
|
// MSVC produces link error on the type mismatch.
|
|
// Linux does not have build errors and validations work as expected.
|
|
#if 0 // !defined(_WIN32) && GTEST_HAS_DEATH_TEST
|
|
|
|
TEST(Flagtest, TestTypeMismatchValidations) {
|
|
// For builtin types, GetFlag() only does validation in debug mode.
|
|
EXPECT_DEBUG_DEATH(
|
|
absl::GetFlag(FLAGS_mistyped_int_flag),
|
|
"Flag 'mistyped_int_flag' is defined as one type and declared "
|
|
"as another");
|
|
EXPECT_DEATH(absl::SetFlag(&FLAGS_mistyped_int_flag, 0),
|
|
"Flag 'mistyped_int_flag' is defined as one type and declared "
|
|
"as another");
|
|
|
|
EXPECT_DEATH(absl::GetFlag(FLAGS_mistyped_string_flag),
|
|
"Flag 'mistyped_string_flag' is defined as one type and "
|
|
"declared as another");
|
|
EXPECT_DEATH(
|
|
absl::SetFlag(&FLAGS_mistyped_string_flag, std::vector<std::string>{}),
|
|
"Flag 'mistyped_string_flag' is defined as one type and declared as "
|
|
"another");
|
|
}
|
|
|
|
#endif
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
// A contrived type that offers implicit and explicit conversion from specific
|
|
// source types.
|
|
struct ConversionTestVal {
|
|
ConversionTestVal() = default;
|
|
explicit ConversionTestVal(int a_in) : a(a_in) {}
|
|
|
|
enum class ViaImplicitConv { kTen = 10, kEleven };
|
|
// NOLINTNEXTLINE
|
|
ConversionTestVal(ViaImplicitConv from) : a(static_cast<int>(from)) {}
|
|
|
|
int a;
|
|
};
|
|
|
|
bool AbslParseFlag(absl::string_view in, ConversionTestVal* val_out,
|
|
std::string*) {
|
|
if (!absl::SimpleAtoi(in, &val_out->a)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
std::string AbslUnparseFlag(const ConversionTestVal& val) {
|
|
return absl::StrCat(val.a);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
// Flag default values can be specified with a value that converts to the flag
|
|
// value type implicitly.
|
|
ABSL_FLAG(ConversionTestVal, test_flag_16,
|
|
ConversionTestVal::ViaImplicitConv::kTen, "test flag 16");
|
|
|
|
namespace {
|
|
|
|
TEST_F(FlagTest, CanSetViaImplicitConversion) {
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_16).a, 10);
|
|
absl::SetFlag(&FLAGS_test_flag_16,
|
|
ConversionTestVal::ViaImplicitConv::kEleven);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_16).a, 11);
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
struct NonDfltConstructible {
|
|
public:
|
|
// This constructor tests that we can initialize the flag with int value
|
|
NonDfltConstructible(int i) : value(i) {} // NOLINT
|
|
|
|
// This constructor tests that we can't initialize the flag with char value
|
|
// but can with explicitly constructed NonDfltConstructible.
|
|
explicit NonDfltConstructible(char c) : value(100 + static_cast<int>(c)) {}
|
|
|
|
int value;
|
|
};
|
|
|
|
bool AbslParseFlag(absl::string_view in, NonDfltConstructible* ndc_out,
|
|
std::string*) {
|
|
return absl::SimpleAtoi(in, &ndc_out->value);
|
|
}
|
|
std::string AbslUnparseFlag(const NonDfltConstructible& ndc) {
|
|
return absl::StrCat(ndc.value);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
ABSL_FLAG(NonDfltConstructible, ndc_flag1, NonDfltConstructible('1'),
|
|
"Flag with non default constructible type");
|
|
ABSL_FLAG(NonDfltConstructible, ndc_flag2, 0,
|
|
"Flag with non default constructible type");
|
|
|
|
namespace {
|
|
|
|
TEST_F(FlagTest, TestNonDefaultConstructibleType) {
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, '1' + 100);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 0);
|
|
|
|
absl::SetFlag(&FLAGS_ndc_flag1, NonDfltConstructible('A'));
|
|
absl::SetFlag(&FLAGS_ndc_flag2, 25);
|
|
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, 'A' + 100);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 25);
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
} // namespace
|
|
|
|
ABSL_RETIRED_FLAG(bool, old_bool_flag, true, "old descr");
|
|
ABSL_RETIRED_FLAG(int, old_int_flag, (int)std::sqrt(10), "old descr");
|
|
ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr"));
|
|
|
|
namespace {
|
|
|
|
TEST_F(FlagTest, TestRetiredFlagRegistration) {
|
|
bool is_bool = false;
|
|
EXPECT_TRUE(flags::IsRetiredFlag("old_bool_flag", &is_bool));
|
|
EXPECT_TRUE(is_bool);
|
|
EXPECT_TRUE(flags::IsRetiredFlag("old_int_flag", &is_bool));
|
|
EXPECT_FALSE(is_bool);
|
|
EXPECT_TRUE(flags::IsRetiredFlag("old_str_flag", &is_bool));
|
|
EXPECT_FALSE(is_bool);
|
|
EXPECT_FALSE(flags::IsRetiredFlag("some_other_flag", &is_bool));
|
|
}
|
|
|
|
} // namespace
|