diff options
author | Regina Pfeifer <regina@mailbox.org> | 2019-03-23 21:45:41 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2019-04-04 17:24:39 (GMT) |
commit | 4359fe133b03aac5d0b0c1ed2aa98a49515edf56 (patch) | |
tree | 0092e4186bce033cd72135c4b1f7234a45d1bbb6 /Tests/CMakeLib | |
parent | 8c28e63cb4da99dbb894573a996c27e260b5baeb (diff) | |
download | CMake-4359fe133b03aac5d0b0c1ed2aa98a49515edf56.zip CMake-4359fe133b03aac5d0b0c1ed2aa98a49515edf56.tar.gz CMake-4359fe133b03aac5d0b0c1ed2aa98a49515edf56.tar.bz2 |
Introduce cmArgumentParser
Diffstat (limited to 'Tests/CMakeLib')
-rw-r--r-- | Tests/CMakeLib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Tests/CMakeLib/testArgumentParser.cxx | 148 |
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; +} |