1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// http://code.google.com/p/protobuf/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9//     * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11//     * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15//     * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// Author: kenton@google.com (Kenton Varda)
32
33#include <vector>
34#include <google/protobuf/stubs/common.h>
35#include <google/protobuf/stubs/strutil.h>
36#include <google/protobuf/stubs/substitute.h>
37
38#include <google/protobuf/testing/googletest.h>
39#include <gtest/gtest.h>
40
41#include "config.h"
42
43namespace google {
44namespace protobuf {
45namespace {
46
47// TODO(kenton):  More tests.
48
49#ifdef PACKAGE_VERSION  // only defined when using automake, not MSVC
50
51TEST(VersionTest, VersionMatchesConfig) {
52  // Verify that the version string specified in config.h matches the one
53  // in common.h.  The config.h version is a string which may have a suffix
54  // like "beta" or "rc1", so we remove that.
55  string version = PACKAGE_VERSION;
56  int pos = 0;
57  while (pos < version.size() &&
58         (ascii_isdigit(version[pos]) || version[pos] == '.')) {
59    ++pos;
60  }
61  version.erase(pos);
62
63  EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION));
64}
65
66#endif  // PACKAGE_VERSION
67
68TEST(CommonTest, IntMinMaxConstants) {
69  // kint32min was declared incorrectly in the first release of protobufs.
70  // Ugh.
71  EXPECT_LT(kint32min, kint32max);
72  EXPECT_EQ(static_cast<uint32>(kint32min), static_cast<uint32>(kint32max) + 1);
73  EXPECT_LT(kint64min, kint64max);
74  EXPECT_EQ(static_cast<uint64>(kint64min), static_cast<uint64>(kint64max) + 1);
75  EXPECT_EQ(0, kuint32max + 1);
76  EXPECT_EQ(0, kuint64max + 1);
77}
78
79vector<string> captured_messages_;
80
81void CaptureLog(LogLevel level, const char* filename, int line,
82                const string& message) {
83  captured_messages_.push_back(
84    strings::Substitute("$0 $1:$2: $3",
85      implicit_cast<int>(level), filename, line, message));
86}
87
88TEST(LoggingTest, DefaultLogging) {
89  CaptureTestStderr();
90  int line = __LINE__;
91  GOOGLE_LOG(INFO   ) << "A message.";
92  GOOGLE_LOG(WARNING) << "A warning.";
93  GOOGLE_LOG(ERROR  ) << "An error.";
94
95  string text = GetCapturedTestStderr();
96  EXPECT_EQ(
97    "libprotobuf INFO "__FILE__":" + SimpleItoa(line + 1) + "] A message.\n"
98    "libprotobuf WARNING "__FILE__":" + SimpleItoa(line + 2) + "] A warning.\n"
99    "libprotobuf ERROR "__FILE__":" + SimpleItoa(line + 3) + "] An error.\n",
100    text);
101}
102
103TEST(LoggingTest, NullLogging) {
104  LogHandler* old_handler = SetLogHandler(NULL);
105
106  CaptureTestStderr();
107  GOOGLE_LOG(INFO   ) << "A message.";
108  GOOGLE_LOG(WARNING) << "A warning.";
109  GOOGLE_LOG(ERROR  ) << "An error.";
110
111  EXPECT_TRUE(SetLogHandler(old_handler) == NULL);
112
113  string text = GetCapturedTestStderr();
114  EXPECT_EQ("", text);
115}
116
117TEST(LoggingTest, CaptureLogging) {
118  captured_messages_.clear();
119
120  LogHandler* old_handler = SetLogHandler(&CaptureLog);
121
122  int start_line = __LINE__;
123  GOOGLE_LOG(ERROR) << "An error.";
124  GOOGLE_LOG(WARNING) << "A warning.";
125
126  EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
127
128  ASSERT_EQ(2, captured_messages_.size());
129  EXPECT_EQ(
130    "2 "__FILE__":" + SimpleItoa(start_line + 1) + ": An error.",
131    captured_messages_[0]);
132  EXPECT_EQ(
133    "1 "__FILE__":" + SimpleItoa(start_line + 2) + ": A warning.",
134    captured_messages_[1]);
135}
136
137TEST(LoggingTest, SilenceLogging) {
138  captured_messages_.clear();
139
140  LogHandler* old_handler = SetLogHandler(&CaptureLog);
141
142  int line1 = __LINE__; GOOGLE_LOG(INFO) << "Visible1";
143  LogSilencer* silencer1 = new LogSilencer;
144  GOOGLE_LOG(INFO) << "Not visible.";
145  LogSilencer* silencer2 = new LogSilencer;
146  GOOGLE_LOG(INFO) << "Not visible.";
147  delete silencer1;
148  GOOGLE_LOG(INFO) << "Not visible.";
149  delete silencer2;
150  int line2 = __LINE__; GOOGLE_LOG(INFO) << "Visible2";
151
152  EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
153
154  ASSERT_EQ(2, captured_messages_.size());
155  EXPECT_EQ(
156    "0 "__FILE__":" + SimpleItoa(line1) + ": Visible1",
157    captured_messages_[0]);
158  EXPECT_EQ(
159    "0 "__FILE__":" + SimpleItoa(line2) + ": Visible2",
160    captured_messages_[1]);
161}
162
163class ClosureTest : public testing::Test {
164 public:
165  void SetA123Method()   { a_ = 123; }
166  static void SetA123Function() { current_instance_->a_ = 123; }
167
168  void SetAMethod(int a)         { a_ = a; }
169  void SetCMethod(string c)      { c_ = c; }
170
171  static void SetAFunction(int a)         { current_instance_->a_ = a; }
172  static void SetCFunction(string c)      { current_instance_->c_ = c; }
173
174  void SetABMethod(int a, const char* b)  { a_ = a; b_ = b; }
175  static void SetABFunction(int a, const char* b) {
176    current_instance_->a_ = a;
177    current_instance_->b_ = b;
178  }
179
180  virtual void SetUp() {
181    current_instance_ = this;
182    a_ = 0;
183    b_ = NULL;
184    c_.clear();
185  }
186
187  int a_;
188  const char* b_;
189  string c_;
190
191  static ClosureTest* current_instance_;
192};
193
194ClosureTest* ClosureTest::current_instance_ = NULL;
195
196TEST_F(ClosureTest, TestClosureFunction0) {
197  Closure* closure = NewCallback(&SetA123Function);
198  EXPECT_NE(123, a_);
199  closure->Run();
200  EXPECT_EQ(123, a_);
201}
202
203TEST_F(ClosureTest, TestClosureMethod0) {
204  Closure* closure = NewCallback(current_instance_,
205                                 &ClosureTest::SetA123Method);
206  EXPECT_NE(123, a_);
207  closure->Run();
208  EXPECT_EQ(123, a_);
209}
210
211TEST_F(ClosureTest, TestClosureFunction1) {
212  Closure* closure = NewCallback(&SetAFunction, 456);
213  EXPECT_NE(456, a_);
214  closure->Run();
215  EXPECT_EQ(456, a_);
216}
217
218TEST_F(ClosureTest, TestClosureMethod1) {
219  Closure* closure = NewCallback(current_instance_,
220                                 &ClosureTest::SetAMethod, 456);
221  EXPECT_NE(456, a_);
222  closure->Run();
223  EXPECT_EQ(456, a_);
224}
225
226TEST_F(ClosureTest, TestClosureFunction1String) {
227  Closure* closure = NewCallback(&SetCFunction, string("test"));
228  EXPECT_NE("test", c_);
229  closure->Run();
230  EXPECT_EQ("test", c_);
231}
232
233TEST_F(ClosureTest, TestClosureMethod1String) {
234  Closure* closure = NewCallback(current_instance_,
235                                 &ClosureTest::SetCMethod, string("test"));
236  EXPECT_NE("test", c_);
237  closure->Run();
238  EXPECT_EQ("test", c_);
239}
240
241TEST_F(ClosureTest, TestClosureFunction2) {
242  const char* cstr = "hello";
243  Closure* closure = NewCallback(&SetABFunction, 789, cstr);
244  EXPECT_NE(789, a_);
245  EXPECT_NE(cstr, b_);
246  closure->Run();
247  EXPECT_EQ(789, a_);
248  EXPECT_EQ(cstr, b_);
249}
250
251TEST_F(ClosureTest, TestClosureMethod2) {
252  const char* cstr = "hello";
253  Closure* closure = NewCallback(current_instance_,
254                                 &ClosureTest::SetABMethod, 789, cstr);
255  EXPECT_NE(789, a_);
256  EXPECT_NE(cstr, b_);
257  closure->Run();
258  EXPECT_EQ(789, a_);
259  EXPECT_EQ(cstr, b_);
260}
261
262// Repeat all of the above with NewPermanentCallback()
263
264TEST_F(ClosureTest, TestPermanentClosureFunction0) {
265  Closure* closure = NewPermanentCallback(&SetA123Function);
266  EXPECT_NE(123, a_);
267  closure->Run();
268  EXPECT_EQ(123, a_);
269  a_ = 0;
270  closure->Run();
271  EXPECT_EQ(123, a_);
272  delete closure;
273}
274
275TEST_F(ClosureTest, TestPermanentClosureMethod0) {
276  Closure* closure = NewPermanentCallback(current_instance_,
277                                          &ClosureTest::SetA123Method);
278  EXPECT_NE(123, a_);
279  closure->Run();
280  EXPECT_EQ(123, a_);
281  a_ = 0;
282  closure->Run();
283  EXPECT_EQ(123, a_);
284  delete closure;
285}
286
287TEST_F(ClosureTest, TestPermanentClosureFunction1) {
288  Closure* closure = NewPermanentCallback(&SetAFunction, 456);
289  EXPECT_NE(456, a_);
290  closure->Run();
291  EXPECT_EQ(456, a_);
292  a_ = 0;
293  closure->Run();
294  EXPECT_EQ(456, a_);
295  delete closure;
296}
297
298TEST_F(ClosureTest, TestPermanentClosureMethod1) {
299  Closure* closure = NewPermanentCallback(current_instance_,
300                                          &ClosureTest::SetAMethod, 456);
301  EXPECT_NE(456, a_);
302  closure->Run();
303  EXPECT_EQ(456, a_);
304  a_ = 0;
305  closure->Run();
306  EXPECT_EQ(456, a_);
307  delete closure;
308}
309
310TEST_F(ClosureTest, TestPermanentClosureFunction2) {
311  const char* cstr = "hello";
312  Closure* closure = NewPermanentCallback(&SetABFunction, 789, cstr);
313  EXPECT_NE(789, a_);
314  EXPECT_NE(cstr, b_);
315  closure->Run();
316  EXPECT_EQ(789, a_);
317  EXPECT_EQ(cstr, b_);
318  a_ = 0;
319  b_ = NULL;
320  closure->Run();
321  EXPECT_EQ(789, a_);
322  EXPECT_EQ(cstr, b_);
323  delete closure;
324}
325
326TEST_F(ClosureTest, TestPermanentClosureMethod2) {
327  const char* cstr = "hello";
328  Closure* closure = NewPermanentCallback(current_instance_,
329                                          &ClosureTest::SetABMethod, 789, cstr);
330  EXPECT_NE(789, a_);
331  EXPECT_NE(cstr, b_);
332  closure->Run();
333  EXPECT_EQ(789, a_);
334  EXPECT_EQ(cstr, b_);
335  a_ = 0;
336  b_ = NULL;
337  closure->Run();
338  EXPECT_EQ(789, a_);
339  EXPECT_EQ(cstr, b_);
340  delete closure;
341}
342
343}  // anonymous namespace
344}  // namespace protobuf
345}  // namespace google
346