blob: f4d43d49e77b366e4839da4189c40d9a6f74adb7 [file] [log] [blame]
[email protected]72e2e2422012-02-27 18:38:121// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
dcheng093de9b2016-04-04 21:25:515#include "base/command_line.h"
6
7#include <memory>
initial.commitd7cae122008-07-26 21:49:388#include <string>
9#include <vector>
10
[email protected]57999812013-02-24 05:40:5211#include "base/files/file_path.h"
Avi Drissmane3b70bf2019-01-04 19:50:2212#include "base/stl_util.h"
jdoerrie5c4dc4e2019-02-01 18:02:3313#include "base/strings/strcat.h"
[email protected]a4ea1f12013-06-07 18:37:0714#include "base/strings/utf_string_conversions.h"
avi9b6f42932015-12-26 22:15:1415#include "build/build_config.h"
Pavol Markobf16b812019-06-14 00:53:1216#include "testing/gmock/include/gmock/gmock.h"
initial.commitd7cae122008-07-26 21:49:3817#include "testing/gtest/include/gtest/gtest.h"
18
pgal.u-szeged421dddb2014-11-25 12:55:0219namespace base {
[email protected]023ad6ab2013-02-17 05:07:2320
[email protected]98a1c2682010-08-10 18:14:1921// To test Windows quoting behavior, we use a string that has some backslashes
22// and quotes.
23// Consider the command-line argument: q\"bs1\bs2\\bs3q\\\"
24// Here it is with C-style escapes.
[email protected]a40ca4302011-05-14 01:10:2425static const CommandLine::StringType kTrickyQuoted =
26 FILE_PATH_LITERAL("q\\\"bs1\\bs2\\\\bs3q\\\\\\\"");
[email protected]98a1c2682010-08-10 18:14:1927// It should be parsed by Windows as: q"bs1\bs2\\bs3q\"
28// Here that is with C-style escapes.
[email protected]a40ca4302011-05-14 01:10:2429static const CommandLine::StringType kTricky =
30 FILE_PATH_LITERAL("q\"bs1\\bs2\\\\bs3q\\\"");
[email protected]98a1c2682010-08-10 18:14:1931
initial.commitd7cae122008-07-26 21:49:3832TEST(CommandLineTest, CommandLineConstructor) {
[email protected]a40ca4302011-05-14 01:10:2433 const CommandLine::CharType* argv[] = {
34 FILE_PATH_LITERAL("program"),
35 FILE_PATH_LITERAL("--foo="),
36 FILE_PATH_LITERAL("-bAr"),
37 FILE_PATH_LITERAL("-spaetzel=pierogi"),
38 FILE_PATH_LITERAL("-baz"),
39 FILE_PATH_LITERAL("flim"),
40 FILE_PATH_LITERAL("--other-switches=--dog=canine --cat=feline"),
41 FILE_PATH_LITERAL("-spaetzle=Crepe"),
42 FILE_PATH_LITERAL("-=loosevalue"),
[email protected]21e342f2012-10-19 06:19:5943 FILE_PATH_LITERAL("-"),
[email protected]a40ca4302011-05-14 01:10:2444 FILE_PATH_LITERAL("FLAN"),
[email protected]1fa39f02011-09-13 15:45:3445 FILE_PATH_LITERAL("a"),
[email protected]a40ca4302011-05-14 01:10:2446 FILE_PATH_LITERAL("--input-translation=45--output-rotation"),
47 FILE_PATH_LITERAL("--"),
48 FILE_PATH_LITERAL("--"),
49 FILE_PATH_LITERAL("--not-a-switch"),
50 FILE_PATH_LITERAL("\"in the time of submarines...\""),
51 FILE_PATH_LITERAL("unquoted arg-with-space")};
jdoerrie5c4dc4e2019-02-01 18:02:3352 CommandLine cl(size(argv), argv);
[email protected]a40ca4302011-05-14 01:10:2453
[email protected]61a4c6f2011-07-20 04:54:5254 EXPECT_FALSE(cl.GetCommandLineString().empty());
[email protected]a40ca4302011-05-14 01:10:2455 EXPECT_FALSE(cl.HasSwitch("cruller"));
56 EXPECT_FALSE(cl.HasSwitch("flim"));
57 EXPECT_FALSE(cl.HasSwitch("program"));
58 EXPECT_FALSE(cl.HasSwitch("dog"));
59 EXPECT_FALSE(cl.HasSwitch("cat"));
60 EXPECT_FALSE(cl.HasSwitch("output-rotation"));
61 EXPECT_FALSE(cl.HasSwitch("not-a-switch"));
62 EXPECT_FALSE(cl.HasSwitch("--"));
63
64 EXPECT_EQ(FilePath(FILE_PATH_LITERAL("program")).value(),
65 cl.GetProgram().value());
66
67 EXPECT_TRUE(cl.HasSwitch("foo"));
jackhoub20cbb42015-04-22 02:21:4468#if defined(OS_WIN)
69 EXPECT_TRUE(cl.HasSwitch("bar"));
70#else
71 EXPECT_FALSE(cl.HasSwitch("bar"));
72#endif
[email protected]a40ca4302011-05-14 01:10:2473 EXPECT_TRUE(cl.HasSwitch("baz"));
74 EXPECT_TRUE(cl.HasSwitch("spaetzle"));
[email protected]a40ca4302011-05-14 01:10:2475 EXPECT_TRUE(cl.HasSwitch("other-switches"));
76 EXPECT_TRUE(cl.HasSwitch("input-translation"));
77
78 EXPECT_EQ("Crepe", cl.GetSwitchValueASCII("spaetzle"));
jackhou1bd9da92015-05-21 04:48:0079 EXPECT_EQ("", cl.GetSwitchValueASCII("foo"));
[email protected]a40ca4302011-05-14 01:10:2480 EXPECT_EQ("", cl.GetSwitchValueASCII("bar"));
81 EXPECT_EQ("", cl.GetSwitchValueASCII("cruller"));
82 EXPECT_EQ("--dog=canine --cat=feline", cl.GetSwitchValueASCII(
83 "other-switches"));
84 EXPECT_EQ("45--output-rotation", cl.GetSwitchValueASCII("input-translation"));
85
[email protected]75f1c782011-07-13 23:41:2286 const CommandLine::StringVector& args = cl.GetArgs();
[email protected]21e342f2012-10-19 06:19:5987 ASSERT_EQ(8U, args.size());
[email protected]a40ca4302011-05-14 01:10:2488
jdoerrie1c4b8ff2018-10-03 00:10:5789 auto iter = args.begin();
[email protected]a40ca4302011-05-14 01:10:2490 EXPECT_EQ(FILE_PATH_LITERAL("flim"), *iter);
91 ++iter;
[email protected]21e342f2012-10-19 06:19:5992 EXPECT_EQ(FILE_PATH_LITERAL("-"), *iter);
93 ++iter;
[email protected]a40ca4302011-05-14 01:10:2494 EXPECT_EQ(FILE_PATH_LITERAL("FLAN"), *iter);
95 ++iter;
[email protected]1fa39f02011-09-13 15:45:3496 EXPECT_EQ(FILE_PATH_LITERAL("a"), *iter);
97 ++iter;
[email protected]a40ca4302011-05-14 01:10:2498 EXPECT_EQ(FILE_PATH_LITERAL("--"), *iter);
99 ++iter;
100 EXPECT_EQ(FILE_PATH_LITERAL("--not-a-switch"), *iter);
101 ++iter;
102 EXPECT_EQ(FILE_PATH_LITERAL("\"in the time of submarines...\""), *iter);
103 ++iter;
104 EXPECT_EQ(FILE_PATH_LITERAL("unquoted arg-with-space"), *iter);
105 ++iter;
106 EXPECT_TRUE(iter == args.end());
107}
108
109TEST(CommandLineTest, CommandLineFromString) {
[email protected]bb975362009-01-21 01:00:22110#if defined(OS_WIN)
Jan Wilken Dörrieda77fd432019-10-24 21:40:34111 CommandLine cl = CommandLine::FromString(
112 L"program --foo= -bAr /Spaetzel=pierogi /Baz flim "
113 L"--other-switches=\"--dog=canine --cat=feline\" "
114 L"-spaetzle=Crepe -=loosevalue FLAN "
115 L"--input-translation=\"45\"--output-rotation "
116 L"--quotes=" +
117 kTrickyQuoted +
118 L" -- -- --not-a-switch \"in the time of submarines...\"");
[email protected]a40ca4302011-05-14 01:10:24119
[email protected]61a4c6f2011-07-20 04:54:52120 EXPECT_FALSE(cl.GetCommandLineString().empty());
[email protected]b7e0a2a2009-10-13 02:07:25121 EXPECT_FALSE(cl.HasSwitch("cruller"));
122 EXPECT_FALSE(cl.HasSwitch("flim"));
123 EXPECT_FALSE(cl.HasSwitch("program"));
124 EXPECT_FALSE(cl.HasSwitch("dog"));
125 EXPECT_FALSE(cl.HasSwitch("cat"));
126 EXPECT_FALSE(cl.HasSwitch("output-rotation"));
127 EXPECT_FALSE(cl.HasSwitch("not-a-switch"));
128 EXPECT_FALSE(cl.HasSwitch("--"));
initial.commitd7cae122008-07-26 21:49:38129
[email protected]78c4c422010-10-08 00:06:31130 EXPECT_EQ(FilePath(FILE_PATH_LITERAL("program")).value(),
131 cl.GetProgram().value());
initial.commitd7cae122008-07-26 21:49:38132
[email protected]b7e0a2a2009-10-13 02:07:25133 EXPECT_TRUE(cl.HasSwitch("foo"));
134 EXPECT_TRUE(cl.HasSwitch("bar"));
135 EXPECT_TRUE(cl.HasSwitch("baz"));
136 EXPECT_TRUE(cl.HasSwitch("spaetzle"));
[email protected]b7e0a2a2009-10-13 02:07:25137 EXPECT_TRUE(cl.HasSwitch("other-switches"));
138 EXPECT_TRUE(cl.HasSwitch("input-translation"));
[email protected]98a1c2682010-08-10 18:14:19139 EXPECT_TRUE(cl.HasSwitch("quotes"));
initial.commitd7cae122008-07-26 21:49:38140
[email protected]c4e52f0d2009-11-06 19:55:16141 EXPECT_EQ("Crepe", cl.GetSwitchValueASCII("spaetzle"));
jackhou1bd9da92015-05-21 04:48:00142 EXPECT_EQ("", cl.GetSwitchValueASCII("foo"));
[email protected]c4e52f0d2009-11-06 19:55:16143 EXPECT_EQ("", cl.GetSwitchValueASCII("bar"));
144 EXPECT_EQ("", cl.GetSwitchValueASCII("cruller"));
145 EXPECT_EQ("--dog=canine --cat=feline", cl.GetSwitchValueASCII(
146 "other-switches"));
147 EXPECT_EQ("45--output-rotation", cl.GetSwitchValueASCII("input-translation"));
[email protected]a40ca4302011-05-14 01:10:24148 EXPECT_EQ(kTricky, cl.GetSwitchValueNative("quotes"));
initial.commitd7cae122008-07-26 21:49:38149
[email protected]75f1c782011-07-13 23:41:22150 const CommandLine::StringVector& args = cl.GetArgs();
[email protected]2e4c50c2010-07-21 15:57:23151 ASSERT_EQ(5U, args.size());
initial.commitd7cae122008-07-26 21:49:38152
[email protected]2e4c50c2010-07-21 15:57:23153 std::vector<CommandLine::StringType>::const_iterator iter = args.begin();
154 EXPECT_EQ(FILE_PATH_LITERAL("flim"), *iter);
initial.commitd7cae122008-07-26 21:49:38155 ++iter;
[email protected]a40ca4302011-05-14 01:10:24156 EXPECT_EQ(FILE_PATH_LITERAL("FLAN"), *iter);
initial.commitd7cae122008-07-26 21:49:38157 ++iter;
[email protected]2e4c50c2010-07-21 15:57:23158 EXPECT_EQ(FILE_PATH_LITERAL("--"), *iter);
[email protected]02c87962008-10-06 10:25:35159 ++iter;
[email protected]2e4c50c2010-07-21 15:57:23160 EXPECT_EQ(FILE_PATH_LITERAL("--not-a-switch"), *iter);
[email protected]02c87962008-10-06 10:25:35161 ++iter;
[email protected]2e4c50c2010-07-21 15:57:23162 EXPECT_EQ(FILE_PATH_LITERAL("in the time of submarines..."), *iter);
initial.commitd7cae122008-07-26 21:49:38163 ++iter;
[email protected]2e4c50c2010-07-21 15:57:23164 EXPECT_TRUE(iter == args.end());
[email protected]10e42bf2008-10-15 21:59:08165
[email protected]a40ca4302011-05-14 01:10:24166 // Check that a generated string produces an equivalent command line.
[email protected]61a4c6f2011-07-20 04:54:52167 CommandLine cl_duplicate = CommandLine::FromString(cl.GetCommandLineString());
168 EXPECT_EQ(cl.GetCommandLineString(), cl_duplicate.GetCommandLineString());
[email protected]10e42bf2008-10-15 21:59:08169#endif
initial.commitd7cae122008-07-26 21:49:38170}
171
initial.commitd7cae122008-07-26 21:49:38172// Tests behavior with an empty input string.
173TEST(CommandLineTest, EmptyString) {
[email protected]f3adb5c2008-08-07 20:07:32174#if defined(OS_WIN)
Jan Wilken Dörrieda77fd432019-10-24 21:40:34175 CommandLine cl_from_string = CommandLine::FromString(std::wstring());
[email protected]61a4c6f2011-07-20 04:54:52176 EXPECT_TRUE(cl_from_string.GetCommandLineString().empty());
[email protected]a40ca4302011-05-14 01:10:24177 EXPECT_TRUE(cl_from_string.GetProgram().empty());
178 EXPECT_EQ(1U, cl_from_string.argv().size());
[email protected]75f1c782011-07-13 23:41:22179 EXPECT_TRUE(cl_from_string.GetArgs().empty());
[email protected]f3adb5c2008-08-07 20:07:32180#endif
Ivan Kotenkova16212a52017-11-08 12:37:33181 CommandLine cl_from_argv(0, nullptr);
[email protected]61a4c6f2011-07-20 04:54:52182 EXPECT_TRUE(cl_from_argv.GetCommandLineString().empty());
[email protected]a40ca4302011-05-14 01:10:24183 EXPECT_TRUE(cl_from_argv.GetProgram().empty());
184 EXPECT_EQ(1U, cl_from_argv.argv().size());
[email protected]75f1c782011-07-13 23:41:22185 EXPECT_TRUE(cl_from_argv.GetArgs().empty());
initial.commitd7cae122008-07-26 21:49:38186}
187
[email protected]45f982e2012-10-29 21:31:31188TEST(CommandLineTest, GetArgumentsString) {
189 static const FilePath::CharType kPath1[] =
190 FILE_PATH_LITERAL("C:\\Some File\\With Spaces.ggg");
191 static const FilePath::CharType kPath2[] =
192 FILE_PATH_LITERAL("C:\\no\\spaces.ggg");
193
194 static const char kFirstArgName[] = "first-arg";
195 static const char kSecondArgName[] = "arg2";
196 static const char kThirdArgName[] = "arg with space";
197 static const char kFourthArgName[] = "nospace";
[email protected]45f982e2012-10-29 21:31:31198
199 CommandLine cl(CommandLine::NO_PROGRAM);
200 cl.AppendSwitchPath(kFirstArgName, FilePath(kPath1));
201 cl.AppendSwitchPath(kSecondArgName, FilePath(kPath2));
202 cl.AppendArg(kThirdArgName);
203 cl.AppendArg(kFourthArgName);
[email protected]45f982e2012-10-29 21:31:31204
205#if defined(OS_WIN)
Jan Wilken Dörrieda77fd432019-10-24 21:40:34206 CommandLine::StringType expected_first_arg(UTF8ToWide(kFirstArgName));
207 CommandLine::StringType expected_second_arg(UTF8ToWide(kSecondArgName));
208 CommandLine::StringType expected_third_arg(UTF8ToWide(kThirdArgName));
209 CommandLine::StringType expected_fourth_arg(UTF8ToWide(kFourthArgName));
Fabrice de Gans-Riberi306871de2018-05-16 19:38:39210#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]45f982e2012-10-29 21:31:31211 CommandLine::StringType expected_first_arg(kFirstArgName);
212 CommandLine::StringType expected_second_arg(kSecondArgName);
213 CommandLine::StringType expected_third_arg(kThirdArgName);
214 CommandLine::StringType expected_fourth_arg(kFourthArgName);
[email protected]45f982e2012-10-29 21:31:31215#endif
216
217#if defined(OS_WIN)
218#define QUOTE_ON_WIN FILE_PATH_LITERAL("\"")
219#else
220#define QUOTE_ON_WIN FILE_PATH_LITERAL("")
221#endif // OS_WIN
222
223 CommandLine::StringType expected_str;
224 expected_str.append(FILE_PATH_LITERAL("--"))
Jesse McKenna452f8312020-05-29 23:06:56225 .append(expected_first_arg)
226 .append(FILE_PATH_LITERAL("="))
227 .append(QUOTE_ON_WIN)
228 .append(kPath1)
229 .append(QUOTE_ON_WIN)
230 .append(FILE_PATH_LITERAL(" "))
231 .append(FILE_PATH_LITERAL("--"))
232 .append(expected_second_arg)
233 .append(FILE_PATH_LITERAL("="))
234 .append(QUOTE_ON_WIN)
235 .append(kPath2)
236 .append(QUOTE_ON_WIN)
237 .append(FILE_PATH_LITERAL(" "))
238 .append(QUOTE_ON_WIN)
239 .append(expected_third_arg)
240 .append(QUOTE_ON_WIN)
241 .append(FILE_PATH_LITERAL(" "))
242 .append(expected_fourth_arg);
243 EXPECT_EQ(expected_str, cl.GetArgumentsString());
[email protected]45f982e2012-10-29 21:31:31244}
245
[email protected]bb975362009-01-21 01:00:22246// Test methods for appending switches to a command line.
initial.commitd7cae122008-07-26 21:49:38247TEST(CommandLineTest, AppendSwitches) {
[email protected]b7e0a2a2009-10-13 02:07:25248 std::string switch1 = "switch1";
249 std::string switch2 = "switch2";
[email protected]a40ca4302011-05-14 01:10:24250 std::string value2 = "value";
[email protected]b7e0a2a2009-10-13 02:07:25251 std::string switch3 = "switch3";
[email protected]05076ba22010-07-30 05:59:57252 std::string value3 = "a value with spaces";
[email protected]b7e0a2a2009-10-13 02:07:25253 std::string switch4 = "switch4";
[email protected]05076ba22010-07-30 05:59:57254 std::string value4 = "\"a value with quotes\"";
[email protected]98a1c2682010-08-10 18:14:19255 std::string switch5 = "quotes";
[email protected]a40ca4302011-05-14 01:10:24256 CommandLine::StringType value5 = kTricky;
initial.commitd7cae122008-07-26 21:49:38257
[email protected]51343d5a2009-10-26 22:39:33258 CommandLine cl(FilePath(FILE_PATH_LITERAL("Program")));
initial.commitd7cae122008-07-26 21:49:38259
[email protected]bb975362009-01-21 01:00:22260 cl.AppendSwitch(switch1);
[email protected]a40ca4302011-05-14 01:10:24261 cl.AppendSwitchASCII(switch2, value2);
[email protected]05076ba22010-07-30 05:59:57262 cl.AppendSwitchASCII(switch3, value3);
263 cl.AppendSwitchASCII(switch4, value4);
jackhou1bd9da92015-05-21 04:48:00264 cl.AppendSwitchASCII(switch5, value4);
[email protected]a40ca4302011-05-14 01:10:24265 cl.AppendSwitchNative(switch5, value5);
[email protected]bb975362009-01-21 01:00:22266
initial.commitd7cae122008-07-26 21:49:38267 EXPECT_TRUE(cl.HasSwitch(switch1));
268 EXPECT_TRUE(cl.HasSwitch(switch2));
[email protected]a40ca4302011-05-14 01:10:24269 EXPECT_EQ(value2, cl.GetSwitchValueASCII(switch2));
initial.commitd7cae122008-07-26 21:49:38270 EXPECT_TRUE(cl.HasSwitch(switch3));
[email protected]05076ba22010-07-30 05:59:57271 EXPECT_EQ(value3, cl.GetSwitchValueASCII(switch3));
[email protected]8c9510d2008-10-10 21:38:20272 EXPECT_TRUE(cl.HasSwitch(switch4));
[email protected]05076ba22010-07-30 05:59:57273 EXPECT_EQ(value4, cl.GetSwitchValueASCII(switch4));
[email protected]98a1c2682010-08-10 18:14:19274 EXPECT_TRUE(cl.HasSwitch(switch5));
[email protected]a40ca4302011-05-14 01:10:24275 EXPECT_EQ(value5, cl.GetSwitchValueNative(switch5));
[email protected]98a1c2682010-08-10 18:14:19276
277#if defined(OS_WIN)
jdoerrie5c4dc4e2019-02-01 18:02:33278 EXPECT_EQ(
Jan Wilken Dörrieda77fd432019-10-24 21:40:34279 L"Program "
280 L"--switch1 "
281 L"--switch2=value "
282 L"--switch3=\"a value with spaces\" "
283 L"--switch4=\"\\\"a value with quotes\\\"\" "
284 // Even though the switches are unique, appending can add repeat
285 // switches to argv.
286 L"--quotes=\"\\\"a value with quotes\\\"\" "
287 L"--quotes=\"" +
288 kTrickyQuoted + L"\"",
jdoerrie5c4dc4e2019-02-01 18:02:33289 cl.GetCommandLineString());
[email protected]98a1c2682010-08-10 18:14:19290#endif
initial.commitd7cae122008-07-26 21:49:38291}
[email protected]e6124ad52010-11-15 04:17:52292
[email protected]a40ca4302011-05-14 01:10:24293TEST(CommandLineTest, AppendSwitchesDashDash) {
294 const CommandLine::CharType* raw_argv[] = { FILE_PATH_LITERAL("prog"),
295 FILE_PATH_LITERAL("--"),
296 FILE_PATH_LITERAL("--arg1") };
jdoerrie5c4dc4e2019-02-01 18:02:33297 CommandLine cl(size(raw_argv), raw_argv);
[email protected]a40ca4302011-05-14 01:10:24298
Avi Drissmane3b70bf2019-01-04 19:50:22299 cl.AppendSwitch("switch1");
300 cl.AppendSwitchASCII("switch2", "foo");
[email protected]a40ca4302011-05-14 01:10:24301
Avi Drissmane3b70bf2019-01-04 19:50:22302 cl.AppendArg("--arg2");
[email protected]a40ca4302011-05-14 01:10:24303
Avi Drissmane3b70bf2019-01-04 19:50:22304 EXPECT_EQ(FILE_PATH_LITERAL("prog --switch1 --switch2=foo -- --arg1 --arg2"),
305 cl.GetCommandLineString());
306 CommandLine::StringVector cl_argv = cl.argv();
307 EXPECT_EQ(FILE_PATH_LITERAL("prog"), cl_argv[0]);
308 EXPECT_EQ(FILE_PATH_LITERAL("--switch1"), cl_argv[1]);
309 EXPECT_EQ(FILE_PATH_LITERAL("--switch2=foo"), cl_argv[2]);
310 EXPECT_EQ(FILE_PATH_LITERAL("--"), cl_argv[3]);
311 EXPECT_EQ(FILE_PATH_LITERAL("--arg1"), cl_argv[4]);
312 EXPECT_EQ(FILE_PATH_LITERAL("--arg2"), cl_argv[5]);
[email protected]a40ca4302011-05-14 01:10:24313}
314
Jesse McKenna452f8312020-05-29 23:06:56315#if defined(OS_WIN)
316TEST(CommandLineTest, GetCommandLineStringForShell) {
317 CommandLine cl = CommandLine::FromString(
318 FILE_PATH_LITERAL("program --switch /switch2 --"));
319 EXPECT_EQ(
320 cl.GetCommandLineStringForShell(),
321 FILE_PATH_LITERAL("program --switch /switch2 -- --single-argument=%1"));
322}
323#endif // defined(OS_WIN)
324
[email protected]e6124ad52010-11-15 04:17:52325// Tests that when AppendArguments is called that the program is set correctly
326// on the target CommandLine object and the switches from the source
327// CommandLine are added to the target.
328TEST(CommandLineTest, AppendArguments) {
329 CommandLine cl1(FilePath(FILE_PATH_LITERAL("Program")));
330 cl1.AppendSwitch("switch1");
331 cl1.AppendSwitchASCII("switch2", "foo");
332
333 CommandLine cl2(CommandLine::NO_PROGRAM);
334 cl2.AppendArguments(cl1, true);
335 EXPECT_EQ(cl1.GetProgram().value(), cl2.GetProgram().value());
[email protected]61a4c6f2011-07-20 04:54:52336 EXPECT_EQ(cl1.GetCommandLineString(), cl2.GetCommandLineString());
[email protected]e6124ad52010-11-15 04:17:52337
338 CommandLine c1(FilePath(FILE_PATH_LITERAL("Program1")));
339 c1.AppendSwitch("switch1");
340 CommandLine c2(FilePath(FILE_PATH_LITERAL("Program2")));
341 c2.AppendSwitch("switch2");
342
343 c1.AppendArguments(c2, true);
344 EXPECT_EQ(c1.GetProgram().value(), c2.GetProgram().value());
345 EXPECT_TRUE(c1.HasSwitch("switch1"));
346 EXPECT_TRUE(c1.HasSwitch("switch2"));
347}
348
[email protected]450b34ec2010-11-29 21:12:22349#if defined(OS_WIN)
[email protected]61a4c6f2011-07-20 04:54:52350// Make sure that the command line string program paths are quoted as necessary.
[email protected]450b34ec2010-11-29 21:12:22351// This only makes sense on Windows and the test is basically here to guard
352// against regressions.
353TEST(CommandLineTest, ProgramQuotes) {
[email protected]a40ca4302011-05-14 01:10:24354 // Check that quotes are not added for paths without spaces.
Jan Wilken Dörrieda77fd432019-10-24 21:40:34355 const FilePath kProgram(L"Program");
[email protected]a40ca4302011-05-14 01:10:24356 CommandLine cl_program(kProgram);
357 EXPECT_EQ(kProgram.value(), cl_program.GetProgram().value());
[email protected]61a4c6f2011-07-20 04:54:52358 EXPECT_EQ(kProgram.value(), cl_program.GetCommandLineString());
[email protected]a40ca4302011-05-14 01:10:24359
Jan Wilken Dörrieda77fd432019-10-24 21:40:34360 const FilePath kProgramPath(L"Program Path");
[email protected]450b34ec2010-11-29 21:12:22361
362 // Check that quotes are not returned from GetProgram().
[email protected]a40ca4302011-05-14 01:10:24363 CommandLine cl_program_path(kProgramPath);
364 EXPECT_EQ(kProgramPath.value(), cl_program_path.GetProgram().value());
[email protected]450b34ec2010-11-29 21:12:22365
[email protected]a40ca4302011-05-14 01:10:24366 // Check that quotes are added to command line string paths containing spaces.
[email protected]61a4c6f2011-07-20 04:54:52367 CommandLine::StringType cmd_string(cl_program_path.GetCommandLineString());
Jan Wilken Dörrieda77fd432019-10-24 21:40:34368 EXPECT_EQ(L"\"Program Path\"", cmd_string);
[email protected]450b34ec2010-11-29 21:12:22369}
370#endif
[email protected]f96fe2c42011-07-13 18:03:34371
372// Calling Init multiple times should not modify the previous CommandLine.
373TEST(CommandLineTest, Init) {
arihce89963ac2015-08-12 23:45:48374 // Call Init without checking output once so we know it's been called
375 // whether or not the test runner does so.
Ivan Kotenkova16212a52017-11-08 12:37:33376 CommandLine::Init(0, nullptr);
[email protected]f96fe2c42011-07-13 18:03:34377 CommandLine* initial = CommandLine::ForCurrentProcess();
Ivan Kotenkova16212a52017-11-08 12:37:33378 EXPECT_FALSE(CommandLine::Init(0, nullptr));
[email protected]f96fe2c42011-07-13 18:03:34379 CommandLine* current = CommandLine::ForCurrentProcess();
380 EXPECT_EQ(initial, current);
381}
pgal.u-szeged421dddb2014-11-25 12:55:02382
jackhou1bd9da92015-05-21 04:48:00383// Test that copies of CommandLine have a valid StringPiece map.
384TEST(CommandLineTest, Copy) {
dcheng093de9b2016-04-04 21:25:51385 std::unique_ptr<CommandLine> initial(
386 new CommandLine(CommandLine::NO_PROGRAM));
jackhou1bd9da92015-05-21 04:48:00387 initial->AppendSwitch("a");
388 initial->AppendSwitch("bbbbbbbbbbbbbbb");
389 initial->AppendSwitch("c");
390 CommandLine copy_constructed(*initial);
391 CommandLine assigned = *initial;
392 CommandLine::SwitchMap switch_map = initial->GetSwitches();
393 initial.reset();
394 for (const auto& pair : switch_map)
395 EXPECT_TRUE(copy_constructed.HasSwitch(pair.first));
396 for (const auto& pair : switch_map)
397 EXPECT_TRUE(assigned.HasSwitch(pair.first));
398}
399
skyostild851aa12017-03-29 17:38:35400TEST(CommandLineTest, PrependSimpleWrapper) {
401 CommandLine cl(FilePath(FILE_PATH_LITERAL("Program")));
402 cl.AppendSwitch("a");
403 cl.AppendSwitch("b");
404 cl.PrependWrapper(FILE_PATH_LITERAL("wrapper --foo --bar"));
405
406 EXPECT_EQ(6u, cl.argv().size());
407 EXPECT_EQ(FILE_PATH_LITERAL("wrapper"), cl.argv()[0]);
408 EXPECT_EQ(FILE_PATH_LITERAL("--foo"), cl.argv()[1]);
409 EXPECT_EQ(FILE_PATH_LITERAL("--bar"), cl.argv()[2]);
410 EXPECT_EQ(FILE_PATH_LITERAL("Program"), cl.argv()[3]);
411 EXPECT_EQ(FILE_PATH_LITERAL("--a"), cl.argv()[4]);
412 EXPECT_EQ(FILE_PATH_LITERAL("--b"), cl.argv()[5]);
413}
414
415TEST(CommandLineTest, PrependComplexWrapper) {
416 CommandLine cl(FilePath(FILE_PATH_LITERAL("Program")));
417 cl.AppendSwitch("a");
418 cl.AppendSwitch("b");
419 cl.PrependWrapper(
420 FILE_PATH_LITERAL("wrapper --foo='hello world' --bar=\"let's go\""));
421
422 EXPECT_EQ(6u, cl.argv().size());
423 EXPECT_EQ(FILE_PATH_LITERAL("wrapper"), cl.argv()[0]);
424 EXPECT_EQ(FILE_PATH_LITERAL("--foo='hello world'"), cl.argv()[1]);
425 EXPECT_EQ(FILE_PATH_LITERAL("--bar=\"let's go\""), cl.argv()[2]);
426 EXPECT_EQ(FILE_PATH_LITERAL("Program"), cl.argv()[3]);
427 EXPECT_EQ(FILE_PATH_LITERAL("--a"), cl.argv()[4]);
428 EXPECT_EQ(FILE_PATH_LITERAL("--b"), cl.argv()[5]);
429}
430
Avi Drissman1aa6cb92019-01-23 15:58:38431TEST(CommandLineTest, RemoveSwitch) {
Pavol Markobf16b812019-06-14 00:53:12432 const std::string switch1 = "switch1";
433 const std::string switch2 = "switch2";
434 const std::string value2 = "value";
Avi Drissman1aa6cb92019-01-23 15:58:38435
436 CommandLine cl(FilePath(FILE_PATH_LITERAL("Program")));
437
438 cl.AppendSwitch(switch1);
439 cl.AppendSwitchASCII(switch2, value2);
440
441 EXPECT_TRUE(cl.HasSwitch(switch1));
442 EXPECT_TRUE(cl.HasSwitch(switch2));
443 EXPECT_EQ(value2, cl.GetSwitchValueASCII(switch2));
Pavol Markobf16b812019-06-14 00:53:12444 EXPECT_THAT(cl.argv(),
445 testing::ElementsAre(FILE_PATH_LITERAL("Program"),
446 FILE_PATH_LITERAL("--switch1"),
447 FILE_PATH_LITERAL("--switch2=value")));
Avi Drissman1aa6cb92019-01-23 15:58:38448
449 cl.RemoveSwitch(switch1);
450
451 EXPECT_FALSE(cl.HasSwitch(switch1));
452 EXPECT_TRUE(cl.HasSwitch(switch2));
453 EXPECT_EQ(value2, cl.GetSwitchValueASCII(switch2));
Pavol Markobf16b812019-06-14 00:53:12454 EXPECT_THAT(cl.argv(),
455 testing::ElementsAre(FILE_PATH_LITERAL("Program"),
456 FILE_PATH_LITERAL("--switch2=value")));
457}
458
459TEST(CommandLineTest, RemoveSwitchWithValue) {
460 const std::string switch1 = "switch1";
461 const std::string switch2 = "switch2";
462 const std::string value2 = "value";
463
464 CommandLine cl(FilePath(FILE_PATH_LITERAL("Program")));
465
466 cl.AppendSwitch(switch1);
467 cl.AppendSwitchASCII(switch2, value2);
468
469 EXPECT_TRUE(cl.HasSwitch(switch1));
470 EXPECT_TRUE(cl.HasSwitch(switch2));
471 EXPECT_EQ(value2, cl.GetSwitchValueASCII(switch2));
472 EXPECT_THAT(cl.argv(),
473 testing::ElementsAre(FILE_PATH_LITERAL("Program"),
474 FILE_PATH_LITERAL("--switch1"),
475 FILE_PATH_LITERAL("--switch2=value")));
476
477 cl.RemoveSwitch(switch2);
478
479 EXPECT_TRUE(cl.HasSwitch(switch1));
480 EXPECT_FALSE(cl.HasSwitch(switch2));
481 EXPECT_THAT(cl.argv(), testing::ElementsAre(FILE_PATH_LITERAL("Program"),
482 FILE_PATH_LITERAL("--switch1")));
483}
484
Andrei Polushin2ec89bc2019-07-30 20:47:17485TEST(CommandLineTest, RemoveSwitchDropsMultipleSameSwitches) {
486 const std::string switch1 = "switch1";
487 const std::string value2 = "value2";
488
489 CommandLine cl(FilePath(FILE_PATH_LITERAL("Program")));
490
491 cl.AppendSwitch(switch1);
492 cl.AppendSwitchASCII(switch1, value2);
493
494 EXPECT_TRUE(cl.HasSwitch(switch1));
495 EXPECT_EQ(value2, cl.GetSwitchValueASCII(switch1));
496 EXPECT_THAT(cl.argv(),
497 testing::ElementsAre(FILE_PATH_LITERAL("Program"),
498 FILE_PATH_LITERAL("--switch1"),
499 FILE_PATH_LITERAL("--switch1=value2")));
500
501 cl.RemoveSwitch(switch1);
502
503 EXPECT_FALSE(cl.HasSwitch(switch1));
504 EXPECT_THAT(cl.argv(), testing::ElementsAre(FILE_PATH_LITERAL("Program")));
505}
506
Pavol Markobf16b812019-06-14 00:53:12507TEST(CommandLineTest, AppendAndRemoveSwitchWithDefaultPrefix) {
508 CommandLine cl(FilePath(FILE_PATH_LITERAL("Program")));
509
510 cl.AppendSwitch("foo");
511 EXPECT_THAT(cl.argv(), testing::ElementsAre(FILE_PATH_LITERAL("Program"),
512 FILE_PATH_LITERAL("--foo")));
513 EXPECT_EQ(0u, cl.GetArgs().size());
514
515 cl.RemoveSwitch("foo");
516 EXPECT_THAT(cl.argv(), testing::ElementsAre(FILE_PATH_LITERAL("Program")));
517 EXPECT_EQ(0u, cl.GetArgs().size());
518}
519
520TEST(CommandLineTest, AppendAndRemoveSwitchWithAlternativePrefix) {
521 CommandLine cl(FilePath(FILE_PATH_LITERAL("Program")));
522
523 cl.AppendSwitch("-foo");
524 EXPECT_THAT(cl.argv(), testing::ElementsAre(FILE_PATH_LITERAL("Program"),
525 FILE_PATH_LITERAL("-foo")));
526 EXPECT_EQ(0u, cl.GetArgs().size());
527
528 cl.RemoveSwitch("foo");
529 EXPECT_THAT(cl.argv(), testing::ElementsAre(FILE_PATH_LITERAL("Program")));
530 EXPECT_EQ(0u, cl.GetArgs().size());
531}
532
533TEST(CommandLineTest, AppendAndRemoveSwitchPreservesOtherSwitchesAndArgs) {
534 CommandLine cl(FilePath(FILE_PATH_LITERAL("Program")));
535
536 cl.AppendSwitch("foo");
537 cl.AppendSwitch("bar");
538 cl.AppendArg("arg");
539 EXPECT_THAT(cl.argv(), testing::ElementsAre(FILE_PATH_LITERAL("Program"),
540 FILE_PATH_LITERAL("--foo"),
541 FILE_PATH_LITERAL("--bar"),
542 FILE_PATH_LITERAL("arg")));
543 EXPECT_THAT(cl.GetArgs(), testing::ElementsAre(FILE_PATH_LITERAL("arg")));
544
545 cl.RemoveSwitch("foo");
546 EXPECT_THAT(cl.argv(), testing::ElementsAre(FILE_PATH_LITERAL("Program"),
547 FILE_PATH_LITERAL("--bar"),
548 FILE_PATH_LITERAL("arg")));
549 EXPECT_THAT(cl.GetArgs(), testing::ElementsAre(FILE_PATH_LITERAL("arg")));
Avi Drissman1aa6cb92019-01-23 15:58:38550}
551
John Rummellb1d5fcb2019-04-27 01:13:33552TEST(CommandLineTest, MultipleSameSwitch) {
553 const CommandLine::CharType* argv[] = {
554 FILE_PATH_LITERAL("program"),
555 FILE_PATH_LITERAL("--foo=one"), // --foo first time
556 FILE_PATH_LITERAL("-baz"),
557 FILE_PATH_LITERAL("--foo=two") // --foo second time
558 };
559 CommandLine cl(size(argv), argv);
560
561 EXPECT_TRUE(cl.HasSwitch("foo"));
562 EXPECT_TRUE(cl.HasSwitch("baz"));
563
564 EXPECT_EQ("two", cl.GetSwitchValueASCII("foo"));
565}
566
Jesse McKenna452f8312020-05-29 23:06:56567#if defined(OS_WIN)
568TEST(CommandLineTest, ParseAsSingleArgument) {
569 CommandLine cl = CommandLine::FromString(
570 FILE_PATH_LITERAL("program --switch_before arg_before "
571 "--single-argument=arg with spaces \"and quotes\" \""));
572
573 EXPECT_FALSE(cl.GetCommandLineString().empty());
574 EXPECT_EQ(FilePath(FILE_PATH_LITERAL("program")), cl.GetProgram());
575 EXPECT_TRUE(cl.HasSwitch("switch_before"));
576 EXPECT_EQ(cl.GetArgs(), CommandLine::StringVector({FILE_PATH_LITERAL(
577 "arg with spaces \"and quotes\" \"")}));
578}
579#endif // defined(OS_WIN)
580
pgal.u-szeged421dddb2014-11-25 12:55:02581} // namespace base