Browse Source

Util+Test: Add parsing of multi-value options

master
Riyyi 3 years ago
parent
commit
68cdd625b4
  1. 17
      src/util/argparser.cpp
  2. 1
      src/util/argparser.h
  3. 102
      test/testutilargparser.cpp

17
src/util/argparser.cpp

@ -293,4 +293,21 @@ void ArgParser::addOption(std::string& value, char shortName, const char* longNa
addOption(std::move(option));
}
void ArgParser::addOption(std::vector<std::string>& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName, Required requiresArgument)
{
Option option {
shortName,
longName,
argumentName,
usageString,
manString,
requiresArgument,
[&value](const char* a) -> bool {
value.push_back(a);
return true;
}
};
addOption(std::move(option));
}
} // namespace Util

1
src/util/argparser.h

@ -47,6 +47,7 @@ public:
void addOption(Option&& option);
void addOption(bool& value, char shortName, const char* longName, const char* usageString, const char* manString);
void addOption(std::string& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName = "", Required requiresArgument = Required::No);
void addOption(std::vector<std::string>& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName = "", Required requiresArgument = Required::No);
void setOptionIndex(int index) { m_optionIndex = index; }
void setExitOnFirstError(bool state) { m_exitOnFirstError = state; }

102
test/testutilargparser.cpp

@ -1,4 +1,5 @@
#include <string>
#include <vector>
#include "macro.h"
#include "testcase.h"
@ -299,6 +300,105 @@ TEST_CASE(SingleNonRequiredStringOptions)
// -----------------------------------------
TEST_CASE(VectorStringOptions)
{
// Required vector string short option, not given
std::vector<std::string> vectorOpt1 = {};
auto result = runParser({}, [&](auto& parser) {
parser.addOption(vectorOpt1, 'v', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
});
EXPECT_EQ(result, true);
EXPECT_EQ(vectorOpt1.size(), 0);
// Required vector string short option, empty given
vectorOpt1 = {};
result = runParser({ "-v" }, [&](auto& parser) {
parser.addOption(vectorOpt1, 'v', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
});
EXPECT_EQ(result, false);
EXPECT_EQ(vectorOpt1.size(), 0);
// Required vector string short option, one given
vectorOpt1 = {};
result = runParser({ "-v", "a vector argument!" }, [&](auto& parser) {
parser.addOption(vectorOpt1, 'v', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
});
EXPECT_EQ(result, true);
EXPECT_EQ(vectorOpt1.size(), 1);
if (vectorOpt1.size() == 1) {
EXPECT_EQ(vectorOpt1[0], "a vector argument!");
}
// Required vector string short option, two given
vectorOpt1 = {};
result = runParser({ "-v", "hello", "-v", "world" }, [&](auto& parser) {
parser.addOption(vectorOpt1, 'v', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
});
EXPECT_EQ(result, true);
EXPECT_EQ(vectorOpt1.size(), 2);
if (vectorOpt1.size() == 2) {
EXPECT_EQ(vectorOpt1[0], "hello");
EXPECT_EQ(vectorOpt1[1], "world");
}
// Required vector string short option, two given directly after
vectorOpt1 = {};
result = runParser({ "-vhello", "-vworld" }, [&](auto& parser) {
parser.addOption(vectorOpt1, 'v', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
});
EXPECT_EQ(result, true);
EXPECT_EQ(vectorOpt1.size(), 2);
if (vectorOpt1.size() == 2) {
EXPECT_EQ(vectorOpt1[0], "hello");
EXPECT_EQ(vectorOpt1[1], "world");
}
// Required vector string long option, empty given
vectorOpt1 = {};
result = runParser({ "--vector" }, [&](auto& parser) {
parser.addOption(vectorOpt1, '\0', "vector", nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
});
EXPECT_EQ(result, false);
EXPECT_EQ(vectorOpt1.size(), 0);
// Required vector string long option, one given
vectorOpt1 = {};
result = runParser({ "--vector", "a vector argument!" }, [&](auto& parser) {
parser.addOption(vectorOpt1, '\0', "vector", nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
});
EXPECT_EQ(result, true);
EXPECT_EQ(vectorOpt1.size(), 1);
if (vectorOpt1.size() == 1) {
EXPECT_EQ(vectorOpt1[0], "a vector argument!");
}
// Required vector string long option, two given
vectorOpt1 = {};
result = runParser({ "--vector", "hello", "--vector", "world" }, [&](auto& parser) {
parser.addOption(vectorOpt1, '\0', "vector", nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
});
EXPECT_EQ(result, true);
EXPECT_EQ(vectorOpt1.size(), 2);
if (vectorOpt1.size() == 2) {
EXPECT_EQ(vectorOpt1[0], "hello");
EXPECT_EQ(vectorOpt1[1], "world");
}
// Required vector string long option, two given directly after
vectorOpt1 = {};
result = runParser({ "--vector=hello", "--vector=world" }, [&](auto& parser) {
parser.addOption(vectorOpt1, '\0', "vector", nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
});
EXPECT_EQ(result, true);
EXPECT_EQ(vectorOpt1.size(), 2);
if (vectorOpt1.size() == 2) {
EXPECT_EQ(vectorOpt1[0], "hello");
EXPECT_EQ(vectorOpt1[1], "world");
}
}
// -----------------------------------------
TEST_CASE(MultipleOptions)
{
// Both short options, second is required, with a non-option argument in-between
@ -313,6 +413,8 @@ TEST_CASE(MultipleOptions)
EXPECT_EQ(stringOpt1, "a-string-value");
}
// -----------------------------------------
TEST_CASE(NonOptionMode)
{
// Bool short options, missing

Loading…
Cancel
Save