-- 167cd2647144583746311129b0cc98a89a9897e1 by Andy Soffer <asoffer@google.com>: Internal Changes PiperOrigin-RevId: 268000987 -- ab44fea7dfdaf763c69609a08ddfac22480ce520 by Derek Mauro <dmauro@google.com>: Fix flags Cmake tests on Windows PiperOrigin-RevId: 267859442 -- d7ec9f7611370b01bc9a5aed7e18460df2a15429 by Abseil Team <absl-team@google.com>: Fix undefined behavior in symbolize_elf.inc PiperOrigin-RevId: 267684904 -- e7c5f8e472a91ed99bdf4876942f2bda5751aa6c by Abseil Team <absl-team@google.com>: Turn off ABSL_HAS_ALARM on Fuchsia. PiperOrigin-RevId: 267666090 -- b7d25d5c71a49e697a8bf6440ed30f2e3f036420 by Chris Kennelly <ckennelly@google.com>: Mark once initialization function as no inline. We expect this code to run infrequently. PiperOrigin-RevId: 267649713 -- dc2a5e5f1e39a03fff837d34a319033fde55d9ba by Derek Mauro <dmauro@google.com>: Fix the MSVC CMake random build PiperOrigin-RevId: 267624074 -- ba2751b67fa17d1b6c53e5ba79f81a5371e4a03a by Abseil Team <absl-team@google.com>: Move "internal/flag.*" files to the "internal" build target. PiperOrigin-RevId: 267588996 -- 05b985a33eec4f8acff1809ad9218a1e22220f34 by Abseil Team <absl-team@google.com>: Move "internal/flag.*" files to the "internal" build target. PiperOrigin-RevId: 267580412 GitOrigin-RevId: 167cd2647144583746311129b0cc98a89a9897e1 Change-Id: Ibd334f46a5671c7c1d3fcf5354029e2fbb7ba91f
		
			
				
	
	
		
			506 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			506 lines
		
	
	
	
		
			16 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 <algorithm>
 | 
						|
#include <string>
 | 
						|
 | 
						|
#include "gtest/gtest.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"
 | 
						|
 | 
						|
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 "help"; }
 | 
						|
template <typename T>
 | 
						|
void* TestMakeDflt() {
 | 
						|
  return new T{};
 | 
						|
}
 | 
						|
void TestCallback() {}
 | 
						|
 | 
						|
template <typename T>
 | 
						|
bool TestConstructionFor() {
 | 
						|
  constexpr flags::Flag<T> f1("f1", &TestHelpMsg, "file",
 | 
						|
                              &absl::flags_internal::FlagMarshallingOps<T>,
 | 
						|
                              &TestMakeDflt<T>);
 | 
						|
  EXPECT_EQ(f1.Name(), "f1");
 | 
						|
  EXPECT_EQ(f1.Help(), "help");
 | 
						|
  EXPECT_EQ(f1.Filename(), "file");
 | 
						|
 | 
						|
  ABSL_CONST_INIT static flags::Flag<T> f2(
 | 
						|
      "f2", &TestHelpMsg, "file", &absl::flags_internal::FlagMarshallingOps<T>,
 | 
						|
      &TestMakeDflt<T>);
 | 
						|
  flags::FlagRegistrar<T, false>(&f2).OnUpdate(TestCallback);
 | 
						|
 | 
						|
  EXPECT_EQ(f2.Name(), "f2");
 | 
						|
  EXPECT_EQ(f2.Help(), "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
 |