basic gmock test
authorEvan Martin <martine@danga.com>
Sun, 17 Oct 2010 05:17:37 +0000 (22:17 -0700)
committerEvan Martin <martine@danga.com>
Sun, 17 Oct 2010 05:17:37 +0000 (22:17 -0700)
Makefile
manifest_parser.h
ninja.h
ninja_test.cc

index 44877bf..2fad958 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ CXXFLAGS := -Wall -g
 
 all_i_currently_care_about: ninja_test
 
-ninja_test: LDFLAGS = -lgtest -lgtest_main
+ninja_test: LDFLAGS = -lgtest -lgmock -lgmock_main -lpthread
 ninja_test: ninja_test.o
 ninja_test.o: ninja_test.cc ninja.h manifest_parser.h
 
index e2addcc..0b2eff2 100644 (file)
@@ -98,15 +98,15 @@ bool ManifestParser::ParseRule(string* err) {
 }
 
 bool ManifestParser::ParseEdge(string* err) {
-  vector<string> ins, outs;
   string rule;
+  vector<string> ins, outs;
   SkipWhitespace();
   for (;;) {
     if (!NextToken())
       return Error("expected output file list", err);
     if (token_ == ":")
       break;
-    ins.push_back(token_);
+    outs.push_back(token_);
   }
   if (!NextToken())
     return Error("expected build command name", err);
@@ -114,7 +114,7 @@ bool ManifestParser::ParseEdge(string* err) {
   for (;;) {
     if (!NextToken())
       break;
-    outs.push_back(token_);
+    ins.push_back(token_);
   }
   if (!Newline(err))
     return false;
diff --git a/ninja.h b/ninja.h
index 5bcb854..300fddc 100644 (file)
--- a/ninja.h
+++ b/ninja.h
@@ -220,7 +220,7 @@ void State::AddInOut(Edge* edge, Edge::InOut inout, const string& path) {
 }
 
 struct Plan {
-  Plan(State* state) : state_(state) {}
+  explicit Plan(State* state) : state_(state) {}
 
   void AddTarget(const string& path);
   bool AddTarget(Node* node);
@@ -230,6 +230,10 @@ struct Plan {
   State* state_;
   set<Node*> want_;
   queue<Edge*> ready_;
+
+private:
+  Plan();
+  Plan(const Plan&);
 };
 
 void Plan::AddTarget(const string& path) {
@@ -267,3 +271,33 @@ Edge* Plan::FindWork() {
 }
 
 #include "manifest_parser.h"
+
+struct Shell {
+  virtual ~Shell() {}
+  virtual bool RunCommand(const string& command) = 0;
+};
+
+struct Builder {
+  Builder(State* state) : plan_(state) {}
+  virtual ~Builder() {}
+
+  void AddTarget(const string& name) {
+    plan_.AddTarget(name);
+  }
+  bool Build(Shell* shell, string* err);
+
+  Plan plan_;
+};
+
+bool Builder::Build(Shell* shell, string* err) {
+  while (Edge* edge = plan_.FindWork()) {
+    string command = edge->EvaluateCommand();
+    if (!shell->RunCommand(command)) {
+      err->assign("command '" + command + "' failed.");
+      return false;
+    }
+    // XXX tell plan about the files we've updated, so we have more
+    // work to do
+  }
+  return true;
+}
index 138a339..3ad9b09 100644 (file)
@@ -78,3 +78,46 @@ TEST(EvalString, OneVariable) {
   env.vars["$var"] = "there";
   EXPECT_EQ("hi there", str.Evaluate(&env));
 }
+
+#include <gmock/gmock.h>
+using ::testing::Return;
+using ::testing::_;
+
+struct MockShell : public Shell {
+  MOCK_METHOD1(RunCommand, bool(const string& command));
+};
+
+TEST(Build, OneStep) {
+  State state;
+  ManifestParser parser(&state);
+  string err;
+  ASSERT_TRUE(parser.Parse(
+"rule cat\n"
+"command cat @in > $out\n"
+"\n"
+"build lib: cat in1 in2\n"
+"build bin: cat main lib\n",
+      &err));
+  ASSERT_EQ("", err);
+
+  {
+    MockShell shell;
+    Builder builder(&state);
+    builder.AddTarget("bin");
+    EXPECT_CALL(shell, RunCommand(_))
+      .Times(0);
+    EXPECT_TRUE(builder.Build(&shell, &err));
+    EXPECT_EQ("", err);
+  }
+
+  {
+    MockShell shell;
+    Builder builder(&state);
+    state.stat_cache()->GetFile("in1")->Touch(1);
+    builder.AddTarget("bin");
+    EXPECT_CALL(shell, RunCommand("cat in1 in2 > lib"))
+      .WillOnce(Return(true));
+    EXPECT_TRUE(builder.Build(&shell, &err));
+    EXPECT_EQ("", err);
+  }
+}