blob: 808f6de4bdced97f7f6fc96523d8e152c226cd31 [file] [log] [blame]
// Copyright 2012 The Goma Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "lib/cmdline_parser.h"
#include "glog/logging.h"
#include "gtest/gtest.h"
using std::string;
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvSimple) {
const string input = "a b c";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("b");
expected_argv.push_back("c");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvWithQuote) {
const string input = "a \"b \" \'c \'";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("b ");
expected_argv.push_back("c ");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvWithQuoteInDifferentQuote) {
const string input = "a \"b \' \" \'c \" \'";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("b \' ");
expected_argv.push_back("c \" ");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvNoCloseQuoteAfterBackslash) {
const string input = "a \"b \\\" \" \'c \\\'";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("b \" ");
expected_argv.push_back("c \\");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvKeepNonEscapeInDQuote) {
const string input = "a \"b \\c \" \"d\\?e\" f";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("b \\c ");
expected_argv.push_back("d\\?e");
expected_argv.push_back("f");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvConjunctSpaceWithBackslash) {
const string input = "a b\\ c d";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("b c");
expected_argv.push_back("d");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvKeepCharAfterBackslashAsIs) {
const string input = "a b\\c d";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("bc");
expected_argv.push_back("d");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvBackslashAfterBackslash) {
const string input = "a b\\\\c d";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("b\\c");
expected_argv.push_back("d");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvIgnoreEndlAfterBackslash) {
const string input = "a b\\\nc d";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("bc");
expected_argv.push_back("d");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvConjunctCharAfterBackslash) {
const string input = "a b\\ \"c \" \"d \"\\ e f\\ \' g \'\\ h i";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("b c ");
expected_argv.push_back("d e");
expected_argv.push_back("f g h");
expected_argv.push_back("i");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvBackslashEndlInQuote) {
const string input = "a \"b\\\nc\" \'d\\\ne\' f";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("bc");
expected_argv.push_back("d\\\ne");
expected_argv.push_back("f");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvSingleBackslashInQuote) {
const string input = "a \"b\\c\" \'d\\e\' f";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("b\\c");
expected_argv.push_back("d\\e");
expected_argv.push_back("f");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvDoubleBackslashesInQuote) {
const string input = "a \"b\\\\c\" \'d\\\\e\' f";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("b\\c");
expected_argv.push_back("d\\\\e");
expected_argv.push_back("f");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvTripleBackslashesInQuote) {
const string input = "a \"b\\\\\\c\" \'d\\\\\\e\' f";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("b\\\\c");
expected_argv.push_back("d\\\\\\e");
expected_argv.push_back("f");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParsePosixCommandLineToArgvReturnFalseForUnfinished) {
const string open_single_quote = "\"";
const string open_double_quote = "\'";
const string open_backslash = "\\";
std::vector<string> argv;
EXPECT_FALSE(devtools_goma::ParsePosixCommandLineToArgv(open_single_quote,
&argv));
EXPECT_FALSE(devtools_goma::ParsePosixCommandLineToArgv(open_double_quote,
&argv));
EXPECT_FALSE(devtools_goma::ParsePosixCommandLineToArgv(open_backslash,
&argv));
}
TEST(CmdlineParserTest, ParsePosixCommandLineShouldKeepOriginalArgv) {
const string input = "a b";
std::vector<string> argv;
argv.push_back("0");
argv.push_back("1");
EXPECT_TRUE(devtools_goma::ParsePosixCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("0");
expected_argv.push_back("1");
expected_argv.push_back("a");
expected_argv.push_back("b");
EXPECT_EQ(expected_argv, argv);
}
// All test vectors for ParseWinCommandLineToArgv are come from:
// Results of Parsing Command Lines in
// http://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft(v=vs.85).aspx
//
// Note:
// In the document argv[3] is always capitailzed but I thought it typo.
TEST(CmdlineParserTest, ParseWinCommandLineToArgvRule1) {
const string input = "\"abc\" d e";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParseWinCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("abc");
expected_argv.push_back("d");
expected_argv.push_back("e");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParseWinCommandLineToArgvRule2) {
const string input = "a\\\\\\b d\"e f\"g h";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParseWinCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a\\\\\\b");
expected_argv.push_back("de fg");
expected_argv.push_back("h");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParseWinCommandLineToArgvRule3) {
const string input = "a\\\\\\\"b c d";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParseWinCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a\\\"b");
expected_argv.push_back("c");
expected_argv.push_back("d");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParseWinCommandLineToArgvRule4) {
const string input = "a\\\\\\\\\"b c\" d e";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParseWinCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a\\\\b c");
expected_argv.push_back("d");
expected_argv.push_back("e");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParseWinCommandLineToArgvRule5) {
const string input = " \t\n\r";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParseWinCommandLineToArgv(input, &argv));
EXPECT_EQ(0U, argv.size());
}
TEST(CmdlineParserTest, ParseWinCommandLineToArgvRule6) {
const string input = " \n a \r b \t c ";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParseWinCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("a");
expected_argv.push_back("b");
expected_argv.push_back("c");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParseWinCommandLineToArgvRule7) {
const string input = " \n \" a \" b\t\n\t \"c \"\n\t\" d\t\" ";
std::vector<string> argv;
EXPECT_TRUE(devtools_goma::ParseWinCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back(" a ");
expected_argv.push_back("b");
expected_argv.push_back("c ");
expected_argv.push_back(" d\t");
EXPECT_EQ(expected_argv, argv);
}
TEST(CmdlineParserTest, ParseWinCommandLineToArgvReturnFalseWithoutEndQuote) {
const string input = "\"";
std::vector<string> argv;
EXPECT_FALSE(devtools_goma::ParseWinCommandLineToArgv(input, &argv));
}
TEST(CmdlineParserTest, ParseWinCommandLineToArgvShouldKeepOriginalArgv) {
const string input = "a b";
std::vector<string> argv;
argv.push_back("0");
argv.push_back("1");
EXPECT_TRUE(devtools_goma::ParseWinCommandLineToArgv(input, &argv));
std::vector<string> expected_argv;
expected_argv.push_back("0");
expected_argv.push_back("1");
expected_argv.push_back("a");
expected_argv.push_back("b");
EXPECT_EQ(expected_argv, argv);
}