1 // Copyright 2011 Google Inc. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #include "manifest_parser.h"
24 struct ParserTest : public testing::Test {
25 void AssertParse(const char* input) {
26 ManifestParser parser(&state, &fs_, kDupeEdgeActionWarn);
28 EXPECT_TRUE(parser.ParseTest(input, &err));
34 VirtualFileSystem fs_;
37 TEST_F(ParserTest, Empty) {
38 ASSERT_NO_FATAL_FAILURE(AssertParse(""));
41 TEST_F(ParserTest, Rules) {
42 ASSERT_NO_FATAL_FAILURE(AssertParse(
44 " command = cat $in > $out\n"
47 " command = date > $out\n"
49 "build result: cat in_1.cc in-2.O\n"));
51 ASSERT_EQ(3u, state.bindings_.GetRules().size());
52 const Rule* rule = state.bindings_.GetRules().begin()->second;
53 EXPECT_EQ("cat", rule->name());
54 EXPECT_EQ("[cat ][$in][ > ][$out]",
55 rule->GetBinding("command")->Serialize());
58 TEST_F(ParserTest, RuleAttributes) {
59 // Check that all of the allowed rule attributes are parsed ok.
60 ASSERT_NO_FATAL_FAILURE(AssertParse(
69 " rspfile_content = a\n"
73 TEST_F(ParserTest, IgnoreIndentedComments) {
74 ASSERT_NO_FATAL_FAILURE(AssertParse(
75 " #indented comment\n"
77 " command = cat $in > $out\n"
79 " restat = 1 # comment\n"
81 "build result: cat in_1.cc in-2.O\n"
84 ASSERT_EQ(2u, state.bindings_.GetRules().size());
85 const Rule* rule = state.bindings_.GetRules().begin()->second;
86 EXPECT_EQ("cat", rule->name());
87 Edge* edge = state.GetNode("result", 0)->in_edge();
88 EXPECT_TRUE(edge->GetBindingBool("restat"));
89 EXPECT_FALSE(edge->GetBindingBool("generator"));
92 TEST_F(ParserTest, IgnoreIndentedBlankLines) {
93 // the indented blanks used to cause parse errors
94 ASSERT_NO_FATAL_FAILURE(AssertParse(
97 " command = cat $in > $out\n"
99 "build result: cat in_1.cc in-2.O\n"
103 // the variable must be in the top level environment
104 EXPECT_EQ("1", state.bindings_.LookupVariable("variable"));
107 TEST_F(ParserTest, ResponseFiles) {
108 ASSERT_NO_FATAL_FAILURE(AssertParse(
110 " command = cat $rspfile > $out\n"
111 " rspfile = $rspfile\n"
112 " rspfile_content = $in\n"
114 "build out: cat_rsp in\n"
115 " rspfile=out.rsp\n"));
117 ASSERT_EQ(2u, state.bindings_.GetRules().size());
118 const Rule* rule = state.bindings_.GetRules().begin()->second;
119 EXPECT_EQ("cat_rsp", rule->name());
120 EXPECT_EQ("[cat ][$rspfile][ > ][$out]",
121 rule->GetBinding("command")->Serialize());
122 EXPECT_EQ("[$rspfile]", rule->GetBinding("rspfile")->Serialize());
123 EXPECT_EQ("[$in]", rule->GetBinding("rspfile_content")->Serialize());
126 TEST_F(ParserTest, InNewline) {
127 ASSERT_NO_FATAL_FAILURE(AssertParse(
129 " command = cat $in_newline > $out\n"
131 "build out: cat_rsp in in2\n"
132 " rspfile=out.rsp\n"));
134 ASSERT_EQ(2u, state.bindings_.GetRules().size());
135 const Rule* rule = state.bindings_.GetRules().begin()->second;
136 EXPECT_EQ("cat_rsp", rule->name());
137 EXPECT_EQ("[cat ][$in_newline][ > ][$out]",
138 rule->GetBinding("command")->Serialize());
140 Edge* edge = state.edges_[0];
141 EXPECT_EQ("cat in\nin2 > out", edge->EvaluateCommand());
144 TEST_F(ParserTest, Variables) {
145 ASSERT_NO_FATAL_FAILURE(AssertParse(
146 "l = one-letter-test\n"
148 " command = ld $l $extra $with_under -o $out $in\n"
151 "with_under = -under\n"
152 "build a: link b c\n"
154 "nested2 = $nested1/2\n"
155 "build supernested: link x\n"
156 " extra = $nested2/3\n"));
158 ASSERT_EQ(2u, state.edges_.size());
159 Edge* edge = state.edges_[0];
160 EXPECT_EQ("ld one-letter-test -pthread -under -o a b c",
161 edge->EvaluateCommand());
162 EXPECT_EQ("1/2", state.bindings_.LookupVariable("nested2"));
164 edge = state.edges_[1];
165 EXPECT_EQ("ld one-letter-test 1/2/3 -under -o supernested x",
166 edge->EvaluateCommand());
169 TEST_F(ParserTest, VariableScope) {
170 ASSERT_NO_FATAL_FAILURE(AssertParse(
173 " command = cmd $foo $in $out\n"
175 "build inner: cmd a\n"
177 "build outer: cmd b\n"
178 "\n" // Extra newline after build line tickles a regression.
181 ASSERT_EQ(2u, state.edges_.size());
182 EXPECT_EQ("cmd baz a inner", state.edges_[0]->EvaluateCommand());
183 EXPECT_EQ("cmd bar b outer", state.edges_[1]->EvaluateCommand());
186 TEST_F(ParserTest, Continuation) {
187 ASSERT_NO_FATAL_FAILURE(AssertParse(
189 " command = foo bar $\n"
192 "build a: link c $\n"
195 ASSERT_EQ(2u, state.bindings_.GetRules().size());
196 const Rule* rule = state.bindings_.GetRules().begin()->second;
197 EXPECT_EQ("link", rule->name());
198 EXPECT_EQ("[foo bar baz]", rule->GetBinding("command")->Serialize());
201 TEST_F(ParserTest, Backslash) {
202 ASSERT_NO_FATAL_FAILURE(AssertParse(
206 EXPECT_EQ("bar\\baz", state.bindings_.LookupVariable("foo"));
207 EXPECT_EQ("bar\\ baz", state.bindings_.LookupVariable("foo2"));
210 TEST_F(ParserTest, Comment) {
211 ASSERT_NO_FATAL_FAILURE(AssertParse(
212 "# this is a comment\n"
213 "foo = not # a comment\n"));
214 EXPECT_EQ("not # a comment", state.bindings_.LookupVariable("foo"));
217 TEST_F(ParserTest, Dollars) {
218 ASSERT_NO_FATAL_FAILURE(AssertParse(
220 " command = ${out}bar$$baz$$$\n"
225 EXPECT_EQ("$dollar", state.bindings_.LookupVariable("x"));
227 EXPECT_EQ("$dollarbar$baz$blah", state.edges_[0]->EvaluateCommand());
229 EXPECT_EQ("'$dollar'bar$baz$blah", state.edges_[0]->EvaluateCommand());
233 TEST_F(ParserTest, EscapeSpaces) {
234 ASSERT_NO_FATAL_FAILURE(AssertParse(
236 " command = something\n"
237 "build foo$ bar: spaces $$one two$$$ three\n"
239 EXPECT_TRUE(state.LookupNode("foo bar"));
240 EXPECT_EQ(state.edges_[0]->outputs_[0]->path(), "foo bar");
241 EXPECT_EQ(state.edges_[0]->inputs_[0]->path(), "$one");
242 EXPECT_EQ(state.edges_[0]->inputs_[1]->path(), "two$ three");
243 EXPECT_EQ(state.edges_[0]->EvaluateCommand(), "something");
246 TEST_F(ParserTest, CanonicalizeFile) {
247 ASSERT_NO_FATAL_FAILURE(AssertParse(
249 " command = cat $in > $out\n"
250 "build out: cat in/1 in//2\n"
252 "build in/2: cat\n"));
254 EXPECT_TRUE(state.LookupNode("in/1"));
255 EXPECT_TRUE(state.LookupNode("in/2"));
256 EXPECT_FALSE(state.LookupNode("in//1"));
257 EXPECT_FALSE(state.LookupNode("in//2"));
261 TEST_F(ParserTest, CanonicalizeFileBackslashes) {
262 ASSERT_NO_FATAL_FAILURE(AssertParse(
264 " command = cat $in > $out\n"
265 "build out: cat in\\1 in\\\\2\n"
267 "build in\\2: cat\n"));
269 Node* node = state.LookupNode("in/1");;
271 EXPECT_EQ(1, node->slash_bits());
272 node = state.LookupNode("in/2");
274 EXPECT_EQ(1, node->slash_bits());
275 EXPECT_FALSE(state.LookupNode("in//1"));
276 EXPECT_FALSE(state.LookupNode("in//2"));
280 TEST_F(ParserTest, PathVariables) {
281 ASSERT_NO_FATAL_FAILURE(AssertParse(
283 " command = cat $in > $out\n"
285 "build $dir/exe: cat src\n"));
287 EXPECT_FALSE(state.LookupNode("$dir/exe"));
288 EXPECT_TRUE(state.LookupNode("out/exe"));
291 TEST_F(ParserTest, CanonicalizePaths) {
292 ASSERT_NO_FATAL_FAILURE(AssertParse(
294 " command = cat $in > $out\n"
295 "build ./out.o: cat ./bar/baz/../foo.cc\n"));
297 EXPECT_FALSE(state.LookupNode("./out.o"));
298 EXPECT_TRUE(state.LookupNode("out.o"));
299 EXPECT_FALSE(state.LookupNode("./bar/baz/../foo.cc"));
300 EXPECT_TRUE(state.LookupNode("bar/foo.cc"));
304 TEST_F(ParserTest, CanonicalizePathsBackslashes) {
305 ASSERT_NO_FATAL_FAILURE(AssertParse(
307 " command = cat $in > $out\n"
308 "build ./out.o: cat ./bar/baz/../foo.cc\n"
309 "build .\\out2.o: cat .\\bar/baz\\..\\foo.cc\n"
310 "build .\\out3.o: cat .\\bar\\baz\\..\\foo3.cc\n"
313 EXPECT_FALSE(state.LookupNode("./out.o"));
314 EXPECT_FALSE(state.LookupNode(".\\out2.o"));
315 EXPECT_FALSE(state.LookupNode(".\\out3.o"));
316 EXPECT_TRUE(state.LookupNode("out.o"));
317 EXPECT_TRUE(state.LookupNode("out2.o"));
318 EXPECT_TRUE(state.LookupNode("out3.o"));
319 EXPECT_FALSE(state.LookupNode("./bar/baz/../foo.cc"));
320 EXPECT_FALSE(state.LookupNode(".\\bar/baz\\..\\foo.cc"));
321 EXPECT_FALSE(state.LookupNode(".\\bar/baz\\..\\foo3.cc"));
322 Node* node = state.LookupNode("bar/foo.cc");
324 EXPECT_EQ(0, node->slash_bits());
325 node = state.LookupNode("bar/foo3.cc");
327 EXPECT_EQ(1, node->slash_bits());
331 TEST_F(ParserTest, DuplicateEdgeWithMultipleOutputs) {
332 ASSERT_NO_FATAL_FAILURE(AssertParse(
334 " command = cat $in > $out\n"
335 "build out1 out2: cat in1\n"
336 "build out1: cat in2\n"
337 "build final: cat out1\n"
339 // AssertParse() checks that the generated build graph is self-consistent.
340 // That's all the checking that this test needs.
343 TEST_F(ParserTest, NoDeadPointerFromDuplicateEdge) {
344 ASSERT_NO_FATAL_FAILURE(AssertParse(
346 " command = cat $in > $out\n"
347 "build out: cat in\n"
348 "build out: cat in\n"
350 // AssertParse() checks that the generated build graph is self-consistent.
351 // That's all the checking that this test needs.
354 TEST_F(ParserTest, DuplicateEdgeWithMultipleOutputsError) {
355 const char kInput[] =
357 " command = cat $in > $out\n"
358 "build out1 out2: cat in1\n"
359 "build out1: cat in2\n"
360 "build final: cat out1\n";
361 ManifestParser parser(&state, &fs_, kDupeEdgeActionError);
363 EXPECT_FALSE(parser.ParseTest(kInput, &err));
364 EXPECT_EQ("input:5: multiple rules generate out1 [-w dupbuild=err]\n", err);
367 TEST_F(ParserTest, DuplicateEdgeInIncludedFile) {
368 fs_.Create("sub.ninja",
370 " command = cat $in > $out\n"
371 "build out1 out2: cat in1\n"
372 "build out1: cat in2\n"
373 "build final: cat out1\n");
374 const char kInput[] =
375 "subninja sub.ninja\n";
376 ManifestParser parser(&state, &fs_, kDupeEdgeActionError);
378 EXPECT_FALSE(parser.ParseTest(kInput, &err));
379 EXPECT_EQ("sub.ninja:5: multiple rules generate out1 [-w dupbuild=err]\n",
383 TEST_F(ParserTest, ReservedWords) {
384 ASSERT_NO_FATAL_FAILURE(AssertParse(
386 " command = rule run $out\n"
387 "build subninja: build include default foo.cc\n"
388 "default subninja\n"));
391 TEST_F(ParserTest, Errors) {
394 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
396 EXPECT_FALSE(parser.ParseTest(string("subn", 4), &err));
397 EXPECT_EQ("input:1: expected '=', got eof\n"
405 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
407 EXPECT_FALSE(parser.ParseTest("foobar", &err));
408 EXPECT_EQ("input:1: expected '=', got eof\n"
416 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
418 EXPECT_FALSE(parser.ParseTest("x 3", &err));
419 EXPECT_EQ("input:1: expected '=', got identifier\n"
427 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
429 EXPECT_FALSE(parser.ParseTest("x = 3", &err));
430 EXPECT_EQ("input:1: unexpected EOF\n"
438 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
440 EXPECT_FALSE(parser.ParseTest("x = 3\ny 2", &err));
441 EXPECT_EQ("input:2: expected '=', got identifier\n"
449 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
451 EXPECT_FALSE(parser.ParseTest("x = $", &err));
452 EXPECT_EQ("input:1: bad $-escape (literal $ must be written as $$)\n"
460 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
462 EXPECT_FALSE(parser.ParseTest("x = $\n $[\n", &err));
463 EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
471 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
473 EXPECT_FALSE(parser.ParseTest("x = a$\n b$\n $\n", &err));
474 EXPECT_EQ("input:4: unexpected EOF\n"
480 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
482 EXPECT_FALSE(parser.ParseTest("build\n", &err));
483 EXPECT_EQ("input:1: expected path\n"
491 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
493 EXPECT_FALSE(parser.ParseTest("build x: y z\n", &err));
494 EXPECT_EQ("input:1: unknown build rule 'y'\n"
502 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
504 EXPECT_FALSE(parser.ParseTest("build x:: y z\n", &err));
505 EXPECT_EQ("input:1: expected build command name\n"
513 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
515 EXPECT_FALSE(parser.ParseTest("rule cat\n command = cat ok\n"
516 "build x: cat $\n :\n",
518 EXPECT_EQ("input:4: expected newline, got ':'\n"
526 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
528 EXPECT_FALSE(parser.ParseTest("rule cat\n",
530 EXPECT_EQ("input:2: expected 'command =' line\n", err);
535 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
537 EXPECT_FALSE(parser.ParseTest("rule cat\n"
540 " command = echo\n", &err));
541 EXPECT_EQ("input:3: duplicate rule 'cat'\n"
549 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
551 EXPECT_FALSE(parser.ParseTest("rule cat\n"
553 " rspfile = cat.rsp\n", &err));
555 "input:4: rspfile and rspfile_content need to be both specified\n",
561 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
563 EXPECT_FALSE(parser.ParseTest("rule cat\n"
564 " command = ${fafsd\n"
567 EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
568 " command = ${fafsd\n"
576 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
578 EXPECT_FALSE(parser.ParseTest("rule cat\n"
580 "build $.: cat foo\n",
582 EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
583 "build $.: cat foo\n"
591 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
593 EXPECT_FALSE(parser.ParseTest("rule cat\n"
595 "build $: cat foo\n",
597 EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
605 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
607 EXPECT_FALSE(parser.ParseTest("rule %foo\n",
609 EXPECT_EQ("input:1: expected rule name\n", err);
614 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
616 EXPECT_FALSE(parser.ParseTest("rule cc\n"
620 EXPECT_EQ("input:3: unexpected variable 'othervar'\n"
628 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
630 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n"
631 "build $.: cc bar.cc\n",
633 EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
634 "build $.: cc bar.cc\n"
641 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
643 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n && bar",
645 EXPECT_EQ("input:3: expected variable name\n", err);
650 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
652 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n"
653 "build $: cc bar.cc\n",
655 EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
656 "build $: cc bar.cc\n"
663 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
665 EXPECT_FALSE(parser.ParseTest("default\n",
667 EXPECT_EQ("input:1: expected target name\n"
675 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
677 EXPECT_FALSE(parser.ParseTest("default nonexistent\n",
679 EXPECT_EQ("input:1: unknown target 'nonexistent'\n"
680 "default nonexistent\n"
687 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
689 EXPECT_FALSE(parser.ParseTest("rule r\n command = r\n"
693 EXPECT_EQ("input:4: expected newline, got ':'\n"
701 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
703 EXPECT_FALSE(parser.ParseTest("default $a\n", &err));
704 EXPECT_EQ("input:1: empty path\n"
712 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
714 EXPECT_FALSE(parser.ParseTest("rule r\n"
716 "build $a: r $c\n", &err));
717 // XXX the line number is wrong; we should evaluate paths in ParseEdge
718 // as we see them, not after we've read them all!
719 EXPECT_EQ("input:4: empty path\n", err);
724 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
726 // the indented blank line must terminate the rule
727 // this also verifies that "unexpected (token)" errors are correct
728 EXPECT_FALSE(parser.ParseTest("rule r\n"
731 " generator = 1\n", &err));
732 EXPECT_EQ("input:4: unexpected indent\n", err);
737 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
739 EXPECT_FALSE(parser.ParseTest("pool\n", &err));
740 EXPECT_EQ("input:1: expected pool name\n", err);
745 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
747 EXPECT_FALSE(parser.ParseTest("pool foo\n", &err));
748 EXPECT_EQ("input:2: expected 'depth =' line\n", err);
753 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
755 EXPECT_FALSE(parser.ParseTest("pool foo\n"
757 "pool foo\n", &err));
758 EXPECT_EQ("input:3: duplicate pool 'foo'\n"
766 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
768 EXPECT_FALSE(parser.ParseTest("pool foo\n"
769 " depth = -1\n", &err));
770 EXPECT_EQ("input:2: invalid pool depth\n"
778 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
780 EXPECT_FALSE(parser.ParseTest("pool foo\n"
781 " bar = 1\n", &err));
782 EXPECT_EQ("input:2: unexpected variable 'bar'\n"
790 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
792 // Pool names are dereferenced at edge parsing time.
793 EXPECT_FALSE(parser.ParseTest("rule run\n"
795 " pool = unnamed_pool\n"
796 "build out: run in\n", &err));
797 EXPECT_EQ("input:5: unknown pool name 'unnamed_pool'\n", err);
801 TEST_F(ParserTest, MissingInput) {
803 ManifestParser parser(&local_state, &fs_, kDupeEdgeActionWarn);
805 EXPECT_FALSE(parser.Load("build.ninja", &err));
806 EXPECT_EQ("loading 'build.ninja': No such file or directory", err);
809 TEST_F(ParserTest, MultipleOutputs) {
811 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
813 EXPECT_TRUE(parser.ParseTest("rule cc\n command = foo\n depfile = bar\n"
814 "build a.o b.o: cc c.cc\n",
819 TEST_F(ParserTest, MultipleOutputsWithDeps) {
821 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
823 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n deps = gcc\n"
824 "build a.o b.o: cc c.cc\n",
826 EXPECT_EQ("input:5: multiple outputs aren't (yet?) supported by depslog; "
827 "bring this up on the mailing list if it affects you\n", err);
830 TEST_F(ParserTest, SubNinja) {
831 fs_.Create("test.ninja",
833 "build $builddir/inner: varref\n");
834 ASSERT_NO_FATAL_FAILURE(AssertParse(
835 "builddir = some_dir/\n"
837 " command = varref $var\n"
839 "build $builddir/outer: varref\n"
840 "subninja test.ninja\n"
841 "build $builddir/outer2: varref\n"));
842 ASSERT_EQ(1u, fs_.files_read_.size());
844 EXPECT_EQ("test.ninja", fs_.files_read_[0]);
845 EXPECT_TRUE(state.LookupNode("some_dir/outer"));
846 // Verify our builddir setting is inherited.
847 EXPECT_TRUE(state.LookupNode("some_dir/inner"));
849 ASSERT_EQ(3u, state.edges_.size());
850 EXPECT_EQ("varref outer", state.edges_[0]->EvaluateCommand());
851 EXPECT_EQ("varref inner", state.edges_[1]->EvaluateCommand());
852 EXPECT_EQ("varref outer", state.edges_[2]->EvaluateCommand());
855 TEST_F(ParserTest, MissingSubNinja) {
856 ManifestParser parser(&state, &fs_, kDupeEdgeActionWarn);
858 EXPECT_FALSE(parser.ParseTest("subninja foo.ninja\n", &err));
859 EXPECT_EQ("input:1: loading 'foo.ninja': No such file or directory\n"
860 "subninja foo.ninja\n"
865 TEST_F(ParserTest, DuplicateRuleInDifferentSubninjas) {
866 // Test that rules are scoped to subninjas.
867 fs_.Create("test.ninja", "rule cat\n"
869 ManifestParser parser(&state, &fs_, kDupeEdgeActionWarn);
871 EXPECT_TRUE(parser.ParseTest("rule cat\n"
873 "subninja test.ninja\n", &err));
876 TEST_F(ParserTest, DuplicateRuleInDifferentSubninjasWithInclude) {
877 // Test that rules are scoped to subninjas even with includes.
878 fs_.Create("rules.ninja", "rule cat\n"
880 fs_.Create("test.ninja", "include rules.ninja\n"
882 ManifestParser parser(&state, &fs_, kDupeEdgeActionWarn);
884 EXPECT_TRUE(parser.ParseTest("include rules.ninja\n"
885 "subninja test.ninja\n"
886 "build y : cat\n", &err));
889 TEST_F(ParserTest, Include) {
890 fs_.Create("include.ninja", "var = inner\n");
891 ASSERT_NO_FATAL_FAILURE(AssertParse(
893 "include include.ninja\n"));
895 ASSERT_EQ(1u, fs_.files_read_.size());
896 EXPECT_EQ("include.ninja", fs_.files_read_[0]);
897 EXPECT_EQ("inner", state.bindings_.LookupVariable("var"));
900 TEST_F(ParserTest, BrokenInclude) {
901 fs_.Create("include.ninja", "build\n");
902 ManifestParser parser(&state, &fs_, kDupeEdgeActionWarn);
904 EXPECT_FALSE(parser.ParseTest("include include.ninja\n", &err));
905 EXPECT_EQ("include.ninja:1: expected path\n"
911 TEST_F(ParserTest, Implicit) {
912 ASSERT_NO_FATAL_FAILURE(AssertParse(
914 " command = cat $in > $out\n"
915 "build foo: cat bar | baz\n"));
917 Edge* edge = state.LookupNode("foo")->in_edge();
918 ASSERT_TRUE(edge->is_implicit(1));
921 TEST_F(ParserTest, OrderOnly) {
922 ASSERT_NO_FATAL_FAILURE(AssertParse(
923 "rule cat\n command = cat $in > $out\n"
924 "build foo: cat bar || baz\n"));
926 Edge* edge = state.LookupNode("foo")->in_edge();
927 ASSERT_TRUE(edge->is_order_only(1));
930 TEST_F(ParserTest, ImplicitOutput) {
931 ASSERT_NO_FATAL_FAILURE(AssertParse(
933 " command = cat $in > $out\n"
934 "build foo | imp: cat bar\n"));
936 Edge* edge = state.LookupNode("imp")->in_edge();
937 ASSERT_EQ(edge->outputs_.size(), 2);
938 EXPECT_TRUE(edge->is_implicit_out(1));
941 TEST_F(ParserTest, ImplicitOutputEmpty) {
942 ASSERT_NO_FATAL_FAILURE(AssertParse(
944 " command = cat $in > $out\n"
945 "build foo | : cat bar\n"));
947 Edge* edge = state.LookupNode("foo")->in_edge();
948 ASSERT_EQ(edge->outputs_.size(), 1);
949 EXPECT_FALSE(edge->is_implicit_out(0));
952 TEST_F(ParserTest, ImplicitOutputDupe) {
953 ASSERT_NO_FATAL_FAILURE(AssertParse(
955 " command = cat $in > $out\n"
956 "build foo baz | foo baq foo: cat bar\n"));
958 Edge* edge = state.LookupNode("foo")->in_edge();
959 ASSERT_EQ(edge->outputs_.size(), 3);
960 EXPECT_FALSE(edge->is_implicit_out(0));
961 EXPECT_FALSE(edge->is_implicit_out(1));
962 EXPECT_TRUE(edge->is_implicit_out(2));
965 TEST_F(ParserTest, ImplicitOutputDupes) {
966 ASSERT_NO_FATAL_FAILURE(AssertParse(
968 " command = cat $in > $out\n"
969 "build foo foo foo | foo foo foo foo: cat bar\n"));
971 Edge* edge = state.LookupNode("foo")->in_edge();
972 ASSERT_EQ(edge->outputs_.size(), 1);
973 EXPECT_FALSE(edge->is_implicit_out(0));
976 TEST_F(ParserTest, NoExplicitOutput) {
977 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
979 EXPECT_TRUE(parser.ParseTest(
981 " command = cat $in > $out\n"
982 "build | imp : cat bar\n", &err));
985 TEST_F(ParserTest, DefaultDefault) {
986 ASSERT_NO_FATAL_FAILURE(AssertParse(
987 "rule cat\n command = cat $in > $out\n"
991 "build d: cat foo\n"));
994 EXPECT_EQ(4u, state.DefaultNodes(&err).size());
998 TEST_F(ParserTest, DefaultDefaultCycle) {
999 ASSERT_NO_FATAL_FAILURE(AssertParse(
1000 "rule cat\n command = cat $in > $out\n"
1001 "build a: cat a\n"));
1004 EXPECT_EQ(0u, state.DefaultNodes(&err).size());
1005 EXPECT_EQ("could not determine root nodes of build graph", err);
1008 TEST_F(ParserTest, DefaultStatements) {
1009 ASSERT_NO_FATAL_FAILURE(AssertParse(
1010 "rule cat\n command = cat $in > $out\n"
1011 "build a: cat foo\n"
1012 "build b: cat foo\n"
1013 "build c: cat foo\n"
1014 "build d: cat foo\n"
1017 "default $third\n"));
1020 vector<Node*> nodes = state.DefaultNodes(&err);
1022 ASSERT_EQ(3u, nodes.size());
1023 EXPECT_EQ("a", nodes[0]->path());
1024 EXPECT_EQ("b", nodes[1]->path());
1025 EXPECT_EQ("c", nodes[2]->path());
1028 TEST_F(ParserTest, UTF8) {
1029 ASSERT_NO_FATAL_FAILURE(AssertParse(
1032 " description = compilaci\xC3\xB3\n"));
1035 TEST_F(ParserTest, CRLF) {
1037 ManifestParser parser(&local_state, NULL, kDupeEdgeActionWarn);
1040 EXPECT_TRUE(parser.ParseTest("# comment with crlf\r\n", &err));
1041 EXPECT_TRUE(parser.ParseTest("foo = foo\nbar = bar\r\n", &err));
1042 EXPECT_TRUE(parser.ParseTest(
1043 "pool link_pool\r\n"
1044 " depth = 15\r\n\r\n"
1046 " command = something$expand \r\n"
1047 " description = YAY!\r\n",