Imported Upstream version 1.7.1
[platform/upstream/ninja.git] / src / test.h
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
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
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
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.
14
15 #ifndef NINJA_TEST_H_
16 #define NINJA_TEST_H_
17
18 #include "disk_interface.h"
19 #include "state.h"
20 #include "util.h"
21
22 // A tiny testing framework inspired by googletest, but much simpler and
23 // faster to compile. It supports most things commonly used from googltest. The
24 // most noticeable things missing: EXPECT_* and ASSERT_* don't support
25 // streaming notes to them with operator<<, and for failing tests the lhs and
26 // rhs are not printed. That's so that this header does not have to include
27 // sstream, which slows down building ninja_test almost 20%.
28 namespace testing {
29 class Test {
30   bool failed_;
31   int assertion_failures_;
32  public:
33   Test() : failed_(false), assertion_failures_(0) {}
34   virtual ~Test() {}
35   virtual void SetUp() {}
36   virtual void TearDown() {}
37   virtual void Run() = 0;
38
39   bool Failed() const { return failed_; }
40   int AssertionFailures() const { return assertion_failures_; }
41   void AddAssertionFailure() { assertion_failures_++; }
42   bool Check(bool condition, const char* file, int line, const char* error);
43 };
44 }
45
46 void RegisterTest(testing::Test* (*)(), const char*);
47
48 extern testing::Test* g_current_test;
49 #define TEST_F_(x, y, name)                                           \
50   struct y : public x {                                               \
51     static testing::Test* Create() { return g_current_test = new y; } \
52     virtual void Run();                                               \
53   };                                                                  \
54   struct Register##y {                                                \
55     Register##y() { RegisterTest(y::Create, name); }                  \
56   };                                                                  \
57   Register##y g_register_##y;                                         \
58   void y::Run()
59
60 #define TEST_F(x, y) TEST_F_(x, x##y, #x "." #y)
61 #define TEST(x, y) TEST_F_(testing::Test, x##y, #x "." #y)
62
63 #define EXPECT_EQ(a, b) \
64   g_current_test->Check(a == b, __FILE__, __LINE__, #a " == " #b)
65 #define EXPECT_NE(a, b) \
66   g_current_test->Check(a != b, __FILE__, __LINE__, #a " != " #b)
67 #define EXPECT_GT(a, b) \
68   g_current_test->Check(a > b, __FILE__, __LINE__, #a " > " #b)
69 #define EXPECT_LT(a, b) \
70   g_current_test->Check(a < b, __FILE__, __LINE__, #a " < " #b)
71 #define EXPECT_GE(a, b) \
72   g_current_test->Check(a >= b, __FILE__, __LINE__, #a " >= " #b)
73 #define EXPECT_LE(a, b) \
74   g_current_test->Check(a <= b, __FILE__, __LINE__, #a " <= " #b)
75 #define EXPECT_TRUE(a) \
76   g_current_test->Check(static_cast<bool>(a), __FILE__, __LINE__, #a)
77 #define EXPECT_FALSE(a) \
78   g_current_test->Check(!static_cast<bool>(a), __FILE__, __LINE__, #a)
79
80 #define ASSERT_EQ(a, b) \
81   if (!EXPECT_EQ(a, b)) { g_current_test->AddAssertionFailure(); return; }
82 #define ASSERT_NE(a, b) \
83   if (!EXPECT_NE(a, b)) { g_current_test->AddAssertionFailure(); return; }
84 #define ASSERT_GT(a, b) \
85   if (!EXPECT_GT(a, b)) { g_current_test->AddAssertionFailure(); return; }
86 #define ASSERT_LT(a, b) \
87   if (!EXPECT_LT(a, b)) { g_current_test->AddAssertionFailure(); return; }
88 #define ASSERT_GE(a, b) \
89   if (!EXPECT_GE(a, b)) { g_current_test->AddAssertionFailure(); return; }
90 #define ASSERT_LE(a, b) \
91   if (!EXPECT_LE(a, b)) { g_current_test->AddAssertionFailure(); return; }
92 #define ASSERT_TRUE(a)  \
93   if (!EXPECT_TRUE(a))  { g_current_test->AddAssertionFailure(); return; }
94 #define ASSERT_FALSE(a) \
95   if (!EXPECT_FALSE(a)) { g_current_test->AddAssertionFailure(); return; }
96 #define ASSERT_NO_FATAL_FAILURE(a)                           \
97   {                                                          \
98     int fail_count = g_current_test->AssertionFailures();    \
99     a;                                                       \
100     if (fail_count != g_current_test->AssertionFailures()) { \
101       g_current_test->AddAssertionFailure();                 \
102       return;                                                \
103     }                                                        \
104   }
105
106 // Support utilites for tests.
107
108 struct Node;
109
110 /// A base test fixture that includes a State object with a
111 /// builtin "cat" rule.
112 struct StateTestWithBuiltinRules : public testing::Test {
113   StateTestWithBuiltinRules();
114
115   /// Add a "cat" rule to \a state.  Used by some tests; it's
116   /// otherwise done by the ctor to state_.
117   void AddCatRule(State* state);
118
119   /// Short way to get a Node by its path from state_.
120   Node* GetNode(const string& path);
121
122   State state_;
123 };
124
125 void AssertParse(State* state, const char* input);
126 void AssertHash(const char* expected, uint64_t actual);
127 void VerifyGraph(const State& state);
128
129 /// An implementation of DiskInterface that uses an in-memory representation
130 /// of disk state.  It also logs file accesses and directory creations
131 /// so it can be used by tests to verify disk access patterns.
132 struct VirtualFileSystem : public DiskInterface {
133   VirtualFileSystem() : now_(1) {}
134
135   /// "Create" a file with contents.
136   void Create(const string& path, const string& contents);
137
138   /// Tick "time" forwards; subsequent file operations will be newer than
139   /// previous ones.
140   int Tick() {
141     return ++now_;
142   }
143
144   // DiskInterface
145   virtual TimeStamp Stat(const string& path, string* err) const;
146   virtual bool WriteFile(const string& path, const string& contents);
147   virtual bool MakeDir(const string& path);
148   virtual Status ReadFile(const string& path, string* contents, string* err);
149   virtual int RemoveFile(const string& path);
150
151   /// An entry for a single in-memory file.
152   struct Entry {
153     int mtime;
154     string stat_error;  // If mtime is -1.
155     string contents;
156   };
157
158   vector<string> directories_made_;
159   vector<string> files_read_;
160   typedef map<string, Entry> FileMap;
161   FileMap files_;
162   set<string> files_removed_;
163   set<string> files_created_;
164
165   /// A simple fake timestamp for file operations.
166   int now_;
167 };
168
169 struct ScopedTempDir {
170   /// Create a temporary directory and chdir into it.
171   void CreateAndEnter(const string& name);
172
173   /// Clean up the temporary directory.
174   void Cleanup();
175
176   /// The temp directory containing our dir.
177   string start_dir_;
178   /// The subdirectory name for our dir, or empty if it hasn't been set up.
179   string temp_dir_name_;
180 };
181
182 #endif // NINJA_TEST_H_