MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tap_event_listener.cc
1 /* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 // First include (the generated) my_config.h, to get correct platform defines.
17 #include "my_config.h"
18 #include <gtest/gtest.h>
19 
20 #include <stdarg.h>
21 #include <string>
22 #include <sstream>
23 
24 using testing::TestEventListeners;
25 using testing::TestCase;
26 using testing::TestEventListener;
27 using testing::TestInfo;
28 using testing::TestPartResult;
29 using testing::UnitTest;
30 
31 
38 class TapEventListener : public TestEventListener
39 {
40 public:
41  TapEventListener() : m_test_number(0) {}
42  virtual ~TapEventListener() {}
43 
44  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
45  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
46  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
47  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
48  virtual void OnTestCaseStart(const TestCase& test_case);
49  virtual void OnTestStart(const TestInfo& test_info);
50  virtual void OnTestPartResult(const TestPartResult& test_part_result);
51  virtual void OnTestEnd(const TestInfo& test_info);
52  virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {};
53  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
54  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
55  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
56  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
57 private:
58  int m_test_number;
59  std::string m_test_case_name;
60 };
61 
62 
66 static void tap_diagnostic_printf(const std::stringstream &str_stream)
67 {
68  std::string message= str_stream.str();
69  size_t pos = 0;
70  while((pos = message.find("\n", pos)) != std::string::npos)
71  {
72  message.replace(pos, 1, "\n# ");
73  pos += 1;
74  }
75  printf("# %s\n", message.c_str());
76  fflush(stdout);
77 }
78 
79 // Convenience wrapper function.
80 static void tap_diagnostic_printf(const std::string &txt)
81 {
82  std::stringstream str_str;
83  str_str << txt;
84  tap_diagnostic_printf(str_str);
85 }
86 
87 // Convenience wrapper function.
88 static void tap_diagnostic_printf(const char *txt)
89 {
90  tap_diagnostic_printf(std::string(txt));
91 }
92 
93 
94 namespace {
95 // Helper struct to simplify output of "1 test" or "n tests".
96 struct num_tests
97 {
98  num_tests(int num) : m_num(num) {}
99  int m_num;
100 };
101 
102 std::ostream &operator<< (std::ostream &s, const num_tests &num)
103 {
104  return s << num.m_num << (num.m_num == 1 ? " test" : " tests");
105 }
106 
107 // Helper struct to simplify output of "1 test case" or "n test cases".
108 struct num_test_cases
109 {
110  num_test_cases(int num) : m_num(num) {}
111  int m_num;
112 };
113 
114 std::ostream &operator<< (std::ostream &s, const num_test_cases &num)
115 {
116  return s << num.m_num << (num.m_num == 1 ? " test case" : " test cases");
117 }
118 } // namespace
119 
120 
125 static std::string test_part_result_type_tostring(TestPartResult::Type type)
126 {
127  switch (type)
128  {
129  case TestPartResult::kSuccess:
130  return "Success";
131 
132  case TestPartResult::kNonFatalFailure:
133  case TestPartResult::kFatalFailure:
134  return "Failure";
135  }
136  return "";
137 }
138 
139 
144 static std::string format_file_location(const TestPartResult &test_part_result)
145 {
146  const char* const file= test_part_result.file_name();
147  const char* const file_name = file == NULL ? "unknown file" : file;
148  const int line= test_part_result.line_number();
149  std::stringstream str_stream;
150  str_stream << file_name << ":";
151  if (line >= 0)
152  str_stream << line << ":";
153  return str_stream.str();
154 }
155 
156 
160 static std::string test_part_result_tostring(const TestPartResult
161  &test_part_result)
162 {
163  return format_file_location(test_part_result)
164  + " "
165  + test_part_result_type_tostring(test_part_result.type())
166  + test_part_result.message();
167 }
168 
169 
170 void TapEventListener::OnTestIterationStart(const UnitTest& unit_test,
171  int iteration)
172 {
173  std::stringstream str_stream;
174  str_stream << "Running " << num_tests(unit_test.test_to_run_count())
175  << " from " << num_test_cases(unit_test.test_case_to_run_count());
176  tap_diagnostic_printf(str_stream);
177  printf("%d..%d\n", 1, unit_test.test_to_run_count());
178  fflush(stdout);
179 }
180 
181 
182 void TapEventListener::OnEnvironmentsSetUpStart(const UnitTest& unit_test)
183 {
184  tap_diagnostic_printf("Global test environment set-up");
185 }
186 
187 
188 void TapEventListener::OnTestCaseStart(const TestCase& test_case)
189 {
190  m_test_case_name = test_case.name();
191 }
192 
193 
194 void TapEventListener::OnTestStart(const TestInfo& test_info)
195 {
196  ++m_test_number;
197  std::stringstream str_stream;
198  str_stream << "Run " << m_test_number << " "
199  << m_test_case_name << "." << test_info.name();
200  tap_diagnostic_printf(str_stream);
201 }
202 
203 
204 void TapEventListener::OnTestPartResult(const TestPartResult& test_part_result)
205 {
206  if (test_part_result.passed())
207  return;
208  // Don't prefix error messages with #, as the tap harness will hide them!
209  fprintf(stderr, "%s\n", test_part_result_tostring(test_part_result).c_str());
210 }
211 
212 
213 void TapEventListener::OnTestEnd(const TestInfo& test_info)
214 {
215  if (test_info.result()->Passed())
216  printf("ok %d\n", m_test_number);
217  else
218  printf("not ok %d\n", m_test_number);
219  fflush(stdout);
220 }
221 
222 
223 void TapEventListener::OnEnvironmentsTearDownStart(const UnitTest& unit_test)
224 {
225  tap_diagnostic_printf("Global test environment tear-down");
226 }
227 
228 
229 void TapEventListener::OnTestIterationEnd(const UnitTest& unit_test,
230  int iteration)
231 {
232  std::stringstream str_stream;
233  str_stream << "Ran " << num_tests(unit_test.test_to_run_count())
234  << " from " << num_test_cases(unit_test.test_case_to_run_count())
235  << "\n"
236  << "Passed " << num_tests(unit_test.successful_test_count());
237 
238  if (!unit_test.Passed())
239  str_stream << "\n"
240  << "Failed " << num_tests(unit_test.failed_test_count());
241 
242  const int num_disabled = unit_test.disabled_test_count();
243  if (num_disabled && !testing::GTEST_FLAG(also_run_disabled_tests))
244  str_stream << "\n"
245  << "YOU HAVE " << num_disabled << " DISABLED "
246  << (num_disabled == 1 ? "TEST" : "TESTS");
247 
248  tap_diagnostic_printf(str_stream);
249 }
250 
251 
256 void install_tap_listener()
257 {
258  TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
259  delete listeners.Release(listeners.default_result_printer());
260  listeners.Append(new TapEventListener);
261 }