You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
3.3 KiB

2 years ago
  1. /*****************************************************************************
  2. *
  3. * CLIPP - command line interfaces for modern C++
  4. *
  5. * released under MIT license
  6. *
  7. * (c) 2017-2018 André Müller; foss@andremueller-online.de
  8. *
  9. *****************************************************************************/
  10. #include "testing.h"
  11. //-------------------------------------------------------------------
  12. struct active {
  13. active() = default;
  14. explicit
  15. active(bool a_, bool b_, bool c_, bool d_):
  16. a{a_}, b{b_}, c{c_}, d{d_}
  17. {}
  18. bool a = false, b = false, c = false, d = false;
  19. bool conflict = false;
  20. std::size_t missing = 0;
  21. friend bool operator == (const active& x, const active& y) noexcept {
  22. return (x.a == y.a && x.b == y.b && x.c == y.c && x.d == y.d &&
  23. x.conflict == y.conflict && x.missing == y.missing);
  24. }
  25. };
  26. //-------------------------------------------------------------------
  27. void test(int lineNo,
  28. const std::initializer_list<const char*> args,
  29. const active& matches)
  30. {
  31. using namespace clipp;
  32. {
  33. active m;
  34. auto cli = required("-a").set(m.a) |
  35. required("-b").set(m.b) |
  36. required("-c").set(m.c) |
  37. required("-d").set(m.d);
  38. auto res = parse(args, cli);
  39. m.missing = res.missing().size();
  40. m.conflict = res.any_conflict();
  41. if(!(m == matches)) {
  42. throw std::runtime_error{"failed " + std::string( __FILE__ ) +
  43. " #1 in line " + std::to_string(lineNo)};
  44. }
  45. }
  46. {
  47. active m;
  48. auto cli = (
  49. option("?????"),
  50. (
  51. required("-a").set(m.a) |
  52. required("-b").set(m.b) |
  53. required("-c").set(m.c) |
  54. required("-d").set(m.d)
  55. )
  56. );
  57. auto res = parse(args, cli);
  58. m.missing = res.missing().size();
  59. m.conflict = res.any_conflict();
  60. if(!(m == matches)) {
  61. throw std::runtime_error{"failed " + std::string( __FILE__ ) +
  62. " #2 in line " + std::to_string(lineNo)};
  63. }
  64. }
  65. }
  66. //-------------------------------------------------------------------
  67. int main()
  68. {
  69. try {
  70. {
  71. active e; e.missing = 4;
  72. test(__LINE__, {""}, e);
  73. test(__LINE__, {"x"}, e);
  74. test(__LINE__, {"-x"}, e);
  75. test(__LINE__, {"x", "-y"}, e);
  76. }
  77. //parsing should catch all occurrences
  78. test(__LINE__, {"-a"}, active{1,0,0,0});
  79. test(__LINE__, {"-b"}, active{0,1,0,0});
  80. test(__LINE__, {"-c"}, active{0,0,1,0});
  81. test(__LINE__, {"-d"}, active{0,0,0,1});
  82. {
  83. active e; e.conflict = true;
  84. test(__LINE__, {"-a","-b"}, e);
  85. test(__LINE__, {"-b","-a"}, e);
  86. test(__LINE__, {"-b","-c"}, e);
  87. test(__LINE__, {"-c","-b"}, e);
  88. test(__LINE__, {"-a","-d"}, e);
  89. test(__LINE__, {"-d","-a"}, e);
  90. test(__LINE__, {"-d","-a","-c"}, e);
  91. test(__LINE__, {"-c","-b","-a"}, e);
  92. test(__LINE__, {"-a","-b","-c", "-d"}, e);
  93. test(__LINE__, {"-c","-a","-d", "-b"}, e);
  94. }
  95. }
  96. catch(std::exception& e) {
  97. std::cerr << e.what() << std::endl;
  98. return 1;
  99. }
  100. }