usage_test.cc 17 KB

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