xref: /freebsd/contrib/kyua/cli/cmd_help_test.cpp (revision b0d29bc47dba79f6f38e67eabadfb4b32ffd9390)
1*b0d29bc4SBrooks Davis // Copyright 2010 The Kyua Authors.
2*b0d29bc4SBrooks Davis // All rights reserved.
3*b0d29bc4SBrooks Davis //
4*b0d29bc4SBrooks Davis // Redistribution and use in source and binary forms, with or without
5*b0d29bc4SBrooks Davis // modification, are permitted provided that the following conditions are
6*b0d29bc4SBrooks Davis // met:
7*b0d29bc4SBrooks Davis //
8*b0d29bc4SBrooks Davis // * Redistributions of source code must retain the above copyright
9*b0d29bc4SBrooks Davis //   notice, this list of conditions and the following disclaimer.
10*b0d29bc4SBrooks Davis // * Redistributions in binary form must reproduce the above copyright
11*b0d29bc4SBrooks Davis //   notice, this list of conditions and the following disclaimer in the
12*b0d29bc4SBrooks Davis //   documentation and/or other materials provided with the distribution.
13*b0d29bc4SBrooks Davis // * Neither the name of Google Inc. nor the names of its contributors
14*b0d29bc4SBrooks Davis //   may be used to endorse or promote products derived from this software
15*b0d29bc4SBrooks Davis //   without specific prior written permission.
16*b0d29bc4SBrooks Davis //
17*b0d29bc4SBrooks Davis // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*b0d29bc4SBrooks Davis // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*b0d29bc4SBrooks Davis // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*b0d29bc4SBrooks Davis // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*b0d29bc4SBrooks Davis // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*b0d29bc4SBrooks Davis // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*b0d29bc4SBrooks Davis // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*b0d29bc4SBrooks Davis // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*b0d29bc4SBrooks Davis // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*b0d29bc4SBrooks Davis // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*b0d29bc4SBrooks Davis // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*b0d29bc4SBrooks Davis 
29*b0d29bc4SBrooks Davis #include "cli/cmd_help.hpp"
30*b0d29bc4SBrooks Davis 
31*b0d29bc4SBrooks Davis #include <algorithm>
32*b0d29bc4SBrooks Davis #include <cstdlib>
33*b0d29bc4SBrooks Davis #include <iterator>
34*b0d29bc4SBrooks Davis 
35*b0d29bc4SBrooks Davis #include <atf-c++.hpp>
36*b0d29bc4SBrooks Davis 
37*b0d29bc4SBrooks Davis #include "cli/common.ipp"
38*b0d29bc4SBrooks Davis #include "engine/config.hpp"
39*b0d29bc4SBrooks Davis #include "utils/cmdline/commands_map.ipp"
40*b0d29bc4SBrooks Davis #include "utils/cmdline/exceptions.hpp"
41*b0d29bc4SBrooks Davis #include "utils/cmdline/globals.hpp"
42*b0d29bc4SBrooks Davis #include "utils/cmdline/options.hpp"
43*b0d29bc4SBrooks Davis #include "utils/cmdline/parser.hpp"
44*b0d29bc4SBrooks Davis #include "utils/cmdline/ui_mock.hpp"
45*b0d29bc4SBrooks Davis #include "utils/config/tree.ipp"
46*b0d29bc4SBrooks Davis #include "utils/defs.hpp"
47*b0d29bc4SBrooks Davis #include "utils/sanity.hpp"
48*b0d29bc4SBrooks Davis 
49*b0d29bc4SBrooks Davis #if defined(HAVE_CONFIG_H)
50*b0d29bc4SBrooks Davis #   include "config.h"
51*b0d29bc4SBrooks Davis #endif
52*b0d29bc4SBrooks Davis 
53*b0d29bc4SBrooks Davis namespace cmdline = utils::cmdline;
54*b0d29bc4SBrooks Davis namespace config = utils::config;
55*b0d29bc4SBrooks Davis 
56*b0d29bc4SBrooks Davis using cli::cmd_help;
57*b0d29bc4SBrooks Davis 
58*b0d29bc4SBrooks Davis 
59*b0d29bc4SBrooks Davis namespace {
60*b0d29bc4SBrooks Davis 
61*b0d29bc4SBrooks Davis 
62*b0d29bc4SBrooks Davis /// Mock command with a simple definition (no options, no arguments).
63*b0d29bc4SBrooks Davis ///
64*b0d29bc4SBrooks Davis /// Attempting to run this command will result in a crash.  It is only provided
65*b0d29bc4SBrooks Davis /// to validate the generation of interactive help.
66*b0d29bc4SBrooks Davis class cmd_mock_simple : public cli::cli_command {
67*b0d29bc4SBrooks Davis public:
68*b0d29bc4SBrooks Davis     /// Constructs a new mock command.
69*b0d29bc4SBrooks Davis     ///
70*b0d29bc4SBrooks Davis     /// \param name_ The name of the command to create.
cmd_mock_simple(const char * name_)71*b0d29bc4SBrooks Davis     cmd_mock_simple(const char* name_) : cli::cli_command(
72*b0d29bc4SBrooks Davis         name_, "", 0, 0, "Simple command")
73*b0d29bc4SBrooks Davis     {
74*b0d29bc4SBrooks Davis     }
75*b0d29bc4SBrooks Davis 
76*b0d29bc4SBrooks Davis     /// Runs the mock command.
77*b0d29bc4SBrooks Davis     ///
78*b0d29bc4SBrooks Davis     /// \return Nothing because this function is never called.
79*b0d29bc4SBrooks Davis     int
run(cmdline::ui *,const cmdline::parsed_cmdline &,const config::tree &)80*b0d29bc4SBrooks Davis     run(cmdline::ui* /* ui */,
81*b0d29bc4SBrooks Davis         const cmdline::parsed_cmdline& /* cmdline */,
82*b0d29bc4SBrooks Davis         const config::tree& /* user_config */)
83*b0d29bc4SBrooks Davis     {
84*b0d29bc4SBrooks Davis         UNREACHABLE;
85*b0d29bc4SBrooks Davis     }
86*b0d29bc4SBrooks Davis };
87*b0d29bc4SBrooks Davis 
88*b0d29bc4SBrooks Davis 
89*b0d29bc4SBrooks Davis /// Mock command with a complex definition (some options, some arguments).
90*b0d29bc4SBrooks Davis ///
91*b0d29bc4SBrooks Davis /// Attempting to run this command will result in a crash.  It is only provided
92*b0d29bc4SBrooks Davis /// to validate the generation of interactive help.
93*b0d29bc4SBrooks Davis class cmd_mock_complex : public cli::cli_command {
94*b0d29bc4SBrooks Davis public:
95*b0d29bc4SBrooks Davis     /// Constructs a new mock command.
96*b0d29bc4SBrooks Davis     ///
97*b0d29bc4SBrooks Davis     /// \param name_ The name of the command to create.
cmd_mock_complex(const char * name_)98*b0d29bc4SBrooks Davis     cmd_mock_complex(const char* name_) : cli::cli_command(
99*b0d29bc4SBrooks Davis         name_, "[arg1 .. argN]", 0, 2, "Complex command")
100*b0d29bc4SBrooks Davis     {
101*b0d29bc4SBrooks Davis         add_option(cmdline::bool_option("flag_a", "Flag A"));
102*b0d29bc4SBrooks Davis         add_option(cmdline::bool_option('b', "flag_b", "Flag B"));
103*b0d29bc4SBrooks Davis         add_option(cmdline::string_option('c', "flag_c", "Flag C", "c_arg"));
104*b0d29bc4SBrooks Davis         add_option(cmdline::string_option("flag_d", "Flag D", "d_arg", "foo"));
105*b0d29bc4SBrooks Davis     }
106*b0d29bc4SBrooks Davis 
107*b0d29bc4SBrooks Davis     /// Runs the mock command.
108*b0d29bc4SBrooks Davis     ///
109*b0d29bc4SBrooks Davis     /// \return Nothing because this function is never called.
110*b0d29bc4SBrooks Davis     int
run(cmdline::ui *,const cmdline::parsed_cmdline &,const config::tree &)111*b0d29bc4SBrooks Davis     run(cmdline::ui* /* ui */,
112*b0d29bc4SBrooks Davis         const cmdline::parsed_cmdline& /* cmdline */,
113*b0d29bc4SBrooks Davis         const config::tree& /* user_config */)
114*b0d29bc4SBrooks Davis     {
115*b0d29bc4SBrooks Davis         UNREACHABLE;
116*b0d29bc4SBrooks Davis     }
117*b0d29bc4SBrooks Davis };
118*b0d29bc4SBrooks Davis 
119*b0d29bc4SBrooks Davis 
120*b0d29bc4SBrooks Davis /// Initializes the cmdline library and generates the set of test commands.
121*b0d29bc4SBrooks Davis ///
122*b0d29bc4SBrooks Davis /// \param [out] commands A mapping that is updated to contain the commands to
123*b0d29bc4SBrooks Davis ///     use for testing.
124*b0d29bc4SBrooks Davis static void
setup(cmdline::commands_map<cli::cli_command> & commands)125*b0d29bc4SBrooks Davis setup(cmdline::commands_map< cli::cli_command >& commands)
126*b0d29bc4SBrooks Davis {
127*b0d29bc4SBrooks Davis     cmdline::init("progname");
128*b0d29bc4SBrooks Davis 
129*b0d29bc4SBrooks Davis     commands.insert(new cmd_mock_simple("mock_simple"));
130*b0d29bc4SBrooks Davis     commands.insert(new cmd_mock_complex("mock_complex"));
131*b0d29bc4SBrooks Davis 
132*b0d29bc4SBrooks Davis     commands.insert(new cmd_mock_simple("mock_simple_2"), "First");
133*b0d29bc4SBrooks Davis     commands.insert(new cmd_mock_complex("mock_complex_2"), "First");
134*b0d29bc4SBrooks Davis 
135*b0d29bc4SBrooks Davis     commands.insert(new cmd_mock_simple("mock_simple_3"), "Second");
136*b0d29bc4SBrooks Davis }
137*b0d29bc4SBrooks Davis 
138*b0d29bc4SBrooks Davis 
139*b0d29bc4SBrooks Davis /// Performs a test on the global help (not that of a subcommand).
140*b0d29bc4SBrooks Davis ///
141*b0d29bc4SBrooks Davis /// \param general_options The genral options supported by the tool, if any.
142*b0d29bc4SBrooks Davis /// \param expected_options Expected lines of help output documenting the
143*b0d29bc4SBrooks Davis ///     options in general_options.
144*b0d29bc4SBrooks Davis /// \param ui The cmdline::mock_ui object to which to write the output.
145*b0d29bc4SBrooks Davis static void
global_test(const cmdline::options_vector & general_options,const std::vector<std::string> & expected_options,cmdline::ui_mock & ui)146*b0d29bc4SBrooks Davis global_test(const cmdline::options_vector& general_options,
147*b0d29bc4SBrooks Davis             const std::vector< std::string >& expected_options,
148*b0d29bc4SBrooks Davis             cmdline::ui_mock& ui)
149*b0d29bc4SBrooks Davis {
150*b0d29bc4SBrooks Davis     cmdline::commands_map< cli::cli_command > mock_commands;
151*b0d29bc4SBrooks Davis     setup(mock_commands);
152*b0d29bc4SBrooks Davis 
153*b0d29bc4SBrooks Davis     cmdline::args_vector args;
154*b0d29bc4SBrooks Davis     args.push_back("help");
155*b0d29bc4SBrooks Davis 
156*b0d29bc4SBrooks Davis     cmd_help cmd(&general_options, &mock_commands);
157*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(EXIT_SUCCESS, cmd.main(&ui, args, engine::default_config()));
158*b0d29bc4SBrooks Davis 
159*b0d29bc4SBrooks Davis     std::vector< std::string > expected;
160*b0d29bc4SBrooks Davis 
161*b0d29bc4SBrooks Davis     expected.push_back(PACKAGE " (" PACKAGE_NAME ") " PACKAGE_VERSION);
162*b0d29bc4SBrooks Davis     expected.push_back("");
163*b0d29bc4SBrooks Davis     expected.push_back("Usage: progname [general_options] command "
164*b0d29bc4SBrooks Davis                        "[command_options] [args]");
165*b0d29bc4SBrooks Davis     if (!general_options.empty()) {
166*b0d29bc4SBrooks Davis         expected.push_back("");
167*b0d29bc4SBrooks Davis         expected.push_back("Available general options:");
168*b0d29bc4SBrooks Davis         std::copy(expected_options.begin(), expected_options.end(),
169*b0d29bc4SBrooks Davis                   std::back_inserter(expected));
170*b0d29bc4SBrooks Davis     }
171*b0d29bc4SBrooks Davis     expected.push_back("");
172*b0d29bc4SBrooks Davis     expected.push_back("Generic commands:");
173*b0d29bc4SBrooks Davis     expected.push_back("  mock_complex    Complex command.");
174*b0d29bc4SBrooks Davis     expected.push_back("  mock_simple     Simple command.");
175*b0d29bc4SBrooks Davis     expected.push_back("");
176*b0d29bc4SBrooks Davis     expected.push_back("First commands:");
177*b0d29bc4SBrooks Davis     expected.push_back("  mock_complex_2  Complex command.");
178*b0d29bc4SBrooks Davis     expected.push_back("  mock_simple_2   Simple command.");
179*b0d29bc4SBrooks Davis     expected.push_back("");
180*b0d29bc4SBrooks Davis     expected.push_back("Second commands:");
181*b0d29bc4SBrooks Davis     expected.push_back("  mock_simple_3   Simple command.");
182*b0d29bc4SBrooks Davis     expected.push_back("");
183*b0d29bc4SBrooks Davis     expected.push_back("See kyua(1) for more details.");
184*b0d29bc4SBrooks Davis 
185*b0d29bc4SBrooks Davis     ATF_REQUIRE(expected == ui.out_log());
186*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
187*b0d29bc4SBrooks Davis }
188*b0d29bc4SBrooks Davis 
189*b0d29bc4SBrooks Davis 
190*b0d29bc4SBrooks Davis }  // anonymous namespace
191*b0d29bc4SBrooks Davis 
192*b0d29bc4SBrooks Davis 
193*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(global__no_options);
ATF_TEST_CASE_BODY(global__no_options)194*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(global__no_options)
195*b0d29bc4SBrooks Davis {
196*b0d29bc4SBrooks Davis     cmdline::ui_mock ui;
197*b0d29bc4SBrooks Davis 
198*b0d29bc4SBrooks Davis     cmdline::options_vector general_options;
199*b0d29bc4SBrooks Davis 
200*b0d29bc4SBrooks Davis     global_test(general_options, std::vector< std::string >(), ui);
201*b0d29bc4SBrooks Davis }
202*b0d29bc4SBrooks Davis 
203*b0d29bc4SBrooks Davis 
204*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(global__some_options);
ATF_TEST_CASE_BODY(global__some_options)205*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(global__some_options)
206*b0d29bc4SBrooks Davis {
207*b0d29bc4SBrooks Davis     cmdline::ui_mock ui;
208*b0d29bc4SBrooks Davis 
209*b0d29bc4SBrooks Davis     cmdline::options_vector general_options;
210*b0d29bc4SBrooks Davis     const cmdline::bool_option flag_a("flag_a", "Flag A");
211*b0d29bc4SBrooks Davis     general_options.push_back(&flag_a);
212*b0d29bc4SBrooks Davis     const cmdline::string_option flag_c('c', "lc", "Flag C", "X");
213*b0d29bc4SBrooks Davis     general_options.push_back(&flag_c);
214*b0d29bc4SBrooks Davis 
215*b0d29bc4SBrooks Davis     std::vector< std::string > expected;
216*b0d29bc4SBrooks Davis     expected.push_back("  --flag_a        Flag A.");
217*b0d29bc4SBrooks Davis     expected.push_back("  -c X, --lc=X    Flag C.");
218*b0d29bc4SBrooks Davis 
219*b0d29bc4SBrooks Davis     global_test(general_options, expected, ui);
220*b0d29bc4SBrooks Davis }
221*b0d29bc4SBrooks Davis 
222*b0d29bc4SBrooks Davis 
223*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(subcommand__simple);
ATF_TEST_CASE_BODY(subcommand__simple)224*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(subcommand__simple)
225*b0d29bc4SBrooks Davis {
226*b0d29bc4SBrooks Davis     cmdline::options_vector general_options;
227*b0d29bc4SBrooks Davis 
228*b0d29bc4SBrooks Davis     cmdline::commands_map< cli::cli_command > mock_commands;
229*b0d29bc4SBrooks Davis     setup(mock_commands);
230*b0d29bc4SBrooks Davis 
231*b0d29bc4SBrooks Davis     cmdline::args_vector args;
232*b0d29bc4SBrooks Davis     args.push_back("help");
233*b0d29bc4SBrooks Davis     args.push_back("mock_simple");
234*b0d29bc4SBrooks Davis 
235*b0d29bc4SBrooks Davis     cmd_help cmd(&general_options, &mock_commands);
236*b0d29bc4SBrooks Davis     cmdline::ui_mock ui;
237*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(EXIT_SUCCESS, cmd.main(&ui, args, engine::default_config()));
238*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection(
239*b0d29bc4SBrooks Davis         "^kyua.*" PACKAGE_VERSION, ui.out_log()));
240*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection(
241*b0d29bc4SBrooks Davis         "^Usage: progname \\[general_options\\] mock_simple$", ui.out_log()));
242*b0d29bc4SBrooks Davis     ATF_REQUIRE(!atf::utils::grep_collection(
243*b0d29bc4SBrooks Davis         "Available.*options", ui.out_log()));
244*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection(
245*b0d29bc4SBrooks Davis         "^See kyua-mock_simple\\(1\\) for more details.", ui.out_log()));
246*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
247*b0d29bc4SBrooks Davis }
248*b0d29bc4SBrooks Davis 
249*b0d29bc4SBrooks Davis 
250*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(subcommand__complex);
ATF_TEST_CASE_BODY(subcommand__complex)251*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(subcommand__complex)
252*b0d29bc4SBrooks Davis {
253*b0d29bc4SBrooks Davis     cmdline::options_vector general_options;
254*b0d29bc4SBrooks Davis     const cmdline::bool_option global_a("global_a", "Global A");
255*b0d29bc4SBrooks Davis     general_options.push_back(&global_a);
256*b0d29bc4SBrooks Davis     const cmdline::string_option global_c('c', "global_c", "Global C",
257*b0d29bc4SBrooks Davis                                           "c_global");
258*b0d29bc4SBrooks Davis     general_options.push_back(&global_c);
259*b0d29bc4SBrooks Davis 
260*b0d29bc4SBrooks Davis     cmdline::commands_map< cli::cli_command > mock_commands;
261*b0d29bc4SBrooks Davis     setup(mock_commands);
262*b0d29bc4SBrooks Davis 
263*b0d29bc4SBrooks Davis     cmdline::args_vector args;
264*b0d29bc4SBrooks Davis     args.push_back("help");
265*b0d29bc4SBrooks Davis     args.push_back("mock_complex");
266*b0d29bc4SBrooks Davis 
267*b0d29bc4SBrooks Davis     cmd_help cmd(&general_options, &mock_commands);
268*b0d29bc4SBrooks Davis     cmdline::ui_mock ui;
269*b0d29bc4SBrooks Davis     ATF_REQUIRE_EQ(EXIT_SUCCESS, cmd.main(&ui, args, engine::default_config()));
270*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection(
271*b0d29bc4SBrooks Davis         "^kyua.*" PACKAGE_VERSION, ui.out_log()));
272*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection(
273*b0d29bc4SBrooks Davis         "^Usage: progname \\[general_options\\] mock_complex "
274*b0d29bc4SBrooks Davis         "\\[command_options\\] \\[arg1 .. argN\\]$", ui.out_log()));
275*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection("Available general options",
276*b0d29bc4SBrooks Davis                                             ui.out_log()));
277*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection("--global_a", ui.out_log()));
278*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection("--global_c=c_global",
279*b0d29bc4SBrooks Davis                                             ui.out_log()));
280*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection("Available command options",
281*b0d29bc4SBrooks Davis                                             ui.out_log()));
282*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection("--flag_a   *Flag A",
283*b0d29bc4SBrooks Davis                                             ui.out_log()));
284*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection("-b.*--flag_b   *Flag B",
285*b0d29bc4SBrooks Davis                                             ui.out_log()));
286*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection(
287*b0d29bc4SBrooks Davis         "-c c_arg.*--flag_c=c_arg   *Flag C", ui.out_log()));
288*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection(
289*b0d29bc4SBrooks Davis         "--flag_d=d_arg   *Flag D.*default.*foo", ui.out_log()));
290*b0d29bc4SBrooks Davis     ATF_REQUIRE(atf::utils::grep_collection(
291*b0d29bc4SBrooks Davis         "^See kyua-mock_complex\\(1\\) for more details.", ui.out_log()));
292*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
293*b0d29bc4SBrooks Davis }
294*b0d29bc4SBrooks Davis 
295*b0d29bc4SBrooks Davis 
296*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(subcommand__unknown);
ATF_TEST_CASE_BODY(subcommand__unknown)297*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(subcommand__unknown)
298*b0d29bc4SBrooks Davis {
299*b0d29bc4SBrooks Davis     cmdline::options_vector general_options;
300*b0d29bc4SBrooks Davis 
301*b0d29bc4SBrooks Davis     cmdline::commands_map< cli::cli_command > mock_commands;
302*b0d29bc4SBrooks Davis     setup(mock_commands);
303*b0d29bc4SBrooks Davis 
304*b0d29bc4SBrooks Davis     cmdline::args_vector args;
305*b0d29bc4SBrooks Davis     args.push_back("help");
306*b0d29bc4SBrooks Davis     args.push_back("foobar");
307*b0d29bc4SBrooks Davis 
308*b0d29bc4SBrooks Davis     cmd_help cmd(&general_options, &mock_commands);
309*b0d29bc4SBrooks Davis     cmdline::ui_mock ui;
310*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW_RE(cmdline::usage_error, "command foobar.*not exist",
311*b0d29bc4SBrooks Davis                          cmd.main(&ui, args, engine::default_config()));
312*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.out_log().empty());
313*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
314*b0d29bc4SBrooks Davis }
315*b0d29bc4SBrooks Davis 
316*b0d29bc4SBrooks Davis 
317*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(invalid_args);
ATF_TEST_CASE_BODY(invalid_args)318*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(invalid_args)
319*b0d29bc4SBrooks Davis {
320*b0d29bc4SBrooks Davis     cmdline::options_vector general_options;
321*b0d29bc4SBrooks Davis 
322*b0d29bc4SBrooks Davis     cmdline::commands_map< cli::cli_command > mock_commands;
323*b0d29bc4SBrooks Davis     setup(mock_commands);
324*b0d29bc4SBrooks Davis 
325*b0d29bc4SBrooks Davis     cmdline::args_vector args;
326*b0d29bc4SBrooks Davis     args.push_back("help");
327*b0d29bc4SBrooks Davis     args.push_back("mock_simple");
328*b0d29bc4SBrooks Davis     args.push_back("mock_complex");
329*b0d29bc4SBrooks Davis 
330*b0d29bc4SBrooks Davis     cmd_help cmd(&general_options, &mock_commands);
331*b0d29bc4SBrooks Davis     cmdline::ui_mock ui;
332*b0d29bc4SBrooks Davis     ATF_REQUIRE_THROW_RE(cmdline::usage_error, "Too many arguments",
333*b0d29bc4SBrooks Davis                          cmd.main(&ui, args, engine::default_config()));
334*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.out_log().empty());
335*b0d29bc4SBrooks Davis     ATF_REQUIRE(ui.err_log().empty());
336*b0d29bc4SBrooks Davis }
337*b0d29bc4SBrooks Davis 
338*b0d29bc4SBrooks Davis 
ATF_INIT_TEST_CASES(tcs)339*b0d29bc4SBrooks Davis ATF_INIT_TEST_CASES(tcs)
340*b0d29bc4SBrooks Davis {
341*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, global__no_options);
342*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, global__some_options);
343*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, subcommand__simple);
344*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, subcommand__complex);
345*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, subcommand__unknown);
346*b0d29bc4SBrooks Davis     ATF_ADD_TEST_CASE(tcs, invalid_args);
347*b0d29bc4SBrooks Davis }
348