15 #include <gtest/gtest.h>
28 struct DiskInterfaceTest :
public testing::Test {
29 virtual void SetUp() {
31 temp_dir_.CreateAndEnter(
"Ninja-DiskInterfaceTest");
34 virtual void TearDown() {
38 bool Touch(
const char* path) {
39 FILE *f = fopen(path,
"w");
42 return fclose(f) == 0;
49 TEST_F(DiskInterfaceTest, StatMissingFile) {
50 EXPECT_EQ(0, disk_.Stat(
"nosuchfile"));
54 EXPECT_EQ(0, disk_.Stat(
"nosuchdir/nosuchfile"));
58 ASSERT_TRUE(Touch(
"notadir"));
59 EXPECT_EQ(0, disk_.Stat(
"notadir/nosuchfile"));
62 TEST_F(DiskInterfaceTest, StatBadPath) {
65 string bad_path(
"cc:\\foo");
66 EXPECT_EQ(-1, disk_.Stat(bad_path));
68 string too_long_name(512,
'x');
69 EXPECT_EQ(-1, disk_.Stat(too_long_name));
74 TEST_F(DiskInterfaceTest, StatExistingFile) {
75 ASSERT_TRUE(Touch(
"file"));
76 EXPECT_GT(disk_.Stat(
"file"), 1);
81 EXPECT_EQ(
"", disk_.ReadFile(
"foobar", &err));
84 const char* kTestFile =
"testfile";
85 FILE* f = fopen(kTestFile,
"wb");
87 const char* kTestContent =
"test content\nok";
88 fprintf(f,
"%s", kTestContent);
89 ASSERT_EQ(0, fclose(f));
91 EXPECT_EQ(kTestContent, disk_.ReadFile(kTestFile, &err));
95 TEST_F(DiskInterfaceTest, MakeDirs) {
96 EXPECT_TRUE(disk_.MakeDirs(
"path/with/double//slash/"));
99 TEST_F(DiskInterfaceTest, RemoveFile) {
100 const char* kFileName =
"file-to-remove";
101 ASSERT_TRUE(Touch(kFileName));
102 EXPECT_EQ(0, disk_.RemoveFile(kFileName));
103 EXPECT_EQ(1, disk_.RemoveFile(kFileName));
104 EXPECT_EQ(1, disk_.RemoveFile(
"does not exist"));
109 StatTest() : scan_(&state_, NULL, NULL, this) {}
113 virtual bool WriteFile(
const string& path,
const string& contents) {
117 virtual bool MakeDir(
const string& path) {
121 virtual string ReadFile(
const string& path,
string* err) {
131 map<string, TimeStamp> mtimes_;
132 vector<string> stats_;
136 stats_.push_back(path);
137 map<string, TimeStamp>::iterator i = mtimes_.find(path);
138 if (i == mtimes_.end())
143 TEST_F(StatTest, Simple) {
145 "build out: cat in\n"));
147 Node* out = GetNode(
"out");
149 ASSERT_EQ(1u, stats_.size());
150 scan_.RecomputeDirty(out->
in_edge(), NULL);
151 ASSERT_EQ(2u, stats_.size());
152 ASSERT_EQ(
"out", stats_[0]);
153 ASSERT_EQ(
"in", stats_[1]);
156 TEST_F(StatTest, TwoStep) {
158 "build out: cat mid\n"
159 "build mid: cat in\n"));
161 Node* out = GetNode(
"out");
163 ASSERT_EQ(1u, stats_.size());
164 scan_.RecomputeDirty(out->
in_edge(), NULL);
165 ASSERT_EQ(3u, stats_.size());
166 ASSERT_EQ(
"out", stats_[0]);
167 ASSERT_TRUE(GetNode(
"out")->dirty());
168 ASSERT_EQ(
"mid", stats_[1]);
169 ASSERT_TRUE(GetNode(
"mid")->dirty());
170 ASSERT_EQ(
"in", stats_[2]);
175 "build out: cat mid1 mid2\n"
176 "build mid1: cat in11 in12\n"
177 "build mid2: cat in21 in22\n"));
179 Node* out = GetNode(
"out");
181 ASSERT_EQ(1u, stats_.size());
182 scan_.RecomputeDirty(out->
in_edge(), NULL);
183 ASSERT_EQ(1u + 6u, stats_.size());
184 ASSERT_EQ(
"mid1", stats_[1]);
185 ASSERT_TRUE(GetNode(
"mid1")->dirty());
186 ASSERT_EQ(
"in11", stats_[2]);
189 TEST_F(StatTest, Middle) {
191 "build out: cat mid\n"
192 "build mid: cat in\n"));
198 Node* out = GetNode(
"out");
200 ASSERT_EQ(1u, stats_.size());
201 scan_.RecomputeDirty(out->
in_edge(), NULL);
202 ASSERT_FALSE(GetNode(
"in")->dirty());
203 ASSERT_TRUE(GetNode(
"mid")->dirty());
204 ASSERT_TRUE(GetNode(
"out")->dirty());