Precommit (#1)

* first commit

* cleanup
This commit is contained in:
tompzf
2025-11-04 13:28:06 +01:00
committed by GitHub
parent dba45dc636
commit 6ed4b1534e
898 changed files with 256340 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
# Define project
project (UnitTest_CommandLine_Parser VERSION 1.0 LANGUAGES CXX)
if (WIN32)
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
add_compile_options(/bigobj)
else()
add_compile_options(-Wa,-mbig-obj)
endif()
endif()
# Compile the source code
add_executable(UnitTest_CommandLine_Parser
"commandline_parser_test.cpp"
"commandline_parser_test.h"
"defaultarg_parser_test.cpp"
"option_parser_test.cpp"
"suboption_parser_test.cpp"
"windows_option_parser_test.cpp"
"main.cpp"
"option_parser_test_no_assignment_char.cpp"
"suboption_parser_test_no_assignment_char.cpp"
"option_parser_test_assignment_next_arg.cpp"
"suboption_parser_test_assignment_next_arg.cpp"
"option_argument_selective_group.cpp"
"suboption_argument_selective_group.cpp"
"incompatible_arguments.cpp")
target_link_libraries(UnitTest_CommandLine_Parser ${CMAKE_DL_LIBS} GTest::GTest)
# Add the IDL Compiler unittest
add_test(NAME UnitTest_CommandLine_Parser COMMAND UnitTest_CommandLine_Parser)
# Execute the test
add_custom_command(TARGET UnitTest_CommandLine_Parser POST_BUILD
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_CommandLine_Parser>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_CommandLine_Parser.xml
VERBATIM
)
# The unit-test project depends on a proper compilation of the compiler before
add_dependencies(UnitTest_CommandLine_Parser dependency_sdv_components)

View File

@@ -0,0 +1,250 @@
#include "../../include/gtest_custom.h"
#include "commandline_parser_test.h"
#include "../../../global/cmdlnparser/cmdlnparser.cpp"
void CCommandLineParserTest::SetUpTestCase()
{}
void CCommandLineParserTest::TearDownTestCase()
{}
void CCommandLineParserTest::SetUp()
{}
void CCommandLineParserTest::TearDown()
{}
TEST_F(CCommandLineParserTest, Instantiation)
{
const char* rgszCommandLine[] = {"this_exe.app"};
CCommandLine cl;
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
}
TEST_F(CCommandLineParserTest, NoOptionAssignment)
{
const char* rgszCommandLine[] = {"this_exe.app"};
CCommandLine cl;
size_t nVar1 = 0; cl.DefineOption("nvar1", nVar1, "first variable");
size_t nVar2 = 0; cl.DefineOption("nvar2", nVar2, "second variable");
bool bFlag = false; cl.DefineOption("flag", bFlag, "flag variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(nVar1, 0);
EXPECT_EQ(nVar2, 0);
EXPECT_FALSE(bFlag);
}
TEST_F(CCommandLineParserTest, NoSubOptionAssignment)
{
const char* rgszCommandLine[] = {"this_exe.app"};
CCommandLine cl;
size_t nVar1 = 0; cl.DefineSubOption("nvar1", nVar1, "first variable");
size_t nVar2 = 0; cl.DefineSubOption("nvar2", nVar2, "second variable");
bool bFlag = false; cl.DefineSubOption("flag", bFlag, "flag variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(nVar1, 0);
EXPECT_EQ(nVar2, 0);
EXPECT_FALSE(bFlag);
}
TEST_F(CCommandLineParserTest, OptionAssignment)
{
const char* rgszCommandLine[] = {"this_exe.app", "-nvar1=1", "-nvar2:2", "-flag"};
CCommandLine cl;
size_t nVar1 = 0; cl.DefineOption("nvar1", nVar1, "first variable");
size_t nVar2 = 0; cl.DefineOption("nvar2", nVar2, "second variable");
bool bFlag = false; cl.DefineOption("flag", bFlag, "flag variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(nVar1, 1);
EXPECT_EQ(nVar2, 2);
EXPECT_TRUE(bFlag);
}
TEST_F(CCommandLineParserTest, SubOptionAssignment)
{
const char* rgszCommandLine[] = {"this_exe.app", "--nvar1=1", "--nvar2:2", "--flag"};
CCommandLine cl;
size_t nVar1 = 0; cl.DefineSubOption("nvar1", nVar1, "first variable");
size_t nVar2 = 0; cl.DefineSubOption("nvar2", nVar2, "second variable");
bool bFlag = false; cl.DefineSubOption("flag", bFlag, "flag variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(nVar1, 1);
EXPECT_EQ(nVar2, 2);
EXPECT_TRUE(bFlag);
}
TEST_F(CCommandLineParserTest, OptionEmptyAssignment)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1=", "-ssvar2=\"\"", "-nvar3="};
CCommandLine cl;
std::string ssVar1; cl.DefineOption("ssvar1", ssVar1, "first variable");
std::string ssVar2; cl.DefineOption("ssvar2", ssVar2, "second variable");
size_t nVar3 = 0; cl.DefineOption("nvar3", nVar3, "third variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(ssVar1.empty());
EXPECT_TRUE(ssVar2.empty());
EXPECT_EQ(nVar3, 0u);
}
TEST_F(CCommandLineParserTest, SubOptionEmptyAssignment)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1=", "--ssvar2=\"\"", "--nvar3="};
CCommandLine cl;
std::string ssVar1; cl.DefineSubOption("ssvar1", ssVar1, "first variable");
std::string ssVar2; cl.DefineSubOption("ssvar2", ssVar2, "second variable");
size_t nVar3 = 0; cl.DefineSubOption("nvar3", nVar3, "third variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(ssVar1.empty());
EXPECT_TRUE(ssVar2.empty());
EXPECT_EQ(nVar3, 0u);
}
TEST_F(CCommandLineParserTest, InvalidArgOption)
{
const char* rgszCommandLine[] = {"this_exe.app", "-invalid"};
CCommandLine cl;
EXPECT_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine), SArgumentParseException);
}
TEST_F(CCommandLineParserTest, InvalidArgSubOption)
{
const char* rgszCommandLine[] = {"this_exe.app", "--invalid"};
CCommandLine cl;
EXPECT_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine), SArgumentParseException);
}
TEST_F(CCommandLineParserTest, InvalidDefaultArg)
{
const char* rgszCommandLine[] = {"this_exe.app", "invalid"};
CCommandLine cl;
EXPECT_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine), SArgumentParseException);
}
TEST_F(CCommandLineParserTest, InvalidArgTypeOption)
{
const char* rgszCommandLine[] = {"this_exe.app", "-val=abc"};
CCommandLine cl;
size_t nVar = 0; cl.DefineOption("val", nVar, "variable");
EXPECT_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine), SArgumentParseException);
}
TEST_F(CCommandLineParserTest, InvalidArgTypeSubOption)
{
const char* rgszCommandLine[] = {"this_exe.app", "--val=abc"};
CCommandLine cl;
size_t nVar = 0; cl.DefineSubOption("val", nVar, "variable");
EXPECT_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine), SArgumentParseException);
}
TEST_F(CCommandLineParserTest, InvalidDefaultArgType)
{
const char* rgszCommandLine[] = {"this_exe.app", "abc"};
CCommandLine cl;
size_t nVar = 0; cl.DefineDefaultArgument(nVar, "variable");
EXPECT_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine), SArgumentParseException);
}
TEST_F(CCommandLineParserTest, MixedArguments)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1=abc", "--ssvar2=def", "ghi"};
CCommandLine cl;
std::string ssVar1; cl.DefineOption("ssvar1", ssVar1, "first variable");
std::string ssVar2; cl.DefineSubOption("ssvar2", ssVar2, "second variable");
std::string ssVar3; cl.DefineDefaultArgument(ssVar3, "third variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(ssVar1, "abc");
EXPECT_EQ(ssVar2, "def");
EXPECT_EQ(ssVar3, "ghi");
}
TEST_F(CCommandLineParserTest, MixedOptionArgumentsReuse)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar=abc", "--ssvar=def"};
CCommandLine cl;
std::string ssVar1; cl.DefineOption("ssvar", ssVar1, "first variable");
std::string ssVar2; cl.DefineSubOption("ssvar", ssVar2, "second variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(ssVar1, "abc");
EXPECT_EQ(ssVar2, "def");
}
TEST_F(CCommandLineParserTest, MixedOptionArgumentsNoAssignmentChar)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvarabc", "-nvar1234"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::string ssVar; cl.DefineOption("ssvar", ssVar, "first variable");
size_t nVar = 0; cl.DefineOption("nvar", nVar, "second variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(ssVar, "abc");
EXPECT_EQ(nVar, 1234);
}
TEST_F(CCommandLineParserTest, MultipleDefaultArgs)
{
const char* rgszCommandLine[] = {"this_exe.app", "arg1", "arg2", "arg3"};
CCommandLine cl;
std::vector<std::string> vecDefault; cl.DefineDefaultArgument(vecDefault, "default argument");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
ASSERT_EQ(vecDefault.size(), 3);
EXPECT_EQ(vecDefault[0], "arg1");
EXPECT_EQ(vecDefault[1], "arg2");
EXPECT_EQ(vecDefault[2], "arg3");
}
TEST_F(CCommandLineParserTest, MultipleOptionArgs)
{
const char* rgszCommandLine[] = {"this_exe.app", "-opt=arg1", "-opt=arg2", "-opt=arg3"};
CCommandLine cl;
std::vector<std::string> vecOption; cl.DefineOption("opt", vecOption, "default argument");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
ASSERT_EQ(vecOption.size(), 3);
EXPECT_EQ(vecOption[0], "arg1");
EXPECT_EQ(vecOption[1], "arg2");
EXPECT_EQ(vecOption[2], "arg3");
}
TEST_F(CCommandLineParserTest, MultipleOptionArgsNoAssignmentChar)
{
const char* rgszCommandLine[] = {"this_exe.app", "-optarg1", "-optarg2", "-optarg3"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::vector<std::string> vecOption; cl.DefineOption("opt", vecOption, "default argument");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
ASSERT_EQ(vecOption.size(), 3);
EXPECT_EQ(vecOption[0], "arg1");
EXPECT_EQ(vecOption[1], "arg2");
EXPECT_EQ(vecOption[2], "arg3");
}
TEST_F(CCommandLineParserTest, MultipleSubOptionArgs)
{
const char* rgszCommandLine[] = {"this_exe.app", "--opt=arg1", "--opt=arg2", "--opt=arg3"};
CCommandLine cl;
std::vector<std::string> vecOption; cl.DefineSubOption("opt", vecOption, "default argument");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
ASSERT_EQ(vecOption.size(), 3);
EXPECT_EQ(vecOption[0], "arg1");
EXPECT_EQ(vecOption[1], "arg2");
EXPECT_EQ(vecOption[2], "arg3");
}
TEST_F(CCommandLineParserTest, MultipleSubOptionArgsNoAssignmentChar)
{
const char* rgszCommandLine[] = {"this_exe.app", "--optarg1", "--optarg2", "--optarg3"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::vector<std::string> vecOption; cl.DefineSubOption("opt", vecOption, "default argument");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
ASSERT_EQ(vecOption.size(), 3);
EXPECT_EQ(vecOption[0], "arg1");
EXPECT_EQ(vecOption[1], "arg2");
EXPECT_EQ(vecOption[2], "arg3");
}
// Add exceptions (invalid command line args, arg assignments out of scope or too large/small)
// - Wrong default arguments
// - Multiple default arguments, but only one var
// - Wrong option/sub-option
// - Same name for option/sub-option
// - Assignment with semi-colon and assignment character
// - Case sensitivity
// - Multiple assignments with same option adding to vector or list

View File

@@ -0,0 +1,39 @@
#ifndef COMMANDLINE_PARSER_TEST_H
#define COMMANDLINE_PARSER_TEST_H
#include <support/mem_access.h>
#include <support/interface_ptr.h>
/**
* \brief Test class for instantiation tests.
*/
class CCommandLineParserTest : public testing::Test
{
public:
/**
* \brief Constructor
*/
CCommandLineParserTest() = default;
/**
* \brief Set up the test suite.
*/
static void SetUpTestCase();
/**
* \brief Tear down the test suite.
*/
static void TearDownTestCase();
/**
* \brief Test setup.
*/
void SetUp() override;
/**
* \brief Test teardown.
*/
void TearDown() override;
};
#endif // !defined COMMANDLINE_PARSER_TEST_H

View File

@@ -0,0 +1,408 @@
#include "../../include/gtest_custom.h"
#include "commandline_parser_test.h"
#include "../../../global/cmdlnparser/cmdlnparser.h"
TEST_F(CCommandLineParserTest, DefaultArgParseIntegralIndependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "--i8var=-1", "--i16var=-2", "--i32var=-3", "--i64var=-4",
"--ui8var=5", "--ui16var=6", "7", "--ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineSubOption("i8var", i8Var, "int8_t variable");
int16_t i16Var = 0; cl.DefineSubOption("i16var", i16Var, "int16_t variable");
int32_t i32Var = 0; cl.DefineSubOption("i32var", i32Var, "int32_t variable");
int64_t i64Var = 0; cl.DefineSubOption("i64var", i64Var, "int64_t variable");
uint8_t ui8Var = 0; cl.DefineSubOption("ui8var", ui8Var, "uint8_t variable");
uint16_t ui16Var = 0; cl.DefineSubOption("ui16var", ui16Var, "uint16_t variable");
uint32_t ui32Var = 0; cl.DefineDefaultArgument(ui32Var, "uint32_t variable");
uint64_t ui64Var = 0; cl.DefineSubOption("ui64var", ui64Var, "uint64_t variable");
int8_t i8Control = -10; cl.DefineSubOption("i8control", i8Control, "int8_t no change!");
int16_t i16Control = -20; cl.DefineSubOption("i16control", i16Control, "int16_t no change!");
int32_t i32Control = -30; cl.DefineSubOption("i32control", i32Control, "int32_t no change!");
int64_t i64Control = -40; cl.DefineSubOption("i64control", i64Control, "int64_t no change!");
uint8_t ui8Control = 50; cl.DefineSubOption("ui8control", ui8Control, "uint8_t no change!");
uint16_t ui16Control = 60; cl.DefineSubOption("ui16control", ui16Control, "uint16_t no change!");
uint32_t ui32Control = 70; cl.DefineSubOption("ui32control", ui32Control, "uint32_t no change!");
uint64_t ui64Control = 80; cl.DefineSubOption("ui64control", ui64Control, "uint64_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(i8Var, -1);
EXPECT_EQ(i16Var, -2);
EXPECT_EQ(i32Var, -3);
EXPECT_EQ(i64Var, -4);
EXPECT_EQ(ui8Var, 5u);
EXPECT_EQ(ui16Var, 6u);
EXPECT_EQ(ui32Var, 7u);
EXPECT_EQ(ui64Var, 8u);
EXPECT_EQ(i8Control, -10);
EXPECT_EQ(i16Control, -20);
EXPECT_EQ(i32Control, -30);
EXPECT_EQ(i64Control, -40);
EXPECT_EQ(ui8Control, 50u);
EXPECT_EQ(ui16Control, 60u);
EXPECT_EQ(ui32Control, 70u);
EXPECT_EQ(ui64Control, 80u);
}
TEST_F(CCommandLineParserTest, DefaultArgParseIntegralDedependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar=-1", "--svar=-2", "--lvar=-3", "--ivar=-4", "--llvar=-5",
"--ucvar=6", "--usvar=7", "8", "--uivar=9", "--ullvar=10", "--nvar=11"};
CCommandLine cl;
signed char cVar = 0; cl.DefineSubOption("cvar", cVar, "char variable");
short sVar = 0; cl.DefineSubOption("svar", sVar, "short variable");
long lVar = 0; cl.DefineSubOption("lvar", lVar, "long variable");
int iVar = 0; cl.DefineSubOption("ivar", iVar, "int variable");
long long llVar = 0; cl.DefineSubOption("llvar", llVar, "long long variable");
unsigned char ucVar = 0; cl.DefineSubOption("ucvar", ucVar, "unsigned char variable");
unsigned short usVar = 0; cl.DefineSubOption("usvar", usVar, "unsigned short variable");
unsigned long ulVar = 0; cl.DefineDefaultArgument(ulVar, "unsigned long variable");
unsigned int uiVar = 0; cl.DefineSubOption("uivar", uiVar, "unsigned int variable");
unsigned long long ullVar = 0; cl.DefineSubOption("ullvar", ullVar, "unsigned long long variable");
size_t nVar = 0; cl.DefineSubOption("nvar", nVar, "size_t variable");
signed char cControl = -10; cl.DefineSubOption("ccontrol", cControl, "char no change!");
short sControl = -20; cl.DefineSubOption("scontrol", sControl, "short no change!");
long lControl = -30; cl.DefineSubOption("lcontrol", lControl, "long no change!");
int iControl = -40; cl.DefineSubOption("icontrol", iControl, "int no change!");
long long llControl = -50; cl.DefineSubOption("llcontrol", llControl, "long long no change!");
unsigned char ucControl = 60; cl.DefineSubOption("uccontrol", ucControl, "unsigned char no change!");
unsigned short usControl = 70; cl.DefineSubOption("uscontrol", usControl, "unsigned short no change!");
unsigned long ulControl = 80; cl.DefineSubOption("ulcontrol", ulControl, "unsigned long no change!");
unsigned int uiControl = 90; cl.DefineSubOption("uicontrol", uiControl, "unsigned int no change!");
unsigned long long ullControl = 100; cl.DefineSubOption("ullcontrol", ullControl, "unsigned long long no change!");
size_t nControl = 110; cl.DefineSubOption("ncontrol", nControl, "size_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(cVar, -1);
EXPECT_EQ(sVar, -2);
EXPECT_EQ(lVar, -3);
EXPECT_EQ(iVar, -4);
EXPECT_EQ(llVar, -5);
EXPECT_EQ(ucVar, 6u);
EXPECT_EQ(usVar, 7u);
EXPECT_EQ(ulVar, 8u);
EXPECT_EQ(uiVar, 9u);
EXPECT_EQ(ullVar, 10u);
EXPECT_EQ(nVar, 11u);
EXPECT_EQ(cControl, -10);
EXPECT_EQ(sControl, -20);
EXPECT_EQ(lControl, -30);
EXPECT_EQ(iControl, -40);
EXPECT_EQ(llControl, -50);
EXPECT_EQ(ucControl, 60u);
EXPECT_EQ(usControl, 70u);
EXPECT_EQ(ulControl, 80u);
EXPECT_EQ(uiControl, 90u);
EXPECT_EQ(ullControl, 100u);
EXPECT_EQ(nControl, 110u);
}
TEST_F(CCommandLineParserTest, DefaultArgParseIntegralIndependentVector)
{
// Attention: std::vector<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"--i8var=-1,2, -3",*/ "--i16var=-2,3,-4", "--i32var=-3,4,-5", "--i64var=-4,5,-6",
"--ui8var=5,6,7", "--ui16var=6,7,8", "7", "8", "9", "--ui64var=8,9,10"};
CCommandLine cl;
//std::vector<int8_t> veci8Var; cl.DefineSubOption("i8var", veci8Var, "vector of int8_t variable");
std::vector<int16_t> veci16Var; cl.DefineSubOption("i16var", veci16Var, "vector of int16_t variable");
std::vector<int32_t> veci32Var; cl.DefineSubOption("i32var", veci32Var, "vector of int32_t variable");
std::vector<int64_t> veci64Var; cl.DefineSubOption("i64var", veci64Var, "vector of int64_t variable");
std::vector<uint8_t> vecui8Var; cl.DefineSubOption("ui8var", vecui8Var, "vector of uint8_t variable");
std::vector<uint16_t> vecui16Var; cl.DefineSubOption("ui16var", vecui16Var, "vector of uint16_t variable");
std::vector<uint32_t> vecui32Var; cl.DefineDefaultArgument(vecui32Var, "vector of uint32_t variable");
std::vector<uint64_t> vecui64Var; cl.DefineSubOption("ui64var", vecui64Var, "vector of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(veci8Var, -1, 2, -3);
EXPECT_ARREQ(veci16Var, -2, 3, -4);
EXPECT_ARREQ(veci32Var, -3, 4, -5);
EXPECT_ARREQ(veci64Var, -4, 5, -6);
EXPECT_ARREQ(vecui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(vecui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(vecui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(vecui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTest, DefaultArgParseIntegralDedependentVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar=-1,2,-3", "--svar=-2,3,-4", "--lvar=-3,4,-5", "--ivar=-4,5,-6", "--llvar=-5,6,-7",
"--ucvar=6,7,8", "--usvar=7,8,9", "8", "9", "10", "--uivar=9,10,11", "--ullvar=10,11,12", "--nvar=11,12,13"};
CCommandLine cl;
std::vector<signed char> veccVar; cl.DefineSubOption("cvar", veccVar, "vector of char variable");
std::vector<short> vecsVar; cl.DefineSubOption("svar", vecsVar, "vector of short variable");
std::vector<long> veclVar; cl.DefineSubOption("lvar", veclVar, "vector of long variable");
std::vector<int> veciVar; cl.DefineSubOption("ivar", veciVar, "vector of int variable");
std::vector<long long> vecllVar; cl.DefineSubOption("llvar", vecllVar, "vector of long long variable");
std::vector<unsigned char> vecucVar; cl.DefineSubOption("ucvar", vecucVar, "vector of unsigned char variable");
std::vector<unsigned short> vecusVar; cl.DefineSubOption("usvar", vecusVar, "vector of unsigned short variable");
std::vector<unsigned long> veculVar; cl.DefineDefaultArgument(veculVar, "vector of unsigned long variable");
std::vector<unsigned int> vecuiVar; cl.DefineSubOption("uivar", vecuiVar, "vector of unsigned int variable");
std::vector<unsigned long long> vecullVar; cl.DefineSubOption("ullvar", vecullVar, "vector of unsigned long long variable");
std::vector<size_t> vecnVar; cl.DefineSubOption("nvar", vecnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(veccVar, -1, 2, -3);
EXPECT_ARREQ(vecsVar, -2, 3, -4);
EXPECT_ARREQ(veclVar, -3, 4, -5);
EXPECT_ARREQ(veciVar, -4, 5, -6);
EXPECT_ARREQ(vecllVar, -5, 6, -7);
EXPECT_ARREQ(vecucVar, 6u, 7u, 8u);
EXPECT_ARREQ(vecusVar, 7u, 8u, 9u);
EXPECT_ARREQ(veculVar, 8u, 9u, 10u);
EXPECT_ARREQ(vecuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(vecullVar, 10u, 11u, 12u);
EXPECT_ARREQ(vecnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTest, DefaultArgParseIntegralIndependentList)
{
// Attention: std::list<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"--i8var=-1,2, -3",*/ "--i16var=-2,3,-4", "--i32var=-3,4,-5", "--i64var=-4,5,-6",
"--ui8var=5,6,7", "--ui16var=6,7,8", "7", "8", "9", "--ui64var=8,9,10"};
CCommandLine cl;
//std::list<int8_t> lsti8Var; cl.DefineSubOption("i8var", lsti8Var, "list of int8_t variable");
std::list<int16_t> lsti16Var; cl.DefineSubOption("i16var", lsti16Var, "list of int16_t variable");
std::list<int32_t> lsti32Var; cl.DefineSubOption("i32var", lsti32Var, "list of int32_t variable");
std::list<int64_t> lsti64Var; cl.DefineSubOption("i64var", lsti64Var, "list of int64_t variable");
std::list<uint8_t> lstui8Var; cl.DefineSubOption("ui8var", lstui8Var, "list of uint8_t variable");
std::list<uint16_t> lstui16Var; cl.DefineSubOption("ui16var", lstui16Var, "list of uint16_t variable");
std::list<uint32_t> lstui32Var; cl.DefineDefaultArgument(lstui32Var, "list of uint32_t variable");
std::list<uint64_t> lstui64Var; cl.DefineSubOption("ui64var", lstui64Var, "list of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(lsti8Var, -1, 2, -3);
EXPECT_ARREQ(lsti16Var, -2, 3, -4);
EXPECT_ARREQ(lsti32Var, -3, 4, -5);
EXPECT_ARREQ(lsti64Var, -4, 5, -6);
EXPECT_ARREQ(lstui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(lstui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(lstui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(lstui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTest, DefaultArgParseIntegralDedependentList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar=-1,2,-3", "--svar=-2,3,-4", "--lvar=-3,4,-5", "--ivar=-4,5,-6", "--llvar=-5,6,-7",
"--ucvar=6,7,8", "--usvar=7,8,9", "8", "9", "10", "--uivar=9,10,11", "--ullvar=10,11,12", "--nvar=11,12,13"};
CCommandLine cl;
std::list<signed char> lstcVar; cl.DefineSubOption("cvar", lstcVar, "list of char variable");
std::list<short> lstsVar; cl.DefineSubOption("svar", lstsVar, "list of short variable");
std::list<long> lstlVar; cl.DefineSubOption("lvar", lstlVar, "list of long variable");
std::list<int> lstiVar; cl.DefineSubOption("ivar", lstiVar, "list of int variable");
std::list<long long> lstllVar; cl.DefineSubOption("llvar", lstllVar, "list of long long variable");
std::list<unsigned char> lstucVar; cl.DefineSubOption("ucvar", lstucVar, "list of unsigned char variable");
std::list<unsigned short> lstusVar; cl.DefineSubOption("usvar", lstusVar, "list of unsigned short variable");
std::list<unsigned long> lstulVar; cl.DefineDefaultArgument(lstulVar, "list of unsigned long variable");
std::list<unsigned int> lstuiVar; cl.DefineSubOption("uivar", lstuiVar, "list of unsigned int variable");
std::list<unsigned long long> lstullVar; cl.DefineSubOption("ullvar", lstullVar, "list of unsigned long long variable");
std::list<size_t> lstnVar; cl.DefineSubOption("nvar", lstnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstcVar, -1, 2, -3);
EXPECT_ARREQ(lstsVar, -2, 3, -4);
EXPECT_ARREQ(lstlVar, -3, 4, -5);
EXPECT_ARREQ(lstiVar, -4, 5, -6);
EXPECT_ARREQ(lstllVar, -5, 6, -7);
EXPECT_ARREQ(lstucVar, 6u, 7u, 8u);
EXPECT_ARREQ(lstusVar, 7u, 8u, 9u);
EXPECT_ARREQ(lstulVar, 8u, 9u, 10u);
EXPECT_ARREQ(lstuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(lstullVar, 10u, 11u, 12u);
EXPECT_ARREQ(lstnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTest, DefaultArgParseFloatingPoint)
{
const char* rgszCommandLine[] = {"this_exe.app", "12345.6789", "--dvar=12345678.9E10", "--ldvar=0.12345678E-5"};
CCommandLine cl;
float fVar = 0; cl.DefineDefaultArgument(fVar, "float variable");
double dVar = 0; cl.DefineSubOption("dvar", dVar, "double variable");
long double ldVar = 0; cl.DefineSubOption("ldvar", ldVar, "long double variable");
float fControl = 123.456f; cl.DefineSubOption("fcontrol", fControl, "float no change!");
double dControl = 456.789; cl.DefineSubOption("dcontrol", dControl, "double no change!");
long double ldControl = 876.543; cl.DefineSubOption("ldcontrol", ldControl, "long double no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_FPEQ(fVar, 12345.6789f);
EXPECT_FPEQ(dVar, 12345678.9E10);
#ifndef __GNUC__ // Long double is not well supported by G++ compiler
EXPECT_FPEQ(ldVar, 0.12345678E-5);
#endif
EXPECT_FPEQ(fControl, 123.456f);
EXPECT_FPEQ(dControl, 456.789);
EXPECT_FPEQ(ldControl, 876.543);
}
TEST_F(CCommandLineParserTest, DefaultArgParseFloatingPointVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "12345.6789", "9876.54321", "134679", "--dvar=12345678.9E10,1098765.43E21", "--ldvar=0.12345678E-5,0.87654321E9"};
CCommandLine cl;
std::vector<float> vecfVar; cl.DefineDefaultArgument(vecfVar, "vector of float variable");
std::vector<double> vecdVar; cl.DefineSubOption("dvar", vecdVar, "vector of double variable");
std::vector<long double> vecldVar; cl.DefineSubOption("ldvar", vecldVar, "vector of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecfVar, 12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(vecdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(vecldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTest, DefaultArgParseFloatingPointList)
{
const char* rgszCommandLine[] = {"this_exe.app", "12345.6789", "9876.54321", "134679", "--dvar=12345678.9E10,1098765.43E21", "--ldvar=0.12345678E-5,0.87654321E9"};
CCommandLine cl;
std::list<float> lstfVar; cl.DefineDefaultArgument(lstfVar, "list of float variable");
std::list<double> lstdVar; cl.DefineSubOption("dvar", lstdVar, "list of double variable");
std::list<long double> lstldVar; cl.DefineSubOption("ldvar", lstldVar, "list of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstfVar, 12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(lstdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(lstldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTest, DefaultArgParseEnum)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "test2", "--scoped_enum=test5"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
EUnscopedTest eUnscopedTest = test1; cl.DefineDefaultArgument(eUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedTest = EScopedTest::test4; cl.DefineSubOption("scoped_enum", eScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EUnscopedTest eUnscopedControl = test1; cl.DefineSubOption("unscoped_enum_control", eUnscopedControl, "unscoped enum no change!").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedControl = EScopedTest::test4; cl.DefineSubOption("scoped_enum_control", eScopedControl, "scoped enum no change!").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(eUnscopedTest, test2);
EXPECT_EQ(eScopedTest, EScopedTest::test5);
EXPECT_EQ(eUnscopedControl, test1);
EXPECT_EQ(eScopedControl, EScopedTest::test4);
}
TEST_F(CCommandLineParserTest, DefaultArgParseEnumVector)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "test2" ,"test3", "--scoped_enum=test5,test6"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::vector<EUnscopedTest> vecUnscopedTest; cl.DefineDefaultArgument(vecUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::vector<EScopedTest> vecScopedTest; cl.DefineSubOption("scoped_enum", vecScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecUnscopedTest, test2, test3);
EXPECT_ARREQ(vecScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTest, DefaultArgParseEnumList)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "test2", "test3", "--scoped_enum=test5,test6"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::list<EUnscopedTest> lstUnscopedTest; cl.DefineDefaultArgument(lstUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::list<EScopedTest> lstScopedTest; cl.DefineSubOption("scoped_enum", lstScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstUnscopedTest, test2, test3);
EXPECT_ARREQ(lstScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTest, DefaultArgParseString)
{
const char* rgszCommandLine[] = {"this_exe.app", "test_a", "--ssu8var1=test_b", "--ssvar2=\"test_c\"",
"--ssu8var2=\"test_d\""};
CCommandLine cl;
std::string ssVar1; cl.DefineDefaultArgument(ssVar1, "std::string variable");
sdv::u8string ssu8Var1; cl.DefineSubOption("ssu8var1", ssu8Var1, "sdv::u8string variable");
std::string ssVar2; cl.DefineSubOption("ssvar2", ssVar2, "sdv::string variable");
sdv::u8string ssu8Var2; cl.DefineSubOption("ssu8var2", ssu8Var2, "sdv::u8string variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(ssVar1, "test_a");
EXPECT_EQ(ssu8Var1, "test_b");
EXPECT_EQ(ssVar2, "test_c");
EXPECT_EQ(ssu8Var2, "test_d");
}
TEST_F(CCommandLineParserTest, DefaultArgParseStringVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "test_a", "test_b", "--ssu8var1=test_b,test_c", "--ssvar2=\"test_c\",\"test_d\"",
"--ssu8var2=\"test_d\",\"test_e\""};
CCommandLine cl;
std::vector<std::string> vecssVar1; cl.DefineDefaultArgument(vecssVar1, "std::vector<std::string> variable");
std::vector<sdv::u8string> vecssu8Var1; cl.DefineSubOption("ssu8var1", vecssu8Var1, "std::vector<sdv::u8string> variable");
std::vector<std::string> vecssVar2; cl.DefineSubOption("ssvar2", vecssVar2, "std::vector<sdv::string> variable");
std::vector<sdv::u8string> vecssu8Var2; cl.DefineSubOption("ssu8var2", vecssu8Var2, "std::vector<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecssVar1, "test_a", "test_b");
EXPECT_ARREQ(vecssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(vecssVar2, "test_c", "test_d");
EXPECT_ARREQ(vecssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTest, DefaultArgParseStringList)
{
const char* rgszCommandLine[] = {"this_exe.app", "test_a", "test_b", "--ssu8var1=test_b,test_c", "--ssvar2=\"test_c\",\"test_d\"",
"--ssu8var2=\"test_d\",\"test_e\""};
CCommandLine cl;
std::list<std::string> lstssVar1; cl.DefineDefaultArgument(lstssVar1, "std::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var1; cl.DefineSubOption("ssu8var1", lstssu8Var1, "std::list<sdv::u8string> variable");
std::list<std::string> lstssVar2; cl.DefineSubOption("ssvar2", lstssVar2, "std::vector<sdv::list> variable");
std::list<sdv::u8string> lstssu8Var2; cl.DefineSubOption("ssu8var2", lstssu8Var2, "std::vector<sdv::list> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstssVar1, "test_a", "test_b");
EXPECT_ARREQ(lstssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(lstssVar2, "test_c", "test_d");
EXPECT_ARREQ(lstssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTest, DefaultArgParsePath)
{
const char* rgszCommandLine[] = {"this_exe.app", "abc.def", "--pathvar2=\"ghi.jkl\""};
CCommandLine cl;
std::filesystem::path pathVar1; cl.DefineDefaultArgument(pathVar1, "std::filesystem::path variable");
std::filesystem::path pathVar2; cl.DefineSubOption("pathvar2", pathVar2, "std::filesystem::path variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(pathVar1, "abc.def");
EXPECT_EQ(pathVar2, "ghi.jkl");
}
TEST_F(CCommandLineParserTest, DefaultArgParsePathVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "abc.def", "ghi.jkl", "--pathvar2=\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl;
std::vector<std::filesystem::path> vecpathVar1; cl.DefineDefaultArgument(vecpathVar1, "std::vector<std::filesystem::path> variable");
std::vector<std::filesystem::path> vecpathVar2; cl.DefineSubOption("pathvar2", vecpathVar2, "std::vector<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(vecpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTest, DefaultArgParsePathList)
{
const char* rgszCommandLine[] = {"this_exe.app", "abc.def", "ghi.jkl", "--pathvar2=\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl;
std::list<std::filesystem::path> lstpathVar1; cl.DefineDefaultArgument(lstpathVar1, "std::list<std::filesystem::path> variable");
std::list<std::filesystem::path> lstpathVar2; cl.DefineSubOption("pathvar2", lstpathVar2, "std::list<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(lstpathVar2, "ghi.jkl", "mno.pqr");
}

View File

@@ -0,0 +1,624 @@
#include "../../include/gtest_custom.h"
#include "commandline_parser_test.h"
#include "../../../global/cmdlnparser/cmdlnparser.h"
using CCommandLineParserTestIncompatibleArguments = CCommandLineParserTest;
TEST_F(CCommandLineParserTestIncompatibleArguments, OptionParseCaseSensitiveFullArgument)
{
const char* rgszCommandLine[] = {"this_exe.app", "-i8var=-1", "-i16var=-2", "-i32var=-3", "-i64var=-4",
"-ui8var=5", "-ui16var=6", "-ui32var=7", "-ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineOption("i8var", i8Var, "int8_t variable", true, 0, 1);
int16_t i16Var = 0; cl.DefineOption("i16var", i16Var, "int16_t variable", true, 1, 2);
int32_t i32Var = 0; cl.DefineOption("i32var", i32Var, "int32_t variable", true, 2, 3);
int64_t i64Var = 0; cl.DefineOption("i64var", i64Var, "int64_t variable", true, 3, 4);
uint8_t ui8Var = 0; cl.DefineOption("ui8var", ui8Var, "uint8_t variable", true, 4, 5);
uint16_t ui16Var = 0; cl.DefineOption("ui16var", ui16Var, "uint16_t variable", true, 5, 6);
uint32_t ui32Var = 0; cl.DefineOption("ui32var", ui32Var, "uint32_t variable", true, 6, 7);
uint64_t ui64Var = 0; cl.DefineOption("ui64var", ui64Var, "uint64_t variable", true, 7, 8);
int8_t i8Control = -10; cl.DefineOption("i8control", i8Control, "int8_t no change!", true, 0, 1);
int16_t i16Control = -20; cl.DefineOption("i16control", i16Control, "int16_t no change!", true, 1, 2);
int32_t i32Control = -30; cl.DefineOption("i32control", i32Control, "int32_t no change!", true, 2, 3);
int64_t i64Control = -40; cl.DefineOption("i64control", i64Control, "int64_t no change!", true, 3, 4);
uint8_t ui8Control = 50; cl.DefineOption("ui8control", ui8Control, "uint8_t no change!", true, 4, 5);
uint16_t ui16Control = 60; cl.DefineOption("ui16control", ui16Control, "uint16_t no change!", true, 5, 6);
uint32_t ui32Control = 70; cl.DefineOption("ui32control", ui32Control, "uint32_t no change!", true, 6, 7);
uint64_t ui64Control = 80; cl.DefineOption("ui64control", ui64Control, "uint64_t no change!", true, 7, 8);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0)[0], "-i16var=-2"); // Full argument
EXPECT_EQ(cl.IncompatibleArguments(1).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9).size(), 7); // Arguments of group #0 are always included.
}
#ifdef _WIN32
TEST_F(CCommandLineParserTestIncompatibleArguments, OptionParseCaseSensitiveFullArgumentWin)
{
const char* rgszCommandLine[] = {"this_exe.app", "/i8var=-1", "/i16var=-2", "/i32var=-3", "/i64var=-4",
"/ui8var=5", "/ui16var=6", "/ui32var=7", "/ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineOption("i8var", i8Var, "int8_t variable", true, 0, 1);
int16_t i16Var = 0; cl.DefineOption("i16var", i16Var, "int16_t variable", true, 1, 2);
int32_t i32Var = 0; cl.DefineOption("i32var", i32Var, "int32_t variable", true, 2, 3);
int64_t i64Var = 0; cl.DefineOption("i64var", i64Var, "int64_t variable", true, 3, 4);
uint8_t ui8Var = 0; cl.DefineOption("ui8var", ui8Var, "uint8_t variable", true, 4, 5);
uint16_t ui16Var = 0; cl.DefineOption("ui16var", ui16Var, "uint16_t variable", true, 5, 6);
uint32_t ui32Var = 0; cl.DefineOption("ui32var", ui32Var, "uint32_t variable", true, 6, 7);
uint64_t ui64Var = 0; cl.DefineOption("ui64var", ui64Var, "uint64_t variable", true, 7, 8);
int8_t i8Control = -10; cl.DefineOption("i8control", i8Control, "int8_t no change!", true, 0, 1);
int16_t i16Control = -20; cl.DefineOption("i16control", i16Control, "int16_t no change!", true, 1, 2);
int32_t i32Control = -30; cl.DefineOption("i32control", i32Control, "int32_t no change!", true, 2, 3);
int64_t i64Control = -40; cl.DefineOption("i64control", i64Control, "int64_t no change!", true, 3, 4);
uint8_t ui8Control = 50; cl.DefineOption("ui8control", ui8Control, "uint8_t no change!", true, 4, 5);
uint16_t ui16Control = 60; cl.DefineOption("ui16control", ui16Control, "uint16_t no change!", true, 5, 6);
uint32_t ui32Control = 70; cl.DefineOption("ui32control", ui32Control, "uint32_t no change!", true, 6, 7);
uint64_t ui64Control = 80; cl.DefineOption("ui64control", ui64Control, "uint64_t no change!", true, 7, 8);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0)[0], "/i16var=-2"); // Full argument
EXPECT_EQ(cl.IncompatibleArguments(1).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9).size(), 7); // Arguments of group #0 are always included.
}
#endif
TEST_F(CCommandLineParserTestIncompatibleArguments, SubOptionParseCaseSensitiveFullArgument)
{
const char* rgszCommandLine[] = {"this_exe.app", "--i8var=-1", "--i16var=-2", "--i32var=-3", "--i64var=-4",
"--ui8var=5", "--ui16var=6", "--ui32var=7", "--ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineSubOption("i8var", i8Var, "int8_t variable", true, 0, 1);
int16_t i16Var = 0; cl.DefineSubOption("i16var", i16Var, "int16_t variable", true, 1, 2);
int32_t i32Var = 0; cl.DefineSubOption("i32var", i32Var, "int32_t variable", true, 2, 3);
int64_t i64Var = 0; cl.DefineSubOption("i64var", i64Var, "int64_t variable", true, 3, 4);
uint8_t ui8Var = 0; cl.DefineSubOption("ui8var", ui8Var, "uint8_t variable", true, 4, 5);
uint16_t ui16Var = 0; cl.DefineSubOption("ui16var", ui16Var, "uint16_t variable", true, 5, 6);
uint32_t ui32Var = 0; cl.DefineSubOption("ui32var", ui32Var, "uint32_t variable", true, 6, 7);
uint64_t ui64Var = 0; cl.DefineSubOption("ui64var", ui64Var, "uint64_t variable", true, 7, 8);
int8_t i8Control = -10; cl.DefineSubOption("i8control", i8Control, "int8_t no change!", true, 0, 1);
int16_t i16Control = -20; cl.DefineSubOption("i16control", i16Control, "int16_t no change!", true, 1, 2);
int32_t i32Control = -30; cl.DefineSubOption("i32control", i32Control, "int32_t no change!", true, 2, 3);
int64_t i64Control = -40; cl.DefineSubOption("i64control", i64Control, "int64_t no change!", true, 3, 4);
uint8_t ui8Control = 50; cl.DefineSubOption("ui8control", ui8Control, "uint8_t no change!", true, 4, 5);
uint16_t ui16Control = 60; cl.DefineSubOption("ui16control", ui16Control, "uint16_t no change!", true, 5, 6);
uint32_t ui32Control = 70; cl.DefineSubOption("ui32control", ui32Control, "uint32_t no change!", true, 6, 7);
uint64_t ui64Control = 80; cl.DefineSubOption("ui64control", ui64Control, "uint64_t no change!", true, 7, 8);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0)[0], "--i16var=-2"); // Full argument
EXPECT_EQ(cl.IncompatibleArguments(1).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9).size(), 7); // Arguments of group #0 are always included.
}
TEST_F(CCommandLineParserTestIncompatibleArguments, OptionParseCaseInsensitiveFullArgument)
{
const char* rgszCommandLine[] = {"this_exe.app", "-i8VAR=-1", "-i16VAR=-2", "-i32VAR=-3", "-i64VAR=-4",
"-ui8VAR=5", "-ui16VAR=6", "-ui32VAR=7", "-ui64VAR=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineOption("i8var", i8Var, "int8_t variable", false, 0, 1);
int16_t i16Var = 0; cl.DefineOption("i16var", i16Var, "int16_t variable", false, 1, 2);
int32_t i32Var = 0; cl.DefineOption("i32var", i32Var, "int32_t variable", false, 2, 3);
int64_t i64Var = 0; cl.DefineOption("i64var", i64Var, "int64_t variable", false, 3, 4);
uint8_t ui8Var = 0; cl.DefineOption("ui8var", ui8Var, "uint8_t variable", false, 4, 5);
uint16_t ui16Var = 0; cl.DefineOption("ui16var", ui16Var, "uint16_t variable", false, 5, 6);
uint32_t ui32Var = 0; cl.DefineOption("ui32var", ui32Var, "uint32_t variable", false, 6, 7);
uint64_t ui64Var = 0; cl.DefineOption("ui64var", ui64Var, "uint64_t variable", false, 7, 8);
int8_t i8Control = -10; cl.DefineOption("i8control", i8Control, "int8_t no change!", false, 0, 1);
int16_t i16Control = -20; cl.DefineOption("i16control", i16Control, "int16_t no change!", false, 1, 2);
int32_t i32Control = -30; cl.DefineOption("i32control", i32Control, "int32_t no change!", false, 2, 3);
int64_t i64Control = -40; cl.DefineOption("i64control", i64Control, "int64_t no change!", false, 3, 4);
uint8_t ui8Control = 50; cl.DefineOption("ui8control", ui8Control, "uint8_t no change!", false, 4, 5);
uint16_t ui16Control = 60; cl.DefineOption("ui16control", ui16Control, "uint16_t no change!", false, 5, 6);
uint32_t ui32Control = 70; cl.DefineOption("ui32control", ui32Control, "uint32_t no change!", false, 6, 7);
uint64_t ui64Control = 80; cl.DefineOption("ui64control", ui64Control, "uint64_t no change!", false, 7, 8);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0)[0], "-i16VAR=-2"); // Full argument
EXPECT_EQ(cl.IncompatibleArguments(1).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9).size(), 7); // Arguments of group #0 are always included.
}
#ifdef _WIN32
TEST_F(CCommandLineParserTestIncompatibleArguments, OptionParseCaseInsensitiveFullArgumentWin)
{
const char* rgszCommandLine[] = {"this_exe.app", "/i8VAR=-1", "/i16VAR=-2", "/i32VAR=-3", "/i64VAR=-4",
"/ui8VAR=5", "/ui16VAR=6", "/ui32VAR=7", "/ui64VAR=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineOption("i8var", i8Var, "int8_t variable", false, 0, 1);
int16_t i16Var = 0; cl.DefineOption("i16var", i16Var, "int16_t variable", false, 1, 2);
int32_t i32Var = 0; cl.DefineOption("i32var", i32Var, "int32_t variable", false, 2, 3);
int64_t i64Var = 0; cl.DefineOption("i64var", i64Var, "int64_t variable", false, 3, 4);
uint8_t ui8Var = 0; cl.DefineOption("ui8var", ui8Var, "uint8_t variable", false, 4, 5);
uint16_t ui16Var = 0; cl.DefineOption("ui16var", ui16Var, "uint16_t variable", false, 5, 6);
uint32_t ui32Var = 0; cl.DefineOption("ui32var", ui32Var, "uint32_t variable", false, 6, 7);
uint64_t ui64Var = 0; cl.DefineOption("ui64var", ui64Var, "uint64_t variable", false, 7, 8);
int8_t i8Control = -10; cl.DefineOption("i8control", i8Control, "int8_t no change!", false, 0, 1);
int16_t i16Control = -20; cl.DefineOption("i16control", i16Control, "int16_t no change!", false, 1, 2);
int32_t i32Control = -30; cl.DefineOption("i32control", i32Control, "int32_t no change!", false, 2, 3);
int64_t i64Control = -40; cl.DefineOption("i64control", i64Control, "int64_t no change!", false, 3, 4);
uint8_t ui8Control = 50; cl.DefineOption("ui8control", ui8Control, "uint8_t no change!", false, 4, 5);
uint16_t ui16Control = 60; cl.DefineOption("ui16control", ui16Control, "uint16_t no change!", false, 5, 6);
uint32_t ui32Control = 70; cl.DefineOption("ui32control", ui32Control, "uint32_t no change!", false, 6, 7);
uint64_t ui64Control = 80; cl.DefineOption("ui64control", ui64Control, "uint64_t no change!", false, 7, 8);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0)[0], "/i16VAR=-2"); // Full argument
EXPECT_EQ(cl.IncompatibleArguments(1).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9).size(), 7); // Arguments of group #0 are always included.
}
#endif
TEST_F(CCommandLineParserTestIncompatibleArguments, SubOptionParseCaseInsensitiveFullArgument)
{
const char* rgszCommandLine[] = {"this_exe.app", "--i8VAR=-1", "--i16VAR=-2", "--i32VAR=-3", "--i64VAR=-4",
"--ui8VAR=5", "--ui16VAR=6", "--ui32VAR=7", "--ui64VAR=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineSubOption("i8var", i8Var, "int8_t variable", false, 0, 1);
int16_t i16Var = 0; cl.DefineSubOption("i16var", i16Var, "int16_t variable", false, 1, 2);
int32_t i32Var = 0; cl.DefineSubOption("i32var", i32Var, "int32_t variable", false, 2, 3);
int64_t i64Var = 0; cl.DefineSubOption("i64var", i64Var, "int64_t variable", false, 3, 4);
uint8_t ui8Var = 0; cl.DefineSubOption("ui8var", ui8Var, "uint8_t variable", false, 4, 5);
uint16_t ui16Var = 0; cl.DefineSubOption("ui16var", ui16Var, "uint16_t variable", false, 5, 6);
uint32_t ui32Var = 0; cl.DefineSubOption("ui32var", ui32Var, "uint32_t variable", false, 6, 7);
uint64_t ui64Var = 0; cl.DefineSubOption("ui64var", ui64Var, "uint64_t variable", false, 7, 8);
int8_t i8Control = -10; cl.DefineSubOption("i8control", i8Control, "int8_t no change!", false, 0, 1);
int16_t i16Control = -20; cl.DefineSubOption("i16control", i16Control, "int16_t no change!", false, 1, 2);
int32_t i32Control = -30; cl.DefineSubOption("i32control", i32Control, "int32_t no change!", false, 2, 3);
int64_t i64Control = -40; cl.DefineSubOption("i64control", i64Control, "int64_t no change!", false, 3, 4);
uint8_t ui8Control = 50; cl.DefineSubOption("ui8control", ui8Control, "uint8_t no change!", false, 4, 5);
uint16_t ui16Control = 60; cl.DefineSubOption("ui16control", ui16Control, "uint16_t no change!", false, 5, 6);
uint32_t ui32Control = 70; cl.DefineSubOption("ui32control", ui32Control, "uint32_t no change!", false, 6, 7);
uint64_t ui64Control = 80; cl.DefineSubOption("ui64control", ui64Control, "uint64_t no change!", false, 7, 8);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0)[0], "--i16VAR=-2"); // Full argument
EXPECT_EQ(cl.IncompatibleArguments(1).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9).size(), 7); // Arguments of group #0 are always included.
}
TEST_F(CCommandLineParserTestIncompatibleArguments, OptionParseCaseSensitiveNameArgument)
{
const char* rgszCommandLine[] = {"this_exe.app", "-i8var=-1", "-i16var=-2", "-i32var=-3", "-i64var=-4",
"-ui8var=5", "-ui16var=6", "-ui32var=7", "-ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineOption("i8var", i8Var, "int8_t variable", true, 0, 1);
int16_t i16Var = 0; cl.DefineOption("i16var", i16Var, "int16_t variable", true, 1, 2);
int32_t i32Var = 0; cl.DefineOption("i32var", i32Var, "int32_t variable", true, 2, 3);
int64_t i64Var = 0; cl.DefineOption("i64var", i64Var, "int64_t variable", true, 3, 4);
uint8_t ui8Var = 0; cl.DefineOption("ui8var", ui8Var, "uint8_t variable", true, 4, 5);
uint16_t ui16Var = 0; cl.DefineOption("ui16var", ui16Var, "uint16_t variable", true, 5, 6);
uint32_t ui32Var = 0; cl.DefineOption("ui32var", ui32Var, "uint32_t variable", true, 6, 7);
uint64_t ui64Var = 0; cl.DefineOption("ui64var", ui64Var, "uint64_t variable", true, 7, 8);
int8_t i8Control = -10; cl.DefineOption("i8control", i8Control, "int8_t no change!", true, 0, 1);
int16_t i16Control = -20; cl.DefineOption("i16control", i16Control, "int16_t no change!", true, 1, 2);
int32_t i32Control = -30; cl.DefineOption("i32control", i32Control, "int32_t no change!", true, 2, 3);
int64_t i64Control = -40; cl.DefineOption("i64control", i64Control, "int64_t no change!", true, 3, 4);
uint8_t ui8Control = 50; cl.DefineOption("ui8control", ui8Control, "uint8_t no change!", true, 4, 5);
uint16_t ui16Control = 60; cl.DefineOption("ui16control", ui16Control, "uint16_t no change!", true, 5, 6);
uint32_t ui32Control = 70; cl.DefineOption("ui32control", ui32Control, "uint32_t no change!", true, 6, 7);
uint64_t ui64Control = 80; cl.DefineOption("ui64control", ui64Control, "uint64_t no change!", true, 7, 8);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0, false).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0, false)[0], "-i16var"); // Argument without assignment
EXPECT_EQ(cl.IncompatibleArguments(1, false).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8, false).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9, false).size(), 7); // Arguments of group #0 are always included.
}
#ifdef _WIN32
TEST_F(CCommandLineParserTestIncompatibleArguments, OptionParseCaseSensitiveNameArgumentWin)
{
const char* rgszCommandLine[] = {"this_exe.app", "/i8var=-1", "/i16var=-2", "/i32var=-3", "/i64var=-4",
"/ui8var=5", "/ui16var=6", "/ui32var=7", "/ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineOption("i8var", i8Var, "int8_t variable", true, 0, 1);
int16_t i16Var = 0; cl.DefineOption("i16var", i16Var, "int16_t variable", true, 1, 2);
int32_t i32Var = 0; cl.DefineOption("i32var", i32Var, "int32_t variable", true, 2, 3);
int64_t i64Var = 0; cl.DefineOption("i64var", i64Var, "int64_t variable", true, 3, 4);
uint8_t ui8Var = 0; cl.DefineOption("ui8var", ui8Var, "uint8_t variable", true, 4, 5);
uint16_t ui16Var = 0; cl.DefineOption("ui16var", ui16Var, "uint16_t variable", true, 5, 6);
uint32_t ui32Var = 0; cl.DefineOption("ui32var", ui32Var, "uint32_t variable", true, 6, 7);
uint64_t ui64Var = 0; cl.DefineOption("ui64var", ui64Var, "uint64_t variable", true, 7, 8);
int8_t i8Control = -10; cl.DefineOption("i8control", i8Control, "int8_t no change!", true, 0, 1);
int16_t i16Control = -20; cl.DefineOption("i16control", i16Control, "int16_t no change!", true, 1, 2);
int32_t i32Control = -30; cl.DefineOption("i32control", i32Control, "int32_t no change!", true, 2, 3);
int64_t i64Control = -40; cl.DefineOption("i64control", i64Control, "int64_t no change!", true, 3, 4);
uint8_t ui8Control = 50; cl.DefineOption("ui8control", ui8Control, "uint8_t no change!", true, 4, 5);
uint16_t ui16Control = 60; cl.DefineOption("ui16control", ui16Control, "uint16_t no change!", true, 5, 6);
uint32_t ui32Control = 70; cl.DefineOption("ui32control", ui32Control, "uint32_t no change!", true, 6, 7);
uint64_t ui64Control = 80; cl.DefineOption("ui64control", ui64Control, "uint64_t no change!", true, 7, 8);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0, false).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0, false)[0], "/i16var"); // Argument without assignment
EXPECT_EQ(cl.IncompatibleArguments(1, false).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8, false).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9, false).size(), 7); // Arguments of group #0 are always included.
}
#endif
TEST_F(CCommandLineParserTestIncompatibleArguments, SubOptionParseCaseSensitiveNameArgument)
{
const char* rgszCommandLine[] = {"this_exe.app", "--i8var=-1", "--i16var=-2", "--i32var=-3", "--i64var=-4",
"--ui8var=5", "--ui16var=6", "--ui32var=7", "--ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineSubOption("i8var", i8Var, "int8_t variable", true, 0, 1);
int16_t i16Var = 0; cl.DefineSubOption("i16var", i16Var, "int16_t variable", true, 1, 2);
int32_t i32Var = 0; cl.DefineSubOption("i32var", i32Var, "int32_t variable", true, 2, 3);
int64_t i64Var = 0; cl.DefineSubOption("i64var", i64Var, "int64_t variable", true, 3, 4);
uint8_t ui8Var = 0; cl.DefineSubOption("ui8var", ui8Var, "uint8_t variable", true, 4, 5);
uint16_t ui16Var = 0; cl.DefineSubOption("ui16var", ui16Var, "uint16_t variable", true, 5, 6);
uint32_t ui32Var = 0; cl.DefineSubOption("ui32var", ui32Var, "uint32_t variable", true, 6, 7);
uint64_t ui64Var = 0; cl.DefineSubOption("ui64var", ui64Var, "uint64_t variable", true, 7, 8);
int8_t i8Control = -10; cl.DefineSubOption("i8control", i8Control, "int8_t no change!", true, 0, 1);
int16_t i16Control = -20; cl.DefineSubOption("i16control", i16Control, "int16_t no change!", true, 1, 2);
int32_t i32Control = -30; cl.DefineSubOption("i32control", i32Control, "int32_t no change!", true, 2, 3);
int64_t i64Control = -40; cl.DefineSubOption("i64control", i64Control, "int64_t no change!", true, 3, 4);
uint8_t ui8Control = 50; cl.DefineSubOption("ui8control", ui8Control, "uint8_t no change!", true, 4, 5);
uint16_t ui16Control = 60; cl.DefineSubOption("ui16control", ui16Control, "uint16_t no change!", true, 5, 6);
uint32_t ui32Control = 70; cl.DefineSubOption("ui32control", ui32Control, "uint32_t no change!", true, 6, 7);
uint64_t ui64Control = 80; cl.DefineSubOption("ui64control", ui64Control, "uint64_t no change!", true, 7, 8);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0, false).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0, false)[0], "--i16var"); // Argument without assignment
EXPECT_EQ(cl.IncompatibleArguments(1, false).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8, false).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9, false).size(), 7); // Arguments of group #0 are always included.
}
TEST_F(CCommandLineParserTestIncompatibleArguments, OptionParseCaseInsensitiveNameArgument)
{
const char* rgszCommandLine[] = {"this_exe.app", "-i8VAR=-1", "-i16VAR=-2", "-i32VAR=-3", "-i64VAR=-4",
"-ui8VAR=5", "-ui16VAR=6", "-ui32VAR=7", "-ui64VAR=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineOption("i8var", i8Var, "int8_t variable", false, 0, 1);
int16_t i16Var = 0; cl.DefineOption("i16var", i16Var, "int16_t variable", false, 1, 2);
int32_t i32Var = 0; cl.DefineOption("i32var", i32Var, "int32_t variable", false, 2, 3);
int64_t i64Var = 0; cl.DefineOption("i64var", i64Var, "int64_t variable", false, 3, 4);
uint8_t ui8Var = 0; cl.DefineOption("ui8var", ui8Var, "uint8_t variable", false, 4, 5);
uint16_t ui16Var = 0; cl.DefineOption("ui16var", ui16Var, "uint16_t variable", false, 5, 6);
uint32_t ui32Var = 0; cl.DefineOption("ui32var", ui32Var, "uint32_t variable", false, 6, 7);
uint64_t ui64Var = 0; cl.DefineOption("ui64var", ui64Var, "uint64_t variable", false, 7, 8);
int8_t i8Control = -10; cl.DefineOption("i8control", i8Control, "int8_t no change!", false, 0, 1);
int16_t i16Control = -20; cl.DefineOption("i16control", i16Control, "int16_t no change!", false, 1, 2);
int32_t i32Control = -30; cl.DefineOption("i32control", i32Control, "int32_t no change!", false, 2, 3);
int64_t i64Control = -40; cl.DefineOption("i64control", i64Control, "int64_t no change!", false, 3, 4);
uint8_t ui8Control = 50; cl.DefineOption("ui8control", ui8Control, "uint8_t no change!", false, 4, 5);
uint16_t ui16Control = 60; cl.DefineOption("ui16control", ui16Control, "uint16_t no change!", false, 5, 6);
uint32_t ui32Control = 70; cl.DefineOption("ui32control", ui32Control, "uint32_t no change!", false, 6, 7);
uint64_t ui64Control = 80; cl.DefineOption("ui64control", ui64Control, "uint64_t no change!", false, 7, 8);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0, false).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0, false)[0], "-i16VAR"); // Argument without assignment
EXPECT_EQ(cl.IncompatibleArguments(1, false).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8, false).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9, false).size(), 7); // Arguments of group #0 are always included.
}
#ifdef _WIN32
TEST_F(CCommandLineParserTestIncompatibleArguments, OptionParseCaseInsensitiveNameArgumentWin)
{
const char* rgszCommandLine[] = {"this_exe.app", "/i8VAR=-1", "/i16VAR=-2", "/i32VAR=-3", "/i64VAR=-4",
"/ui8VAR=5", "/ui16VAR=6", "/ui32VAR=7", "/ui64VAR=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineOption("i8var", i8Var, "int8_t variable", false, 0, 1);
int16_t i16Var = 0; cl.DefineOption("i16var", i16Var, "int16_t variable", false, 1, 2);
int32_t i32Var = 0; cl.DefineOption("i32var", i32Var, "int32_t variable", false, 2, 3);
int64_t i64Var = 0; cl.DefineOption("i64var", i64Var, "int64_t variable", false, 3, 4);
uint8_t ui8Var = 0; cl.DefineOption("ui8var", ui8Var, "uint8_t variable", false, 4, 5);
uint16_t ui16Var = 0; cl.DefineOption("ui16var", ui16Var, "uint16_t variable", false, 5, 6);
uint32_t ui32Var = 0; cl.DefineOption("ui32var", ui32Var, "uint32_t variable", false, 6, 7);
uint64_t ui64Var = 0; cl.DefineOption("ui64var", ui64Var, "uint64_t variable", false, 7, 8);
int8_t i8Control = -10; cl.DefineOption("i8control", i8Control, "int8_t no change!", false, 0, 1);
int16_t i16Control = -20; cl.DefineOption("i16control", i16Control, "int16_t no change!", false, 1, 2);
int32_t i32Control = -30; cl.DefineOption("i32control", i32Control, "int32_t no change!", false, 2, 3);
int64_t i64Control = -40; cl.DefineOption("i64control", i64Control, "int64_t no change!", false, 3, 4);
uint8_t ui8Control = 50; cl.DefineOption("ui8control", ui8Control, "uint8_t no change!", false, 4, 5);
uint16_t ui16Control = 60; cl.DefineOption("ui16control", ui16Control, "uint16_t no change!", false, 5, 6);
uint32_t ui32Control = 70; cl.DefineOption("ui32control", ui32Control, "uint32_t no change!", false, 6, 7);
uint64_t ui64Control = 80; cl.DefineOption("ui64control", ui64Control, "uint64_t no change!", false, 7, 8);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0, false).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0, false)[0], "/i16VAR"); // Argument without assignment
EXPECT_EQ(cl.IncompatibleArguments(1, false).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8, false).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9, false).size(), 7); // Arguments of group #0 are always included.
}
#endif
TEST_F(CCommandLineParserTestIncompatibleArguments, SubOptionParseCaseInsensitiveNameArgument)
{
const char* rgszCommandLine[] = {"this_exe.app", "--i8VAR=-1", "--i16VAR=-2", "--i32VAR=-3", "--i64VAR=-4",
"--ui8VAR=5", "--ui16VAR=6", "--ui32VAR=7", "--ui64VAR=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineSubOption("i8var", i8Var, "int8_t variable", false, 0, 1);
int16_t i16Var = 0; cl.DefineSubOption("i16var", i16Var, "int16_t variable", false, 1, 2);
int32_t i32Var = 0; cl.DefineSubOption("i32var", i32Var, "int32_t variable", false, 2, 3);
int64_t i64Var = 0; cl.DefineSubOption("i64var", i64Var, "int64_t variable", false, 3, 4);
uint8_t ui8Var = 0; cl.DefineSubOption("ui8var", ui8Var, "uint8_t variable", false, 4, 5);
uint16_t ui16Var = 0; cl.DefineSubOption("ui16var", ui16Var, "uint16_t variable", false, 5, 6);
uint32_t ui32Var = 0; cl.DefineSubOption("ui32var", ui32Var, "uint32_t variable", false, 6, 7);
uint64_t ui64Var = 0; cl.DefineSubOption("ui64var", ui64Var, "uint64_t variable", false, 7, 8);
int8_t i8Control = -10; cl.DefineSubOption("i8control", i8Control, "int8_t no change!", false, 0, 1);
int16_t i16Control = -20; cl.DefineSubOption("i16control", i16Control, "int16_t no change!", false, 1, 2);
int32_t i32Control = -30; cl.DefineSubOption("i32control", i32Control, "int32_t no change!", false, 2, 3);
int64_t i64Control = -40; cl.DefineSubOption("i64control", i64Control, "int64_t no change!", false, 3, 4);
uint8_t ui8Control = 50; cl.DefineSubOption("ui8control", ui8Control, "uint8_t no change!", false, 4, 5);
uint16_t ui16Control = 60; cl.DefineSubOption("ui16control", ui16Control, "uint16_t no change!", false, 5, 6);
uint32_t ui32Control = 70; cl.DefineSubOption("ui32control", ui32Control, "uint32_t no change!", false, 6, 7);
uint64_t ui64Control = 80; cl.DefineSubOption("ui64control", ui64Control, "uint64_t no change!", false, 7, 8);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0, false).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0, false)[0], "--i16VAR"); // Argument without assignment
EXPECT_EQ(cl.IncompatibleArguments(1, false).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7, false).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8, false).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9, false).size(), 7); // Arguments of group #0 are always included.
}
TEST_F(CCommandLineParserTestIncompatibleArguments, MultiOptionParseCaseSensitiveFullArgument)
{
const char* rgszCommandLine[] = {"this_exe.app", "-i8var=-1", "-i16var=-2", "-i32var=-3", "-i64var=-4",
"-ui8var=5", "-ui16var=6", "-ui32var=7", "-ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0;
auto& rI8Var = cl.DefineOption("i8VAR", i8Var, "int8_t variable", true, 0, 1);
rI8Var.AddOptionName("i8var");
int16_t i16Var = 0;
auto& rI16Var = cl.DefineOption("i16VAR", i16Var, "int16_t variable", true, 1, 2);
rI16Var.AddOptionName("i16var");
int32_t i32Var = 0;
auto& rI32Var = cl.DefineOption("i32VAR", i32Var, "int32_t variable", true, 2, 3);
rI32Var.AddOptionName("i32var");
int64_t i64Var = 0;
auto& rI64Var = cl.DefineOption("i64VAR", i64Var, "int64_t variable", true, 3, 4);
rI64Var.AddOptionName("i64var");
uint8_t ui8Var = 0;
auto& rUI8Var = cl.DefineOption("ui8VAR", ui8Var, "uint8_t variable", true, 4, 5);
rUI8Var.AddOptionName("ui8var");
uint16_t ui16Var = 0;
auto& rUI16Var = cl.DefineOption("ui16VAR", ui16Var, "uint16_t variable", true, 5, 6);
rUI16Var.AddOptionName("ui16var");
uint32_t ui32Var = 0;
auto& rUI32Var = cl.DefineOption("ui32VAR", ui32Var, "uint32_t variable", true, 6, 7);
rUI32Var.AddOptionName("ui32var");
uint64_t ui64Var = 0;
auto& rUI64Var = cl.DefineOption("ui64VAR", ui64Var, "uint64_t variable", true, 7, 8);
rUI64Var.AddOptionName("ui64var");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0)[0], "-i16var=-2"); // Full argument
EXPECT_EQ(cl.IncompatibleArguments(1).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9).size(), 7); // Arguments of group #0 are always included.
}
#ifdef _WIN32
TEST_F(CCommandLineParserTestIncompatibleArguments, MultiOptionParseCaseSensitiveFullArgumentWin)
{
const char* rgszCommandLine[] = {"this_exe.app", "/i8var=-1", "/i16var=-2", "/i32var=-3", "/i64var=-4",
"/ui8var=5", "/ui16var=6", "/ui32var=7", "/ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0;
auto& rI8Var = cl.DefineOption("i8VAR", i8Var, "int8_t variable", true, 0, 1);
rI8Var.AddOptionName("i8var");
int16_t i16Var = 0;
auto& rI16Var = cl.DefineOption("i16VAR", i16Var, "int16_t variable", true, 1, 2);
rI16Var.AddOptionName("i16var");
int32_t i32Var = 0;
auto& rI32Var = cl.DefineOption("i32VAR", i32Var, "int32_t variable", true, 2, 3);
rI32Var.AddOptionName("i32var");
int64_t i64Var = 0;
auto& rI64Var = cl.DefineOption("i64VAR", i64Var, "int64_t variable", true, 3, 4);
rI64Var.AddOptionName("i64var");
uint8_t ui8Var = 0;
auto& rUI8Var = cl.DefineOption("ui8VAR", ui8Var, "uint8_t variable", true, 4, 5);
rUI8Var.AddOptionName("ui8var");
uint16_t ui16Var = 0;
auto& rUI16Var = cl.DefineOption("ui16VAR", ui16Var, "uint16_t variable", true, 5, 6);
rUI16Var.AddOptionName("ui16var");
uint32_t ui32Var = 0;
auto& rUI32Var = cl.DefineOption("ui32VAR", ui32Var, "uint32_t variable", true, 6, 7);
rUI32Var.AddOptionName("ui32var");
uint64_t ui64Var = 0;
auto& rUI64Var = cl.DefineOption("ui64VAR", ui64Var, "uint64_t variable", true, 7, 8);
rUI64Var.AddOptionName("ui64var");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0)[0], "/i16var=-2"); // Full argument
EXPECT_EQ(cl.IncompatibleArguments(1).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9).size(), 7); // Arguments of group #0 are always included.
}
#endif
TEST_F(CCommandLineParserTestIncompatibleArguments, MultiSubOptionParseCaseSensitiveFullArgument)
{
const char* rgszCommandLine[] = {"this_exe.app", "--i8var=-1", "--i16var=-2", "--i32var=-3", "--i64var=-4",
"--ui8var=5", "--ui16var=6", "--ui32var=7", "--ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0;
auto& rI8Var = cl.DefineSubOption("i8VAR", i8Var, "int8_t variable", true, 0, 1);
rI8Var.AddSubOptionName("i8var");
int16_t i16Var = 0;
auto& rI16Var = cl.DefineSubOption("i16VAR", i16Var, "int16_t variable", true, 1, 2);
rI16Var.AddSubOptionName("i16var");
int32_t i32Var = 0;
auto& rI32Var = cl.DefineSubOption("i32VAR", i32Var, "int32_t variable", true, 2, 3);
rI32Var.AddSubOptionName("i32var");
int64_t i64Var = 0;
auto& rI64Var = cl.DefineSubOption("i64VAR", i64Var, "int64_t variable", true, 3, 4);
rI64Var.AddSubOptionName("i64var");
uint8_t ui8Var = 0;
auto& rUI8Var = cl.DefineSubOption("ui8VAR", ui8Var, "uint8_t variable", true, 4, 5);
rUI8Var.AddSubOptionName("ui8var");
uint16_t ui16Var = 0;
auto& rUI16Var = cl.DefineSubOption("ui16VAR", ui16Var, "uint16_t variable", true, 5, 6);
rUI16Var.AddSubOptionName("ui16var");
uint32_t ui32Var = 0;
auto& rUI32Var = cl.DefineSubOption("ui32VAR", ui32Var, "uint32_t variable", true, 6, 7);
rUI32Var.AddSubOptionName("ui32var");
uint64_t ui64Var = 0;
auto& rUI64Var = cl.DefineSubOption("ui64VAR", ui64Var, "uint64_t variable", true, 7, 8);
rUI64Var.AddSubOptionName("ui64var");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
// For each group check the supplied arguments. The arguments belonging to group 0 are compatible with all groups. The other
// arguments are compatible with the group they have been assigned to only.
ASSERT_EQ(cl.IncompatibleArguments(0).size(), 7);
EXPECT_EQ(cl.IncompatibleArguments(0)[0], "--i16var=-2"); // Full argument
EXPECT_EQ(cl.IncompatibleArguments(1).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(2).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(3).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(4).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(5).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(6).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(7).size(), 5);
EXPECT_EQ(cl.IncompatibleArguments(8).size(), 6);
EXPECT_EQ(cl.IncompatibleArguments(9).size(), 7); // Arguments of group #0 are always included.
}

View File

@@ -0,0 +1,19 @@
#include <gtest/gtest.h>
#include "../../../global/process_watchdog.h"
#include "../../../global/localmemmgr.h"
/**
* @brief Main function
*/
#if defined(_WIN32) && defined(_UNICODE)
extern "C" int wmain(int argc, wchar_t* argv[])
#else
extern "C" int main(int argc, char* argv[])
#endif
{
CProcessWatchdog watchdog;
CLocalMemMgr memmgr;
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,555 @@
#include "../../include/gtest_custom.h"
#include "commandline_parser_test.h"
#include "../../../global/cmdlnparser/cmdlnparser.h"
TEST_F(CCommandLineParserTest, OptionParseBoolean)
{
const char* rgszCommandLine[] = {"this_exe.app", "-select"};
CCommandLine cl;
bool bSelect = false; cl.DefineOption("select", bSelect, "Select it!");
bool bControlNegative = false; cl.DefineOption("neg_control", bControlNegative, "No change!");
bool bControlPositive = true; cl.DefineOption("pos_control", bControlPositive, "No change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bSelect);
EXPECT_FALSE(bControlNegative);
EXPECT_TRUE(bControlPositive);
}
TEST_F(CCommandLineParserTest, OptionParseIntegralIndependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "-i8var=-1", "-i16var=-2", "-i32var=-3", "-i64var=-4",
"-ui8var=5", "-ui16var=6", "-ui32var=7", "-ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineOption("i8var", i8Var, "int8_t variable");
int16_t i16Var = 0; cl.DefineOption("i16var", i16Var, "int16_t variable");
int32_t i32Var = 0; cl.DefineOption("i32var", i32Var, "int32_t variable");
int64_t i64Var = 0; cl.DefineOption("i64var", i64Var, "int64_t variable");
uint8_t ui8Var = 0; cl.DefineOption("ui8var", ui8Var, "uint8_t variable");
uint16_t ui16Var = 0; cl.DefineOption("ui16var", ui16Var, "uint16_t variable");
uint32_t ui32Var = 0; cl.DefineOption("ui32var", ui32Var, "uint32_t variable");
uint64_t ui64Var = 0; cl.DefineOption("ui64var", ui64Var, "uint64_t variable");
int8_t i8Control = -10; cl.DefineOption("i8control", i8Control, "int8_t no change!");
int16_t i16Control = -20; cl.DefineOption("i16control", i16Control, "int16_t no change!");
int32_t i32Control = -30; cl.DefineOption("i32control", i32Control, "int32_t no change!");
int64_t i64Control = -40; cl.DefineOption("i64control", i64Control, "int64_t no change!");
uint8_t ui8Control = 50; cl.DefineOption("ui8control", ui8Control, "uint8_t no change!");
uint16_t ui16Control = 60; cl.DefineOption("ui16control", ui16Control, "uint16_t no change!");
uint32_t ui32Control = 70; cl.DefineOption("ui32control", ui32Control, "uint32_t no change!");
uint64_t ui64Control = 80; cl.DefineOption("ui64control", ui64Control, "uint64_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(i8Var, -1);
EXPECT_EQ(i16Var, -2);
EXPECT_EQ(i32Var, -3);
EXPECT_EQ(i64Var, -4);
EXPECT_EQ(ui8Var, 5u);
EXPECT_EQ(ui16Var, 6u);
EXPECT_EQ(ui32Var, 7u);
EXPECT_EQ(ui64Var, 8u);
EXPECT_EQ(i8Control, -10);
EXPECT_EQ(i16Control, -20);
EXPECT_EQ(i32Control, -30);
EXPECT_EQ(i64Control, -40);
EXPECT_EQ(ui8Control, 50u);
EXPECT_EQ(ui16Control, 60u);
EXPECT_EQ(ui32Control, 70u);
EXPECT_EQ(ui64Control, 80u);
}
TEST_F(CCommandLineParserTest, OptionParseIntegralDedependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "-cvar=-1", "-svar=-2", "-lvar=-3", "-ivar=-4", "-llvar=-5",
"-ucvar=6", "-usvar=7", "-ulvar=8", "-uivar=9", "-ullvar=10", "-nvar=11"};
CCommandLine cl;
signed char cVar = 0; cl.DefineOption("cvar", cVar, "char variable");
short sVar = 0; cl.DefineOption("svar", sVar, "short variable");
long lVar = 0; cl.DefineOption("lvar", lVar, "long variable");
int iVar = 0; cl.DefineOption("ivar", iVar, "int variable");
long long llVar = 0; cl.DefineOption("llvar", llVar, "long long variable");
unsigned char ucVar = 0; cl.DefineOption("ucvar", ucVar, "unsigned char variable");
unsigned short usVar = 0; cl.DefineOption("usvar", usVar, "unsigned short variable");
unsigned long ulVar = 0; cl.DefineOption("ulvar", ulVar, "unsigned long variable");
unsigned int uiVar = 0; cl.DefineOption("uivar", uiVar, "unsigned int variable");
unsigned long long ullVar = 0; cl.DefineOption("ullvar", ullVar, "unsigned long long variable");
size_t nVar = 0; cl.DefineOption("nvar", nVar, "size_t variable");
signed char cControl = -10; cl.DefineOption("ccontrol", cControl, "char no change!");
short sControl = -20; cl.DefineOption("scontrol", sControl, "short no change!");
long lControl = -30; cl.DefineOption("lcontrol", lControl, "long no change!");
int iControl = -40; cl.DefineOption("icontrol", iControl, "int no change!");
long long llControl = -50; cl.DefineOption("llcontrol", llControl, "long long no change!");
unsigned char ucControl = 60; cl.DefineOption("uccontrol", ucControl, "unsigned char no change!");
unsigned short usControl = 70; cl.DefineOption("uscontrol", usControl, "unsigned short no change!");
unsigned long ulControl = 80; cl.DefineOption("ulcontrol", ulControl, "unsigned long no change!");
unsigned int uiControl = 90; cl.DefineOption("uicontrol", uiControl, "unsigned int no change!");
unsigned long long ullControl = 100; cl.DefineOption("ullcontrol", ullControl, "unsigned long long no change!");
size_t nControl = 110; cl.DefineOption("ncontrol", nControl, "size_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(cVar, -1);
EXPECT_EQ(sVar, -2);
EXPECT_EQ(lVar, -3);
EXPECT_EQ(iVar, -4);
EXPECT_EQ(llVar, -5);
EXPECT_EQ(ucVar, 6u);
EXPECT_EQ(usVar, 7u);
EXPECT_EQ(ulVar, 8u);
EXPECT_EQ(uiVar, 9u);
EXPECT_EQ(ullVar, 10u);
EXPECT_EQ(nVar, 11u);
EXPECT_EQ(cControl, -10);
EXPECT_EQ(sControl, -20);
EXPECT_EQ(lControl, -30);
EXPECT_EQ(iControl, -40);
EXPECT_EQ(llControl, -50);
EXPECT_EQ(ucControl, 60u);
EXPECT_EQ(usControl, 70u);
EXPECT_EQ(ulControl, 80u);
EXPECT_EQ(uiControl, 90u);
EXPECT_EQ(ullControl, 100u);
EXPECT_EQ(nControl, 110u);
}
TEST_F(CCommandLineParserTest, OptionParseIntegralIndependentVector)
{
// Attention: std::vector<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"-i8var=-1,2, -3",*/ "-i16var=-2,3,-4", "-i32var=-3,4,-5", "-i64var=-4,5,-6",
"-ui8var=5,6,7", "-ui16var=6,7,8", "-ui32var=7,8,9", "-ui64var=8,9,10"};
CCommandLine cl;
//std::vector<int8_t> veci8Var; cl.DefineOption("i8var", veci8Var, "vector of int8_t variable");
std::vector<int16_t> veci16Var; cl.DefineOption("i16var", veci16Var, "vector of int16_t variable");
std::vector<int32_t> veci32Var; cl.DefineOption("i32var", veci32Var, "vector of int32_t variable");
std::vector<int64_t> veci64Var; cl.DefineOption("i64var", veci64Var, "vector of int64_t variable");
std::vector<uint8_t> vecui8Var; cl.DefineOption("ui8var", vecui8Var, "vector of uint8_t variable");
std::vector<uint16_t> vecui16Var; cl.DefineOption("ui16var", vecui16Var, "vector of uint16_t variable");
std::vector<uint32_t> vecui32Var; cl.DefineOption("ui32var", vecui32Var, "vector of uint32_t variable");
std::vector<uint64_t> vecui64Var; cl.DefineOption("ui64var", vecui64Var, "vector of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(veci8Var, -1, 2, -3);
EXPECT_ARREQ(veci16Var, -2, 3, -4);
EXPECT_ARREQ(veci32Var, -3, 4, -5);
EXPECT_ARREQ(veci64Var, -4, 5, -6);
EXPECT_ARREQ(vecui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(vecui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(vecui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(vecui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTest, OptionParseIntegralDedependentVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "-cvar=-1,2,-3", "-svar=-2,3,-4", "-lvar=-3,4,-5", "-ivar=-4,5,-6", "-llvar=-5,6,-7",
"-ucvar=6,7,8", "-usvar=7,8,9", "-ulvar=8,9,10", "-uivar=9,10,11", "-ullvar=10,11,12", "-nvar=11,12,13"};
CCommandLine cl;
std::vector<signed char> veccVar; cl.DefineOption("cvar", veccVar, "vector of char variable");
std::vector<short> vecsVar; cl.DefineOption("svar", vecsVar, "vector of short variable");
std::vector<long> veclVar; cl.DefineOption("lvar", veclVar, "vector of long variable");
std::vector<int> veciVar; cl.DefineOption("ivar", veciVar, "vector of int variable");
std::vector<long long> vecllVar; cl.DefineOption("llvar", vecllVar, "vector of long long variable");
std::vector<unsigned char> vecucVar; cl.DefineOption("ucvar", vecucVar, "vector of unsigned char variable");
std::vector<unsigned short> vecusVar; cl.DefineOption("usvar", vecusVar, "vector of unsigned short variable");
std::vector<unsigned long> veculVar; cl.DefineOption("ulvar", veculVar, "vector of unsigned long variable");
std::vector<unsigned int> vecuiVar; cl.DefineOption("uivar", vecuiVar, "vector of unsigned int variable");
std::vector<unsigned long long> vecullVar; cl.DefineOption("ullvar", vecullVar, "vector of unsigned long long variable");
std::vector<size_t> vecnVar; cl.DefineOption("nvar", vecnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(veccVar, -1, 2, -3);
EXPECT_ARREQ(vecsVar, -2, 3, -4);
EXPECT_ARREQ(veclVar, -3, 4, -5);
EXPECT_ARREQ(veciVar, -4, 5, -6);
EXPECT_ARREQ(vecllVar, -5, 6, -7);
EXPECT_ARREQ(vecucVar, 6u, 7u, 8u);
EXPECT_ARREQ(vecusVar, 7u, 8u, 9u);
EXPECT_ARREQ(veculVar, 8u, 9u, 10u);
EXPECT_ARREQ(vecuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(vecullVar, 10u, 11u, 12u);
EXPECT_ARREQ(vecnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTest, OptionParseIntegralIndependentSequence)
{
// Attention: sdv::sequence<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"-i8var=-1,2, -3",*/ "-i16var=-2,3,-4", "-i32var=-3,4,-5", "-i64var=-4,5,-6",
"-ui8var=5,6,7", "-ui16var=6,7,8", "-ui32var=7,8,9", "-ui64var=8,9,10"};
CCommandLine cl;
//sdv::sequence<int8_t> seqi8Var; cl.DefineOption("i8var", seqi8Var, "sequence of int8_t variable");
sdv::sequence<int16_t> seqi16Var; cl.DefineOption("i16var", seqi16Var, "sequence of int16_t variable");
sdv::sequence<int32_t> seqi32Var; cl.DefineOption("i32var", seqi32Var, "sequence of int32_t variable");
sdv::sequence<int64_t> seqi64Var; cl.DefineOption("i64var", seqi64Var, "sequence of int64_t variable");
sdv::sequence<uint8_t> sequi8Var; cl.DefineOption("ui8var", sequi8Var, "sequence of uint8_t variable");
sdv::sequence<uint16_t> sequi16Var; cl.DefineOption("ui16var", sequi16Var, "sequence of uint16_t variable");
sdv::sequence<uint32_t> sequi32Var; cl.DefineOption("ui32var", sequi32Var, "sequence of uint32_t variable");
sdv::sequence<uint64_t> sequi64Var; cl.DefineOption("ui64var", sequi64Var, "sequence of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(seqi8Var, -1, 2, -3);
EXPECT_ARREQ(seqi16Var, -2, 3, -4);
EXPECT_ARREQ(seqi32Var, -3, 4, -5);
EXPECT_ARREQ(seqi64Var, -4, 5, -6);
EXPECT_ARREQ(sequi8Var, 5u, 6u, 7u);
EXPECT_ARREQ(sequi16Var, 6u, 7u, 8u);
EXPECT_ARREQ(sequi32Var, 7u, 8u, 9u);
EXPECT_ARREQ(sequi64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTest, OptionParseIntegralDedependentSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "-cvar=-1,2,-3", "-svar=-2,3,-4", "-lvar=-3,4,-5", "-ivar=-4,5,-6", "-llvar=-5,6,-7",
"-ucvar=6,7,8", "-usvar=7,8,9", "-ulvar=8,9,10", "-uivar=9,10,11", "-ullvar=10,11,12", "-nvar=11,12,13"};
CCommandLine cl;
sdv::sequence<signed char> seqcVar; cl.DefineOption("cvar", seqcVar, "sequence of char variable");
sdv::sequence<short> seqsVar; cl.DefineOption("svar", seqsVar, "sequence of short variable");
sdv::sequence<long> seqlVar; cl.DefineOption("lvar", seqlVar, "sequence of long variable");
sdv::sequence<int> seqiVar; cl.DefineOption("ivar", seqiVar, "sequence of int variable");
sdv::sequence<long long> seqllVar; cl.DefineOption("llvar", seqllVar, "sequence of long long variable");
sdv::sequence<unsigned char> sequcVar; cl.DefineOption("ucvar", sequcVar, "sequence of unsigned char variable");
sdv::sequence<unsigned short> sequsVar; cl.DefineOption("usvar", sequsVar, "sequence of unsigned short variable");
sdv::sequence<unsigned long> sequlVar; cl.DefineOption("ulvar", sequlVar, "sequence of unsigned long variable");
sdv::sequence<unsigned int> sequiVar; cl.DefineOption("uivar", sequiVar, "sequence of unsigned int variable");
sdv::sequence<unsigned long long> sequllVar; cl.DefineOption("ullvar", sequllVar, "sequence of unsigned long long variable");
sdv::sequence<size_t> seqnVar; cl.DefineOption("nvar", seqnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqcVar, -1, 2, -3);
EXPECT_ARREQ(seqsVar, -2, 3, -4);
EXPECT_ARREQ(seqlVar, -3, 4, -5);
EXPECT_ARREQ(seqiVar, -4, 5, -6);
EXPECT_ARREQ(seqllVar, -5, 6, -7);
EXPECT_ARREQ(sequcVar, 6u, 7u, 8u);
EXPECT_ARREQ(sequsVar, 7u, 8u, 9u);
EXPECT_ARREQ(sequlVar, 8u, 9u, 10u);
EXPECT_ARREQ(sequiVar, 9u, 10u, 11u);
EXPECT_ARREQ(sequllVar, 10u, 11u, 12u);
EXPECT_ARREQ(seqnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTest, OptionParseIntegralIndependentList)
{
// Attention: std::list<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"-i8var=-1,2, -3",*/ "-i16var=-2,3,-4", "-i32var=-3,4,-5", "-i64var=-4,5,-6",
"-ui8var=5,6,7", "-ui16var=6,7,8", "-ui32var=7,8,9", "-ui64var=8,9,10"};
CCommandLine cl;
//std::list<int8_t> lsti8Var; cl.DefineOption("i8var", lsti8Var, "list of int8_t variable");
std::list<int16_t> lsti16Var; cl.DefineOption("i16var", lsti16Var, "list of int16_t variable");
std::list<int32_t> lsti32Var; cl.DefineOption("i32var", lsti32Var, "list of int32_t variable");
std::list<int64_t> lsti64Var; cl.DefineOption("i64var", lsti64Var, "list of int64_t variable");
std::list<uint8_t> lstui8Var; cl.DefineOption("ui8var", lstui8Var, "list of uint8_t variable");
std::list<uint16_t> lstui16Var; cl.DefineOption("ui16var", lstui16Var, "list of uint16_t variable");
std::list<uint32_t> lstui32Var; cl.DefineOption("ui32var", lstui32Var, "list of uint32_t variable");
std::list<uint64_t> lstui64Var; cl.DefineOption("ui64var", lstui64Var, "list of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(lsti8Var, -1, 2, -3);
EXPECT_ARREQ(lsti16Var, -2, 3, -4);
EXPECT_ARREQ(lsti32Var, -3, 4, -5);
EXPECT_ARREQ(lsti64Var, -4, 5, -6);
EXPECT_ARREQ(lstui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(lstui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(lstui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(lstui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTest, OptionParseIntegralDedependentList)
{
const char* rgszCommandLine[] = {"this_exe.app", "-cvar=-1,2,-3", "-svar=-2,3,-4", "-lvar=-3,4,-5", "-ivar=-4,5,-6", "-llvar=-5,6,-7",
"-ucvar=6,7,8", "-usvar=7,8,9", "-ulvar=8,9,10", "-uivar=9,10,11", "-ullvar=10,11,12", "-nvar=11,12,13"};
CCommandLine cl;
std::list<signed char> lstcVar; cl.DefineOption("cvar", lstcVar, "list of char variable");
std::list<short> lstsVar; cl.DefineOption("svar", lstsVar, "list of short variable");
std::list<long> lstlVar; cl.DefineOption("lvar", lstlVar, "list of long variable");
std::list<int> lstiVar; cl.DefineOption("ivar", lstiVar, "list of int variable");
std::list<long long> lstllVar; cl.DefineOption("llvar", lstllVar, "list of long long variable");
std::list<unsigned char> lstucVar; cl.DefineOption("ucvar", lstucVar, "list of unsigned char variable");
std::list<unsigned short> lstusVar; cl.DefineOption("usvar", lstusVar, "list of unsigned short variable");
std::list<unsigned long> lstulVar; cl.DefineOption("ulvar", lstulVar, "list of unsigned long variable");
std::list<unsigned int> lstuiVar; cl.DefineOption("uivar", lstuiVar, "list of unsigned int variable");
std::list<unsigned long long> lstullVar; cl.DefineOption("ullvar", lstullVar, "list of unsigned long long variable");
std::list<size_t> lstnVar; cl.DefineOption("nvar", lstnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstcVar, -1, 2, -3);
EXPECT_ARREQ(lstsVar, -2, 3, -4);
EXPECT_ARREQ(lstlVar, -3, 4, -5);
EXPECT_ARREQ(lstiVar, -4, 5, -6);
EXPECT_ARREQ(lstllVar, -5, 6, -7);
EXPECT_ARREQ(lstucVar, 6u, 7u, 8u);
EXPECT_ARREQ(lstusVar, 7u, 8u, 9u);
EXPECT_ARREQ(lstulVar, 8u, 9u, 10u);
EXPECT_ARREQ(lstuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(lstullVar, 10u, 11u, 12u);
EXPECT_ARREQ(lstnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTest, OptionParseFloatingPoint)
{
const char* rgszCommandLine[] = {"this_exe.app", "-fvar=-12345.6789", "-dvar=12345678.9E10", "-ldvar=0.12345678E-5"};
CCommandLine cl;
float fVar = 0; cl.DefineOption("fvar", fVar, "float variable");
double dVar = 0; cl.DefineOption("dvar", dVar, "double variable");
long double ldVar = 0; cl.DefineOption("ldvar", ldVar, "long double variable");
float fControl = 123.456f; cl.DefineOption("fcontrol", fControl, "float no change!");
double dControl = 456.789; cl.DefineOption("dcontrol", dControl, "double no change!");
long double ldControl = 876.543; cl.DefineOption("ldcontrol", ldControl, "long double no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_FPEQ(fVar, -12345.6789f);
EXPECT_FPEQ(dVar, 12345678.9E10);
#ifndef __GNUC__ // Long double is not well supported by G++ compiler
EXPECT_FPEQ(ldVar, 0.12345678E-5);
#endif
EXPECT_FPEQ(fControl, 123.456f);
EXPECT_FPEQ(dControl, 456.789);
EXPECT_FPEQ(ldControl, 876.543);
}
TEST_F(CCommandLineParserTest, OptionParseFloatingPointVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "-fvar=-12345.6789,9876.54321,134679", "-dvar=12345678.9E10,1098765.43E21", "-ldvar=0.12345678E-5,0.87654321E9"};
CCommandLine cl;
std::vector<float> vecfVar; cl.DefineOption("fvar", vecfVar, "vector of float variable");
std::vector<double> vecdVar; cl.DefineOption("dvar", vecdVar, "vector of double variable");
std::vector<long double> vecldVar; cl.DefineOption("ldvar", vecldVar, "vector of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(vecdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(vecldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTest, OptionParseFloatingPointSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "-fvar=-12345.6789,9876.54321,134679", "-dvar=12345678.9E10,1098765.43E21", "-ldvar=0.12345678E-5,0.87654321E9"};
CCommandLine cl;
sdv::sequence<float> seqfVar; cl.DefineOption("fvar", seqfVar, "sequence of float variable");
sdv::sequence<double> seqdVar; cl.DefineOption("dvar", seqdVar, "sequence of double variable");
sdv::sequence<long double> seqldVar; cl.DefineOption("ldvar", seqldVar, "sequence of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(seqdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(seqldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTest, OptionParseFloatingPointList)
{
const char* rgszCommandLine[] = {"this_exe.app", "-fvar=-12345.6789,9876.54321,134679", "-dvar=12345678.9E10,1098765.43E21", "-ldvar=0.12345678E-5,0.87654321E9"};
CCommandLine cl;
std::list<float> lstfVar; cl.DefineOption("fvar", lstfVar, "list of float variable");
std::list<double> lstdVar; cl.DefineOption("dvar", lstdVar, "list of double variable");
std::list<long double> lstldVar; cl.DefineOption("ldvar", lstldVar, "list of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(lstdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(lstldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTest, OptionParseEnum)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "-unscoped_enum=test2", "-scoped_enum=test5"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
EUnscopedTest eUnscopedTest = test1; cl.DefineOption("unscoped_enum", eUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedTest = EScopedTest::test4; cl.DefineOption("scoped_enum", eScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EUnscopedTest eUnscopedControl = test1; cl.DefineOption("unscoped_enum_control", eUnscopedControl, "unscoped enum no change!").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedControl = EScopedTest::test4; cl.DefineOption("scoped_enum_control", eScopedControl, "scoped enum no change!").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(eUnscopedTest, test2);
EXPECT_EQ(eScopedTest, EScopedTest::test5);
EXPECT_EQ(eUnscopedControl, test1);
EXPECT_EQ(eScopedControl, EScopedTest::test4);
}
TEST_F(CCommandLineParserTest, OptionParseEnumVector)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "-unscoped_enum=test2,test3", "-scoped_enum=test5,test6"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::vector<EUnscopedTest> vecUnscopedTest; cl.DefineOption("unscoped_enum", vecUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::vector<EScopedTest> vecScopedTest; cl.DefineOption("scoped_enum", vecScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecUnscopedTest, test2, test3);
EXPECT_ARREQ(vecScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTest, OptionParseEnumSequence)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "-unscoped_enum=test2,test3", "-scoped_enum=test5,test6"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
sdv::sequence<EUnscopedTest> seqUnscopedTest; cl.DefineOption("unscoped_enum", seqUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
sdv::sequence<EScopedTest> seqScopedTest; cl.DefineOption("scoped_enum", seqScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqUnscopedTest, test2, test3);
EXPECT_ARREQ(seqScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTest, OptionParseEnumList)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "-unscoped_enum=test2,test3", "-scoped_enum=test5,test6"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::list<EUnscopedTest> lstUnscopedTest; cl.DefineOption("unscoped_enum", lstUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::list<EScopedTest> lstScopedTest; cl.DefineOption("scoped_enum", lstScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstUnscopedTest, test2, test3);
EXPECT_ARREQ(lstScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTest, OptionParseString)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1=test_a", "-ssu8var1=test_b", "-ssvar2=\"test_c\"",
"-ssu8var2=\"test_d\""};
CCommandLine cl;
std::string ssVar1; cl.DefineOption("ssvar1", ssVar1, "std::string variable");
sdv::u8string ssu8Var1; cl.DefineOption("ssu8var1", ssu8Var1, "sdv::u8string variable");
std::string ssVar2; cl.DefineOption("ssvar2", ssVar2, "sdv::string variable");
sdv::u8string ssu8Var2; cl.DefineOption("ssu8var2", ssu8Var2, "sdv::u8string variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(ssVar1, "test_a");
EXPECT_EQ(ssu8Var1, "test_b");
EXPECT_EQ(ssVar2, "test_c");
EXPECT_EQ(ssu8Var2, "test_d");
}
TEST_F(CCommandLineParserTest, OptionParseStringVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1=test_a,test_b", "-ssu8var1=test_b,test_c", "-ssvar2=\"test_c\",\"test_d\"",
"-ssu8var2=\"test_d\",\"test_e\""};
CCommandLine cl;
std::vector<std::string> vecssVar1; cl.DefineOption("ssvar1", vecssVar1, "std::vector<std::string> variable");
std::vector<sdv::u8string> vecssu8Var1; cl.DefineOption("ssu8var1", vecssu8Var1, "std::vector<sdv::u8string> variable");
std::vector<std::string> vecssVar2; cl.DefineOption("ssvar2", vecssVar2, "std::vector<sdv::string> variable");
std::vector<sdv::u8string> vecssu8Var2; cl.DefineOption("ssu8var2", vecssu8Var2, "std::vector<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecssVar1, "test_a", "test_b");
EXPECT_ARREQ(vecssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(vecssVar2, "test_c", "test_d");
EXPECT_ARREQ(vecssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTest, OptionParseStringSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1=test_a,test_b", "-ssu8var1=test_b,test_c", "-ssvar2=\"test_c\",\"test_d\"",
"-ssu8var2=\"test_d\",\"test_e\""};
CCommandLine cl;
sdv::sequence<std::string> seqssVar1; cl.DefineOption("ssvar1", seqssVar1, "sdv::sequence<std::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var1; cl.DefineOption("ssu8var1", seqssu8Var1, "sdv::sequence<sdv::u8string> variable");
sdv::sequence<std::string> seqssVar2; cl.DefineOption("ssvar2", seqssVar2, "sdv::sequence<sdv::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var2; cl.DefineOption("ssu8var2", seqssu8Var2, "sdv::sequence<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqssVar1, "test_a", "test_b");
EXPECT_ARREQ(seqssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(seqssVar2, "test_c", "test_d");
EXPECT_ARREQ(seqssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTest, OptionParseStringList)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1=test_a,test_b", "-ssu8var1=test_b,test_c", "-ssvar2=\"test_c\",\"test_d\"",
"-ssu8var2=\"test_d\",\"test_e\""};
CCommandLine cl;
std::list<std::string> lstssVar1; cl.DefineOption("ssvar1", lstssVar1, "std::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var1; cl.DefineOption("ssu8var1", lstssu8Var1, "std::list<sdv::u8string> variable");
std::list<std::string> lstssVar2; cl.DefineOption("ssvar2", lstssVar2, "std::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var2; cl.DefineOption("ssu8var2", lstssu8Var2, "std::list<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstssVar1, "test_a", "test_b");
EXPECT_ARREQ(lstssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(lstssVar2, "test_c", "test_d");
EXPECT_ARREQ(lstssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTest, OptionParsePath)
{
const char* rgszCommandLine[] = {"this_exe.app", "-pathvar1=abc.def", "-pathvar2=\"ghi.jkl\""};
CCommandLine cl;
std::filesystem::path pathVar1; cl.DefineOption("pathvar1", pathVar1, "std::filesystem::path variable");
std::filesystem::path pathVar2; cl.DefineOption("pathvar2", pathVar2, "std::filesystem::path variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(pathVar1, "abc.def");
EXPECT_EQ(pathVar2, "ghi.jkl");
}
TEST_F(CCommandLineParserTest, OptionParsePathVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "-pathvar1=abc.def,ghi.jkl", "-pathvar2=\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl;
std::vector<std::filesystem::path> vecpathVar1; cl.DefineOption("pathvar1", vecpathVar1, "std::vector<std::filesystem::path> variable");
std::vector<std::filesystem::path> vecpathVar2; cl.DefineOption("pathvar2", vecpathVar2, "std::vector<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(vecpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTest, OptionParsePathSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "-pathvar1=abc.def,ghi.jkl", "-pathvar2=\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl;
sdv::sequence<std::filesystem::path> seqpathVar1; cl.DefineOption("pathvar1", seqpathVar1, "sdv::sequence<std::filesystem::path> variable");
sdv::sequence<std::filesystem::path> seqpathVar2; cl.DefineOption("pathvar2", seqpathVar2, "sdv::sequence<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(seqpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTest, OptionParsePathList)
{
const char* rgszCommandLine[] = {"this_exe.app", "-pathvar1=abc.def,ghi.jkl", "-pathvar2=\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl;
std::list<std::filesystem::path> lstpathVar1; cl.DefineOption("pathvar1", lstpathVar1, "std::list<std::filesystem::path> variable");
std::list<std::filesystem::path> lstpathVar2; cl.DefineOption("pathvar2", lstpathVar2, "std::list<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(lstpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTest, OptionParseFlags)
{
const char* rgszCommandLine[] = {"this_exe.app", "-flag_neg+", "-flag_pos-"};
CCommandLine cl;
bool bFlagNeg = false; cl.DefineFlagOption("flag_neg", bFlagNeg, "negative flag variable");
bool bFlagPos = true; cl.DefineFlagOption("flag_pos", bFlagPos, "positive flag variable");
bool bFlagNegControl = false; cl.DefineFlagOption("controlflag_neg", bFlagNegControl, "negative flag variable");
bool bFlagPosControl = true; cl.DefineFlagOption("control_flag_pos", bFlagPosControl, "positive flag variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bFlagNeg);
EXPECT_FALSE(bFlagPos);
EXPECT_FALSE(bFlagNegControl);
EXPECT_TRUE(bFlagPosControl);
}

View File

@@ -0,0 +1,557 @@
#include "../../include/gtest_custom.h"
#include "commandline_parser_test.h"
#include "../../../global/cmdlnparser/cmdlnparser.h"
using CCommandLineParserTestAssignmentNextArg = CCommandLineParserTest;
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseBoolean)
{
const char* rgszCommandLine[] = {"this_exe.app", "-select"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
bool bSelect = false; cl.DefineOption("select", bSelect, "Select it!");
bool bControlNegative = false; cl.DefineOption("neg_control", bControlNegative, "No change!");
bool bControlPositive = true; cl.DefineOption("pos_control", bControlPositive, "No change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bSelect);
EXPECT_FALSE(bControlNegative);
EXPECT_TRUE(bControlPositive);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseIntegralIndependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "-i8var", "-1", "-i16var", "-2", "-i32var", "-3", "-i64var", "-4",
"-ui8var", "5", "-ui16var", "6", "-ui32var", "7", "-ui64var", "8"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
int8_t i8Var = 0; cl.DefineOption("i8var", i8Var, "int8_t variable");
int16_t i16Var = 0; cl.DefineOption("i16var", i16Var, "int16_t variable");
int32_t i32Var = 0; cl.DefineOption("i32var", i32Var, "int32_t variable");
int64_t i64Var = 0; cl.DefineOption("i64var", i64Var, "int64_t variable");
uint8_t ui8Var = 0; cl.DefineOption("ui8var", ui8Var, "uint8_t variable");
uint16_t ui16Var = 0; cl.DefineOption("ui16var", ui16Var, "uint16_t variable");
uint32_t ui32Var = 0; cl.DefineOption("ui32var", ui32Var, "uint32_t variable");
uint64_t ui64Var = 0; cl.DefineOption("ui64var", ui64Var, "uint64_t variable");
int8_t i8Control = -10; cl.DefineOption("i8control", i8Control, "int8_t no change!");
int16_t i16Control = -20; cl.DefineOption("i16control", i16Control, "int16_t no change!");
int32_t i32Control = -30; cl.DefineOption("i32control", i32Control, "int32_t no change!");
int64_t i64Control = -40; cl.DefineOption("i64control", i64Control, "int64_t no change!");
uint8_t ui8Control = 50; cl.DefineOption("ui8control", ui8Control, "uint8_t no change!");
uint16_t ui16Control = 60; cl.DefineOption("ui16control", ui16Control, "uint16_t no change!");
uint32_t ui32Control = 70; cl.DefineOption("ui32control", ui32Control, "uint32_t no change!");
uint64_t ui64Control = 80; cl.DefineOption("ui64control", ui64Control, "uint64_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(i8Var, -1);
EXPECT_EQ(i16Var, -2);
EXPECT_EQ(i32Var, -3);
EXPECT_EQ(i64Var, -4);
EXPECT_EQ(ui8Var, 5u);
EXPECT_EQ(ui16Var, 6u);
EXPECT_EQ(ui32Var, 7u);
EXPECT_EQ(ui64Var, 8u);
EXPECT_EQ(i8Control, -10);
EXPECT_EQ(i16Control, -20);
EXPECT_EQ(i32Control, -30);
EXPECT_EQ(i64Control, -40);
EXPECT_EQ(ui8Control, 50u);
EXPECT_EQ(ui16Control, 60u);
EXPECT_EQ(ui32Control, 70u);
EXPECT_EQ(ui64Control, 80u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseIntegralDedependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "-cvar", "-1", "-svar", "-2", "-lvar", "-3", "-ivar", "-4", "-llvar", "-5",
"-ucvar", "6", "-usvar", "7", "-ulvar", "8", "-uivar", "9", "-ullvar", "10", "-nvar", "11"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
signed char cVar = 0; cl.DefineOption("cvar", cVar, "char variable");
short sVar = 0; cl.DefineOption("svar", sVar, "short variable");
long lVar = 0; cl.DefineOption("lvar", lVar, "long variable");
int iVar = 0; cl.DefineOption("ivar", iVar, "int variable");
long long llVar = 0; cl.DefineOption("llvar", llVar, "long long variable");
unsigned char ucVar = 0; cl.DefineOption("ucvar", ucVar, "unsigned char variable");
unsigned short usVar = 0; cl.DefineOption("usvar", usVar, "unsigned short variable");
unsigned long ulVar = 0; cl.DefineOption("ulvar", ulVar, "unsigned long variable");
unsigned int uiVar = 0; cl.DefineOption("uivar", uiVar, "unsigned int variable");
unsigned long long ullVar = 0; cl.DefineOption("ullvar", ullVar, "unsigned long long variable");
size_t nVar = 0; cl.DefineOption("nvar", nVar, "size_t variable");
signed char cControl = -10; cl.DefineOption("ccontrol", cControl, "char no change!");
short sControl = -20; cl.DefineOption("scontrol", sControl, "short no change!");
long lControl = -30; cl.DefineOption("lcontrol", lControl, "long no change!");
int iControl = -40; cl.DefineOption("icontrol", iControl, "int no change!");
long long llControl = -50; cl.DefineOption("llcontrol", llControl, "long long no change!");
unsigned char ucControl = 60; cl.DefineOption("uccontrol", ucControl, "unsigned char no change!");
unsigned short usControl = 70; cl.DefineOption("uscontrol", usControl, "unsigned short no change!");
unsigned long ulControl = 80; cl.DefineOption("ulcontrol", ulControl, "unsigned long no change!");
unsigned int uiControl = 90; cl.DefineOption("uicontrol", uiControl, "unsigned int no change!");
unsigned long long ullControl = 100; cl.DefineOption("ullcontrol", ullControl, "unsigned long long no change!");
size_t nControl = 110; cl.DefineOption("ncontrol", nControl, "size_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(cVar, -1);
EXPECT_EQ(sVar, -2);
EXPECT_EQ(lVar, -3);
EXPECT_EQ(iVar, -4);
EXPECT_EQ(llVar, -5);
EXPECT_EQ(ucVar, 6u);
EXPECT_EQ(usVar, 7u);
EXPECT_EQ(ulVar, 8u);
EXPECT_EQ(uiVar, 9u);
EXPECT_EQ(ullVar, 10u);
EXPECT_EQ(nVar, 11u);
EXPECT_EQ(cControl, -10);
EXPECT_EQ(sControl, -20);
EXPECT_EQ(lControl, -30);
EXPECT_EQ(iControl, -40);
EXPECT_EQ(llControl, -50);
EXPECT_EQ(ucControl, 60u);
EXPECT_EQ(usControl, 70u);
EXPECT_EQ(ulControl, 80u);
EXPECT_EQ(uiControl, 90u);
EXPECT_EQ(ullControl, 100u);
EXPECT_EQ(nControl, 110u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseIntegralIndependentVector)
{
// Attention: std::vector<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"-i8var", "-1,2, -3",*/ "-i16var", "-2,3,-4", "-i32var", "-3,4,-5", "-i64var", "-4,5,-6",
"-ui8var", "5,6,7", "-ui16var", "6,7,8", "-ui32var", "7,8,9", "-ui64var", "8,9,10"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
//std::vector<int8_t> veci8Var; cl.DefineOption("i8var", veci8Var, "vector of int8_t variable");
std::vector<int16_t> veci16Var; cl.DefineOption("i16var", veci16Var, "vector of int16_t variable");
std::vector<int32_t> veci32Var; cl.DefineOption("i32var", veci32Var, "vector of int32_t variable");
std::vector<int64_t> veci64Var; cl.DefineOption("i64var", veci64Var, "vector of int64_t variable");
std::vector<uint8_t> vecui8Var; cl.DefineOption("ui8var", vecui8Var, "vector of uint8_t variable");
std::vector<uint16_t> vecui16Var; cl.DefineOption("ui16var", vecui16Var, "vector of uint16_t variable");
std::vector<uint32_t> vecui32Var; cl.DefineOption("ui32var", vecui32Var, "vector of uint32_t variable");
std::vector<uint64_t> vecui64Var; cl.DefineOption("ui64var", vecui64Var, "vector of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(veci8Var, -1, 2, -3);
EXPECT_ARREQ(veci16Var, -2, 3, -4);
EXPECT_ARREQ(veci32Var, -3, 4, -5);
EXPECT_ARREQ(veci64Var, -4, 5, -6);
EXPECT_ARREQ(vecui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(vecui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(vecui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(vecui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseIntegralDedependentVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "-cvar", "-1,2,-3", "-svar", "-2,3,-4", "-lvar", "-3,4,-5", "-ivar", "-4,5,-6", "-llvar", "-5,6,-7",
"-ucvar", "6,7,8", "-usvar", "7,8,9", "-ulvar", "8,9,10", "-uivar", "9,10,11", "-ullvar", "10,11,12", "-nvar", "11,12,13"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::vector<signed char> veccVar; cl.DefineOption("cvar", veccVar, "vector of char variable");
std::vector<short> vecsVar; cl.DefineOption("svar", vecsVar, "vector of short variable");
std::vector<long> veclVar; cl.DefineOption("lvar", veclVar, "vector of long variable");
std::vector<int> veciVar; cl.DefineOption("ivar", veciVar, "vector of int variable");
std::vector<long long> vecllVar; cl.DefineOption("llvar", vecllVar, "vector of long long variable");
std::vector<unsigned char> vecucVar; cl.DefineOption("ucvar", vecucVar, "vector of unsigned char variable");
std::vector<unsigned short> vecusVar; cl.DefineOption("usvar", vecusVar, "vector of unsigned short variable");
std::vector<unsigned long> veculVar; cl.DefineOption("ulvar", veculVar, "vector of unsigned long variable");
std::vector<unsigned int> vecuiVar; cl.DefineOption("uivar", vecuiVar, "vector of unsigned int variable");
std::vector<unsigned long long> vecullVar; cl.DefineOption("ullvar", vecullVar, "vector of unsigned long long variable");
std::vector<size_t> vecnVar; cl.DefineOption("nvar", vecnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(veccVar, -1, 2, -3);
EXPECT_ARREQ(vecsVar, -2, 3, -4);
EXPECT_ARREQ(veclVar, -3, 4, -5);
EXPECT_ARREQ(veciVar, -4, 5, -6);
EXPECT_ARREQ(vecllVar, -5, 6, -7);
EXPECT_ARREQ(vecucVar, 6u, 7u, 8u);
EXPECT_ARREQ(vecusVar, 7u, 8u, 9u);
EXPECT_ARREQ(veculVar, 8u, 9u, 10u);
EXPECT_ARREQ(vecuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(vecullVar, 10u, 11u, 12u);
EXPECT_ARREQ(vecnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseIntegralIndependentSequence)
{
// Attention: sdv::sequence<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"-i8var", "-1,2, -3",*/ "-i16var", "-2,3,-4", "-i32var", "-3,4,-5", "-i64var", "-4,5,-6",
"-ui8var", "5,6,7", "-ui16var", "6,7,8", "-ui32var", "7,8,9", "-ui64var", "8,9,10"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
//sdv::sequence<int8_t> seqi8Var; cl.DefineOption("i8var", seqi8Var, "sequence of int8_t variable");
sdv::sequence<int16_t> seqi16Var; cl.DefineOption("i16var", seqi16Var, "sequence of int16_t variable");
sdv::sequence<int32_t> seqi32Var; cl.DefineOption("i32var", seqi32Var, "sequence of int32_t variable");
sdv::sequence<int64_t> seqi64Var; cl.DefineOption("i64var", seqi64Var, "sequence of int64_t variable");
sdv::sequence<uint8_t> sequi8Var; cl.DefineOption("ui8var", sequi8Var, "sequence of uint8_t variable");
sdv::sequence<uint16_t> sequi16Var; cl.DefineOption("ui16var", sequi16Var, "sequence of uint16_t variable");
sdv::sequence<uint32_t> sequi32Var; cl.DefineOption("ui32var", sequi32Var, "sequence of uint32_t variable");
sdv::sequence<uint64_t> sequi64Var; cl.DefineOption("ui64var", sequi64Var, "sequence of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(seqi8Var, -1, 2, -3);
EXPECT_ARREQ(seqi16Var, -2, 3, -4);
EXPECT_ARREQ(seqi32Var, -3, 4, -5);
EXPECT_ARREQ(seqi64Var, -4, 5, -6);
EXPECT_ARREQ(sequi8Var, 5u, 6u, 7u);
EXPECT_ARREQ(sequi16Var, 6u, 7u, 8u);
EXPECT_ARREQ(sequi32Var, 7u, 8u, 9u);
EXPECT_ARREQ(sequi64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseIntegralDedependentSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "-cvar", "-1,2,-3", "-svar", "-2,3,-4", "-lvar", "-3,4,-5", "-ivar", "-4,5,-6", "-llvar", "-5,6,-7",
"-ucvar", "6,7,8", "-usvar", "7,8,9", "-ulvar", "8,9,10", "-uivar", "9,10,11", "-ullvar", "10,11,12", "-nvar", "11,12,13"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
sdv::sequence<signed char> seqcVar; cl.DefineOption("cvar", seqcVar, "sequence of char variable");
sdv::sequence<short> seqsVar; cl.DefineOption("svar", seqsVar, "sequence of short variable");
sdv::sequence<long> seqlVar; cl.DefineOption("lvar", seqlVar, "sequence of long variable");
sdv::sequence<int> seqiVar; cl.DefineOption("ivar", seqiVar, "sequence of int variable");
sdv::sequence<long long> seqllVar; cl.DefineOption("llvar", seqllVar, "sequence of long long variable");
sdv::sequence<unsigned char> sequcVar; cl.DefineOption("ucvar", sequcVar, "sequence of unsigned char variable");
sdv::sequence<unsigned short> sequsVar; cl.DefineOption("usvar", sequsVar, "sequence of unsigned short variable");
sdv::sequence<unsigned long> sequlVar; cl.DefineOption("ulvar", sequlVar, "sequence of unsigned long variable");
sdv::sequence<unsigned int> sequiVar; cl.DefineOption("uivar", sequiVar, "sequence of unsigned int variable");
sdv::sequence<unsigned long long> sequllVar; cl.DefineOption("ullvar", sequllVar, "sequence of unsigned long long variable");
sdv::sequence<size_t> seqnVar; cl.DefineOption("nvar", seqnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqcVar, -1, 2, -3);
EXPECT_ARREQ(seqsVar, -2, 3, -4);
EXPECT_ARREQ(seqlVar, -3, 4, -5);
EXPECT_ARREQ(seqiVar, -4, 5, -6);
EXPECT_ARREQ(seqllVar, -5, 6, -7);
EXPECT_ARREQ(sequcVar, 6u, 7u, 8u);
EXPECT_ARREQ(sequsVar, 7u, 8u, 9u);
EXPECT_ARREQ(sequlVar, 8u, 9u, 10u);
EXPECT_ARREQ(sequiVar, 9u, 10u, 11u);
EXPECT_ARREQ(sequllVar, 10u, 11u, 12u);
EXPECT_ARREQ(seqnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseIntegralIndependentList)
{
// Attention: std::list<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"-i8var", "-1,2, -3",*/ "-i16var", "-2,3,-4", "-i32var", "-3,4,-5", "-i64var", "-4,5,-6",
"-ui8var", "5,6,7", "-ui16var", "6,7,8", "-ui32var", "7,8,9", "-ui64var", "8,9,10"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
//std::list<int8_t> lsti8Var; cl.DefineOption("i8var", lsti8Var, "list of int8_t variable");
std::list<int16_t> lsti16Var; cl.DefineOption("i16var", lsti16Var, "list of int16_t variable");
std::list<int32_t> lsti32Var; cl.DefineOption("i32var", lsti32Var, "list of int32_t variable");
std::list<int64_t> lsti64Var; cl.DefineOption("i64var", lsti64Var, "list of int64_t variable");
std::list<uint8_t> lstui8Var; cl.DefineOption("ui8var", lstui8Var, "list of uint8_t variable");
std::list<uint16_t> lstui16Var; cl.DefineOption("ui16var", lstui16Var, "list of uint16_t variable");
std::list<uint32_t> lstui32Var; cl.DefineOption("ui32var", lstui32Var, "list of uint32_t variable");
std::list<uint64_t> lstui64Var; cl.DefineOption("ui64var", lstui64Var, "list of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(lsti8Var, -1, 2, -3);
EXPECT_ARREQ(lsti16Var, -2, 3, -4);
EXPECT_ARREQ(lsti32Var, -3, 4, -5);
EXPECT_ARREQ(lsti64Var, -4, 5, -6);
EXPECT_ARREQ(lstui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(lstui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(lstui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(lstui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseIntegralDedependentList)
{
const char* rgszCommandLine[] = {"this_exe.app", "-cvar", "-1,2,-3", "-svar", "-2,3,-4", "-lvar", "-3,4,-5", "-ivar", "-4,5,-6", "-llvar", "-5,6,-7",
"-ucvar", "6,7,8", "-usvar", "7,8,9", "-ulvar", "8,9,10", "-uivar", "9,10,11", "-ullvar", "10,11,12", "-nvar", "11,12,13"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::list<signed char> lstcVar; cl.DefineOption("cvar", lstcVar, "list of char variable");
std::list<short> lstsVar; cl.DefineOption("svar", lstsVar, "list of short variable");
std::list<long> lstlVar; cl.DefineOption("lvar", lstlVar, "list of long variable");
std::list<int> lstiVar; cl.DefineOption("ivar", lstiVar, "list of int variable");
std::list<long long> lstllVar; cl.DefineOption("llvar", lstllVar, "list of long long variable");
std::list<unsigned char> lstucVar; cl.DefineOption("ucvar", lstucVar, "list of unsigned char variable");
std::list<unsigned short> lstusVar; cl.DefineOption("usvar", lstusVar, "list of unsigned short variable");
std::list<unsigned long> lstulVar; cl.DefineOption("ulvar", lstulVar, "list of unsigned long variable");
std::list<unsigned int> lstuiVar; cl.DefineOption("uivar", lstuiVar, "list of unsigned int variable");
std::list<unsigned long long> lstullVar; cl.DefineOption("ullvar", lstullVar, "list of unsigned long long variable");
std::list<size_t> lstnVar; cl.DefineOption("nvar", lstnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstcVar, -1, 2, -3);
EXPECT_ARREQ(lstsVar, -2, 3, -4);
EXPECT_ARREQ(lstlVar, -3, 4, -5);
EXPECT_ARREQ(lstiVar, -4, 5, -6);
EXPECT_ARREQ(lstllVar, -5, 6, -7);
EXPECT_ARREQ(lstucVar, 6u, 7u, 8u);
EXPECT_ARREQ(lstusVar, 7u, 8u, 9u);
EXPECT_ARREQ(lstulVar, 8u, 9u, 10u);
EXPECT_ARREQ(lstuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(lstullVar, 10u, 11u, 12u);
EXPECT_ARREQ(lstnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseFloatingPoint)
{
const char* rgszCommandLine[] = {"this_exe.app", "-fvar", "-12345.6789", "-dvar", "12345678.9E10", "-ldvar", "0.12345678E-5"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
float fVar = 0; cl.DefineOption("fvar", fVar, "float variable");
double dVar = 0; cl.DefineOption("dvar", dVar, "double variable");
long double ldVar = 0; cl.DefineOption("ldvar", ldVar, "long double variable");
float fControl = 123.456f; cl.DefineOption("fcontrol", fControl, "float no change!");
double dControl = 456.789; cl.DefineOption("dcontrol", dControl, "double no change!");
long double ldControl = 876.543; cl.DefineOption("ldcontrol", ldControl, "long double no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_FPEQ(fVar, -12345.6789f);
EXPECT_FPEQ(dVar, 12345678.9E10);
#ifndef __GNUC__ // Long double is not well supported by G++ compiler
EXPECT_FPEQ(ldVar, 0.12345678E-5);
#endif
EXPECT_FPEQ(fControl, 123.456f);
EXPECT_FPEQ(dControl, 456.789);
EXPECT_FPEQ(ldControl, 876.543);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseFloatingPointVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "-fvar", "-12345.6789,9876.54321,134679", "-dvar", "12345678.9E10,1098765.43E21", "-ldvar", "0.12345678E-5,0.87654321E9"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::vector<float> vecfVar; cl.DefineOption("fvar", vecfVar, "vector of float variable");
std::vector<double> vecdVar; cl.DefineOption("dvar", vecdVar, "vector of double variable");
std::vector<long double> vecldVar; cl.DefineOption("ldvar", vecldVar, "vector of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(vecdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(vecldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseFloatingPointSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "-fvar", "-12345.6789,9876.54321,134679", "-dvar", "12345678.9E10,1098765.43E21", "-ldvar", "0.12345678E-5,0.87654321E9"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
sdv::sequence<float> seqfVar; cl.DefineOption("fvar", seqfVar, "sequence of float variable");
sdv::sequence<double> seqdVar; cl.DefineOption("dvar", seqdVar, "sequence of double variable");
sdv::sequence<long double> seqldVar; cl.DefineOption("ldvar", seqldVar, "sequence of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(seqdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(seqldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseFloatingPointList)
{
const char* rgszCommandLine[] = {"this_exe.app", "-fvar", "-12345.6789,9876.54321,134679", "-dvar", "12345678.9E10,1098765.43E21", "-ldvar", "0.12345678E-5,0.87654321E9"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::list<float> lstfVar; cl.DefineOption("fvar", lstfVar, "list of float variable");
std::list<double> lstdVar; cl.DefineOption("dvar", lstdVar, "list of double variable");
std::list<long double> lstldVar; cl.DefineOption("ldvar", lstldVar, "list of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(lstdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(lstldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseEnum)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "-unscoped_enum", "test2", "-scoped_enum", "test5"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
EUnscopedTest eUnscopedTest = test1; cl.DefineOption("unscoped_enum", eUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedTest = EScopedTest::test4; cl.DefineOption("scoped_enum", eScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EUnscopedTest eUnscopedControl = test1; cl.DefineOption("unscoped_enum_control", eUnscopedControl, "unscoped enum no change!").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedControl = EScopedTest::test4; cl.DefineOption("scoped_enum_control", eScopedControl, "scoped enum no change!").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(eUnscopedTest, test2);
EXPECT_EQ(eScopedTest, EScopedTest::test5);
EXPECT_EQ(eUnscopedControl, test1);
EXPECT_EQ(eScopedControl, EScopedTest::test4);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseEnumVector)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "-unscoped_enum", "test2,test3", "-scoped_enum", "test5,test6"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::vector<EUnscopedTest> vecUnscopedTest; cl.DefineOption("unscoped_enum", vecUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::vector<EScopedTest> vecScopedTest; cl.DefineOption("scoped_enum", vecScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecUnscopedTest, test2, test3);
EXPECT_ARREQ(vecScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseEnumSequence)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "-unscoped_enum", "test2,test3", "-scoped_enum", "test5,test6"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
sdv::sequence<EUnscopedTest> seqUnscopedTest; cl.DefineOption("unscoped_enum", seqUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
sdv::sequence<EScopedTest> seqScopedTest; cl.DefineOption("scoped_enum", seqScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqUnscopedTest, test2, test3);
EXPECT_ARREQ(seqScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseEnumList)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "-unscoped_enum", "test2,test3", "-scoped_enum", "test5,test6"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::list<EUnscopedTest> lstUnscopedTest; cl.DefineOption("unscoped_enum", lstUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::list<EScopedTest> lstScopedTest; cl.DefineOption("scoped_enum", lstScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstUnscopedTest, test2, test3);
EXPECT_ARREQ(lstScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseString)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1", "test_a", "-ssu8var1", "test_b", "-ssvar2", "\"test_c\"",
"-ssu8var2", "\"test_d\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::string ssVar1; cl.DefineOption("ssvar1", ssVar1, "std::string variable");
sdv::u8string ssu8Var1; cl.DefineOption("ssu8var1", ssu8Var1, "sdv::u8string variable");
std::string ssVar2; cl.DefineOption("ssvar2", ssVar2, "sdv::string variable");
sdv::u8string ssu8Var2; cl.DefineOption("ssu8var2", ssu8Var2, "sdv::u8string variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(ssVar1, "test_a");
EXPECT_EQ(ssu8Var1, "test_b");
EXPECT_EQ(ssVar2, "test_c");
EXPECT_EQ(ssu8Var2, "test_d");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseStringVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1", "test_a,test_b", "-ssu8var1", "test_b,test_c", "-ssvar2", "\"test_c\",\"test_d\"",
"-ssu8var2", "\"test_d\",\"test_e\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::vector<std::string> vecssVar1; cl.DefineOption("ssvar1", vecssVar1, "std::vector<std::string> variable");
std::vector<sdv::u8string> vecssu8Var1; cl.DefineOption("ssu8var1", vecssu8Var1, "std::vector<sdv::u8string> variable");
std::vector<std::string> vecssVar2; cl.DefineOption("ssvar2", vecssVar2, "std::vector<sdv::string> variable");
std::vector<sdv::u8string> vecssu8Var2; cl.DefineOption("ssu8var2", vecssu8Var2, "std::vector<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecssVar1, "test_a", "test_b");
EXPECT_ARREQ(vecssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(vecssVar2, "test_c", "test_d");
EXPECT_ARREQ(vecssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseStringSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1", "test_a,test_b", "-ssu8var1", "test_b,test_c", "-ssvar2", "\"test_c\",\"test_d\"",
"-ssu8var2", "\"test_d\",\"test_e\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
sdv::sequence<std::string> seqssVar1; cl.DefineOption("ssvar1", seqssVar1, "sdv::sequence<std::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var1; cl.DefineOption("ssu8var1", seqssu8Var1, "sdv::sequence<sdv::u8string> variable");
sdv::sequence<std::string> seqssVar2; cl.DefineOption("ssvar2", seqssVar2, "sdv::sequence<sdv::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var2; cl.DefineOption("ssu8var2", seqssu8Var2, "sdv::sequence<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqssVar1, "test_a", "test_b");
EXPECT_ARREQ(seqssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(seqssVar2, "test_c", "test_d");
EXPECT_ARREQ(seqssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseStringList)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1", "test_a,test_b", "-ssu8var1", "test_b,test_c", "-ssvar2", "\"test_c\",\"test_d\"",
"-ssu8var2", "\"test_d\",\"test_e\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::list<std::string> lstssVar1; cl.DefineOption("ssvar1", lstssVar1, "std::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var1; cl.DefineOption("ssu8var1", lstssu8Var1, "std::list<sdv::u8string> variable");
std::list<std::string> lstssVar2; cl.DefineOption("ssvar2", lstssVar2, "std::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var2; cl.DefineOption("ssu8var2", lstssu8Var2, "std::list<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstssVar1, "test_a", "test_b");
EXPECT_ARREQ(lstssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(lstssVar2, "test_c", "test_d");
EXPECT_ARREQ(lstssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParsePath)
{
const char* rgszCommandLine[] = {"this_exe.app", "-pathvar1", "abc.def", "-pathvar2", "\"ghi.jkl\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::filesystem::path pathVar1; cl.DefineOption("pathvar1", pathVar1, "std::filesystem::path variable");
std::filesystem::path pathVar2; cl.DefineOption("pathvar2", pathVar2, "std::filesystem::path variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(pathVar1, "abc.def");
EXPECT_EQ(pathVar2, "ghi.jkl");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParsePathVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "-pathvar1", "abc.def,ghi.jkl", "-pathvar2", "\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::vector<std::filesystem::path> vecpathVar1; cl.DefineOption("pathvar1", vecpathVar1, "std::vector<std::filesystem::path> variable");
std::vector<std::filesystem::path> vecpathVar2; cl.DefineOption("pathvar2", vecpathVar2, "std::vector<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(vecpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParsePathSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "-pathvar1", "abc.def,ghi.jkl", "-pathvar2", "\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
sdv::sequence<std::filesystem::path> seqpathVar1; cl.DefineOption("pathvar1", seqpathVar1, "sdv::sequence<std::filesystem::path> variable");
sdv::sequence<std::filesystem::path> seqpathVar2; cl.DefineOption("pathvar2", seqpathVar2, "sdv::sequence<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(seqpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParsePathList)
{
const char* rgszCommandLine[] = {"this_exe.app", "-pathvar1", "abc.def,ghi.jkl", "-pathvar2", "\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::list<std::filesystem::path> lstpathVar1; cl.DefineOption("pathvar1", lstpathVar1, "std::list<std::filesystem::path> variable");
std::list<std::filesystem::path> lstpathVar2; cl.DefineOption("pathvar2", lstpathVar2, "std::list<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(lstpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, OptionParseFlags)
{
const char* rgszCommandLine[] = {"this_exe.app", "-flag_neg+", "-flag_pos-"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
bool bFlagNeg = false; cl.DefineFlagOption("flag_neg", bFlagNeg, "negative flag variable");
bool bFlagPos = true; cl.DefineFlagOption("flag_pos", bFlagPos, "positive flag variable");
bool bFlagNegControl = false; cl.DefineFlagOption("controlflag_neg", bFlagNegControl, "negative flag variable");
bool bFlagPosControl = true; cl.DefineFlagOption("control_flag_pos", bFlagPosControl, "positive flag variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bFlagNeg);
EXPECT_FALSE(bFlagPos);
EXPECT_FALSE(bFlagNegControl);
EXPECT_TRUE(bFlagPosControl);
}

View File

@@ -0,0 +1,600 @@
#include "../../include/gtest_custom.h"
#include "commandline_parser_test.h"
#include "../../../global/cmdlnparser/cmdlnparser.h"
using CCommandLineParserTestNoAssignment = CCommandLineParserTest;
TEST_F(CCommandLineParserTestNoAssignment, OptionParseBoolean)
{
const char* rgszCommandLine[] = {"this_exe.app", "-select"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
bool bSelect = false; cl.DefineOption("select", bSelect, "Select it!");
bool bControlNegative = false; cl.DefineOption("neg_control", bControlNegative, "No change!");
bool bControlPositive = true; cl.DefineOption("pos_control", bControlPositive, "No change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bSelect);
EXPECT_FALSE(bControlNegative);
EXPECT_TRUE(bControlPositive);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseIntegralIndependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "-i8var-1", "-i16var-2", "-i32var-3", "-i64var-4",
"-ui8var5", "-ui16var6", "-ui32var7", "-ui64var8"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
int8_t i8Var = 0; cl.DefineOption("i8var", i8Var, "int8_t variable");
int16_t i16Var = 0; cl.DefineOption("i16var", i16Var, "int16_t variable");
int32_t i32Var = 0; cl.DefineOption("i32var", i32Var, "int32_t variable");
int64_t i64Var = 0; cl.DefineOption("i64var", i64Var, "int64_t variable");
uint8_t ui8Var = 0; cl.DefineOption("ui8var", ui8Var, "uint8_t variable");
uint16_t ui16Var = 0; cl.DefineOption("ui16var", ui16Var, "uint16_t variable");
uint32_t ui32Var = 0; cl.DefineOption("ui32var", ui32Var, "uint32_t variable");
uint64_t ui64Var = 0; cl.DefineOption("ui64var", ui64Var, "uint64_t variable");
int8_t i8Control = -10; cl.DefineOption("i8control", i8Control, "int8_t no change!");
int16_t i16Control = -20; cl.DefineOption("i16control", i16Control, "int16_t no change!");
int32_t i32Control = -30; cl.DefineOption("i32control", i32Control, "int32_t no change!");
int64_t i64Control = -40; cl.DefineOption("i64control", i64Control, "int64_t no change!");
uint8_t ui8Control = 50; cl.DefineOption("ui8control", ui8Control, "uint8_t no change!");
uint16_t ui16Control = 60; cl.DefineOption("ui16control", ui16Control, "uint16_t no change!");
uint32_t ui32Control = 70; cl.DefineOption("ui32control", ui32Control, "uint32_t no change!");
uint64_t ui64Control = 80; cl.DefineOption("ui64control", ui64Control, "uint64_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(i8Var, -1);
EXPECT_EQ(i16Var, -2);
EXPECT_EQ(i32Var, -3);
EXPECT_EQ(i64Var, -4);
EXPECT_EQ(ui8Var, 5u);
EXPECT_EQ(ui16Var, 6u);
EXPECT_EQ(ui32Var, 7u);
EXPECT_EQ(ui64Var, 8u);
EXPECT_EQ(i8Control, -10);
EXPECT_EQ(i16Control, -20);
EXPECT_EQ(i32Control, -30);
EXPECT_EQ(i64Control, -40);
EXPECT_EQ(ui8Control, 50u);
EXPECT_EQ(ui16Control, 60u);
EXPECT_EQ(ui32Control, 70u);
EXPECT_EQ(ui64Control, 80u);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseIntegralDedependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "-cvar-1", "-svar-2", "-lvar-3", "-ivar-4", "-llvar-5",
"-ucvar6", "-usvar7", "-ulvar8", "-uivar9", "-ullvar10", "-nvar11"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
signed char cVar = 0; cl.DefineOption("cvar", cVar, "char variable");
short sVar = 0; cl.DefineOption("svar", sVar, "short variable");
long lVar = 0; cl.DefineOption("lvar", lVar, "long variable");
int iVar = 0; cl.DefineOption("ivar", iVar, "int variable");
long long llVar = 0; cl.DefineOption("llvar", llVar, "long long variable");
unsigned char ucVar = 0; cl.DefineOption("ucvar", ucVar, "unsigned char variable");
unsigned short usVar = 0; cl.DefineOption("usvar", usVar, "unsigned short variable");
unsigned long ulVar = 0; cl.DefineOption("ulvar", ulVar, "unsigned long variable");
unsigned int uiVar = 0; cl.DefineOption("uivar", uiVar, "unsigned int variable");
unsigned long long ullVar = 0; cl.DefineOption("ullvar", ullVar, "unsigned long long variable");
size_t nVar = 0; cl.DefineOption("nvar", nVar, "size_t variable");
signed char cControl = -10; cl.DefineOption("ccontrol", cControl, "char no change!");
short sControl = -20; cl.DefineOption("scontrol", sControl, "short no change!");
long lControl = -30; cl.DefineOption("lcontrol", lControl, "long no change!");
int iControl = -40; cl.DefineOption("icontrol", iControl, "int no change!");
long long llControl = -50; cl.DefineOption("llcontrol", llControl, "long long no change!");
unsigned char ucControl = 60; cl.DefineOption("uccontrol", ucControl, "unsigned char no change!");
unsigned short usControl = 70; cl.DefineOption("uscontrol", usControl, "unsigned short no change!");
unsigned long ulControl = 80; cl.DefineOption("ulcontrol", ulControl, "unsigned long no change!");
unsigned int uiControl = 90; cl.DefineOption("uicontrol", uiControl, "unsigned int no change!");
unsigned long long ullControl = 100; cl.DefineOption("ullcontrol", ullControl, "unsigned long long no change!");
size_t nControl = 110; cl.DefineOption("ncontrol", nControl, "size_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(cVar, -1);
EXPECT_EQ(sVar, -2);
EXPECT_EQ(lVar, -3);
EXPECT_EQ(iVar, -4);
EXPECT_EQ(llVar, -5);
EXPECT_EQ(ucVar, 6u);
EXPECT_EQ(usVar, 7u);
EXPECT_EQ(ulVar, 8u);
EXPECT_EQ(uiVar, 9u);
EXPECT_EQ(ullVar, 10u);
EXPECT_EQ(nVar, 11u);
EXPECT_EQ(cControl, -10);
EXPECT_EQ(sControl, -20);
EXPECT_EQ(lControl, -30);
EXPECT_EQ(iControl, -40);
EXPECT_EQ(llControl, -50);
EXPECT_EQ(ucControl, 60u);
EXPECT_EQ(usControl, 70u);
EXPECT_EQ(ulControl, 80u);
EXPECT_EQ(uiControl, 90u);
EXPECT_EQ(ullControl, 100u);
EXPECT_EQ(nControl, 110u);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseIntegralIndependentVector)
{
// Attention: std::vector<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"-i8var-1,2, -3",*/ "-i16var-2,3,-4", "-i32var-3,4,-5", "-i64var-4,5,-6",
"-ui8var5,6,7", "-ui16var6,7,8", "-ui32var7,8,9", "-ui64var8,9,10"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
//std::vector<int8_t> veci8Var; cl.DefineOption("i8var", veci8Var, "vector of int8_t variable");
std::vector<int16_t> veci16Var; cl.DefineOption("i16var", veci16Var, "vector of int16_t variable");
std::vector<int32_t> veci32Var; cl.DefineOption("i32var", veci32Var, "vector of int32_t variable");
std::vector<int64_t> veci64Var; cl.DefineOption("i64var", veci64Var, "vector of int64_t variable");
std::vector<uint8_t> vecui8Var; cl.DefineOption("ui8var", vecui8Var, "vector of uint8_t variable");
std::vector<uint16_t> vecui16Var; cl.DefineOption("ui16var", vecui16Var, "vector of uint16_t variable");
std::vector<uint32_t> vecui32Var; cl.DefineOption("ui32var", vecui32Var, "vector of uint32_t variable");
std::vector<uint64_t> vecui64Var; cl.DefineOption("ui64var", vecui64Var, "vector of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(veci8Var, -1, 2, -3);
EXPECT_ARREQ(veci16Var, -2, 3, -4);
EXPECT_ARREQ(veci32Var, -3, 4, -5);
EXPECT_ARREQ(veci64Var, -4, 5, -6);
EXPECT_ARREQ(vecui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(vecui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(vecui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(vecui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseIntegralDedependentVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "-cvar-1,2,-3", "-svar-2,3,-4", "-lvar-3,4,-5", "-ivar-4,5,-6", "-llvar-5,6,-7",
"-ucvar6,7,8", "-usvar7,8,9", "-ulvar8,9,10", "-uivar9,10,11", "-ullvar10,11,12", "-nvar11,12,13"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::vector<signed char> veccVar; cl.DefineOption("cvar", veccVar, "vector of char variable");
std::vector<short> vecsVar; cl.DefineOption("svar", vecsVar, "vector of short variable");
std::vector<long> veclVar; cl.DefineOption("lvar", veclVar, "vector of long variable");
std::vector<int> veciVar; cl.DefineOption("ivar", veciVar, "vector of int variable");
std::vector<long long> vecllVar; cl.DefineOption("llvar", vecllVar, "vector of long long variable");
std::vector<unsigned char> vecucVar; cl.DefineOption("ucvar", vecucVar, "vector of unsigned char variable");
std::vector<unsigned short> vecusVar; cl.DefineOption("usvar", vecusVar, "vector of unsigned short variable");
std::vector<unsigned long> veculVar; cl.DefineOption("ulvar", veculVar, "vector of unsigned long variable");
std::vector<unsigned int> vecuiVar; cl.DefineOption("uivar", vecuiVar, "vector of unsigned int variable");
std::vector<unsigned long long> vecullVar; cl.DefineOption("ullvar", vecullVar, "vector of unsigned long long variable");
std::vector<size_t> vecnVar; cl.DefineOption("nvar", vecnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(veccVar, -1, 2, -3);
EXPECT_ARREQ(vecsVar, -2, 3, -4);
EXPECT_ARREQ(veclVar, -3, 4, -5);
EXPECT_ARREQ(veciVar, -4, 5, -6);
EXPECT_ARREQ(vecllVar, -5, 6, -7);
EXPECT_ARREQ(vecucVar, 6u, 7u, 8u);
EXPECT_ARREQ(vecusVar, 7u, 8u, 9u);
EXPECT_ARREQ(veculVar, 8u, 9u, 10u);
EXPECT_ARREQ(vecuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(vecullVar, 10u, 11u, 12u);
EXPECT_ARREQ(vecnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseIntegralIndependentSequence)
{
// Attention: sdv::sequence<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"-i8var-1,2, -3",*/ "-i16var-2,3,-4", "-i32var-3,4,-5", "-i64var-4,5,-6",
"-ui8var5,6,7", "-ui16var6,7,8", "-ui32var7,8,9", "-ui64var8,9,10"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
//sdv::sequence<int8_t> seqi8Var; cl.DefineOption("i8var", seqi8Var, "sequence of int8_t variable");
sdv::sequence<int16_t> seqi16Var; cl.DefineOption("i16var", seqi16Var, "sequence of int16_t variable");
sdv::sequence<int32_t> seqi32Var; cl.DefineOption("i32var", seqi32Var, "sequence of int32_t variable");
sdv::sequence<int64_t> seqi64Var; cl.DefineOption("i64var", seqi64Var, "sequence of int64_t variable");
sdv::sequence<uint8_t> sequi8Var; cl.DefineOption("ui8var", sequi8Var, "sequence of uint8_t variable");
sdv::sequence<uint16_t> sequi16Var; cl.DefineOption("ui16var", sequi16Var, "sequence of uint16_t variable");
sdv::sequence<uint32_t> sequi32Var; cl.DefineOption("ui32var", sequi32Var, "sequence of uint32_t variable");
sdv::sequence<uint64_t> sequi64Var; cl.DefineOption("ui64var", sequi64Var, "sequence of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(seqi8Var, -1, 2, -3);
EXPECT_ARREQ(seqi16Var, -2, 3, -4);
EXPECT_ARREQ(seqi32Var, -3, 4, -5);
EXPECT_ARREQ(seqi64Var, -4, 5, -6);
EXPECT_ARREQ(sequi8Var, 5u, 6u, 7u);
EXPECT_ARREQ(sequi16Var, 6u, 7u, 8u);
EXPECT_ARREQ(sequi32Var, 7u, 8u, 9u);
EXPECT_ARREQ(sequi64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseIntegralDedependentSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "-cvar-1,2,-3", "-svar-2,3,-4", "-lvar-3,4,-5", "-ivar-4,5,-6", "-llvar-5,6,-7",
"-ucvar6,7,8", "-usvar7,8,9", "-ulvar8,9,10", "-uivar9,10,11", "-ullvar10,11,12", "-nvar11,12,13"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
sdv::sequence<signed char> seqcVar; cl.DefineOption("cvar", seqcVar, "sequence of char variable");
sdv::sequence<short> seqsVar; cl.DefineOption("svar", seqsVar, "sequence of short variable");
sdv::sequence<long> seqlVar; cl.DefineOption("lvar", seqlVar, "sequence of long variable");
sdv::sequence<int> seqiVar; cl.DefineOption("ivar", seqiVar, "sequence of int variable");
sdv::sequence<long long> seqllVar; cl.DefineOption("llvar", seqllVar, "sequence of long long variable");
sdv::sequence<unsigned char> sequcVar; cl.DefineOption("ucvar", sequcVar, "sequence of unsigned char variable");
sdv::sequence<unsigned short> sequsVar; cl.DefineOption("usvar", sequsVar, "sequence of unsigned short variable");
sdv::sequence<unsigned long> sequlVar; cl.DefineOption("ulvar", sequlVar, "sequence of unsigned long variable");
sdv::sequence<unsigned int> sequiVar; cl.DefineOption("uivar", sequiVar, "sequence of unsigned int variable");
sdv::sequence<unsigned long long> sequllVar; cl.DefineOption("ullvar", sequllVar, "sequence of unsigned long long variable");
sdv::sequence<size_t> seqnVar; cl.DefineOption("nvar", seqnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqcVar, -1, 2, -3);
EXPECT_ARREQ(seqsVar, -2, 3, -4);
EXPECT_ARREQ(seqlVar, -3, 4, -5);
EXPECT_ARREQ(seqiVar, -4, 5, -6);
EXPECT_ARREQ(seqllVar, -5, 6, -7);
EXPECT_ARREQ(sequcVar, 6u, 7u, 8u);
EXPECT_ARREQ(sequsVar, 7u, 8u, 9u);
EXPECT_ARREQ(sequlVar, 8u, 9u, 10u);
EXPECT_ARREQ(sequiVar, 9u, 10u, 11u);
EXPECT_ARREQ(sequllVar, 10u, 11u, 12u);
EXPECT_ARREQ(seqnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseIntegralIndependentList)
{
// Attention: std::list<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"-i8var-1,2, -3",*/ "-i16var-2,3,-4", "-i32var-3,4,-5", "-i64var-4,5,-6",
"-ui8var5,6,7", "-ui16var6,7,8", "-ui32var7,8,9", "-ui64var8,9,10"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
//std::list<int8_t> lsti8Var; cl.DefineOption("i8var", lsti8Var, "list of int8_t variable");
std::list<int16_t> lsti16Var; cl.DefineOption("i16var", lsti16Var, "list of int16_t variable");
std::list<int32_t> lsti32Var; cl.DefineOption("i32var", lsti32Var, "list of int32_t variable");
std::list<int64_t> lsti64Var; cl.DefineOption("i64var", lsti64Var, "list of int64_t variable");
std::list<uint8_t> lstui8Var; cl.DefineOption("ui8var", lstui8Var, "list of uint8_t variable");
std::list<uint16_t> lstui16Var; cl.DefineOption("ui16var", lstui16Var, "list of uint16_t variable");
std::list<uint32_t> lstui32Var; cl.DefineOption("ui32var", lstui32Var, "list of uint32_t variable");
std::list<uint64_t> lstui64Var; cl.DefineOption("ui64var", lstui64Var, "list of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(lsti8Var, -1, 2, -3);
EXPECT_ARREQ(lsti16Var, -2, 3, -4);
EXPECT_ARREQ(lsti32Var, -3, 4, -5);
EXPECT_ARREQ(lsti64Var, -4, 5, -6);
EXPECT_ARREQ(lstui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(lstui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(lstui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(lstui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseIntegralDedependentList)
{
const char* rgszCommandLine[] = {"this_exe.app", "-cvar-1,2,-3", "-svar-2,3,-4", "-lvar-3,4,-5", "-ivar-4,5,-6", "-llvar-5,6,-7",
"-ucvar6,7,8", "-usvar7,8,9", "-ulvar8,9,10", "-uivar9,10,11", "-ullvar10,11,12", "-nvar11,12,13"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::list<signed char> lstcVar; cl.DefineOption("cvar", lstcVar, "list of char variable");
std::list<short> lstsVar; cl.DefineOption("svar", lstsVar, "list of short variable");
std::list<long> lstlVar; cl.DefineOption("lvar", lstlVar, "list of long variable");
std::list<int> lstiVar; cl.DefineOption("ivar", lstiVar, "list of int variable");
std::list<long long> lstllVar; cl.DefineOption("llvar", lstllVar, "list of long long variable");
std::list<unsigned char> lstucVar; cl.DefineOption("ucvar", lstucVar, "list of unsigned char variable");
std::list<unsigned short> lstusVar; cl.DefineOption("usvar", lstusVar, "list of unsigned short variable");
std::list<unsigned long> lstulVar; cl.DefineOption("ulvar", lstulVar, "list of unsigned long variable");
std::list<unsigned int> lstuiVar; cl.DefineOption("uivar", lstuiVar, "list of unsigned int variable");
std::list<unsigned long long> lstullVar; cl.DefineOption("ullvar", lstullVar, "list of unsigned long long variable");
std::list<size_t> lstnVar; cl.DefineOption("nvar", lstnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstcVar, -1, 2, -3);
EXPECT_ARREQ(lstsVar, -2, 3, -4);
EXPECT_ARREQ(lstlVar, -3, 4, -5);
EXPECT_ARREQ(lstiVar, -4, 5, -6);
EXPECT_ARREQ(lstllVar, -5, 6, -7);
EXPECT_ARREQ(lstucVar, 6u, 7u, 8u);
EXPECT_ARREQ(lstusVar, 7u, 8u, 9u);
EXPECT_ARREQ(lstulVar, 8u, 9u, 10u);
EXPECT_ARREQ(lstuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(lstullVar, 10u, 11u, 12u);
EXPECT_ARREQ(lstnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseFloatingPoint)
{
const char* rgszCommandLine[] = {"this_exe.app", "-fvar-12345.6789", "-dvar12345678.9E10", "-ldvar0.12345678E-5"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
float fVar = 0; cl.DefineOption("fvar", fVar, "float variable");
double dVar = 0; cl.DefineOption("dvar", dVar, "double variable");
long double ldVar = 0; cl.DefineOption("ldvar", ldVar, "long double variable");
float fControl = 123.456f; cl.DefineOption("fcontrol", fControl, "float no change!");
double dControl = 456.789; cl.DefineOption("dcontrol", dControl, "double no change!");
long double ldControl = 876.543; cl.DefineOption("ldcontrol", ldControl, "long double no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_FPEQ(fVar, -12345.6789f);
EXPECT_FPEQ(dVar, 12345678.9E10);
#ifndef __GNUC__ // Long double is not well supported by G++ compiler
EXPECT_FPEQ(ldVar, 0.12345678E-5);
#endif
EXPECT_FPEQ(fControl, 123.456f);
EXPECT_FPEQ(dControl, 456.789);
EXPECT_FPEQ(ldControl, 876.543);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseFloatingPointVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "-fvar-12345.6789,9876.54321,134679", "-dvar12345678.9E10,1098765.43E21",
"-ldvar0.12345678E-5,0.87654321E9"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::vector<float> vecfVar; cl.DefineOption("fvar", vecfVar, "vector of float variable");
std::vector<double> vecdVar; cl.DefineOption("dvar", vecdVar, "vector of double variable");
std::vector<long double> vecldVar; cl.DefineOption("ldvar", vecldVar, "vector of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(vecdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(vecldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseFloatingPointSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "-fvar-12345.6789,9876.54321,134679", "-dvar12345678.9E10,1098765.43E21",
"-ldvar0.12345678E-5,0.87654321E9"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
sdv::sequence<float> seqfVar; cl.DefineOption("fvar", seqfVar, "sequence of float variable");
sdv::sequence<double> seqdVar; cl.DefineOption("dvar", seqdVar, "sequence of double variable");
sdv::sequence<long double> seqldVar; cl.DefineOption("ldvar", seqldVar, "sequence of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(seqdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(seqldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseFloatingPointList)
{
const char* rgszCommandLine[] = {"this_exe.app", "-fvar-12345.6789,9876.54321,134679", "-dvar12345678.9E10,1098765.43E21",
"-ldvar0.12345678E-5,0.87654321E9"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::list<float> lstfVar; cl.DefineOption("fvar", lstfVar, "list of float variable");
std::list<double> lstdVar; cl.DefineOption("dvar", lstdVar, "list of double variable");
std::list<long double> lstldVar; cl.DefineOption("ldvar", lstldVar, "list of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(lstdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(lstldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseEnum)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "-unscoped_enumtest2", "-scoped_enumtest5"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
EUnscopedTest eUnscopedTest = test1; cl.DefineOption("unscoped_enum", eUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedTest = EScopedTest::test4; cl.DefineOption("scoped_enum", eScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EUnscopedTest eUnscopedControl = test1; cl.DefineOption("unscoped_enum_control", eUnscopedControl, "unscoped enum no change!").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedControl = EScopedTest::test4; cl.DefineOption("scoped_enum_control", eScopedControl, "scoped enum no change!").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(eUnscopedTest, test2);
EXPECT_EQ(eScopedTest, EScopedTest::test5);
EXPECT_EQ(eUnscopedControl, test1);
EXPECT_EQ(eScopedControl, EScopedTest::test4);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseEnumVector)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "-unscoped_enumtest2,test3", "-scoped_enumtest5,test6"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::vector<EUnscopedTest> vecUnscopedTest; cl.DefineOption("unscoped_enum", vecUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::vector<EScopedTest> vecScopedTest; cl.DefineOption("scoped_enum", vecScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecUnscopedTest, test2, test3);
EXPECT_ARREQ(vecScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseEnumSequence)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "-unscoped_enumtest2,test3", "-scoped_enumtest5,test6"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
sdv::sequence<EUnscopedTest> seqUnscopedTest; cl.DefineOption("unscoped_enum", seqUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
sdv::sequence<EScopedTest> seqScopedTest; cl.DefineOption("scoped_enum", seqScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqUnscopedTest, test2, test3);
EXPECT_ARREQ(seqScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseEnumList)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "-unscoped_enumtest2,test3", "-scoped_enumtest5,test6"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::list<EUnscopedTest> lstUnscopedTest; cl.DefineOption("unscoped_enum", lstUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::list<EScopedTest> lstScopedTest; cl.DefineOption("scoped_enum", lstScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstUnscopedTest, test2, test3);
EXPECT_ARREQ(lstScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseString)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1test_a", "-ssu8var1test_b", "-ssvar2\"test_c\"",
"-ssu8var2\"test_d\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::string ssVar1; cl.DefineOption("ssvar1", ssVar1, "std::string variable");
sdv::u8string ssu8Var1; cl.DefineOption("ssu8var1", ssu8Var1, "sdv::u8string variable");
std::string ssVar2; cl.DefineOption("ssvar2", ssVar2, "sdv::string variable");
sdv::u8string ssu8Var2; cl.DefineOption("ssu8var2", ssu8Var2, "sdv::u8string variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(ssVar1, "test_a");
EXPECT_EQ(ssu8Var1, "test_b");
EXPECT_EQ(ssVar2, "test_c");
EXPECT_EQ(ssu8Var2, "test_d");
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseStringVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1test_a,test_b", "-ssu8var1test_b,test_c",
"-ssvar2\"test_c\",\"test_d\"", "-ssu8var2\"test_d\",\"test_e\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::vector<std::string> vecssVar1; cl.DefineOption("ssvar1", vecssVar1, "std::vector<std::string> variable");
std::vector<sdv::u8string> vecssu8Var1; cl.DefineOption("ssu8var1", vecssu8Var1, "std::vector<sdv::u8string> variable");
std::vector<std::string> vecssVar2; cl.DefineOption("ssvar2", vecssVar2, "std::vector<sdv::string> variable");
std::vector<sdv::u8string> vecssu8Var2; cl.DefineOption("ssu8var2", vecssu8Var2, "std::vector<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecssVar1, "test_a", "test_b");
EXPECT_ARREQ(vecssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(vecssVar2, "test_c", "test_d");
EXPECT_ARREQ(vecssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseStringSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1test_a,test_b", "-ssu8var1test_b,test_c", "-ssvar2\"test_c\",\"test_d\"",
"-ssu8var2\"test_d\",\"test_e\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
sdv::sequence<std::string> seqssVar1; cl.DefineOption("ssvar1", seqssVar1, "sdv::sequence<std::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var1; cl.DefineOption("ssu8var1", seqssu8Var1, "sdv::sequence<sdv::u8string> variable");
sdv::sequence<std::string> seqssVar2; cl.DefineOption("ssvar2", seqssVar2, "sdv::sequence<sdv::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var2; cl.DefineOption("ssu8var2", seqssu8Var2, "sdv::sequence<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqssVar1, "test_a", "test_b");
EXPECT_ARREQ(seqssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(seqssVar2, "test_c", "test_d");
EXPECT_ARREQ(seqssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseStringList)
{
const char* rgszCommandLine[] = {"this_exe.app", "-ssvar1test_a,test_b", "-ssu8var1test_b,test_c", "-ssvar2\"test_c\",\"test_d\"",
"-ssu8var2\"test_d\",\"test_e\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::list<std::string> lstssVar1; cl.DefineOption("ssvar1", lstssVar1, "std::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var1; cl.DefineOption("ssu8var1", lstssu8Var1, "std::list<sdv::u8string> variable");
std::list<std::string> lstssVar2; cl.DefineOption("ssvar2", lstssVar2, "std::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var2; cl.DefineOption("ssu8var2", lstssu8Var2, "std::list<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstssVar1, "test_a", "test_b");
EXPECT_ARREQ(lstssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(lstssVar2, "test_c", "test_d");
EXPECT_ARREQ(lstssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParsePath)
{
const char* rgszCommandLine[] = {"this_exe.app", "-pathvar1abc.def", "-pathvar2\"ghi.jkl\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::filesystem::path pathVar1; cl.DefineOption("pathvar1", pathVar1, "std::filesystem::path variable");
std::filesystem::path pathVar2; cl.DefineOption("pathvar2", pathVar2, "std::filesystem::path variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(pathVar1, "abc.def");
EXPECT_EQ(pathVar2, "ghi.jkl");
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParsePathVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "-pathvar1abc.def,ghi.jkl", "-pathvar2\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::vector<std::filesystem::path> vecpathVar1; cl.DefineOption("pathvar1", vecpathVar1, "std::vector<std::filesystem::path> variable");
std::vector<std::filesystem::path> vecpathVar2; cl.DefineOption("pathvar2", vecpathVar2, "std::vector<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(vecpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParsePathSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "-pathvar1abc.def,ghi.jkl", "-pathvar2\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
sdv::sequence<std::filesystem::path> seqpathVar1; cl.DefineOption("pathvar1", seqpathVar1, "sdv::sequence<std::filesystem::path> variable");
sdv::sequence<std::filesystem::path> seqpathVar2; cl.DefineOption("pathvar2", seqpathVar2, "sdv::sequence<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(seqpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParsePathList)
{
const char* rgszCommandLine[] = {"this_exe.app", "-pathvar1abc.def,ghi.jkl", "-pathvar2\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::list<std::filesystem::path> lstpathVar1; cl.DefineOption("pathvar1", lstpathVar1, "std::list<std::filesystem::path> variable");
std::list<std::filesystem::path> lstpathVar2; cl.DefineOption("pathvar2", lstpathVar2, "std::list<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(lstpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTestNoAssignment, OptionParseFlags)
{
const char* rgszCommandLine[] = {"this_exe.app", "-flag_neg+", "-flag_pos-"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
bool bFlagNeg = false; cl.DefineFlagOption("flag_neg", bFlagNeg, "negative flag variable");
bool bFlagPos = true; cl.DefineFlagOption("flag_pos", bFlagPos, "positive flag variable");
bool bFlagNegControl = false; cl.DefineFlagOption("controlflag_neg", bFlagNegControl, "negative flag variable");
bool bFlagPosControl = true; cl.DefineFlagOption("control_flag_pos", bFlagPosControl, "positive flag variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bFlagNeg);
EXPECT_FALSE(bFlagPos);
EXPECT_FALSE(bFlagNegControl);
EXPECT_TRUE(bFlagPosControl);
}
TEST_F(CCommandLineParserTestNoAssignment, OptionOverlappingArg)
{
// Mixing up -server and -s
const char* rgszCommandLine1[] = {"this_exe.app", "-server"};
CCommandLine cl1(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
bool bSilence = false; cl1.DefineOption("s", bSilence, "silence flag");
bool bServer = false; cl1.DefineOption("server", bServer, "server enabled");
EXPECT_NO_THROW(cl1.Parse(std::extent<decltype(rgszCommandLine1)>::value, rgszCommandLine1));
EXPECT_FALSE(bSilence);
EXPECT_TRUE(bServer);
// Mixing up -instance<val> and -instance_a
const char* rgszCommandLine2[] = {"this_exe.app", "-instance_a"};
CCommandLine cl2(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::string ssInstance; cl2.DefineOption("instance", ssInstance, "Instance ID");
bool bInstance_a = false; cl2.DefineOption("instance_a", bInstance_a, "Instance A is activited");
EXPECT_NO_THROW(cl2.Parse(std::extent<decltype(rgszCommandLine2)>::value, rgszCommandLine2));
EXPECT_TRUE(ssInstance.empty());
EXPECT_TRUE(bInstance_a);
// Mixiong up -enable_opt+ and -enable_options
const char* rgszCommandLine3[] = {"this_exe.app", "-enable_options"};
CCommandLine cl3(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
bool bOptFlag = false; cl3.DefineOption("enable_opt", bOptFlag, "enable/disable one option");
bool bOptions = false; cl3.DefineOption("enable_options", bOptions, "enable all options");
EXPECT_NO_THROW(cl3.Parse(std::extent<decltype(rgszCommandLine3)>::value, rgszCommandLine3));
EXPECT_FALSE(bOptFlag);
EXPECT_TRUE(bOptions);
// Mixing up -server and -s when double assignment
const char* rgszCommandLine4[] = {"this_exe.app", "-s"};
CCommandLine cl4(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
bSilence = false; auto rSilenceOption = cl4.DefineSubOption("silence", bSilence, "silence flag");
rSilenceOption.AddOptionName("s");
bServer = false; cl4.DefineOption("server", bServer, "server enabled");
EXPECT_NO_THROW(cl4.Parse(std::extent<decltype(rgszCommandLine4)>::value, rgszCommandLine4));
EXPECT_TRUE(bSilence);
EXPECT_FALSE(bServer);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,544 @@
#include "../../include/gtest_custom.h"
#include "commandline_parser_test.h"
#include "../../../global/cmdlnparser/cmdlnparser.h"
TEST_F(CCommandLineParserTest, SubOptionParseBoolean)
{
const char* rgszCommandLine[] = {"this_exe.app", "--select"};
CCommandLine cl;
bool bSelect = false; cl.DefineSubOption("select", bSelect, "Select it!");
bool bControlNegative = false; cl.DefineSubOption("neg_control", bControlNegative, "No change!");
bool bControlPositive = true; cl.DefineSubOption("pos_control", bControlPositive, "No change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bSelect);
EXPECT_FALSE(bControlNegative);
EXPECT_TRUE(bControlPositive);
}
TEST_F(CCommandLineParserTest, SubOptionParseIntegralIndependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "--i8var=-1", "--i16var=-2", "--i32var=-3", "--i64var=-4",
"--ui8var=5", "--ui16var=6", "--ui32var=7", "--ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineSubOption("i8var", i8Var, "int8_t variable");
int16_t i16Var = 0; cl.DefineSubOption("i16var", i16Var, "int16_t variable");
int32_t i32Var = 0; cl.DefineSubOption("i32var", i32Var, "int32_t variable");
int64_t i64Var = 0; cl.DefineSubOption("i64var", i64Var, "int64_t variable");
uint8_t ui8Var = 0; cl.DefineSubOption("ui8var", ui8Var, "uint8_t variable");
uint16_t ui16Var = 0; cl.DefineSubOption("ui16var", ui16Var, "uint16_t variable");
uint32_t ui32Var = 0; cl.DefineSubOption("ui32var", ui32Var, "uint32_t variable");
uint64_t ui64Var = 0; cl.DefineSubOption("ui64var", ui64Var, "uint64_t variable");
int8_t i8Control = -10; cl.DefineSubOption("i8control", i8Control, "int8_t no change!");
int16_t i16Control = -20; cl.DefineSubOption("i16control", i16Control, "int16_t no change!");
int32_t i32Control = -30; cl.DefineSubOption("i32control", i32Control, "int32_t no change!");
int64_t i64Control = -40; cl.DefineSubOption("i64control", i64Control, "int64_t no change!");
uint8_t ui8Control = 50; cl.DefineSubOption("ui8control", ui8Control, "uint8_t no change!");
uint16_t ui16Control = 60; cl.DefineSubOption("ui16control", ui16Control, "uint16_t no change!");
uint32_t ui32Control = 70; cl.DefineSubOption("ui32control", ui32Control, "uint32_t no change!");
uint64_t ui64Control = 80; cl.DefineSubOption("ui64control", ui64Control, "uint64_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(i8Var, -1);
EXPECT_EQ(i16Var, -2);
EXPECT_EQ(i32Var, -3);
EXPECT_EQ(i64Var, -4);
EXPECT_EQ(ui8Var, 5u);
EXPECT_EQ(ui16Var, 6u);
EXPECT_EQ(ui32Var, 7u);
EXPECT_EQ(ui64Var, 8u);
EXPECT_EQ(i8Control, -10);
EXPECT_EQ(i16Control, -20);
EXPECT_EQ(i32Control, -30);
EXPECT_EQ(i64Control, -40);
EXPECT_EQ(ui8Control, 50u);
EXPECT_EQ(ui16Control, 60u);
EXPECT_EQ(ui32Control, 70u);
EXPECT_EQ(ui64Control, 80u);
}
TEST_F(CCommandLineParserTest, SubOptionParseIntegralDedependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar=-1", "--svar=-2", "--lvar=-3", "--ivar=-4", "--llvar=-5",
"--ucvar=6", "--usvar=7", "--ulvar=8", "--uivar=9", "--ullvar=10", "--nvar=11"};
CCommandLine cl;
signed char cVar = 0; cl.DefineSubOption("cvar", cVar, "char variable");
short sVar = 0; cl.DefineSubOption("svar", sVar, "short variable");
long lVar = 0; cl.DefineSubOption("lvar", lVar, "long variable");
int iVar = 0; cl.DefineSubOption("ivar", iVar, "int variable");
long long llVar = 0; cl.DefineSubOption("llvar", llVar, "long long variable");
unsigned char ucVar = 0; cl.DefineSubOption("ucvar", ucVar, "unsigned char variable");
unsigned short usVar = 0; cl.DefineSubOption("usvar", usVar, "unsigned short variable");
unsigned long ulVar = 0; cl.DefineSubOption("ulvar", ulVar, "unsigned long variable");
unsigned int uiVar = 0; cl.DefineSubOption("uivar", uiVar, "unsigned int variable");
unsigned long long ullVar = 0; cl.DefineSubOption("ullvar", ullVar, "unsigned long long variable");
size_t nVar = 0; cl.DefineSubOption("nvar", nVar, "size_t variable");
signed char cControl = -10; cl.DefineSubOption("ccontrol", cControl, "char no change!");
short sControl = -20; cl.DefineSubOption("scontrol", sControl, "short no change!");
long lControl = -30; cl.DefineSubOption("lcontrol", lControl, "long no change!");
int iControl = -40; cl.DefineSubOption("icontrol", iControl, "int no change!");
long long llControl = -50; cl.DefineSubOption("llcontrol", llControl, "long long no change!");
unsigned char ucControl = 60; cl.DefineSubOption("uccontrol", ucControl, "unsigned char no change!");
unsigned short usControl = 70; cl.DefineSubOption("uscontrol", usControl, "unsigned short no change!");
unsigned long ulControl = 80; cl.DefineSubOption("ulcontrol", ulControl, "unsigned long no change!");
unsigned int uiControl = 90; cl.DefineSubOption("uicontrol", uiControl, "unsigned int no change!");
unsigned long long ullControl = 100; cl.DefineSubOption("ullcontrol", ullControl, "unsigned long long no change!");
size_t nControl = 110; cl.DefineSubOption("ncontrol", nControl, "size_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(cVar, -1);
EXPECT_EQ(sVar, -2);
EXPECT_EQ(lVar, -3);
EXPECT_EQ(iVar, -4);
EXPECT_EQ(llVar, -5);
EXPECT_EQ(ucVar, 6u);
EXPECT_EQ(usVar, 7u);
EXPECT_EQ(ulVar, 8u);
EXPECT_EQ(uiVar, 9u);
EXPECT_EQ(ullVar, 10u);
EXPECT_EQ(nVar, 11u);
EXPECT_EQ(cControl, -10);
EXPECT_EQ(sControl, -20);
EXPECT_EQ(lControl, -30);
EXPECT_EQ(iControl, -40);
EXPECT_EQ(llControl, -50);
EXPECT_EQ(ucControl, 60u);
EXPECT_EQ(usControl, 70u);
EXPECT_EQ(ulControl, 80u);
EXPECT_EQ(uiControl, 90u);
EXPECT_EQ(ullControl, 100u);
EXPECT_EQ(nControl, 110u);
}
TEST_F(CCommandLineParserTest, SubOptionParseIntegralIndependentVector)
{
// Attention: std::vector<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"--i8var=-1,2, -3",*/ "--i16var=-2,3,-4", "--i32var=-3,4,-5", "--i64var=-4,5,-6",
"--ui8var=5,6,7", "--ui16var=6,7,8", "--ui32var=7,8,9", "--ui64var=8,9,10"};
CCommandLine cl;
//std::vector<int8_t> veci8Var; cl.DefineSubOption("i8var", veci8Var, "vector of int8_t variable");
std::vector<int16_t> veci16Var; cl.DefineSubOption("i16var", veci16Var, "vector of int16_t variable");
std::vector<int32_t> veci32Var; cl.DefineSubOption("i32var", veci32Var, "vector of int32_t variable");
std::vector<int64_t> veci64Var; cl.DefineSubOption("i64var", veci64Var, "vector of int64_t variable");
std::vector<uint8_t> vecui8Var; cl.DefineSubOption("ui8var", vecui8Var, "vector of uint8_t variable");
std::vector<uint16_t> vecui16Var; cl.DefineSubOption("ui16var", vecui16Var, "vector of uint16_t variable");
std::vector<uint32_t> vecui32Var; cl.DefineSubOption("ui32var", vecui32Var, "vector of uint32_t variable");
std::vector<uint64_t> vecui64Var; cl.DefineSubOption("ui64var", vecui64Var, "vector of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(veci8Var, -1, 2, -3);
EXPECT_ARREQ(veci16Var, -2, 3, -4);
EXPECT_ARREQ(veci32Var, -3, 4, -5);
EXPECT_ARREQ(veci64Var, -4, 5, -6);
EXPECT_ARREQ(vecui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(vecui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(vecui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(vecui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTest, SubOptionParseIntegralDedependentVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar=-1,2,-3", "--svar=-2,3,-4", "--lvar=-3,4,-5", "--ivar=-4,5,-6", "--llvar=-5,6,-7",
"--ucvar=6,7,8", "--usvar=7,8,9", "--ulvar=8,9,10", "--uivar=9,10,11", "--ullvar=10,11,12", "--nvar=11,12,13"};
CCommandLine cl;
std::vector<signed char> veccVar; cl.DefineSubOption("cvar", veccVar, "vector of char variable");
std::vector<short> vecsVar; cl.DefineSubOption("svar", vecsVar, "vector of short variable");
std::vector<long> veclVar; cl.DefineSubOption("lvar", veclVar, "vector of long variable");
std::vector<int> veciVar; cl.DefineSubOption("ivar", veciVar, "vector of int variable");
std::vector<long long> vecllVar; cl.DefineSubOption("llvar", vecllVar, "vector of long long variable");
std::vector<unsigned char> vecucVar; cl.DefineSubOption("ucvar", vecucVar, "vector of unsigned char variable");
std::vector<unsigned short> vecusVar; cl.DefineSubOption("usvar", vecusVar, "vector of unsigned short variable");
std::vector<unsigned long> veculVar; cl.DefineSubOption("ulvar", veculVar, "vector of unsigned long variable");
std::vector<unsigned int> vecuiVar; cl.DefineSubOption("uivar", vecuiVar, "vector of unsigned int variable");
std::vector<unsigned long long> vecullVar; cl.DefineSubOption("ullvar", vecullVar, "vector of unsigned long long variable");
std::vector<size_t> vecnVar; cl.DefineSubOption("nvar", vecnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(veccVar, -1, 2, -3);
EXPECT_ARREQ(vecsVar, -2, 3, -4);
EXPECT_ARREQ(veclVar, -3, 4, -5);
EXPECT_ARREQ(veciVar, -4, 5, -6);
EXPECT_ARREQ(vecllVar, -5, 6, -7);
EXPECT_ARREQ(vecucVar, 6u, 7u, 8u);
EXPECT_ARREQ(vecusVar, 7u, 8u, 9u);
EXPECT_ARREQ(veculVar, 8u, 9u, 10u);
EXPECT_ARREQ(vecuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(vecullVar, 10u, 11u, 12u);
EXPECT_ARREQ(vecnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTest, SubOptionParseIntegralIndependentSequence)
{
// Attention: sdv::sequence<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"--i8var=-1,2, -3",*/ "--i16var=-2,3,-4", "--i32var=-3,4,-5", "--i64var=-4,5,-6",
"--ui8var=5,6,7", "--ui16var=6,7,8", "--ui32var=7,8,9", "--ui64var=8,9,10"};
CCommandLine cl;
//sdv::sequence<int8_t> seqi8Var; cl.DefineSubOption("i8var", seqi8Var, "sequence of int8_t variable");
sdv::sequence<int16_t> seqi16Var; cl.DefineSubOption("i16var", seqi16Var, "sequence of int16_t variable");
sdv::sequence<int32_t> seqi32Var; cl.DefineSubOption("i32var", seqi32Var, "sequence of int32_t variable");
sdv::sequence<int64_t> seqi64Var; cl.DefineSubOption("i64var", seqi64Var, "sequence of int64_t variable");
sdv::sequence<uint8_t> sequi8Var; cl.DefineSubOption("ui8var", sequi8Var, "sequence of uint8_t variable");
sdv::sequence<uint16_t> sequi16Var; cl.DefineSubOption("ui16var", sequi16Var, "sequence of uint16_t variable");
sdv::sequence<uint32_t> sequi32Var; cl.DefineSubOption("ui32var", sequi32Var, "sequence of uint32_t variable");
sdv::sequence<uint64_t> sequi64Var; cl.DefineSubOption("ui64var", sequi64Var, "sequence of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(seqi8Var, -1, 2, -3);
EXPECT_ARREQ(seqi16Var, -2, 3, -4);
EXPECT_ARREQ(seqi32Var, -3, 4, -5);
EXPECT_ARREQ(seqi64Var, -4, 5, -6);
EXPECT_ARREQ(sequi8Var, 5u, 6u, 7u);
EXPECT_ARREQ(sequi16Var, 6u, 7u, 8u);
EXPECT_ARREQ(sequi32Var, 7u, 8u, 9u);
EXPECT_ARREQ(sequi64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTest, SubOptionParseIntegralDedependentSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar=-1,2,-3", "--svar=-2,3,-4", "--lvar=-3,4,-5", "--ivar=-4,5,-6", "--llvar=-5,6,-7",
"--ucvar=6,7,8", "--usvar=7,8,9", "--ulvar=8,9,10", "--uivar=9,10,11", "--ullvar=10,11,12", "--nvar=11,12,13"};
CCommandLine cl;
sdv::sequence<signed char> seqcVar; cl.DefineSubOption("cvar", seqcVar, "sequence of char variable");
sdv::sequence<short> seqsVar; cl.DefineSubOption("svar", seqsVar, "sequence of short variable");
sdv::sequence<long> seqlVar; cl.DefineSubOption("lvar", seqlVar, "sequence of long variable");
sdv::sequence<int> seqiVar; cl.DefineSubOption("ivar", seqiVar, "sequence of int variable");
sdv::sequence<long long> seqllVar; cl.DefineSubOption("llvar", seqllVar, "sequence of long long variable");
sdv::sequence<unsigned char> sequcVar; cl.DefineSubOption("ucvar", sequcVar, "sequence of unsigned char variable");
sdv::sequence<unsigned short> sequsVar; cl.DefineSubOption("usvar", sequsVar, "sequence of unsigned short variable");
sdv::sequence<unsigned long> sequlVar; cl.DefineSubOption("ulvar", sequlVar, "sequence of unsigned long variable");
sdv::sequence<unsigned int> sequiVar; cl.DefineSubOption("uivar", sequiVar, "sequence of unsigned int variable");
sdv::sequence<unsigned long long> sequllVar; cl.DefineSubOption("ullvar", sequllVar, "sequence of unsigned long long variable");
sdv::sequence<size_t> seqnVar; cl.DefineSubOption("nvar", seqnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqcVar, -1, 2, -3);
EXPECT_ARREQ(seqsVar, -2, 3, -4);
EXPECT_ARREQ(seqlVar, -3, 4, -5);
EXPECT_ARREQ(seqiVar, -4, 5, -6);
EXPECT_ARREQ(seqllVar, -5, 6, -7);
EXPECT_ARREQ(sequcVar, 6u, 7u, 8u);
EXPECT_ARREQ(sequsVar, 7u, 8u, 9u);
EXPECT_ARREQ(sequlVar, 8u, 9u, 10u);
EXPECT_ARREQ(sequiVar, 9u, 10u, 11u);
EXPECT_ARREQ(sequllVar, 10u, 11u, 12u);
EXPECT_ARREQ(seqnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTest, SubOptionParseIntegralIndependentList)
{
// Attention: std::list<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"--i8var=-1,2, -3",*/ "--i16var=-2,3,-4", "--i32var=-3,4,-5", "--i64var=-4,5,-6",
"--ui8var=5,6,7", "--ui16var=6,7,8", "--ui32var=7,8,9", "--ui64var=8,9,10"};
CCommandLine cl;
//std::list<int8_t> lsti8Var; cl.DefineSubOption("i8var", lsti8Var, "list of int8_t variable");
std::list<int16_t> lsti16Var; cl.DefineSubOption("i16var", lsti16Var, "list of int16_t variable");
std::list<int32_t> lsti32Var; cl.DefineSubOption("i32var", lsti32Var, "list of int32_t variable");
std::list<int64_t> lsti64Var; cl.DefineSubOption("i64var", lsti64Var, "list of int64_t variable");
std::list<uint8_t> lstui8Var; cl.DefineSubOption("ui8var", lstui8Var, "list of uint8_t variable");
std::list<uint16_t> lstui16Var; cl.DefineSubOption("ui16var", lstui16Var, "list of uint16_t variable");
std::list<uint32_t> lstui32Var; cl.DefineSubOption("ui32var", lstui32Var, "list of uint32_t variable");
std::list<uint64_t> lstui64Var; cl.DefineSubOption("ui64var", lstui64Var, "list of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(lsti8Var, -1, 2, -3);
EXPECT_ARREQ(lsti16Var, -2, 3, -4);
EXPECT_ARREQ(lsti32Var, -3, 4, -5);
EXPECT_ARREQ(lsti64Var, -4, 5, -6);
EXPECT_ARREQ(lstui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(lstui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(lstui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(lstui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTest, SubOptionParseIntegralDedependentList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar=-1,2,-3", "--svar=-2,3,-4", "--lvar=-3,4,-5", "--ivar=-4,5,-6", "--llvar=-5,6,-7",
"--ucvar=6,7,8", "--usvar=7,8,9", "--ulvar=8,9,10", "--uivar=9,10,11", "--ullvar=10,11,12", "--nvar=11,12,13"};
CCommandLine cl;
std::list<signed char> lstcVar; cl.DefineSubOption("cvar", lstcVar, "list of char variable");
std::list<short> lstsVar; cl.DefineSubOption("svar", lstsVar, "list of short variable");
std::list<long> lstlVar; cl.DefineSubOption("lvar", lstlVar, "list of long variable");
std::list<int> lstiVar; cl.DefineSubOption("ivar", lstiVar, "list of int variable");
std::list<long long> lstllVar; cl.DefineSubOption("llvar", lstllVar, "list of long long variable");
std::list<unsigned char> lstucVar; cl.DefineSubOption("ucvar", lstucVar, "list of unsigned char variable");
std::list<unsigned short> lstusVar; cl.DefineSubOption("usvar", lstusVar, "list of unsigned short variable");
std::list<unsigned long> lstulVar; cl.DefineSubOption("ulvar", lstulVar, "list of unsigned long variable");
std::list<unsigned int> lstuiVar; cl.DefineSubOption("uivar", lstuiVar, "list of unsigned int variable");
std::list<unsigned long long> lstullVar; cl.DefineSubOption("ullvar", lstullVar, "list of unsigned long long variable");
std::list<size_t> lstnVar; cl.DefineSubOption("nvar", lstnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstcVar, -1, 2, -3);
EXPECT_ARREQ(lstsVar, -2, 3, -4);
EXPECT_ARREQ(lstlVar, -3, 4, -5);
EXPECT_ARREQ(lstiVar, -4, 5, -6);
EXPECT_ARREQ(lstllVar, -5, 6, -7);
EXPECT_ARREQ(lstucVar, 6u, 7u, 8u);
EXPECT_ARREQ(lstusVar, 7u, 8u, 9u);
EXPECT_ARREQ(lstulVar, 8u, 9u, 10u);
EXPECT_ARREQ(lstuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(lstullVar, 10u, 11u, 12u);
EXPECT_ARREQ(lstnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTest, SubOptionParseFloatingPoint)
{
const char* rgszCommandLine[] = {"this_exe.app", "--fvar=-12345.6789", "--dvar=12345678.9E10", "--ldvar=0.12345678E-5"};
CCommandLine cl;
float fVar = 0; cl.DefineSubOption("fvar", fVar, "float variable");
double dVar = 0; cl.DefineSubOption("dvar", dVar, "double variable");
long double ldVar = 0; cl.DefineSubOption("ldvar", ldVar, "long double variable");
float fControl = 123.456f; cl.DefineSubOption("fcontrol", fControl, "float no change!");
double dControl = 456.789; cl.DefineSubOption("dcontrol", dControl, "double no change!");
long double ldControl = 876.543; cl.DefineSubOption("ldcontrol", ldControl, "long double no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_FPEQ(fVar, -12345.6789f);
EXPECT_FPEQ(dVar, 12345678.9E10);
#ifndef __GNUC__ // Long double is not well supported by G++ compiler
EXPECT_FPEQ(ldVar, 0.12345678E-5);
#endif
EXPECT_FPEQ(fControl, 123.456f);
EXPECT_FPEQ(dControl, 456.789);
EXPECT_FPEQ(ldControl, 876.543);
}
TEST_F(CCommandLineParserTest, SubOptionParseFloatingPointVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "--fvar=-12345.6789,9876.54321,134679", "--dvar=12345678.9E10,1098765.43E21", "--ldvar=0.12345678E-5,0.87654321E9"};
CCommandLine cl;
std::vector<float> vecfVar; cl.DefineSubOption("fvar", vecfVar, "vector of float variable");
std::vector<double> vecdVar; cl.DefineSubOption("dvar", vecdVar, "vector of double variable");
std::vector<long double> vecldVar; cl.DefineSubOption("ldvar", vecldVar, "vector of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(vecdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(vecldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTest, SubOptionParseFloatingPointSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "--fvar=-12345.6789,9876.54321,134679", "--dvar=12345678.9E10,1098765.43E21", "--ldvar=0.12345678E-5,0.87654321E9"};
CCommandLine cl;
sdv::sequence<float> seqfVar; cl.DefineSubOption("fvar", seqfVar, "sequence of float variable");
sdv::sequence<double> seqdVar; cl.DefineSubOption("dvar", seqdVar, "sequence of double variable");
sdv::sequence<long double> seqldVar; cl.DefineSubOption("ldvar", seqldVar, "sequence of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(seqdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(seqldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTest, SubOptionParseFloatingPointList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--fvar=-12345.6789,9876.54321,134679", "--dvar=12345678.9E10,1098765.43E21", "--ldvar=0.12345678E-5,0.87654321E9"};
CCommandLine cl;
std::list<float> lstfVar; cl.DefineSubOption("fvar", lstfVar, "list of float variable");
std::list<double> lstdVar; cl.DefineSubOption("dvar", lstdVar, "list of double variable");
std::list<long double> lstldVar; cl.DefineSubOption("ldvar", lstldVar, "list of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(lstdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(lstldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTest, SubOptionParseEnum)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "--unscoped_enum=test2", "--scoped_enum=test5"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
EUnscopedTest eUnscopedTest = test1; cl.DefineSubOption("unscoped_enum", eUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedTest = EScopedTest::test4; cl.DefineSubOption("scoped_enum", eScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EUnscopedTest eUnscopedControl = test1; cl.DefineSubOption("unscoped_enum_control", eUnscopedControl, "unscoped enum no change!").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedControl = EScopedTest::test4; cl.DefineSubOption("scoped_enum_control", eScopedControl, "scoped enum no change!").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(eUnscopedTest, test2);
EXPECT_EQ(eScopedTest, EScopedTest::test5);
EXPECT_EQ(eUnscopedControl, test1);
EXPECT_EQ(eScopedControl, EScopedTest::test4);
}
TEST_F(CCommandLineParserTest, SubOptionParseEnumVector)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "--unscoped_enum=test2,test3", "--scoped_enum=test5,test6"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::vector<EUnscopedTest> vecUnscopedTest; cl.DefineSubOption("unscoped_enum", vecUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::vector<EScopedTest> vecScopedTest; cl.DefineSubOption("scoped_enum", vecScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecUnscopedTest, test2, test3);
EXPECT_ARREQ(vecScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTest, SubOptionParseEnumSequence)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "--unscoped_enum=test2,test3", "--scoped_enum=test5,test6"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
sdv::sequence<EUnscopedTest> seqUnscopedTest; cl.DefineSubOption("unscoped_enum", seqUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
sdv::sequence<EScopedTest> seqScopedTest; cl.DefineSubOption("scoped_enum", seqScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqUnscopedTest, test2, test3);
EXPECT_ARREQ(seqScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTest, SubOptionParseEnumList)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "--unscoped_enum=test2,test3", "--scoped_enum=test5,test6"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::list<EUnscopedTest> lstUnscopedTest; cl.DefineSubOption("unscoped_enum", lstUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::list<EScopedTest> lstScopedTest; cl.DefineSubOption("scoped_enum", lstScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstUnscopedTest, test2, test3);
EXPECT_ARREQ(lstScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTest, SubOptionParseString)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1=test_a", "--ssu8var1=test_b", "--ssvar2=\"test_c\"",
"--ssu8var2=\"test_d\""};
CCommandLine cl;
std::string ssVar1; cl.DefineSubOption("ssvar1", ssVar1, "std::string variable");
sdv::u8string ssu8Var1; cl.DefineSubOption("ssu8var1", ssu8Var1, "sdv::u8string variable");
std::string ssVar2; cl.DefineSubOption("ssvar2", ssVar2, "sdv::string variable");
sdv::u8string ssu8Var2; cl.DefineSubOption("ssu8var2", ssu8Var2, "sdv::u8string variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(ssVar1, "test_a");
EXPECT_EQ(ssu8Var1, "test_b");
EXPECT_EQ(ssVar2, "test_c");
EXPECT_EQ(ssu8Var2, "test_d");
}
TEST_F(CCommandLineParserTest, SubOptionParseStringVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1=test_a,test_b", "--ssu8var1=test_b,test_c", "--ssvar2=\"test_c\",\"test_d\"",
"--ssu8var2=\"test_d\",\"test_e\""};
CCommandLine cl;
std::vector<std::string> vecssVar1; cl.DefineSubOption("ssvar1", vecssVar1, "std::vector<std::string> variable");
std::vector<sdv::u8string> vecssu8Var1; cl.DefineSubOption("ssu8var1", vecssu8Var1, "std::vector<sdv::u8string> variable");
std::vector<std::string> vecssVar2; cl.DefineSubOption("ssvar2", vecssVar2, "std::vector<sdv::string> variable");
std::vector<sdv::u8string> vecssu8Var2; cl.DefineSubOption("ssu8var2", vecssu8Var2, "std::vector<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecssVar1, "test_a", "test_b");
EXPECT_ARREQ(vecssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(vecssVar2, "test_c", "test_d");
EXPECT_ARREQ(vecssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTest, SubOptionParseStringSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1=test_a,test_b", "--ssu8var1=test_b,test_c", "--ssvar2=\"test_c\",\"test_d\"",
"--ssu8var2=\"test_d\",\"test_e\""};
CCommandLine cl;
sdv::sequence<std::string> seqssVar1; cl.DefineSubOption("ssvar1", seqssVar1, "sdv::sequence<std::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var1; cl.DefineSubOption("ssu8var1", seqssu8Var1, "sdv::sequence<sdv::u8string> variable");
sdv::sequence<std::string> seqssVar2; cl.DefineSubOption("ssvar2", seqssVar2, "sdv::sequence<sdv::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var2; cl.DefineSubOption("ssu8var2", seqssu8Var2, "sdv::sequence<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqssVar1, "test_a", "test_b");
EXPECT_ARREQ(seqssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(seqssVar2, "test_c", "test_d");
EXPECT_ARREQ(seqssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTest, SubOptionParseStringList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1=test_a,test_b", "--ssu8var1=test_b,test_c", "--ssvar2=\"test_c\",\"test_d\"",
"--ssu8var2=\"test_d\",\"test_e\""};
CCommandLine cl;
std::list<std::string> lstssVar1; cl.DefineSubOption("ssvar1", lstssVar1, "std::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var1; cl.DefineSubOption("ssu8var1", lstssu8Var1, "std::list<sdv::u8string> variable");
std::list<std::string> lstssVar2; cl.DefineSubOption("ssvar2", lstssVar2, "td::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var2; cl.DefineSubOption("ssu8var2", lstssu8Var2, "std::list<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstssVar1, "test_a", "test_b");
EXPECT_ARREQ(lstssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(lstssVar2, "test_c", "test_d");
EXPECT_ARREQ(lstssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTest, SubOptionParsePath)
{
const char* rgszCommandLine[] = {"this_exe.app", "--pathvar1=abc.def", "--pathvar2=\"ghi.jkl\""};
CCommandLine cl;
std::filesystem::path pathVar1; cl.DefineSubOption("pathvar1", pathVar1, "std::filesystem::path variable");
std::filesystem::path pathVar2; cl.DefineSubOption("pathvar2", pathVar2, "std::filesystem::path variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(pathVar1, "abc.def");
EXPECT_EQ(pathVar2, "ghi.jkl");
}
TEST_F(CCommandLineParserTest, SubOptionParsePathSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "--pathvar1=abc.def,ghi.jkl", "--pathvar2=\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl;
sdv::sequence<std::filesystem::path> seqpathVar1; cl.DefineSubOption("pathvar1", seqpathVar1, "sdv::sequence<std::filesystem::path> variable");
sdv::sequence<std::filesystem::path> seqpathVar2; cl.DefineSubOption("pathvar2", seqpathVar2, "sdv::sequence<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(seqpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTest, SubOptionParsePathList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--pathvar1=abc.def,ghi.jkl", "--pathvar2=\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl;
std::list<std::filesystem::path> lstpathVar1; cl.DefineSubOption("pathvar1", lstpathVar1, "std::list<std::filesystem::path> variable");
std::list<std::filesystem::path> lstpathVar2; cl.DefineSubOption("pathvar2", lstpathVar2, "std::list<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(lstpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTest, SubOptionParseFlags)
{
const char* rgszCommandLine[] = {"this_exe.app", "--flag_neg+", "--flag_pos-"};
CCommandLine cl;
bool bFlagNeg = false; cl.DefineFlagSubOption("flag_neg", bFlagNeg, "negative flag variable");
bool bFlagPos = true; cl.DefineFlagSubOption("flag_pos", bFlagPos, "positive flag variable");
bool bFlagNegControl = false; cl.DefineFlagSubOption("controlflag_neg", bFlagNegControl, "negative flag variable");
bool bFlagPosControl = true; cl.DefineFlagSubOption("control_flag_pos", bFlagPosControl, "positive flag variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bFlagNeg);
EXPECT_FALSE(bFlagPos);
EXPECT_FALSE(bFlagNegControl);
EXPECT_TRUE(bFlagPosControl);
}

View File

@@ -0,0 +1,546 @@
#include "../../include/gtest_custom.h"
#include "commandline_parser_test.h"
#include "../../../global/cmdlnparser/cmdlnparser.h"
using CCommandLineParserTestAssignmentNextArg = CCommandLineParserTest;
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseBoolean)
{
const char* rgszCommandLine[] = {"this_exe.app", "--select"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
bool bSelect = false; cl.DefineSubOption("select", bSelect, "Select it!");
bool bControlNegative = false; cl.DefineSubOption("neg_control", bControlNegative, "No change!");
bool bControlPositive = true; cl.DefineSubOption("pos_control", bControlPositive, "No change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bSelect);
EXPECT_FALSE(bControlNegative);
EXPECT_TRUE(bControlPositive);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseIntegralIndependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "--i8var", "-1", "--i16var", "-2", "--i32var", "-3", "--i64var", "-4",
"--ui8var", "5", "--ui16var", "6", "--ui32var", "7", "--ui64var", "8"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
int8_t i8Var = 0; cl.DefineSubOption("i8var", i8Var, "int8_t variable");
int16_t i16Var = 0; cl.DefineSubOption("i16var", i16Var, "int16_t variable");
int32_t i32Var = 0; cl.DefineSubOption("i32var", i32Var, "int32_t variable");
int64_t i64Var = 0; cl.DefineSubOption("i64var", i64Var, "int64_t variable");
uint8_t ui8Var = 0; cl.DefineSubOption("ui8var", ui8Var, "uint8_t variable");
uint16_t ui16Var = 0; cl.DefineSubOption("ui16var", ui16Var, "uint16_t variable");
uint32_t ui32Var = 0; cl.DefineSubOption("ui32var", ui32Var, "uint32_t variable");
uint64_t ui64Var = 0; cl.DefineSubOption("ui64var", ui64Var, "uint64_t variable");
int8_t i8Control = -10; cl.DefineSubOption("i8control", i8Control, "int8_t no change!");
int16_t i16Control = -20; cl.DefineSubOption("i16control", i16Control, "int16_t no change!");
int32_t i32Control = -30; cl.DefineSubOption("i32control", i32Control, "int32_t no change!");
int64_t i64Control = -40; cl.DefineSubOption("i64control", i64Control, "int64_t no change!");
uint8_t ui8Control = 50; cl.DefineSubOption("ui8control", ui8Control, "uint8_t no change!");
uint16_t ui16Control = 60; cl.DefineSubOption("ui16control", ui16Control, "uint16_t no change!");
uint32_t ui32Control = 70; cl.DefineSubOption("ui32control", ui32Control, "uint32_t no change!");
uint64_t ui64Control = 80; cl.DefineSubOption("ui64control", ui64Control, "uint64_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(i8Var, -1);
EXPECT_EQ(i16Var, -2);
EXPECT_EQ(i32Var, -3);
EXPECT_EQ(i64Var, -4);
EXPECT_EQ(ui8Var, 5u);
EXPECT_EQ(ui16Var, 6u);
EXPECT_EQ(ui32Var, 7u);
EXPECT_EQ(ui64Var, 8u);
EXPECT_EQ(i8Control, -10);
EXPECT_EQ(i16Control, -20);
EXPECT_EQ(i32Control, -30);
EXPECT_EQ(i64Control, -40);
EXPECT_EQ(ui8Control, 50u);
EXPECT_EQ(ui16Control, 60u);
EXPECT_EQ(ui32Control, 70u);
EXPECT_EQ(ui64Control, 80u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseIntegralDedependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar", "-1", "--svar", "-2", "--lvar", "-3", "--ivar", "-4", "--llvar", "-5",
"--ucvar", "6", "--usvar", "7", "--ulvar", "8", "--uivar", "9", "--ullvar", "10", "--nvar", "11"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
signed char cVar = 0; cl.DefineSubOption("cvar", cVar, "char variable");
short sVar = 0; cl.DefineSubOption("svar", sVar, "short variable");
long lVar = 0; cl.DefineSubOption("lvar", lVar, "long variable");
int iVar = 0; cl.DefineSubOption("ivar", iVar, "int variable");
long long llVar = 0; cl.DefineSubOption("llvar", llVar, "long long variable");
unsigned char ucVar = 0; cl.DefineSubOption("ucvar", ucVar, "unsigned char variable");
unsigned short usVar = 0; cl.DefineSubOption("usvar", usVar, "unsigned short variable");
unsigned long ulVar = 0; cl.DefineSubOption("ulvar", ulVar, "unsigned long variable");
unsigned int uiVar = 0; cl.DefineSubOption("uivar", uiVar, "unsigned int variable");
unsigned long long ullVar = 0; cl.DefineSubOption("ullvar", ullVar, "unsigned long long variable");
size_t nVar = 0; cl.DefineSubOption("nvar", nVar, "size_t variable");
signed char cControl = -10; cl.DefineSubOption("ccontrol", cControl, "char no change!");
short sControl = -20; cl.DefineSubOption("scontrol", sControl, "short no change!");
long lControl = -30; cl.DefineSubOption("lcontrol", lControl, "long no change!");
int iControl = -40; cl.DefineSubOption("icontrol", iControl, "int no change!");
long long llControl = -50; cl.DefineSubOption("llcontrol", llControl, "long long no change!");
unsigned char ucControl = 60; cl.DefineSubOption("uccontrol", ucControl, "unsigned char no change!");
unsigned short usControl = 70; cl.DefineSubOption("uscontrol", usControl, "unsigned short no change!");
unsigned long ulControl = 80; cl.DefineSubOption("ulcontrol", ulControl, "unsigned long no change!");
unsigned int uiControl = 90; cl.DefineSubOption("uicontrol", uiControl, "unsigned int no change!");
unsigned long long ullControl = 100; cl.DefineSubOption("ullcontrol", ullControl, "unsigned long long no change!");
size_t nControl = 110; cl.DefineSubOption("ncontrol", nControl, "size_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(cVar, -1);
EXPECT_EQ(sVar, -2);
EXPECT_EQ(lVar, -3);
EXPECT_EQ(iVar, -4);
EXPECT_EQ(llVar, -5);
EXPECT_EQ(ucVar, 6u);
EXPECT_EQ(usVar, 7u);
EXPECT_EQ(ulVar, 8u);
EXPECT_EQ(uiVar, 9u);
EXPECT_EQ(ullVar, 10u);
EXPECT_EQ(nVar, 11u);
EXPECT_EQ(cControl, -10);
EXPECT_EQ(sControl, -20);
EXPECT_EQ(lControl, -30);
EXPECT_EQ(iControl, -40);
EXPECT_EQ(llControl, -50);
EXPECT_EQ(ucControl, 60u);
EXPECT_EQ(usControl, 70u);
EXPECT_EQ(ulControl, 80u);
EXPECT_EQ(uiControl, 90u);
EXPECT_EQ(ullControl, 100u);
EXPECT_EQ(nControl, 110u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseIntegralIndependentVector)
{
// Attention: std::vector<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"--i8var", "-1,2, -3",*/ "--i16var", "-2,3,-4", "--i32var", "-3,4,-5", "--i64var", "-4,5,-6",
"--ui8var", "5,6,7", "--ui16var", "6,7,8", "--ui32var", "7,8,9", "--ui64var", "8,9,10"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
//std::vector<int8_t> veci8Var; cl.DefineSubOption("i8var", veci8Var, "vector of int8_t variable");
std::vector<int16_t> veci16Var; cl.DefineSubOption("i16var", veci16Var, "vector of int16_t variable");
std::vector<int32_t> veci32Var; cl.DefineSubOption("i32var", veci32Var, "vector of int32_t variable");
std::vector<int64_t> veci64Var; cl.DefineSubOption("i64var", veci64Var, "vector of int64_t variable");
std::vector<uint8_t> vecui8Var; cl.DefineSubOption("ui8var", vecui8Var, "vector of uint8_t variable");
std::vector<uint16_t> vecui16Var; cl.DefineSubOption("ui16var", vecui16Var, "vector of uint16_t variable");
std::vector<uint32_t> vecui32Var; cl.DefineSubOption("ui32var", vecui32Var, "vector of uint32_t variable");
std::vector<uint64_t> vecui64Var; cl.DefineSubOption("ui64var", vecui64Var, "vector of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(veci8Var, -1, 2, -3);
EXPECT_ARREQ(veci16Var, -2, 3, -4);
EXPECT_ARREQ(veci32Var, -3, 4, -5);
EXPECT_ARREQ(veci64Var, -4, 5, -6);
EXPECT_ARREQ(vecui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(vecui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(vecui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(vecui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseIntegralDedependentVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar", "-1,2,-3", "--svar", "-2,3,-4", "--lvar", "-3,4,-5", "--ivar", "-4,5,-6", "--llvar", "-5,6,-7",
"--ucvar", "6,7,8", "--usvar", "7,8,9", "--ulvar", "8,9,10", "--uivar", "9,10,11", "--ullvar", "10,11,12", "--nvar", "11,12,13"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::vector<signed char> veccVar; cl.DefineSubOption("cvar", veccVar, "vector of char variable");
std::vector<short> vecsVar; cl.DefineSubOption("svar", vecsVar, "vector of short variable");
std::vector<long> veclVar; cl.DefineSubOption("lvar", veclVar, "vector of long variable");
std::vector<int> veciVar; cl.DefineSubOption("ivar", veciVar, "vector of int variable");
std::vector<long long> vecllVar; cl.DefineSubOption("llvar", vecllVar, "vector of long long variable");
std::vector<unsigned char> vecucVar; cl.DefineSubOption("ucvar", vecucVar, "vector of unsigned char variable");
std::vector<unsigned short> vecusVar; cl.DefineSubOption("usvar", vecusVar, "vector of unsigned short variable");
std::vector<unsigned long> veculVar; cl.DefineSubOption("ulvar", veculVar, "vector of unsigned long variable");
std::vector<unsigned int> vecuiVar; cl.DefineSubOption("uivar", vecuiVar, "vector of unsigned int variable");
std::vector<unsigned long long> vecullVar; cl.DefineSubOption("ullvar", vecullVar, "vector of unsigned long long variable");
std::vector<size_t> vecnVar; cl.DefineSubOption("nvar", vecnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(veccVar, -1, 2, -3);
EXPECT_ARREQ(vecsVar, -2, 3, -4);
EXPECT_ARREQ(veclVar, -3, 4, -5);
EXPECT_ARREQ(veciVar, -4, 5, -6);
EXPECT_ARREQ(vecllVar, -5, 6, -7);
EXPECT_ARREQ(vecucVar, 6u, 7u, 8u);
EXPECT_ARREQ(vecusVar, 7u, 8u, 9u);
EXPECT_ARREQ(veculVar, 8u, 9u, 10u);
EXPECT_ARREQ(vecuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(vecullVar, 10u, 11u, 12u);
EXPECT_ARREQ(vecnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseIntegralIndependentSequence)
{
// Attention: sdv::sequence<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"--i8var", "-1,2, -3",*/ "--i16var", "-2,3,-4", "--i32var", "-3,4,-5", "--i64var", "-4,5,-6",
"--ui8var", "5,6,7", "--ui16var", "6,7,8", "--ui32var", "7,8,9", "--ui64var", "8,9,10"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
//sdv::sequence<int8_t> seqi8Var; cl.DefineSubOption("i8var", seqi8Var, "sequence of int8_t variable");
sdv::sequence<int16_t> seqi16Var; cl.DefineSubOption("i16var", seqi16Var, "sequence of int16_t variable");
sdv::sequence<int32_t> seqi32Var; cl.DefineSubOption("i32var", seqi32Var, "sequence of int32_t variable");
sdv::sequence<int64_t> seqi64Var; cl.DefineSubOption("i64var", seqi64Var, "sequence of int64_t variable");
sdv::sequence<uint8_t> sequi8Var; cl.DefineSubOption("ui8var", sequi8Var, "sequence of uint8_t variable");
sdv::sequence<uint16_t> sequi16Var; cl.DefineSubOption("ui16var", sequi16Var, "sequence of uint16_t variable");
sdv::sequence<uint32_t> sequi32Var; cl.DefineSubOption("ui32var", sequi32Var, "sequence of uint32_t variable");
sdv::sequence<uint64_t> sequi64Var; cl.DefineSubOption("ui64var", sequi64Var, "sequence of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(seqi8Var, -1, 2, -3);
EXPECT_ARREQ(seqi16Var, -2, 3, -4);
EXPECT_ARREQ(seqi32Var, -3, 4, -5);
EXPECT_ARREQ(seqi64Var, -4, 5, -6);
EXPECT_ARREQ(sequi8Var, 5u, 6u, 7u);
EXPECT_ARREQ(sequi16Var, 6u, 7u, 8u);
EXPECT_ARREQ(sequi32Var, 7u, 8u, 9u);
EXPECT_ARREQ(sequi64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseIntegralDedependentSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar", "-1,2,-3", "--svar", "-2,3,-4", "--lvar", "-3,4,-5", "--ivar", "-4,5,-6", "--llvar", "-5,6,-7",
"--ucvar", "6,7,8", "--usvar", "7,8,9", "--ulvar", "8,9,10", "--uivar", "9,10,11", "--ullvar", "10,11,12", "--nvar", "11,12,13"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
sdv::sequence<signed char> seqcVar; cl.DefineSubOption("cvar", seqcVar, "sequence of char variable");
sdv::sequence<short> seqsVar; cl.DefineSubOption("svar", seqsVar, "sequence of short variable");
sdv::sequence<long> seqlVar; cl.DefineSubOption("lvar", seqlVar, "sequence of long variable");
sdv::sequence<int> seqiVar; cl.DefineSubOption("ivar", seqiVar, "sequence of int variable");
sdv::sequence<long long> seqllVar; cl.DefineSubOption("llvar", seqllVar, "sequence of long long variable");
sdv::sequence<unsigned char> sequcVar; cl.DefineSubOption("ucvar", sequcVar, "sequence of unsigned char variable");
sdv::sequence<unsigned short> sequsVar; cl.DefineSubOption("usvar", sequsVar, "sequence of unsigned short variable");
sdv::sequence<unsigned long> sequlVar; cl.DefineSubOption("ulvar", sequlVar, "sequence of unsigned long variable");
sdv::sequence<unsigned int> sequiVar; cl.DefineSubOption("uivar", sequiVar, "sequence of unsigned int variable");
sdv::sequence<unsigned long long> sequllVar; cl.DefineSubOption("ullvar", sequllVar, "sequence of unsigned long long variable");
sdv::sequence<size_t> seqnVar; cl.DefineSubOption("nvar", seqnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqcVar, -1, 2, -3);
EXPECT_ARREQ(seqsVar, -2, 3, -4);
EXPECT_ARREQ(seqlVar, -3, 4, -5);
EXPECT_ARREQ(seqiVar, -4, 5, -6);
EXPECT_ARREQ(seqllVar, -5, 6, -7);
EXPECT_ARREQ(sequcVar, 6u, 7u, 8u);
EXPECT_ARREQ(sequsVar, 7u, 8u, 9u);
EXPECT_ARREQ(sequlVar, 8u, 9u, 10u);
EXPECT_ARREQ(sequiVar, 9u, 10u, 11u);
EXPECT_ARREQ(sequllVar, 10u, 11u, 12u);
EXPECT_ARREQ(seqnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseIntegralIndependentList)
{
// Attention: std::list<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"--i8var", "-1,2, -3",*/ "--i16var", "-2,3,-4", "--i32var", "-3,4,-5", "--i64var", "-4,5,-6",
"--ui8var", "5,6,7", "--ui16var", "6,7,8", "--ui32var", "7,8,9", "--ui64var", "8,9,10"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
//std::list<int8_t> lsti8Var; cl.DefineSubOption("i8var", lsti8Var, "list of int8_t variable");
std::list<int16_t> lsti16Var; cl.DefineSubOption("i16var", lsti16Var, "list of int16_t variable");
std::list<int32_t> lsti32Var; cl.DefineSubOption("i32var", lsti32Var, "list of int32_t variable");
std::list<int64_t> lsti64Var; cl.DefineSubOption("i64var", lsti64Var, "list of int64_t variable");
std::list<uint8_t> lstui8Var; cl.DefineSubOption("ui8var", lstui8Var, "list of uint8_t variable");
std::list<uint16_t> lstui16Var; cl.DefineSubOption("ui16var", lstui16Var, "list of uint16_t variable");
std::list<uint32_t> lstui32Var; cl.DefineSubOption("ui32var", lstui32Var, "list of uint32_t variable");
std::list<uint64_t> lstui64Var; cl.DefineSubOption("ui64var", lstui64Var, "list of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(lsti8Var, -1, 2, -3);
EXPECT_ARREQ(lsti16Var, -2, 3, -4);
EXPECT_ARREQ(lsti32Var, -3, 4, -5);
EXPECT_ARREQ(lsti64Var, -4, 5, -6);
EXPECT_ARREQ(lstui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(lstui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(lstui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(lstui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseIntegralDedependentList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar", "-1,2,-3", "--svar", "-2,3,-4", "--lvar", "-3,4,-5", "--ivar", "-4,5,-6", "--llvar", "-5,6,-7",
"--ucvar", "6,7,8", "--usvar", "7,8,9", "--ulvar", "8,9,10", "--uivar", "9,10,11", "--ullvar", "10,11,12", "--nvar", "11,12,13"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::list<signed char> lstcVar; cl.DefineSubOption("cvar", lstcVar, "list of char variable");
std::list<short> lstsVar; cl.DefineSubOption("svar", lstsVar, "list of short variable");
std::list<long> lstlVar; cl.DefineSubOption("lvar", lstlVar, "list of long variable");
std::list<int> lstiVar; cl.DefineSubOption("ivar", lstiVar, "list of int variable");
std::list<long long> lstllVar; cl.DefineSubOption("llvar", lstllVar, "list of long long variable");
std::list<unsigned char> lstucVar; cl.DefineSubOption("ucvar", lstucVar, "list of unsigned char variable");
std::list<unsigned short> lstusVar; cl.DefineSubOption("usvar", lstusVar, "list of unsigned short variable");
std::list<unsigned long> lstulVar; cl.DefineSubOption("ulvar", lstulVar, "list of unsigned long variable");
std::list<unsigned int> lstuiVar; cl.DefineSubOption("uivar", lstuiVar, "list of unsigned int variable");
std::list<unsigned long long> lstullVar; cl.DefineSubOption("ullvar", lstullVar, "list of unsigned long long variable");
std::list<size_t> lstnVar; cl.DefineSubOption("nvar", lstnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstcVar, -1, 2, -3);
EXPECT_ARREQ(lstsVar, -2, 3, -4);
EXPECT_ARREQ(lstlVar, -3, 4, -5);
EXPECT_ARREQ(lstiVar, -4, 5, -6);
EXPECT_ARREQ(lstllVar, -5, 6, -7);
EXPECT_ARREQ(lstucVar, 6u, 7u, 8u);
EXPECT_ARREQ(lstusVar, 7u, 8u, 9u);
EXPECT_ARREQ(lstulVar, 8u, 9u, 10u);
EXPECT_ARREQ(lstuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(lstullVar, 10u, 11u, 12u);
EXPECT_ARREQ(lstnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseFloatingPoint)
{
const char* rgszCommandLine[] = {"this_exe.app", "--fvar", "-12345.6789", "--dvar", "12345678.9E10", "--ldvar", "0.12345678E-5"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
float fVar = 0; cl.DefineSubOption("fvar", fVar, "float variable");
double dVar = 0; cl.DefineSubOption("dvar", dVar, "double variable");
long double ldVar = 0; cl.DefineSubOption("ldvar", ldVar, "long double variable");
float fControl = 123.456f; cl.DefineSubOption("fcontrol", fControl, "float no change!");
double dControl = 456.789; cl.DefineSubOption("dcontrol", dControl, "double no change!");
long double ldControl = 876.543; cl.DefineSubOption("ldcontrol", ldControl, "long double no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_FPEQ(fVar, -12345.6789f);
EXPECT_FPEQ(dVar, 12345678.9E10);
#ifndef __GNUC__ // Long double is not well supported by G++ compiler
EXPECT_FPEQ(ldVar, 0.12345678E-5);
#endif
EXPECT_FPEQ(fControl, 123.456f);
EXPECT_FPEQ(dControl, 456.789);
EXPECT_FPEQ(ldControl, 876.543);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseFloatingPointVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "--fvar", "-12345.6789,9876.54321,134679", "--dvar", "12345678.9E10,1098765.43E21", "--ldvar", "0.12345678E-5,0.87654321E9"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::vector<float> vecfVar; cl.DefineSubOption("fvar", vecfVar, "vector of float variable");
std::vector<double> vecdVar; cl.DefineSubOption("dvar", vecdVar, "vector of double variable");
std::vector<long double> vecldVar; cl.DefineSubOption("ldvar", vecldVar, "vector of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(vecdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(vecldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseFloatingPointSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "--fvar", "-12345.6789,9876.54321,134679", "--dvar", "12345678.9E10,1098765.43E21", "--ldvar", "0.12345678E-5,0.87654321E9"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
sdv::sequence<float> seqfVar; cl.DefineSubOption("fvar", seqfVar, "sequence of float variable");
sdv::sequence<double> seqdVar; cl.DefineSubOption("dvar", seqdVar, "sequence of double variable");
sdv::sequence<long double> seqldVar; cl.DefineSubOption("ldvar", seqldVar, "sequence of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(seqdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(seqldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseFloatingPointList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--fvar", "-12345.6789,9876.54321,134679", "--dvar", "12345678.9E10,1098765.43E21", "--ldvar", "0.12345678E-5,0.87654321E9"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::list<float> lstfVar; cl.DefineSubOption("fvar", lstfVar, "list of float variable");
std::list<double> lstdVar; cl.DefineSubOption("dvar", lstdVar, "list of double variable");
std::list<long double> lstldVar; cl.DefineSubOption("ldvar", lstldVar, "list of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(lstdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(lstldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseEnum)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "--unscoped_enum", "test2", "--scoped_enum", "test5"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
EUnscopedTest eUnscopedTest = test1; cl.DefineSubOption("unscoped_enum", eUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedTest = EScopedTest::test4; cl.DefineSubOption("scoped_enum", eScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EUnscopedTest eUnscopedControl = test1; cl.DefineSubOption("unscoped_enum_control", eUnscopedControl, "unscoped enum no change!").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedControl = EScopedTest::test4; cl.DefineSubOption("scoped_enum_control", eScopedControl, "scoped enum no change!").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(eUnscopedTest, test2);
EXPECT_EQ(eScopedTest, EScopedTest::test5);
EXPECT_EQ(eUnscopedControl, test1);
EXPECT_EQ(eScopedControl, EScopedTest::test4);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseEnumVector)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "--unscoped_enum", "test2,test3", "--scoped_enum", "test5,test6"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::vector<EUnscopedTest> vecUnscopedTest; cl.DefineSubOption("unscoped_enum", vecUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::vector<EScopedTest> vecScopedTest; cl.DefineSubOption("scoped_enum", vecScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecUnscopedTest, test2, test3);
EXPECT_ARREQ(vecScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseEnumSequence)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "--unscoped_enum", "test2,test3", "--scoped_enum", "test5,test6"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
sdv::sequence<EUnscopedTest> seqUnscopedTest; cl.DefineSubOption("unscoped_enum", seqUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
sdv::sequence<EScopedTest> seqScopedTest; cl.DefineSubOption("scoped_enum", seqScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqUnscopedTest, test2, test3);
EXPECT_ARREQ(seqScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseEnumList)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "--unscoped_enum", "test2,test3", "--scoped_enum", "test5,test6"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::list<EUnscopedTest> lstUnscopedTest; cl.DefineSubOption("unscoped_enum", lstUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::list<EScopedTest> lstScopedTest; cl.DefineSubOption("scoped_enum", lstScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstUnscopedTest, test2, test3);
EXPECT_ARREQ(lstScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseString)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1", "test_a", "--ssu8var1", "test_b", "--ssvar2", "\"test_c\"",
"--ssu8var2", "\"test_d\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::string ssVar1; cl.DefineSubOption("ssvar1", ssVar1, "std::string variable");
sdv::u8string ssu8Var1; cl.DefineSubOption("ssu8var1", ssu8Var1, "sdv::u8string variable");
std::string ssVar2; cl.DefineSubOption("ssvar2", ssVar2, "sdv::string variable");
sdv::u8string ssu8Var2; cl.DefineSubOption("ssu8var2", ssu8Var2, "sdv::u8string variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(ssVar1, "test_a");
EXPECT_EQ(ssu8Var1, "test_b");
EXPECT_EQ(ssVar2, "test_c");
EXPECT_EQ(ssu8Var2, "test_d");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseStringVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1", "test_a,test_b", "--ssu8var1", "test_b,test_c", "--ssvar2", "\"test_c\",\"test_d\"",
"--ssu8var2", "\"test_d\",\"test_e\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::vector<std::string> vecssVar1; cl.DefineSubOption("ssvar1", vecssVar1, "std::vector<std::string> variable");
std::vector<sdv::u8string> vecssu8Var1; cl.DefineSubOption("ssu8var1", vecssu8Var1, "std::vector<sdv::u8string> variable");
std::vector<std::string> vecssVar2; cl.DefineSubOption("ssvar2", vecssVar2, "std::vector<sdv::string> variable");
std::vector<sdv::u8string> vecssu8Var2; cl.DefineSubOption("ssu8var2", vecssu8Var2, "std::vector<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecssVar1, "test_a", "test_b");
EXPECT_ARREQ(vecssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(vecssVar2, "test_c", "test_d");
EXPECT_ARREQ(vecssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseStringSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1", "test_a,test_b", "--ssu8var1", "test_b,test_c", "--ssvar2", "\"test_c\",\"test_d\"",
"--ssu8var2", "\"test_d\",\"test_e\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
sdv::sequence<std::string> seqssVar1; cl.DefineSubOption("ssvar1", seqssVar1, "sdv::sequence<std::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var1; cl.DefineSubOption("ssu8var1", seqssu8Var1, "sdv::sequence<sdv::u8string> variable");
sdv::sequence<std::string> seqssVar2; cl.DefineSubOption("ssvar2", seqssVar2, "sdv::sequence<sdv::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var2; cl.DefineSubOption("ssu8var2", seqssu8Var2, "sdv::sequence<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqssVar1, "test_a", "test_b");
EXPECT_ARREQ(seqssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(seqssVar2, "test_c", "test_d");
EXPECT_ARREQ(seqssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseStringList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1", "test_a,test_b", "--ssu8var1", "test_b,test_c", "--ssvar2", "\"test_c\",\"test_d\"",
"--ssu8var2", "\"test_d\",\"test_e\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::list<std::string> lstssVar1; cl.DefineSubOption("ssvar1", lstssVar1, "std::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var1; cl.DefineSubOption("ssu8var1", lstssu8Var1, "std::list<sdv::u8string> variable");
std::list<std::string> lstssVar2; cl.DefineSubOption("ssvar2", lstssVar2, "td::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var2; cl.DefineSubOption("ssu8var2", lstssu8Var2, "std::list<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstssVar1, "test_a", "test_b");
EXPECT_ARREQ(lstssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(lstssVar2, "test_c", "test_d");
EXPECT_ARREQ(lstssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParsePath)
{
const char* rgszCommandLine[] = {"this_exe.app", "--pathvar1", "abc.def", "--pathvar2", "\"ghi.jkl\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::filesystem::path pathVar1; cl.DefineSubOption("pathvar1", pathVar1, "std::filesystem::path variable");
std::filesystem::path pathVar2; cl.DefineSubOption("pathvar2", pathVar2, "std::filesystem::path variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(pathVar1, "abc.def");
EXPECT_EQ(pathVar2, "ghi.jkl");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParsePathSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "--pathvar1", "abc.def,ghi.jkl", "--pathvar2", "\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
sdv::sequence<std::filesystem::path> seqpathVar1; cl.DefineSubOption("pathvar1", seqpathVar1, "sdv::sequence<std::filesystem::path> variable");
sdv::sequence<std::filesystem::path> seqpathVar2; cl.DefineSubOption("pathvar2", seqpathVar2, "sdv::sequence<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(seqpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParsePathList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--pathvar1", "abc.def,ghi.jkl", "--pathvar2", "\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
std::list<std::filesystem::path> lstpathVar1; cl.DefineSubOption("pathvar1", lstpathVar1, "std::list<std::filesystem::path> variable");
std::list<std::filesystem::path> lstpathVar2; cl.DefineSubOption("pathvar2", lstpathVar2, "std::list<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(lstpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTestAssignmentNextArg, SubOptionParseFlags)
{
const char* rgszCommandLine[] = {"this_exe.app", "--flag_neg+", "--flag_pos-"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::assignment_next_arg));
bool bFlagNeg = false; cl.DefineFlagSubOption("flag_neg", bFlagNeg, "negative flag variable");
bool bFlagPos = true; cl.DefineFlagSubOption("flag_pos", bFlagPos, "positive flag variable");
bool bFlagNegControl = false; cl.DefineFlagSubOption("controlflag_neg", bFlagNegControl, "negative flag variable");
bool bFlagPosControl = true; cl.DefineFlagSubOption("control_flag_pos", bFlagPosControl, "positive flag variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bFlagNeg);
EXPECT_FALSE(bFlagPos);
EXPECT_FALSE(bFlagNegControl);
EXPECT_TRUE(bFlagPosControl);
}

View File

@@ -0,0 +1,586 @@
#include "../../include/gtest_custom.h"
#include "commandline_parser_test.h"
#include "../../../global/cmdlnparser/cmdlnparser.h"
using CCommandLineParserTestNoAssignment = CCommandLineParserTest;
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseBoolean)
{
const char* rgszCommandLine[] = {"this_exe.app", "--select"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
bool bSelect = false; cl.DefineSubOption("select", bSelect, "Select it!");
bool bControlNegative = false; cl.DefineSubOption("neg_control", bControlNegative, "No change!");
bool bControlPositive = true; cl.DefineSubOption("pos_control", bControlPositive, "No change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bSelect);
EXPECT_FALSE(bControlNegative);
EXPECT_TRUE(bControlPositive);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseIntegralIndependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "--i8var-1", "--i16var-2", "--i32var-3", "--i64var-4",
"--ui8var5", "--ui16var6", "--ui32var7", "--ui64var8"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
int8_t i8Var = 0; cl.DefineSubOption("i8var", i8Var, "int8_t variable");
int16_t i16Var = 0; cl.DefineSubOption("i16var", i16Var, "int16_t variable");
int32_t i32Var = 0; cl.DefineSubOption("i32var", i32Var, "int32_t variable");
int64_t i64Var = 0; cl.DefineSubOption("i64var", i64Var, "int64_t variable");
uint8_t ui8Var = 0; cl.DefineSubOption("ui8var", ui8Var, "uint8_t variable");
uint16_t ui16Var = 0; cl.DefineSubOption("ui16var", ui16Var, "uint16_t variable");
uint32_t ui32Var = 0; cl.DefineSubOption("ui32var", ui32Var, "uint32_t variable");
uint64_t ui64Var = 0; cl.DefineSubOption("ui64var", ui64Var, "uint64_t variable");
int8_t i8Control = -10; cl.DefineSubOption("i8control", i8Control, "int8_t no change!");
int16_t i16Control = -20; cl.DefineSubOption("i16control", i16Control, "int16_t no change!");
int32_t i32Control = -30; cl.DefineSubOption("i32control", i32Control, "int32_t no change!");
int64_t i64Control = -40; cl.DefineSubOption("i64control", i64Control, "int64_t no change!");
uint8_t ui8Control = 50; cl.DefineSubOption("ui8control", ui8Control, "uint8_t no change!");
uint16_t ui16Control = 60; cl.DefineSubOption("ui16control", ui16Control, "uint16_t no change!");
uint32_t ui32Control = 70; cl.DefineSubOption("ui32control", ui32Control, "uint32_t no change!");
uint64_t ui64Control = 80; cl.DefineSubOption("ui64control", ui64Control, "uint64_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(i8Var, -1);
EXPECT_EQ(i16Var, -2);
EXPECT_EQ(i32Var, -3);
EXPECT_EQ(i64Var, -4);
EXPECT_EQ(ui8Var, 5u);
EXPECT_EQ(ui16Var, 6u);
EXPECT_EQ(ui32Var, 7u);
EXPECT_EQ(ui64Var, 8u);
EXPECT_EQ(i8Control, -10);
EXPECT_EQ(i16Control, -20);
EXPECT_EQ(i32Control, -30);
EXPECT_EQ(i64Control, -40);
EXPECT_EQ(ui8Control, 50u);
EXPECT_EQ(ui16Control, 60u);
EXPECT_EQ(ui32Control, 70u);
EXPECT_EQ(ui64Control, 80u);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseIntegralDedependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar-1", "--svar-2", "--lvar-3", "--ivar-4", "--llvar-5",
"--ucvar6", "--usvar7", "--ulvar8", "--uivar9", "--ullvar10", "--nvar11"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
signed char cVar = 0; cl.DefineSubOption("cvar", cVar, "char variable");
short sVar = 0; cl.DefineSubOption("svar", sVar, "short variable");
long lVar = 0; cl.DefineSubOption("lvar", lVar, "long variable");
int iVar = 0; cl.DefineSubOption("ivar", iVar, "int variable");
long long llVar = 0; cl.DefineSubOption("llvar", llVar, "long long variable");
unsigned char ucVar = 0; cl.DefineSubOption("ucvar", ucVar, "unsigned char variable");
unsigned short usVar = 0; cl.DefineSubOption("usvar", usVar, "unsigned short variable");
unsigned long ulVar = 0; cl.DefineSubOption("ulvar", ulVar, "unsigned long variable");
unsigned int uiVar = 0; cl.DefineSubOption("uivar", uiVar, "unsigned int variable");
unsigned long long ullVar = 0; cl.DefineSubOption("ullvar", ullVar, "unsigned long long variable");
size_t nVar = 0; cl.DefineSubOption("nvar", nVar, "size_t variable");
signed char cControl = -10; cl.DefineSubOption("ccontrol", cControl, "char no change!");
short sControl = -20; cl.DefineSubOption("scontrol", sControl, "short no change!");
long lControl = -30; cl.DefineSubOption("lcontrol", lControl, "long no change!");
int iControl = -40; cl.DefineSubOption("icontrol", iControl, "int no change!");
long long llControl = -50; cl.DefineSubOption("llcontrol", llControl, "long long no change!");
unsigned char ucControl = 60; cl.DefineSubOption("uccontrol", ucControl, "unsigned char no change!");
unsigned short usControl = 70; cl.DefineSubOption("uscontrol", usControl, "unsigned short no change!");
unsigned long ulControl = 80; cl.DefineSubOption("ulcontrol", ulControl, "unsigned long no change!");
unsigned int uiControl = 90; cl.DefineSubOption("uicontrol", uiControl, "unsigned int no change!");
unsigned long long ullControl = 100; cl.DefineSubOption("ullcontrol", ullControl, "unsigned long long no change!");
size_t nControl = 110; cl.DefineSubOption("ncontrol", nControl, "size_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(cVar, -1);
EXPECT_EQ(sVar, -2);
EXPECT_EQ(lVar, -3);
EXPECT_EQ(iVar, -4);
EXPECT_EQ(llVar, -5);
EXPECT_EQ(ucVar, 6u);
EXPECT_EQ(usVar, 7u);
EXPECT_EQ(ulVar, 8u);
EXPECT_EQ(uiVar, 9u);
EXPECT_EQ(ullVar, 10u);
EXPECT_EQ(nVar, 11u);
EXPECT_EQ(cControl, -10);
EXPECT_EQ(sControl, -20);
EXPECT_EQ(lControl, -30);
EXPECT_EQ(iControl, -40);
EXPECT_EQ(llControl, -50);
EXPECT_EQ(ucControl, 60u);
EXPECT_EQ(usControl, 70u);
EXPECT_EQ(ulControl, 80u);
EXPECT_EQ(uiControl, 90u);
EXPECT_EQ(ullControl, 100u);
EXPECT_EQ(nControl, 110u);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseIntegralIndependentVector)
{
// Attention: std::vector<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"--i8var-1,2, -3",*/ "--i16var-2,3,-4", "--i32var-3,4,-5", "--i64var-4,5,-6",
"--ui8var5,6,7", "--ui16var6,7,8", "--ui32var7,8,9", "--ui64var8,9,10"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
//std::vector<int8_t> veci8Var; cl.DefineSubOption("i8var", veci8Var, "vector of int8_t variable");
std::vector<int16_t> veci16Var; cl.DefineSubOption("i16var", veci16Var, "vector of int16_t variable");
std::vector<int32_t> veci32Var; cl.DefineSubOption("i32var", veci32Var, "vector of int32_t variable");
std::vector<int64_t> veci64Var; cl.DefineSubOption("i64var", veci64Var, "vector of int64_t variable");
std::vector<uint8_t> vecui8Var; cl.DefineSubOption("ui8var", vecui8Var, "vector of uint8_t variable");
std::vector<uint16_t> vecui16Var; cl.DefineSubOption("ui16var", vecui16Var, "vector of uint16_t variable");
std::vector<uint32_t> vecui32Var; cl.DefineSubOption("ui32var", vecui32Var, "vector of uint32_t variable");
std::vector<uint64_t> vecui64Var; cl.DefineSubOption("ui64var", vecui64Var, "vector of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(veci8Var, -1, 2, -3);
EXPECT_ARREQ(veci16Var, -2, 3, -4);
EXPECT_ARREQ(veci32Var, -3, 4, -5);
EXPECT_ARREQ(veci64Var, -4, 5, -6);
EXPECT_ARREQ(vecui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(vecui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(vecui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(vecui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseIntegralDedependentVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar-1,2,-3", "--svar-2,3,-4", "--lvar-3,4,-5", "--ivar-4,5,-6", "--llvar-5,6,-7",
"--ucvar6,7,8", "--usvar7,8,9", "--ulvar8,9,10", "--uivar9,10,11", "--ullvar10,11,12", "--nvar11,12,13"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::vector<signed char> veccVar; cl.DefineSubOption("cvar", veccVar, "vector of char variable");
std::vector<short> vecsVar; cl.DefineSubOption("svar", vecsVar, "vector of short variable");
std::vector<long> veclVar; cl.DefineSubOption("lvar", veclVar, "vector of long variable");
std::vector<int> veciVar; cl.DefineSubOption("ivar", veciVar, "vector of int variable");
std::vector<long long> vecllVar; cl.DefineSubOption("llvar", vecllVar, "vector of long long variable");
std::vector<unsigned char> vecucVar; cl.DefineSubOption("ucvar", vecucVar, "vector of unsigned char variable");
std::vector<unsigned short> vecusVar; cl.DefineSubOption("usvar", vecusVar, "vector of unsigned short variable");
std::vector<unsigned long> veculVar; cl.DefineSubOption("ulvar", veculVar, "vector of unsigned long variable");
std::vector<unsigned int> vecuiVar; cl.DefineSubOption("uivar", vecuiVar, "vector of unsigned int variable");
std::vector<unsigned long long> vecullVar; cl.DefineSubOption("ullvar", vecullVar, "vector of unsigned long long variable");
std::vector<size_t> vecnVar; cl.DefineSubOption("nvar", vecnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(veccVar, -1, 2, -3);
EXPECT_ARREQ(vecsVar, -2, 3, -4);
EXPECT_ARREQ(veclVar, -3, 4, -5);
EXPECT_ARREQ(veciVar, -4, 5, -6);
EXPECT_ARREQ(vecllVar, -5, 6, -7);
EXPECT_ARREQ(vecucVar, 6u, 7u, 8u);
EXPECT_ARREQ(vecusVar, 7u, 8u, 9u);
EXPECT_ARREQ(veculVar, 8u, 9u, 10u);
EXPECT_ARREQ(vecuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(vecullVar, 10u, 11u, 12u);
EXPECT_ARREQ(vecnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseIntegralIndependentSequence)
{
// Attention: sdv::sequence<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"--i8var-1,2, -3",*/ "--i16var-2,3,-4", "--i32var-3,4,-5", "--i64var-4,5,-6",
"--ui8var5,6,7", "--ui16var6,7,8", "--ui32var7,8,9", "--ui64var8,9,10"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
//sdv::sequence<int8_t> seqi8Var; cl.DefineSubOption("i8var", seqi8Var, "sequence of int8_t variable");
sdv::sequence<int16_t> seqi16Var; cl.DefineSubOption("i16var", seqi16Var, "sequence of int16_t variable");
sdv::sequence<int32_t> seqi32Var; cl.DefineSubOption("i32var", seqi32Var, "sequence of int32_t variable");
sdv::sequence<int64_t> seqi64Var; cl.DefineSubOption("i64var", seqi64Var, "sequence of int64_t variable");
sdv::sequence<uint8_t> sequi8Var; cl.DefineSubOption("ui8var", sequi8Var, "sequence of uint8_t variable");
sdv::sequence<uint16_t> sequi16Var; cl.DefineSubOption("ui16var", sequi16Var, "sequence of uint16_t variable");
sdv::sequence<uint32_t> sequi32Var; cl.DefineSubOption("ui32var", sequi32Var, "sequence of uint32_t variable");
sdv::sequence<uint64_t> sequi64Var; cl.DefineSubOption("ui64var", sequi64Var, "sequence of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(seqi8Var, -1, 2, -3);
EXPECT_ARREQ(seqi16Var, -2, 3, -4);
EXPECT_ARREQ(seqi32Var, -3, 4, -5);
EXPECT_ARREQ(seqi64Var, -4, 5, -6);
EXPECT_ARREQ(sequi8Var, 5u, 6u, 7u);
EXPECT_ARREQ(sequi16Var, 6u, 7u, 8u);
EXPECT_ARREQ(sequi32Var, 7u, 8u, 9u);
EXPECT_ARREQ(sequi64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseIntegralDedependentSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar-1,2,-3", "--svar-2,3,-4", "--lvar-3,4,-5", "--ivar-4,5,-6", "--llvar-5,6,-7",
"--ucvar6,7,8", "--usvar7,8,9", "--ulvar8,9,10", "--uivar9,10,11", "--ullvar10,11,12", "--nvar11,12,13"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
sdv::sequence<signed char> seqcVar; cl.DefineSubOption("cvar", seqcVar, "sequence of char variable");
sdv::sequence<short> seqsVar; cl.DefineSubOption("svar", seqsVar, "sequence of short variable");
sdv::sequence<long> seqlVar; cl.DefineSubOption("lvar", seqlVar, "sequence of long variable");
sdv::sequence<int> seqiVar; cl.DefineSubOption("ivar", seqiVar, "sequence of int variable");
sdv::sequence<long long> seqllVar; cl.DefineSubOption("llvar", seqllVar, "sequence of long long variable");
sdv::sequence<unsigned char> sequcVar; cl.DefineSubOption("ucvar", sequcVar, "sequence of unsigned char variable");
sdv::sequence<unsigned short> sequsVar; cl.DefineSubOption("usvar", sequsVar, "sequence of unsigned short variable");
sdv::sequence<unsigned long> sequlVar; cl.DefineSubOption("ulvar", sequlVar, "sequence of unsigned long variable");
sdv::sequence<unsigned int> sequiVar; cl.DefineSubOption("uivar", sequiVar, "sequence of unsigned int variable");
sdv::sequence<unsigned long long> sequllVar; cl.DefineSubOption("ullvar", sequllVar, "sequence of unsigned long long variable");
sdv::sequence<size_t> seqnVar; cl.DefineSubOption("nvar", seqnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqcVar, -1, 2, -3);
EXPECT_ARREQ(seqsVar, -2, 3, -4);
EXPECT_ARREQ(seqlVar, -3, 4, -5);
EXPECT_ARREQ(seqiVar, -4, 5, -6);
EXPECT_ARREQ(seqllVar, -5, 6, -7);
EXPECT_ARREQ(sequcVar, 6u, 7u, 8u);
EXPECT_ARREQ(sequsVar, 7u, 8u, 9u);
EXPECT_ARREQ(sequlVar, 8u, 9u, 10u);
EXPECT_ARREQ(sequiVar, 9u, 10u, 11u);
EXPECT_ARREQ(sequllVar, 10u, 11u, 12u);
EXPECT_ARREQ(seqnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseIntegralIndependentList)
{
// Attention: std::list<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"--i8var-1,2, -3",*/ "--i16var-2,3,-4", "--i32var-3,4,-5", "--i64var-4,5,-6",
"--ui8var5,6,7", "--ui16var6,7,8", "--ui32var7,8,9", "--ui64var8,9,10"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
//std::list<int8_t> lsti8Var; cl.DefineSubOption("i8var", lsti8Var, "list of int8_t variable");
std::list<int16_t> lsti16Var; cl.DefineSubOption("i16var", lsti16Var, "list of int16_t variable");
std::list<int32_t> lsti32Var; cl.DefineSubOption("i32var", lsti32Var, "list of int32_t variable");
std::list<int64_t> lsti64Var; cl.DefineSubOption("i64var", lsti64Var, "list of int64_t variable");
std::list<uint8_t> lstui8Var; cl.DefineSubOption("ui8var", lstui8Var, "list of uint8_t variable");
std::list<uint16_t> lstui16Var; cl.DefineSubOption("ui16var", lstui16Var, "list of uint16_t variable");
std::list<uint32_t> lstui32Var; cl.DefineSubOption("ui32var", lstui32Var, "list of uint32_t variable");
std::list<uint64_t> lstui64Var; cl.DefineSubOption("ui64var", lstui64Var, "list of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(lsti8Var, -1, 2, -3);
EXPECT_ARREQ(lsti16Var, -2, 3, -4);
EXPECT_ARREQ(lsti32Var, -3, 4, -5);
EXPECT_ARREQ(lsti64Var, -4, 5, -6);
EXPECT_ARREQ(lstui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(lstui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(lstui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(lstui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseIntegralDedependentList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--cvar-1,2,-3", "--svar-2,3,-4", "--lvar-3,4,-5", "--ivar-4,5,-6", "--llvar-5,6,-7",
"--ucvar6,7,8", "--usvar7,8,9", "--ulvar8,9,10", "--uivar9,10,11", "--ullvar10,11,12", "--nvar11,12,13"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::list<signed char> lstcVar; cl.DefineSubOption("cvar", lstcVar, "list of char variable");
std::list<short> lstsVar; cl.DefineSubOption("svar", lstsVar, "list of short variable");
std::list<long> lstlVar; cl.DefineSubOption("lvar", lstlVar, "list of long variable");
std::list<int> lstiVar; cl.DefineSubOption("ivar", lstiVar, "list of int variable");
std::list<long long> lstllVar; cl.DefineSubOption("llvar", lstllVar, "list of long long variable");
std::list<unsigned char> lstucVar; cl.DefineSubOption("ucvar", lstucVar, "list of unsigned char variable");
std::list<unsigned short> lstusVar; cl.DefineSubOption("usvar", lstusVar, "list of unsigned short variable");
std::list<unsigned long> lstulVar; cl.DefineSubOption("ulvar", lstulVar, "list of unsigned long variable");
std::list<unsigned int> lstuiVar; cl.DefineSubOption("uivar", lstuiVar, "list of unsigned int variable");
std::list<unsigned long long> lstullVar; cl.DefineSubOption("ullvar", lstullVar, "list of unsigned long long variable");
std::list<size_t> lstnVar; cl.DefineSubOption("nvar", lstnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstcVar, -1, 2, -3);
EXPECT_ARREQ(lstsVar, -2, 3, -4);
EXPECT_ARREQ(lstlVar, -3, 4, -5);
EXPECT_ARREQ(lstiVar, -4, 5, -6);
EXPECT_ARREQ(lstllVar, -5, 6, -7);
EXPECT_ARREQ(lstucVar, 6u, 7u, 8u);
EXPECT_ARREQ(lstusVar, 7u, 8u, 9u);
EXPECT_ARREQ(lstulVar, 8u, 9u, 10u);
EXPECT_ARREQ(lstuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(lstullVar, 10u, 11u, 12u);
EXPECT_ARREQ(lstnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseFloatingPoint)
{
const char* rgszCommandLine[] = {"this_exe.app", "--fvar-12345.6789", "--dvar12345678.9E10", "--ldvar0.12345678E-5"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
float fVar = 0; cl.DefineSubOption("fvar", fVar, "float variable");
double dVar = 0; cl.DefineSubOption("dvar", dVar, "double variable");
long double ldVar = 0; cl.DefineSubOption("ldvar", ldVar, "long double variable");
float fControl = 123.456f; cl.DefineSubOption("fcontrol", fControl, "float no change!");
double dControl = 456.789; cl.DefineSubOption("dcontrol", dControl, "double no change!");
long double ldControl = 876.543; cl.DefineSubOption("ldcontrol", ldControl, "long double no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_FPEQ(fVar, -12345.6789f);
EXPECT_FPEQ(dVar, 12345678.9E10);
#ifndef __GNUC__ // Long double is not well supported by G++ compiler
EXPECT_FPEQ(ldVar, 0.12345678E-5);
#endif
EXPECT_FPEQ(fControl, 123.456f);
EXPECT_FPEQ(dControl, 456.789);
EXPECT_FPEQ(ldControl, 876.543);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseFloatingPointVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "--fvar-12345.6789,9876.54321,134679", "--dvar12345678.9E10,1098765.43E21", "--ldvar0.12345678E-5,0.87654321E9"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::vector<float> vecfVar; cl.DefineSubOption("fvar", vecfVar, "vector of float variable");
std::vector<double> vecdVar; cl.DefineSubOption("dvar", vecdVar, "vector of double variable");
std::vector<long double> vecldVar; cl.DefineSubOption("ldvar", vecldVar, "vector of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(vecdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(vecldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseFloatingPointSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "--fvar-12345.6789,9876.54321,134679", "--dvar12345678.9E10,1098765.43E21", "--ldvar0.12345678E-5,0.87654321E9"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
sdv::sequence<float> seqfVar; cl.DefineSubOption("fvar", seqfVar, "sequence of float variable");
sdv::sequence<double> seqdVar; cl.DefineSubOption("dvar", seqdVar, "sequence of double variable");
sdv::sequence<long double> seqldVar; cl.DefineSubOption("ldvar", seqldVar, "sequence of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(seqdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(seqldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseFloatingPointList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--fvar-12345.6789,9876.54321,134679", "--dvar12345678.9E10,1098765.43E21", "--ldvar0.12345678E-5,0.87654321E9"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::list<float> lstfVar; cl.DefineSubOption("fvar", lstfVar, "list of float variable");
std::list<double> lstdVar; cl.DefineSubOption("dvar", lstdVar, "list of double variable");
std::list<long double> lstldVar; cl.DefineSubOption("ldvar", lstldVar, "list of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(lstdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(lstldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseEnum)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "--unscoped_enumtest2", "--scoped_enumtest5"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
EUnscopedTest eUnscopedTest = test1; cl.DefineSubOption("unscoped_enum", eUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedTest = EScopedTest::test4; cl.DefineSubOption("scoped_enum", eScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EUnscopedTest eUnscopedControl = test1; cl.DefineSubOption("unscoped_enum_control", eUnscopedControl, "unscoped enum no change!").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedControl = EScopedTest::test4; cl.DefineSubOption("scoped_enum_control", eScopedControl, "scoped enum no change!").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(eUnscopedTest, test2);
EXPECT_EQ(eScopedTest, EScopedTest::test5);
EXPECT_EQ(eUnscopedControl, test1);
EXPECT_EQ(eScopedControl, EScopedTest::test4);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseEnumVector)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "--unscoped_enumtest2,test3", "--scoped_enumtest5,test6"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::vector<EUnscopedTest> vecUnscopedTest; cl.DefineSubOption("unscoped_enum", vecUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::vector<EScopedTest> vecScopedTest; cl.DefineSubOption("scoped_enum", vecScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecUnscopedTest, test2, test3);
EXPECT_ARREQ(vecScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseEnumSequence)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "--unscoped_enumtest2,test3", "--scoped_enumtest5,test6"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
sdv::sequence<EUnscopedTest> seqUnscopedTest; cl.DefineSubOption("unscoped_enum", seqUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
sdv::sequence<EScopedTest> seqScopedTest; cl.DefineSubOption("scoped_enum", seqScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqUnscopedTest, test2, test3);
EXPECT_ARREQ(seqScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseEnumList)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "--unscoped_enumtest2,test3", "--scoped_enumtest5,test6"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::list<EUnscopedTest> lstUnscopedTest; cl.DefineSubOption("unscoped_enum", lstUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::list<EScopedTest> lstScopedTest; cl.DefineSubOption("scoped_enum", lstScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstUnscopedTest, test2, test3);
EXPECT_ARREQ(lstScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseString)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1test_a", "--ssu8var1test_b", "--ssvar2\"test_c\"",
"--ssu8var2\"test_d\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::string ssVar1; cl.DefineSubOption("ssvar1", ssVar1, "std::string variable");
sdv::u8string ssu8Var1; cl.DefineSubOption("ssu8var1", ssu8Var1, "sdv::u8string variable");
std::string ssVar2; cl.DefineSubOption("ssvar2", ssVar2, "sdv::string variable");
sdv::u8string ssu8Var2; cl.DefineSubOption("ssu8var2", ssu8Var2, "sdv::u8string variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(ssVar1, "test_a");
EXPECT_EQ(ssu8Var1, "test_b");
EXPECT_EQ(ssVar2, "test_c");
EXPECT_EQ(ssu8Var2, "test_d");
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseStringVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1test_a,test_b", "--ssu8var1test_b,test_c", "--ssvar2\"test_c\",\"test_d\"",
"--ssu8var2\"test_d\",\"test_e\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::vector<std::string> vecssVar1; cl.DefineSubOption("ssvar1", vecssVar1, "std::vector<std::string> variable");
std::vector<sdv::u8string> vecssu8Var1; cl.DefineSubOption("ssu8var1", vecssu8Var1, "std::vector<sdv::u8string> variable");
std::vector<std::string> vecssVar2; cl.DefineSubOption("ssvar2", vecssVar2, "std::vector<sdv::string> variable");
std::vector<sdv::u8string> vecssu8Var2; cl.DefineSubOption("ssu8var2", vecssu8Var2, "std::vector<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecssVar1, "test_a", "test_b");
EXPECT_ARREQ(vecssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(vecssVar2, "test_c", "test_d");
EXPECT_ARREQ(vecssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseStringSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1test_a,test_b", "--ssu8var1test_b,test_c", "--ssvar2\"test_c\",\"test_d\"",
"--ssu8var2\"test_d\",\"test_e\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
sdv::sequence<std::string> seqssVar1; cl.DefineSubOption("ssvar1", seqssVar1, "sdv::sequence<std::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var1; cl.DefineSubOption("ssu8var1", seqssu8Var1, "sdv::sequence<sdv::u8string> variable");
sdv::sequence<std::string> seqssVar2; cl.DefineSubOption("ssvar2", seqssVar2, "sdv::sequence<sdv::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var2; cl.DefineSubOption("ssu8var2", seqssu8Var2, "sdv::sequence<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqssVar1, "test_a", "test_b");
EXPECT_ARREQ(seqssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(seqssVar2, "test_c", "test_d");
EXPECT_ARREQ(seqssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseStringList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--ssvar1test_a,test_b", "--ssu8var1test_b,test_c", "--ssvar2\"test_c\",\"test_d\"",
"--ssu8var2\"test_d\",\"test_e\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::list<std::string> lstssVar1; cl.DefineSubOption("ssvar1", lstssVar1, "std::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var1; cl.DefineSubOption("ssu8var1", lstssu8Var1, "std::list<sdv::u8string> variable");
std::list<std::string> lstssVar2; cl.DefineSubOption("ssvar2", lstssVar2, "td::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var2; cl.DefineSubOption("ssu8var2", lstssu8Var2, "std::list<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstssVar1, "test_a", "test_b");
EXPECT_ARREQ(lstssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(lstssVar2, "test_c", "test_d");
EXPECT_ARREQ(lstssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParsePath)
{
const char* rgszCommandLine[] = {"this_exe.app", "--pathvar1abc.def", "--pathvar2\"ghi.jkl\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::filesystem::path pathVar1; cl.DefineSubOption("pathvar1", pathVar1, "std::filesystem::path variable");
std::filesystem::path pathVar2; cl.DefineSubOption("pathvar2", pathVar2, "std::filesystem::path variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(pathVar1, "abc.def");
EXPECT_EQ(pathVar2, "ghi.jkl");
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParsePathSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "--pathvar1abc.def,ghi.jkl", "--pathvar2\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
sdv::sequence<std::filesystem::path> seqpathVar1; cl.DefineSubOption("pathvar1", seqpathVar1, "sdv::sequence<std::filesystem::path> variable");
sdv::sequence<std::filesystem::path> seqpathVar2; cl.DefineSubOption("pathvar2", seqpathVar2, "sdv::sequence<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(seqpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParsePathList)
{
const char* rgszCommandLine[] = {"this_exe.app", "--pathvar1abc.def,ghi.jkl", "--pathvar2\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::list<std::filesystem::path> lstpathVar1; cl.DefineSubOption("pathvar1", lstpathVar1, "std::list<std::filesystem::path> variable");
std::list<std::filesystem::path> lstpathVar2; cl.DefineSubOption("pathvar2", lstpathVar2, "std::list<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(lstpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionParseFlags)
{
const char* rgszCommandLine[] = {"this_exe.app", "--flag_neg+", "--flag_pos-"};
CCommandLine cl(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
bool bFlagNeg = false; cl.DefineFlagSubOption("flag_neg", bFlagNeg, "negative flag variable");
bool bFlagPos = true; cl.DefineFlagSubOption("flag_pos", bFlagPos, "positive flag variable");
bool bFlagNegControl = false; cl.DefineFlagSubOption("controlflag_neg", bFlagNegControl, "negative flag variable");
bool bFlagPosControl = true; cl.DefineFlagSubOption("control_flag_pos", bFlagPosControl, "positive flag variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bFlagNeg);
EXPECT_FALSE(bFlagPos);
EXPECT_FALSE(bFlagNegControl);
EXPECT_TRUE(bFlagPosControl);
}
TEST_F(CCommandLineParserTestNoAssignment, SubOptionOverlappingArg)
{
// Mixing up -server and -s
const char* rgszCommandLine1[] = {"this_exe.app", "--server"};
CCommandLine cl1(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
bool bSilence = false; cl1.DefineSubOption("s", bSilence, "silence flag");
bool bServer = false; cl1.DefineSubOption("server", bServer, "server enabled");
EXPECT_NO_THROW(cl1.Parse(std::extent<decltype(rgszCommandLine1)>::value, rgszCommandLine1));
EXPECT_FALSE(bSilence);
EXPECT_TRUE(bServer);
// Mixing up -instance<val> and -instance_a
const char* rgszCommandLine2[] = {"this_exe.app", "--instance_a"};
CCommandLine cl2(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
std::string ssInstance; cl2.DefineSubOption("instance", ssInstance, "Instance ID");
bool bInstance_a = false; cl2.DefineSubOption("instance_a", bInstance_a, "Instance A is activited");
EXPECT_NO_THROW(cl2.Parse(std::extent<decltype(rgszCommandLine2)>::value, rgszCommandLine2));
EXPECT_TRUE(ssInstance.empty());
EXPECT_TRUE(bInstance_a);
// Mixiong up -enable_opt+ and -enable_options
const char* rgszCommandLine3[] = {"this_exe.app", "--enable_options"};
CCommandLine cl3(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
bool bOptFlag = false; cl3.DefineSubOption("enable_opt", bOptFlag, "enable/disable one option");
bool bOptions = false; cl3.DefineSubOption("enable_options", bOptions, "enable all options");
EXPECT_NO_THROW(cl3.Parse(std::extent<decltype(rgszCommandLine3)>::value, rgszCommandLine3));
EXPECT_FALSE(bOptFlag);
EXPECT_TRUE(bOptions);
// Mixing up -server and -s when double assignment
const char* rgszCommandLine4[] = {"this_exe.app", "--s"};
CCommandLine cl4(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
bSilence = false; auto rSilenceOption = cl4.DefineOption("silence", bSilence, "silence flag");
rSilenceOption.AddSubOptionName("s");
bServer = false; cl4.DefineSubOption("server", bServer, "server enabled");
EXPECT_NO_THROW(cl4.Parse(std::extent<decltype(rgszCommandLine4)>::value, rgszCommandLine4));
EXPECT_TRUE(bSilence);
EXPECT_FALSE(bServer);
}

View File

@@ -0,0 +1,557 @@
#include "../../include/gtest_custom.h"
#include "commandline_parser_test.h"
#include "../../../global/cmdlnparser/cmdlnparser.h"
#ifdef _WIN32
TEST_F(CCommandLineParserTest, WOptionParseBoolean)
{
const char* rgszCommandLine[] = {"this_exe.app", "/select"};
CCommandLine cl;
bool bSelect = false; cl.DefineOption("select", bSelect, "Select it!");
bool bControlNegative = false; cl.DefineOption("neg_control", bControlNegative, "No change!");
bool bControlPositive = true; cl.DefineOption("pos_control", bControlPositive, "No change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bSelect);
EXPECT_FALSE(bControlNegative);
EXPECT_TRUE(bControlPositive);
}
TEST_F(CCommandLineParserTest, WOptionParseIntegralIndependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "/i8var=-1", "/i16var=-2", "/i32var=-3", "/i64var=-4",
"/ui8var=5", "/ui16var=6", "/ui32var=7", "/ui64var=8"};
CCommandLine cl;
int8_t i8Var = 0; cl.DefineOption("i8var", i8Var, "int8_t variable");
int16_t i16Var = 0; cl.DefineOption("i16var", i16Var, "int16_t variable");
int32_t i32Var = 0; cl.DefineOption("i32var", i32Var, "int32_t variable");
int64_t i64Var = 0; cl.DefineOption("i64var", i64Var, "int64_t variable");
uint8_t ui8Var = 0; cl.DefineOption("ui8var", ui8Var, "uint8_t variable");
uint16_t ui16Var = 0; cl.DefineOption("ui16var", ui16Var, "uint16_t variable");
uint32_t ui32Var = 0; cl.DefineOption("ui32var", ui32Var, "uint32_t variable");
uint64_t ui64Var = 0; cl.DefineOption("ui64var", ui64Var, "uint64_t variable");
int8_t i8Control = -10; cl.DefineOption("i8control", i8Control, "int8_t no change!");
int16_t i16Control = -20; cl.DefineOption("i16control", i16Control, "int16_t no change!");
int32_t i32Control = -30; cl.DefineOption("i32control", i32Control, "int32_t no change!");
int64_t i64Control = -40; cl.DefineOption("i64control", i64Control, "int64_t no change!");
uint8_t ui8Control = 50; cl.DefineOption("ui8control", ui8Control, "uint8_t no change!");
uint16_t ui16Control = 60; cl.DefineOption("ui16control", ui16Control, "uint16_t no change!");
uint32_t ui32Control = 70; cl.DefineOption("ui32control", ui32Control, "uint32_t no change!");
uint64_t ui64Control = 80; cl.DefineOption("ui64control", ui64Control, "uint64_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(i8Var, -1);
EXPECT_EQ(i16Var, -2);
EXPECT_EQ(i32Var, -3);
EXPECT_EQ(i64Var, -4);
EXPECT_EQ(ui8Var, 5u);
EXPECT_EQ(ui16Var, 6u);
EXPECT_EQ(ui32Var, 7u);
EXPECT_EQ(ui64Var, 8u);
EXPECT_EQ(i8Control, -10);
EXPECT_EQ(i16Control, -20);
EXPECT_EQ(i32Control, -30);
EXPECT_EQ(i64Control, -40);
EXPECT_EQ(ui8Control, 50u);
EXPECT_EQ(ui16Control, 60u);
EXPECT_EQ(ui32Control, 70u);
EXPECT_EQ(ui64Control, 80u);
}
TEST_F(CCommandLineParserTest, WOptionParseIntegralDedependent)
{
const char* rgszCommandLine[] = {"this_exe.app", "/cvar=-1", "/svar=-2", "/lvar=-3", "/ivar=-4", "/llvar=-5",
"/ucvar=6", "/usvar=7", "/ulvar=8", "/uivar=9", "/ullvar=10", "/nvar=11"};
CCommandLine cl;
signed char cVar = 0; cl.DefineOption("cvar", cVar, "char variable");
short sVar = 0; cl.DefineOption("svar", sVar, "short variable");
long lVar = 0; cl.DefineOption("lvar", lVar, "long variable");
int iVar = 0; cl.DefineOption("ivar", iVar, "int variable");
long long llVar = 0; cl.DefineOption("llvar", llVar, "long long variable");
unsigned char ucVar = 0; cl.DefineOption("ucvar", ucVar, "unsigned char variable");
unsigned short usVar = 0; cl.DefineOption("usvar", usVar, "unsigned short variable");
unsigned long ulVar = 0; cl.DefineOption("ulvar", ulVar, "unsigned long variable");
unsigned int uiVar = 0; cl.DefineOption("uivar", uiVar, "unsigned int variable");
unsigned long long ullVar = 0; cl.DefineOption("ullvar", ullVar, "unsigned long long variable");
size_t nVar = 0; cl.DefineOption("nvar", nVar, "size_t variable");
signed char cControl = -10; cl.DefineOption("ccontrol", cControl, "char no change!");
short sControl = -20; cl.DefineOption("scontrol", sControl, "short no change!");
long lControl = -30; cl.DefineOption("lcontrol", lControl, "long no change!");
int iControl = -40; cl.DefineOption("icontrol", iControl, "int no change!");
long long llControl = -50; cl.DefineOption("llcontrol", llControl, "long long no change!");
unsigned char ucControl = 60; cl.DefineOption("uccontrol", ucControl, "unsigned char no change!");
unsigned short usControl = 70; cl.DefineOption("uscontrol", usControl, "unsigned short no change!");
unsigned long ulControl = 80; cl.DefineOption("ulcontrol", ulControl, "unsigned long no change!");
unsigned int uiControl = 90; cl.DefineOption("uicontrol", uiControl, "unsigned int no change!");
unsigned long long ullControl = 100; cl.DefineOption("ullcontrol", ullControl, "unsigned long long no change!");
size_t nControl = 110; cl.DefineOption("ncontrol", nControl, "size_t no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(cVar, -1);
EXPECT_EQ(sVar, -2);
EXPECT_EQ(lVar, -3);
EXPECT_EQ(iVar, -4);
EXPECT_EQ(llVar, -5);
EXPECT_EQ(ucVar, 6u);
EXPECT_EQ(usVar, 7u);
EXPECT_EQ(ulVar, 8u);
EXPECT_EQ(uiVar, 9u);
EXPECT_EQ(ullVar, 10u);
EXPECT_EQ(nVar, 11u);
EXPECT_EQ(cControl, -10);
EXPECT_EQ(sControl, -20);
EXPECT_EQ(lControl, -30);
EXPECT_EQ(iControl, -40);
EXPECT_EQ(llControl, -50);
EXPECT_EQ(ucControl, 60u);
EXPECT_EQ(usControl, 70u);
EXPECT_EQ(ulControl, 80u);
EXPECT_EQ(uiControl, 90u);
EXPECT_EQ(ullControl, 100u);
EXPECT_EQ(nControl, 110u);
}
TEST_F(CCommandLineParserTest, WOptionParseIntegralIndependentVector)
{
// Attention: std::vector<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"/i8var=-1,2, -3",*/ "/i16var=-2,3,-4", "/i32var=-3,4,-5", "/i64var=-4,5,-6",
"/ui8var=5,6,7", "/ui16var=6,7,8", "/ui32var=7,8,9", "/ui64var=8,9,10"};
CCommandLine cl;
//std::vector<int8_t> veci8Var; cl.DefineOption("i8var", veci8Var, "vector of int8_t variable");
std::vector<int16_t> veci16Var; cl.DefineOption("i16var", veci16Var, "vector of int16_t variable");
std::vector<int32_t> veci32Var; cl.DefineOption("i32var", veci32Var, "vector of int32_t variable");
std::vector<int64_t> veci64Var; cl.DefineOption("i64var", veci64Var, "vector of int64_t variable");
std::vector<uint8_t> vecui8Var; cl.DefineOption("ui8var", vecui8Var, "vector of uint8_t variable");
std::vector<uint16_t> vecui16Var; cl.DefineOption("ui16var", vecui16Var, "vector of uint16_t variable");
std::vector<uint32_t> vecui32Var; cl.DefineOption("ui32var", vecui32Var, "vector of uint32_t variable");
std::vector<uint64_t> vecui64Var; cl.DefineOption("ui64var", vecui64Var, "vector of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(veci8Var, -1, 2, -3);
EXPECT_ARREQ(veci16Var, -2, 3, -4);
EXPECT_ARREQ(veci32Var, -3, 4, -5);
EXPECT_ARREQ(veci64Var, -4, 5, -6);
EXPECT_ARREQ(vecui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(vecui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(vecui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(vecui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTest, WOptionParseIntegralDedependentVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "/cvar=-1,2,-3", "/svar=-2,3,-4", "/lvar=-3,4,-5", "/ivar=-4,5,-6", "/llvar=-5,6,-7",
"/ucvar=6,7,8", "/usvar=7,8,9", "/ulvar=8,9,10", "/uivar=9,10,11", "/ullvar=10,11,12", "/nvar=11,12,13"};
CCommandLine cl;
std::vector<signed char> veccVar; cl.DefineOption("cvar", veccVar, "vector of char variable");
std::vector<short> vecsVar; cl.DefineOption("svar", vecsVar, "vector of short variable");
std::vector<long> veclVar; cl.DefineOption("lvar", veclVar, "vector of long variable");
std::vector<int> veciVar; cl.DefineOption("ivar", veciVar, "vector of int variable");
std::vector<long long> vecllVar; cl.DefineOption("llvar", vecllVar, "vector of long long variable");
std::vector<unsigned char> vecucVar; cl.DefineOption("ucvar", vecucVar, "vector of unsigned char variable");
std::vector<unsigned short> vecusVar; cl.DefineOption("usvar", vecusVar, "vector of unsigned short variable");
std::vector<unsigned long> veculVar; cl.DefineOption("ulvar", veculVar, "vector of unsigned long variable");
std::vector<unsigned int> vecuiVar; cl.DefineOption("uivar", vecuiVar, "vector of unsigned int variable");
std::vector<unsigned long long> vecullVar; cl.DefineOption("ullvar", vecullVar, "vector of unsigned long long variable");
std::vector<size_t> vecnVar; cl.DefineOption("nvar", vecnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(veccVar, -1, 2, -3);
EXPECT_ARREQ(vecsVar, -2, 3, -4);
EXPECT_ARREQ(veclVar, -3, 4, -5);
EXPECT_ARREQ(veciVar, -4, 5, -6);
EXPECT_ARREQ(vecllVar, -5, 6, -7);
EXPECT_ARREQ(vecucVar, 6u, 7u, 8u);
EXPECT_ARREQ(vecusVar, 7u, 8u, 9u);
EXPECT_ARREQ(veculVar, 8u, 9u, 10u);
EXPECT_ARREQ(vecuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(vecullVar, 10u, 11u, 12u);
EXPECT_ARREQ(vecnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTest, WOptionParseIntegralIndependentSequence)
{
// Attention: std::vector<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"/i8var=-1,2, -3",*/ "/i16var=-2,3,-4", "/i32var=-3,4,-5", "/i64var=-4,5,-6",
"/ui8var=5,6,7", "/ui16var=6,7,8", "/ui32var=7,8,9", "/ui64var=8,9,10"};
CCommandLine cl;
//sdv::sequence<int8_t> seqi8Var; cl.DefineOption("i8var", seqi8Var, "sequence of int8_t variable");
sdv::sequence<int16_t> seqi16Var; cl.DefineOption("i16var", seqi16Var, "sequence of int16_t variable");
sdv::sequence<int32_t> seqi32Var; cl.DefineOption("i32var", seqi32Var, "sequence of int32_t variable");
sdv::sequence<int64_t> seqi64Var; cl.DefineOption("i64var", seqi64Var, "sequence of int64_t variable");
sdv::sequence<uint8_t> sequi8Var; cl.DefineOption("ui8var", sequi8Var, "sequence of uint8_t variable");
sdv::sequence<uint16_t> sequi16Var; cl.DefineOption("ui16var", sequi16Var, "sequence of uint16_t variable");
sdv::sequence<uint32_t> sequi32Var; cl.DefineOption("ui32var", sequi32Var, "sequence of uint32_t variable");
sdv::sequence<uint64_t> sequi64Var; cl.DefineOption("ui64var", sequi64Var, "sequence of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(seqi8Var, -1, 2, -3);
EXPECT_ARREQ(seqi16Var, -2, 3, -4);
//EXPECT_ARREQ(seqi32Var, -3, 4, -5);
EXPECT_ARREQ(seqi64Var, -4, 5, -6);
EXPECT_ARREQ(sequi8Var, 5u, 6u, 7u);
EXPECT_ARREQ(sequi16Var, 6u, 7u, 8u);
EXPECT_ARREQ(sequi32Var, 7u, 8u, 9u);
EXPECT_ARREQ(sequi64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTest, WOptionParseIntegralDedependentSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "/cvar=-1,2,-3", "/svar=-2,3,-4", "/lvar=-3,4,-5", /*"/ivar=-4,5,-6",*/ "/llvar=-5,6,-7",
"/ucvar=6,7,8", "/usvar=7,8,9", "/ulvar=8,9,10", "/uivar=9,10,11", "/ullvar=10,11,12", "/nvar=11,12,13"};
CCommandLine cl;
sdv::sequence<signed char> seqcVar; cl.DefineOption("cvar", seqcVar, "sequence of char variable");
sdv::sequence<short> seqsVar; cl.DefineOption("svar", seqsVar, "sequence of short variable");
sdv::sequence<long> seqlVar; cl.DefineOption("lvar", seqlVar, "sequence of long variable");
//sdv::sequence<int> seqiVar; cl.DefineOption("ivar", seqiVar, "sequence of int variable");
sdv::sequence<long long> seqllVar; cl.DefineOption("llvar", seqllVar, "sequence of long long variable");
sdv::sequence<unsigned char> sequcVar; cl.DefineOption("ucvar", sequcVar, "sequence of unsigned char variable");
sdv::sequence<unsigned short> sequsVar; cl.DefineOption("usvar", sequsVar, "sequence of unsigned short variable");
sdv::sequence<unsigned long> sequlVar; cl.DefineOption("ulvar", sequlVar, "sequence of unsigned long variable");
sdv::sequence<unsigned int> sequiVar; cl.DefineOption("uivar", sequiVar, "sequence of unsigned int variable");
sdv::sequence<unsigned long long> sequllVar; cl.DefineOption("ullvar", sequllVar, "sequence of unsigned long long variable");
sdv::sequence<size_t> seqnVar; cl.DefineOption("nvar", seqnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqcVar, -1, 2, -3);
EXPECT_ARREQ(seqsVar, -2, 3, -4);
EXPECT_ARREQ(seqlVar, -3, 4, -5);
//EXPECT_ARREQ(seqiVar, -4, 5, -6);
EXPECT_ARREQ(seqllVar, -5, 6, -7);
EXPECT_ARREQ(sequcVar, 6u, 7u, 8u);
EXPECT_ARREQ(sequsVar, 7u, 8u, 9u);
EXPECT_ARREQ(sequlVar, 8u, 9u, 10u);
EXPECT_ARREQ(sequiVar, 9u, 10u, 11u);
EXPECT_ARREQ(sequllVar, 10u, 11u, 12u);
EXPECT_ARREQ(seqnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTest, WOptionParseIntegralIndependentList)
{
// Attention: std::list<int8_t> causes compiler problems with MSVC and GCC.
const char* rgszCommandLine[] = {"this_exe.app", /*"/i8var=-1,2, -3",*/ "/i16var=-2,3,-4", "/i32var=-3,4,-5", "/i64var=-4,5,-6",
"/ui8var=5,6,7", "/ui16var=6,7,8", "/ui32var=7,8,9", "/ui64var=8,9,10"};
CCommandLine cl;
//std::list<int8_t> lsti8Var; cl.DefineOption("i8var", lsti8Var, "list of int8_t variable");
std::list<int16_t> lsti16Var; cl.DefineOption("i16var", lsti16Var, "list of int16_t variable");
std::list<int32_t> lsti32Var; cl.DefineOption("i32var", lsti32Var, "list of int32_t variable");
std::list<int64_t> lsti64Var; cl.DefineOption("i64var", lsti64Var, "list of int64_t variable");
std::list<uint8_t> lstui8Var; cl.DefineOption("ui8var", lstui8Var, "list of uint8_t variable");
std::list<uint16_t> lstui16Var; cl.DefineOption("ui16var", lstui16Var, "list of uint16_t variable");
std::list<uint32_t> lstui32Var; cl.DefineOption("ui32var", lstui32Var, "list of uint32_t variable");
std::list<uint64_t> lstui64Var; cl.DefineOption("ui64var", lstui64Var, "list of uint64_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
//EXPECT_ARREQ(lsti8Var, -1, 2, -3);
EXPECT_ARREQ(lsti16Var, -2, 3, -4);
EXPECT_ARREQ(lsti32Var, -3, 4, -5);
EXPECT_ARREQ(lsti64Var, -4, 5, -6);
EXPECT_ARREQ(lstui8Var, 5u, 6u, 7u);
EXPECT_ARREQ(lstui16Var, 6u, 7u, 8u);
EXPECT_ARREQ(lstui32Var, 7u, 8u, 9u);
EXPECT_ARREQ(lstui64Var, 8u, 9u, 10u);
}
TEST_F(CCommandLineParserTest, WOptionParseIntegralDedependentList)
{
const char* rgszCommandLine[] = {"this_exe.app", "/cvar=-1,2,-3", "/svar=-2,3,-4", "/lvar=-3,4,-5", "/ivar=-4,5,-6", "/llvar=-5,6,-7",
"/ucvar=6,7,8", "/usvar=7,8,9", "/ulvar=8,9,10", "/uivar=9,10,11", "/ullvar=10,11,12", "/nvar=11,12,13"};
CCommandLine cl;
std::list<signed char> lstcVar; cl.DefineOption("cvar", lstcVar, "list of char variable");
std::list<short> lstsVar; cl.DefineOption("svar", lstsVar, "list of short variable");
std::list<long> lstlVar; cl.DefineOption("lvar", lstlVar, "list of long variable");
std::list<int> lstiVar; cl.DefineOption("ivar", lstiVar, "list of int variable");
std::list<long long> lstllVar; cl.DefineOption("llvar", lstllVar, "list of long long variable");
std::list<unsigned char> lstucVar; cl.DefineOption("ucvar", lstucVar, "list of unsigned char variable");
std::list<unsigned short> lstusVar; cl.DefineOption("usvar", lstusVar, "list of unsigned short variable");
std::list<unsigned long> lstulVar; cl.DefineOption("ulvar", lstulVar, "list of unsigned long variable");
std::list<unsigned int> lstuiVar; cl.DefineOption("uivar", lstuiVar, "list of unsigned int variable");
std::list<unsigned long long> lstullVar; cl.DefineOption("ullvar", lstullVar, "list of unsigned long long variable");
std::list<size_t> lstnVar; cl.DefineOption("nvar", lstnVar, "list of size_t variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstcVar, -1, 2, -3);
EXPECT_ARREQ(lstsVar, -2, 3, -4);
EXPECT_ARREQ(lstlVar, -3, 4, -5);
EXPECT_ARREQ(lstiVar, -4, 5, -6);
EXPECT_ARREQ(lstllVar, -5, 6, -7);
EXPECT_ARREQ(lstucVar, 6u, 7u, 8u);
EXPECT_ARREQ(lstusVar, 7u, 8u, 9u);
EXPECT_ARREQ(lstulVar, 8u, 9u, 10u);
EXPECT_ARREQ(lstuiVar, 9u, 10u, 11u);
EXPECT_ARREQ(lstullVar, 10u, 11u, 12u);
EXPECT_ARREQ(lstnVar, 11u, 12u, 13u);
}
TEST_F(CCommandLineParserTest, WOptionParseFloatingPoint)
{
const char* rgszCommandLine[] = {"this_exe.app", "/fvar=-12345.6789", "/dvar=12345678.9E10", "/ldvar=0.12345678E-5"};
CCommandLine cl;
float fVar = 0; cl.DefineOption("fvar", fVar, "float variable");
double dVar = 0; cl.DefineOption("dvar", dVar, "double variable");
long double ldVar = 0; cl.DefineOption("ldvar", ldVar, "long double variable");
float fControl = 123.456f; cl.DefineOption("fcontrol", fControl, "float no change!");
double dControl = 456.789; cl.DefineOption("dcontrol", dControl, "double no change!");
long double ldControl = 876.543; cl.DefineOption("ldcontrol", ldControl, "long double no change!");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_FPEQ(fVar, -12345.6789f);
EXPECT_FPEQ(dVar, 12345678.9E10);
EXPECT_FPEQ(ldVar, 0.12345678E-5);
EXPECT_FPEQ(fControl, 123.456f);
EXPECT_FPEQ(dControl, 456.789);
EXPECT_FPEQ(ldControl, 876.543);
}
TEST_F(CCommandLineParserTest, WOptionParseFloatingPointVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "/fvar=-12345.6789,9876.54321,134679", "/dvar=12345678.9E10,1098765.43E21", "/ldvar=0.12345678E-5,0.87654321E9"};
CCommandLine cl;
std::vector<float> vecfVar; cl.DefineOption("fvar", vecfVar, "vector of float variable");
std::vector<double> vecdVar; cl.DefineOption("dvar", vecdVar, "vector of double variable");
std::vector<long double> vecldVar; cl.DefineOption("ldvar", vecldVar, "vector of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(vecdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(vecldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTest, WOptionParseFloatingPointSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "/fvar=-12345.6789,9876.54321,134679", "/dvar=12345678.9E10,1098765.43E21", "/ldvar=0.12345678E-5,0.87654321E9"};
CCommandLine cl;
sdv::sequence<float> seqfVar; cl.DefineOption("fvar", seqfVar, "sequence of float variable");
sdv::sequence<double> seqdVar; cl.DefineOption("dvar", seqdVar, "sequence of double variable");
sdv::sequence<long double> seqldVar; cl.DefineOption("ldvar", seqldVar, "sequence of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(seqdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(seqldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTest, WOptionParseFloatingPointList)
{
const char* rgszCommandLine[] = {"this_exe.app", "/fvar=-12345.6789,9876.54321,134679", "/dvar=12345678.9E10,1098765.43E21", "/ldvar=0.12345678E-5,0.87654321E9"};
CCommandLine cl;
std::list<float> lstfVar; cl.DefineOption("fvar", lstfVar, "list of float variable");
std::list<double> lstdVar; cl.DefineOption("dvar", lstdVar, "list of double variable");
std::list<long double> lstldVar; cl.DefineOption("ldvar", lstldVar, "list of long double variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstfVar, -12345.6789f, 9876.54321f, 134679.f);
EXPECT_ARREQ(lstdVar, 12345678.9E10, 1098765.43E21);
// Attention: GCC doesn't support long double very well.
//EXPECT_ARREQ(lstldVar, 0.12345678E-5, 0.87654321E9);
}
TEST_F(CCommandLineParserTest, WOptionParseEnum)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "/unscoped_enum=test2", "/scoped_enum=test5"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
EUnscopedTest eUnscopedTest = test1; cl.DefineOption("unscoped_enum", eUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedTest = EScopedTest::test4; cl.DefineOption("scoped_enum", eScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EUnscopedTest eUnscopedControl = test1; cl.DefineOption("unscoped_enum_control", eUnscopedControl, "unscoped enum no change!").AddAssociations(rgsUnscopedEnumAssociations);
EScopedTest eScopedControl = EScopedTest::test4; cl.DefineOption("scoped_enum_control", eScopedControl, "scoped enum no change!").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(eUnscopedTest, test2);
EXPECT_EQ(eScopedTest, EScopedTest::test5);
EXPECT_EQ(eUnscopedControl, test1);
EXPECT_EQ(eScopedControl, EScopedTest::test4);
}
TEST_F(CCommandLineParserTest, WOptionParseEnumVector)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "/unscoped_enum=test2,test3", "/scoped_enum=test5,test6"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::vector<EUnscopedTest> vecUnscopedTest; cl.DefineOption("unscoped_enum", vecUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::vector<EScopedTest> vecScopedTest; cl.DefineOption("scoped_enum", vecScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecUnscopedTest, test2, test3);
EXPECT_ARREQ(vecScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTest, WOptionParseEnumSequence)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "/unscoped_enum=test2,test3", "/scoped_enum=test5,test6"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
sdv::sequence<EUnscopedTest> seqUnscopedTest; cl.DefineOption("unscoped_enum", seqUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
sdv::sequence<EScopedTest> seqScopedTest; cl.DefineOption("scoped_enum", seqScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqUnscopedTest, test2, test3);
EXPECT_ARREQ(seqScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTest, WOptionParseEnumList)
{
enum EUnscopedTest { test1, test2, test3 };
enum class EScopedTest : size_t {test4, test5, test6};
const char* rgszCommandLine[] = {"this_exe.app", "/unscoped_enum=test2,test3", "/scoped_enum=test5,test6"};
CCommandLine cl;
SEnumArgumentAssoc<EUnscopedTest> rgsUnscopedEnumAssociations[] = {
{test1, "test1", "Test the #1"},
{test2, "test2", "Test the #2"},
{test3, "test3", "Test the #3"}
};
SEnumArgumentAssoc<EScopedTest> rgsScopedEnumAssociations[] = {
{EScopedTest::test4, "test4", "Test the #4"},
{EScopedTest::test5, "test5", "Test the #5"},
{EScopedTest::test6, "test6", "Test the #6"}
};
std::list<EUnscopedTest> lstUnscopedTest; cl.DefineOption("unscoped_enum", lstUnscopedTest, "unscoped enum variable").AddAssociations(rgsUnscopedEnumAssociations);
std::list<EScopedTest> lstScopedTest; cl.DefineOption("scoped_enum", lstScopedTest, "scoped enum variable").AddAssociations(rgsScopedEnumAssociations);
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstUnscopedTest, test2, test3);
EXPECT_ARREQ(lstScopedTest, EScopedTest::test5, EScopedTest::test6);
}
TEST_F(CCommandLineParserTest, WOptionParseString)
{
const char* rgszCommandLine[] = {"this_exe.app", "/ssvar1=test_a", "/ssu8var1=test_b", "/ssvar2=\"test_c\"",
"/ssu8var2=\"test_d\""};
CCommandLine cl;
std::string ssVar1; cl.DefineOption("ssvar1", ssVar1, "std::string variable");
sdv::u8string ssu8Var1; cl.DefineOption("ssu8var1", ssu8Var1, "sdv::u8string variable");
std::string ssVar2; cl.DefineOption("ssvar2", ssVar2, "sdv::string variable");
sdv::u8string ssu8Var2; cl.DefineOption("ssu8var2", ssu8Var2, "sdv::u8string variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(ssVar1, "test_a");
EXPECT_EQ(ssu8Var1, "test_b");
EXPECT_EQ(ssVar2, "test_c");
EXPECT_EQ(ssu8Var2, "test_d");
}
TEST_F(CCommandLineParserTest, WOptionParseStringVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "/ssvar1=test_a,test_b", "/ssu8var1=test_b,test_c", "/ssvar2=\"test_c\",\"test_d\"",
"/ssu8var2=\"test_d\",\"test_e\""};
CCommandLine cl;
std::vector<std::string> vecssVar1; cl.DefineOption("ssvar1", vecssVar1, "std::vector<std::string> variable");
std::vector<sdv::u8string> vecssu8Var1; cl.DefineOption("ssu8var1", vecssu8Var1, "std::vector<sdv::u8string> variable");
std::vector<std::string> vecssVar2; cl.DefineOption("ssvar2", vecssVar2, "std::vector<sdv::string> variable");
std::vector<sdv::u8string> vecssu8Var2; cl.DefineOption("ssu8var2", vecssu8Var2, "std::vector<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecssVar1, "test_a", "test_b");
EXPECT_ARREQ(vecssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(vecssVar2, "test_c", "test_d");
EXPECT_ARREQ(vecssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTest, WOptionParseStringSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "/ssvar1=test_a,test_b", "/ssu8var1=test_b,test_c", "/ssvar2=\"test_c\",\"test_d\"",
"/ssu8var2=\"test_d\",\"test_e\""};
CCommandLine cl;
sdv::sequence<std::string> seqssVar1; cl.DefineOption("ssvar1", seqssVar1, "sdv::sequence<std::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var1; cl.DefineOption("ssu8var1", seqssu8Var1, "sdv::sequence<sdv::u8string> variable");
sdv::sequence<std::string> seqssVar2; cl.DefineOption("ssvar2", seqssVar2, "sdv::sequence<sdv::string> variable");
sdv::sequence<sdv::u8string> seqssu8Var2; cl.DefineOption("ssu8var2", seqssu8Var2, "sdv::sequence<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqssVar1, "test_a", "test_b");
EXPECT_ARREQ(seqssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(seqssVar2, "test_c", "test_d");
EXPECT_ARREQ(seqssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTest, WOptionParseStringList)
{
const char* rgszCommandLine[] = {"this_exe.app", "/ssvar1=test_a,test_b", "/ssu8var1=test_b,test_c", "/ssvar2=\"test_c\",\"test_d\"",
"/ssu8var2=\"test_d\",\"test_e\""};
CCommandLine cl;
std::list<std::string> lstssVar1; cl.DefineOption("ssvar1", lstssVar1, "std::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var1; cl.DefineOption("ssu8var1", lstssu8Var1, "std::list<sdv::u8string> variable");
std::list<std::string> lstssVar2; cl.DefineOption("ssvar2", lstssVar2, "std::list<std::string> variable");
std::list<sdv::u8string> lstssu8Var2; cl.DefineOption("ssu8var2", lstssu8Var2, "std::list<sdv::u8string> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstssVar1, "test_a", "test_b");
EXPECT_ARREQ(lstssu8Var1, "test_b", "test_c");
EXPECT_ARREQ(lstssVar2, "test_c", "test_d");
EXPECT_ARREQ(lstssu8Var2, "test_d", "test_e");
}
TEST_F(CCommandLineParserTest, WOptionParsePath)
{
const char* rgszCommandLine[] = {"this_exe.app", "/pathvar1=abc.def", "/pathvar2=\"ghi.jkl\""};
CCommandLine cl;
std::filesystem::path pathVar1; cl.DefineOption("pathvar1", pathVar1, "std::filesystem::path variable");
std::filesystem::path pathVar2; cl.DefineOption("pathvar2", pathVar2, "std::filesystem::path variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_EQ(pathVar1, "abc.def");
EXPECT_EQ(pathVar2, "ghi.jkl");
}
TEST_F(CCommandLineParserTest, WOptionParsePathVector)
{
const char* rgszCommandLine[] = {"this_exe.app", "/pathvar1=abc.def,ghi.jkl", "/pathvar2=\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl;
std::vector<std::filesystem::path> vecpathVar1; cl.DefineOption("pathvar1", vecpathVar1, "std::vector<std::filesystem::path> variable");
std::vector<std::filesystem::path> vecpathVar2; cl.DefineOption("pathvar2", vecpathVar2, "std::vector<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(vecpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(vecpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTest, WOptionParsePathSequence)
{
const char* rgszCommandLine[] = {"this_exe.app", "/pathvar1=abc.def,ghi.jkl", "/pathvar2=\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl;
sdv::sequence<std::filesystem::path> seqpathVar1; cl.DefineOption("pathvar1", seqpathVar1, "sdv::sequence<std::filesystem::path> variable");
sdv::sequence<std::filesystem::path> seqpathVar2; cl.DefineOption("pathvar2", seqpathVar2, "sdv::sequence<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(seqpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(seqpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTest, WOptionParsePathList)
{
const char* rgszCommandLine[] = {"this_exe.app", "/pathvar1=abc.def,ghi.jkl", "/pathvar2=\"ghi.jkl\",\"mno.pqr\""};
CCommandLine cl;
std::list<std::filesystem::path> lstpathVar1; cl.DefineOption("pathvar1", lstpathVar1, "std::list<std::filesystem::path> variable");
std::list<std::filesystem::path> lstpathVar2; cl.DefineOption("pathvar2", lstpathVar2, "std::list<std::filesystem::path> variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_ARREQ(lstpathVar1, "abc.def", "ghi.jkl");
EXPECT_ARREQ(lstpathVar2, "ghi.jkl", "mno.pqr");
}
TEST_F(CCommandLineParserTest, WOptionParseFlags)
{
const char* rgszCommandLine[] = {"this_exe.app", "/flag_neg+", "/flag_pos-"};
CCommandLine cl;
bool bFlagNeg = false; cl.DefineFlagOption("flag_neg", bFlagNeg, "negative flag variable");
bool bFlagPos = true; cl.DefineFlagOption("flag_pos", bFlagPos, "positive flag variable");
bool bFlagNegControl = false; cl.DefineFlagOption("controlflag_neg", bFlagNegControl, "negative flag variable");
bool bFlagPosControl = true; cl.DefineFlagOption("control_flag_pos", bFlagPosControl, "positive flag variable");
EXPECT_NO_THROW(cl.Parse(std::extent<decltype(rgszCommandLine)>::value, rgszCommandLine));
EXPECT_TRUE(bFlagNeg);
EXPECT_FALSE(bFlagPos);
EXPECT_FALSE(bFlagNegControl);
EXPECT_TRUE(bFlagPosControl);
}
#endif // defined _WIN32