commandlineflag_test.cc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. #include "absl/flags/commandlineflag.h"
  16. #include <memory>
  17. #include <string>
  18. #include "gtest/gtest.h"
  19. #include "absl/flags/flag.h"
  20. #include "absl/flags/internal/commandlineflag.h"
  21. #include "absl/flags/internal/private_handle_accessor.h"
  22. #include "absl/flags/reflection.h"
  23. #include "absl/flags/usage_config.h"
  24. #include "absl/memory/memory.h"
  25. #include "absl/strings/match.h"
  26. #include "absl/strings/str_cat.h"
  27. #include "absl/strings/string_view.h"
  28. ABSL_FLAG(int, int_flag, 201, "int_flag help");
  29. ABSL_FLAG(std::string, string_flag, "dflt",
  30. absl::StrCat("string_flag", " help"));
  31. ABSL_RETIRED_FLAG(bool, bool_retired_flag, false, "bool_retired_flag help");
  32. // These are only used to test default values.
  33. ABSL_FLAG(int, int_flag2, 201, "");
  34. ABSL_FLAG(std::string, string_flag2, "dflt", "");
  35. namespace {
  36. namespace flags = absl::flags_internal;
  37. class CommandLineFlagTest : public testing::Test {
  38. protected:
  39. static void SetUpTestSuite() {
  40. // Install a function to normalize filenames before this test is run.
  41. absl::FlagsUsageConfig default_config;
  42. default_config.normalize_filename = &CommandLineFlagTest::NormalizeFileName;
  43. absl::SetFlagsUsageConfig(default_config);
  44. }
  45. void SetUp() override { flag_saver_ = absl::make_unique<absl::FlagSaver>(); }
  46. void TearDown() override { flag_saver_.reset(); }
  47. private:
  48. static std::string NormalizeFileName(absl::string_view fname) {
  49. #ifdef _WIN32
  50. std::string normalized(fname);
  51. std::replace(normalized.begin(), normalized.end(), '\\', '/');
  52. fname = normalized;
  53. #endif
  54. return std::string(fname);
  55. }
  56. std::unique_ptr<absl::FlagSaver> flag_saver_;
  57. };
  58. TEST_F(CommandLineFlagTest, TestAttributesAccessMethods) {
  59. auto* flag_01 = absl::FindCommandLineFlag("int_flag");
  60. ASSERT_TRUE(flag_01);
  61. EXPECT_EQ(flag_01->Name(), "int_flag");
  62. EXPECT_EQ(flag_01->Help(), "int_flag help");
  63. EXPECT_TRUE(!flag_01->IsRetired());
  64. EXPECT_TRUE(flag_01->IsOfType<int>());
  65. EXPECT_TRUE(!flag_01->IsOfType<bool>());
  66. EXPECT_TRUE(!flag_01->IsOfType<std::string>());
  67. EXPECT_TRUE(absl::EndsWith(flag_01->Filename(),
  68. "absl/flags/commandlineflag_test.cc"))
  69. << flag_01->Filename();
  70. auto* flag_02 = absl::FindCommandLineFlag("string_flag");
  71. ASSERT_TRUE(flag_02);
  72. EXPECT_EQ(flag_02->Name(), "string_flag");
  73. EXPECT_EQ(flag_02->Help(), "string_flag help");
  74. EXPECT_TRUE(!flag_02->IsRetired());
  75. EXPECT_TRUE(flag_02->IsOfType<std::string>());
  76. EXPECT_TRUE(!flag_02->IsOfType<bool>());
  77. EXPECT_TRUE(!flag_02->IsOfType<int>());
  78. EXPECT_TRUE(absl::EndsWith(flag_02->Filename(),
  79. "absl/flags/commandlineflag_test.cc"))
  80. << flag_02->Filename();
  81. }
  82. // --------------------------------------------------------------------
  83. TEST_F(CommandLineFlagTest, TestValueAccessMethods) {
  84. absl::SetFlag(&FLAGS_int_flag2, 301);
  85. auto* flag_01 = absl::FindCommandLineFlag("int_flag2");
  86. ASSERT_TRUE(flag_01);
  87. EXPECT_EQ(flag_01->CurrentValue(), "301");
  88. EXPECT_EQ(flag_01->DefaultValue(), "201");
  89. absl::SetFlag(&FLAGS_string_flag2, "new_str_value");
  90. auto* flag_02 = absl::FindCommandLineFlag("string_flag2");
  91. ASSERT_TRUE(flag_02);
  92. EXPECT_EQ(flag_02->CurrentValue(), "new_str_value");
  93. EXPECT_EQ(flag_02->DefaultValue(), "dflt");
  94. }
  95. // --------------------------------------------------------------------
  96. TEST_F(CommandLineFlagTest, TestParseFromCurrentValue) {
  97. std::string err;
  98. auto* flag_01 = absl::FindCommandLineFlag("int_flag");
  99. EXPECT_FALSE(
  100. flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
  101. EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
  102. *flag_01, "11", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err));
  103. EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 11);
  104. EXPECT_FALSE(
  105. flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
  106. EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
  107. *flag_01, "-123", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
  108. err));
  109. EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123);
  110. EXPECT_FALSE(
  111. flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
  112. EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom(
  113. *flag_01, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
  114. err));
  115. EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123);
  116. EXPECT_EQ(err, "Illegal value 'xyz' specified for flag 'int_flag'");
  117. EXPECT_FALSE(
  118. flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
  119. EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom(
  120. *flag_01, "A1", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err));
  121. EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123);
  122. EXPECT_EQ(err, "Illegal value 'A1' specified for flag 'int_flag'");
  123. EXPECT_FALSE(
  124. flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
  125. EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
  126. *flag_01, "0x10", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
  127. err));
  128. EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 16);
  129. EXPECT_FALSE(
  130. flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
  131. EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
  132. *flag_01, "011", flags::SET_FLAGS_VALUE, flags::kCommandLine, err));
  133. EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 11);
  134. EXPECT_TRUE(flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
  135. EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom(
  136. *flag_01, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err));
  137. EXPECT_EQ(err, "Illegal value '' specified for flag 'int_flag'");
  138. auto* flag_02 = absl::FindCommandLineFlag("string_flag");
  139. EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
  140. *flag_02, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
  141. err));
  142. EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "xyz");
  143. EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
  144. *flag_02, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err));
  145. EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "");
  146. }
  147. // --------------------------------------------------------------------
  148. TEST_F(CommandLineFlagTest, TestParseFromDefaultValue) {
  149. std::string err;
  150. auto* flag_01 = absl::FindCommandLineFlag("int_flag");
  151. EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
  152. *flag_01, "111", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange,
  153. err));
  154. EXPECT_EQ(flag_01->DefaultValue(), "111");
  155. auto* flag_02 = absl::FindCommandLineFlag("string_flag");
  156. EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
  157. *flag_02, "abc", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange,
  158. err));
  159. EXPECT_EQ(flag_02->DefaultValue(), "abc");
  160. }
  161. // --------------------------------------------------------------------
  162. TEST_F(CommandLineFlagTest, TestParseFromIfDefault) {
  163. std::string err;
  164. auto* flag_01 = absl::FindCommandLineFlag("int_flag");
  165. EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
  166. *flag_01, "22", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
  167. err))
  168. << err;
  169. EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 22);
  170. EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
  171. *flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
  172. err));
  173. EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 22);
  174. // EXPECT_EQ(err, "ERROR: int_flag is already set to 22");
  175. // Reset back to default value
  176. EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
  177. *flag_01, "201", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
  178. err));
  179. EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
  180. *flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
  181. err));
  182. EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 201);
  183. // EXPECT_EQ(err, "ERROR: int_flag is already set to 201");
  184. }
  185. } // namespace