xref: /minix3/external/bsd/kyua-cli/dist/utils/cmdline/base_command_test.cpp (revision 11be35a165022172ed3cea20f2b5df0307540b0e)
1*11be35a1SLionel Sambuc // Copyright 2010 Google Inc.
2*11be35a1SLionel Sambuc // All rights reserved.
3*11be35a1SLionel Sambuc //
4*11be35a1SLionel Sambuc // Redistribution and use in source and binary forms, with or without
5*11be35a1SLionel Sambuc // modification, are permitted provided that the following conditions are
6*11be35a1SLionel Sambuc // met:
7*11be35a1SLionel Sambuc //
8*11be35a1SLionel Sambuc // * Redistributions of source code must retain the above copyright
9*11be35a1SLionel Sambuc //   notice, this list of conditions and the following disclaimer.
10*11be35a1SLionel Sambuc // * Redistributions in binary form must reproduce the above copyright
11*11be35a1SLionel Sambuc //   notice, this list of conditions and the following disclaimer in the
12*11be35a1SLionel Sambuc //   documentation and/or other materials provided with the distribution.
13*11be35a1SLionel Sambuc // * Neither the name of Google Inc. nor the names of its contributors
14*11be35a1SLionel Sambuc //   may be used to endorse or promote products derived from this software
15*11be35a1SLionel Sambuc //   without specific prior written permission.
16*11be35a1SLionel Sambuc //
17*11be35a1SLionel Sambuc // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*11be35a1SLionel Sambuc // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*11be35a1SLionel Sambuc // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*11be35a1SLionel Sambuc // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*11be35a1SLionel Sambuc // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*11be35a1SLionel Sambuc // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*11be35a1SLionel Sambuc // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*11be35a1SLionel Sambuc // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*11be35a1SLionel Sambuc // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*11be35a1SLionel Sambuc // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*11be35a1SLionel Sambuc // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*11be35a1SLionel Sambuc 
29*11be35a1SLionel Sambuc #include "utils/cmdline/base_command.ipp"
30*11be35a1SLionel Sambuc 
31*11be35a1SLionel Sambuc #include <atf-c++.hpp>
32*11be35a1SLionel Sambuc 
33*11be35a1SLionel Sambuc #include "utils/cmdline/exceptions.hpp"
34*11be35a1SLionel Sambuc #include "utils/cmdline/options.hpp"
35*11be35a1SLionel Sambuc #include "utils/cmdline/parser.ipp"
36*11be35a1SLionel Sambuc #include "utils/cmdline/ui_mock.hpp"
37*11be35a1SLionel Sambuc #include "utils/defs.hpp"
38*11be35a1SLionel Sambuc 
39*11be35a1SLionel Sambuc namespace cmdline = utils::cmdline;
40*11be35a1SLionel Sambuc 
41*11be35a1SLionel Sambuc 
42*11be35a1SLionel Sambuc namespace {
43*11be35a1SLionel Sambuc 
44*11be35a1SLionel Sambuc 
45*11be35a1SLionel Sambuc /// Mock command to test the cmdline::base_command base class.
46*11be35a1SLionel Sambuc ///
47*11be35a1SLionel Sambuc /// \param Data The type of the opaque data object passed to main().
48*11be35a1SLionel Sambuc /// \param ExpectedData The value run() will expect to find in the Data object
49*11be35a1SLionel Sambuc ///     passed to main().
50*11be35a1SLionel Sambuc template< typename Data, Data ExpectedData >
51*11be35a1SLionel Sambuc class mock_cmd : public cmdline::base_command< Data > {
52*11be35a1SLionel Sambuc public:
53*11be35a1SLionel Sambuc     /// Indicates if run() has been called already and executed correctly.
54*11be35a1SLionel Sambuc     bool executed;
55*11be35a1SLionel Sambuc 
56*11be35a1SLionel Sambuc     /// Contains the argument of --the_string after run() is executed.
57*11be35a1SLionel Sambuc     std::string optvalue;
58*11be35a1SLionel Sambuc 
59*11be35a1SLionel Sambuc     /// Constructs a new mock command.
mock_cmd(void)60*11be35a1SLionel Sambuc     mock_cmd(void) :
61*11be35a1SLionel Sambuc         cmdline::base_command< Data >("mock", "arg1 [arg2 [arg3]]", 1, 3,
62*11be35a1SLionel Sambuc                                       "Command for testing."),
63*11be35a1SLionel Sambuc         executed(false)
64*11be35a1SLionel Sambuc     {
65*11be35a1SLionel Sambuc         this->add_option(cmdline::string_option("the_string", "Test option",
66*11be35a1SLionel Sambuc                                                 "arg"));
67*11be35a1SLionel Sambuc     }
68*11be35a1SLionel Sambuc 
69*11be35a1SLionel Sambuc     /// Executes the command.
70*11be35a1SLionel Sambuc     ///
71*11be35a1SLionel Sambuc     /// \param unused_ui Object to interact with the I/O of the program.
72*11be35a1SLionel Sambuc     /// \param cmdline Representation of the command line to the subcommand.
73*11be35a1SLionel Sambuc     /// \param data Arbitrary data cookie passed to the command.
74*11be35a1SLionel Sambuc     ///
75*11be35a1SLionel Sambuc     /// \return A hardcoded number for testing purposes.
76*11be35a1SLionel Sambuc     int
run(cmdline::ui * UTILS_UNUSED_PARAM (ui),const cmdline::parsed_cmdline & cmdline,const Data & data)77*11be35a1SLionel Sambuc     run(cmdline::ui* UTILS_UNUSED_PARAM(ui),
78*11be35a1SLionel Sambuc         const cmdline::parsed_cmdline& cmdline, const Data& data)
79*11be35a1SLionel Sambuc     {
80*11be35a1SLionel Sambuc         if (cmdline.has_option("the_string"))
81*11be35a1SLionel Sambuc             optvalue = cmdline.get_option< cmdline::string_option >(
82*11be35a1SLionel Sambuc                 "the_string");
83*11be35a1SLionel Sambuc         ATF_REQUIRE_EQ(ExpectedData, data);
84*11be35a1SLionel Sambuc         executed = true;
85*11be35a1SLionel Sambuc         return 1234;
86*11be35a1SLionel Sambuc     }
87*11be35a1SLionel Sambuc };
88*11be35a1SLionel Sambuc 
89*11be35a1SLionel Sambuc 
90*11be35a1SLionel Sambuc /// Mock command to test the cmdline::base_command_no_data base class.
91*11be35a1SLionel Sambuc class mock_cmd_no_data : public cmdline::base_command_no_data {
92*11be35a1SLionel Sambuc public:
93*11be35a1SLionel Sambuc     /// Indicates if run() has been called already and executed correctly.
94*11be35a1SLionel Sambuc     bool executed;
95*11be35a1SLionel Sambuc 
96*11be35a1SLionel Sambuc     /// Contains the argument of --the_string after run() is executed.
97*11be35a1SLionel Sambuc     std::string optvalue;
98*11be35a1SLionel Sambuc 
99*11be35a1SLionel Sambuc     /// Constructs a new mock command.
mock_cmd_no_data(void)100*11be35a1SLionel Sambuc     mock_cmd_no_data(void) :
101*11be35a1SLionel Sambuc         cmdline::base_command_no_data("mock", "arg1 [arg2 [arg3]]", 1, 3,
102*11be35a1SLionel Sambuc                                       "Command for testing."),
103*11be35a1SLionel Sambuc         executed(false)
104*11be35a1SLionel Sambuc     {
105*11be35a1SLionel Sambuc         add_option(cmdline::string_option("the_string", "Test option", "arg"));
106*11be35a1SLionel Sambuc     }
107*11be35a1SLionel Sambuc 
108*11be35a1SLionel Sambuc     /// Executes the command.
109*11be35a1SLionel Sambuc     ///
110*11be35a1SLionel Sambuc     /// \param unused_ui Object to interact with the I/O of the program.
111*11be35a1SLionel Sambuc     /// \param cmdline Representation of the command line to the subcommand.
112*11be35a1SLionel Sambuc     ///
113*11be35a1SLionel Sambuc     /// \return A hardcoded number for testing purposes.
114*11be35a1SLionel Sambuc     int
run(cmdline::ui * UTILS_UNUSED_PARAM (ui),const cmdline::parsed_cmdline & cmdline)115*11be35a1SLionel Sambuc     run(cmdline::ui* UTILS_UNUSED_PARAM(ui),
116*11be35a1SLionel Sambuc         const cmdline::parsed_cmdline& cmdline)
117*11be35a1SLionel Sambuc     {
118*11be35a1SLionel Sambuc         if (cmdline.has_option("the_string"))
119*11be35a1SLionel Sambuc             optvalue = cmdline.get_option< cmdline::string_option >(
120*11be35a1SLionel Sambuc                 "the_string");
121*11be35a1SLionel Sambuc         executed = true;
122*11be35a1SLionel Sambuc         return 1234;
123*11be35a1SLionel Sambuc     }
124*11be35a1SLionel Sambuc };
125*11be35a1SLionel Sambuc 
126*11be35a1SLionel Sambuc 
127*11be35a1SLionel Sambuc /// Implementation of a command to get access to parse_cmdline().
128*11be35a1SLionel Sambuc class parse_cmdline_portal : public cmdline::command_proto {
129*11be35a1SLionel Sambuc public:
130*11be35a1SLionel Sambuc     /// Constructs a new mock command.
parse_cmdline_portal(void)131*11be35a1SLionel Sambuc     parse_cmdline_portal(void) :
132*11be35a1SLionel Sambuc         cmdline::command_proto("portal", "arg1 [arg2 [arg3]]", 1, 3,
133*11be35a1SLionel Sambuc                                "Command for testing.")
134*11be35a1SLionel Sambuc     {
135*11be35a1SLionel Sambuc         this->add_option(cmdline::string_option("the_string", "Test option",
136*11be35a1SLionel Sambuc                                                 "arg"));
137*11be35a1SLionel Sambuc     }
138*11be35a1SLionel Sambuc 
139*11be35a1SLionel Sambuc     /// Delegator for the internal parse_cmdline() method.
140*11be35a1SLionel Sambuc     ///
141*11be35a1SLionel Sambuc     /// \param args The input arguments to be parsed.
142*11be35a1SLionel Sambuc     ///
143*11be35a1SLionel Sambuc     /// \return The parsed command line, split in options and arguments.
144*11be35a1SLionel Sambuc     cmdline::parsed_cmdline
operator ()(const cmdline::args_vector & args) const145*11be35a1SLionel Sambuc     operator()(const cmdline::args_vector& args) const
146*11be35a1SLionel Sambuc     {
147*11be35a1SLionel Sambuc         return parse_cmdline(args);
148*11be35a1SLionel Sambuc     }
149*11be35a1SLionel Sambuc };
150*11be35a1SLionel Sambuc 
151*11be35a1SLionel Sambuc 
152*11be35a1SLionel Sambuc }  // anonymous namespace
153*11be35a1SLionel Sambuc 
154*11be35a1SLionel Sambuc 
155*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(command_proto__parse_cmdline__ok);
ATF_TEST_CASE_BODY(command_proto__parse_cmdline__ok)156*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(command_proto__parse_cmdline__ok)
157*11be35a1SLionel Sambuc {
158*11be35a1SLionel Sambuc     cmdline::args_vector args;
159*11be35a1SLionel Sambuc     args.push_back("portal");
160*11be35a1SLionel Sambuc     args.push_back("--the_string=foo bar");
161*11be35a1SLionel Sambuc     args.push_back("one arg");
162*11be35a1SLionel Sambuc     args.push_back("another arg");
163*11be35a1SLionel Sambuc     (void)parse_cmdline_portal()(args);
164*11be35a1SLionel Sambuc }
165*11be35a1SLionel Sambuc 
166*11be35a1SLionel Sambuc 
167*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(command_proto__parse_cmdline__parse_fail);
ATF_TEST_CASE_BODY(command_proto__parse_cmdline__parse_fail)168*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(command_proto__parse_cmdline__parse_fail)
169*11be35a1SLionel Sambuc {
170*11be35a1SLionel Sambuc     cmdline::args_vector args;
171*11be35a1SLionel Sambuc     args.push_back("portal");
172*11be35a1SLionel Sambuc     args.push_back("--foo-bar");
173*11be35a1SLionel Sambuc     ATF_REQUIRE_THROW_RE(cmdline::usage_error, "Unknown.*foo-bar",
174*11be35a1SLionel Sambuc                          (void)parse_cmdline_portal()(args));
175*11be35a1SLionel Sambuc }
176*11be35a1SLionel Sambuc 
177*11be35a1SLionel Sambuc 
178*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(command_proto__parse_cmdline__args_invalid);
ATF_TEST_CASE_BODY(command_proto__parse_cmdline__args_invalid)179*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(command_proto__parse_cmdline__args_invalid)
180*11be35a1SLionel Sambuc {
181*11be35a1SLionel Sambuc     cmdline::args_vector args;
182*11be35a1SLionel Sambuc     args.push_back("portal");
183*11be35a1SLionel Sambuc 
184*11be35a1SLionel Sambuc     ATF_REQUIRE_THROW_RE(cmdline::usage_error, "Not enough arguments",
185*11be35a1SLionel Sambuc                          (void)parse_cmdline_portal()(args));
186*11be35a1SLionel Sambuc 
187*11be35a1SLionel Sambuc     args.push_back("1");
188*11be35a1SLionel Sambuc     args.push_back("2");
189*11be35a1SLionel Sambuc     args.push_back("3");
190*11be35a1SLionel Sambuc     args.push_back("4");
191*11be35a1SLionel Sambuc     ATF_REQUIRE_THROW_RE(cmdline::usage_error, "Too many arguments",
192*11be35a1SLionel Sambuc                          (void)parse_cmdline_portal()(args));
193*11be35a1SLionel Sambuc }
194*11be35a1SLionel Sambuc 
195*11be35a1SLionel Sambuc 
196*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(base_command__getters);
ATF_TEST_CASE_BODY(base_command__getters)197*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(base_command__getters)
198*11be35a1SLionel Sambuc {
199*11be35a1SLionel Sambuc     mock_cmd< int, 584 > cmd;
200*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ("mock", cmd.name());
201*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ("arg1 [arg2 [arg3]]", cmd.arg_list());
202*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ("Command for testing.", cmd.short_description());
203*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ(1, cmd.options().size());
204*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ("the_string", cmd.options()[0]->long_name());
205*11be35a1SLionel Sambuc }
206*11be35a1SLionel Sambuc 
207*11be35a1SLionel Sambuc 
208*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(base_command__main__ok)
ATF_TEST_CASE_BODY(base_command__main__ok)209*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(base_command__main__ok)
210*11be35a1SLionel Sambuc {
211*11be35a1SLionel Sambuc     mock_cmd< int, 584 > cmd;
212*11be35a1SLionel Sambuc 
213*11be35a1SLionel Sambuc     cmdline::ui_mock ui;
214*11be35a1SLionel Sambuc     cmdline::args_vector args;
215*11be35a1SLionel Sambuc     args.push_back("mock");
216*11be35a1SLionel Sambuc     args.push_back("--the_string=foo bar");
217*11be35a1SLionel Sambuc     args.push_back("one arg");
218*11be35a1SLionel Sambuc     args.push_back("another arg");
219*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ(1234, cmd.main(&ui, args, 584));
220*11be35a1SLionel Sambuc     ATF_REQUIRE(cmd.executed);
221*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ("foo bar", cmd.optvalue);
222*11be35a1SLionel Sambuc }
223*11be35a1SLionel Sambuc 
224*11be35a1SLionel Sambuc 
225*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(base_command__main__parse_cmdline_fail)
ATF_TEST_CASE_BODY(base_command__main__parse_cmdline_fail)226*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(base_command__main__parse_cmdline_fail)
227*11be35a1SLionel Sambuc {
228*11be35a1SLionel Sambuc     mock_cmd< int, 584 > cmd;
229*11be35a1SLionel Sambuc 
230*11be35a1SLionel Sambuc     cmdline::ui_mock ui;
231*11be35a1SLionel Sambuc     cmdline::args_vector args;
232*11be35a1SLionel Sambuc     args.push_back("mock");
233*11be35a1SLionel Sambuc     args.push_back("--foo-bar");
234*11be35a1SLionel Sambuc     ATF_REQUIRE_THROW_RE(cmdline::usage_error, "Unknown.*foo-bar",
235*11be35a1SLionel Sambuc                          cmd.main(&ui, args, 584));
236*11be35a1SLionel Sambuc     ATF_REQUIRE(!cmd.executed);
237*11be35a1SLionel Sambuc }
238*11be35a1SLionel Sambuc 
239*11be35a1SLionel Sambuc 
240*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(base_command_no_data__getters);
ATF_TEST_CASE_BODY(base_command_no_data__getters)241*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(base_command_no_data__getters)
242*11be35a1SLionel Sambuc {
243*11be35a1SLionel Sambuc     mock_cmd_no_data cmd;
244*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ("mock", cmd.name());
245*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ("arg1 [arg2 [arg3]]", cmd.arg_list());
246*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ("Command for testing.", cmd.short_description());
247*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ(1, cmd.options().size());
248*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ("the_string", cmd.options()[0]->long_name());
249*11be35a1SLionel Sambuc }
250*11be35a1SLionel Sambuc 
251*11be35a1SLionel Sambuc 
252*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(base_command_no_data__main__ok)
ATF_TEST_CASE_BODY(base_command_no_data__main__ok)253*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(base_command_no_data__main__ok)
254*11be35a1SLionel Sambuc {
255*11be35a1SLionel Sambuc     mock_cmd_no_data cmd;
256*11be35a1SLionel Sambuc 
257*11be35a1SLionel Sambuc     cmdline::ui_mock ui;
258*11be35a1SLionel Sambuc     cmdline::args_vector args;
259*11be35a1SLionel Sambuc     args.push_back("mock");
260*11be35a1SLionel Sambuc     args.push_back("--the_string=foo bar");
261*11be35a1SLionel Sambuc     args.push_back("one arg");
262*11be35a1SLionel Sambuc     args.push_back("another arg");
263*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ(1234, cmd.main(&ui, args));
264*11be35a1SLionel Sambuc     ATF_REQUIRE(cmd.executed);
265*11be35a1SLionel Sambuc     ATF_REQUIRE_EQ("foo bar", cmd.optvalue);
266*11be35a1SLionel Sambuc }
267*11be35a1SLionel Sambuc 
268*11be35a1SLionel Sambuc 
269*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(base_command_no_data__main__parse_cmdline_fail)
ATF_TEST_CASE_BODY(base_command_no_data__main__parse_cmdline_fail)270*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(base_command_no_data__main__parse_cmdline_fail)
271*11be35a1SLionel Sambuc {
272*11be35a1SLionel Sambuc     mock_cmd_no_data cmd;
273*11be35a1SLionel Sambuc 
274*11be35a1SLionel Sambuc     cmdline::ui_mock ui;
275*11be35a1SLionel Sambuc     cmdline::args_vector args;
276*11be35a1SLionel Sambuc     args.push_back("mock");
277*11be35a1SLionel Sambuc     args.push_back("--foo-bar");
278*11be35a1SLionel Sambuc     ATF_REQUIRE_THROW_RE(cmdline::usage_error, "Unknown.*foo-bar",
279*11be35a1SLionel Sambuc                          cmd.main(&ui, args));
280*11be35a1SLionel Sambuc     ATF_REQUIRE(!cmd.executed);
281*11be35a1SLionel Sambuc }
282*11be35a1SLionel Sambuc 
283*11be35a1SLionel Sambuc 
ATF_INIT_TEST_CASES(tcs)284*11be35a1SLionel Sambuc ATF_INIT_TEST_CASES(tcs)
285*11be35a1SLionel Sambuc {
286*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, command_proto__parse_cmdline__ok);
287*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, command_proto__parse_cmdline__parse_fail);
288*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, command_proto__parse_cmdline__args_invalid);
289*11be35a1SLionel Sambuc 
290*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, base_command__getters);
291*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, base_command__main__ok);
292*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, base_command__main__parse_cmdline_fail);
293*11be35a1SLionel Sambuc 
294*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, base_command_no_data__getters);
295*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, base_command_no_data__main__ok);
296*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, base_command_no_data__main__parse_cmdline_fail);
297*11be35a1SLionel Sambuc }
298