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