lib/cli: make flags return more accurate error codes

revealed by writing a test and it behaving differently from what I expected
BodgeMaster-unfinished
BodgeMaster 2022-07-17 12:09:19 +02:00
parent 4ceaca745b
commit 2cbf048f2e
2 changed files with 45 additions and 6 deletions

View File

@ -194,17 +194,21 @@ namespace CLI {
ErrorOr<bool> ArgumentsParser::getFlag(char shortName) { ErrorOr<bool> ArgumentsParser::getFlag(char shortName) {
if (!this->flagsByShortName.contains(shortName)) return ErrorOr<bool>(true, ErrorCodes::UNKNOWN_KEY, false); if (!this->flagsByShortName.contains(shortName)) return ErrorOr<bool>(true, ErrorCodes::UNKNOWN_KEY, false);
if (this->wrongUsage) { if (this->wrongUsage) {
return ErrorOr<bool>(true, ErrorCodes::WRONG_USAGE, this->flagsByShortName[shortName]->present); if (this->flagsByShortName[shortName]->present) return ErrorOr<bool>(true, ErrorCodes::WRONG_USAGE, true);
else return ErrorOr<bool>(true, ErrorCodes::NOT_PRESENT, false);
} }
return ErrorOr<bool>(this->flagsByShortName[shortName]->present); if (this->flagsByShortName[shortName]->present) return ErrorOr<bool>(true);
else return ErrorOr<bool>(false, ErrorCodes::NOT_PRESENT, false);
} }
ErrorOr<bool> ArgumentsParser::getFlag(std::string longName) { ErrorOr<bool> ArgumentsParser::getFlag(std::string longName) {
if (!this->flagsByLongName.contains(longName)) return ErrorOr<bool>(true, ErrorCodes::UNKNOWN_KEY, false); if (!this->flagsByLongName.contains(longName)) return ErrorOr<bool>(true, ErrorCodes::UNKNOWN_KEY, false);
if (this->wrongUsage) { if (this->wrongUsage) {
return ErrorOr<bool>(true, ErrorCodes::WRONG_USAGE, this->flagsByLongName[longName]->present); if (this->flagsByLongName[longName]->present) return ErrorOr<bool>(true, ErrorCodes::WRONG_USAGE, true);
else return ErrorOr<bool>(true, ErrorCodes::NOT_PRESENT, false);
} }
return ErrorOr<bool>(this->flagsByLongName[longName]->present); if (this->flagsByLongName[longName]->present) return ErrorOr<bool>(true);
else return ErrorOr<bool> (false, ErrorCodes::NOT_PRESENT, false);
} }
ErrorOr<std::string> ArgumentsParser::getPositionalArgument(std::vector<CLI::PositionalArgument>::size_type position){ ErrorOr<std::string> ArgumentsParser::getPositionalArgument(std::vector<CLI::PositionalArgument>::size_type position){

View File

@ -184,12 +184,47 @@ int main(int argc, char* argv[]) {
std::cout << "Passed empty input test." << std::endl; std::cout << "Passed empty input test." << std::endl;
//TODO add tests for invalid input //TODO add tests for invalid input
std::cerr << "TODO: invalid input tests" << std::endl;
// test cases for invalid input: // test cases for invalid input:
// - unknown flags, arguments (mixed with other input and standalone) // - unknown flags, arguments (mixed with other input and standalone)
// - too few, too many positional arguments (mixed with other input and standalone) // - too few, too many positional arguments (mixed with other input and standalone)
// - check the produced error messages // - check the produced error messages
std::vector<CLI::Flag> unknownFlagTestFlags;
unknownFlagTestFlags.push_back(CLI::Flag('0', "zero", "test flag"));
unknownFlagTestFlags.push_back(CLI::Flag('1', "one", "test flag"));
unknownFlagTestFlags.push_back(CLI::Flag('2', "two", "test flag"));
unknownFlagTestFlags.push_back(CLI::Flag('3', "three","test flag"));
unknownFlagTestFlags.push_back(CLI::Flag('4', "four", "test flag"));
unknownFlagTestFlags.push_back(CLI::Flag('5', "five", "test flag"));
std::vector<CLI::UnpositionalArgument> unknownFlagTestUnpositionalArguments;
std::vector<CLI::PositionalArgument> unknownFlagTestPositionalArguments;
const char** unknownFlagTestParameterList = new const char*[3];
unknownFlagTestParameterList[0] = "test";
unknownFlagTestParameterList[1] = "-a";
unknownFlagTestParameterList[2] = "-1";
unknownFlagTestParameterList[3] = "-2";
unknownFlagTestParameterList[4] = "-3";
unknownFlagTestParameterList[5] = "-4";
unknownFlagTestParameterList[6] = "-5";
int unknownFlagStandaloneTestParameterCount = 2;
CLI::ArgumentsParser unknownFlagStandaloneTestParser = CLI::ArgumentsParser(unknownFlagStandaloneTestParameterCount, unknownFlagTestParameterList, unknownFlagTestFlags, unknownFlagTestUnpositionalArguments, unknownFlagTestPositionalArguments);
ASSERT(unknownFlagStandaloneTestParser.getFlag('1').isError);
ASSERT(unknownFlagStandaloneTestParser.getFlag('1').errorCode == ErrorCodes::NOT_PRESENT);
ASSERT(!unknownFlagStandaloneTestParser.getFlag('1').value);
int unknownFlagMixedTestParameterCount = 7;
CLI::ArgumentsParser unknownFlagMixedTestParser = CLI::ArgumentsParser(unknownFlagMixedTestParameterCount, unknownFlagTestParameterList, unknownFlagTestFlags, unknownFlagTestUnpositionalArguments, unknownFlagTestPositionalArguments);
ASSERT(unknownFlagMixedTestParser.getFlag('1').isError);
ASSERT(unknownFlagMixedTestParser.getFlag('1').errorCode == ErrorCodes::WRONG_USAGE);
ASSERT(unknownFlagMixedTestParser.getFlag('1').value);
delete[] unknownFlagTestParameterList;
std::cout << "Passed unknown flag test." << std::endl;
return 0; return 0;
} }