summaryrefslogtreecommitdiffstats
path: root/Tests/CMakeLib
diff options
context:
space:
mode:
authorRegina Pfeifer <regina@mailbox.org>2019-03-23 21:45:41 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2019-04-04 17:24:39 (GMT)
commit4359fe133b03aac5d0b0c1ed2aa98a49515edf56 (patch)
tree0092e4186bce033cd72135c4b1f7234a45d1bbb6 /Tests/CMakeLib
parent8c28e63cb4da99dbb894573a996c27e260b5baeb (diff)
downloadCMake-4359fe133b03aac5d0b0c1ed2aa98a49515edf56.zip
CMake-4359fe133b03aac5d0b0c1ed2aa98a49515edf56.tar.gz
CMake-4359fe133b03aac5d0b0c1ed2aa98a49515edf56.tar.bz2
Introduce cmArgumentParser
Diffstat (limited to 'Tests/CMakeLib')
-rw-r--r--Tests/CMakeLib/CMakeLists.txt1
-rw-r--r--Tests/CMakeLib/testArgumentParser.cxx148
2 files changed, 149 insertions, 0 deletions
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index 91f7e25..031ab01 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -5,6 +5,7 @@ include_directories(
)
set(CMakeLib_TESTS
+ testArgumentParser.cxx
testGeneratedFileStream.cxx
testRST.cxx
testRange.cxx
diff --git a/Tests/CMakeLib/testArgumentParser.cxx b/Tests/CMakeLib/testArgumentParser.cxx
new file mode 100644
index 0000000..788fece
--- /dev/null
+++ b/Tests/CMakeLib/testArgumentParser.cxx
@@ -0,0 +1,148 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmArgumentParser.h"
+
+#include "cm_static_string_view.hxx"
+#include "cm_string_view.hxx"
+
+#include <initializer_list>
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace {
+
+struct Result
+{
+ bool Option1 = false;
+ bool Option2 = false;
+
+ std::string String1;
+ std::string String2;
+
+ std::vector<std::string> List1;
+ std::vector<std::string> List2;
+ std::vector<std::string> List3;
+
+ std::vector<std::vector<std::string>> Multi1;
+ std::vector<std::vector<std::string>> Multi2;
+ std::vector<std::vector<std::string>> Multi3;
+};
+
+std::initializer_list<cm::string_view> const args = {
+ /* clang-format off */
+ "OPTION_1", // option
+ "STRING_1", // string arg missing value
+ "STRING_2", "foo", "bar", // string arg + unparsed value
+ "LIST_1", // list arg missing values
+ "LIST_2", "foo", "bar", // list arg with 2 elems
+ "LIST_3", "bar", // list arg ...
+ "LIST_3", "foo", // ... with continuation
+ "MULTI_2", // multi list with 0 lists
+ "MULTI_3", "foo", "bar", // multi list with first list with two elems
+ "MULTI_3", "bar", "foo", // multi list with second list with two elems
+ /* clang-format on */
+};
+
+bool verifyResult(Result const& result,
+ std::vector<std::string> const& unparsedArguments,
+ std::vector<std::string> const& keywordsMissingValue)
+{
+ static std::vector<std::string> const foobar = { "foo", "bar" };
+ static std::vector<std::string> const barfoo = { "bar", "foo" };
+ static std::vector<std::string> const missing = { "STRING_1", "LIST_1" };
+
+#define ASSERT_TRUE(x) \
+ do { \
+ if (!(x)) { \
+ std::cout << "ASSERT_TRUE(" #x ") failed on line " << __LINE__ << "\n"; \
+ return false; \
+ } \
+ } while (false)
+
+ ASSERT_TRUE(result.Option1);
+ ASSERT_TRUE(!result.Option2);
+
+ ASSERT_TRUE(result.String1.empty());
+ ASSERT_TRUE(result.String2 == "foo");
+
+ ASSERT_TRUE(result.List1.empty());
+ ASSERT_TRUE(result.List2 == foobar);
+ ASSERT_TRUE(result.List3 == barfoo);
+
+ ASSERT_TRUE(result.Multi1.empty());
+ ASSERT_TRUE(result.Multi2.size() == 1);
+ ASSERT_TRUE(result.Multi2[0].empty());
+ ASSERT_TRUE(result.Multi3.size() == 2);
+ ASSERT_TRUE(result.Multi3[0] == foobar);
+ ASSERT_TRUE(result.Multi3[1] == barfoo);
+
+ ASSERT_TRUE(unparsedArguments.size() == 1);
+ ASSERT_TRUE(unparsedArguments[0] == "bar");
+ ASSERT_TRUE(keywordsMissingValue == missing);
+
+ return true;
+}
+
+bool testArgumentParserDynamic()
+{
+ Result result;
+ std::vector<std::string> unparsedArguments;
+ std::vector<std::string> keywordsMissingValue;
+
+ cmArgumentParser<void>{}
+ .Bind("OPTION_1"_s, result.Option1)
+ .Bind("OPTION_2"_s, result.Option2)
+ .Bind("STRING_1"_s, result.String1)
+ .Bind("STRING_2"_s, result.String2)
+ .Bind("LIST_1"_s, result.List1)
+ .Bind("LIST_2"_s, result.List2)
+ .Bind("LIST_3"_s, result.List3)
+ .Bind("MULTI_1"_s, result.Multi1)
+ .Bind("MULTI_2"_s, result.Multi2)
+ .Bind("MULTI_3"_s, result.Multi3)
+ .Parse(args, &unparsedArguments, &keywordsMissingValue);
+
+ return verifyResult(result, unparsedArguments, keywordsMissingValue);
+}
+
+bool testArgumentParserStatic()
+{
+ static auto const parser = //
+ cmArgumentParser<Result>{}
+ .Bind("OPTION_1"_s, &Result::Option1)
+ .Bind("OPTION_2"_s, &Result::Option2)
+ .Bind("STRING_1"_s, &Result::String1)
+ .Bind("STRING_2"_s, &Result::String2)
+ .Bind("LIST_1"_s, &Result::List1)
+ .Bind("LIST_2"_s, &Result::List2)
+ .Bind("LIST_3"_s, &Result::List3)
+ .Bind("MULTI_1"_s, &Result::Multi1)
+ .Bind("MULTI_2"_s, &Result::Multi2)
+ .Bind("MULTI_3"_s, &Result::Multi3);
+
+ std::vector<std::string> unparsedArguments;
+ std::vector<std::string> keywordsMissingValue;
+ Result const result =
+ parser.Parse(args, &unparsedArguments, &keywordsMissingValue);
+
+ return verifyResult(result, unparsedArguments, keywordsMissingValue);
+}
+
+} // namespace
+
+int testArgumentParser(int /*unused*/, char* /*unused*/ [])
+{
+ if (!testArgumentParserDynamic()) {
+ std::cout << "While executing testArgumentParserDynamic().\n";
+ return -1;
+ }
+
+ if (!testArgumentParserStatic()) {
+ std::cout << "While executing testArgumentParserStatic().\n";
+ return -1;
+ }
+
+ return 0;
+}