b40e1769c662f945ec5197120c1069250e95d50d
[platform/upstream/ninja.git] / src / ninja_test.cc
1 // Copyright 2013 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 #include <stdarg.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18
19 #ifdef _WIN32
20 #include "getopt.h"
21 #elif defined(_AIX)
22 #include "getopt.h"
23 #include <unistd.h>
24 #else
25 #include <getopt.h>
26 #endif
27
28 #include "test.h"
29 #include "line_printer.h"
30
31 using namespace std;
32
33 struct RegisteredTest {
34   testing::Test* (*factory)();
35   const char *name;
36   bool should_run;
37 };
38 // This can't be a vector because tests call RegisterTest from static
39 // initializers and the order static initializers run it isn't specified. So
40 // the vector constructor isn't guaranteed to run before all of the
41 // RegisterTest() calls.
42 static RegisteredTest tests[10000];
43 testing::Test* g_current_test;
44 static int ntests;
45 static LinePrinter printer;
46
47 void RegisterTest(testing::Test* (*factory)(), const char* name) {
48   tests[ntests].factory = factory;
49   tests[ntests++].name = name;
50 }
51
52 namespace {
53 string StringPrintf(const char* format, ...) {
54   const int N = 1024;
55   char buf[N];
56
57   va_list ap;
58   va_start(ap, format);
59   vsnprintf(buf, N, format, ap);
60   va_end(ap);
61
62   return buf;
63 }
64
65 void Usage() {
66   fprintf(stderr,
67 "usage: ninja_tests [options]\n"
68 "\n"
69 "options:\n"
70 "  --gtest_filter=POSTIVE_PATTERN[-NEGATIVE_PATTERN]\n"
71 "      Run tests whose names match the positive but not the negative pattern.\n"
72 "      '*' matches any substring. (gtest's ':', '?' are not implemented).\n");
73 }
74
75 bool PatternMatchesString(const char* pattern, const char* str) {
76   switch (*pattern) {
77     case '\0':
78     case '-': return *str == '\0';
79     case '*': return (*str != '\0' && PatternMatchesString(pattern, str + 1)) ||
80                      PatternMatchesString(pattern + 1, str);
81     default:  return *pattern == *str &&
82                      PatternMatchesString(pattern + 1, str + 1);
83   }
84 }
85
86 bool TestMatchesFilter(const char* test, const char* filter) {
87   // Split --gtest_filter at '-' into positive and negative filters.
88   const char* const dash = strchr(filter, '-');
89   const char* pos = dash == filter ? "*" : filter; //Treat '-test1' as '*-test1'
90   const char* neg = dash ? dash + 1 : "";
91   return PatternMatchesString(pos, test) && !PatternMatchesString(neg, test);
92 }
93
94 bool ReadFlags(int* argc, char*** argv, const char** test_filter) {
95   enum { OPT_GTEST_FILTER = 1 };
96   const option kLongOptions[] = {
97     { "gtest_filter", required_argument, NULL, OPT_GTEST_FILTER },
98     { NULL, 0, NULL, 0 }
99   };
100
101   int opt;
102   while ((opt = getopt_long(*argc, *argv, "h", kLongOptions, NULL)) != -1) {
103     switch (opt) {
104     case OPT_GTEST_FILTER:
105       if (strchr(optarg, '?') == NULL && strchr(optarg, ':') == NULL) {
106         *test_filter = optarg;
107         break;
108       }  // else fall through.
109     default:
110       Usage();
111       return false;
112     }
113   }
114   *argv += optind;
115   *argc -= optind;
116   return true;
117 }
118
119 }  // namespace
120
121 bool testing::Test::Check(bool condition, const char* file, int line,
122                           const char* error) {
123   if (!condition) {
124     printer.PrintOnNewLine(
125         StringPrintf("*** Failure in %s:%d\n%s\n", file, line, error));
126     failed_ = true;
127   }
128   return condition;
129 }
130
131 int main(int argc, char **argv) {
132   int tests_started = 0;
133
134   const char* test_filter = "*";
135   if (!ReadFlags(&argc, &argv, &test_filter))
136     return 1;
137
138   int nactivetests = 0;
139   for (int i = 0; i < ntests; i++)
140     if ((tests[i].should_run = TestMatchesFilter(tests[i].name, test_filter)))
141       ++nactivetests;
142
143   bool passed = true;
144   for (int i = 0; i < ntests; i++) {
145     if (!tests[i].should_run) continue;
146
147     ++tests_started;
148     testing::Test* test = tests[i].factory();
149     printer.Print(
150         StringPrintf("[%d/%d] %s", tests_started, nactivetests, tests[i].name),
151         LinePrinter::ELIDE);
152     test->SetUp();
153     test->Run();
154     test->TearDown();
155     if (test->Failed())
156       passed = false;
157     delete test;
158   }
159
160   printer.PrintOnNewLine(passed ? "passed\n" : "failed\n");
161   return passed ? EXIT_SUCCESS : EXIT_FAILURE;
162 }