Commit b774c57dc2e632f3dc17f6653d8bedb09e3efa88

Authored by Henry Fredrick Schreiner
1 parent 67047b71

Adding help testing, option groups

cmake/AddGoogletest.cmake
... ... @@ -14,16 +14,16 @@ download_project(PROJ googletest
14 14 )
15 15  
16 16  
17   -add_subdirectory(${googletest_SOURCE_DIR}/googletest ${googletest_SOURCE_DIR})
18   -
19   -mark_as_advanced(
20   - gtest_build_samples
21   - gtest_build_tests
22   - gtest_disable_pthreads
23   - gtest_force_shared_crt
24   - gtest_hide_internal_symbols
25   - BUILD_SHARED_LIBS
26   -)
  17 +add_subdirectory(${googletest_SOURCE_DIR} ${googletest_SOURCE_DIR})
  18 +
  19 +#mark_as_advanced(
  20 +# gtest_build_samples
  21 +# gtest_build_tests
  22 +# gtest_disable_pthreads
  23 +# gtest_force_shared_crt
  24 +# gtest_hide_internal_symbols
  25 +# BUILD_SHARED_LIBS
  26 +#)
27 27  
28 28 if (CMAKE_CONFIGURATION_TYPES)
29 29 add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
... ... @@ -34,14 +34,14 @@ else()
34 34 --force-new-ctest-process --output-on-failure)
35 35 endif()
36 36  
37   -include_directories(${gtest_SOURCE_DIR}/include)
  37 +#include_directories(${gtest_SOURCE_DIR}/include)
38 38  
39 39 # More modern way to do the last line, less messy but needs newish CMake:
40 40 # target_include_directories(gtest INTERFACE ${gtest_SOURCE_DIR}/include)
41 41  
42 42 # Target must already exist
43 43 macro(add_gtest TESTNAME)
44   - target_link_libraries(${TESTNAME} PUBLIC gtest gtest_main)
  44 + target_link_libraries(${TESTNAME} PUBLIC gtest gmock gtest_main)
45 45 add_test(${TESTNAME} ${TESTNAME})
46 46 endmacro()
47 47  
... ...
include/CLI/App.hpp
... ... @@ -559,15 +559,16 @@ public:
559 559  
560 560 // Check for options
561 561 bool npos = false;
  562 + std::set<std::string> groups;
562 563 for(const Option_p &opt : options) {
563 564 if(opt->nonpositional()) {
564 565 npos = true;
565   - break;
  566 + groups.insert(opt->get_group());
566 567 }
567 568 }
568 569  
569 570 if(npos)
570   - out << " [OPTIONS...]";
  571 + out << " [OPTIONS]";
571 572  
572 573 // Positionals
573 574 bool pos=false;
... ... @@ -593,13 +594,15 @@ public:
593 594  
594 595 // Options
595 596 if(npos) {
596   - out << "Options:" << std::endl;
597   - for(const Option_p &opt : options) {
598   - if(opt->nonpositional())
599   - detail::format_help(out, opt->help_name(), opt->get_description(), wid);
600   -
  597 + for (const std::string& group : groups) {
  598 + out << group << ":" << std::endl;
  599 + for(const Option_p &opt : options) {
  600 + if(opt->nonpositional() && opt->get_group() == group)
  601 + detail::format_help(out, opt->help_name(), opt->get_description(), wid);
  602 +
  603 + }
  604 + out << std::endl;
601 605 }
602   - out << std::endl;
603 606 }
604 607  
605 608 // Subcommands
... ...
include/CLI/Option.hpp
... ... @@ -34,7 +34,7 @@ protected:
34 34 // These are for help strings
35 35 std::string defaultval;
36 36 std::string typeval;
37   -
  37 + std::string _group {"Options"};
38 38  
39 39 bool _default {false};
40 40 bool _required {false};
... ... @@ -115,6 +115,15 @@ public:
115 115 return this;
116 116 }
117 117  
  118 + Option* group(std::string name) {
  119 + _group = name;
  120 + return this;
  121 + }
  122 +
  123 + const std::string& get_group() const {
  124 + return _group;
  125 + }
  126 +
118 127 /// Get the description
119 128 const std::string& get_description() const {
120 129 return description;
... ...
tests/CMakeLists.txt
1 1 include(AddGoogletest)
2 2  
3   -set(CLI_TESTS SmallTest IniTest CLITest)
  3 +set(CLI_TESTS SmallTest IniTest CLITest HelpTest)
4 4  
5 5 foreach(T ${CLI_TESTS})
6 6  
... ...
tests/HelpTest.cpp 0 → 100644
  1 +#ifdef CLI_SINGLE_FILE
  2 +#include "CLI11.hpp"
  3 +#else
  4 +#include "CLI/CLI.hpp"
  5 +#endif
  6 +
  7 +#include "gtest/gtest.h"
  8 +#include "gmock/gmock.h"
  9 +#include <fstream>
  10 +
  11 +using ::testing::HasSubstr;
  12 +
  13 +TEST(THelp, Basic) {
  14 + CLI::App app{"My prog"};
  15 +
  16 + std::string help = app.help();
  17 +
  18 + EXPECT_THAT(help, HasSubstr("My prog"));
  19 + EXPECT_THAT(help, HasSubstr("-h,--help"));
  20 + EXPECT_THAT(help, HasSubstr("Options:"));
  21 + EXPECT_THAT(help, HasSubstr("Usage:"));
  22 +
  23 +}
  24 +
  25 +TEST(THelp, OptionalPositional) {
  26 + CLI::App app{"My prog"};
  27 +
  28 + std::string x;
  29 + app.add_option("something", x, "My option here");
  30 +
  31 + std::string help = app.help();
  32 +
  33 + EXPECT_THAT(help, HasSubstr("My prog"));
  34 + EXPECT_THAT(help, HasSubstr("-h,--help"));
  35 + EXPECT_THAT(help, HasSubstr("Options:"));
  36 + EXPECT_THAT(help, HasSubstr("Positionals:"));
  37 + EXPECT_THAT(help, HasSubstr("something STRING"));
  38 + EXPECT_THAT(help, HasSubstr("My option here"));
  39 + EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] [something]"));
  40 +
  41 +}
  42 +TEST(THelp, OptionalPositionalAndOptions) {
  43 + CLI::App app{"My prog"};
  44 + app.add_flag("-q,--quick");
  45 +
  46 + std::string x;
  47 + app.add_option("something", x, "My option here");
  48 +
  49 + std::string help = app.help();
  50 +
  51 + EXPECT_THAT(help, HasSubstr("My prog"));
  52 + EXPECT_THAT(help, HasSubstr("-h,--help"));
  53 + EXPECT_THAT(help, HasSubstr("Options:"));
  54 + EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] [something]"));
  55 +
  56 +}
  57 +
  58 +TEST(THelp, RequiredPositionalAndOptions) {
  59 + CLI::App app{"My prog"};
  60 + app.add_flag("-q,--quick");
  61 +
  62 + std::string x;
  63 + app.add_option("something", x, "My option here")
  64 + ->required();
  65 +
  66 + std::string help = app.help();
  67 +
  68 + EXPECT_THAT(help, HasSubstr("My prog"));
  69 + EXPECT_THAT(help, HasSubstr("-h,--help"));
  70 + EXPECT_THAT(help, HasSubstr("Options:"));
  71 + EXPECT_THAT(help, HasSubstr("Positionals:"));
  72 + EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] something"));
  73 +
  74 +}
... ...