From 368af75bf23d5f571e50213c6e66e4b3f110ae18 Mon Sep 17 00:00:00 2001 From: sigurdp Date: Wed, 4 Dec 2013 14:56:04 +0100 Subject: [PATCH] Refactored ProgramOptions class --- .../Application/RiaApplication.cpp | 84 ++++--- Fwk/VizFwk/LibCore/cvfProgramOptions.cpp | 217 +++++++++++++----- Fwk/VizFwk/LibCore/cvfProgramOptions.h | 35 ++- .../cvfProgramOptions-Test.cpp | 161 ++++++++++--- 4 files changed, 363 insertions(+), 134 deletions(-) diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index 6e6a83feef..65db2f19a6 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -1019,7 +1019,7 @@ bool RiaApplication::parseArguments() if (!parseOk || progOpt.hasOption("help") || progOpt.hasOption("?")) { { - cvf::String usageText = progOpt.usageText(80, 30); + cvf::String usageText = progOpt.usageText(110, 30); cvf::Trace::show(usageText); } @@ -1037,31 +1037,33 @@ bool RiaApplication::parseArguments() // Handling of the actual command line options // -------------------------------------------------------- - if (progOpt.hasOption("regressiontest")) + if (cvf::Option o = progOpt.option("regressiontest")) { - QString regressionTestPath = cvfqt::Utils::toQString(progOpt.firstValue("regressiontest")); + CVF_ASSERT(o.valueCount() == 1); + QString regressionTestPath = cvfqt::Utils::toQString(o.value(0)); executeRegressionTests(regressionTestPath); return false; } - if (progOpt.hasOption("updateregressiontestbase")) + if (cvf::Option o = progOpt.option("updateregressiontestbase")) { - QString regressionTestPath = cvfqt::Utils::toQString(progOpt.firstValue("updateregressiontestbase")); + CVF_ASSERT(o.valueCount() == 1); + QString regressionTestPath = cvfqt::Utils::toQString(o.value(0)); updateRegressionTest(regressionTestPath); return false; } - if (progOpt.hasOption("startdir")) + if (cvf::Option o = progOpt.option("startdir")) { - m_startupDefaultDirectory = cvfqt::Utils::toQString(progOpt.firstValue("startdir")); + CVF_ASSERT(o.valueCount() == 1); + m_startupDefaultDirectory = cvfqt::Utils::toQString(o.value(0)); } - if (progOpt.hasOption("size")) + if (cvf::Option o = progOpt.option("size")) { - std::vector vals = progOpt.values("size"); RiuMainWindow* mainWnd = RiuMainWindow::instance(); - int width = (vals.size() > 0) ? vals[0].toInt(-1) : -1; - int height = (vals.size() > 1) ? vals[1].toInt(-1) : -1; + int width = o.safeValue(0).toInt(-1); + int height = o.safeValue(1).toInt(-1); if (mainWnd && width > 0 && height > 0) { mainWnd->resize(width, height); @@ -1076,18 +1078,22 @@ bool RiaApplication::parseArguments() projectFileName = m_preferences->lastUsedProjectFileName; } - if (progOpt.hasOption("project")) + if (cvf::Option o = progOpt.option("project")) { - projectFileName = cvfqt::Utils::toQString(progOpt.firstValue("project")); + CVF_ASSERT(o.valueCount() == 1); + projectFileName = cvfqt::Utils::toQString(o.value(0)); } - if (progOpt.hasOption("multiCaseSnapshots") && !projectFileName.isEmpty()) + if (!projectFileName.isEmpty()) { - QString gridListFile = cvfqt::Utils::toQString(progOpt.firstValue("multiCaseSnapshots")); - std::vector gridFiles = readFileListFromTextFile(gridListFile); - runMultiCaseSnapshots(projectFileName, gridFiles, "multiCaseSnapshots"); - return false; + if (cvf::Option o = progOpt.option("multiCaseSnapshots")) + { + QString gridListFile = cvfqt::Utils::toQString(o.safeValue(0)); + std::vector gridFiles = readFileListFromTextFile(gridListFile); + runMultiCaseSnapshots(projectFileName, gridFiles, "multiCaseSnapshots"); + return false; + } } @@ -1096,47 +1102,37 @@ bool RiaApplication::parseArguments() cvf::ref projectModifier; ProjectLoadAction projectLoadAction = PLA_NONE; - if (progOpt.hasOption("replaceCase")) + if (cvf::Option o = progOpt.option("replaceCase")) { if (projectModifier.isNull()) projectModifier = new RiaProjectModifier; - std::vector vals = progOpt.values("replaceCase"); - CVF_ASSERT(vals.size() >= 1); - if (vals.size() == 1) + const int caseId = o.safeValue(0).toInt(-1); + if (caseId != -1 && o.valueCount() > 1) { - QString gridFileName = cvfqt::Utils::toQString(vals[0]); - projectModifier->setReplaceCaseFirstOccurence(gridFileName); + QString gridFileName = cvfqt::Utils::toQString(o.value(1)); + projectModifier->setReplaceCase(caseId, gridFileName); } else { - const int caseId = vals[0].toInt(cvf::UNDEFINED_INT); - if (caseId != cvf::UNDEFINED_INT) - { - QString gridFileName = cvfqt::Utils::toQString(vals[1]); - projectModifier->setReplaceCase(caseId, gridFileName); - } + QString gridFileName = cvfqt::Utils::toQString(o.safeValue(0)); + projectModifier->setReplaceCaseFirstOccurence(gridFileName); } } - if (progOpt.hasOption("replaceSourceCases")) + if (cvf::Option o = progOpt.option("replaceSourceCases")) { if (projectModifier.isNull()) projectModifier = new RiaProjectModifier; - std::vector vals = progOpt.values("replaceSourceCases"); - CVF_ASSERT(vals.size() >= 1); - if (vals.size() == 1) + const int caseGroupId = o.safeValue(0).toInt(-1); + if (caseGroupId != -1 && o.valueCount() > 1) { - std::vector gridFileNames = readFileListFromTextFile(cvfqt::Utils::toQString(vals[0])); - projectModifier->setReplaceSourceCasesFirstOccurence(gridFileNames); + std::vector gridFileNames = readFileListFromTextFile(cvfqt::Utils::toQString(o.value(1))); + projectModifier->setReplaceSourceCasesById(caseGroupId, gridFileNames); } else { - const int caseGroupId = vals[0].toInt(cvf::UNDEFINED_INT); - if (caseGroupId != cvf::UNDEFINED_INT) - { - std::vector gridFileNames = readFileListFromTextFile(cvfqt::Utils::toQString(vals[1])); - projectModifier->setReplaceSourceCasesById(caseGroupId, gridFileNames); - } + std::vector gridFileNames = readFileListFromTextFile(cvfqt::Utils::toQString(o.safeValue(0))); + projectModifier->setReplaceSourceCasesFirstOccurence(gridFileNames); } projectLoadAction = PLA_CALCULATE_STATISTICS; @@ -1147,9 +1143,9 @@ bool RiaApplication::parseArguments() } - if (progOpt.hasOption("case")) + if (cvf::Option o = progOpt.option("case")) { - QStringList caseNames = cvfqt::Utils::toQStringList(progOpt.values("case")); + QStringList caseNames = cvfqt::Utils::toQStringList(o.values()); foreach (QString caseName, caseNames) { QString caseFileNameWithExt = caseName + ".EGRID"; diff --git a/Fwk/VizFwk/LibCore/cvfProgramOptions.cpp b/Fwk/VizFwk/LibCore/cvfProgramOptions.cpp index 6e83deeb7d..65b2cbd494 100644 --- a/Fwk/VizFwk/LibCore/cvfProgramOptions.cpp +++ b/Fwk/VizFwk/LibCore/cvfProgramOptions.cpp @@ -125,6 +125,122 @@ public: +//================================================================================================== +/// +/// \class cvf::Option +/// \ingroup Core +/// +/// +/// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// Constructs an invalid/empty option +//-------------------------------------------------------------------------------------------------- +Option::Option() +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Option::Option(const String& name, const std::vector& values) +: m_name(name), + m_values(values) +{ + CVF_ASSERT(!m_name.isEmpty()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +String Option::name() const +{ + return m_name; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t Option::valueCount() const +{ + return m_values.size(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +String Option::value(size_t valueIndex) const +{ + CVF_ASSERT(valueIndex < m_values.size()); + return m_values[valueIndex]; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +String Option::safeValue(size_t valueIndex) const +{ + if (valueIndex < m_values.size()) + { + return m_values[valueIndex]; + } + else + { + return String(); + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector Option::values() const +{ + return m_values; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +String Option::combinedValues() const +{ + String combined; + + for (size_t i = 0; i < m_values.size(); i++) + { + if (i > 0) combined += " "; + combined += m_values[i]; + } + + return combined; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool Option::isValid() const +{ + return m_name.isEmpty() ? false : true; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Option::operator bool_type() const +{ + return isValid() ? &Option::this_type_does_not_support_comparisons : 0; +} + + //================================================================================================== /// @@ -361,16 +477,33 @@ bool ProgramOptions::hasOption(const String& optionName) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t ProgramOptions::valueCount(const String& optionName) const +Option ProgramOptions::option(const String& optionName) const { const ParsedOption* parsedOption = findParsedOption(optionName); if (parsedOption) { - return parsedOption->m_values.size(); + return Option(parsedOption->m_spec->m_name, parsedOption->m_values); } else { - return 0; + return Option(); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +String ProgramOptions::firstValue(const String& optionName) const +{ + const ParsedOption* parsedOption = findParsedOption(optionName); + if (parsedOption && parsedOption->m_values.size() > 0) + { + return parsedOption->m_values[0]; + } + else + { + return String(); } } @@ -392,44 +525,6 @@ std::vector ProgramOptions::values(const String& optionName) const } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -String ProgramOptions::combinedValues(const String& optionName) const -{ - String combined; - const ParsedOption* parsedOption = findParsedOption(optionName); - if (parsedOption) - { - for (size_t i = 0; i < parsedOption->m_values.size(); i++) - { - if (i > 0) combined += " "; - combined += parsedOption->m_values[i]; - } - } - - return combined; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::String ProgramOptions::firstValue(const String& optionName) const -{ - const ParsedOption* parsedOption = findParsedOption(optionName); - if (parsedOption && parsedOption->m_values.size() > 0) - { - return parsedOption->m_values[0]; - } - else - { - return String(); - } -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -553,29 +648,26 @@ String ProgramOptions::usageText(int maxWidth, int maxOptionWidth) const for (size_t iopt = 0; iopt < numOpts; iopt++) { const String optAndVal = optAndValArr[iopt]; - const String descr = descrArr[iopt]; - const int optAndValLen = static_cast(optAndVal.size()); - const int descrLen = static_cast(descr.size()); - if (optAndValLen + 1 <= firstColWidth && - firstColWidth + descrLen <= maxWidth) - { - String s = String("%1 %2").arg(optAndValArr[iopt], -(firstColWidth - 1)).arg(descr); - retStr += s + String("\n"); - } - else - { - const int maxDescrWidth = CVF_MAX((maxWidth - firstColWidth), 1); - std::vector lines = breakStringIntoLines(descr, static_cast(maxDescrWidth)); - - String s = optAndValArr[iopt]; - for (size_t i = 0; i < lines.size(); i++) - { - s += String("\n") + firstColBlanks + lines[i]; - } - retStr += s + String("\n"); + + const int maxDescrWidth = CVF_MAX((maxWidth - firstColWidth), 1); + std::vector descrLines = breakStringIntoLines(descrArr[iopt], static_cast(maxDescrWidth)); + + String s = String("%1 ").arg(optAndValArr[iopt], -(firstColWidth - 1)); + if (s.size() > static_cast(firstColWidth) && descrLines.size() > 0) + { + s += "\n" + firstColBlanks; } - + for (size_t i = 0; i < descrLines.size(); i++) + { + if (i > 0) + { + s += "\n" + firstColBlanks; + } + s += descrLines[i]; + } + + retStr += s + String("\n"); } return retStr; @@ -617,5 +709,6 @@ std::vector ProgramOptions::breakStringIntoLines(const String& str, size return lines; } + } // namespace cvf diff --git a/Fwk/VizFwk/LibCore/cvfProgramOptions.h b/Fwk/VizFwk/LibCore/cvfProgramOptions.h index 35c68ff346..57408ea31b 100644 --- a/Fwk/VizFwk/LibCore/cvfProgramOptions.h +++ b/Fwk/VizFwk/LibCore/cvfProgramOptions.h @@ -44,6 +44,38 @@ namespace cvf { +//================================================================================================== +// +// +// +//================================================================================================== +class Option +{ +public: + Option(); + Option(const String& name, const std::vector& values); + + String name() const; + size_t valueCount() const; + String value(size_t valueIndex) const; + String safeValue(size_t valueIndex) const; + std::vector values() const; + String combinedValues() const; + + bool isValid() const; + + // Safe bool idiom, internally calls isValid() + typedef void (Option::*bool_type)() const; + operator bool_type() const; + +private: + const String m_name; + const std::vector m_values; + +private: + void this_type_does_not_support_comparisons() const {} +}; + //================================================================================================== // @@ -85,9 +117,8 @@ public: bool parse(const std::vector& commandLineArguments); bool hasOption(const String& optionName) const; - size_t valueCount(const String& optionName) const; + Option option(const String& optionName) const; std::vector values(const String& optionName) const; - String combinedValues(const String& optionName) const; String firstValue(const String& optionName) const; std::vector positionalParameters() const; diff --git a/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfProgramOptions-Test.cpp b/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfProgramOptions-Test.cpp index e0f3b56761..b7323e8e21 100644 --- a/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfProgramOptions-Test.cpp +++ b/Fwk/VizFwk/Tests/LibCore_UnitTests/cvfProgramOptions-Test.cpp @@ -45,6 +45,43 @@ using namespace cvf; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(OptionTest, DefaultConstructionInvalidObj) +{ + Option o; + EXPECT_FALSE(o.isValid()); + EXPECT_FALSE(o); + EXPECT_TRUE(o.name() == ""); + EXPECT_EQ(0, o.valueCount()); + EXPECT_EQ(0, o.values().size()); + EXPECT_TRUE(o.combinedValues() == ""); +} + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(OptionTest, Construction) +{ + std::vector vals; + vals.push_back("v0"); + vals.push_back("v1"); + Option o("dummy", vals); + EXPECT_TRUE(o.isValid()); + EXPECT_TRUE(o); + EXPECT_TRUE(o.name() == "dummy"); + EXPECT_EQ(2, o.valueCount()); + ASSERT_EQ(2, o.values().size()); + EXPECT_TRUE(o.values()[0] == "v0"); + EXPECT_TRUE(o.values()[1] == "v1"); + EXPECT_TRUE(o.combinedValues() == "v0 v1"); +} + + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -52,9 +89,14 @@ TEST(ProgramOptionsTest, Construction) { ProgramOptions po; ASSERT_FALSE(po.hasOption("dummy")); - ASSERT_EQ(0, po.valueCount("dummy")); + ASSERT_TRUE(po.firstValue("dummy") == ""); ASSERT_EQ(0, po.values("dummy").size()); - ASSERT_TRUE(po.combinedValues("dummy") == ""); + + Option o = po.option("dummy"); + ASSERT_FALSE(o.isValid()); + ASSERT_EQ(0, o.valueCount()); + ASSERT_TRUE(o.combinedValues() == ""); + ASSERT_TRUE(po.option("dummy").combinedValues() == ""); ASSERT_EQ(0, po.positionalParameters().size()); ASSERT_EQ(0, po.unknownOptions().size()); @@ -119,11 +161,11 @@ TEST(ProgramOptionsTest, SingleValueOptions) ASSERT_TRUE(po.parse(cmdLineArgs)); ASSERT_TRUE(po.hasOption("opt1")); - ASSERT_EQ(1, po.valueCount("opt1")); + ASSERT_EQ(1, po.values("opt1").size()); EXPECT_TRUE(po.values("opt1")[0] == "AA"); EXPECT_TRUE(po.hasOption("opt2")); - ASSERT_EQ(1, po.valueCount("opt2")); + ASSERT_EQ(1, po.values("opt2").size()); EXPECT_TRUE(po.values("opt2")[0] == "BB"); } @@ -143,16 +185,16 @@ TEST(ProgramOptionsTest, MultiValueOptions) ASSERT_TRUE(po.parse(cmdLineArgs)); ASSERT_TRUE(po.hasOption("opt1")); - ASSERT_EQ(1, po.valueCount("opt1")); + ASSERT_EQ(1, po.values("opt1").size()); EXPECT_TRUE(po.values("opt1")[0] == "A0"); EXPECT_TRUE(po.hasOption("opt2")); - ASSERT_EQ(2, po.valueCount("opt2")); + ASSERT_EQ(2, po.values("opt2").size()); EXPECT_TRUE(po.values("opt2")[0] == "B0"); EXPECT_TRUE(po.values("opt2")[1] == "B1"); EXPECT_TRUE(po.hasOption("opt3")); - ASSERT_EQ(3, po.valueCount("opt3")); + ASSERT_EQ(3, po.values("opt3").size()); EXPECT_TRUE(po.values("opt3")[0] == "C0"); EXPECT_TRUE(po.values("opt3")[1] == "C1"); EXPECT_TRUE(po.values("opt3")[2] == "C2"); @@ -174,16 +216,16 @@ TEST(ProgramOptionsTest, SingleValueOptionWithMissingValue) ASSERT_FALSE(po.parse(cmdLineArgs)); ASSERT_TRUE(po.hasOption("opt1")); - ASSERT_EQ(1, po.valueCount("opt1")); + ASSERT_EQ(1, po.values("opt1").size()); EXPECT_TRUE(po.values("opt1")[0] == "1"); EXPECT_FALSE(po.hasOption("opt2")); - ASSERT_EQ(0, po.valueCount("opt2")); + ASSERT_EQ(0, po.values("opt2").size()); ASSERT_EQ(1, po.optionsWithMissingValues().size()); EXPECT_TRUE(po.optionsWithMissingValues()[0] == "opt2"); EXPECT_TRUE(po.hasOption("opt3")); - ASSERT_EQ(1, po.valueCount("opt3")); + ASSERT_EQ(1, po.values("opt3").size()); EXPECT_TRUE(po.values("opt3")[0] == "3"); } @@ -203,16 +245,16 @@ TEST(ProgramOptionsTest, MultiValueOptionWithMissingValues) ASSERT_FALSE(po.parse(cmdLineArgs)); ASSERT_TRUE(po.hasOption("opt1")); - ASSERT_EQ(1, po.valueCount("opt1")); + ASSERT_EQ(1, po.values("opt1").size()); EXPECT_TRUE(po.values("opt1")[0] == "1"); EXPECT_FALSE(po.hasOption("opt2")); - ASSERT_EQ(0, po.valueCount("opt2")); + ASSERT_EQ(0, po.values("opt2").size()); ASSERT_EQ(1, po.optionsWithMissingValues().size()); EXPECT_TRUE(po.optionsWithMissingValues()[0] == "opt2"); EXPECT_TRUE(po.hasOption("opt3")); - ASSERT_EQ(3, po.valueCount("opt3")); + ASSERT_EQ(3, po.values("opt3").size()); EXPECT_TRUE(po.values("opt3")[0] == "1"); EXPECT_TRUE(po.values("opt3")[1] == "2"); EXPECT_TRUE(po.values("opt3")[2] == "3"); @@ -235,11 +277,20 @@ TEST(ProgramOptionsTest, UnknownOptions) ASSERT_FALSE(po.parse(cmdLineArgs)); ASSERT_TRUE(po.hasOption("noval")); - ASSERT_EQ(0, po.valueCount("noval")); + ASSERT_EQ(0, po.values("noval").size()); ASSERT_TRUE(po.hasOption("single")); - ASSERT_EQ(1, po.valueCount("single")); + ASSERT_EQ(1, po.values("single").size()); ASSERT_TRUE(po.hasOption("multi")); - ASSERT_EQ(2, po.valueCount("multi")); + ASSERT_EQ(2, po.values("multi").size()); + + EXPECT_FALSE(po.hasOption("u1")); + EXPECT_FALSE(po.hasOption("u2")); + EXPECT_FALSE(po.hasOption("u3")); + EXPECT_FALSE(po.hasOption("u4")); + EXPECT_FALSE(po.option("u1")); + EXPECT_FALSE(po.option("u2")); + EXPECT_FALSE(po.option("u3")); + EXPECT_FALSE(po.option("u4")); ASSERT_EQ(4, po.unknownOptions().size()); EXPECT_TRUE(po.unknownOptions()[0] == "u1"); @@ -270,12 +321,12 @@ TEST(ProgramOptionsTest, RepeatOptions) ASSERT_TRUE(po.parse(cmdLineArgs)); ASSERT_TRUE(po.hasOption("single")); - ASSERT_EQ(1, po.valueCount("single")); - ASSERT_TRUE(po.combinedValues("single") == "2"); + ASSERT_EQ(1, po.values("single").size()); + ASSERT_TRUE(po.option("single").combinedValues() == "2"); ASSERT_TRUE(po.hasOption("multi")); - ASSERT_EQ(2, po.valueCount("multi")); - ASSERT_TRUE(po.combinedValues("multi") == "A B"); + ASSERT_EQ(2, po.values("multi").size()); + ASSERT_TRUE(po.option("multi").combinedValues() == "A B"); } @@ -294,12 +345,12 @@ TEST(ProgramOptionsTest, RepeatOptionsCombining) ASSERT_TRUE(po.parse(cmdLineArgs)); ASSERT_TRUE(po.hasOption("single")); - ASSERT_EQ(2, po.valueCount("single")); - ASSERT_TRUE(po.combinedValues("single") == "1 2"); + ASSERT_EQ(2, po.values("single").size()); + ASSERT_TRUE(po.option("single").combinedValues() == "1 2"); ASSERT_TRUE(po.hasOption("multi")); - ASSERT_EQ(3, po.valueCount("multi")); - ASSERT_TRUE(po.combinedValues("multi") == "A A B"); + ASSERT_EQ(3, po.values("multi").size()); + ASSERT_TRUE(po.option("multi").combinedValues() == "A A B"); } @@ -354,7 +405,7 @@ TEST(ProgramOptionsTest, RealWorld_1) { ASSERT_TRUE(po.hasOption("outFile")); - String fileName = po.combinedValues("outFile"); + String fileName = po.firstValue("outFile"); EXPECT_TRUE(fileName == "outfile.txt"); } } @@ -383,7 +434,7 @@ TEST(ProgramOptionsTest, RealWorld_2) { ASSERT_TRUE(po.hasOption("width")); - int width = po.combinedValues("width").toInt(); + int width = po.firstValue("width").toInt(); EXPECT_EQ(25, width); } @@ -415,3 +466,61 @@ TEST(ProgramOptionsTest, UsageText) } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(ProgramOptionsTest, RealWorld_3) +{ + ProgramOptions po; + po.registerOption("myFlag1", "", "", ProgramOptions::NO_VALUE); + po.registerOption("myFlag2", "", "", ProgramOptions::NO_VALUE); + po.registerOption("size", " ", "", ProgramOptions::MULTI_VALUE); + po.registerOption("outFile", "", "", ProgramOptions::SINGLE_VALUE); + + String cmdLine("MyExe --size 10 20 --myFlag2 --outfile outfile.txt"); + std::vector cmdLineArgs = cmdLine.split(); + ASSERT_TRUE(po.parse(cmdLineArgs)); + + if (Option o = po.option("myFlag1")) + { + FAIL() << "Option should not be present."; + } + + if (Option o = po.option("myFlag2")) + { + EXPECT_TRUE(o.isValid()); + EXPECT_EQ(0, o.valueCount()); + } + else + { + FAIL() << "Option missing."; + } + + if (Option o = po.option("size")) + { + EXPECT_TRUE(o.isValid()); + EXPECT_EQ(2, o.valueCount()); + int x = o.safeValue(0).toInt(-1); + int y = o.safeValue(1).toInt(-1); + EXPECT_EQ(10, x); + EXPECT_EQ(20, y); + } + else + { + FAIL() << "Option missing."; + } + + if (Option o = po.option("outFile")) + { + EXPECT_TRUE(o.isValid()); + EXPECT_EQ(1, o.valueCount()); + String fileName = o.combinedValues(); + EXPECT_TRUE(fileName == "outfile.txt"); + } + else + { + FAIL() << "Option missing."; + } +} + +