| // Copyright 2019 WebAssembly Community Group participants |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "gtest/gtest.h" |
| |
| #include <string> |
| |
| #include "wabt/option-parser.h" |
| |
| using namespace wabt; |
| |
| #define ERROR_ENDING "\nTry '--help' for more information." |
| |
| TEST(OptionParser, LongFlag) { |
| bool flag = false; |
| OptionParser parser("prog", "desc"); |
| parser.AddOption("flag", "help", [&]() { flag = true; }); |
| const char* args[] = {"prog name", "--flag"}; |
| parser.Parse(2, const_cast<char**>(args)); |
| EXPECT_EQ(true, flag); |
| } |
| |
| TEST(OptionParser, ShortAndLongFlag) { |
| int count = 0; |
| OptionParser parser("prog", "desc"); |
| parser.AddOption('f', "flag", "help", [&]() { ++count; }); |
| const char* args[] = {"prog name", "-f", "--flag", "-f", "--flag"}; |
| parser.Parse(5, const_cast<char**>(args)); |
| EXPECT_EQ(4, count); |
| } |
| |
| TEST(OptionParser, ShortFlagCombined) { |
| int count = 0; |
| OptionParser parser("prog", "desc"); |
| parser.AddOption('a', "a", "help", [&]() { count += 1; }); |
| parser.AddOption('b', "b", "help", [&]() { count += 2; }); |
| const char* args[] = {"prog name", "-aa", "-abb"}; |
| parser.Parse(3, const_cast<char**>(args)); |
| EXPECT_EQ(7, count); |
| } |
| |
| TEST(OptionParser, UnknownShortOption) { |
| std::string error; |
| OptionParser parser("prog", "desc"); |
| parser.SetErrorCallback([&](const char* msg) { error = msg; }); |
| const char* args[] = {"prog name", "-f"}; |
| parser.Parse(2, const_cast<char**>(args)); |
| EXPECT_EQ(error, "prog: unknown option '-f'" ERROR_ENDING); |
| } |
| |
| TEST(OptionParser, UnknownLongOption) { |
| std::string error; |
| OptionParser parser("prog", "desc"); |
| parser.SetErrorCallback([&](const char* msg) { error = msg; }); |
| const char* args[] = {"prog name", "--foo"}; |
| parser.Parse(2, const_cast<char**>(args)); |
| EXPECT_EQ(error, "prog: unknown option '--foo'" ERROR_ENDING); |
| } |
| |
| TEST(OptionParser, ShortAndLongParam) { |
| std::string param; |
| OptionParser parser("prog", "desc"); |
| parser.AddOption('p', "param", "metavar", "help", |
| [&](const char* arg) { param += arg; }); |
| const char* args[] = {"prog name", "-p", "h", "--param", "el", "--param=lo"}; |
| parser.Parse(6, const_cast<char**>(args)); |
| EXPECT_EQ("hello", param); |
| } |
| |
| TEST(OptionParser, MissingParam) { |
| std::string error; |
| std::string param; |
| OptionParser parser("prog", "desc"); |
| parser.SetErrorCallback([&](const char* msg) { error = msg; }); |
| parser.AddOption('p', "param", "metavar", "help", |
| [&](const char* arg) { param = arg; }); |
| const char* args[] = {"prog name", "--param"}; |
| parser.Parse(2, const_cast<char**>(args)); |
| EXPECT_EQ("", param); |
| EXPECT_EQ(error, "prog: option '--param' requires argument" ERROR_ENDING); |
| } |
| |
| TEST(OptionParser, MissingArgument) { |
| std::string error; |
| OptionParser parser("prog", "desc"); |
| parser.AddArgument("arg", OptionParser::ArgumentCount::One, |
| [&](const char* arg) {}); |
| parser.SetErrorCallback([&](const char* msg) { error = msg; }); |
| const char* args[] = {"prog name"}; |
| parser.Parse(1, const_cast<char**>(args)); |
| EXPECT_EQ(error, "prog: expected arg argument." ERROR_ENDING); |
| } |
| |
| TEST(OptionParser, FlagCombinedAfterShortParam) { |
| std::string error; |
| std::string param; |
| bool has_x = false; |
| |
| OptionParser parser("prog", "desc"); |
| parser.SetErrorCallback([&](const char* msg) { error = msg; }); |
| parser.AddOption('p', "p", "metavar", "help", |
| [&](const char* arg) { param = arg; }); |
| parser.AddOption('x', "x", "help", [&]() { has_x = true; }); |
| const char* args[] = {"prog name", "-px", "stuff"}; |
| parser.Parse(3, const_cast<char**>(args)); |
| EXPECT_EQ("", param); |
| EXPECT_TRUE(has_x); |
| EXPECT_EQ(error, "prog: unexpected argument 'stuff'" ERROR_ENDING); |
| } |
| |
| TEST(OptionParser, OneArgument) { |
| std::string argument; |
| OptionParser parser("prog", "desc"); |
| parser.AddArgument("arg", OptionParser::ArgumentCount::One, |
| [&](const char* arg) { argument = arg; }); |
| const char* args[] = {"prog name", "hello"}; |
| parser.Parse(2, const_cast<char**>(args)); |
| EXPECT_EQ("hello", argument); |
| } |
| |
| TEST(OptionParser, TooManyArguments) { |
| std::string error; |
| OptionParser parser("prog", "desc"); |
| parser.SetErrorCallback([&](const char* msg) { error = msg; }); |
| parser.AddArgument("arg", OptionParser::ArgumentCount::One, |
| [&](const char* arg) {}); |
| const char* args[] = {"prog name", "hello", "goodbye"}; |
| parser.Parse(3, const_cast<char**>(args)); |
| EXPECT_EQ(error, "prog: unexpected argument 'goodbye'" ERROR_ENDING); |
| } |
| |
| TEST(OptionParser, OneOrMoreArguments) { |
| std::string argument; |
| OptionParser parser("prog", "desc"); |
| parser.AddArgument("arg", OptionParser::ArgumentCount::OneOrMore, |
| [&](const char* arg) { argument += arg; }); |
| const char* args[] = {"prog name", "hello", "goodbye"}; |
| parser.Parse(3, const_cast<char**>(args)); |
| EXPECT_EQ("hellogoodbye", argument); |
| } |
| |
| TEST(OptionParser, ZeroOrMoreArguments) { |
| std::string argument; |
| OptionParser parser("prog", "desc"); |
| parser.AddArgument("arg", OptionParser::ArgumentCount::ZeroOrMore, |
| [&](const char* arg) { argument += arg; }); |
| |
| const char* args_none[] = {"prog name"}; |
| parser.Parse(1, const_cast<char**>(args_none)); |
| EXPECT_EQ("", argument); |
| |
| const char* args_many[] = {"prog name", "hello", "goodbye"}; |
| parser.Parse(3, const_cast<char**>(args_many)); |
| EXPECT_EQ("hellogoodbye", argument); |
| } |
| |
| TEST(OptionParser, StopProccessing) { |
| std::string argument; |
| bool has_x = false; |
| OptionParser parser("prog", "desc"); |
| parser.AddArgument("arg", OptionParser::ArgumentCount::ZeroOrMore, |
| [&](const char* arg) { argument += arg; }); |
| parser.AddOption('x', "x", "help", [&]() { has_x = true; }); |
| |
| const char* args_many[] = {"prog name", "-x", "--", "foo", "-x", "-y", "bar"}; |
| parser.Parse(7, const_cast<char**>(args_many)); |
| EXPECT_TRUE(has_x); |
| EXPECT_EQ("foo-x-ybar", argument); |
| } |