blob: 0a1bf280fd653d323c8bc9e52b6803b13f3f7917 [file] [log] [blame]
ccalvarin58acb7b2018-03-08 10:53:24 -08001// Copyright 2018 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include <vector>
16
17#include "src/main/cpp/blaze_util.h"
18#include "src/main/cpp/blaze_util_platform.h"
19#include "src/main/cpp/option_processor.h"
20#include "src/main/cpp/util/file.h"
21#include "src/main/cpp/util/file_platform.h"
ccalvarinac69da02018-06-05 15:27:26 -070022#include "src/main/cpp/util/path.h"
ccalvarin58acb7b2018-03-08 10:53:24 -080023#include "src/main/cpp/util/strings.h"
24#include "src/main/cpp/workspace_layout.h"
ccalvarin8ceaa652018-08-24 12:44:31 -070025#include "googlemock/include/gmock/gmock.h"
ccalvarin8e9f4a82018-03-23 08:19:37 -070026#include "googletest/include/gtest/gtest.h"
ccalvarin58acb7b2018-03-08 10:53:24 -080027
28namespace blaze {
29using std::string;
30using std::unordered_map;
31using std::vector;
ccalvarin8ceaa652018-08-24 12:44:31 -070032using ::testing::MatchesRegex;
ccalvarin58acb7b2018-03-08 10:53:24 -080033
Googlerda23fd52022-09-14 15:29:38 -070034#if _WIN32
35constexpr bool kIsWindows = true;
36#else
37constexpr bool kIsWindows = false;
38#endif
39
ccalvarin58acb7b2018-03-08 10:53:24 -080040class RcOptionsTest : public ::testing::Test {
41 protected:
42 RcOptionsTest()
arostovtsev04e182e2019-12-26 09:14:02 -080043 : test_file_dir_(blaze_util::JoinPath(
44 blaze::GetPathEnv("TEST_TMPDIR"),
45 ::testing::UnitTest::GetInstance()->current_test_info()->name())),
46 workspace_layout_() {
47 }
ccalvarin58acb7b2018-03-08 10:53:24 -080048
49 const string test_file_dir_;
50 const WorkspaceLayout workspace_layout_;
51
52 void WriteRc(const string& filename, const string& contents) {
arostovtsev04e182e2019-12-26 09:14:02 -080053 bool success_mkdir = blaze_util::MakeDirectories(test_file_dir_, 0755);
54 ASSERT_TRUE(success_mkdir) << "Failed to mkdir -p " << test_file_dir_;
55 bool success_write = blaze_util::WriteFile(
ccalvarin58acb7b2018-03-08 10:53:24 -080056 contents, blaze_util::JoinPath(test_file_dir_, filename));
arostovtsev04e182e2019-12-26 09:14:02 -080057 ASSERT_TRUE(success_write) << "Failed to write " << filename;
ccalvarin58acb7b2018-03-08 10:53:24 -080058 }
59
60 std::unique_ptr<RcFile> Parse(const string& filename,
61 RcFile::ParseError* error,
62 std::string* error_text) {
63 return RcFile::Parse(
64 blaze_util::JoinPath(test_file_dir_, filename),
65 &workspace_layout_,
66 // Set workspace to test_file_dir_ so importing %workspace%/foo works.
67 test_file_dir_,
68 error,
69 error_text);
70 }
71
72 void SuccessfullyParseRcWithExpectedArgs(
73 const string& filename,
74 const unordered_map<string, vector<string>>& expected_args_map) {
75 RcFile::ParseError error;
76 string error_text;
77 std::unique_ptr<RcFile> rc = Parse(filename, &error, &error_text);
78 EXPECT_EQ(error_text, "");
79 ASSERT_EQ(error, RcFile::ParseError::NONE);
80
81 // Test that exactly each command in the expected map was in the results,
82 // and that for each of these, exactly the expected args are found, in the
Xiangquan Xiao7c0bdc22022-10-27 00:05:38 -070083 // correct order. Note that this is not just an exercise in rewriting map
ccalvarin58acb7b2018-03-08 10:53:24 -080084 // equality - the results have type RcOption, and the expected values
85 // are just strings. This is ignoring the source_path for convenience.
86 const RcFile::OptionMap& result = rc->options();
87 ASSERT_EQ(expected_args_map.size(), result.size());
88 for (const auto& command_args_pair : expected_args_map) {
89 const string& expected_command = command_args_pair.first;
90 const vector<string>& expected_args = command_args_pair.second;
91 const auto result_args_iter = result.find(expected_command);
92 ASSERT_NE(result_args_iter, rc->options().end());
93 const std::vector<RcOption>& result_args = result_args_iter->second;
94 ASSERT_EQ(result_args.size(), expected_args.size());
95 for (size_t i = 0; i < result_args.size(); ++i) {
96 EXPECT_EQ(result_args[i].option, expected_args[i]);
97 }
98 }
99 }
100};
101
ccalvarin58acb7b2018-03-08 10:53:24 -0800102TEST_F(RcOptionsTest, Empty) {
103 WriteRc("empty.bazelrc",
104 "");
105 unordered_map<string, vector<string>> no_expected_args;
106 SuccessfullyParseRcWithExpectedArgs("empty.bazelrc", no_expected_args);
107}
108
109TEST_F(RcOptionsTest, Whitespace) {
110 WriteRc("whitespace.bazelrc",
111 " \n\t ");
112 unordered_map<string, vector<string>> no_expected_args;
113 SuccessfullyParseRcWithExpectedArgs("whitespace.bazelrc", no_expected_args);
114}
115
116TEST_F(RcOptionsTest, CommentedStartup) {
117 WriteRc("commented_startup.bazelrc",
118 "# startup foo");
119 unordered_map<string, vector<string>> no_expected_args;
arostovtsev04e182e2019-12-26 09:14:02 -0800120 SuccessfullyParseRcWithExpectedArgs("commented_startup.bazelrc",
121 no_expected_args);
ccalvarin58acb7b2018-03-08 10:53:24 -0800122}
123
124TEST_F(RcOptionsTest, EmptyStartupLine) {
125 WriteRc("empty_startup_line.bazelrc",
126 "startup");
127 unordered_map<string, vector<string>> no_expected_args;
128 SuccessfullyParseRcWithExpectedArgs("empty_startup_line.bazelrc",
129 no_expected_args);
130}
131
132TEST_F(RcOptionsTest, StartupWithOnlyCommentedArg) {
133 WriteRc("startup_with_comment.bazelrc",
134 "startup # bar");
135 unordered_map<string, vector<string>> no_expected_args;
136 SuccessfullyParseRcWithExpectedArgs("startup_with_comment.bazelrc",
137 no_expected_args);
138}
139
ccalvarin58acb7b2018-03-08 10:53:24 -0800140TEST_F(RcOptionsTest, SingleStartupArg) {
141 WriteRc("startup_foo.bazelrc",
142 "startup foo");
143 SuccessfullyParseRcWithExpectedArgs(
144 "startup_foo.bazelrc",
145 {{"startup", {"foo"}}});
146}
147
148TEST_F(RcOptionsTest, SingleStartupArgWithComment) {
149 WriteRc("startup_foo_and_comment.bazelrc",
150 "startup foo # comment");
151 SuccessfullyParseRcWithExpectedArgs(
152 "startup_foo_and_comment.bazelrc",
153 {{"startup", {"foo"}}});
154}
155
156TEST_F(RcOptionsTest, TwoStartupArgsOnOneLine) {
157 WriteRc("startup_foo_bar.bazelrc",
158 "startup foo bar");
159 SuccessfullyParseRcWithExpectedArgs(
160 "startup_foo_bar.bazelrc",
161 {{"startup", {"foo", "bar"}}});
162}
163
164TEST_F(RcOptionsTest, TwoStartupArgsOnOneLineTabSeparated) {
165 WriteRc("startup_with_tabs.bazelrc",
166 "startup\tfoo\tbar");
167 SuccessfullyParseRcWithExpectedArgs(
168 "startup_with_tabs.bazelrc",
169 {{"startup", {"foo", "bar"}}});
170}
171
172TEST_F(RcOptionsTest, StartupOptWithSimpleValue) {
173 WriteRc("startup_opt_with_simple_value.bazelrc",
174 "startup --opt=foo");
175 SuccessfullyParseRcWithExpectedArgs(
176 "startup_opt_with_simple_value.bazelrc",
177 {{"startup", {"--opt=foo"}}});
178}
179
180TEST_F(RcOptionsTest, StartupQuotedArg) {
181 WriteRc("startup_quoted_foo_bar.bazelrc",
182 "startup \"foo bar\"");
183 SuccessfullyParseRcWithExpectedArgs(
184 "startup_quoted_foo_bar.bazelrc",
185 {{"startup", {"foo bar"}}});
186}
187
188TEST_F(RcOptionsTest, QuotedValueStartupArgAfterEquals) {
189 WriteRc("startup_opt_quoted_arg.bazelrc",
190 "startup --opt=\"foo bar\"");
191 SuccessfullyParseRcWithExpectedArgs(
192 "startup_opt_quoted_arg.bazelrc",
193 {{"startup", {"--opt=foo bar"}}});
194}
195
196TEST_F(RcOptionsTest, QuotedValueStartupArgAfterWhitespace) {
197 WriteRc("startup_opt_quoted_arg_as_separate_token.bazelrc",
198 "startup --opt \"foo bar\"");
199 SuccessfullyParseRcWithExpectedArgs(
200 "startup_opt_quoted_arg_as_separate_token.bazelrc",
201 {{"startup", {"--opt", "foo bar"}}});
202}
203
204TEST_F(RcOptionsTest, QuotedValueStartupArgOnNewLine) {
205 WriteRc("startup_opt_quoted_arg_different_line.bazelrc",
206 "startup --opt\n"
207 "startup \"foo bar\"");
208 SuccessfullyParseRcWithExpectedArgs(
209 "startup_opt_quoted_arg_different_line.bazelrc",
210 {{"startup", {"--opt", "foo bar"}}});
211}
212
213TEST_F(RcOptionsTest, TwoOptStartup) {
214 WriteRc("startup_two_options.bazelrc",
215 "startup --opt1\n"
216 "startup --opt2");
217 SuccessfullyParseRcWithExpectedArgs(
218 "startup_two_options.bazelrc",
219 {{"startup", {"--opt1", "--opt2"}}});
220}
221
222TEST_F(RcOptionsTest, WhitespaceBeforeStartup) {
223 WriteRc("whitespace_before_command.bazelrc",
224 " startup foo\n"
225 " # indented comments\n"
226 "startup bar\n"
227 "\tstartup \t baz");
228 SuccessfullyParseRcWithExpectedArgs(
229 "whitespace_before_command.bazelrc",
230 {{"startup", {"foo", "bar", "baz"}}});
231}
232
233TEST_F(RcOptionsTest, StartupLineContinuation) {
234 WriteRc("startup_line_continuation.bazelrc",
235 "startup \\\n"
236 "foo\n"
237 "startup bar \\\n"
238 "baz");
239 SuccessfullyParseRcWithExpectedArgs(
240 "startup_line_continuation.bazelrc",
241 {{"startup", {"foo", "bar", "baz"}}});
242}
243
244TEST_F(RcOptionsTest, ManyArgStartup) {
245 WriteRc("startup_with_many_args.bazelrc",
246 "# Many arguments\n"
247 "startup foo # First argument has reasons.\n"
248 "startup --opt1 --opt2 # These arguments are split wide\n"
249 "#startup --this_is_not_an_arg\n"
250 "\n\n\n # A few empty lines for good measure\n"
251 "startup\t \"string input Value 123. \" --bar");
252 SuccessfullyParseRcWithExpectedArgs(
253 "startup_with_many_args.bazelrc",
254 {{
255 "startup",
256 {"foo", "--opt1", "--opt2", "string input Value 123. ", "--bar"}
257 }});
258}
259
ccalvarin58acb7b2018-03-08 10:53:24 -0800260TEST_F(RcOptionsTest, MultipleCommands) {
261 WriteRc("multiple_commands_intermixed.bazelrc",
262 "startup foo\n"
263 "build aaa\n"
264 "startup bar baz\n"
265 "build bbb\n"
266 "build ccc\n");
267 SuccessfullyParseRcWithExpectedArgs(
268 "multiple_commands_intermixed.bazelrc",
269 {{"startup", {"foo", "bar", "baz"}}, {"build", {"aaa", "bbb", "ccc"}}});
270}
271
ccalvarin58acb7b2018-03-08 10:53:24 -0800272TEST_F(RcOptionsTest, SimpleImportFoo) {
273 WriteRc("startup_foo.bazelrc",
274 "startup foo");
275 WriteRc("import_simple.bazelrc",
276 "import %workspace%/startup_foo.bazelrc");
277 SuccessfullyParseRcWithExpectedArgs(
278 "import_simple.bazelrc",
279 {{"startup", {"foo"}}});
280}
281
282TEST_F(RcOptionsTest, ImportFooThenAddBar) {
283 WriteRc("startup_foo.bazelrc",
284 "startup foo");
285 WriteRc("import_foo_then_bar.bazelrc",
286 "import %workspace%/startup_foo.bazelrc\n"
287 "startup bar");
288 SuccessfullyParseRcWithExpectedArgs(
289 "import_foo_then_bar.bazelrc",
290 {{"startup", {"foo", "bar"}}});
291}
292
293TEST_F(RcOptionsTest, StartupBarThenImportFoo) {
294 WriteRc("startup_foo.bazelrc",
295 "startup foo");
296 WriteRc("bar_then_import_foo.bazelrc",
297 "startup bar\n"
298 "import %workspace%/startup_foo.bazelrc");
299 SuccessfullyParseRcWithExpectedArgs(
300 "bar_then_import_foo.bazelrc",
301 {{"startup", {"bar", "foo"}}});
302}
303
ccalvarinf03acca2018-09-06 14:25:27 -0700304TEST_F(RcOptionsTest, SimpleTryImportFoo) {
305 WriteRc("startup_foo.bazelrc", "startup foo");
306 WriteRc("import_simple.bazelrc",
307 "try-import %workspace%/startup_foo.bazelrc");
308 SuccessfullyParseRcWithExpectedArgs("import_simple.bazelrc",
309 {{"startup", {"foo"}}});
310}
311
312TEST_F(RcOptionsTest, ImportTryFooThenAddBar) {
313 WriteRc("startup_foo.bazelrc", "startup foo");
314 WriteRc("import_foo_then_bar.bazelrc",
315 "try-import %workspace%/startup_foo.bazelrc\n"
316 "startup bar");
317 SuccessfullyParseRcWithExpectedArgs("import_foo_then_bar.bazelrc",
318 {{"startup", {"foo", "bar"}}});
319}
320
321TEST_F(RcOptionsTest, StartupBarThenTryImportFoo) {
322 WriteRc("startup_foo.bazelrc", "startup foo");
323 WriteRc("bar_then_import_foo.bazelrc",
324 "startup bar\n"
325 "try-import %workspace%/startup_foo.bazelrc");
326 SuccessfullyParseRcWithExpectedArgs("bar_then_import_foo.bazelrc",
327 {{"startup", {"bar", "foo"}}});
328}
329
330// Most likely, import diamonds like this are unintended, and they might lead
331// to surprising doubled values for allow_multiple options. This causes a
332// warning in option_processor, which checks for duplicates across multiple rc
333// files.
ccalvarin58acb7b2018-03-08 10:53:24 -0800334TEST_F(RcOptionsTest, ImportDiamond) {
335 WriteRc("startup_foo.bazelrc",
336 "startup foo");
337 WriteRc("import_foo_then_bar.bazelrc",
338 "import %workspace%/startup_foo.bazelrc\n"
339 "startup bar");
340 WriteRc("bar_then_import_foo.bazelrc",
341 "startup bar\n"
342 "import %workspace%/startup_foo.bazelrc");
343 WriteRc("import_diamond.bazelrc",
344 "import %workspace%/import_foo_then_bar.bazelrc\n"
345 "import %workspace%/bar_then_import_foo.bazelrc");
346 SuccessfullyParseRcWithExpectedArgs(
347 "import_diamond.bazelrc",
348 {{"startup", {"foo", "bar", "bar", "foo"}}});
349}
350
ccalvarin58acb7b2018-03-08 10:53:24 -0800351
352TEST_F(RcOptionsTest, ImportCycleFails) {
353 WriteRc("import_cycle_1.bazelrc",
354 "import %workspace%/import_cycle_2.bazelrc");
355 WriteRc("import_cycle_2.bazelrc",
356 "import %workspace%/import_cycle_1.bazelrc");
357
358 RcFile::ParseError error;
359 string error_text;
360 std::unique_ptr<RcFile> rc =
361 Parse("import_cycle_1.bazelrc", &error, &error_text);
362 EXPECT_EQ(error, RcFile::ParseError::IMPORT_LOOP);
ccalvarin8ceaa652018-08-24 12:44:31 -0700363 ASSERT_THAT(
364 error_text,
365 MatchesRegex("Import loop detected:\n"
366 " .*import_cycle_1.bazelrc\n"
367 " .*import_cycle_2.bazelrc\n"
368 " .*import_cycle_1.bazelrc\n"));
ccalvarin58acb7b2018-03-08 10:53:24 -0800369}
370
371TEST_F(RcOptionsTest, LongImportCycleFails) {
372 WriteRc("chain_to_cycle_1.bazelrc",
373 "import %workspace%/chain_to_cycle_2.bazelrc");
374 WriteRc("chain_to_cycle_2.bazelrc",
375 "import %workspace%/chain_to_cycle_3.bazelrc");
376 WriteRc("chain_to_cycle_3.bazelrc",
377 "import %workspace%/chain_to_cycle_4.bazelrc");
378 WriteRc("chain_to_cycle_4.bazelrc",
379 "import %workspace%/import_cycle_1.bazelrc");
380 WriteRc("import_cycle_1.bazelrc",
381 "import %workspace%/import_cycle_2.bazelrc");
382 WriteRc("import_cycle_2.bazelrc",
383 "import %workspace%/import_cycle_1.bazelrc");
384
385 RcFile::ParseError error;
386 string error_text;
387 std::unique_ptr<RcFile> rc =
388 Parse("chain_to_cycle_1.bazelrc", &error, &error_text);
389 EXPECT_EQ(error, RcFile::ParseError::IMPORT_LOOP);
ccalvarin8ceaa652018-08-24 12:44:31 -0700390 ASSERT_THAT(
391 error_text,
392 MatchesRegex("Import loop detected:\n"
393 " .*chain_to_cycle_1.bazelrc\n"
394 " .*chain_to_cycle_2.bazelrc\n"
395 " .*chain_to_cycle_3.bazelrc\n"
396 " .*chain_to_cycle_4.bazelrc\n"
397 " .*import_cycle_1.bazelrc\n"
398 " .*import_cycle_2.bazelrc\n"
399 " .*import_cycle_1.bazelrc\n"));
ccalvarin58acb7b2018-03-08 10:53:24 -0800400}
401
402TEST_F(RcOptionsTest, FileDoesNotExist) {
403 RcFile::ParseError error;
404 string error_text;
405 std::unique_ptr<RcFile> rc = Parse("not_a_file.bazelrc", &error, &error_text);
406 EXPECT_EQ(error, RcFile::ParseError::UNREADABLE_FILE);
ccalvarin8ceaa652018-08-24 12:44:31 -0700407 ASSERT_THAT(
408 error_text,
bazel.build machine account81fe96a2024-06-19 05:24:24 -0400409 MatchesRegex(kIsWindows ? "Unexpected error reading config file "
410 "'.*not_a_file\\.bazelrc':.*"
411 : "Unexpected error reading config file "
412 "'.*not_a_file\\.bazelrc': "
413 "\\(error: 2\\): No such file or directory"));
ccalvarin58acb7b2018-03-08 10:53:24 -0800414}
415
416TEST_F(RcOptionsTest, ImportedFileDoesNotExist) {
417 WriteRc("import_fake_file.bazelrc",
418 "import somefile");
419
420 RcFile::ParseError error;
421 string error_text;
422 std::unique_ptr<RcFile> rc =
423 Parse("import_fake_file.bazelrc", &error, &error_text);
424 EXPECT_EQ(error, RcFile::ParseError::UNREADABLE_FILE);
Googlerda23fd52022-09-14 15:29:38 -0700425 if (kIsWindows) {
bazel.build machine account81fe96a2024-06-19 05:24:24 -0400426 ASSERT_THAT(
427 error_text,
428 MatchesRegex("Unexpected error reading config file 'somefile':.*"));
Googlerda23fd52022-09-14 15:29:38 -0700429 } else {
bazel.build machine account81fe96a2024-06-19 05:24:24 -0400430 ASSERT_EQ(
431 error_text,
432 "Unexpected error reading config file 'somefile': (error: 2): No such "
433 "file or directory");
Googlerda23fd52022-09-14 15:29:38 -0700434 }
ccalvarin58acb7b2018-03-08 10:53:24 -0800435}
436
ccalvarinf03acca2018-09-06 14:25:27 -0700437TEST_F(RcOptionsTest, TryImportedFileDoesNotExist) {
438 WriteRc("try_import_fake_file.bazelrc", "try-import somefile");
439
440 unordered_map<string, vector<string>> no_expected_args;
441 SuccessfullyParseRcWithExpectedArgs("try_import_fake_file.bazelrc",
442 no_expected_args);
443}
444
ccalvarin58acb7b2018-03-08 10:53:24 -0800445TEST_F(RcOptionsTest, ImportHasTooManyArgs) {
446 WriteRc("bad_import.bazelrc",
447 "import somefile bar");
448
449 RcFile::ParseError error;
450 string error_text;
451 std::unique_ptr<RcFile> rc = Parse("bad_import.bazelrc", &error, &error_text);
452 EXPECT_EQ(error, RcFile::ParseError::INVALID_FORMAT);
ccalvarin8ceaa652018-08-24 12:44:31 -0700453 ASSERT_THAT(
454 error_text,
bazel.build machine account81fe96a2024-06-19 05:24:24 -0400455 MatchesRegex("Invalid import declaration in config file "
ccalvarin8ceaa652018-08-24 12:44:31 -0700456 "'.*bad_import.bazelrc': 'import somefile bar' \\(are you "
457 "in your source checkout/WORKSPACE\\?\\)"));
ccalvarin58acb7b2018-03-08 10:53:24 -0800458}
459
ccalvarinf03acca2018-09-06 14:25:27 -0700460TEST_F(RcOptionsTest, TryImportHasTooManyArgs) {
461 WriteRc("bad_import.bazelrc", "try-import somefile bar");
462
463 RcFile::ParseError error;
464 string error_text;
465 std::unique_ptr<RcFile> rc = Parse("bad_import.bazelrc", &error, &error_text);
466 EXPECT_EQ(error, RcFile::ParseError::INVALID_FORMAT);
467 ASSERT_THAT(
468 error_text,
bazel.build machine account81fe96a2024-06-19 05:24:24 -0400469 MatchesRegex("Invalid import declaration in config file "
ccalvarinf03acca2018-09-06 14:25:27 -0700470 "'.*bad_import.bazelrc': 'try-import somefile bar' \\(are "
471 "you in your source checkout/WORKSPACE\\?\\)"));
472}
473
ccalvarin58acb7b2018-03-08 10:53:24 -0800474// TODO(b/34811299) The tests below identify ways that '\' used as a line
475// continuation is broken. This is on top of user-reported cases where an
476// unintentional '\' made the command on the following line show up as
477// an argument, which lead to cryptic messages. There is no value added by '\',
478// since the following line could just repeat the command, so it might be best
479// to remove this feature entirely.
480//
481// For now, these tests serve as documentation of the brokenness, and to keep
482// broken behavior consistent before we get around to fixing it.
483
484TEST_F(RcOptionsTest, BadStartupLineContinuation_HasWhitespaceAfterSlash) {
485 WriteRc("bad_startup_line_continuation.bazelrc",
486 "startup foo \\ \n"
487 "bar");
488 SuccessfullyParseRcWithExpectedArgs(
489 "bad_startup_line_continuation.bazelrc",
490 {{"startup", {"foo"}}}); // Does not contain "bar" from the next line.
491}
492
493TEST_F(RcOptionsTest, BadStartupLineContinuation_HasErroneousSlash) {
494 WriteRc("bad_startup_line_continuation.bazelrc",
495 "startup foo \\ bar");
496 SuccessfullyParseRcWithExpectedArgs(
497 "bad_startup_line_continuation.bazelrc",
498 // Whitespace between the slash and bar gets counted as part of the token.
499 {{"startup", {"foo", " bar"}}});
500}
501
502TEST_F(RcOptionsTest, BadStartupLineContinuation_HasCommentAfterSlash) {
503 WriteRc("bad_startup_line_continuation.bazelrc",
504 "startup foo \\ # comment\n"
505 "bar");
506 SuccessfullyParseRcWithExpectedArgs(
507 "bad_startup_line_continuation.bazelrc",
508 // Whitespace between the slash and comment gets counted as a new token,
509 // and the bar on the next line is ignored (it's an argumentless command).
510 {{"startup", {"foo", " "}}});
511}
512
513TEST_F(RcOptionsTest, BadStartupLineContinuation_InterpretsNextLineAsNewline) {
514 WriteRc("bad_startup_line_continuation.bazelrc",
515 "startup foo \\ #comment\n"
516 "bar baz");
517 SuccessfullyParseRcWithExpectedArgs(
518 "bad_startup_line_continuation.bazelrc",
519 // Whitespace between the slash and comment gets counted as a new token,
520 // and the bar on the next line treated as its own command, instead of as
521 // a "startup" args.
522 {{"startup", {"foo", " "}}, {"bar", {"baz"}}});
523}
524
525} // namespace blaze
526