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 public ManifestParser::FileReader {
26 void AssertParse(const char* input) {
27 ManifestParser parser(&state, this, kDupeEdgeActionWarn);
29 EXPECT_TRUE(parser.ParseTest(input, &err));
34 virtual bool ReadFile(const string& path, string* content, string* err) {
35 files_read_.push_back(path);
36 map<string, string>::iterator i = files_.find(path);
37 if (i == files_.end()) {
38 *err = "No such file or directory"; // Match strerror() for ENOENT.
46 map<string, string> files_;
47 vector<string> files_read_;
50 TEST_F(ParserTest, Empty) {
51 ASSERT_NO_FATAL_FAILURE(AssertParse(""));
54 TEST_F(ParserTest, Rules) {
55 ASSERT_NO_FATAL_FAILURE(AssertParse(
57 " command = cat $in > $out\n"
60 " command = date > $out\n"
62 "build result: cat in_1.cc in-2.O\n"));
64 ASSERT_EQ(3u, state.bindings_.GetRules().size());
65 const Rule* rule = state.bindings_.GetRules().begin()->second;
66 EXPECT_EQ("cat", rule->name());
67 EXPECT_EQ("[cat ][$in][ > ][$out]",
68 rule->GetBinding("command")->Serialize());
71 TEST_F(ParserTest, RuleAttributes) {
72 // Check that all of the allowed rule attributes are parsed ok.
73 ASSERT_NO_FATAL_FAILURE(AssertParse(
82 " rspfile_content = a\n"
86 TEST_F(ParserTest, IgnoreIndentedComments) {
87 ASSERT_NO_FATAL_FAILURE(AssertParse(
88 " #indented comment\n"
90 " command = cat $in > $out\n"
92 " restat = 1 # comment\n"
94 "build result: cat in_1.cc in-2.O\n"
97 ASSERT_EQ(2u, state.bindings_.GetRules().size());
98 const Rule* rule = state.bindings_.GetRules().begin()->second;
99 EXPECT_EQ("cat", rule->name());
100 Edge* edge = state.GetNode("result", 0)->in_edge();
101 EXPECT_TRUE(edge->GetBindingBool("restat"));
102 EXPECT_FALSE(edge->GetBindingBool("generator"));
105 TEST_F(ParserTest, IgnoreIndentedBlankLines) {
106 // the indented blanks used to cause parse errors
107 ASSERT_NO_FATAL_FAILURE(AssertParse(
110 " command = cat $in > $out\n"
112 "build result: cat in_1.cc in-2.O\n"
116 // the variable must be in the top level environment
117 EXPECT_EQ("1", state.bindings_.LookupVariable("variable"));
120 TEST_F(ParserTest, ResponseFiles) {
121 ASSERT_NO_FATAL_FAILURE(AssertParse(
123 " command = cat $rspfile > $out\n"
124 " rspfile = $rspfile\n"
125 " rspfile_content = $in\n"
127 "build out: cat_rsp in\n"
128 " rspfile=out.rsp\n"));
130 ASSERT_EQ(2u, state.bindings_.GetRules().size());
131 const Rule* rule = state.bindings_.GetRules().begin()->second;
132 EXPECT_EQ("cat_rsp", rule->name());
133 EXPECT_EQ("[cat ][$rspfile][ > ][$out]",
134 rule->GetBinding("command")->Serialize());
135 EXPECT_EQ("[$rspfile]", rule->GetBinding("rspfile")->Serialize());
136 EXPECT_EQ("[$in]", rule->GetBinding("rspfile_content")->Serialize());
139 TEST_F(ParserTest, InNewline) {
140 ASSERT_NO_FATAL_FAILURE(AssertParse(
142 " command = cat $in_newline > $out\n"
144 "build out: cat_rsp in in2\n"
145 " rspfile=out.rsp\n"));
147 ASSERT_EQ(2u, state.bindings_.GetRules().size());
148 const Rule* rule = state.bindings_.GetRules().begin()->second;
149 EXPECT_EQ("cat_rsp", rule->name());
150 EXPECT_EQ("[cat ][$in_newline][ > ][$out]",
151 rule->GetBinding("command")->Serialize());
153 Edge* edge = state.edges_[0];
154 EXPECT_EQ("cat in\nin2 > out", edge->EvaluateCommand());
157 TEST_F(ParserTest, Variables) {
158 ASSERT_NO_FATAL_FAILURE(AssertParse(
159 "l = one-letter-test\n"
161 " command = ld $l $extra $with_under -o $out $in\n"
164 "with_under = -under\n"
165 "build a: link b c\n"
167 "nested2 = $nested1/2\n"
168 "build supernested: link x\n"
169 " extra = $nested2/3\n"));
171 ASSERT_EQ(2u, state.edges_.size());
172 Edge* edge = state.edges_[0];
173 EXPECT_EQ("ld one-letter-test -pthread -under -o a b c",
174 edge->EvaluateCommand());
175 EXPECT_EQ("1/2", state.bindings_.LookupVariable("nested2"));
177 edge = state.edges_[1];
178 EXPECT_EQ("ld one-letter-test 1/2/3 -under -o supernested x",
179 edge->EvaluateCommand());
182 TEST_F(ParserTest, VariableScope) {
183 ASSERT_NO_FATAL_FAILURE(AssertParse(
186 " command = cmd $foo $in $out\n"
188 "build inner: cmd a\n"
190 "build outer: cmd b\n"
191 "\n" // Extra newline after build line tickles a regression.
194 ASSERT_EQ(2u, state.edges_.size());
195 EXPECT_EQ("cmd baz a inner", state.edges_[0]->EvaluateCommand());
196 EXPECT_EQ("cmd bar b outer", state.edges_[1]->EvaluateCommand());
199 TEST_F(ParserTest, Continuation) {
200 ASSERT_NO_FATAL_FAILURE(AssertParse(
202 " command = foo bar $\n"
205 "build a: link c $\n"
208 ASSERT_EQ(2u, state.bindings_.GetRules().size());
209 const Rule* rule = state.bindings_.GetRules().begin()->second;
210 EXPECT_EQ("link", rule->name());
211 EXPECT_EQ("[foo bar baz]", rule->GetBinding("command")->Serialize());
214 TEST_F(ParserTest, Backslash) {
215 ASSERT_NO_FATAL_FAILURE(AssertParse(
219 EXPECT_EQ("bar\\baz", state.bindings_.LookupVariable("foo"));
220 EXPECT_EQ("bar\\ baz", state.bindings_.LookupVariable("foo2"));
223 TEST_F(ParserTest, Comment) {
224 ASSERT_NO_FATAL_FAILURE(AssertParse(
225 "# this is a comment\n"
226 "foo = not # a comment\n"));
227 EXPECT_EQ("not # a comment", state.bindings_.LookupVariable("foo"));
230 TEST_F(ParserTest, Dollars) {
231 ASSERT_NO_FATAL_FAILURE(AssertParse(
233 " command = ${out}bar$$baz$$$\n"
238 EXPECT_EQ("$dollar", state.bindings_.LookupVariable("x"));
240 EXPECT_EQ("$dollarbar$baz$blah", state.edges_[0]->EvaluateCommand());
242 EXPECT_EQ("'$dollar'bar$baz$blah", state.edges_[0]->EvaluateCommand());
246 TEST_F(ParserTest, EscapeSpaces) {
247 ASSERT_NO_FATAL_FAILURE(AssertParse(
249 " command = something\n"
250 "build foo$ bar: spaces $$one two$$$ three\n"
252 EXPECT_TRUE(state.LookupNode("foo bar"));
253 EXPECT_EQ(state.edges_[0]->outputs_[0]->path(), "foo bar");
254 EXPECT_EQ(state.edges_[0]->inputs_[0]->path(), "$one");
255 EXPECT_EQ(state.edges_[0]->inputs_[1]->path(), "two$ three");
256 EXPECT_EQ(state.edges_[0]->EvaluateCommand(), "something");
259 TEST_F(ParserTest, CanonicalizeFile) {
260 ASSERT_NO_FATAL_FAILURE(AssertParse(
262 " command = cat $in > $out\n"
263 "build out: cat in/1 in//2\n"
265 "build in/2: cat\n"));
267 EXPECT_TRUE(state.LookupNode("in/1"));
268 EXPECT_TRUE(state.LookupNode("in/2"));
269 EXPECT_FALSE(state.LookupNode("in//1"));
270 EXPECT_FALSE(state.LookupNode("in//2"));
274 TEST_F(ParserTest, CanonicalizeFileBackslashes) {
275 ASSERT_NO_FATAL_FAILURE(AssertParse(
277 " command = cat $in > $out\n"
278 "build out: cat in\\1 in\\\\2\n"
280 "build in\\2: cat\n"));
282 Node* node = state.LookupNode("in/1");;
284 EXPECT_EQ(1, node->slash_bits());
285 node = state.LookupNode("in/2");
287 EXPECT_EQ(1, node->slash_bits());
288 EXPECT_FALSE(state.LookupNode("in//1"));
289 EXPECT_FALSE(state.LookupNode("in//2"));
293 TEST_F(ParserTest, PathVariables) {
294 ASSERT_NO_FATAL_FAILURE(AssertParse(
296 " command = cat $in > $out\n"
298 "build $dir/exe: cat src\n"));
300 EXPECT_FALSE(state.LookupNode("$dir/exe"));
301 EXPECT_TRUE(state.LookupNode("out/exe"));
304 TEST_F(ParserTest, CanonicalizePaths) {
305 ASSERT_NO_FATAL_FAILURE(AssertParse(
307 " command = cat $in > $out\n"
308 "build ./out.o: cat ./bar/baz/../foo.cc\n"));
310 EXPECT_FALSE(state.LookupNode("./out.o"));
311 EXPECT_TRUE(state.LookupNode("out.o"));
312 EXPECT_FALSE(state.LookupNode("./bar/baz/../foo.cc"));
313 EXPECT_TRUE(state.LookupNode("bar/foo.cc"));
317 TEST_F(ParserTest, CanonicalizePathsBackslashes) {
318 ASSERT_NO_FATAL_FAILURE(AssertParse(
320 " command = cat $in > $out\n"
321 "build ./out.o: cat ./bar/baz/../foo.cc\n"
322 "build .\\out2.o: cat .\\bar/baz\\..\\foo.cc\n"
323 "build .\\out3.o: cat .\\bar\\baz\\..\\foo3.cc\n"
326 EXPECT_FALSE(state.LookupNode("./out.o"));
327 EXPECT_FALSE(state.LookupNode(".\\out2.o"));
328 EXPECT_FALSE(state.LookupNode(".\\out3.o"));
329 EXPECT_TRUE(state.LookupNode("out.o"));
330 EXPECT_TRUE(state.LookupNode("out2.o"));
331 EXPECT_TRUE(state.LookupNode("out3.o"));
332 EXPECT_FALSE(state.LookupNode("./bar/baz/../foo.cc"));
333 EXPECT_FALSE(state.LookupNode(".\\bar/baz\\..\\foo.cc"));
334 EXPECT_FALSE(state.LookupNode(".\\bar/baz\\..\\foo3.cc"));
335 Node* node = state.LookupNode("bar/foo.cc");
337 EXPECT_EQ(0, node->slash_bits());
338 node = state.LookupNode("bar/foo3.cc");
340 EXPECT_EQ(1, node->slash_bits());
344 TEST_F(ParserTest, DuplicateEdgeWithMultipleOutputs) {
345 ASSERT_NO_FATAL_FAILURE(AssertParse(
347 " command = cat $in > $out\n"
348 "build out1 out2: cat in1\n"
349 "build out1: cat in2\n"
350 "build final: cat out1\n"
352 // AssertParse() checks that the generated build graph is self-consistent.
353 // That's all the checking that this test needs.
356 TEST_F(ParserTest, NoDeadPointerFromDuplicateEdge) {
357 ASSERT_NO_FATAL_FAILURE(AssertParse(
359 " command = cat $in > $out\n"
360 "build out: cat in\n"
361 "build out: cat in\n"
363 // AssertParse() checks that the generated build graph is self-consistent.
364 // That's all the checking that this test needs.
367 TEST_F(ParserTest, DuplicateEdgeWithMultipleOutputsError) {
368 const char kInput[] =
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 ManifestParser parser(&state, this, kDupeEdgeActionError);
376 EXPECT_FALSE(parser.ParseTest(kInput, &err));
377 EXPECT_EQ("input:5: multiple rules generate out1 [-w dupbuild=err]\n", err);
380 TEST_F(ParserTest, DuplicateEdgeInIncludedFile) {
381 files_["sub.ninja"] =
383 " command = cat $in > $out\n"
384 "build out1 out2: cat in1\n"
385 "build out1: cat in2\n"
386 "build final: cat out1\n";
387 const char kInput[] =
388 "subninja sub.ninja\n";
389 ManifestParser parser(&state, this, kDupeEdgeActionError);
391 EXPECT_FALSE(parser.ParseTest(kInput, &err));
392 EXPECT_EQ("sub.ninja:5: multiple rules generate out1 [-w dupbuild=err]\n",
396 TEST_F(ParserTest, ReservedWords) {
397 ASSERT_NO_FATAL_FAILURE(AssertParse(
399 " command = rule run $out\n"
400 "build subninja: build include default foo.cc\n"
401 "default subninja\n"));
404 TEST_F(ParserTest, Errors) {
407 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
409 EXPECT_FALSE(parser.ParseTest(string("subn", 4), &err));
410 EXPECT_EQ("input:1: expected '=', got eof\n"
418 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
420 EXPECT_FALSE(parser.ParseTest("foobar", &err));
421 EXPECT_EQ("input:1: expected '=', got eof\n"
429 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
431 EXPECT_FALSE(parser.ParseTest("x 3", &err));
432 EXPECT_EQ("input:1: expected '=', got identifier\n"
440 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
442 EXPECT_FALSE(parser.ParseTest("x = 3", &err));
443 EXPECT_EQ("input:1: unexpected EOF\n"
451 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
453 EXPECT_FALSE(parser.ParseTest("x = 3\ny 2", &err));
454 EXPECT_EQ("input:2: expected '=', got identifier\n"
462 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
464 EXPECT_FALSE(parser.ParseTest("x = $", &err));
465 EXPECT_EQ("input:1: bad $-escape (literal $ must be written as $$)\n"
473 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
475 EXPECT_FALSE(parser.ParseTest("x = $\n $[\n", &err));
476 EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
484 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
486 EXPECT_FALSE(parser.ParseTest("x = a$\n b$\n $\n", &err));
487 EXPECT_EQ("input:4: unexpected EOF\n"
493 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
495 EXPECT_FALSE(parser.ParseTest("build\n", &err));
496 EXPECT_EQ("input:1: expected path\n"
504 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
506 EXPECT_FALSE(parser.ParseTest("build x: y z\n", &err));
507 EXPECT_EQ("input:1: unknown build rule 'y'\n"
515 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
517 EXPECT_FALSE(parser.ParseTest("build x:: y z\n", &err));
518 EXPECT_EQ("input:1: expected build command name\n"
526 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
528 EXPECT_FALSE(parser.ParseTest("rule cat\n command = cat ok\n"
529 "build x: cat $\n :\n",
531 EXPECT_EQ("input:4: expected newline, got ':'\n"
539 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
541 EXPECT_FALSE(parser.ParseTest("rule cat\n",
543 EXPECT_EQ("input:2: expected 'command =' line\n", err);
548 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
550 EXPECT_FALSE(parser.ParseTest("rule cat\n"
553 " command = echo\n", &err));
554 EXPECT_EQ("input:3: duplicate rule 'cat'\n"
562 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
564 EXPECT_FALSE(parser.ParseTest("rule cat\n"
566 " rspfile = cat.rsp\n", &err));
568 "input:4: rspfile and rspfile_content need to be both specified\n",
574 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
576 EXPECT_FALSE(parser.ParseTest("rule cat\n"
577 " command = ${fafsd\n"
580 EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
581 " command = ${fafsd\n"
589 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
591 EXPECT_FALSE(parser.ParseTest("rule cat\n"
593 "build $.: cat foo\n",
595 EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
596 "build $.: cat foo\n"
604 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
606 EXPECT_FALSE(parser.ParseTest("rule cat\n"
608 "build $: cat foo\n",
610 EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
618 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
620 EXPECT_FALSE(parser.ParseTest("rule %foo\n",
622 EXPECT_EQ("input:1: expected rule name\n", err);
627 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
629 EXPECT_FALSE(parser.ParseTest("rule cc\n"
633 EXPECT_EQ("input:3: unexpected variable 'othervar'\n"
641 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
643 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n"
644 "build $.: cc bar.cc\n",
646 EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
647 "build $.: cc bar.cc\n"
654 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
656 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n && bar",
658 EXPECT_EQ("input:3: expected variable name\n", err);
663 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
665 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n"
666 "build $: cc bar.cc\n",
668 EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
669 "build $: cc bar.cc\n"
676 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
678 EXPECT_FALSE(parser.ParseTest("default\n",
680 EXPECT_EQ("input:1: expected target name\n"
688 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
690 EXPECT_FALSE(parser.ParseTest("default nonexistent\n",
692 EXPECT_EQ("input:1: unknown target 'nonexistent'\n"
693 "default nonexistent\n"
700 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
702 EXPECT_FALSE(parser.ParseTest("rule r\n command = r\n"
706 EXPECT_EQ("input:4: expected newline, got ':'\n"
714 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
716 EXPECT_FALSE(parser.ParseTest("default $a\n", &err));
717 EXPECT_EQ("input:1: empty path\n"
725 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
727 EXPECT_FALSE(parser.ParseTest("rule r\n"
729 "build $a: r $c\n", &err));
730 // XXX the line number is wrong; we should evaluate paths in ParseEdge
731 // as we see them, not after we've read them all!
732 EXPECT_EQ("input:4: empty path\n", err);
737 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
739 // the indented blank line must terminate the rule
740 // this also verifies that "unexpected (token)" errors are correct
741 EXPECT_FALSE(parser.ParseTest("rule r\n"
744 " generator = 1\n", &err));
745 EXPECT_EQ("input:4: unexpected indent\n", err);
750 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
752 EXPECT_FALSE(parser.ParseTest("pool\n", &err));
753 EXPECT_EQ("input:1: expected pool name\n", err);
758 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
760 EXPECT_FALSE(parser.ParseTest("pool foo\n", &err));
761 EXPECT_EQ("input:2: expected 'depth =' line\n", err);
766 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
768 EXPECT_FALSE(parser.ParseTest("pool foo\n"
770 "pool foo\n", &err));
771 EXPECT_EQ("input:3: duplicate pool 'foo'\n"
779 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
781 EXPECT_FALSE(parser.ParseTest("pool foo\n"
782 " depth = -1\n", &err));
783 EXPECT_EQ("input:2: invalid pool depth\n"
791 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
793 EXPECT_FALSE(parser.ParseTest("pool foo\n"
794 " bar = 1\n", &err));
795 EXPECT_EQ("input:2: unexpected variable 'bar'\n"
803 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
805 // Pool names are dereferenced at edge parsing time.
806 EXPECT_FALSE(parser.ParseTest("rule run\n"
808 " pool = unnamed_pool\n"
809 "build out: run in\n", &err));
810 EXPECT_EQ("input:5: unknown pool name 'unnamed_pool'\n", err);
814 TEST_F(ParserTest, MissingInput) {
816 ManifestParser parser(&state, this, kDupeEdgeActionWarn);
818 EXPECT_FALSE(parser.Load("build.ninja", &err));
819 EXPECT_EQ("loading 'build.ninja': No such file or directory", err);
822 TEST_F(ParserTest, MultipleOutputs) {
824 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
826 EXPECT_TRUE(parser.ParseTest("rule cc\n command = foo\n depfile = bar\n"
827 "build a.o b.o: cc c.cc\n",
832 TEST_F(ParserTest, MultipleOutputsWithDeps) {
834 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
836 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n deps = gcc\n"
837 "build a.o b.o: cc c.cc\n",
839 EXPECT_EQ("input:5: multiple outputs aren't (yet?) supported by depslog; "
840 "bring this up on the mailing list if it affects you\n", err);
843 TEST_F(ParserTest, SubNinja) {
844 files_["test.ninja"] =
846 "build $builddir/inner: varref\n";
847 ASSERT_NO_FATAL_FAILURE(AssertParse(
848 "builddir = some_dir/\n"
850 " command = varref $var\n"
852 "build $builddir/outer: varref\n"
853 "subninja test.ninja\n"
854 "build $builddir/outer2: varref\n"));
855 ASSERT_EQ(1u, files_read_.size());
857 EXPECT_EQ("test.ninja", files_read_[0]);
858 EXPECT_TRUE(state.LookupNode("some_dir/outer"));
859 // Verify our builddir setting is inherited.
860 EXPECT_TRUE(state.LookupNode("some_dir/inner"));
862 ASSERT_EQ(3u, state.edges_.size());
863 EXPECT_EQ("varref outer", state.edges_[0]->EvaluateCommand());
864 EXPECT_EQ("varref inner", state.edges_[1]->EvaluateCommand());
865 EXPECT_EQ("varref outer", state.edges_[2]->EvaluateCommand());
868 TEST_F(ParserTest, MissingSubNinja) {
869 ManifestParser parser(&state, this, kDupeEdgeActionWarn);
871 EXPECT_FALSE(parser.ParseTest("subninja foo.ninja\n", &err));
872 EXPECT_EQ("input:1: loading 'foo.ninja': No such file or directory\n"
873 "subninja foo.ninja\n"
878 TEST_F(ParserTest, DuplicateRuleInDifferentSubninjas) {
879 // Test that rules are scoped to subninjas.
880 files_["test.ninja"] = "rule cat\n"
882 ManifestParser parser(&state, this, kDupeEdgeActionWarn);
884 EXPECT_TRUE(parser.ParseTest("rule cat\n"
886 "subninja test.ninja\n", &err));
889 TEST_F(ParserTest, DuplicateRuleInDifferentSubninjasWithInclude) {
890 // Test that rules are scoped to subninjas even with includes.
891 files_["rules.ninja"] = "rule cat\n"
893 files_["test.ninja"] = "include rules.ninja\n"
895 ManifestParser parser(&state, this, kDupeEdgeActionWarn);
897 EXPECT_TRUE(parser.ParseTest("include rules.ninja\n"
898 "subninja test.ninja\n"
899 "build y : cat\n", &err));
902 TEST_F(ParserTest, Include) {
903 files_["include.ninja"] = "var = inner\n";
904 ASSERT_NO_FATAL_FAILURE(AssertParse(
906 "include include.ninja\n"));
908 ASSERT_EQ(1u, files_read_.size());
909 EXPECT_EQ("include.ninja", files_read_[0]);
910 EXPECT_EQ("inner", state.bindings_.LookupVariable("var"));
913 TEST_F(ParserTest, BrokenInclude) {
914 files_["include.ninja"] = "build\n";
915 ManifestParser parser(&state, this, kDupeEdgeActionWarn);
917 EXPECT_FALSE(parser.ParseTest("include include.ninja\n", &err));
918 EXPECT_EQ("include.ninja:1: expected path\n"
924 TEST_F(ParserTest, Implicit) {
925 ASSERT_NO_FATAL_FAILURE(AssertParse(
927 " command = cat $in > $out\n"
928 "build foo: cat bar | baz\n"));
930 Edge* edge = state.LookupNode("foo")->in_edge();
931 ASSERT_TRUE(edge->is_implicit(1));
934 TEST_F(ParserTest, OrderOnly) {
935 ASSERT_NO_FATAL_FAILURE(AssertParse(
936 "rule cat\n command = cat $in > $out\n"
937 "build foo: cat bar || baz\n"));
939 Edge* edge = state.LookupNode("foo")->in_edge();
940 ASSERT_TRUE(edge->is_order_only(1));
943 TEST_F(ParserTest, ImplicitOutput) {
944 ASSERT_NO_FATAL_FAILURE(AssertParse(
946 " command = cat $in > $out\n"
947 "build foo | imp: cat bar\n"));
949 Edge* edge = state.LookupNode("imp")->in_edge();
950 ASSERT_EQ(edge->outputs_.size(), 2);
951 EXPECT_TRUE(edge->is_implicit_out(1));
954 TEST_F(ParserTest, ImplicitOutputEmpty) {
955 ASSERT_NO_FATAL_FAILURE(AssertParse(
957 " command = cat $in > $out\n"
958 "build foo | : cat bar\n"));
960 Edge* edge = state.LookupNode("foo")->in_edge();
961 ASSERT_EQ(edge->outputs_.size(), 1);
962 EXPECT_FALSE(edge->is_implicit_out(0));
965 TEST_F(ParserTest, NoExplicitOutput) {
966 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
968 EXPECT_FALSE(parser.ParseTest(
970 " command = cat $in > $out\n"
971 "build | imp : cat bar\n", &err));
972 ASSERT_EQ("input:3: expected path\n"
973 "build | imp : cat bar\n"
974 " ^ near here", err);
977 TEST_F(ParserTest, DefaultDefault) {
978 ASSERT_NO_FATAL_FAILURE(AssertParse(
979 "rule cat\n command = cat $in > $out\n"
983 "build d: cat foo\n"));
986 EXPECT_EQ(4u, state.DefaultNodes(&err).size());
990 TEST_F(ParserTest, DefaultDefaultCycle) {
991 ASSERT_NO_FATAL_FAILURE(AssertParse(
992 "rule cat\n command = cat $in > $out\n"
993 "build a: cat a\n"));
996 EXPECT_EQ(0u, state.DefaultNodes(&err).size());
997 EXPECT_EQ("could not determine root nodes of build graph", err);
1000 TEST_F(ParserTest, DefaultStatements) {
1001 ASSERT_NO_FATAL_FAILURE(AssertParse(
1002 "rule cat\n command = cat $in > $out\n"
1003 "build a: cat foo\n"
1004 "build b: cat foo\n"
1005 "build c: cat foo\n"
1006 "build d: cat foo\n"
1009 "default $third\n"));
1012 vector<Node*> nodes = state.DefaultNodes(&err);
1014 ASSERT_EQ(3u, nodes.size());
1015 EXPECT_EQ("a", nodes[0]->path());
1016 EXPECT_EQ("b", nodes[1]->path());
1017 EXPECT_EQ("c", nodes[2]->path());
1020 TEST_F(ParserTest, UTF8) {
1021 ASSERT_NO_FATAL_FAILURE(AssertParse(
1024 " description = compilaci\xC3\xB3\n"));
1027 TEST_F(ParserTest, CRLF) {
1029 ManifestParser parser(&state, NULL, kDupeEdgeActionWarn);
1032 EXPECT_TRUE(parser.ParseTest("# comment with crlf\r\n", &err));
1033 EXPECT_TRUE(parser.ParseTest("foo = foo\nbar = bar\r\n", &err));
1034 EXPECT_TRUE(parser.ParseTest(
1035 "pool link_pool\r\n"
1036 " depth = 15\r\n\r\n"
1038 " command = something$expand \r\n"
1039 " description = YAY!\r\n",