From 94f999b681ea4ced1cc27b29e0db77d72554ecf9 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 8 Apr 2013 18:02:05 -0700 Subject: Make gtest output more silent, ninja issue #528. This is just a proof-of-concept. The terminal printing logic should be extracted from src/build.cc and then reused here. --- configure.py | 4 +--- src/ninja_test.cc | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 src/ninja_test.cc diff --git a/configure.py b/configure.py index 10c6994..3ea91f0 100755 --- a/configure.py +++ b/configure.py @@ -331,9 +331,6 @@ if options.with_gtest: objs += n.build(built('gtest-all' + objext), 'cxx', os.path.join(path, 'src', 'gtest-all.cc'), variables=[('cflags', gtest_cflags)]) - objs += n.build(built('gtest_main' + objext), 'cxx', - os.path.join(path, 'src', 'gtest_main.cc'), - variables=[('cflags', gtest_cflags)]) test_cflags.append('-I%s' % os.path.join(path, 'include')) else: @@ -353,6 +350,7 @@ for name in ['build_log_test', 'graph_test', 'lexer_test', 'manifest_parser_test', + 'ninja_test', 'state_test', 'subprocess_test', 'test', diff --git a/src/ninja_test.cc b/src/ninja_test.cc new file mode 100644 index 0000000..0e0f882 --- /dev/null +++ b/src/ninja_test.cc @@ -0,0 +1,54 @@ +#include "gtest/gtest.h" + +/// A test result printer that's less wordy than gtest's default. +class LaconicPrinter : public testing::EmptyTestEventListener { + public: + LaconicPrinter() : have_blank_line_(false), smart_terminal_(true) {} + + virtual void OnTestStart(const testing::TestInfo& test_info) { + printf("\r%s.%s starting.", test_info.test_case_name(), test_info.name()); + printf("\x1B[K"); // Clear to end of line. + fflush(stdout); + have_blank_line_ = false; + } + + virtual void OnTestPartResult( + const testing::TestPartResult& test_part_result) { + if (!test_part_result.failed()) + return; + if (!have_blank_line_ && smart_terminal_) + printf("\n"); + printf("*** Failure in %s:%d\n%s\n", + test_part_result.file_name(), + test_part_result.line_number(), + test_part_result.summary()); + have_blank_line_ = true; + } + + virtual void OnTestEnd(const testing::TestInfo& test_info) { + printf("\r%s.%s ending.", test_info.test_case_name(), test_info.name()); + printf("\x1B[K"); // Clear to end of line. + fflush(stdout); + have_blank_line_ = false; + } + + virtual void OnTestProgramEnd(const testing::UnitTest& unit_test) { + if (!have_blank_line_ && smart_terminal_) + printf("\n"); + } + + private: + bool have_blank_line_; + bool smart_terminal_; +}; + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + + testing::TestEventListeners& listeners = + testing::UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_result_printer()); + listeners.Append(new LaconicPrinter); + + return RUN_ALL_TESTS(); +} -- cgit v0.12 From 10d1c939ae788bfb410eb37c7e71da2be07797f9 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 8 Apr 2013 20:54:28 -0700 Subject: move single-line printing to new class --- configure.py | 1 + src/build.cc | 97 +++++----------------------------------------------- src/build.h | 7 ++-- src/line_printer.cc | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/line_printer.h | 37 ++++++++++++++++++++ src/ninja_test.cc | 14 ++++++++ 6 files changed, 162 insertions(+), 92 deletions(-) create mode 100644 src/line_printer.cc create mode 100644 src/line_printer.h diff --git a/configure.py b/configure.py index 3ea91f0..6db181c 100755 --- a/configure.py +++ b/configure.py @@ -276,6 +276,7 @@ for name in ['build', 'graph', 'graphviz', 'lexer', + 'line_printer', 'manifest_parser', 'metrics', 'state', diff --git a/src/build.cc b/src/build.cc index ae47a50..a98dfda 100644 --- a/src/build.cc +++ b/src/build.cc @@ -19,14 +19,6 @@ #include #include -#ifdef _WIN32 -#include -#else -#include -#include -#include -#endif - #if defined(__SVR4) && defined(__sun) #include #endif @@ -80,25 +72,12 @@ BuildStatus::BuildStatus(const BuildConfig& config) : config_(config), start_time_millis_(GetTimeMillis()), started_edges_(0), finished_edges_(0), total_edges_(0), - have_blank_line_(true), progress_status_format_(NULL), + progress_status_format_(NULL), overall_rate_(), current_rate_(config.parallelism) { -#ifndef _WIN32 - const char* term = getenv("TERM"); - smart_terminal_ = isatty(1) && term && string(term) != "dumb"; -#else - // Disable output buffer. It'd be nice to use line buffering but - // MSDN says: "For some systems, [_IOLBF] provides line - // buffering. However, for Win32, the behavior is the same as _IOFBF - // - Full Buffering." - setvbuf(stdout, NULL, _IONBF, 0); - console_ = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO csbi; - smart_terminal_ = GetConsoleScreenBufferInfo(console_, &csbi); -#endif // Don't do anything fancy in verbose mode. if (config_.verbosity != BuildConfig::NORMAL) - smart_terminal_ = false; + printer_.smart_terminal_ = false; progress_status_format_ = getenv("NINJA_STATUS"); if (!progress_status_format_) @@ -133,11 +112,11 @@ void BuildStatus::BuildEdgeFinished(Edge* edge, if (config_.verbosity == BuildConfig::QUIET) return; - if (smart_terminal_) + if (printer_.smart_terminal_) PrintStatus(edge); if (!success || !output.empty()) { - if (smart_terminal_) + if (printer_.smart_terminal_) printf("\n"); // Print the command that is spewing before printing its output. @@ -157,7 +136,7 @@ void BuildStatus::BuildEdgeFinished(Edge* edge, // thousands of parallel compile commands.) // TODO: There should be a flag to disable escape code stripping. string final_output; - if (!smart_terminal_) + if (!printer_.smart_terminal_) final_output = StripAnsiEscapeCodes(output); else final_output = output; @@ -165,12 +144,12 @@ void BuildStatus::BuildEdgeFinished(Edge* edge, if (!final_output.empty()) printf("%s", final_output.c_str()); - have_blank_line_ = true; + printer_.have_blank_line_ = true; } } void BuildStatus::BuildFinished() { - if (smart_terminal_ && !have_blank_line_) + if (printer_.smart_terminal_ && !printer_.have_blank_line_) printf("\n"); } @@ -267,72 +246,14 @@ void BuildStatus::PrintStatus(Edge* edge) { if (to_print.empty() || force_full_command) to_print = edge->GetBinding("command"); -#ifdef _WIN32 - CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo(console_, &csbi); -#endif - - if (smart_terminal_) { -#ifndef _WIN32 - printf("\r"); // Print over previous line, if any. -#else - csbi.dwCursorPosition.X = 0; - SetConsoleCursorPosition(console_, csbi.dwCursorPosition); -#endif - } - if (finished_edges_ == 0) { overall_rate_.Restart(); current_rate_.Restart(); } to_print = FormatProgressStatus(progress_status_format_) + to_print; - if (smart_terminal_ && !force_full_command) { -#ifndef _WIN32 - // Limit output to width of the terminal if provided so we don't cause - // line-wrapping. - winsize size; - if ((ioctl(0, TIOCGWINSZ, &size) == 0) && size.ws_col) { - to_print = ElideMiddle(to_print, size.ws_col); - } -#else - // Don't use the full width or console will move to next line. - size_t width = static_cast(csbi.dwSize.X) - 1; - to_print = ElideMiddle(to_print, width); -#endif - } - - if (smart_terminal_ && !force_full_command) { -#ifndef _WIN32 - printf("%s", to_print.c_str()); - printf("\x1B[K"); // Clear to end of line. - fflush(stdout); - have_blank_line_ = false; -#else - // We don't want to have the cursor spamming back and forth, so - // use WriteConsoleOutput instead which updates the contents of - // the buffer, but doesn't move the cursor position. - GetConsoleScreenBufferInfo(console_, &csbi); - COORD buf_size = { csbi.dwSize.X, 1 }; - COORD zero_zero = { 0, 0 }; - SMALL_RECT target = { csbi.dwCursorPosition.X, csbi.dwCursorPosition.Y, - (SHORT)(csbi.dwCursorPosition.X + csbi.dwSize.X - 1), - csbi.dwCursorPosition.Y }; - CHAR_INFO* char_data = new CHAR_INFO[csbi.dwSize.X]; - memset(char_data, 0, sizeof(CHAR_INFO) * csbi.dwSize.X); - for (int i = 0; i < csbi.dwSize.X; ++i) { - char_data[i].Char.AsciiChar = ' '; - char_data[i].Attributes = csbi.wAttributes; - } - for (size_t i = 0; i < to_print.size(); ++i) - char_data[i].Char.AsciiChar = to_print[i]; - WriteConsoleOutput(console_, char_data, buf_size, zero_zero, &target); - delete[] char_data; - have_blank_line_ = false; -#endif - } else { - printf("%s\n", to_print.c_str()); - } + printer_.Print(to_print, + force_full_command ? LinePrinter::FULL : LinePrinter::SHORT); } Plan::Plan() : command_edges_(0), wanted_edges_(0) {} diff --git a/src/build.h b/src/build.h index 5747170..52c277a 100644 --- a/src/build.h +++ b/src/build.h @@ -25,6 +25,7 @@ #include "graph.h" // XXX needed for DependencyScan; should rearrange. #include "exit_status.h" +#include "line_printer.h" #include "metrics.h" #include "util.h" // int64_t @@ -198,14 +199,12 @@ struct BuildStatus { int started_edges_, finished_edges_, total_edges_; - bool have_blank_line_; - /// Map of running edge to time the edge started running. typedef map RunningEdgeMap; RunningEdgeMap running_edges_; - /// Whether we can do fancy terminal control codes. - bool smart_terminal_; + /// Prints progress output. + LinePrinter printer_; /// The custom progress status format to use. const char* progress_status_format_; diff --git a/src/line_printer.cc b/src/line_printer.cc new file mode 100644 index 0000000..54f0a5b --- /dev/null +++ b/src/line_printer.cc @@ -0,0 +1,98 @@ +// Copyright 2013 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "line_printer.h" + +#ifdef _WIN32 +#include +#else +#include +#include +#include +#endif + +#include "util.h" + +LinePrinter::LinePrinter() : have_blank_line_(true) { +#ifndef _WIN32 + const char* term = getenv("TERM"); + smart_terminal_ = isatty(1) && term && string(term) != "dumb"; +#else + // Disable output buffer. It'd be nice to use line buffering but + // MSDN says: "For some systems, [_IOLBF] provides line + // buffering. However, for Win32, the behavior is the same as _IOFBF + // - Full Buffering." + setvbuf(stdout, NULL, _IONBF, 0); + console_ = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO csbi; + smart_terminal_ = GetConsoleScreenBufferInfo(console_, &csbi); +#endif +} + +void LinePrinter::Print(std::string to_print, LineType type) { +#ifdef _WIN32 + CONSOLE_SCREEN_BUFFER_INFO csbi; + GetConsoleScreenBufferInfo(console_, &csbi); +#endif + + if (smart_terminal_) { +#ifndef _WIN32 + printf("\r"); // Print over previous line, if any. +#else + csbi.dwCursorPosition.X = 0; + SetConsoleCursorPosition(console_, csbi.dwCursorPosition); +#endif + } + + if (smart_terminal_ && type == SHORT) { +#ifdef _WIN32 + // Don't use the full width or console will move to next line. + size_t width = static_cast(csbi.dwSize.X) - 1; + to_print = ElideMiddle(to_print, width); + // We don't want to have the cursor spamming back and forth, so + // use WriteConsoleOutput instead which updates the contents of + // the buffer, but doesn't move the cursor position. + GetConsoleScreenBufferInfo(console_, &csbi); + COORD buf_size = { csbi.dwSize.X, 1 }; + COORD zero_zero = { 0, 0 }; + SMALL_RECT target = { csbi.dwCursorPosition.X, csbi.dwCursorPosition.Y, + (SHORT)(csbi.dwCursorPosition.X + csbi.dwSize.X - 1), + csbi.dwCursorPosition.Y }; + CHAR_INFO* char_data = new CHAR_INFO[csbi.dwSize.X]; + memset(char_data, 0, sizeof(CHAR_INFO) * csbi.dwSize.X); + for (int i = 0; i < csbi.dwSize.X; ++i) { + char_data[i].Char.AsciiChar = ' '; + char_data[i].Attributes = csbi.wAttributes; + } + for (size_t i = 0; i < to_print.size(); ++i) + char_data[i].Char.AsciiChar = to_print[i]; + WriteConsoleOutput(console_, char_data, buf_size, zero_zero, &target); + delete[] char_data; +#else + // Limit output to width of the terminal if provided so we don't cause + // line-wrapping. + winsize size; + if ((ioctl(0, TIOCGWINSZ, &size) == 0) && size.ws_col) { + to_print = ElideMiddle(to_print, size.ws_col); + } + printf("%s", to_print.c_str()); + printf("\x1B[K"); // Clear to end of line. + fflush(stdout); +#endif + + have_blank_line_ = false; + } else { + printf("%s\n", to_print.c_str()); + } +} diff --git a/src/line_printer.h b/src/line_printer.h new file mode 100644 index 0000000..6002667 --- /dev/null +++ b/src/line_printer.h @@ -0,0 +1,37 @@ +// Copyright 2013 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef NINJA_LINE_PRINTER_H_ +#define NINJA_LINE_PRINTER_H_ + +#include + +class LinePrinter { + public: + LinePrinter(); + + enum LineType { + FULL, + SHORT + }; + void Print(std::string to_print, LineType type); + + //private: + /// Whether we can do fancy terminal control codes. + bool smart_terminal_; + + bool have_blank_line_; +}; + +#endif // NINJA_LINE_PRINTER_H_ diff --git a/src/ninja_test.cc b/src/ninja_test.cc index 0e0f882..f257ee3 100644 --- a/src/ninja_test.cc +++ b/src/ninja_test.cc @@ -1,3 +1,17 @@ +// Copyright 2013 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "gtest/gtest.h" /// A test result printer that's less wordy than gtest's default. -- cgit v0.12 From 7920d7032a8833004fc281fb5b090787888d0fd0 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 8 Apr 2013 21:11:34 -0700 Subject: refactor; no intended functionality change --- src/build.cc | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/build.cc b/src/build.cc index a98dfda..efa4559 100644 --- a/src/build.cc +++ b/src/build.cc @@ -115,13 +115,18 @@ void BuildStatus::BuildEdgeFinished(Edge* edge, if (printer_.smart_terminal_) PrintStatus(edge); - if (!success || !output.empty()) { - if (printer_.smart_terminal_) + if (!success) { + if (!printer_.have_blank_line_) printf("\n"); // Print the command that is spewing before printing its output. - if (!success) - printf("FAILED: %s\n", edge->EvaluateCommand().c_str()); + printf("FAILED: %s\n", edge->EvaluateCommand().c_str()); + printer_.have_blank_line_ = true; + } + + if (!output.empty()) { + if (!printer_.have_blank_line_) + printf("\n"); // ninja sets stdout and stderr of subprocesses to a pipe, to be able to // check if the output is empty. Some compilers, e.g. clang, check @@ -141,10 +146,11 @@ void BuildStatus::BuildEdgeFinished(Edge* edge, else final_output = output; - if (!final_output.empty()) + if (!final_output.empty()) { printf("%s", final_output.c_str()); - - printer_.have_blank_line_ = true; + if (*final_output.rbegin() == '\n') + printer_.have_blank_line_ = true; + } } } -- cgit v0.12 From f872a912c57879767a7715094790aa4380badce2 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 8 Apr 2013 21:14:29 -0700 Subject: move printing of new lines into LinePrinter. --- src/build.cc | 24 +++++------------------- src/line_printer.cc | 7 +++++++ src/line_printer.h | 2 ++ 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/build.cc b/src/build.cc index efa4559..4ed586f 100644 --- a/src/build.cc +++ b/src/build.cc @@ -115,19 +115,11 @@ void BuildStatus::BuildEdgeFinished(Edge* edge, if (printer_.smart_terminal_) PrintStatus(edge); - if (!success) { - if (!printer_.have_blank_line_) - printf("\n"); - - // Print the command that is spewing before printing its output. - printf("FAILED: %s\n", edge->EvaluateCommand().c_str()); - printer_.have_blank_line_ = true; - } + // Print the command that is spewing before printing its output. + if (!success) + printer_.PrintOnNewLine("FAILED: " + edge->EvaluateCommand() + "\n"); if (!output.empty()) { - if (!printer_.have_blank_line_) - printf("\n"); - // ninja sets stdout and stderr of subprocesses to a pipe, to be able to // check if the output is empty. Some compilers, e.g. clang, check // isatty(stderr) to decide if they should print colored output. @@ -145,18 +137,12 @@ void BuildStatus::BuildEdgeFinished(Edge* edge, final_output = StripAnsiEscapeCodes(output); else final_output = output; - - if (!final_output.empty()) { - printf("%s", final_output.c_str()); - if (*final_output.rbegin() == '\n') - printer_.have_blank_line_ = true; - } + printer_.PrintOnNewLine(final_output); } } void BuildStatus::BuildFinished() { - if (printer_.smart_terminal_ && !printer_.have_blank_line_) - printf("\n"); + printer_.PrintOnNewLine(""); } string BuildStatus::FormatProgressStatus( diff --git a/src/line_printer.cc b/src/line_printer.cc index 54f0a5b..bfa737e 100644 --- a/src/line_printer.cc +++ b/src/line_printer.cc @@ -96,3 +96,10 @@ void LinePrinter::Print(std::string to_print, LineType type) { printf("%s\n", to_print.c_str()); } } + +void LinePrinter::PrintOnNewLine(const string& to_print) { + if (!have_blank_line_) + printf("\n"); + printf("%s", to_print.c_str()); + have_blank_line_ = to_print.empty() || *to_print.rbegin() == '\n'; +} diff --git a/src/line_printer.h b/src/line_printer.h index 6002667..b3cb163 100644 --- a/src/line_printer.h +++ b/src/line_printer.h @@ -27,6 +27,8 @@ class LinePrinter { }; void Print(std::string to_print, LineType type); + void PrintOnNewLine(const std::string& to_print); + //private: /// Whether we can do fancy terminal control codes. bool smart_terminal_; -- cgit v0.12 From a95b0819703aefc6a4f74004d6639f2cebd1e5d2 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 8 Apr 2013 21:19:27 -0700 Subject: Make LinePrinter members private, add comments. --- src/build.cc | 6 +++--- src/line_printer.h | 11 ++++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/build.cc b/src/build.cc index 4ed586f..340a3d9 100644 --- a/src/build.cc +++ b/src/build.cc @@ -77,7 +77,7 @@ BuildStatus::BuildStatus(const BuildConfig& config) // Don't do anything fancy in verbose mode. if (config_.verbosity != BuildConfig::NORMAL) - printer_.smart_terminal_ = false; + printer_.set_smart_terminal(false); progress_status_format_ = getenv("NINJA_STATUS"); if (!progress_status_format_) @@ -112,7 +112,7 @@ void BuildStatus::BuildEdgeFinished(Edge* edge, if (config_.verbosity == BuildConfig::QUIET) return; - if (printer_.smart_terminal_) + if (printer_.is_smart_terminal()) PrintStatus(edge); // Print the command that is spewing before printing its output. @@ -133,7 +133,7 @@ void BuildStatus::BuildEdgeFinished(Edge* edge, // thousands of parallel compile commands.) // TODO: There should be a flag to disable escape code stripping. string final_output; - if (!printer_.smart_terminal_) + if (!printer_.is_smart_terminal()) final_output = StripAnsiEscapeCodes(output); else final_output = output; diff --git a/src/line_printer.h b/src/line_printer.h index b3cb163..78510ea 100644 --- a/src/line_printer.h +++ b/src/line_printer.h @@ -17,22 +17,31 @@ #include +/// Prints lines of text, possibly overprinting previously printed lines +/// if the terminal supports it. class LinePrinter { public: LinePrinter(); + bool is_smart_terminal() const { return smart_terminal_; } + void set_smart_terminal(bool smart) { smart_terminal_ = smart; } + enum LineType { FULL, SHORT }; + /// Overprints the current line. If type is SHORT, elides to_print to fit on + /// one line. void Print(std::string to_print, LineType type); + /// Prints a string on a new line, not overprinting previous output. void PrintOnNewLine(const std::string& to_print); - //private: + private: /// Whether we can do fancy terminal control codes. bool smart_terminal_; + /// Whether the caret is at the beginning of a blank line. bool have_blank_line_; }; -- cgit v0.12 From 6c274da149719fd13150ab0f1f853c524e128f1e Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 8 Apr 2013 21:28:12 -0700 Subject: Use LinePrinter in test runner. --- src/ninja_test.cc | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/ninja_test.cc b/src/ninja_test.cc index f257ee3..5808e39 100644 --- a/src/ninja_test.cc +++ b/src/ninja_test.cc @@ -14,46 +14,48 @@ #include "gtest/gtest.h" +#include "line_printer.h" + +std::string StringPrintf(const char* format, ...) { + const int N = 1024; + char buf[N]; + + va_list ap; + va_start(ap, format); + vsnprintf(buf, N, format, ap); + va_end(ap); + + return buf; +} + /// A test result printer that's less wordy than gtest's default. class LaconicPrinter : public testing::EmptyTestEventListener { public: - LaconicPrinter() : have_blank_line_(false), smart_terminal_(true) {} - virtual void OnTestStart(const testing::TestInfo& test_info) { - printf("\r%s.%s starting.", test_info.test_case_name(), test_info.name()); - printf("\x1B[K"); // Clear to end of line. - fflush(stdout); - have_blank_line_ = false; + printer_.Print(StringPrintf("%s.%s starting", test_info.test_case_name(), + test_info.name()), LinePrinter::SHORT); } virtual void OnTestPartResult( const testing::TestPartResult& test_part_result) { if (!test_part_result.failed()) return; - if (!have_blank_line_ && smart_terminal_) - printf("\n"); - printf("*** Failure in %s:%d\n%s\n", - test_part_result.file_name(), - test_part_result.line_number(), - test_part_result.summary()); - have_blank_line_ = true; + printer_.PrintOnNewLine(StringPrintf( + "*** Failure in %s:%d\n%s\n", test_part_result.file_name(), + test_part_result.line_number(), test_part_result.summary())); } virtual void OnTestEnd(const testing::TestInfo& test_info) { - printf("\r%s.%s ending.", test_info.test_case_name(), test_info.name()); - printf("\x1B[K"); // Clear to end of line. - fflush(stdout); - have_blank_line_ = false; + printer_.Print(StringPrintf("%s.%s ending", test_info.test_case_name(), + test_info.name()), LinePrinter::SHORT); } virtual void OnTestProgramEnd(const testing::UnitTest& unit_test) { - if (!have_blank_line_ && smart_terminal_) - printf("\n"); + printer_.PrintOnNewLine(""); } private: - bool have_blank_line_; - bool smart_terminal_; + LinePrinter printer_; }; int main(int argc, char **argv) { -- cgit v0.12 From 45fc9492718aab1256152edc112671214587f020 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 8 Apr 2013 21:41:50 -0700 Subject: Make ninja_test output nicer. --- src/ninja_test.cc | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/ninja_test.cc b/src/ninja_test.cc index 5808e39..8e431ab 100644 --- a/src/ninja_test.cc +++ b/src/ninja_test.cc @@ -31,9 +31,16 @@ std::string StringPrintf(const char* format, ...) { /// A test result printer that's less wordy than gtest's default. class LaconicPrinter : public testing::EmptyTestEventListener { public: + LaconicPrinter() : tests_started_(0), test_count_(0) {} + virtual void OnTestProgramStart(const testing::UnitTest& unit_test) { + test_count_ = unit_test.test_to_run_count(); + } + virtual void OnTestStart(const testing::TestInfo& test_info) { - printer_.Print(StringPrintf("%s.%s starting", test_info.test_case_name(), - test_info.name()), LinePrinter::SHORT); + ++tests_started_; + printer_.Print(StringPrintf("[%d/%d] %s.%s", tests_started_, test_count_, + test_info.test_case_name(), test_info.name()), + LinePrinter::SHORT); } virtual void OnTestPartResult( @@ -45,17 +52,14 @@ class LaconicPrinter : public testing::EmptyTestEventListener { test_part_result.line_number(), test_part_result.summary())); } - virtual void OnTestEnd(const testing::TestInfo& test_info) { - printer_.Print(StringPrintf("%s.%s ending", test_info.test_case_name(), - test_info.name()), LinePrinter::SHORT); - } - virtual void OnTestProgramEnd(const testing::UnitTest& unit_test) { - printer_.PrintOnNewLine(""); + printer_.PrintOnNewLine(unit_test.Passed() ? "passed\n" : "failed\n"); } private: LinePrinter printer_; + int tests_started_; + int test_count_; }; int main(int argc, char **argv) { -- cgit v0.12 From 88013d2f407d8948f9a2d6dc2f80e99e12f8adbf Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 8 Apr 2013 21:48:51 -0700 Subject: Try to fix build on Linux. --- src/line_printer.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/line_printer.cc b/src/line_printer.cc index bfa737e..d30dd2c 100644 --- a/src/line_printer.cc +++ b/src/line_printer.cc @@ -14,6 +14,8 @@ #include "line_printer.h" +#include +#include #ifdef _WIN32 #include #else -- cgit v0.12 From 5b04aadbb2051a613b4a3fe28e21eb4527f2952f Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 8 Apr 2013 21:53:25 -0700 Subject: Try to fix build on Linux more. --- src/ninja_test.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ninja_test.cc b/src/ninja_test.cc index 8e431ab..3376050 100644 --- a/src/ninja_test.cc +++ b/src/ninja_test.cc @@ -12,8 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "gtest/gtest.h" +#include +#include +#include "gtest/gtest.h" #include "line_printer.h" std::string StringPrintf(const char* format, ...) { -- cgit v0.12