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
43 namespace google {
44 namespace protobuf {
45 namespace {
46
47 // TODO(kenton): More tests.
48
49 #ifdef PACKAGE_VERSION // only defined when using automake, not MSVC
50
TEST(VersionTest,VersionMatchesConfig)51 TEST(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
TEST(CommonTest,IntMinMaxConstants)68 TEST(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
79 vector<string> captured_messages_;
80
CaptureLog(LogLevel level,const char * filename,int line,const string & message)81 void 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
TEST(LoggingTest,DefaultLogging)88 TEST(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
TEST(LoggingTest,NullLogging)103 TEST(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
TEST(LoggingTest,CaptureLogging)117 TEST(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
TEST(LoggingTest,SilenceLogging)137 TEST(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
163 class ClosureTest : public testing::Test {
164 public:
SetA123Method()165 void SetA123Method() { a_ = 123; }
SetA123Function()166 static void SetA123Function() { current_instance_->a_ = 123; }
167
SetAMethod(int a)168 void SetAMethod(int a) { a_ = a; }
SetCMethod(string c)169 void SetCMethod(string c) { c_ = c; }
170
SetAFunction(int a)171 static void SetAFunction(int a) { current_instance_->a_ = a; }
SetCFunction(string c)172 static void SetCFunction(string c) { current_instance_->c_ = c; }
173
SetABMethod(int a,const char * b)174 void SetABMethod(int a, const char* b) { a_ = a; b_ = b; }
SetABFunction(int a,const char * b)175 static void SetABFunction(int a, const char* b) {
176 current_instance_->a_ = a;
177 current_instance_->b_ = b;
178 }
179
SetUp()180 virtual void SetUp() {
181 current_instance_ = this;
182 a_ = 0;
183 b_ = NULL;
184 c_.clear();
185 permanent_closure_ = NULL;
186 }
187
DeleteClosureInCallback()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
200 ClosureTest* ClosureTest::current_instance_ = NULL;
201
TEST_F(ClosureTest,TestClosureFunction0)202 TEST_F(ClosureTest, TestClosureFunction0) {
203 Closure* closure = NewCallback(&SetA123Function);
204 EXPECT_NE(123, a_);
205 closure->Run();
206 EXPECT_EQ(123, a_);
207 }
208
TEST_F(ClosureTest,TestClosureMethod0)209 TEST_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
TEST_F(ClosureTest,TestClosureFunction1)217 TEST_F(ClosureTest, TestClosureFunction1) {
218 Closure* closure = NewCallback(&SetAFunction, 456);
219 EXPECT_NE(456, a_);
220 closure->Run();
221 EXPECT_EQ(456, a_);
222 }
223
TEST_F(ClosureTest,TestClosureMethod1)224 TEST_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
TEST_F(ClosureTest,TestClosureFunction1String)232 TEST_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
TEST_F(ClosureTest,TestClosureMethod1String)239 TEST_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
TEST_F(ClosureTest,TestClosureFunction2)247 TEST_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
TEST_F(ClosureTest,TestClosureMethod2)257 TEST_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
TEST_F(ClosureTest,TestPermanentClosureFunction0)270 TEST_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
TEST_F(ClosureTest,TestPermanentClosureMethod0)281 TEST_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
TEST_F(ClosureTest,TestPermanentClosureFunction1)293 TEST_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
TEST_F(ClosureTest,TestPermanentClosureMethod1)304 TEST_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
TEST_F(ClosureTest,TestPermanentClosureFunction2)316 TEST_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
TEST_F(ClosureTest,TestPermanentClosureMethod2)332 TEST_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
TEST_F(ClosureTest,TestPermanentClosureDeleteInCallback)349 TEST_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