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