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
11 #include "testing.h"
12
13
14 //-------------------------------------------------------------------
test(int lineNo,bool expected,const clipp::group & cli)15 void test(int lineNo, bool expected, const clipp::group& cli)
16 {
17 if(cli.flags_are_prefix_free() != expected) {
18
19 std::cout << "prefix '" << cli.common_flag_prefix() << "'" << std::endl;
20
21 throw std::runtime_error{"failed test " + std::string(__FILE__) +
22 " in line " + std::to_string(lineNo)};
23 }
24 }
25
26
27 //-------------------------------------------------------------------
28 clipp::group
make_cli_1()29 make_cli_1()
30 {
31 using namespace clipp;
32
33 auto copyMode = "copy mode:" % (
34 command("copy") | command("move"),
35 option("--all") % "copy all",
36 option("--replace") % "replace existing files",
37 option("-f", "--force") % "don't ask for confirmation"
38 );
39
40 auto compareMode = "compare mode:" % (
41 command("compare"),
42 (command("date") | command("content")),
43 option("-b", "--binary") % "compare files byte by byte",
44 option("-q", "--quick") % "use heuristics for faster comparison"
45 );
46
47 auto mergeAlgo = (
48 command("diff") % "merge using diff" |
49 command("patch") % "merge using patch" |
50 ( command("inside") % "merge based on content",
51 "content based merge options:" % (
52 option("--git-style") % "emulate git's merge behavior",
53 option("-m", "--marker") & value("marker") % "merge marker symbol"
54 )
55 )
56 );
57
58 auto mergeMode = "merge mode:" % (
59 command("merge"),
60 mergeAlgo,
61 required("-o") & value("outdir") % "target directory for merge result",
62 option("--show-conflicts") % "show merge conflicts during run"
63 );
64
65 auto firstOpt = "user interface options:" % (
66 option("-v", "--verbose") % "show detailed output",
67 option("-i", "--interactive") % "use interactive mode"
68 );
69 auto lastOpt = "mode-independent options:" % (
70 values("files") % "input files",
71 option("-r", "--recursive") % "descend into subdirectories",
72 option("-h", "--help") % "show help"
73 );
74
75 return (
76 firstOpt,
77 copyMode | compareMode | mergeMode | command("list"),
78 lastOpt);
79 }
80
81 //-------------------------------------------------------------------
main()82 int main()
83 {
84 using namespace clipp;
85
86 try {
87 test( __LINE__ , true, group{} );
88
89 test( __LINE__ , true, ( option("-a"), option("-b") ));
90
91 test( __LINE__ , true, ( option(""), option("-b") ));
92 test( __LINE__ , true, ( option("-a"), option("") ));
93
94 test( __LINE__ , true, ( option("-a"), option("-b"), option("--a") ));
95 test( __LINE__ , true, ( option(""), option("-b"), option("--a") ));
96 test( __LINE__ , true, ( option("-a"), option(""), option("--a") ));
97 test( __LINE__ , true, ( option("-a"), option("-b"), option("") ));
98
99 test( __LINE__ , true, (
100 option("-a"), option("--a"), option("-b"), option("--b")
101 ));
102
103 test( __LINE__ , true, (
104 option("-a"), option("--a-a"), option("-b"), option("--b-b")
105 ));
106
107 test( __LINE__ , true, (
108 (option("-a"), option("--a-a")) % "a",
109 (option("-b"), option("--b-b")) % "b"
110 ));
111
112 test( __LINE__ , true, ( value("-a"), option("-a"), option("-b") ));
113 test( __LINE__ , true, ( option("-a"), value("-a"), option("-b") ));
114 test( __LINE__ , true, ( option("-a"), option("-b"), value("-b") ));
115
116 test( __LINE__ , true, ( option("-a"), option("-b"), value("") ));
117
118 test( __LINE__ , true, (
119 option("-a"), option("--a"), option("-b"), value("-b"), option("--b")
120 ));
121
122 test( __LINE__ , true, (
123 option("-a"), option("--a-a"), option("-b"), option("--b-b")
124 ));
125
126 test( __LINE__ , true, (
127 (option("-a"), option("--a-a")) % "a",
128 (option("-b"), option("--b-b")) % "b"
129 ));
130
131 //same flags are not an error - TODO is this OK?
132 test( __LINE__ , true, (
133 (option("-a"), option("-a")) % "a",
134 (option("-b"), option("-b")) % "b"
135 ));
136
137 test( __LINE__ , true, (
138 (option("-a") & value("-a"), option("--a-a")) % "a",
139 (option("-b"), option("--b-b") & values("-a")) % "b"
140 ));
141
142
143 test( __LINE__ , false, ( option("-a"), option("-ab") ));
144
145 test( __LINE__ , false, ( option("-ab"), option("-a") ));
146
147 test( __LINE__ , false, (
148 option("-a"), option("-aa"), option("-b"), option("--b-b")
149 ));
150
151 test( __LINE__ , false, (
152 (option("-a"), option("--a")) % "a",
153 (option("-b"), option("-abba")) % "b"
154 ));
155
156 test( __LINE__ , false, (
157 (option("-a") & value("a"), option("--a")) % "a",
158 (option("-b"), option("-abba") & values("-b")) % "b"
159 ));
160
161 test( __LINE__, true, make_cli_1() );
162
163 }
164 catch(std::exception& e) {
165 std::cerr << e.what() << std::endl;
166 return 1;
167 }
168 }
169