arguments_parser_test.cpp revision 1f8d4f47e445bd4316f3e09228cff6de64105f13
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "utils/arguments_parser.h"
18
19#include <gtest/gtest.h>
20
21namespace latinime {
22namespace dicttoolkit {
23namespace {
24
25TEST(ArgumentsParserTests, TestValitadeSpecs) {
26    {
27        std::unordered_map<std::string, OptionSpec> optionSpecs;
28        std::vector<ArgumentSpec> argumentSpecs;
29        EXPECT_TRUE(
30                ArgumentsParser(std::move(optionSpecs), std::move(argumentSpecs)).validateSpecs());
31    }
32    {
33        std::unordered_map<std::string, OptionSpec> optionSpecs;
34        optionSpecs["a"] = OptionSpec::keyValueOption("valueName", "default", "description");
35        const std::vector<ArgumentSpec> argumentSpecs = {
36            ArgumentSpec::singleArgument("name", "description"),
37            ArgumentSpec::variableLengthArguments("name2", 0 /* minCount */,  1 /* maxCount */,
38                    "description2")
39        };
40        EXPECT_TRUE(
41                ArgumentsParser(std::move(optionSpecs), std::move(argumentSpecs)).validateSpecs());
42    }
43    {
44        const std::vector<ArgumentSpec> argumentSpecs = {
45            ArgumentSpec::variableLengthArguments("name", 0 /* minCount */,  0 /* maxCount */,
46                    "description")
47        };
48        EXPECT_FALSE(ArgumentsParser(std::unordered_map<std::string, OptionSpec>(),
49                std::move(argumentSpecs)).validateSpecs());
50    }
51    {
52        const std::vector<ArgumentSpec> argumentSpecs = {
53            ArgumentSpec::singleArgument("name", "description"),
54            ArgumentSpec::variableLengthArguments("name", 0 /* minCount */,  1 /* maxCount */,
55                    "description")
56        };
57        EXPECT_FALSE(ArgumentsParser(std::unordered_map<std::string, OptionSpec>(),
58                std::move(argumentSpecs)).validateSpecs());
59    }
60    {
61        const std::vector<ArgumentSpec> argumentSpecs = {
62            ArgumentSpec::variableLengthArguments("name", 0 /* minCount */,  1 /* maxCount */,
63                    "description"),
64            ArgumentSpec::singleArgument("name2", "description2")
65        };
66        EXPECT_FALSE(ArgumentsParser(std::unordered_map<std::string, OptionSpec>(),
67                std::move(argumentSpecs)).validateSpecs());
68    }
69}
70
71int initArgv(char *mutableCommandLine, char **argv) {
72    bool readingSeparator = false;
73    int argc = 1;
74    argv[0] = mutableCommandLine;
75    const size_t length = strlen(mutableCommandLine);
76    for (size_t i = 0; i < length; ++i) {
77        if (mutableCommandLine[i] != ' ' && readingSeparator) {
78            readingSeparator = false;
79            argv[argc] = mutableCommandLine + i;
80            ++argc;
81        } else if (mutableCommandLine[i] == ' ' && !readingSeparator) {
82            readingSeparator = true;
83            mutableCommandLine[i] = '\0';
84        }
85    }
86    argv[argc] = nullptr;
87    return argc;
88}
89
90TEST(ArgumentsParserTests, TestParseArguments) {
91    std::unordered_map<std::string, OptionSpec> optionSpecs;
92    optionSpecs["a"] = OptionSpec::switchOption("description");
93    optionSpecs["b"] = OptionSpec::keyValueOption("valueName", "default", "description");
94    const std::vector<ArgumentSpec> argumentSpecs = {
95        ArgumentSpec::singleArgument("arg0", "description"),
96        ArgumentSpec::variableLengthArguments("arg1", 0 /* minCount */,  2 /* maxCount */,
97                "description"),
98    };
99    const ArgumentsParser parser =
100            ArgumentsParser(std::move(optionSpecs), std::move(argumentSpecs));
101
102    {
103        char kMutableCommandLine[1024] = "command arg";
104        char *argv[128] = {};
105        const int argc = initArgv(kMutableCommandLine, argv);
106        ASSERT_EQ(2, argc);
107        const ArgumentsAndOptions argumentsAndOptions = parser.parseArguments(
108                argc, argv, false /* printErrorMessages */);
109        EXPECT_FALSE(argumentsAndOptions.hasOption("a"));
110        EXPECT_EQ("default", argumentsAndOptions.getOptionValue("b"));
111        EXPECT_EQ("arg", argumentsAndOptions.getSingleArgument("arg0"));
112        EXPECT_FALSE(argumentsAndOptions.hasArgument("arg1"));
113    }
114    {
115        char kArgumentBuffer[1024] = "command -a arg arg";
116        char *argv[128] = {};
117        const int argc = initArgv(kArgumentBuffer, argv);
118        ASSERT_EQ(4, argc);
119        const ArgumentsAndOptions argumentsAndOptions = parser.parseArguments(
120                argc, argv, false /* printErrorMessages */);
121        EXPECT_TRUE(argumentsAndOptions.hasOption("a"));
122        EXPECT_EQ("default", argumentsAndOptions.getOptionValue("b"));
123        EXPECT_EQ("arg", argumentsAndOptions.getSingleArgument("arg0"));
124        EXPECT_TRUE(argumentsAndOptions.hasArgument("arg1"));
125        EXPECT_EQ(1u, argumentsAndOptions.getVariableLengthArguments("arg1").size());
126    }
127    {
128        char kArgumentBuffer[1024] = "command -b value arg arg1 arg2";
129        char *argv[128] = {};
130        const int argc = initArgv(kArgumentBuffer, argv);
131        ASSERT_EQ(6, argc);
132        const ArgumentsAndOptions argumentsAndOptions = parser.parseArguments(
133                argc, argv, false /* printErrorMessages */);
134        EXPECT_FALSE(argumentsAndOptions.hasOption("a"));
135        EXPECT_EQ("value", argumentsAndOptions.getOptionValue("b"));
136        EXPECT_EQ("arg", argumentsAndOptions.getSingleArgument("arg0"));
137        const std::vector<std::string> &arg1 =
138                argumentsAndOptions.getVariableLengthArguments("arg1");
139        EXPECT_EQ(2u, arg1.size());
140        EXPECT_EQ("arg1", arg1[0]);
141        EXPECT_EQ("arg2", arg1[1]);
142    }
143}
144
145} // namespace
146} // namespace dicttoolkit
147} // namespace latinime
148