Path: blob/main/contrib/kyua/utils/cmdline/base_command_test.cpp
48178 views
// Copyright 2010 The Kyua Authors.1// All rights reserved.2//3// Redistribution and use in source and binary forms, with or without4// modification, are permitted provided that the following conditions are5// met:6//7// * Redistributions of source code must retain the above copyright8// notice, this list of conditions and the following disclaimer.9// * Redistributions in binary form must reproduce the above copyright10// notice, this list of conditions and the following disclaimer in the11// documentation and/or other materials provided with the distribution.12// * Neither the name of Google Inc. nor the names of its contributors13// may be used to endorse or promote products derived from this software14// without specific prior written permission.15//16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.2728#include "utils/cmdline/base_command.ipp"2930#include <atf-c++.hpp>3132#include "utils/cmdline/exceptions.hpp"33#include "utils/cmdline/options.hpp"34#include "utils/cmdline/parser.ipp"35#include "utils/cmdline/ui_mock.hpp"36#include "utils/defs.hpp"3738namespace cmdline = utils::cmdline;394041namespace {424344/// Mock command to test the cmdline::base_command base class.45///46/// \param Data The type of the opaque data object passed to main().47/// \param ExpectedData The value run() will expect to find in the Data object48/// passed to main().49template< typename Data, Data ExpectedData >50class mock_cmd : public cmdline::base_command< Data > {51public:52/// Indicates if run() has been called already and executed correctly.53bool executed;5455/// Contains the argument of --the_string after run() is executed.56std::string optvalue;5758/// Constructs a new mock command.59mock_cmd(void) :60cmdline::base_command< Data >("mock", "arg1 [arg2 [arg3]]", 1, 3,61"Command for testing."),62executed(false)63{64this->add_option(cmdline::string_option("the_string", "Test option",65"arg"));66}6768/// Executes the command.69///70/// \param cmdline Representation of the command line to the subcommand.71/// \param data Arbitrary data cookie passed to the command.72///73/// \return A hardcoded number for testing purposes.74int75run(cmdline::ui* /* ui */,76const cmdline::parsed_cmdline& cmdline, const Data& data)77{78if (cmdline.has_option("the_string"))79optvalue = cmdline.get_option< cmdline::string_option >(80"the_string");81ATF_REQUIRE_EQ(ExpectedData, data);82executed = true;83return 1234;84}85};868788/// Mock command to test the cmdline::base_command_no_data base class.89class mock_cmd_no_data : public cmdline::base_command_no_data {90public:91/// Indicates if run() has been called already and executed correctly.92bool executed;9394/// Contains the argument of --the_string after run() is executed.95std::string optvalue;9697/// Constructs a new mock command.98mock_cmd_no_data(void) :99cmdline::base_command_no_data("mock", "arg1 [arg2 [arg3]]", 1, 3,100"Command for testing."),101executed(false)102{103add_option(cmdline::string_option("the_string", "Test option", "arg"));104}105106/// Executes the command.107///108/// \param cmdline Representation of the command line to the subcommand.109///110/// \return A hardcoded number for testing purposes.111int112run(cmdline::ui* /* ui */,113const cmdline::parsed_cmdline& cmdline)114{115if (cmdline.has_option("the_string"))116optvalue = cmdline.get_option< cmdline::string_option >(117"the_string");118executed = true;119return 1234;120}121};122123124/// Implementation of a command to get access to parse_cmdline().125class parse_cmdline_portal : public cmdline::command_proto {126public:127/// Constructs a new mock command.128parse_cmdline_portal(void) :129cmdline::command_proto("portal", "arg1 [arg2 [arg3]]", 1, 3,130"Command for testing.")131{132this->add_option(cmdline::string_option("the_string", "Test option",133"arg"));134}135136/// Delegator for the internal parse_cmdline() method.137///138/// \param args The input arguments to be parsed.139///140/// \return The parsed command line, split in options and arguments.141cmdline::parsed_cmdline142operator()(const cmdline::args_vector& args) const143{144return parse_cmdline(args);145}146};147148149} // anonymous namespace150151152ATF_TEST_CASE_WITHOUT_HEAD(command_proto__parse_cmdline__ok);153ATF_TEST_CASE_BODY(command_proto__parse_cmdline__ok)154{155cmdline::args_vector args;156args.push_back("portal");157args.push_back("--the_string=foo bar");158args.push_back("one arg");159args.push_back("another arg");160(void)parse_cmdline_portal()(args);161}162163164ATF_TEST_CASE_WITHOUT_HEAD(command_proto__parse_cmdline__parse_fail);165ATF_TEST_CASE_BODY(command_proto__parse_cmdline__parse_fail)166{167cmdline::args_vector args;168args.push_back("portal");169args.push_back("--foo-bar");170ATF_REQUIRE_THROW_RE(cmdline::usage_error, "Unknown.*foo-bar",171(void)parse_cmdline_portal()(args));172}173174175ATF_TEST_CASE_WITHOUT_HEAD(command_proto__parse_cmdline__args_invalid);176ATF_TEST_CASE_BODY(command_proto__parse_cmdline__args_invalid)177{178cmdline::args_vector args;179args.push_back("portal");180181ATF_REQUIRE_THROW_RE(cmdline::usage_error, "Not enough arguments",182(void)parse_cmdline_portal()(args));183184args.push_back("1");185args.push_back("2");186args.push_back("3");187args.push_back("4");188ATF_REQUIRE_THROW_RE(cmdline::usage_error, "Too many arguments",189(void)parse_cmdline_portal()(args));190}191192193ATF_TEST_CASE_WITHOUT_HEAD(base_command__getters);194ATF_TEST_CASE_BODY(base_command__getters)195{196mock_cmd< int, 584 > cmd;197ATF_REQUIRE_EQ("mock", cmd.name());198ATF_REQUIRE_EQ("arg1 [arg2 [arg3]]", cmd.arg_list());199ATF_REQUIRE_EQ("Command for testing.", cmd.short_description());200ATF_REQUIRE_EQ(1, cmd.options().size());201ATF_REQUIRE_EQ("the_string", cmd.options()[0]->long_name());202}203204205ATF_TEST_CASE_WITHOUT_HEAD(base_command__main__ok)206ATF_TEST_CASE_BODY(base_command__main__ok)207{208mock_cmd< int, 584 > cmd;209210cmdline::ui_mock ui;211cmdline::args_vector args;212args.push_back("mock");213args.push_back("--the_string=foo bar");214args.push_back("one arg");215args.push_back("another arg");216ATF_REQUIRE_EQ(1234, cmd.main(&ui, args, 584));217ATF_REQUIRE(cmd.executed);218ATF_REQUIRE_EQ("foo bar", cmd.optvalue);219}220221222ATF_TEST_CASE_WITHOUT_HEAD(base_command__main__parse_cmdline_fail)223ATF_TEST_CASE_BODY(base_command__main__parse_cmdline_fail)224{225mock_cmd< int, 584 > cmd;226227cmdline::ui_mock ui;228cmdline::args_vector args;229args.push_back("mock");230args.push_back("--foo-bar");231ATF_REQUIRE_THROW_RE(cmdline::usage_error, "Unknown.*foo-bar",232cmd.main(&ui, args, 584));233ATF_REQUIRE(!cmd.executed);234}235236237ATF_TEST_CASE_WITHOUT_HEAD(base_command_no_data__getters);238ATF_TEST_CASE_BODY(base_command_no_data__getters)239{240mock_cmd_no_data cmd;241ATF_REQUIRE_EQ("mock", cmd.name());242ATF_REQUIRE_EQ("arg1 [arg2 [arg3]]", cmd.arg_list());243ATF_REQUIRE_EQ("Command for testing.", cmd.short_description());244ATF_REQUIRE_EQ(1, cmd.options().size());245ATF_REQUIRE_EQ("the_string", cmd.options()[0]->long_name());246}247248249ATF_TEST_CASE_WITHOUT_HEAD(base_command_no_data__main__ok)250ATF_TEST_CASE_BODY(base_command_no_data__main__ok)251{252mock_cmd_no_data cmd;253254cmdline::ui_mock ui;255cmdline::args_vector args;256args.push_back("mock");257args.push_back("--the_string=foo bar");258args.push_back("one arg");259args.push_back("another arg");260ATF_REQUIRE_EQ(1234, cmd.main(&ui, args));261ATF_REQUIRE(cmd.executed);262ATF_REQUIRE_EQ("foo bar", cmd.optvalue);263}264265266ATF_TEST_CASE_WITHOUT_HEAD(base_command_no_data__main__parse_cmdline_fail)267ATF_TEST_CASE_BODY(base_command_no_data__main__parse_cmdline_fail)268{269mock_cmd_no_data cmd;270271cmdline::ui_mock ui;272cmdline::args_vector args;273args.push_back("mock");274args.push_back("--foo-bar");275ATF_REQUIRE_THROW_RE(cmdline::usage_error, "Unknown.*foo-bar",276cmd.main(&ui, args));277ATF_REQUIRE(!cmd.executed);278}279280281ATF_INIT_TEST_CASES(tcs)282{283ATF_ADD_TEST_CASE(tcs, command_proto__parse_cmdline__ok);284ATF_ADD_TEST_CASE(tcs, command_proto__parse_cmdline__parse_fail);285ATF_ADD_TEST_CASE(tcs, command_proto__parse_cmdline__args_invalid);286287ATF_ADD_TEST_CASE(tcs, base_command__getters);288ATF_ADD_TEST_CASE(tcs, base_command__main__ok);289ATF_ADD_TEST_CASE(tcs, base_command__main__parse_cmdline_fail);290291ATF_ADD_TEST_CASE(tcs, base_command_no_data__getters);292ATF_ADD_TEST_CASE(tcs, base_command_no_data__main__ok);293ATF_ADD_TEST_CASE(tcs, base_command_no_data__main__parse_cmdline_fail);294}295296297