mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-04-29 12:13:52 +00:00
Moving code to Error, better ArgumentMismatch throwing
This commit is contained in:
parent
4d5bff2393
commit
f6c9ce6109
@ -452,7 +452,7 @@ class App {
|
||||
CLI::callback_t fun = [&member, options, simple_name](CLI::results_t res) {
|
||||
bool retval = detail::lexical_cast(res[0], member);
|
||||
if(!retval)
|
||||
throw ConversionError("The value " + res[0] + "is not an allowed value for " + simple_name);
|
||||
throw ConversionError(res[0], simple_name);
|
||||
return std::find(std::begin(options), std::end(options), member) != std::end(options);
|
||||
};
|
||||
|
||||
@ -475,7 +475,7 @@ class App {
|
||||
CLI::callback_t fun = [&member, options, simple_name](CLI::results_t res) {
|
||||
bool retval = detail::lexical_cast(res[0], member);
|
||||
if(!retval)
|
||||
throw ConversionError("The value " + res[0] + "is not an allowed value for " + simple_name);
|
||||
throw ConversionError(res[0], simple_name);
|
||||
return std::find(std::begin(options), std::end(options), member) != std::end(options);
|
||||
};
|
||||
|
||||
@ -504,7 +504,7 @@ class App {
|
||||
return detail::to_lower(val) == member;
|
||||
});
|
||||
if(iter == std::end(options))
|
||||
throw ConversionError("The value " + member + "is not an allowed value for " + simple_name);
|
||||
throw ConversionError(member, simple_name);
|
||||
else {
|
||||
member = *iter;
|
||||
return true;
|
||||
@ -533,7 +533,7 @@ class App {
|
||||
return detail::to_lower(val) == member;
|
||||
});
|
||||
if(iter == std::end(options))
|
||||
throw ConversionError("The value " + member + "is not an allowed value for " + simple_name);
|
||||
throw ConversionError(member, simple_name);
|
||||
else {
|
||||
member = *iter;
|
||||
return true;
|
||||
@ -1149,12 +1149,7 @@ class App {
|
||||
|
||||
// Required but empty
|
||||
if(opt->get_required() && opt->count() == 0)
|
||||
throw RequiredError(opt->help_name() + " is required");
|
||||
|
||||
// Partially filled
|
||||
if(opt->get_expected() > 0 && static_cast<int>(opt->count()) < opt->get_expected())
|
||||
throw RequiredError(opt->help_name() + " requires " + std::to_string(opt->get_expected()) +
|
||||
" arguments");
|
||||
throw RequiredError(opt->single_name() + " is required");
|
||||
}
|
||||
// Requires
|
||||
for(const Option *opt_req : opt->requires_)
|
||||
@ -1409,8 +1404,8 @@ class App {
|
||||
}
|
||||
|
||||
if(num > 0) {
|
||||
throw RequiredError(op->single_name() + ": " + std::to_string(num) + " required " +
|
||||
op->get_type_name() + " missing");
|
||||
throw ArgumentMismatch(op->single_name() + ": " + std::to_string(num) + " required " +
|
||||
op->get_type_name() + " missing");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1490,8 +1485,8 @@ class App {
|
||||
args.pop_back();
|
||||
}
|
||||
if(num > 0) {
|
||||
throw RequiredError(op->single_name() + ": " + std::to_string(num) + " required " +
|
||||
op->get_type_name() + " missing");
|
||||
throw ArgumentMismatch(op->single_name() + ": " + std::to_string(num) + " required " +
|
||||
op->get_type_name() + " missing");
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -126,19 +126,22 @@ class RuntimeError : public ParseError {
|
||||
/// Thrown when parsing an INI file and it is missing
|
||||
class FileError : public ParseError {
|
||||
CLI11_ERROR_DEF(ParseError, FileError)
|
||||
FileError(std::string msg) : FileError(msg, ExitCodes::File) {}
|
||||
FileError(std::string name) : FileError(name + " was not readable (missing?)", ExitCodes::File) {}
|
||||
};
|
||||
|
||||
/// Thrown when conversion call back fails, such as when an int fails to coerce to a string
|
||||
class ConversionError : public ParseError {
|
||||
CLI11_ERROR_DEF(ParseError, ConversionError)
|
||||
CLI11_ERROR_SIMPLE(ConversionError)
|
||||
ConversionError(std::string member, std::string name)
|
||||
: ConversionError("The value " + member + "is not an allowed value for " + name) {}
|
||||
};
|
||||
|
||||
/// Thrown when validation of results fails
|
||||
class ValidationError : public ParseError {
|
||||
CLI11_ERROR_DEF(ParseError, ValidationError)
|
||||
CLI11_ERROR_SIMPLE(ValidationError)
|
||||
ValidationError(std::string name, std::string msg) : ValidationError(name + ": " + msg) {}
|
||||
};
|
||||
|
||||
/// Thrown when a required option is missing
|
||||
@ -150,6 +153,7 @@ class RequiredError : public ParseError {
|
||||
/// Thrown when the wrong number of arguments has been recieved
|
||||
class ArgumentMismatch : ParseError {
|
||||
CLI11_ERROR_DEF(ParseError, ArgumentMismatch)
|
||||
CLI11_ERROR_SIMPLE(ArgumentMismatch)
|
||||
ArgumentMismatch(std::string name, int expected, size_t recieved)
|
||||
: ArgumentMismatch(expected > 0 ? ("Expected exactly " + std::to_string(expected) + " arguments to " + name +
|
||||
", got " + std::to_string(recieved))
|
||||
|
@ -106,7 +106,7 @@ inline std::vector<ini_ret_t> parse_ini(const std::string &name) {
|
||||
|
||||
std::ifstream input{name};
|
||||
if(!input.good())
|
||||
throw FileError(name + " was not readable (missing?)");
|
||||
throw FileError(name);
|
||||
|
||||
return parse_ini(input);
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ class Option : public OptionBase<Option> {
|
||||
for(const std::function<std::string(std::string &)> &vali : validators_) {
|
||||
std::string err_msg = vali(result);
|
||||
if(!err_msg.empty())
|
||||
throw ValidationError(single_name() + ": " + err_msg);
|
||||
throw ValidationError(single_name(), err_msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,6 +243,26 @@ TEST_F(TApp, MissingValueNonRequiredOpt) {
|
||||
EXPECT_ANY_THROW(run());
|
||||
}
|
||||
|
||||
TEST_F(TApp, NotRequiredOptsSingle) {
|
||||
|
||||
std::string str;
|
||||
app.add_option("--str", str);
|
||||
|
||||
args = {"--str"};
|
||||
|
||||
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||
}
|
||||
|
||||
TEST_F(TApp, NotRequiredOptsSingleShort) {
|
||||
|
||||
std::string str;
|
||||
app.add_option("-s", str);
|
||||
|
||||
args = {"-s"};
|
||||
|
||||
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||
}
|
||||
|
||||
TEST_F(TApp, RequiredOptsSingle) {
|
||||
|
||||
std::string str;
|
||||
@ -250,7 +270,7 @@ TEST_F(TApp, RequiredOptsSingle) {
|
||||
|
||||
args = {"--str"};
|
||||
|
||||
EXPECT_THROW(run(), CLI::RequiredError);
|
||||
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||
}
|
||||
|
||||
TEST_F(TApp, RequiredOptsSingleShort) {
|
||||
@ -260,7 +280,7 @@ TEST_F(TApp, RequiredOptsSingleShort) {
|
||||
|
||||
args = {"-s"};
|
||||
|
||||
EXPECT_THROW(run(), CLI::RequiredError);
|
||||
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||
}
|
||||
|
||||
TEST_F(TApp, RequiredOptsDouble) {
|
||||
@ -270,7 +290,7 @@ TEST_F(TApp, RequiredOptsDouble) {
|
||||
|
||||
args = {"--str", "one"};
|
||||
|
||||
EXPECT_THROW(run(), CLI::RequiredError);
|
||||
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||
|
||||
app.reset();
|
||||
args = {"--str", "one", "two"};
|
||||
@ -287,7 +307,7 @@ TEST_F(TApp, RequiredOptsDoubleShort) {
|
||||
|
||||
args = {"-s", "one"};
|
||||
|
||||
EXPECT_THROW(run(), CLI::RequiredError);
|
||||
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||
|
||||
app.reset();
|
||||
args = {"-s", "one", "two"};
|
||||
@ -414,7 +434,17 @@ TEST_F(TApp, NotRequiedExpectedDouble) {
|
||||
|
||||
args = {"--str", "one"};
|
||||
|
||||
EXPECT_THROW(run(), CLI::RequiredError);
|
||||
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||
}
|
||||
|
||||
TEST_F(TApp, NotRequiedExpectedDoubleShort) {
|
||||
|
||||
std::vector<std::string> strs;
|
||||
app.add_option("-s", strs)->expected(2);
|
||||
|
||||
args = {"-s", "one"};
|
||||
|
||||
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||
}
|
||||
|
||||
TEST_F(TApp, EnumTest) {
|
||||
|
@ -91,5 +91,5 @@ TEST_F(TApp, BuiltinComplexFail) {
|
||||
|
||||
args = {"-c", "4"};
|
||||
|
||||
EXPECT_THROW(run(), CLI::RequiredError);
|
||||
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user