• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 #include "absl/flags/flag.h"
26 #include "absl/flags/internal/parse.h"
27 #include "absl/flags/internal/program_name.h"
28 #include "absl/flags/reflection.h"
29 #include "absl/flags/usage.h"
30 #include "absl/flags/usage_config.h"
31 #include "absl/strings/match.h"
32 #include "absl/strings/string_view.h"
33 
34 ABSL_FLAG(int, usage_reporting_test_flag_01, 101,
35           "usage_reporting_test_flag_01 help message");
36 ABSL_FLAG(bool, usage_reporting_test_flag_02, false,
37           "usage_reporting_test_flag_02 help message");
38 ABSL_FLAG(double, usage_reporting_test_flag_03, 1.03,
39           "usage_reporting_test_flag_03 help message");
40 ABSL_FLAG(int64_t, usage_reporting_test_flag_04, 1000000000000004L,
41           "usage_reporting_test_flag_04 help message");
42 ABSL_FLAG(std::string, usage_reporting_test_flag_07, "\r\n\f\v\a\b\t ",
43           "usage_reporting_test_flag_07 help \r\n\f\v\a\b\t ");
44 
45 static const char kTestUsageMessage[] = "Custom usage message";
46 
47 struct UDT {
48   UDT() = default;
49   UDT(const UDT&) = default;
50   UDT& operator=(const UDT&) = default;
51 };
AbslParseFlag(absl::string_view,UDT *,std::string *)52 static bool AbslParseFlag(absl::string_view, UDT*, std::string*) {
53   return true;
54 }
AbslUnparseFlag(const UDT &)55 static std::string AbslUnparseFlag(const UDT&) { return "UDT{}"; }
56 
57 ABSL_FLAG(UDT, usage_reporting_test_flag_05, {},
58           "usage_reporting_test_flag_05 help message");
59 
60 ABSL_FLAG(
61     std::string, usage_reporting_test_flag_06, {},
62     "usage_reporting_test_flag_06 help message.\n"
63     "\n"
64     "Some more help.\n"
65     "Even more long long long long long long long long long long long long "
66     "help message.");
67 
68 namespace {
69 
70 namespace flags = absl::flags_internal;
71 
NormalizeFileName(absl::string_view fname)72 static std::string NormalizeFileName(absl::string_view fname) {
73 #ifdef _WIN32
74   std::string normalized(fname);
75   std::replace(normalized.begin(), normalized.end(), '\\', '/');
76   fname = normalized;
77 #endif
78 
79   auto absl_pos = fname.rfind("absl/");
80   if (absl_pos != absl::string_view::npos) {
81     fname = fname.substr(absl_pos);
82   }
83   return std::string(fname);
84 }
85 
86 class UsageReportingTest : public testing::Test {
87  protected:
UsageReportingTest()88   UsageReportingTest() {
89     // Install default config for the use on this unit test.
90     // Binary may install a custom config before tests are run.
91     absl::FlagsUsageConfig default_config;
92     default_config.normalize_filename = &NormalizeFileName;
93     absl::SetFlagsUsageConfig(default_config);
94   }
~UsageReportingTest()95   ~UsageReportingTest() override {
96     flags::SetFlagsHelpMode(flags::HelpMode::kNone);
97     flags::SetFlagsHelpMatchSubstr("");
98     flags::SetFlagsHelpFormat(flags::HelpFormat::kHumanReadable);
99   }
100 
101  private:
102   absl::FlagSaver flag_saver_;
103 };
104 
105 // --------------------------------------------------------------------
106 
107 using UsageReportingDeathTest = UsageReportingTest;
108 
TEST_F(UsageReportingDeathTest,TestSetProgramUsageMessage)109 TEST_F(UsageReportingDeathTest, TestSetProgramUsageMessage) {
110 #if !defined(GTEST_HAS_ABSL) || !GTEST_HAS_ABSL
111   // Check for kTestUsageMessage set in main() below.
112   EXPECT_EQ(absl::ProgramUsageMessage(), kTestUsageMessage);
113 #else
114   // Check for part of the usage message set by GoogleTest.
115   EXPECT_THAT(absl::ProgramUsageMessage(),
116               ::testing::HasSubstr(
117                   "This program contains tests written using Google Test"));
118 #endif
119 
120   EXPECT_DEATH_IF_SUPPORTED(
121       absl::SetProgramUsageMessage("custom usage message"),
122       ::testing::HasSubstr("SetProgramUsageMessage() called twice"));
123 }
124 
125 // --------------------------------------------------------------------
126 
TEST_F(UsageReportingTest,TestFlagHelpHRF_on_flag_01)127 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_01) {
128   const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_01");
129   std::stringstream test_buf;
130 
131   flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
132   EXPECT_EQ(
133       test_buf.str(),
134       R"(    --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
135       default: 101;
136 )");
137 }
138 
TEST_F(UsageReportingTest,TestFlagHelpHRF_on_flag_02)139 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_02) {
140   const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_02");
141   std::stringstream test_buf;
142 
143   flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
144   EXPECT_EQ(
145       test_buf.str(),
146       R"(    --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
147       default: false;
148 )");
149 }
150 
TEST_F(UsageReportingTest,TestFlagHelpHRF_on_flag_03)151 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_03) {
152   const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_03");
153   std::stringstream test_buf;
154 
155   flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
156   EXPECT_EQ(
157       test_buf.str(),
158       R"(    --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
159       default: 1.03;
160 )");
161 }
162 
TEST_F(UsageReportingTest,TestFlagHelpHRF_on_flag_04)163 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_04) {
164   const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_04");
165   std::stringstream test_buf;
166 
167   flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
168   EXPECT_EQ(
169       test_buf.str(),
170       R"(    --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
171       default: 1000000000000004;
172 )");
173 }
174 
TEST_F(UsageReportingTest,TestFlagHelpHRF_on_flag_05)175 TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_05) {
176   const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_05");
177   std::stringstream test_buf;
178 
179   flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
180   EXPECT_EQ(
181       test_buf.str(),
182       R"(    --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
183       default: UDT{};
184 )");
185 }
186 
187 // --------------------------------------------------------------------
188 
TEST_F(UsageReportingTest,TestFlagsHelpHRF)189 TEST_F(UsageReportingTest, TestFlagsHelpHRF) {
190   std::string usage_test_flags_out =
191       R"(usage_test: Custom usage message
192 
193   Flags from absl/flags/internal/usage_test.cc:
194     --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
195       default: 101;
196     --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
197       default: false;
198     --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
199       default: 1.03;
200     --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
201       default: 1000000000000004;
202     --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
203       default: UDT{};
204     --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
205 
206       Some more help.
207       Even more long long long long long long long long long long long long help
208       message.); default: "";)"
209 
210       "\n    --usage_reporting_test_flag_07 (usage_reporting_test_flag_07 "
211       "help\n\n      \f\v\a\b ); default: \"\r\n\f\v\a\b\t \";\n"
212 
213       R"(
214 Try --helpfull to get a list of all flags or --help=substring shows help for
215 flags which include specified substring in either in the name, or description or
216 path.
217 )";
218 
219   std::stringstream test_buf_01;
220   flags::FlagsHelp(test_buf_01, "usage_test.cc",
221                    flags::HelpFormat::kHumanReadable, kTestUsageMessage);
222   EXPECT_EQ(test_buf_01.str(), usage_test_flags_out);
223 
224   std::stringstream test_buf_02;
225   flags::FlagsHelp(test_buf_02, "flags/internal/usage_test.cc",
226                    flags::HelpFormat::kHumanReadable, kTestUsageMessage);
227   EXPECT_EQ(test_buf_02.str(), usage_test_flags_out);
228 
229   std::stringstream test_buf_03;
230   flags::FlagsHelp(test_buf_03, "usage_test", flags::HelpFormat::kHumanReadable,
231                    kTestUsageMessage);
232   EXPECT_EQ(test_buf_03.str(), usage_test_flags_out);
233 
234   std::stringstream test_buf_04;
235   flags::FlagsHelp(test_buf_04, "flags/invalid_file_name.cc",
236                    flags::HelpFormat::kHumanReadable, kTestUsageMessage);
237   EXPECT_EQ(test_buf_04.str(),
238             R"(usage_test: Custom usage message
239 
240 No flags matched.
241 
242 Try --helpfull to get a list of all flags or --help=substring shows help for
243 flags which include specified substring in either in the name, or description or
244 path.
245 )");
246 
247   std::stringstream test_buf_05;
248   flags::FlagsHelp(test_buf_05, "", flags::HelpFormat::kHumanReadable,
249                    kTestUsageMessage);
250   std::string test_out = test_buf_05.str();
251   absl::string_view test_out_str(test_out);
252   EXPECT_TRUE(
253       absl::StartsWith(test_out_str, "usage_test: Custom usage message"));
254   EXPECT_TRUE(absl::StrContains(
255       test_out_str, "Flags from absl/flags/internal/usage_test.cc:"));
256   EXPECT_TRUE(
257       absl::StrContains(test_out_str, "-usage_reporting_test_flag_01 "));
258 }
259 
260 // --------------------------------------------------------------------
261 
TEST_F(UsageReportingTest,TestNoUsageFlags)262 TEST_F(UsageReportingTest, TestNoUsageFlags) {
263   std::stringstream test_buf;
264   EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage),
265             flags::HelpMode::kNone);
266 }
267 
268 // --------------------------------------------------------------------
269 
TEST_F(UsageReportingTest,TestUsageFlag_helpshort)270 TEST_F(UsageReportingTest, TestUsageFlag_helpshort) {
271   flags::SetFlagsHelpMode(flags::HelpMode::kShort);
272 
273   std::stringstream test_buf;
274   EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage),
275             flags::HelpMode::kShort);
276   EXPECT_EQ(
277       test_buf.str(),
278       R"(usage_test: Custom usage message
279 
280   Flags from absl/flags/internal/usage_test.cc:
281     --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
282       default: 101;
283     --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
284       default: false;
285     --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
286       default: 1.03;
287     --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
288       default: 1000000000000004;
289     --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
290       default: UDT{};
291     --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
292 
293       Some more help.
294       Even more long long long long long long long long long long long long help
295       message.); default: "";)"
296 
297       "\n    --usage_reporting_test_flag_07 (usage_reporting_test_flag_07 "
298       "help\n\n      \f\v\a\b ); default: \"\r\n\f\v\a\b\t \";\n"
299 
300       R"(
301 Try --helpfull to get a list of all flags or --help=substring shows help for
302 flags which include specified substring in either in the name, or description or
303 path.
304 )");
305 }
306 
307 // --------------------------------------------------------------------
308 
TEST_F(UsageReportingTest,TestUsageFlag_help_simple)309 TEST_F(UsageReportingTest, TestUsageFlag_help_simple) {
310   flags::SetFlagsHelpMode(flags::HelpMode::kImportant);
311 
312   std::stringstream test_buf;
313   EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage),
314             flags::HelpMode::kImportant);
315   EXPECT_EQ(
316       test_buf.str(),
317       R"(usage_test: Custom usage message
318 
319   Flags from absl/flags/internal/usage_test.cc:
320     --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
321       default: 101;
322     --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
323       default: false;
324     --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
325       default: 1.03;
326     --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
327       default: 1000000000000004;
328     --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
329       default: UDT{};
330     --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
331 
332       Some more help.
333       Even more long long long long long long long long long long long long help
334       message.); default: "";)"
335 
336       "\n    --usage_reporting_test_flag_07 (usage_reporting_test_flag_07 "
337       "help\n\n      \f\v\a\b ); default: \"\r\n\f\v\a\b\t \";\n"
338 
339       R"(
340 Try --helpfull to get a list of all flags or --help=substring shows help for
341 flags which include specified substring in either in the name, or description or
342 path.
343 )");
344 }
345 
346 // --------------------------------------------------------------------
347 
TEST_F(UsageReportingTest,TestUsageFlag_help_one_flag)348 TEST_F(UsageReportingTest, TestUsageFlag_help_one_flag) {
349   flags::SetFlagsHelpMode(flags::HelpMode::kMatch);
350   flags::SetFlagsHelpMatchSubstr("usage_reporting_test_flag_06");
351 
352   std::stringstream test_buf;
353   EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage),
354             flags::HelpMode::kMatch);
355   EXPECT_EQ(test_buf.str(),
356             R"(usage_test: Custom usage message
357 
358   Flags from absl/flags/internal/usage_test.cc:
359     --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
360 
361       Some more help.
362       Even more long long long long long long long long long long long long help
363       message.); default: "";
364 
365 Try --helpfull to get a list of all flags or --help=substring shows help for
366 flags which include specified substring in either in the name, or description or
367 path.
368 )");
369 }
370 
371 // --------------------------------------------------------------------
372 
TEST_F(UsageReportingTest,TestUsageFlag_help_multiple_flag)373 TEST_F(UsageReportingTest, TestUsageFlag_help_multiple_flag) {
374   flags::SetFlagsHelpMode(flags::HelpMode::kMatch);
375   flags::SetFlagsHelpMatchSubstr("test_flag");
376 
377   std::stringstream test_buf;
378   EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage),
379             flags::HelpMode::kMatch);
380   EXPECT_EQ(
381       test_buf.str(),
382       R"(usage_test: Custom usage message
383 
384   Flags from absl/flags/internal/usage_test.cc:
385     --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
386       default: 101;
387     --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
388       default: false;
389     --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
390       default: 1.03;
391     --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
392       default: 1000000000000004;
393     --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
394       default: UDT{};
395     --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
396 
397       Some more help.
398       Even more long long long long long long long long long long long long help
399       message.); default: "";)"
400 
401       "\n    --usage_reporting_test_flag_07 (usage_reporting_test_flag_07 "
402       "help\n\n      \f\v\a\b ); default: \"\r\n\f\v\a\b\t \";\n"
403 
404       R"(
405 Try --helpfull to get a list of all flags or --help=substring shows help for
406 flags which include specified substring in either in the name, or description or
407 path.
408 )");
409 }
410 
411 // --------------------------------------------------------------------
412 
TEST_F(UsageReportingTest,TestUsageFlag_helppackage)413 TEST_F(UsageReportingTest, TestUsageFlag_helppackage) {
414   flags::SetFlagsHelpMode(flags::HelpMode::kPackage);
415 
416   std::stringstream test_buf;
417   EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage),
418             flags::HelpMode::kPackage);
419   EXPECT_EQ(
420       test_buf.str(),
421       R"(usage_test: Custom usage message
422 
423   Flags from absl/flags/internal/usage_test.cc:
424     --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
425       default: 101;
426     --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
427       default: false;
428     --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
429       default: 1.03;
430     --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
431       default: 1000000000000004;
432     --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
433       default: UDT{};
434     --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
435 
436       Some more help.
437       Even more long long long long long long long long long long long long help
438       message.); default: "";)"
439 
440       "\n    --usage_reporting_test_flag_07 (usage_reporting_test_flag_07 "
441       "help\n\n      \f\v\a\b ); default: \"\r\n\f\v\a\b\t \";\n"
442 
443       R"(
444 Try --helpfull to get a list of all flags or --help=substring shows help for
445 flags which include specified substring in either in the name, or description or
446 path.
447 )");
448 }
449 
450 // --------------------------------------------------------------------
451 
TEST_F(UsageReportingTest,TestUsageFlag_version)452 TEST_F(UsageReportingTest, TestUsageFlag_version) {
453   flags::SetFlagsHelpMode(flags::HelpMode::kVersion);
454 
455   std::stringstream test_buf;
456   EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage),
457             flags::HelpMode::kVersion);
458 #ifndef NDEBUG
459   EXPECT_EQ(test_buf.str(), "usage_test\nDebug build (NDEBUG not #defined)\n");
460 #else
461   EXPECT_EQ(test_buf.str(), "usage_test\n");
462 #endif
463 }
464 
465 // --------------------------------------------------------------------
466 
TEST_F(UsageReportingTest,TestUsageFlag_only_check_args)467 TEST_F(UsageReportingTest, TestUsageFlag_only_check_args) {
468   flags::SetFlagsHelpMode(flags::HelpMode::kOnlyCheckArgs);
469 
470   std::stringstream test_buf;
471   EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage),
472             flags::HelpMode::kOnlyCheckArgs);
473   EXPECT_EQ(test_buf.str(), "");
474 }
475 
476 // --------------------------------------------------------------------
477 
TEST_F(UsageReportingTest,TestUsageFlag_helpon)478 TEST_F(UsageReportingTest, TestUsageFlag_helpon) {
479   flags::SetFlagsHelpMode(flags::HelpMode::kMatch);
480   flags::SetFlagsHelpMatchSubstr("/bla-bla.");
481 
482   std::stringstream test_buf_01;
483   EXPECT_EQ(flags::HandleUsageFlags(test_buf_01, kTestUsageMessage),
484             flags::HelpMode::kMatch);
485   EXPECT_EQ(test_buf_01.str(),
486             R"(usage_test: Custom usage message
487 
488 No flags matched.
489 
490 Try --helpfull to get a list of all flags or --help=substring shows help for
491 flags which include specified substring in either in the name, or description or
492 path.
493 )");
494 
495   flags::SetFlagsHelpMatchSubstr("/usage_test.");
496 
497   std::stringstream test_buf_02;
498   EXPECT_EQ(flags::HandleUsageFlags(test_buf_02, kTestUsageMessage),
499             flags::HelpMode::kMatch);
500   EXPECT_EQ(
501       test_buf_02.str(),
502       R"(usage_test: Custom usage message
503 
504   Flags from absl/flags/internal/usage_test.cc:
505     --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message);
506       default: 101;
507     --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message);
508       default: false;
509     --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message);
510       default: 1.03;
511     --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message);
512       default: 1000000000000004;
513     --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message);
514       default: UDT{};
515     --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message.
516 
517       Some more help.
518       Even more long long long long long long long long long long long long help
519       message.); default: "";)"
520 
521       "\n    --usage_reporting_test_flag_07 (usage_reporting_test_flag_07 "
522       "help\n\n      \f\v\a\b ); default: \"\r\n\f\v\a\b\t \";\n"
523 
524       R"(
525 Try --helpfull to get a list of all flags or --help=substring shows help for
526 flags which include specified substring in either in the name, or description or
527 path.
528 )");
529 }
530 
531 // --------------------------------------------------------------------
532 
533 }  // namespace
534 
main(int argc,char * argv[])535 int main(int argc, char* argv[]) {
536   (void)absl::GetFlag(FLAGS_undefok);  // Force linking of parse.cc
537   flags::SetProgramInvocationName("usage_test");
538 #if !defined(GTEST_HAS_ABSL) || !GTEST_HAS_ABSL
539   // GoogleTest calls absl::SetProgramUsageMessage() already.
540   absl::SetProgramUsageMessage(kTestUsageMessage);
541 #endif
542   ::testing::InitGoogleTest(&argc, argv);
543   return RUN_ALL_TESTS();
544 }
545