Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <string>
      6 #include <vector>
      7 
      8 #include "base/basictypes.h"
      9 #include "base/command_line.h"
     10 #include "base/file_path.h"
     11 #include "base/utf_string_conversions.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 // To test Windows quoting behavior, we use a string that has some backslashes
     15 // and quotes.
     16 // Consider the command-line argument: q\"bs1\bs2\\bs3q\\\"
     17 // Here it is with C-style escapes.
     18 #define TRICKY_QUOTED L"q\\\"bs1\\bs2\\\\bs3q\\\\\\\""
     19 // It should be parsed by Windows as: q"bs1\bs2\\bs3q\"
     20 // Here that is with C-style escapes.
     21 #define TRICKY L"q\"bs1\\bs2\\\\bs3q\\\""
     22 
     23 TEST(CommandLineTest, CommandLineConstructor) {
     24 #if defined(OS_WIN)
     25   CommandLine cl = CommandLine::FromString(
     26                      L"program --foo= -bAr  /Spaetzel=pierogi /Baz flim "
     27                      L"--other-switches=\"--dog=canine --cat=feline\" "
     28                      L"-spaetzle=Crepe   -=loosevalue  flan "
     29                      L"--input-translation=\"45\"--output-rotation "
     30                      L"--quotes=" TRICKY_QUOTED L" "
     31                      L"-- -- --not-a-switch "
     32                      L"\"in the time of submarines...\"");
     33   EXPECT_FALSE(cl.command_line_string().empty());
     34 #elif defined(OS_POSIX)
     35   const char* argv[] = {"program", "--foo=", "-bar",
     36                         "-spaetzel=pierogi", "-baz", "flim",
     37                         "--other-switches=--dog=canine --cat=feline",
     38                         "-spaetzle=Crepe", "-=loosevalue", "flan",
     39                         "--input-translation=45--output-rotation",
     40                         "--", "--", "--not-a-switch",
     41                         "in the time of submarines..."};
     42   CommandLine cl(arraysize(argv), argv);
     43 #endif
     44   EXPECT_FALSE(cl.HasSwitch("cruller"));
     45   EXPECT_FALSE(cl.HasSwitch("flim"));
     46   EXPECT_FALSE(cl.HasSwitch("program"));
     47   EXPECT_FALSE(cl.HasSwitch("dog"));
     48   EXPECT_FALSE(cl.HasSwitch("cat"));
     49   EXPECT_FALSE(cl.HasSwitch("output-rotation"));
     50   EXPECT_FALSE(cl.HasSwitch("not-a-switch"));
     51   EXPECT_FALSE(cl.HasSwitch("--"));
     52 
     53   EXPECT_EQ(FilePath(FILE_PATH_LITERAL("program")).value(),
     54             cl.GetProgram().value());
     55 
     56   EXPECT_TRUE(cl.HasSwitch("foo"));
     57   EXPECT_TRUE(cl.HasSwitch("bar"));
     58   EXPECT_TRUE(cl.HasSwitch("baz"));
     59   EXPECT_TRUE(cl.HasSwitch("spaetzle"));
     60 #if defined(OS_WIN)
     61   EXPECT_TRUE(cl.HasSwitch("SPAETZLE"));
     62 #endif
     63   EXPECT_TRUE(cl.HasSwitch("other-switches"));
     64   EXPECT_TRUE(cl.HasSwitch("input-translation"));
     65 #if defined(OS_WIN)
     66   EXPECT_TRUE(cl.HasSwitch("quotes"));
     67 #endif
     68 
     69   EXPECT_EQ("Crepe", cl.GetSwitchValueASCII("spaetzle"));
     70   EXPECT_EQ("", cl.GetSwitchValueASCII("Foo"));
     71   EXPECT_EQ("", cl.GetSwitchValueASCII("bar"));
     72   EXPECT_EQ("", cl.GetSwitchValueASCII("cruller"));
     73   EXPECT_EQ("--dog=canine --cat=feline", cl.GetSwitchValueASCII(
     74       "other-switches"));
     75   EXPECT_EQ("45--output-rotation", cl.GetSwitchValueASCII("input-translation"));
     76 #if defined(OS_WIN)
     77   EXPECT_EQ(TRICKY, cl.GetSwitchValueNative("quotes"));
     78 #endif
     79 
     80   const std::vector<CommandLine::StringType>& args = cl.args();
     81   ASSERT_EQ(5U, args.size());
     82 
     83   std::vector<CommandLine::StringType>::const_iterator iter = args.begin();
     84   EXPECT_EQ(FILE_PATH_LITERAL("flim"), *iter);
     85   ++iter;
     86   EXPECT_EQ(FILE_PATH_LITERAL("flan"), *iter);
     87   ++iter;
     88   EXPECT_EQ(FILE_PATH_LITERAL("--"), *iter);
     89   ++iter;
     90   EXPECT_EQ(FILE_PATH_LITERAL("--not-a-switch"), *iter);
     91   ++iter;
     92   EXPECT_EQ(FILE_PATH_LITERAL("in the time of submarines..."), *iter);
     93   ++iter;
     94   EXPECT_TRUE(iter == args.end());
     95 #if defined(OS_POSIX)
     96   const std::vector<std::string>& argvec = cl.argv();
     97 
     98   for (size_t i = 0; i < argvec.size(); i++) {
     99     EXPECT_EQ(0, argvec[i].compare(argv[i]));
    100   }
    101 #endif
    102 }
    103 
    104 // Tests behavior with an empty input string.
    105 TEST(CommandLineTest, EmptyString) {
    106 #if defined(OS_WIN)
    107   CommandLine cl = CommandLine::FromString(L"");
    108   EXPECT_TRUE(cl.command_line_string().empty());
    109   EXPECT_TRUE(cl.GetProgram().empty());
    110 #elif defined(OS_POSIX)
    111   CommandLine cl(0, NULL);
    112   EXPECT_TRUE(cl.argv().empty());
    113 #endif
    114   EXPECT_TRUE(cl.args().empty());
    115 }
    116 
    117 // Test methods for appending switches to a command line.
    118 TEST(CommandLineTest, AppendSwitches) {
    119   std::string switch1 = "switch1";
    120   std::string switch2 = "switch2";
    121   std::string value = "value";
    122   std::string switch3 = "switch3";
    123   std::string value3 = "a value with spaces";
    124   std::string switch4 = "switch4";
    125   std::string value4 = "\"a value with quotes\"";
    126   std::string switch5 = "quotes";
    127   std::string value5 = WideToUTF8(TRICKY);
    128 
    129   CommandLine cl(FilePath(FILE_PATH_LITERAL("Program")));
    130 
    131   cl.AppendSwitch(switch1);
    132   cl.AppendSwitchASCII(switch2, value);
    133   cl.AppendSwitchASCII(switch3, value3);
    134   cl.AppendSwitchASCII(switch4, value4);
    135   cl.AppendSwitchASCII(switch5, value5);
    136 
    137   EXPECT_TRUE(cl.HasSwitch(switch1));
    138   EXPECT_TRUE(cl.HasSwitch(switch2));
    139   EXPECT_EQ(value, cl.GetSwitchValueASCII(switch2));
    140   EXPECT_TRUE(cl.HasSwitch(switch3));
    141   EXPECT_EQ(value3, cl.GetSwitchValueASCII(switch3));
    142   EXPECT_TRUE(cl.HasSwitch(switch4));
    143   EXPECT_EQ(value4, cl.GetSwitchValueASCII(switch4));
    144   EXPECT_TRUE(cl.HasSwitch(switch5));
    145   EXPECT_EQ(value5, cl.GetSwitchValueASCII(switch5));
    146 
    147 #if defined(OS_WIN)
    148   EXPECT_EQ(L"\"Program\" "
    149             L"--switch1 "
    150             L"--switch2=value "
    151             L"--switch3=\"a value with spaces\" "
    152             L"--switch4=\"\\\"a value with quotes\\\"\" "
    153             L"--quotes=\"" TRICKY_QUOTED L"\"",
    154             cl.command_line_string());
    155 #endif
    156 }
    157 
    158 // Tests that when AppendArguments is called that the program is set correctly
    159 // on the target CommandLine object and the switches from the source
    160 // CommandLine are added to the target.
    161 TEST(CommandLineTest, AppendArguments) {
    162   CommandLine cl1(FilePath(FILE_PATH_LITERAL("Program")));
    163   cl1.AppendSwitch("switch1");
    164   cl1.AppendSwitchASCII("switch2", "foo");
    165 
    166   CommandLine cl2(CommandLine::NO_PROGRAM);
    167   cl2.AppendArguments(cl1, true);
    168   EXPECT_EQ(cl1.GetProgram().value(), cl2.GetProgram().value());
    169   EXPECT_EQ(cl1.command_line_string(), cl2.command_line_string());
    170 
    171   CommandLine c1(FilePath(FILE_PATH_LITERAL("Program1")));
    172   c1.AppendSwitch("switch1");
    173   CommandLine c2(FilePath(FILE_PATH_LITERAL("Program2")));
    174   c2.AppendSwitch("switch2");
    175 
    176   c1.AppendArguments(c2, true);
    177   EXPECT_EQ(c1.GetProgram().value(), c2.GetProgram().value());
    178   EXPECT_TRUE(c1.HasSwitch("switch1"));
    179   EXPECT_TRUE(c1.HasSwitch("switch2"));
    180 }
    181 
    182 #if defined(OS_WIN)
    183 // Make sure that the program part of a command line is always quoted.
    184 // This only makes sense on Windows and the test is basically here to guard
    185 // against regressions.
    186 TEST(CommandLineTest, ProgramQuotes) {
    187   const FilePath kProgram(L"Program");
    188 
    189   // Check that quotes are not returned from GetProgram().
    190   CommandLine cl(kProgram);
    191   EXPECT_EQ(kProgram.value(), cl.GetProgram().value());
    192 
    193   // Verify that in the command line string, the program part is always quoted.
    194   CommandLine::StringType cmd(cl.command_line_string());
    195   CommandLine::StringType program(cl.GetProgram().value());
    196   EXPECT_EQ('"', cmd[0]);
    197   EXPECT_EQ(program, cmd.substr(1, program.length()));
    198   EXPECT_EQ('"', cmd[program.length() + 1]);
    199 }
    200 #endif
    201