ccdbb5941 Export of internal Abseil changes 01f5f81f9 Export of internal Abseil changes 2c92bdc7c Export of internal Abseil changes e7ebf9803 Export of internal Abseil changes 2eba343b5 Export of internal Abseil changes a8b03d90e Export of internal Abseil changes 1d31b5c36 Export of internal Abseil changes da3a87690 Export of internal Abseil changes 8faf20461 Exclude empty directories (#697) 2069dc796 Export of internal Abseil changes 4832bf6bf Added a BUILD file in root to expose license. (#695) af8f994af Export of internal Abseil changes 33caf1097 Export of internal Abseil changes cf1a02e2d Export of internal Abseil changes git-subtree-dir: third_party/abseil_cpp git-subtree-split: ccdbb5941f992fabda7eae3ce72f55efc17c826a
895 lines
31 KiB
C++
895 lines
31 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 <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include <cmath>
|
|
#include <new>
|
|
#include <string>
|
|
#include <thread> // NOLINT
|
|
#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/flag.h"
|
|
#include "absl/flags/marshalling.h"
|
|
#include "absl/flags/reflection.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"
|
|
#include "absl/time/time.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"; }
|
|
#if defined(_MSC_VER) && !defined(__clang__)
|
|
std::string TestLiteralHelpMsg() { return "literal help"; }
|
|
#endif
|
|
template <typename T>
|
|
void TestMakeDflt(void* dst) {
|
|
new (dst) T{};
|
|
}
|
|
void TestCallback() {}
|
|
|
|
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);
|
|
}
|
|
absl::FlagSaver flag_saver_;
|
|
};
|
|
|
|
struct S1 {
|
|
S1() = default;
|
|
S1(const S1&) = default;
|
|
int32_t f1;
|
|
int64_t f2;
|
|
};
|
|
|
|
struct S2 {
|
|
S2() = default;
|
|
S2(const S2&) = default;
|
|
int64_t f1;
|
|
double f2;
|
|
};
|
|
|
|
TEST_F(FlagTest, Traits) {
|
|
EXPECT_EQ(flags::StorageKind<int>(),
|
|
flags::FlagValueStorageKind::kOneWordAtomic);
|
|
EXPECT_EQ(flags::StorageKind<bool>(),
|
|
flags::FlagValueStorageKind::kOneWordAtomic);
|
|
EXPECT_EQ(flags::StorageKind<double>(),
|
|
flags::FlagValueStorageKind::kOneWordAtomic);
|
|
EXPECT_EQ(flags::StorageKind<int64_t>(),
|
|
flags::FlagValueStorageKind::kOneWordAtomic);
|
|
|
|
#if defined(ABSL_FLAGS_INTERNAL_ATOMIC_DOUBLE_WORD)
|
|
EXPECT_EQ(flags::StorageKind<S1>(),
|
|
flags::FlagValueStorageKind::kTwoWordsAtomic);
|
|
EXPECT_EQ(flags::StorageKind<S2>(),
|
|
flags::FlagValueStorageKind::kTwoWordsAtomic);
|
|
#else
|
|
EXPECT_EQ(flags::StorageKind<S1>(),
|
|
flags::FlagValueStorageKind::kAlignedBuffer);
|
|
EXPECT_EQ(flags::StorageKind<S2>(),
|
|
flags::FlagValueStorageKind::kAlignedBuffer);
|
|
#endif
|
|
|
|
EXPECT_EQ(flags::StorageKind<std::string>(),
|
|
flags::FlagValueStorageKind::kAlignedBuffer);
|
|
EXPECT_EQ(flags::StorageKind<std::vector<std::string>>(),
|
|
flags::FlagValueStorageKind::kAlignedBuffer);
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
constexpr flags::FlagHelpArg help_arg{flags::FlagHelpMsg("literal help"),
|
|
flags::FlagHelpKind::kLiteral};
|
|
|
|
using String = std::string;
|
|
|
|
#if !defined(_MSC_VER) || defined(__clang__)
|
|
#define DEFINE_CONSTRUCTED_FLAG(T, dflt, dflt_kind) \
|
|
constexpr flags::FlagDefaultArg f1default##T{ \
|
|
flags::FlagDefaultSrc{dflt}, flags::FlagDefaultKind::dflt_kind}; \
|
|
constexpr absl::Flag<T> f1##T{"f1", "file", help_arg, f1default##T}; \
|
|
ABSL_CONST_INIT absl::Flag<T> f2##T { \
|
|
"f2", "file", \
|
|
{flags::FlagHelpMsg(&TestHelpMsg), flags::FlagHelpKind::kGenFunc}, \
|
|
flags::FlagDefaultArg { \
|
|
flags::FlagDefaultSrc(&TestMakeDflt<T>), \
|
|
flags::FlagDefaultKind::kGenFunc \
|
|
} \
|
|
}
|
|
#else
|
|
#define DEFINE_CONSTRUCTED_FLAG(T, dflt, dflt_kind) \
|
|
constexpr flags::FlagDefaultArg f1default##T{ \
|
|
flags::FlagDefaultSrc{dflt}, flags::FlagDefaultKind::dflt_kind}; \
|
|
constexpr absl::Flag<T> f1##T{"f1", "file", &TestLiteralHelpMsg, \
|
|
&TestMakeDflt<T>}; \
|
|
ABSL_CONST_INIT absl::Flag<T> f2##T { \
|
|
"f2", "file", &TestHelpMsg, &TestMakeDflt<T> \
|
|
}
|
|
#endif
|
|
|
|
DEFINE_CONSTRUCTED_FLAG(bool, true, kOneWord);
|
|
DEFINE_CONSTRUCTED_FLAG(int16_t, 1, kOneWord);
|
|
DEFINE_CONSTRUCTED_FLAG(uint16_t, 2, kOneWord);
|
|
DEFINE_CONSTRUCTED_FLAG(int32_t, 3, kOneWord);
|
|
DEFINE_CONSTRUCTED_FLAG(uint32_t, 4, kOneWord);
|
|
DEFINE_CONSTRUCTED_FLAG(int64_t, 5, kOneWord);
|
|
DEFINE_CONSTRUCTED_FLAG(uint64_t, 6, kOneWord);
|
|
DEFINE_CONSTRUCTED_FLAG(float, 7.8, kOneWord);
|
|
DEFINE_CONSTRUCTED_FLAG(double, 9.10, kOneWord);
|
|
DEFINE_CONSTRUCTED_FLAG(String, &TestMakeDflt<String>, kGenFunc);
|
|
DEFINE_CONSTRUCTED_FLAG(UDT, &TestMakeDflt<UDT>, kGenFunc);
|
|
|
|
template <typename T>
|
|
bool TestConstructionFor(const absl::Flag<T>& f1, absl::Flag<T>& f2) {
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Name(), "f1");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Help(), "literal help");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Filename(), "file");
|
|
|
|
flags::FlagRegistrar<T, false>(ABSL_FLAG_IMPL_FLAG_PTR(f2))
|
|
.OnUpdate(TestCallback);
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Name(), "f2");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Help(), "dynamic help");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Filename(), "file");
|
|
|
|
return true;
|
|
}
|
|
|
|
#define TEST_CONSTRUCTED_FLAG(T) TestConstructionFor(f1##T, f2##T);
|
|
|
|
TEST_F(FlagTest, TestConstruction) {
|
|
TEST_CONSTRUCTED_FLAG(bool);
|
|
TEST_CONSTRUCTED_FLAG(int16_t);
|
|
TEST_CONSTRUCTED_FLAG(uint16_t);
|
|
TEST_CONSTRUCTED_FLAG(int32_t);
|
|
TEST_CONSTRUCTED_FLAG(uint32_t);
|
|
TEST_CONSTRUCTED_FLAG(int64_t);
|
|
TEST_CONSTRUCTED_FLAG(uint64_t);
|
|
TEST_CONSTRUCTED_FLAG(float);
|
|
TEST_CONSTRUCTED_FLAG(double);
|
|
TEST_CONSTRUCTED_FLAG(String);
|
|
TEST_CONSTRUCTED_FLAG(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);
|
|
ABSL_DECLARE_FLAG(absl::Duration, test_flag_12);
|
|
|
|
namespace {
|
|
|
|
#if !ABSL_FLAGS_STRIP_NAMES
|
|
|
|
TEST_F(FlagTest, TestFlagDeclaration) {
|
|
// test that we can access flag objects.
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Name(),
|
|
"test_flag_01");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Name(),
|
|
"test_flag_02");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Name(),
|
|
"test_flag_03");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Name(),
|
|
"test_flag_04");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Name(),
|
|
"test_flag_05");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Name(),
|
|
"test_flag_06");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Name(),
|
|
"test_flag_07");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Name(),
|
|
"test_flag_08");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Name(),
|
|
"test_flag_09");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Name(),
|
|
"test_flag_10");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Name(),
|
|
"test_flag_11");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Name(),
|
|
"test_flag_12");
|
|
}
|
|
#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");
|
|
ABSL_FLAG(absl::Duration, test_flag_12, absl::Minutes(10), "test flag 12");
|
|
|
|
namespace {
|
|
|
|
#if !ABSL_FLAGS_STRIP_NAMES
|
|
TEST_F(FlagTest, TestFlagDefinition) {
|
|
absl::string_view expected_file_name = "absl/flags/flag_test.cc";
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Name(),
|
|
"test_flag_01");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Help(),
|
|
"test flag 01");
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Filename(),
|
|
expected_file_name))
|
|
<< absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Filename();
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Name(),
|
|
"test_flag_02");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Help(),
|
|
"test flag 02");
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Filename(),
|
|
expected_file_name))
|
|
<< absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Filename();
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Name(),
|
|
"test_flag_03");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Help(),
|
|
"test flag 03");
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Filename(),
|
|
expected_file_name))
|
|
<< absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Filename();
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Name(),
|
|
"test_flag_04");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Help(),
|
|
"test flag 04");
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Filename(),
|
|
expected_file_name))
|
|
<< absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Filename();
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Name(),
|
|
"test_flag_05");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Help(),
|
|
"test flag 05");
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Filename(),
|
|
expected_file_name))
|
|
<< absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Filename();
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Name(),
|
|
"test_flag_06");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Help(),
|
|
"test flag 06");
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Filename(),
|
|
expected_file_name))
|
|
<< absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Filename();
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Name(),
|
|
"test_flag_07");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Help(),
|
|
"test flag 07");
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Filename(),
|
|
expected_file_name))
|
|
<< absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Filename();
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Name(),
|
|
"test_flag_08");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Help(),
|
|
"test flag 08");
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Filename(),
|
|
expected_file_name))
|
|
<< absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Filename();
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Name(),
|
|
"test_flag_09");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Help(),
|
|
"test flag 09");
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Filename(),
|
|
expected_file_name))
|
|
<< absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Filename();
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Name(),
|
|
"test_flag_10");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Help(),
|
|
"test flag 10");
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Filename(),
|
|
expected_file_name))
|
|
<< absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Filename();
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Name(),
|
|
"test_flag_11");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Help(),
|
|
"test flag 11");
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Filename(),
|
|
expected_file_name))
|
|
<< absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Filename();
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Name(),
|
|
"test_flag_12");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Help(),
|
|
"test flag 12");
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Filename(),
|
|
expected_file_name))
|
|
<< absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Filename();
|
|
}
|
|
#endif // !ABSL_FLAGS_STRIP_NAMES
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
TEST_F(FlagTest, TestDefault) {
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).DefaultValue(),
|
|
"true");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).DefaultValue(),
|
|
"1234");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).DefaultValue(),
|
|
"-34");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).DefaultValue(),
|
|
"189");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).DefaultValue(),
|
|
"10765");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).DefaultValue(),
|
|
"40000");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).DefaultValue(),
|
|
"-1234567");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).DefaultValue(),
|
|
"9876543");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).DefaultValue(),
|
|
"-9.876e-50");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).DefaultValue(),
|
|
"1.234e+12");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).DefaultValue(),
|
|
"");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).DefaultValue(),
|
|
"10m");
|
|
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).CurrentValue(),
|
|
"true");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).CurrentValue(),
|
|
"1234");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).CurrentValue(),
|
|
"-34");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).CurrentValue(),
|
|
"189");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).CurrentValue(),
|
|
"10765");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).CurrentValue(),
|
|
"40000");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).CurrentValue(),
|
|
"-1234567");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).CurrentValue(),
|
|
"9876543");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).CurrentValue(),
|
|
"-9.876e-50");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).CurrentValue(),
|
|
"1.234e+12");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).CurrentValue(),
|
|
"");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).CurrentValue(),
|
|
"10m");
|
|
|
|
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), "");
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), absl::Minutes(10));
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
struct NonTriviallyCopyableAggregate {
|
|
NonTriviallyCopyableAggregate() = default;
|
|
NonTriviallyCopyableAggregate(const NonTriviallyCopyableAggregate& rhs)
|
|
: value(rhs.value) {}
|
|
NonTriviallyCopyableAggregate& operator=(
|
|
const NonTriviallyCopyableAggregate& rhs) {
|
|
value = rhs.value;
|
|
return *this;
|
|
}
|
|
|
|
int value;
|
|
};
|
|
bool AbslParseFlag(absl::string_view src, NonTriviallyCopyableAggregate* f,
|
|
std::string* e) {
|
|
return absl::ParseFlag(src, &f->value, e);
|
|
}
|
|
std::string AbslUnparseFlag(const NonTriviallyCopyableAggregate& ntc) {
|
|
return absl::StrCat(ntc.value);
|
|
}
|
|
|
|
bool operator==(const NonTriviallyCopyableAggregate& ntc1,
|
|
const NonTriviallyCopyableAggregate& ntc2) {
|
|
return ntc1.value == ntc2.value;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
ABSL_FLAG(bool, test_flag_eb_01, {}, "");
|
|
ABSL_FLAG(int32_t, test_flag_eb_02, {}, "");
|
|
ABSL_FLAG(int64_t, test_flag_eb_03, {}, "");
|
|
ABSL_FLAG(double, test_flag_eb_04, {}, "");
|
|
ABSL_FLAG(std::string, test_flag_eb_05, {}, "");
|
|
ABSL_FLAG(NonTriviallyCopyableAggregate, test_flag_eb_06, {}, "");
|
|
|
|
namespace {
|
|
|
|
TEST_F(FlagTest, TestEmptyBracesDefault) {
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_01).DefaultValue(),
|
|
"false");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_02).DefaultValue(),
|
|
"0");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_03).DefaultValue(),
|
|
"0");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_04).DefaultValue(),
|
|
"0");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_05).DefaultValue(),
|
|
"");
|
|
EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_06).DefaultValue(),
|
|
"0");
|
|
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_01), false);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_02), 0);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_03), 0);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_04), 0.0);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_05), "");
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_06),
|
|
NonTriviallyCopyableAggregate{});
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
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");
|
|
|
|
absl::SetFlag(&FLAGS_test_flag_12, absl::Seconds(110));
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), absl::Seconds(110));
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
TEST_F(FlagTest, TestGetViaReflection) {
|
|
auto* handle = absl::FindCommandLineFlag("test_flag_01");
|
|
EXPECT_EQ(*handle->TryGet<bool>(), true);
|
|
handle = absl::FindCommandLineFlag("test_flag_02");
|
|
EXPECT_EQ(*handle->TryGet<int>(), 1234);
|
|
handle = absl::FindCommandLineFlag("test_flag_03");
|
|
EXPECT_EQ(*handle->TryGet<int16_t>(), -34);
|
|
handle = absl::FindCommandLineFlag("test_flag_04");
|
|
EXPECT_EQ(*handle->TryGet<uint16_t>(), 189);
|
|
handle = absl::FindCommandLineFlag("test_flag_05");
|
|
EXPECT_EQ(*handle->TryGet<int32_t>(), 10765);
|
|
handle = absl::FindCommandLineFlag("test_flag_06");
|
|
EXPECT_EQ(*handle->TryGet<uint32_t>(), 40000);
|
|
handle = absl::FindCommandLineFlag("test_flag_07");
|
|
EXPECT_EQ(*handle->TryGet<int64_t>(), -1234567);
|
|
handle = absl::FindCommandLineFlag("test_flag_08");
|
|
EXPECT_EQ(*handle->TryGet<uint64_t>(), 9876543);
|
|
handle = absl::FindCommandLineFlag("test_flag_09");
|
|
EXPECT_NEAR(*handle->TryGet<double>(), -9.876e-50, 1e-55);
|
|
handle = absl::FindCommandLineFlag("test_flag_10");
|
|
EXPECT_NEAR(*handle->TryGet<float>(), 1.234e12f, 1e5f);
|
|
handle = absl::FindCommandLineFlag("test_flag_11");
|
|
EXPECT_EQ(*handle->TryGet<std::string>(), "");
|
|
handle = absl::FindCommandLineFlag("test_flag_12");
|
|
EXPECT_EQ(*handle->TryGet<absl::Duration>(), absl::Minutes(10));
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
int GetDflt1() { return 1; }
|
|
|
|
} // namespace
|
|
|
|
ABSL_FLAG(int, test_int_flag_with_non_const_default, GetDflt1(),
|
|
"test int flag non const default");
|
|
ABSL_FLAG(std::string, test_string_flag_with_non_const_default,
|
|
absl::StrCat("AAA", "BBB"), "test string flag non const default");
|
|
|
|
namespace {
|
|
|
|
TEST_F(FlagTest, TestNonConstexprDefault) {
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_int_flag_with_non_const_default), 1);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_string_flag_with_non_const_default),
|
|
"AAABBB");
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
} // namespace
|
|
|
|
ABSL_FLAG(bool, test_flag_with_non_const_help, true,
|
|
absl::StrCat("test ", "flag ", "non const help"));
|
|
|
|
namespace {
|
|
|
|
#if !ABSL_FLAGS_STRIP_HELP
|
|
TEST_F(FlagTest, TestNonConstexprHelp) {
|
|
EXPECT_EQ(
|
|
absl::GetFlagReflectionHandle(FLAGS_test_flag_with_non_const_help).Help(),
|
|
"test flag non const help");
|
|
}
|
|
#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_custom_udt, CustomUDT(), "test flag custom UDT");
|
|
|
|
namespace {
|
|
|
|
TEST_F(FlagTest, TestCustomUDT) {
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_custom_udt), CustomUDT(1, 1));
|
|
absl::SetFlag(&FLAGS_test_flag_custom_udt, CustomUDT(2, 3));
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_custom_udt), CustomUDT(2, 3));
|
|
}
|
|
|
|
// MSVC produces link error on the type mismatch.
|
|
// Linux does not have build errors and validations work as expected.
|
|
#if !defined(_WIN32) && GTEST_HAS_DEATH_TEST
|
|
|
|
using FlagDeathTest = FlagTest;
|
|
|
|
TEST_F(FlagDeathTest, TestTypeMismatchValidations) {
|
|
#if !defined(NDEBUG)
|
|
EXPECT_DEATH_IF_SUPPORTED(
|
|
static_cast<void>(absl::GetFlag(FLAGS_mistyped_int_flag)),
|
|
"Flag 'mistyped_int_flag' is defined as one type and declared "
|
|
"as another");
|
|
EXPECT_DEATH_IF_SUPPORTED(
|
|
static_cast<void>(absl::GetFlag(FLAGS_mistyped_string_flag)),
|
|
"Flag 'mistyped_string_flag' is defined as one type and "
|
|
"declared as another");
|
|
#endif
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(
|
|
absl::SetFlag(&FLAGS_mistyped_int_flag, 1),
|
|
"Flag 'mistyped_int_flag' is defined as one type and declared "
|
|
"as another");
|
|
EXPECT_DEATH_IF_SUPPORTED(
|
|
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_implicit_conv,
|
|
ConversionTestVal::ViaImplicitConv::kTen,
|
|
"test flag init via implicit conversion");
|
|
|
|
namespace {
|
|
|
|
TEST_F(FlagTest, CanSetViaImplicitConversion) {
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_implicit_conv).a, 10);
|
|
absl::SetFlag(&FLAGS_test_flag_implicit_conv,
|
|
ConversionTestVal::ViaImplicitConv::kEleven);
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_implicit_conv).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) {
|
|
auto* handle = absl::FindCommandLineFlag("old_bool_flag");
|
|
EXPECT_TRUE(handle->IsOfType<bool>());
|
|
EXPECT_TRUE(handle->IsRetired());
|
|
handle = absl::FindCommandLineFlag("old_int_flag");
|
|
EXPECT_TRUE(handle->IsOfType<int>());
|
|
EXPECT_TRUE(handle->IsRetired());
|
|
handle = absl::FindCommandLineFlag("old_str_flag");
|
|
EXPECT_TRUE(handle->IsOfType<std::string>());
|
|
EXPECT_TRUE(handle->IsRetired());
|
|
}
|
|
|
|
} // namespace
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
namespace {
|
|
|
|
// User-defined type with small alignment, but size exceeding 16.
|
|
struct SmallAlignUDT {
|
|
SmallAlignUDT() : c('A'), s(12) {}
|
|
char c;
|
|
int16_t s;
|
|
char bytes[14];
|
|
};
|
|
|
|
bool AbslParseFlag(absl::string_view, SmallAlignUDT*, std::string*) {
|
|
return true;
|
|
}
|
|
std::string AbslUnparseFlag(const SmallAlignUDT&) { return ""; }
|
|
|
|
// User-defined type with small size, but not trivially copyable.
|
|
struct NonTriviallyCopyableUDT {
|
|
NonTriviallyCopyableUDT() : c('A') {}
|
|
NonTriviallyCopyableUDT(const NonTriviallyCopyableUDT& rhs) : c(rhs.c) {}
|
|
NonTriviallyCopyableUDT& operator=(const NonTriviallyCopyableUDT& rhs) {
|
|
c = rhs.c;
|
|
return *this;
|
|
}
|
|
|
|
char c;
|
|
};
|
|
|
|
bool AbslParseFlag(absl::string_view, NonTriviallyCopyableUDT*, std::string*) {
|
|
return true;
|
|
}
|
|
std::string AbslUnparseFlag(const NonTriviallyCopyableUDT&) { return ""; }
|
|
|
|
} // namespace
|
|
|
|
ABSL_FLAG(SmallAlignUDT, test_flag_sa_udt, {}, "help");
|
|
ABSL_FLAG(NonTriviallyCopyableUDT, test_flag_ntc_udt, {}, "help");
|
|
|
|
namespace {
|
|
|
|
TEST_F(FlagTest, TestSmallAlignUDT) {
|
|
SmallAlignUDT value = absl::GetFlag(FLAGS_test_flag_sa_udt);
|
|
EXPECT_EQ(value.c, 'A');
|
|
EXPECT_EQ(value.s, 12);
|
|
|
|
value.c = 'B';
|
|
value.s = 45;
|
|
absl::SetFlag(&FLAGS_test_flag_sa_udt, value);
|
|
value = absl::GetFlag(FLAGS_test_flag_sa_udt);
|
|
EXPECT_EQ(value.c, 'B');
|
|
EXPECT_EQ(value.s, 45);
|
|
}
|
|
|
|
TEST_F(FlagTest, TestNonTriviallyCopyableUDT) {
|
|
NonTriviallyCopyableUDT value = absl::GetFlag(FLAGS_test_flag_ntc_udt);
|
|
EXPECT_EQ(value.c, 'A');
|
|
|
|
value.c = 'B';
|
|
absl::SetFlag(&FLAGS_test_flag_ntc_udt, value);
|
|
value = absl::GetFlag(FLAGS_test_flag_ntc_udt);
|
|
EXPECT_EQ(value.c, 'B');
|
|
}
|
|
|
|
} // namespace
|