• 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 "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