1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// https://developers.google.com/protocol-buffers/
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    permanent_closure_ = NULL;
186  }
187
188  void DeleteClosureInCallback() {
189    delete permanent_closure_;
190  }
191
192  int a_;
193  const char* b_;
194  string c_;
195  Closure* permanent_closure_;
196
197  static ClosureTest* current_instance_;
198};
199
200ClosureTest* ClosureTest::current_instance_ = NULL;
201
202TEST_F(ClosureTest, TestClosureFunction0) {
203  Closure* closure = NewCallback(&SetA123Function);
204  EXPECT_NE(123, a_);
205  closure->Run();
206  EXPECT_EQ(123, a_);
207}
208
209TEST_F(ClosureTest, TestClosureMethod0) {
210  Closure* closure = NewCallback(current_instance_,
211                                 &ClosureTest::SetA123Method);
212  EXPECT_NE(123, a_);
213  closure->Run();
214  EXPECT_EQ(123, a_);
215}
216
217TEST_F(ClosureTest, TestClosureFunction1) {
218  Closure* closure = NewCallback(&SetAFunction, 456);
219  EXPECT_NE(456, a_);
220  closure->Run();
221  EXPECT_EQ(456, a_);
222}
223
224TEST_F(ClosureTest, TestClosureMethod1) {
225  Closure* closure = NewCallback(current_instance_,
226                                 &ClosureTest::SetAMethod, 456);
227  EXPECT_NE(456, a_);
228  closure->Run();
229  EXPECT_EQ(456, a_);
230}
231
232TEST_F(ClosureTest, TestClosureFunction1String) {
233  Closure* closure = NewCallback(&SetCFunction, string("test"));
234  EXPECT_NE("test", c_);
235  closure->Run();
236  EXPECT_EQ("test", c_);
237}
238
239TEST_F(ClosureTest, TestClosureMethod1String) {
240  Closure* closure = NewCallback(current_instance_,
241                                 &ClosureTest::SetCMethod, string("test"));
242  EXPECT_NE("test", c_);
243  closure->Run();
244  EXPECT_EQ("test", c_);
245}
246
247TEST_F(ClosureTest, TestClosureFunction2) {
248  const char* cstr = "hello";
249  Closure* closure = NewCallback(&SetABFunction, 789, cstr);
250  EXPECT_NE(789, a_);
251  EXPECT_NE(cstr, b_);
252  closure->Run();
253  EXPECT_EQ(789, a_);
254  EXPECT_EQ(cstr, b_);
255}
256
257TEST_F(ClosureTest, TestClosureMethod2) {
258  const char* cstr = "hello";
259  Closure* closure = NewCallback(current_instance_,
260                                 &ClosureTest::SetABMethod, 789, cstr);
261  EXPECT_NE(789, a_);
262  EXPECT_NE(cstr, b_);
263  closure->Run();
264  EXPECT_EQ(789, a_);
265  EXPECT_EQ(cstr, b_);
266}
267
268// Repeat all of the above with NewPermanentCallback()
269
270TEST_F(ClosureTest, TestPermanentClosureFunction0) {
271  Closure* closure = NewPermanentCallback(&SetA123Function);
272  EXPECT_NE(123, a_);
273  closure->Run();
274  EXPECT_EQ(123, a_);
275  a_ = 0;
276  closure->Run();
277  EXPECT_EQ(123, a_);
278  delete closure;
279}
280
281TEST_F(ClosureTest, TestPermanentClosureMethod0) {
282  Closure* closure = NewPermanentCallback(current_instance_,
283                                          &ClosureTest::SetA123Method);
284  EXPECT_NE(123, a_);
285  closure->Run();
286  EXPECT_EQ(123, a_);
287  a_ = 0;
288  closure->Run();
289  EXPECT_EQ(123, a_);
290  delete closure;
291}
292
293TEST_F(ClosureTest, TestPermanentClosureFunction1) {
294  Closure* closure = NewPermanentCallback(&SetAFunction, 456);
295  EXPECT_NE(456, a_);
296  closure->Run();
297  EXPECT_EQ(456, a_);
298  a_ = 0;
299  closure->Run();
300  EXPECT_EQ(456, a_);
301  delete closure;
302}
303
304TEST_F(ClosureTest, TestPermanentClosureMethod1) {
305  Closure* closure = NewPermanentCallback(current_instance_,
306                                          &ClosureTest::SetAMethod, 456);
307  EXPECT_NE(456, a_);
308  closure->Run();
309  EXPECT_EQ(456, a_);
310  a_ = 0;
311  closure->Run();
312  EXPECT_EQ(456, a_);
313  delete closure;
314}
315
316TEST_F(ClosureTest, TestPermanentClosureFunction2) {
317  const char* cstr = "hello";
318  Closure* closure = NewPermanentCallback(&SetABFunction, 789, cstr);
319  EXPECT_NE(789, a_);
320  EXPECT_NE(cstr, b_);
321  closure->Run();
322  EXPECT_EQ(789, a_);
323  EXPECT_EQ(cstr, b_);
324  a_ = 0;
325  b_ = NULL;
326  closure->Run();
327  EXPECT_EQ(789, a_);
328  EXPECT_EQ(cstr, b_);
329  delete closure;
330}
331
332TEST_F(ClosureTest, TestPermanentClosureMethod2) {
333  const char* cstr = "hello";
334  Closure* closure = NewPermanentCallback(current_instance_,
335                                          &ClosureTest::SetABMethod, 789, cstr);
336  EXPECT_NE(789, a_);
337  EXPECT_NE(cstr, b_);
338  closure->Run();
339  EXPECT_EQ(789, a_);
340  EXPECT_EQ(cstr, b_);
341  a_ = 0;
342  b_ = NULL;
343  closure->Run();
344  EXPECT_EQ(789, a_);
345  EXPECT_EQ(cstr, b_);
346  delete closure;
347}
348
349TEST_F(ClosureTest, TestPermanentClosureDeleteInCallback) {
350  permanent_closure_ = NewPermanentCallback((ClosureTest*) this,
351      &ClosureTest::DeleteClosureInCallback);
352  permanent_closure_->Run();
353}
354
355}  // anonymous namespace
356}  // namespace protobuf
357}  // namespace google
358