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
16 #include "absl/flags/internal/usage.h"
17
18 #include <stdint.h>
19
20 #include <sstream>
21 #include <string>
22
23 #include "gtest/gtest.h"
24 #include "absl/flags/declare.h"
25 #include "absl/flags/flag.h"
26 #include "absl/flags/internal/parse.h"
27 #include "absl/flags/internal/path_util.h"
28 #include "absl/flags/internal/program_name.h"
29 #include "absl/flags/internal/registry.h"
30 #include "absl/flags/usage.h"
31 #include "absl/flags/usage_config.h"
32 #include "absl/memory/memory.h"
33 #include "absl/strings/match.h"
34 #include "absl/strings/string_view.h"
35
36 ABSL_FLAG(int, usage_reporting_test_flag_01, 101,
37 "usage_reporting_test_flag_01 help message");
38 ABSL_FLAG(bool, usage_reporting_test_flag_02, false,
39 "usage_reporting_test_flag_02 help message");
40 ABSL_FLAG(double, usage_reporting_test_flag_03, 1.03,
41 "usage_reporting_test_flag_03 help message");
42 ABSL_FLAG(int64_t, usage_reporting_test_flag_04, 1000000000000004L,
43 "usage_reporting_test_flag_04 help message");
44
45 static const char kTestUsageMessage[] = "Custom usage message";
46
47 struct UDT {
48 UDT() = default;
49 UDT(const UDT&) = default;
50 };
AbslParseFlag(absl::string_view,UDT *,std::string *)51 bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; }
AbslUnparseFlag(const UDT &)52 std::string AbslUnparseFlag(const UDT&) { return "UDT{}"; }
53
54 ABSL_FLAG(UDT, usage_reporting_test_flag_05, {},
55 "usage_reporting_test_flag_05 help message");
56
57 ABSL_FLAG(
58 std::string, usage_reporting_test_flag_06, {},
59 "usage_reporting_test_flag_06 help message.\n"
60 "\n"
61 "Some more help.\n"
62 "Even more long long long long long long long long long long long long "
63 "help message.");
64
65 namespace {
66
67 namespace flags = absl::flags_internal;
68
NormalizeFileName(absl::string_view fname)69 static std::string NormalizeFileName(absl::string_view fname) {
70 #ifdef _WIN32
71 std::string normalized(fname);
72 std::replace(normalized.begin(), normalized.end(), '\\', '/');
73 fname = normalized;
74 #endif
75
76 auto absl_pos = fname.rfind("absl/");
77 if (absl_pos != absl::string_view::npos) {
78 fname = fname.substr(absl_pos);
79 }
80 return std::string(fname);
81 }
82
83 class UsageReportingTest : public testing::Test {
84 protected:
UsageReportingTest()85 UsageReportingTest() {
86 // Install default config for the use on this unit test.
87 // Binary may install a custom config before tests are run.
88 absl::FlagsUsageConfig default_config;
89 default_config.normalize_filename = &NormalizeFileName;
90 absl::SetFlagsUsageConfig(default_config);
91 }
92
93 private:
94 flags::FlagSaver flag_saver_;
95 };
96
97 // --------------------------------------------------------------------
98
99 using UsageReportingDeathTest = UsageReportingTest;
100
TEST_F(UsageReportingDeathTest,TestSetProgramUsageMessage)101 TEST_F(UsageReportingDeathTest, TestSetProgramUsageMessage) {
102 EXPECT_EQ(absl::ProgramUsageMessage(), kTestUsageMessage);
103
104 #ifndef _WIN32
105 // TODO(rogeeff): figure out why this does not work on Windows.
106 EXPECT_DEATH(absl::SetProgramUsageMessage("custom usage message"),
107 ".*SetProgramUsageMessage\\(\\) called twice.*");
108 #endif
109 }
110
111 // --------------------------------------------------------------------
112
TEST_F(UsageReportingTest,TestFlagHelpHRF_on_flag_01)113 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_01) {
114 const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_01");
115 std::stringstream test_buf;
116
117 flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
118 EXPECT_EQ(
119 test_buf.str(),
120 R"( --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
121 default: 101;
122 )");
123 }
124
TEST_F(UsageReportingTest,TestFlagHelpHRF_on_flag_02)125 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_02) {
126 const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_02");
127 std::stringstream test_buf;
128
129 flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
130 EXPECT_EQ(
131 test_buf.str(),
132 R"( --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
133 default: false;
134 )");
135 }
136
TEST_F(UsageReportingTest,TestFlagHelpHRF_on_flag_03)137 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_03) {
138 const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_03");
139 std::stringstream test_buf;
140
141 flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
142 EXPECT_EQ(
143 test_buf.str(),
144 R"( --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
145 default: 1.03;
146 )");
147 }
148
TEST_F(UsageReportingTest,TestFlagHelpHRF_on_flag_04)149 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_04) {
150 const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_04");
151 std::stringstream test_buf;
152
153 flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
154 EXPECT_EQ(
155 test_buf.str(),
156 R"( --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
157 default: 1000000000000004;
158 )");
159 }
160
TEST_F(UsageReportingTest,TestFlagHelpHRF_on_flag_05)161 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_05) {
162 const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_05");
163 std::stringstream test_buf;
164
165 flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
166 EXPECT_EQ(
167 test_buf.str(),
168 R"( --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
169 default: UDT{};
170 )");
171 }
172
173 // --------------------------------------------------------------------
174
TEST_F(UsageReportingTest,TestFlagsHelpHRF)175 TEST_F(UsageReportingTest, TestFlagsHelpHRF) {
176 std::string usage_test_flags_out =
177 R"(usage_test: Custom usage message
178
179 Flags from absl/flags/internal/usage_test.cc:
180 --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
181 default: 101;
182 --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
183 default: false;
184 --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
185 default: 1.03;
186 --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
187 default: 1000000000000004;
188 --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
189 default: UDT{};
190 --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
191
192 Some more help.
193 Even more long long long long long long long long long long long long help
194 message.); default: "";
195 )";
196
197 std::stringstream test_buf_01;
198 flags::FlagsHelp(test_buf_01, "usage_test.cc",
199 flags::HelpFormat::kHumanReadable, kTestUsageMessage);
200 EXPECT_EQ(test_buf_01.str(), usage_test_flags_out);
201
202 std::stringstream test_buf_02;
203 flags::FlagsHelp(test_buf_02, "flags/internal/usage_test.cc",
204 flags::HelpFormat::kHumanReadable, kTestUsageMessage);
205 EXPECT_EQ(test_buf_02.str(), usage_test_flags_out);
206
207 std::stringstream test_buf_03;
208 flags::FlagsHelp(test_buf_03, "usage_test", flags::HelpFormat::kHumanReadable,
209 kTestUsageMessage);
210 EXPECT_EQ(test_buf_03.str(), usage_test_flags_out);
211
212 std::stringstream test_buf_04;
213 flags::FlagsHelp(test_buf_04, "flags/invalid_file_name.cc",
214 flags::HelpFormat::kHumanReadable, kTestUsageMessage);
215 EXPECT_EQ(test_buf_04.str(),
216 R"(usage_test: Custom usage message
217
218 No modules matched: use -helpfull
219 )");
220
221 std::stringstream test_buf_05;
222 flags::FlagsHelp(test_buf_05, "", flags::HelpFormat::kHumanReadable,
223 kTestUsageMessage);
224 std::string test_out = test_buf_05.str();
225 absl::string_view test_out_str(test_out);
226 EXPECT_TRUE(
227 absl::StartsWith(test_out_str, "usage_test: Custom usage message"));
228 EXPECT_TRUE(absl::StrContains(
229 test_out_str, "Flags from absl/flags/internal/usage_test.cc:"));
230 EXPECT_TRUE(absl::StrContains(test_out_str,
231 "Flags from absl/flags/internal/usage.cc:"));
232 EXPECT_TRUE(
233 absl::StrContains(test_out_str, "-usage_reporting_test_flag_01 "));
234 EXPECT_TRUE(absl::StrContains(test_out_str, "-help (show help"))
235 << test_out_str;
236 }
237
238 // --------------------------------------------------------------------
239
TEST_F(UsageReportingTest,TestNoUsageFlags)240 TEST_F(UsageReportingTest, TestNoUsageFlags) {
241 std::stringstream test_buf;
242 EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), -1);
243 }
244
245 // --------------------------------------------------------------------
246
TEST_F(UsageReportingTest,TestUsageFlag_helpshort)247 TEST_F(UsageReportingTest, TestUsageFlag_helpshort) {
248 absl::SetFlag(&FLAGS_helpshort, true);
249
250 std::stringstream test_buf;
251 EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1);
252 EXPECT_EQ(test_buf.str(),
253 R"(usage_test: Custom usage message
254
255 Flags from absl/flags/internal/usage_test.cc:
256 --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
257 default: 101;
258 --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
259 default: false;
260 --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
261 default: 1.03;
262 --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
263 default: 1000000000000004;
264 --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
265 default: UDT{};
266 --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
267
268 Some more help.
269 Even more long long long long long long long long long long long long help
270 message.); default: "";
271 )");
272 }
273
274 // --------------------------------------------------------------------
275
TEST_F(UsageReportingTest,TestUsageFlag_help)276 TEST_F(UsageReportingTest, TestUsageFlag_help) {
277 absl::SetFlag(&FLAGS_help, true);
278
279 std::stringstream test_buf;
280 EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1);
281 EXPECT_EQ(test_buf.str(),
282 R"(usage_test: Custom usage message
283
284 Flags from absl/flags/internal/usage_test.cc:
285 --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
286 default: 101;
287 --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
288 default: false;
289 --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
290 default: 1.03;
291 --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
292 default: 1000000000000004;
293 --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
294 default: UDT{};
295 --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
296
297 Some more help.
298 Even more long long long long long long long long long long long long help
299 message.); default: "";
300
301 Try --helpfull to get a list of all flags.
302 )");
303 }
304
305 // --------------------------------------------------------------------
306
TEST_F(UsageReportingTest,TestUsageFlag_helppackage)307 TEST_F(UsageReportingTest, TestUsageFlag_helppackage) {
308 absl::SetFlag(&FLAGS_helppackage, true);
309
310 std::stringstream test_buf;
311 EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1);
312 EXPECT_EQ(test_buf.str(),
313 R"(usage_test: Custom usage message
314
315 Flags from absl/flags/internal/usage_test.cc:
316 --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
317 default: 101;
318 --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
319 default: false;
320 --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
321 default: 1.03;
322 --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
323 default: 1000000000000004;
324 --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
325 default: UDT{};
326 --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
327
328 Some more help.
329 Even more long long long long long long long long long long long long help
330 message.); default: "";
331
332 Try --helpfull to get a list of all flags.
333 )");
334 }
335
336 // --------------------------------------------------------------------
337
TEST_F(UsageReportingTest,TestUsageFlag_version)338 TEST_F(UsageReportingTest, TestUsageFlag_version) {
339 absl::SetFlag(&FLAGS_version, true);
340
341 std::stringstream test_buf;
342 EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 0);
343 #ifndef NDEBUG
344 EXPECT_EQ(test_buf.str(), "usage_test\nDebug build (NDEBUG not #defined)\n");
345 #else
346 EXPECT_EQ(test_buf.str(), "usage_test\n");
347 #endif
348 }
349
350 // --------------------------------------------------------------------
351
TEST_F(UsageReportingTest,TestUsageFlag_only_check_args)352 TEST_F(UsageReportingTest, TestUsageFlag_only_check_args) {
353 absl::SetFlag(&FLAGS_only_check_args, true);
354
355 std::stringstream test_buf;
356 EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 0);
357 EXPECT_EQ(test_buf.str(), "");
358 }
359
360 // --------------------------------------------------------------------
361
TEST_F(UsageReportingTest,TestUsageFlag_helpon)362 TEST_F(UsageReportingTest, TestUsageFlag_helpon) {
363 absl::SetFlag(&FLAGS_helpon, "bla-bla");
364
365 std::stringstream test_buf_01;
366 EXPECT_EQ(flags::HandleUsageFlags(test_buf_01, kTestUsageMessage), 1);
367 EXPECT_EQ(test_buf_01.str(),
368 R"(usage_test: Custom usage message
369
370 No modules matched: use -helpfull
371 )");
372
373 absl::SetFlag(&FLAGS_helpon, "usage_test");
374
375 std::stringstream test_buf_02;
376 EXPECT_EQ(flags::HandleUsageFlags(test_buf_02, kTestUsageMessage), 1);
377 EXPECT_EQ(test_buf_02.str(),
378 R"(usage_test: Custom usage message
379
380 Flags from absl/flags/internal/usage_test.cc:
381 --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
382 default: 101;
383 --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
384 default: false;
385 --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
386 default: 1.03;
387 --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
388 default: 1000000000000004;
389 --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
390 default: UDT{};
391 --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
392
393 Some more help.
394 Even more long long long long long long long long long long long long help
395 message.); default: "";
396 )");
397 }
398
399 // --------------------------------------------------------------------
400
401 } // namespace
402
main(int argc,char * argv[])403 int main(int argc, char* argv[]) {
404 (void)absl::GetFlag(FLAGS_undefok); // Force linking of parse.cc
405 flags::SetProgramInvocationName("usage_test");
406 absl::SetProgramUsageMessage(kTestUsageMessage);
407 ::testing::InitGoogleTest(&argc, argv);
408
409 return RUN_ALL_TESTS();
410 }
411