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/casts.h>
35 #include <google/protobuf/stubs/common.h>
36 #include <google/protobuf/stubs/strutil.h>
37 #include <google/protobuf/stubs/substitute.h>
38
39 #include <google/protobuf/testing/googletest.h>
40 #include <gtest/gtest.h>
41
42 namespace google {
43 namespace protobuf {
44 using internal::NewCallback;
45 using internal::NewPermanentCallback;
46 namespace {
47
48 // TODO(kenton): More tests.
49
50 #ifdef PACKAGE_VERSION // only defined when using automake, not MSVC
51
TEST(VersionTest,VersionMatchesConfig)52 TEST(VersionTest, VersionMatchesConfig) {
53 // Verify that the version string specified in config.h matches the one
54 // in common.h. The config.h version is a string which may have a suffix
55 // like "beta" or "rc1", so we remove that.
56 string version = PACKAGE_VERSION;
57 int pos = 0;
58 while (pos < version.size() &&
59 (ascii_isdigit(version[pos]) || version[pos] == '.')) {
60 ++pos;
61 }
62 version.erase(pos);
63
64 EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION));
65 }
66
67 #endif // PACKAGE_VERSION
68
TEST(CommonTest,IntMinMaxConstants)69 TEST(CommonTest, IntMinMaxConstants) {
70 // kint32min was declared incorrectly in the first release of protobufs.
71 // Ugh.
72 EXPECT_LT(kint32min, kint32max);
73 EXPECT_EQ(static_cast<uint32>(kint32min), static_cast<uint32>(kint32max) + 1);
74 EXPECT_LT(kint64min, kint64max);
75 EXPECT_EQ(static_cast<uint64>(kint64min), static_cast<uint64>(kint64max) + 1);
76 EXPECT_EQ(0, kuint32max + 1);
77 EXPECT_EQ(0, kuint64max + 1);
78 }
79
80 vector<string> captured_messages_;
81
CaptureLog(LogLevel level,const char * filename,int line,const string & message)82 void CaptureLog(LogLevel level, const char* filename, int line,
83 const string& message) {
84 captured_messages_.push_back(
85 strings::Substitute("$0 $1:$2: $3",
86 implicit_cast<int>(level), filename, line, message));
87 }
88
TEST(LoggingTest,DefaultLogging)89 TEST(LoggingTest, DefaultLogging) {
90 CaptureTestStderr();
91 int line = __LINE__;
92 GOOGLE_LOG(INFO ) << "A message.";
93 GOOGLE_LOG(WARNING) << "A warning.";
94 GOOGLE_LOG(ERROR ) << "An error.";
95
96 string text = GetCapturedTestStderr();
97 EXPECT_EQ(
98 "[libprotobuf INFO " __FILE__ ":" + SimpleItoa(line + 1) + "] A message.\n"
99 "[libprotobuf WARNING " __FILE__ ":" + SimpleItoa(line + 2) + "] A warning.\n"
100 "[libprotobuf ERROR " __FILE__ ":" + SimpleItoa(line + 3) + "] An error.\n",
101 text);
102 }
103
TEST(LoggingTest,NullLogging)104 TEST(LoggingTest, NullLogging) {
105 LogHandler* old_handler = SetLogHandler(NULL);
106
107 CaptureTestStderr();
108 GOOGLE_LOG(INFO ) << "A message.";
109 GOOGLE_LOG(WARNING) << "A warning.";
110 GOOGLE_LOG(ERROR ) << "An error.";
111
112 EXPECT_TRUE(SetLogHandler(old_handler) == NULL);
113
114 string text = GetCapturedTestStderr();
115 EXPECT_EQ("", text);
116 }
117
TEST(LoggingTest,CaptureLogging)118 TEST(LoggingTest, CaptureLogging) {
119 captured_messages_.clear();
120
121 LogHandler* old_handler = SetLogHandler(&CaptureLog);
122
123 int start_line = __LINE__;
124 GOOGLE_LOG(ERROR) << "An error.";
125 GOOGLE_LOG(WARNING) << "A warning.";
126
127 EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
128
129 ASSERT_EQ(2, captured_messages_.size());
130 EXPECT_EQ(
131 "2 " __FILE__ ":" + SimpleItoa(start_line + 1) + ": An error.",
132 captured_messages_[0]);
133 EXPECT_EQ(
134 "1 " __FILE__ ":" + SimpleItoa(start_line + 2) + ": A warning.",
135 captured_messages_[1]);
136 }
137
TEST(LoggingTest,SilenceLogging)138 TEST(LoggingTest, SilenceLogging) {
139 captured_messages_.clear();
140
141 LogHandler* old_handler = SetLogHandler(&CaptureLog);
142
143 int line1 = __LINE__; GOOGLE_LOG(INFO) << "Visible1";
144 LogSilencer* silencer1 = new LogSilencer;
145 GOOGLE_LOG(INFO) << "Not visible.";
146 LogSilencer* silencer2 = new LogSilencer;
147 GOOGLE_LOG(INFO) << "Not visible.";
148 delete silencer1;
149 GOOGLE_LOG(INFO) << "Not visible.";
150 delete silencer2;
151 int line2 = __LINE__; GOOGLE_LOG(INFO) << "Visible2";
152
153 EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
154
155 ASSERT_EQ(2, captured_messages_.size());
156 EXPECT_EQ(
157 "0 " __FILE__ ":" + SimpleItoa(line1) + ": Visible1",
158 captured_messages_[0]);
159 EXPECT_EQ(
160 "0 " __FILE__ ":" + SimpleItoa(line2) + ": Visible2",
161 captured_messages_[1]);
162 }
163
164 class ClosureTest : public testing::Test {
165 public:
SetA123Method()166 void SetA123Method() { a_ = 123; }
SetA123Function()167 static void SetA123Function() { current_instance_->a_ = 123; }
168
SetAMethod(int a)169 void SetAMethod(int a) { a_ = a; }
SetCMethod(string c)170 void SetCMethod(string c) { c_ = c; }
171
SetAFunction(int a)172 static void SetAFunction(int a) { current_instance_->a_ = a; }
SetCFunction(string c)173 static void SetCFunction(string c) { current_instance_->c_ = c; }
174
SetABMethod(int a,const char * b)175 void SetABMethod(int a, const char* b) { a_ = a; b_ = b; }
SetABFunction(int a,const char * b)176 static void SetABFunction(int a, const char* b) {
177 current_instance_->a_ = a;
178 current_instance_->b_ = b;
179 }
180
SetUp()181 virtual void SetUp() {
182 current_instance_ = this;
183 a_ = 0;
184 b_ = NULL;
185 c_.clear();
186 permanent_closure_ = NULL;
187 }
188
DeleteClosureInCallback()189 void DeleteClosureInCallback() {
190 delete permanent_closure_;
191 }
192
193 int a_;
194 const char* b_;
195 string c_;
196 Closure* permanent_closure_;
197
198 static ClosureTest* current_instance_;
199 };
200
201 ClosureTest* ClosureTest::current_instance_ = NULL;
202
TEST_F(ClosureTest,TestClosureFunction0)203 TEST_F(ClosureTest, TestClosureFunction0) {
204 Closure* closure = NewCallback(&SetA123Function);
205 EXPECT_NE(123, a_);
206 closure->Run();
207 EXPECT_EQ(123, a_);
208 }
209
TEST_F(ClosureTest,TestClosureMethod0)210 TEST_F(ClosureTest, TestClosureMethod0) {
211 Closure* closure = NewCallback(current_instance_,
212 &ClosureTest::SetA123Method);
213 EXPECT_NE(123, a_);
214 closure->Run();
215 EXPECT_EQ(123, a_);
216 }
217
TEST_F(ClosureTest,TestClosureFunction1)218 TEST_F(ClosureTest, TestClosureFunction1) {
219 Closure* closure = NewCallback(&SetAFunction, 456);
220 EXPECT_NE(456, a_);
221 closure->Run();
222 EXPECT_EQ(456, a_);
223 }
224
TEST_F(ClosureTest,TestClosureMethod1)225 TEST_F(ClosureTest, TestClosureMethod1) {
226 Closure* closure = NewCallback(current_instance_,
227 &ClosureTest::SetAMethod, 456);
228 EXPECT_NE(456, a_);
229 closure->Run();
230 EXPECT_EQ(456, a_);
231 }
232
TEST_F(ClosureTest,TestClosureFunction1String)233 TEST_F(ClosureTest, TestClosureFunction1String) {
234 Closure* closure = NewCallback(&SetCFunction, string("test"));
235 EXPECT_NE("test", c_);
236 closure->Run();
237 EXPECT_EQ("test", c_);
238 }
239
TEST_F(ClosureTest,TestClosureMethod1String)240 TEST_F(ClosureTest, TestClosureMethod1String) {
241 Closure* closure = NewCallback(current_instance_,
242 &ClosureTest::SetCMethod, string("test"));
243 EXPECT_NE("test", c_);
244 closure->Run();
245 EXPECT_EQ("test", c_);
246 }
247
TEST_F(ClosureTest,TestClosureFunction2)248 TEST_F(ClosureTest, TestClosureFunction2) {
249 const char* cstr = "hello";
250 Closure* closure = NewCallback(&SetABFunction, 789, cstr);
251 EXPECT_NE(789, a_);
252 EXPECT_NE(cstr, b_);
253 closure->Run();
254 EXPECT_EQ(789, a_);
255 EXPECT_EQ(cstr, b_);
256 }
257
TEST_F(ClosureTest,TestClosureMethod2)258 TEST_F(ClosureTest, TestClosureMethod2) {
259 const char* cstr = "hello";
260 Closure* closure = NewCallback(current_instance_,
261 &ClosureTest::SetABMethod, 789, cstr);
262 EXPECT_NE(789, a_);
263 EXPECT_NE(cstr, b_);
264 closure->Run();
265 EXPECT_EQ(789, a_);
266 EXPECT_EQ(cstr, b_);
267 }
268
269 // Repeat all of the above with NewPermanentCallback()
270
TEST_F(ClosureTest,TestPermanentClosureFunction0)271 TEST_F(ClosureTest, TestPermanentClosureFunction0) {
272 Closure* closure = NewPermanentCallback(&SetA123Function);
273 EXPECT_NE(123, a_);
274 closure->Run();
275 EXPECT_EQ(123, a_);
276 a_ = 0;
277 closure->Run();
278 EXPECT_EQ(123, a_);
279 delete closure;
280 }
281
TEST_F(ClosureTest,TestPermanentClosureMethod0)282 TEST_F(ClosureTest, TestPermanentClosureMethod0) {
283 Closure* closure = NewPermanentCallback(current_instance_,
284 &ClosureTest::SetA123Method);
285 EXPECT_NE(123, a_);
286 closure->Run();
287 EXPECT_EQ(123, a_);
288 a_ = 0;
289 closure->Run();
290 EXPECT_EQ(123, a_);
291 delete closure;
292 }
293
TEST_F(ClosureTest,TestPermanentClosureFunction1)294 TEST_F(ClosureTest, TestPermanentClosureFunction1) {
295 Closure* closure = NewPermanentCallback(&SetAFunction, 456);
296 EXPECT_NE(456, a_);
297 closure->Run();
298 EXPECT_EQ(456, a_);
299 a_ = 0;
300 closure->Run();
301 EXPECT_EQ(456, a_);
302 delete closure;
303 }
304
TEST_F(ClosureTest,TestPermanentClosureMethod1)305 TEST_F(ClosureTest, TestPermanentClosureMethod1) {
306 Closure* closure = NewPermanentCallback(current_instance_,
307 &ClosureTest::SetAMethod, 456);
308 EXPECT_NE(456, a_);
309 closure->Run();
310 EXPECT_EQ(456, a_);
311 a_ = 0;
312 closure->Run();
313 EXPECT_EQ(456, a_);
314 delete closure;
315 }
316
TEST_F(ClosureTest,TestPermanentClosureFunction2)317 TEST_F(ClosureTest, TestPermanentClosureFunction2) {
318 const char* cstr = "hello";
319 Closure* closure = NewPermanentCallback(&SetABFunction, 789, cstr);
320 EXPECT_NE(789, a_);
321 EXPECT_NE(cstr, b_);
322 closure->Run();
323 EXPECT_EQ(789, a_);
324 EXPECT_EQ(cstr, b_);
325 a_ = 0;
326 b_ = NULL;
327 closure->Run();
328 EXPECT_EQ(789, a_);
329 EXPECT_EQ(cstr, b_);
330 delete closure;
331 }
332
TEST_F(ClosureTest,TestPermanentClosureMethod2)333 TEST_F(ClosureTest, TestPermanentClosureMethod2) {
334 const char* cstr = "hello";
335 Closure* closure = NewPermanentCallback(current_instance_,
336 &ClosureTest::SetABMethod, 789, cstr);
337 EXPECT_NE(789, a_);
338 EXPECT_NE(cstr, b_);
339 closure->Run();
340 EXPECT_EQ(789, a_);
341 EXPECT_EQ(cstr, b_);
342 a_ = 0;
343 b_ = NULL;
344 closure->Run();
345 EXPECT_EQ(789, a_);
346 EXPECT_EQ(cstr, b_);
347 delete closure;
348 }
349
TEST_F(ClosureTest,TestPermanentClosureDeleteInCallback)350 TEST_F(ClosureTest, TestPermanentClosureDeleteInCallback) {
351 permanent_closure_ = NewPermanentCallback((ClosureTest*) this,
352 &ClosureTest::DeleteClosureInCallback);
353 permanent_closure_->Run();
354 }
355
356 } // anonymous namespace
357 } // namespace protobuf
358 } // namespace google
359