diff options
author | Nico Weber <nicolasweber@gmx.de> | 2014-09-18 02:48:26 (GMT) |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2014-09-18 02:48:26 (GMT) |
commit | b2fe56caaf0bed497ee480003f10486c18d8de9a (patch) | |
tree | 8d32bf2472cb6fd4344650f24b38421221fcc738 /src/ninja_test.cc | |
parent | 1d9184c3adbfabacb844b0a715a64b08998c204f (diff) | |
download | Ninja-b2fe56caaf0bed497ee480003f10486c18d8de9a.zip Ninja-b2fe56caaf0bed497ee480003f10486c18d8de9a.tar.gz Ninja-b2fe56caaf0bed497ee480003f10486c18d8de9a.tar.bz2 |
Use a small, standalone testing framework instead of googletest.
Ninja currently uses googletest for testing. That makes building
ninja_test somewhat annoying since it requires that one passes
--with-gtest PATH to configure. It turns out just implementing the bits
of googletest that ninja uses needs about the same amount of code than
making the --with-gtest flag in configure.py work and making googletest
print test results in a way we want (!)
In addition to making configuration simpler, this also makes compiling
tests much faster: On my system, touching src/build_test.cc (the slowest
file to build in ninja) and rebuilding ninja_tests is twice as fast than
without this patch. Building all is noticeably faster too: 5.6s with
this patch, 9.1s without this patch (38% faster).
The most noticeable things missing: EXPECT_* and ASSERT_* don't support
streaming notes to them with operator<<, and for failing tests the lhs
and rhs are not printed. That's so that this header does not have to
include sstream, which slows down building ninja_test almost 20%.
If this turns out to be annoying, we can maybe add it.
Diffstat (limited to 'src/ninja_test.cc')
-rw-r--r-- | src/ninja_test.cc | 89 |
1 files changed, 40 insertions, 49 deletions
diff --git a/src/ninja_test.cc b/src/ninja_test.cc index 989ea5c..9499c8b 100644 --- a/src/ninja_test.cc +++ b/src/ninja_test.cc @@ -15,9 +15,22 @@ #include <stdarg.h> #include <stdio.h> -#include "gtest/gtest.h" +#include "test.h" #include "line_printer.h" +// This can't be a vector because tests call RegisterTest from static +// initializers and the order static initializers run it isn't specified. So +// the vector constructor isn't guaranteed to run before all of the +// RegisterTest() calls. +static testing::Test* (*tests[10000])(); +testing::Test* g_current_test; +static int ntests; +static LinePrinter printer; + +void RegisterTest(testing::Test* (*factory)()) { + tests[ntests++] = factory; +} + string StringPrintf(const char* format, ...) { const int N = 1024; char buf[N]; @@ -30,59 +43,37 @@ string StringPrintf(const char* format, ...) { return buf; } -/// A test result printer that's less wordy than gtest's default. -struct LaconicPrinter : public testing::EmptyTestEventListener { - LaconicPrinter() : tests_started_(0), test_count_(0), iteration_(0) {} - virtual void OnTestProgramStart(const testing::UnitTest& unit_test) { - test_count_ = unit_test.test_to_run_count(); - } - - virtual void OnTestIterationStart(const testing::UnitTest& test_info, - int iteration) { - tests_started_ = 0; - iteration_ = iteration; - } - - virtual void OnTestStart(const testing::TestInfo& test_info) { - ++tests_started_; - printer_.Print( - StringPrintf("[%d/%d%s] %s.%s", - tests_started_, - test_count_, - iteration_ ? StringPrintf(" iter %d", iteration_).c_str() - : "", - test_info.test_case_name(), - test_info.name()), - LinePrinter::ELIDE); +bool testing::Test::Check(bool condition, const char* file, int line, + const char* error) { + if (!condition) { + printer.PrintOnNewLine( + StringPrintf("*** Failure in %s:%d\n%s\n", file, line, error)); + failed_ = true; } + return condition; +} - virtual void OnTestPartResult( - const testing::TestPartResult& test_part_result) { - if (!test_part_result.failed()) - return; - printer_.PrintOnNewLine(StringPrintf( - "*** Failure in %s:%d\n%s\n", test_part_result.file_name(), - test_part_result.line_number(), test_part_result.summary())); - } +int main(int argc, char **argv) { + int tests_started = 0; - virtual void OnTestProgramEnd(const testing::UnitTest& unit_test) { - printer_.PrintOnNewLine(unit_test.Passed() ? "passed\n" : "failed\n"); - } + bool passed = true; + for (int i = 0; i < ntests; i++) { + ++tests_started; - private: - LinePrinter printer_; - int tests_started_; - int test_count_; - int iteration_; -}; + testing::Test* test = tests[i](); -int main(int argc, char **argv) { - testing::InitGoogleTest(&argc, argv); + printer.Print( + StringPrintf("[%d/%d] %s", tests_started, ntests, test->Name()), + LinePrinter::ELIDE); - testing::TestEventListeners& listeners = - testing::UnitTest::GetInstance()->listeners(); - delete listeners.Release(listeners.default_result_printer()); - listeners.Append(new LaconicPrinter); + test->SetUp(); + test->Run(); + test->TearDown(); + if (test->Failed()) + passed = false; + delete test; + } - return RUN_ALL_TESTS(); + printer.PrintOnNewLine(passed ? "passed\n" : "failed\n"); + return passed ? EXIT_SUCCESS : EXIT_FAILURE; } |