Ninja
manifest_parser_test.cc
Go to the documentation of this file.
00001 // Copyright 2011 Google Inc. All Rights Reserved.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //     http://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 
00015 #include "manifest_parser.h"
00016 
00017 #include <map>
00018 #include <vector>
00019 
00020 #include <gtest/gtest.h>
00021 
00022 #include "graph.h"
00023 #include "state.h"
00024 
00025 struct ParserTest : public testing::Test,
00026                     public ManifestParser::FileReader {
00027   void AssertParse(const char* input) {
00028     ManifestParser parser(&state, this);
00029     string err;
00030     ASSERT_TRUE(parser.ParseTest(input, &err)) << err;
00031     ASSERT_EQ("", err);
00032   }
00033 
00034   virtual bool ReadFile(const string& path, string* content, string* err) {
00035     files_read_.push_back(path);
00036     map<string, string>::iterator i = files_.find(path);
00037     if (i == files_.end()) {
00038       *err = "No such file or directory";  // Match strerror() for ENOENT.
00039       return false;
00040     }
00041     *content = i->second;
00042     return true;
00043   }
00044 
00045   State state;
00046   map<string, string> files_;
00047   vector<string> files_read_;
00048 };
00049 
00050 TEST_F(ParserTest, Empty) {
00051   ASSERT_NO_FATAL_FAILURE(AssertParse(""));
00052 }
00053 
00054 TEST_F(ParserTest, Rules) {
00055   ASSERT_NO_FATAL_FAILURE(AssertParse(
00056 "rule cat\n"
00057 "  command = cat $in > $out\n"
00058 "\n"
00059 "rule date\n"
00060 "  command = date > $out\n"
00061 "\n"
00062 "build result: cat in_1.cc in-2.O\n"));
00063 
00064   ASSERT_EQ(3u, state.rules_.size());
00065   const Rule* rule = state.rules_.begin()->second;
00066   EXPECT_EQ("cat", rule->name());
00067   EXPECT_EQ("[cat ][$in][ > ][$out]",
00068             rule->GetBinding("command")->Serialize());
00069 }
00070 
00071 TEST_F(ParserTest, RuleAttributes) {
00072   // Check that all of the allowed rule attributes are parsed ok.
00073   ASSERT_NO_FATAL_FAILURE(AssertParse(
00074 "rule cat\n"
00075 "  command = a\n"
00076 "  depfile = a\n"
00077 "  deps = a\n"
00078 "  description = a\n"
00079 "  generator = a\n"
00080 "  restat = a\n"
00081 "  rspfile = a\n"
00082 "  rspfile_content = a\n"
00083 ));
00084 }
00085 
00086 TEST_F(ParserTest, IgnoreIndentedComments) {
00087   ASSERT_NO_FATAL_FAILURE(AssertParse(
00088 "  #indented comment\n"
00089 "rule cat\n"
00090 "  command = cat $in > $out\n"
00091 "  #generator = 1\n"
00092 "  restat = 1 # comment\n"
00093 "  #comment\n"
00094 "build result: cat in_1.cc in-2.O\n"
00095 "  #comment\n"));
00096 
00097   ASSERT_EQ(2u, state.rules_.size());
00098   const Rule* rule = state.rules_.begin()->second;
00099   EXPECT_EQ("cat", rule->name());
00100   Edge* edge = state.GetNode("result")->in_edge();
00101   EXPECT_TRUE(edge->GetBindingBool("restat"));
00102   EXPECT_FALSE(edge->GetBindingBool("generator"));
00103 }
00104 
00105 TEST_F(ParserTest, IgnoreIndentedBlankLines) {
00106   // the indented blanks used to cause parse errors
00107   ASSERT_NO_FATAL_FAILURE(AssertParse(
00108 "  \n"
00109 "rule cat\n"
00110 "  command = cat $in > $out\n"
00111 "  \n"
00112 "build result: cat in_1.cc in-2.O\n"
00113 "  \n"
00114 "variable=1\n"));
00115 
00116   // the variable must be in the top level environment
00117   EXPECT_EQ("1", state.bindings_.LookupVariable("variable"));
00118 }
00119 
00120 TEST_F(ParserTest, ResponseFiles) {
00121   ASSERT_NO_FATAL_FAILURE(AssertParse(
00122 "rule cat_rsp\n"
00123 "  command = cat $rspfile > $out\n"
00124 "  rspfile = $rspfile\n"
00125 "  rspfile_content = $in\n"
00126 "\n"
00127 "build out: cat_rsp in\n"
00128 "  rspfile=out.rsp\n"));
00129 
00130   ASSERT_EQ(2u, state.rules_.size());
00131   const Rule* rule = state.rules_.begin()->second;
00132   EXPECT_EQ("cat_rsp", rule->name());
00133   EXPECT_EQ("[cat ][$rspfile][ > ][$out]",
00134             rule->GetBinding("command")->Serialize());
00135   EXPECT_EQ("[$rspfile]", rule->GetBinding("rspfile")->Serialize());
00136   EXPECT_EQ("[$in]", rule->GetBinding("rspfile_content")->Serialize());
00137 }
00138 
00139 TEST_F(ParserTest, InNewline) {
00140   ASSERT_NO_FATAL_FAILURE(AssertParse(
00141 "rule cat_rsp\n"
00142 "  command = cat $in_newline > $out\n"
00143 "\n"
00144 "build out: cat_rsp in in2\n"
00145 "  rspfile=out.rsp\n"));
00146 
00147   ASSERT_EQ(2u, state.rules_.size());
00148   const Rule* rule = state.rules_.begin()->second;
00149   EXPECT_EQ("cat_rsp", rule->name());
00150   EXPECT_EQ("[cat ][$in_newline][ > ][$out]",
00151             rule->GetBinding("command")->Serialize());
00152 
00153   Edge* edge = state.edges_[0];
00154   EXPECT_EQ("cat in\nin2 > out", edge->EvaluateCommand());
00155 }
00156 
00157 TEST_F(ParserTest, Variables) {
00158   ASSERT_NO_FATAL_FAILURE(AssertParse(
00159 "l = one-letter-test\n"
00160 "rule link\n"
00161 "  command = ld $l $extra $with_under -o $out $in\n"
00162 "\n"
00163 "extra = -pthread\n"
00164 "with_under = -under\n"
00165 "build a: link b c\n"
00166 "nested1 = 1\n"
00167 "nested2 = $nested1/2\n"
00168 "build supernested: link x\n"
00169 "  extra = $nested2/3\n"));
00170 
00171   ASSERT_EQ(2u, state.edges_.size());
00172   Edge* edge = state.edges_[0];
00173   EXPECT_EQ("ld one-letter-test -pthread -under -o a b c",
00174             edge->EvaluateCommand());
00175   EXPECT_EQ("1/2", state.bindings_.LookupVariable("nested2"));
00176 
00177   edge = state.edges_[1];
00178   EXPECT_EQ("ld one-letter-test 1/2/3 -under -o supernested x",
00179             edge->EvaluateCommand());
00180 }
00181 
00182 TEST_F(ParserTest, VariableScope) {
00183   ASSERT_NO_FATAL_FAILURE(AssertParse(
00184 "foo = bar\n"
00185 "rule cmd\n"
00186 "  command = cmd $foo $in $out\n"
00187 "\n"
00188 "build inner: cmd a\n"
00189 "  foo = baz\n"
00190 "build outer: cmd b\n"
00191 "\n"  // Extra newline after build line tickles a regression.
00192 ));
00193 
00194   ASSERT_EQ(2u, state.edges_.size());
00195   EXPECT_EQ("cmd baz a inner", state.edges_[0]->EvaluateCommand());
00196   EXPECT_EQ("cmd bar b outer", state.edges_[1]->EvaluateCommand());
00197 }
00198 
00199 TEST_F(ParserTest, Continuation) {
00200   ASSERT_NO_FATAL_FAILURE(AssertParse(
00201 "rule link\n"
00202 "  command = foo bar $\n"
00203 "    baz\n"
00204 "\n"
00205 "build a: link c $\n"
00206 " d e f\n"));
00207 
00208   ASSERT_EQ(2u, state.rules_.size());
00209   const Rule* rule = state.rules_.begin()->second;
00210   EXPECT_EQ("link", rule->name());
00211   EXPECT_EQ("[foo bar baz]", rule->GetBinding("command")->Serialize());
00212 }
00213 
00214 TEST_F(ParserTest, Backslash) {
00215   ASSERT_NO_FATAL_FAILURE(AssertParse(
00216 "foo = bar\\baz\n"
00217 "foo2 = bar\\ baz\n"
00218 ));
00219   EXPECT_EQ("bar\\baz", state.bindings_.LookupVariable("foo"));
00220   EXPECT_EQ("bar\\ baz", state.bindings_.LookupVariable("foo2"));
00221 }
00222 
00223 TEST_F(ParserTest, Comment) {
00224   ASSERT_NO_FATAL_FAILURE(AssertParse(
00225 "# this is a comment\n"
00226 "foo = not # a comment\n"));
00227   EXPECT_EQ("not # a comment", state.bindings_.LookupVariable("foo"));
00228 }
00229 
00230 TEST_F(ParserTest, Dollars) {
00231   ASSERT_NO_FATAL_FAILURE(AssertParse(
00232 "rule foo\n"
00233 "  command = ${out}bar$$baz$$$\n"
00234 "blah\n"
00235 "x = $$dollar\n"
00236 "build $x: foo y\n"
00237 ));
00238   EXPECT_EQ("$dollar", state.bindings_.LookupVariable("x"));
00239   EXPECT_EQ("$dollarbar$baz$blah", state.edges_[0]->EvaluateCommand());
00240 }
00241 
00242 TEST_F(ParserTest, EscapeSpaces) {
00243   ASSERT_NO_FATAL_FAILURE(AssertParse(
00244 "rule spaces\n"
00245 "  command = something\n"
00246 "build foo$ bar: spaces $$one two$$$ three\n"
00247 ));
00248   EXPECT_TRUE(state.LookupNode("foo bar"));
00249   EXPECT_EQ(state.edges_[0]->outputs_[0]->path(), "foo bar");
00250   EXPECT_EQ(state.edges_[0]->inputs_[0]->path(), "$one");
00251   EXPECT_EQ(state.edges_[0]->inputs_[1]->path(), "two$ three");
00252   EXPECT_EQ(state.edges_[0]->EvaluateCommand(), "something");
00253 }
00254 
00255 TEST_F(ParserTest, CanonicalizeFile) {
00256   ASSERT_NO_FATAL_FAILURE(AssertParse(
00257 "rule cat\n"
00258 "  command = cat $in > $out\n"
00259 "build out: cat in/1 in//2\n"
00260 "build in/1: cat\n"
00261 "build in/2: cat\n"));
00262 
00263   EXPECT_TRUE(state.LookupNode("in/1"));
00264   EXPECT_TRUE(state.LookupNode("in/2"));
00265   EXPECT_FALSE(state.LookupNode("in//1"));
00266   EXPECT_FALSE(state.LookupNode("in//2"));
00267 }
00268 
00269 TEST_F(ParserTest, PathVariables) {
00270   ASSERT_NO_FATAL_FAILURE(AssertParse(
00271 "rule cat\n"
00272 "  command = cat $in > $out\n"
00273 "dir = out\n"
00274 "build $dir/exe: cat src\n"));
00275 
00276   EXPECT_FALSE(state.LookupNode("$dir/exe"));
00277   EXPECT_TRUE(state.LookupNode("out/exe"));
00278 }
00279 
00280 TEST_F(ParserTest, CanonicalizePaths) {
00281   ASSERT_NO_FATAL_FAILURE(AssertParse(
00282 "rule cat\n"
00283 "  command = cat $in > $out\n"
00284 "build ./out.o: cat ./bar/baz/../foo.cc\n"));
00285 
00286   EXPECT_FALSE(state.LookupNode("./out.o"));
00287   EXPECT_TRUE(state.LookupNode("out.o"));
00288   EXPECT_FALSE(state.LookupNode("./bar/baz/../foo.cc"));
00289   EXPECT_TRUE(state.LookupNode("bar/foo.cc"));
00290 }
00291 
00292 TEST_F(ParserTest, ReservedWords) {
00293   ASSERT_NO_FATAL_FAILURE(AssertParse(
00294 "rule build\n"
00295 "  command = rule run $out\n"
00296 "build subninja: build include default foo.cc\n"
00297 "default subninja\n"));
00298 }
00299 
00300 TEST_F(ParserTest, Errors) {
00301   {
00302     State state;
00303     ManifestParser parser(&state, NULL);
00304     string err;
00305     EXPECT_FALSE(parser.ParseTest("foobar", &err));
00306     EXPECT_EQ("input:1: expected '=', got eof\n"
00307               "foobar\n"
00308               "      ^ near here"
00309               , err);
00310   }
00311 
00312   {
00313     State state;
00314     ManifestParser parser(&state, NULL);
00315     string err;
00316     EXPECT_FALSE(parser.ParseTest("x 3", &err));
00317     EXPECT_EQ("input:1: expected '=', got identifier\n"
00318               "x 3\n"
00319               "  ^ near here"
00320               , err);
00321   }
00322 
00323   {
00324     State state;
00325     ManifestParser parser(&state, NULL);
00326     string err;
00327     EXPECT_FALSE(parser.ParseTest("x = 3", &err));
00328     EXPECT_EQ("input:1: unexpected EOF\n"
00329               "x = 3\n"
00330               "     ^ near here"
00331               , err);
00332   }
00333 
00334   {
00335     State state;
00336     ManifestParser parser(&state, NULL);
00337     string err;
00338     EXPECT_FALSE(parser.ParseTest("x = 3\ny 2", &err));
00339     EXPECT_EQ("input:2: expected '=', got identifier\n"
00340               "y 2\n"
00341               "  ^ near here"
00342               , err);
00343   }
00344 
00345   {
00346     State state;
00347     ManifestParser parser(&state, NULL);
00348     string err;
00349     EXPECT_FALSE(parser.ParseTest("x = $", &err));
00350     EXPECT_EQ("input:1: bad $-escape (literal $ must be written as $$)\n"
00351               "x = $\n"
00352               "    ^ near here"
00353               , err);
00354   }
00355 
00356   {
00357     State state;
00358     ManifestParser parser(&state, NULL);
00359     string err;
00360     EXPECT_FALSE(parser.ParseTest("x = $\n $[\n", &err));
00361     EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
00362               " $[\n"
00363               " ^ near here"
00364               , err);
00365   }
00366 
00367   {
00368     State state;
00369     ManifestParser parser(&state, NULL);
00370     string err;
00371     EXPECT_FALSE(parser.ParseTest("x = a$\n b$\n $\n", &err));
00372     EXPECT_EQ("input:4: unexpected EOF\n"
00373               , err);
00374   }
00375 
00376   {
00377     State state;
00378     ManifestParser parser(&state, NULL);
00379     string err;
00380     EXPECT_FALSE(parser.ParseTest("build x: y z\n", &err));
00381     EXPECT_EQ("input:1: unknown build rule 'y'\n"
00382               "build x: y z\n"
00383               "       ^ near here"
00384               , err);
00385   }
00386 
00387   {
00388     State state;
00389     ManifestParser parser(&state, NULL);
00390     string err;
00391     EXPECT_FALSE(parser.ParseTest("build x:: y z\n", &err));
00392     EXPECT_EQ("input:1: expected build command name\n"
00393               "build x:: y z\n"
00394               "       ^ near here"
00395               , err);
00396   }
00397 
00398   {
00399     State state;
00400     ManifestParser parser(&state, NULL);
00401     string err;
00402     EXPECT_FALSE(parser.ParseTest("rule cat\n  command = cat ok\n"
00403                                   "build x: cat $\n :\n",
00404                                   &err));
00405     EXPECT_EQ("input:4: expected newline, got ':'\n"
00406               " :\n"
00407               " ^ near here"
00408               , err);
00409   }
00410 
00411   {
00412     State state;
00413     ManifestParser parser(&state, NULL);
00414     string err;
00415     EXPECT_FALSE(parser.ParseTest("rule cat\n",
00416                                   &err));
00417     EXPECT_EQ("input:2: expected 'command =' line\n", err);
00418   }
00419 
00420   {
00421     State state;
00422     ManifestParser parser(&state, NULL);
00423     string err;
00424     EXPECT_FALSE(parser.ParseTest("rule cat\n"
00425                                   "  command = ${fafsd\n"
00426                                   "foo = bar\n",
00427                                   &err));
00428     EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
00429               "  command = ${fafsd\n"
00430               "            ^ near here"
00431               , err);
00432   }
00433 
00434 
00435   {
00436     State state;
00437     ManifestParser parser(&state, NULL);
00438     string err;
00439     EXPECT_FALSE(parser.ParseTest("rule cat\n"
00440                                   "  command = cat\n"
00441                                   "build $.: cat foo\n",
00442                                   &err));
00443     EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
00444               "build $.: cat foo\n"
00445               "      ^ near here"
00446               , err);
00447   }
00448 
00449 
00450   {
00451     State state;
00452     ManifestParser parser(&state, NULL);
00453     string err;
00454     EXPECT_FALSE(parser.ParseTest("rule cat\n"
00455                                   "  command = cat\n"
00456                                   "build $: cat foo\n",
00457                                   &err));
00458     EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
00459               "build $: cat foo\n"
00460               "                ^ near here"
00461               , err);
00462   }
00463 
00464   {
00465     State state;
00466     ManifestParser parser(&state, NULL);
00467     string err;
00468     EXPECT_FALSE(parser.ParseTest("rule %foo\n",
00469                                   &err));
00470     EXPECT_EQ("input:1: expected rule name\n", err);
00471   }
00472 
00473   {
00474     State state;
00475     ManifestParser parser(&state, NULL);
00476     string err;
00477     EXPECT_FALSE(parser.ParseTest("rule cc\n"
00478                                   "  command = foo\n"
00479                                   "  othervar = bar\n",
00480                                   &err));
00481     EXPECT_EQ("input:3: unexpected variable 'othervar'\n"
00482               "  othervar = bar\n"
00483               "                ^ near here"
00484               , err);
00485   }
00486 
00487   {
00488     State state;
00489     ManifestParser parser(&state, NULL);
00490     string err;
00491     EXPECT_FALSE(parser.ParseTest("rule cc\n  command = foo\n"
00492                                   "build $.: cc bar.cc\n",
00493                                   &err));
00494     EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
00495               "build $.: cc bar.cc\n"
00496               "      ^ near here"
00497               , err);
00498   }
00499 
00500   {
00501     State state;
00502     ManifestParser parser(&state, NULL);
00503     string err;
00504     EXPECT_FALSE(parser.ParseTest("rule cc\n  command = foo\n"
00505                                   "build $: cc bar.cc\n",
00506                                   &err));
00507     EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
00508               "build $: cc bar.cc\n"
00509               "                  ^ near here"
00510               , err);
00511   }
00512 
00513   {
00514     State state;
00515     ManifestParser parser(&state, NULL);
00516     string err;
00517     EXPECT_FALSE(parser.ParseTest("default\n",
00518                                   &err));
00519     EXPECT_EQ("input:1: expected target name\n"
00520               "default\n"
00521               "       ^ near here"
00522               , err);
00523   }
00524 
00525   {
00526     State state;
00527     ManifestParser parser(&state, NULL);
00528     string err;
00529     EXPECT_FALSE(parser.ParseTest("default nonexistent\n",
00530                                   &err));
00531     EXPECT_EQ("input:1: unknown target 'nonexistent'\n"
00532               "default nonexistent\n"
00533               "                   ^ near here"
00534               , err);
00535   }
00536 
00537   {
00538     State state;
00539     ManifestParser parser(&state, NULL);
00540     string err;
00541     EXPECT_FALSE(parser.ParseTest("rule r\n  command = r\n"
00542                                   "build b: r\n"
00543                                   "default b:\n",
00544                                   &err));
00545     EXPECT_EQ("input:4: expected newline, got ':'\n"
00546               "default b:\n"
00547               "         ^ near here"
00548               , err);
00549   }
00550 
00551   {
00552     State state;
00553     ManifestParser parser(&state, NULL);
00554     string err;
00555     EXPECT_FALSE(parser.ParseTest("default $a\n", &err));
00556     EXPECT_EQ("input:1: empty path\n"
00557               "default $a\n"
00558               "          ^ near here"
00559               , err);
00560   }
00561 
00562   {
00563     State state;
00564     ManifestParser parser(&state, NULL);
00565     string err;
00566     EXPECT_FALSE(parser.ParseTest("rule r\n"
00567                                   "  command = r\n"
00568                                   "build $a: r $c\n", &err));
00569     // XXX the line number is wrong; we should evaluate paths in ParseEdge
00570     // as we see them, not after we've read them all!
00571     EXPECT_EQ("input:4: empty path\n", err);
00572   }
00573 
00574   {
00575     State state;
00576     ManifestParser parser(&state, NULL);
00577     string err;
00578     // the indented blank line must terminate the rule
00579     // this also verifies that "unexpected (token)" errors are correct
00580     EXPECT_FALSE(parser.ParseTest("rule r\n"
00581                                   "  command = r\n"
00582                                   "  \n"
00583                                   "  generator = 1\n", &err));
00584     EXPECT_EQ("input:4: unexpected indent\n", err);
00585   }
00586 }
00587 
00588 TEST_F(ParserTest, MissingInput) {
00589   State state;
00590   ManifestParser parser(&state, this);
00591   string err;
00592   EXPECT_FALSE(parser.Load("build.ninja", &err));
00593   EXPECT_EQ("loading 'build.ninja': No such file or directory", err);
00594 }
00595 
00596 TEST_F(ParserTest, MultipleOutputs) {
00597   State state;
00598   ManifestParser parser(&state, NULL);
00599   string err;
00600   EXPECT_TRUE(parser.ParseTest("rule cc\n  command = foo\n  depfile = bar\n"
00601                                "build a.o b.o: cc c.cc\n",
00602                                &err));
00603   EXPECT_EQ("", err);
00604 }
00605 
00606 TEST_F(ParserTest, MultipleOutputsWithDeps) {
00607   State state;
00608   ManifestParser parser(&state, NULL);
00609   string err;
00610   EXPECT_FALSE(parser.ParseTest("rule cc\n  command = foo\n  deps = gcc\n"
00611                                "build a.o b.o: cc c.cc\n",
00612                                &err));
00613   EXPECT_EQ("input:5: multiple outputs aren't (yet?) supported by depslog; "
00614             "bring this up on the mailing list if it affects you\n", err);
00615 }
00616 
00617 TEST_F(ParserTest, SubNinja) {
00618   files_["test.ninja"] =
00619     "var = inner\n"
00620     "build $builddir/inner: varref\n";
00621   ASSERT_NO_FATAL_FAILURE(AssertParse(
00622 "builddir = some_dir/\n"
00623 "rule varref\n"
00624 "  command = varref $var\n"
00625 "var = outer\n"
00626 "build $builddir/outer: varref\n"
00627 "subninja test.ninja\n"
00628 "build $builddir/outer2: varref\n"));
00629   ASSERT_EQ(1u, files_read_.size());
00630 
00631   EXPECT_EQ("test.ninja", files_read_[0]);
00632   EXPECT_TRUE(state.LookupNode("some_dir/outer"));
00633   // Verify our builddir setting is inherited.
00634   EXPECT_TRUE(state.LookupNode("some_dir/inner"));
00635 
00636   ASSERT_EQ(3u, state.edges_.size());
00637   EXPECT_EQ("varref outer", state.edges_[0]->EvaluateCommand());
00638   EXPECT_EQ("varref inner", state.edges_[1]->EvaluateCommand());
00639   EXPECT_EQ("varref outer", state.edges_[2]->EvaluateCommand());
00640 }
00641 
00642 TEST_F(ParserTest, MissingSubNinja) {
00643   ManifestParser parser(&state, this);
00644   string err;
00645   EXPECT_FALSE(parser.ParseTest("subninja foo.ninja\n", &err));
00646   EXPECT_EQ("input:1: loading 'foo.ninja': No such file or directory\n"
00647             "subninja foo.ninja\n"
00648             "                  ^ near here"
00649             , err);
00650 }
00651 
00652 TEST_F(ParserTest, Include) {
00653   files_["include.ninja"] = "var = inner\n";
00654   ASSERT_NO_FATAL_FAILURE(AssertParse(
00655 "var = outer\n"
00656 "include include.ninja\n"));
00657 
00658   ASSERT_EQ(1u, files_read_.size());
00659   EXPECT_EQ("include.ninja", files_read_[0]);
00660   EXPECT_EQ("inner", state.bindings_.LookupVariable("var"));
00661 }
00662 
00663 TEST_F(ParserTest, Implicit) {
00664   ASSERT_NO_FATAL_FAILURE(AssertParse(
00665 "rule cat\n"
00666 "  command = cat $in > $out\n"
00667 "build foo: cat bar | baz\n"));
00668 
00669   Edge* edge = state.LookupNode("foo")->in_edge();
00670   ASSERT_TRUE(edge->is_implicit(1));
00671 }
00672 
00673 TEST_F(ParserTest, OrderOnly) {
00674   ASSERT_NO_FATAL_FAILURE(AssertParse(
00675 "rule cat\n  command = cat $in > $out\n"
00676 "build foo: cat bar || baz\n"));
00677 
00678   Edge* edge = state.LookupNode("foo")->in_edge();
00679   ASSERT_TRUE(edge->is_order_only(1));
00680 }
00681 
00682 TEST_F(ParserTest, DefaultDefault) {
00683   ASSERT_NO_FATAL_FAILURE(AssertParse(
00684 "rule cat\n  command = cat $in > $out\n"
00685 "build a: cat foo\n"
00686 "build b: cat foo\n"
00687 "build c: cat foo\n"
00688 "build d: cat foo\n"));
00689 
00690   string err;
00691   EXPECT_EQ(4u, state.DefaultNodes(&err).size());
00692   EXPECT_EQ("", err);
00693 }
00694 
00695 TEST_F(ParserTest, DefaultStatements) {
00696   ASSERT_NO_FATAL_FAILURE(AssertParse(
00697 "rule cat\n  command = cat $in > $out\n"
00698 "build a: cat foo\n"
00699 "build b: cat foo\n"
00700 "build c: cat foo\n"
00701 "build d: cat foo\n"
00702 "third = c\n"
00703 "default a b\n"
00704 "default $third\n"));
00705 
00706   string err;
00707   vector<Node*> nodes = state.DefaultNodes(&err);
00708   EXPECT_EQ("", err);
00709   ASSERT_EQ(3u, nodes.size());
00710   EXPECT_EQ("a", nodes[0]->path());
00711   EXPECT_EQ("b", nodes[1]->path());
00712   EXPECT_EQ("c", nodes[2]->path());
00713 }
00714 
00715 TEST_F(ParserTest, UTF8) {
00716   ASSERT_NO_FATAL_FAILURE(AssertParse(
00717 "rule utf8\n"
00718 "  command = true\n"
00719 "  description = compilaci\xC3\xB3\n"));
00720 }
00721 
00722 // We might want to eventually allow CRLF to be nice to Windows developers,
00723 // but for now just verify we error out with a nice message.
00724 TEST_F(ParserTest, CRLF) {
00725   State state;
00726   ManifestParser parser(&state, NULL);
00727   string err;
00728 
00729   EXPECT_FALSE(parser.ParseTest("# comment with crlf\r\n",
00730                                 &err));
00731   EXPECT_EQ("input:1: lexing error\n",
00732             err);
00733 
00734   EXPECT_FALSE(parser.ParseTest("foo = foo\nbar = bar\r\n",
00735                                 &err));
00736   EXPECT_EQ("input:2: carriage returns are not allowed, use newlines\n"
00737             "bar = bar\r\n"
00738             "         ^ near here",
00739             err);
00740 }