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.

192 lines
10 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. int av_, int bv_, int cv_, int dv_):
  17. a{a_}, b{b_}, c{c_}, d{d_},
  18. av{av_}, bv{bv_}, cv{cv_}, dv{dv_}
  19. {}
  20. bool a = false, b = false, c = false, d = false;
  21. int av = 0, bv = 0, cv = 0, dv = 0;
  22. friend bool operator == (const active& x, const active& y) noexcept {
  23. return (x.a == y.a && x.b == y.b && x.c == y.c && x.d == y.d &&
  24. x.av == y.av && x.bv == y.bv && x.cv == y.cv && x.dv == y.dv );
  25. }
  26. template<class OStream>
  27. friend OStream& operator << (OStream& os, const active& x) {
  28. return os << '{' << x.a <<' '<< x.b <<' '<< x.c <<' '<< x.d
  29. << " | " << x.av <<' '<< x.bv <<' '<< x.cv <<' '<< x.dv << '}';
  30. }
  31. };
  32. //---------------------------------------------------------------
  33. struct errors {
  34. errors() = default;
  35. explicit
  36. errors(bool a_, bool b_, bool c_, bool d_,
  37. bool av_, bool bv_, bool cv_, bool dv_):
  38. a{a_}, b{b_}, c{c_}, d{d_},
  39. av{av_}, bv{bv_}, cv{cv_}, dv{dv_}
  40. {}
  41. bool a = false, b = false, c = false, d = false;
  42. bool av = false, bv = false, cv = false, dv = false;
  43. friend bool operator == (const errors& x, const errors& y) noexcept {
  44. return (x.a == y.a && x.b == y.b && x.c == y.c && x.d == y.d &&
  45. x.av == y.av && x.bv == y.bv && x.cv == y.cv && x.dv == y.dv );
  46. }
  47. template<class OStream>
  48. friend OStream& operator << (OStream& os, const errors& x) {
  49. return os << '{' << x.a <<' '<< x.b <<' '<< x.c <<' '<< x.d
  50. << " | " << x.av <<' '<< x.bv <<' '<< x.cv <<' '<< x.dv << '}';
  51. }
  52. };
  53. //-------------------------------------------------------------------
  54. void test(int lineNo,
  55. const std::initializer_list<const char*> args,
  56. const active& matches,
  57. const errors& missing)
  58. {
  59. using namespace clipp;
  60. active v;
  61. errors m;
  62. auto mode1 = (
  63. command("mode1"),
  64. option("-r") & opt_value("R")
  65. ,
  66. required("-a", "--aaa").set(v.a).if_missing(set(m.a))
  67. & value("I", v.av).if_missing(set(m.av))
  68. ,
  69. required("-b", "--bee").set(v.b).if_missing(set(m.b))
  70. & value("J", v.bv).if_missing(set(m.bv))
  71. ,
  72. option("-s") & opt_value("S")
  73. ,
  74. required("-c", "--cee").set(v.c).if_missing(set(m.c))
  75. & opt_value("K", v.cv).if_missing(set(m.cv))
  76. ,
  77. required("-d", "--dee").set(v.d).if_missing(set(m.d))
  78. & value("L", v.dv).if_missing(set(m.dv))
  79. ,
  80. option("-t") & value("T")
  81. );
  82. auto mode2 = ( command("mode2"), option("-u"), option("-v") );
  83. auto cli = (mode1 | mode2);
  84. run_wrapped_variants({ __FILE__, lineNo }, args, cli,
  85. [&]{ v = active{}; m = errors{}; },
  86. [&]{ return v == matches && m == missing; });
  87. }
  88. //-------------------------------------------------------------------
  89. int main()
  90. {
  91. try {
  92. test(__LINE__, {""}, active{0,0,0,0, 0,0,0,0}, errors{1,1,1,1, 1,1,0,1});
  93. test(__LINE__, {"mode1"}, active{0,0,0,0, 0,0,0,0}, errors{1,1,1,1, 1,1,0,1});
  94. test(__LINE__, {"mode2"}, active{0,0,0,0, 0,0,0,0}, errors{0,0,0,0, 0,0,0,0});
  95. test(__LINE__, {"mode2", "-a"}, active{0,0,0,0, 0,0,0,0}, errors{0,0,0,0, 0,0,0,0});
  96. test(__LINE__, {"mode2", "-b"}, active{0,0,0,0, 0,0,0,0}, errors{0,0,0,0, 0,0,0,0});
  97. test(__LINE__, {"mode2", "-c"}, active{0,0,0,0, 0,0,0,0}, errors{0,0,0,0, 0,0,0,0});
  98. test(__LINE__, {"mode2", "-d"}, active{0,0,0,0, 0,0,0,0}, errors{0,0,0,0, 0,0,0,0});
  99. test(__LINE__, {"mode1", "-a"}, active{1,0,0,0, 0,0,0,0}, errors{0,1,1,1, 1,1,0,1});
  100. test(__LINE__, {"mode1", "-b"}, active{0,1,0,0, 0,0,0,0}, errors{1,0,1,1, 1,1,0,1});
  101. test(__LINE__, {"mode1", "-c"}, active{0,0,1,0, 0,0,0,0}, errors{1,1,0,1, 1,1,0,1});
  102. test(__LINE__, {"mode1", "-d"}, active{0,0,0,1, 0,0,0,0}, errors{1,1,1,0, 1,1,0,1});
  103. test(__LINE__, {"mode1", "--aaa"}, active{1,0,0,0, 0,0,0,0}, errors{0,1,1,1, 1,1,0,1});
  104. test(__LINE__, {"mode1", "--bee"}, active{0,1,0,0, 0,0,0,0}, errors{1,0,1,1, 1,1,0,1});
  105. test(__LINE__, {"mode1", "--cee"}, active{0,0,1,0, 0,0,0,0}, errors{1,1,0,1, 1,1,0,1});
  106. test(__LINE__, {"mode1", "--dee"}, active{0,0,0,1, 0,0,0,0}, errors{1,1,1,0, 1,1,0,1});
  107. test(__LINE__, {"mode1", "-a", "2"}, active{1,0,0,0, 2,0,0,0}, errors{0,1,1,1, 0,1,0,1});
  108. test(__LINE__, {"mode1", "-b", "2"}, active{0,1,0,0, 0,2,0,0}, errors{1,0,1,1, 1,0,0,1});
  109. test(__LINE__, {"mode1", "-c", "2"}, active{0,0,1,0, 0,0,2,0}, errors{1,1,0,1, 1,1,0,1});
  110. test(__LINE__, {"mode1", "-d", "2"}, active{0,0,0,1, 0,0,0,2}, errors{1,1,1,0, 1,1,0,0});
  111. test(__LINE__, {"mode1", "--aaa", "2"}, active{1,0,0,0, 2,0,0,0}, errors{0,1,1,1, 0,1,0,1});
  112. test(__LINE__, {"mode1", "--bee", "2"}, active{0,1,0,0, 0,2,0,0}, errors{1,0,1,1, 1,0,0,1});
  113. test(__LINE__, {"mode1", "--cee", "2"}, active{0,0,1,0, 0,0,2,0}, errors{1,1,0,1, 1,1,0,1});
  114. test(__LINE__, {"mode1", "--dee", "2"}, active{0,0,0,1, 0,0,0,2}, errors{1,1,1,0, 1,1,0,0});
  115. test(__LINE__, {"mode1", "-a", "2", "-b", "3"}, active{1,1,0,0, 2,3,0,0}, errors{0,0,1,1, 0,0,0,1});
  116. test(__LINE__, {"mode1", "-a", "2", "-c", "3"}, active{1,0,1,0, 2,0,3,0}, errors{0,1,0,1, 0,1,0,1});
  117. test(__LINE__, {"mode1", "-a", "2", "-d", "3"}, active{1,0,0,1, 2,0,0,3}, errors{0,1,1,0, 0,1,0,0});
  118. test(__LINE__, {"mode1", "-b", "2", "-c", "3"}, active{0,1,1,0, 0,2,3,0}, errors{1,0,0,1, 1,0,0,1});
  119. test(__LINE__, {"mode1", "-b", "2", "-d", "3"}, active{0,1,0,1, 0,2,0,3}, errors{1,0,1,0, 1,0,0,0});
  120. test(__LINE__, {"mode1", "-c", "2", "-d", "3"}, active{0,0,1,1, 0,0,2,3}, errors{1,1,0,0, 1,1,0,0});
  121. test(__LINE__, {"mode1", "-b", "3", "-a", "2"}, active{1,1,0,0, 2,3,0,0}, errors{0,0,1,1, 0,0,0,1});
  122. test(__LINE__, {"mode1", "-c", "3", "-a", "2"}, active{1,0,1,0, 2,0,3,0}, errors{0,1,0,1, 0,1,0,1});
  123. test(__LINE__, {"mode1", "-d", "3", "-a", "2"}, active{1,0,0,1, 2,0,0,3}, errors{0,1,1,0, 0,1,0,0});
  124. test(__LINE__, {"mode1", "-c", "3", "-b", "2"}, active{0,1,1,0, 0,2,3,0}, errors{1,0,0,1, 1,0,0,1});
  125. test(__LINE__, {"mode1", "-d", "3", "-b", "2"}, active{0,1,0,1, 0,2,0,3}, errors{1,0,1,0, 1,0,0,0});
  126. test(__LINE__, {"mode1", "-d", "3", "-c", "2"}, active{0,0,1,1, 0,0,2,3}, errors{1,1,0,0, 1,1,0,0});
  127. test(__LINE__, {"mode1", "-a", "2", "-b", "3", "-c", "4"}, active{1,1,1,0, 2,3,4,0}, errors{0,0,0,1, 0,0,0,1});
  128. test(__LINE__, {"mode1", "-b", "3", "-c", "4", "-d", "5"}, active{0,1,1,1, 0,3,4,5}, errors{1,0,0,0, 1,0,0,0});
  129. test(__LINE__, {"mode1", "-a", "2", "-b", "3", "-d", "4"}, active{1,1,0,1, 2,3,0,4}, errors{0,0,1,0, 0,0,0,0});
  130. test(__LINE__, {"mode1", "-a", "2", "-c", "4", "-b", "3"}, active{1,1,1,0, 2,3,4,0}, errors{0,0,0,1, 0,0,0,1});
  131. test(__LINE__, {"mode1", "-c", "4", "-b", "3", "-d", "5"}, active{0,1,1,1, 0,3,4,5}, errors{1,0,0,0, 1,0,0,0});
  132. test(__LINE__, {"mode1", "-b", "3", "-a", "2", "-d", "4"}, active{1,1,0,1, 2,3,0,4}, errors{0,0,1,0, 0,0,0,0});
  133. test(__LINE__, {"mode1", "-d", "4", "-b", "3", "-a", "2"}, active{1,1,0,1, 2,3,0,4}, errors{0,0,1,0, 0,0,0,0});
  134. test(__LINE__, {"mode1", "-a", "2", "-b", "3", "-c", "4", "-d", "5"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  135. test(__LINE__, {"mode1", "-c", "4", "-b", "3", "-a", "2", "-d", "5"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  136. test(__LINE__, {"mode1", "-d", "5", "-c", "4", "-b", "3", "-a", "2"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  137. test(__LINE__, {"mode1", "-d", "5", "-a", "2", "-c", "4", "-b", "3"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  138. test(__LINE__, {"mode1", "-c", "4", "-a", "2", "-d", "5", "-b", "3"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  139. test(__LINE__, {"mode1", "-r", "R", "-a", "2", "-b", "3", "-c", "4", "-d", "5"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  140. test(__LINE__, {"mode1", "-c", "4", "-r", "R", "-b", "3", "-a", "2", "-d", "5"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  141. test(__LINE__, {"mode1", "-d", "5", "-c", "4", "-r", "R", "-b", "3", "-a", "2"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  142. test(__LINE__, {"mode1", "-d", "5", "-a", "2", "-c", "4", "-r", "R", "-b", "3"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  143. test(__LINE__, {"mode1", "-c", "4", "-a", "2", "-d", "5", "-b", "3", "-r", "R"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  144. test(__LINE__, {"mode1", "-s", "S", "-a", "2", "-b", "3", "-c", "4", "-d", "5"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  145. test(__LINE__, {"mode1", "-c", "4", "-s", "S", "-b", "3", "-a", "2", "-d", "5"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  146. test(__LINE__, {"mode1", "-d", "5", "-c", "4", "-s", "S", "-b", "3", "-a", "2"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  147. test(__LINE__, {"mode1", "-d", "5", "-a", "2", "-c", "4", "-s", "S", "-b", "3"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  148. test(__LINE__, {"mode1", "-c", "4", "-a", "2", "-d", "5", "-b", "3", "-s", "S"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  149. test(__LINE__, {"mode1", "-t", "T", "-a", "2"}, active{1,0,0,0, 2,0,0,0}, errors{0,1,1,1, 0,1,0,1});
  150. test(__LINE__, {"mode1", "-t", "T", "-a", "2", "-b", "3", "-c", "4", "-d", "5"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  151. test(__LINE__, {"mode1", "-c", "4", "-t", "T", "-b", "3", "-a", "2", "-d", "5"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  152. test(__LINE__, {"mode1", "-d", "5", "-c", "4", "-t", "T", "-b", "3", "-a", "2"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  153. test(__LINE__, {"mode1", "-d", "5", "-a", "2", "-c", "4", "-t", "T", "-b", "3"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  154. test(__LINE__, {"mode1", "-c", "4", "-a", "2", "-d", "5", "-b", "3", "-t", "T"}, active{1,1,1,1, 2,3,4,5}, errors{0,0,0,0, 0,0,0,0});
  155. }
  156. catch(std::exception& e) {
  157. std::cerr << e.what() << std::endl;
  158. return 1;
  159. }
  160. }