Home | History | Annotate | Download | only in utils
      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 
     21 namespace latinime {
     22 namespace dicttoolkit {
     23 namespace {
     24 
     25 TEST(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 
     71 int 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 
     90 TEST(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