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