blob: bccc1e09f6219b3b1c641d280a5f2e8ec0e49fa7 [file] [log] [blame]
temporal40ee5512008-07-10 02:12:20 +00001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.
3// http://code.google.com/p/protobuf/
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17// Author: kenton@google.com (Kenton Varda)
18
19#include <vector>
20#include <google/protobuf/stubs/common.h>
21#include <google/protobuf/stubs/strutil.h>
22#include <google/protobuf/stubs/substitute.h>
23
24#include <google/protobuf/testing/googletest.h>
25#include <gtest/gtest.h>
26
27#include "config.h"
28
29namespace google {
30namespace protobuf {
31namespace {
32
33// TODO(kenton): More tests.
34
35#ifdef PACKAGE_VERSION // only defined when using automake, not MSVC
36
37TEST(VersionTest, VersionMatchesConfig) {
38 // Verify that the version string specified in config.h matches the one
39 // in common.h. The config.h version is a string which may have a suffix
temporaldd681ad2008-08-18 22:55:31 +000040 // like "beta" or "rc1", so we remove that.
temporal40ee5512008-07-10 02:12:20 +000041 string version = PACKAGE_VERSION;
temporaldd681ad2008-08-18 22:55:31 +000042 int pos = 0;
43 while (pos < version.size() &&
44 (ascii_isdigit(version[pos]) || version[pos] == '.')) {
45 ++pos;
temporal40ee5512008-07-10 02:12:20 +000046 }
47 version.erase(pos);
48
49 EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION));
50}
51
52#endif // PACKAGE_VERSION
53
temporalcc930432008-07-21 20:28:30 +000054TEST(CommonTest, IntMinMaxConstants) {
55 // kint32min was declared incorrectly in the first release of protobufs.
56 // Ugh.
57 EXPECT_LT(kint32min, kint32max);
58 EXPECT_EQ(static_cast<uint32>(kint32min), static_cast<uint32>(kint32max) + 1);
59 EXPECT_LT(kint64min, kint64max);
60 EXPECT_EQ(static_cast<uint64>(kint64min), static_cast<uint64>(kint64max) + 1);
61 EXPECT_EQ(0, kuint32max + 1);
62 EXPECT_EQ(0, kuint64max + 1);
63}
64
temporal40ee5512008-07-10 02:12:20 +000065vector<string> captured_messages_;
66
67void CaptureLog(LogLevel level, const char* filename, int line,
68 const string& message) {
69 captured_messages_.push_back(
70 strings::Substitute("$0 $1:$2: $3",
71 implicit_cast<int>(level), filename, line, message));
72}
73
74TEST(LoggingTest, DefaultLogging) {
75 CaptureTestStderr();
76 int line = __LINE__;
77 GOOGLE_LOG(INFO ) << "A message.";
78 GOOGLE_LOG(WARNING) << "A warning.";
79 GOOGLE_LOG(ERROR ) << "An error.";
80
81 string text = GetCapturedTestStderr();
82 EXPECT_EQ(
83 "libprotobuf INFO "__FILE__":" + SimpleItoa(line + 1) + "] A message.\n"
84 "libprotobuf WARNING "__FILE__":" + SimpleItoa(line + 2) + "] A warning.\n"
85 "libprotobuf ERROR "__FILE__":" + SimpleItoa(line + 3) + "] An error.\n",
86 text);
87}
88
89TEST(LoggingTest, NullLogging) {
90 LogHandler* old_handler = SetLogHandler(NULL);
91
92 CaptureTestStderr();
93 GOOGLE_LOG(INFO ) << "A message.";
94 GOOGLE_LOG(WARNING) << "A warning.";
95 GOOGLE_LOG(ERROR ) << "An error.";
96
97 EXPECT_TRUE(SetLogHandler(old_handler) == NULL);
98
99 string text = GetCapturedTestStderr();
100 EXPECT_EQ("", text);
101}
102
103TEST(LoggingTest, CaptureLogging) {
104 captured_messages_.clear();
105
106 LogHandler* old_handler = SetLogHandler(&CaptureLog);
107
108 int start_line = __LINE__;
109 GOOGLE_LOG(ERROR) << "An error.";
110 GOOGLE_LOG(WARNING) << "A warning.";
111
112 EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
113
114 ASSERT_EQ(2, captured_messages_.size());
115 EXPECT_EQ(
116 "2 "__FILE__":" + SimpleItoa(start_line + 1) + ": An error.",
117 captured_messages_[0]);
118 EXPECT_EQ(
119 "1 "__FILE__":" + SimpleItoa(start_line + 2) + ": A warning.",
120 captured_messages_[1]);
121}
122
123TEST(LoggingTest, SilenceLogging) {
124 captured_messages_.clear();
125
126 LogHandler* old_handler = SetLogHandler(&CaptureLog);
127
128 int line1 = __LINE__; GOOGLE_LOG(INFO) << "Visible1";
129 LogSilencer* silencer1 = new LogSilencer;
130 GOOGLE_LOG(INFO) << "Not visible.";
131 LogSilencer* silencer2 = new LogSilencer;
132 GOOGLE_LOG(INFO) << "Not visible.";
133 delete silencer1;
134 GOOGLE_LOG(INFO) << "Not visible.";
135 delete silencer2;
136 int line2 = __LINE__; GOOGLE_LOG(INFO) << "Visible2";
137
138 EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
139
140 ASSERT_EQ(2, captured_messages_.size());
141 EXPECT_EQ(
142 "0 "__FILE__":" + SimpleItoa(line1) + ": Visible1",
143 captured_messages_[0]);
144 EXPECT_EQ(
145 "0 "__FILE__":" + SimpleItoa(line2) + ": Visible2",
146 captured_messages_[1]);
147}
148
149class ClosureTest : public testing::Test {
150 public:
151 void SetA123Method() { a_ = 123; }
152 static void SetA123Function() { current_instance_->a_ = 123; }
153
154 void SetAMethod(int a) { a_ = a; }
155 void SetCMethod(string c) { c_ = c; }
156
157 static void SetAFunction(int a) { current_instance_->a_ = a; }
158 static void SetCFunction(string c) { current_instance_->c_ = c; }
159
160 void SetABMethod(int a, const char* b) { a_ = a; b_ = b; }
161 static void SetABFunction(int a, const char* b) {
162 current_instance_->a_ = a;
163 current_instance_->b_ = b;
164 }
165
166 virtual void SetUp() {
167 current_instance_ = this;
168 a_ = 0;
169 b_ = NULL;
170 c_.clear();
171 }
172
173 int a_;
174 const char* b_;
175 string c_;
176
177 static ClosureTest* current_instance_;
178};
179
180ClosureTest* ClosureTest::current_instance_ = NULL;
181
182TEST_F(ClosureTest, TestClosureFunction0) {
183 Closure* closure = NewCallback(&SetA123Function);
184 EXPECT_NE(123, a_);
185 closure->Run();
186 EXPECT_EQ(123, a_);
187}
188
189TEST_F(ClosureTest, TestClosureMethod0) {
190 Closure* closure = NewCallback(current_instance_,
191 &ClosureTest::SetA123Method);
192 EXPECT_NE(123, a_);
193 closure->Run();
194 EXPECT_EQ(123, a_);
195}
196
197TEST_F(ClosureTest, TestClosureFunction1) {
198 Closure* closure = NewCallback(&SetAFunction, 456);
199 EXPECT_NE(456, a_);
200 closure->Run();
201 EXPECT_EQ(456, a_);
202}
203
204TEST_F(ClosureTest, TestClosureMethod1) {
205 Closure* closure = NewCallback(current_instance_,
206 &ClosureTest::SetAMethod, 456);
207 EXPECT_NE(456, a_);
208 closure->Run();
209 EXPECT_EQ(456, a_);
210}
211
212TEST_F(ClosureTest, TestClosureFunction1String) {
213 Closure* closure = NewCallback(&SetCFunction, string("test"));
214 EXPECT_NE("test", c_);
215 closure->Run();
216 EXPECT_EQ("test", c_);
217}
218
219TEST_F(ClosureTest, TestClosureMethod1String) {
220 Closure* closure = NewCallback(current_instance_,
221 &ClosureTest::SetCMethod, string("test"));
222 EXPECT_NE("test", c_);
223 closure->Run();
224 EXPECT_EQ("test", c_);
225}
226
227TEST_F(ClosureTest, TestClosureFunction2) {
228 const char* cstr = "hello";
229 Closure* closure = NewCallback(&SetABFunction, 789, cstr);
230 EXPECT_NE(789, a_);
231 EXPECT_NE(cstr, b_);
232 closure->Run();
233 EXPECT_EQ(789, a_);
234 EXPECT_EQ(cstr, b_);
235}
236
237TEST_F(ClosureTest, TestClosureMethod2) {
238 const char* cstr = "hello";
239 Closure* closure = NewCallback(current_instance_,
240 &ClosureTest::SetABMethod, 789, cstr);
241 EXPECT_NE(789, a_);
242 EXPECT_NE(cstr, b_);
243 closure->Run();
244 EXPECT_EQ(789, a_);
245 EXPECT_EQ(cstr, b_);
246}
247
248// Repeat all of the above with NewPermanentCallback()
249
250TEST_F(ClosureTest, TestPermanentClosureFunction0) {
251 Closure* closure = NewPermanentCallback(&SetA123Function);
252 EXPECT_NE(123, a_);
253 closure->Run();
254 EXPECT_EQ(123, a_);
255 a_ = 0;
256 closure->Run();
257 EXPECT_EQ(123, a_);
258 delete closure;
259}
260
261TEST_F(ClosureTest, TestPermanentClosureMethod0) {
262 Closure* closure = NewPermanentCallback(current_instance_,
263 &ClosureTest::SetA123Method);
264 EXPECT_NE(123, a_);
265 closure->Run();
266 EXPECT_EQ(123, a_);
267 a_ = 0;
268 closure->Run();
269 EXPECT_EQ(123, a_);
270 delete closure;
271}
272
273TEST_F(ClosureTest, TestPermanentClosureFunction1) {
274 Closure* closure = NewPermanentCallback(&SetAFunction, 456);
275 EXPECT_NE(456, a_);
276 closure->Run();
277 EXPECT_EQ(456, a_);
278 a_ = 0;
279 closure->Run();
280 EXPECT_EQ(456, a_);
281 delete closure;
282}
283
284TEST_F(ClosureTest, TestPermanentClosureMethod1) {
285 Closure* closure = NewPermanentCallback(current_instance_,
286 &ClosureTest::SetAMethod, 456);
287 EXPECT_NE(456, a_);
288 closure->Run();
289 EXPECT_EQ(456, a_);
290 a_ = 0;
291 closure->Run();
292 EXPECT_EQ(456, a_);
293 delete closure;
294}
295
296TEST_F(ClosureTest, TestPermanentClosureFunction2) {
297 const char* cstr = "hello";
298 Closure* closure = NewPermanentCallback(&SetABFunction, 789, cstr);
299 EXPECT_NE(789, a_);
300 EXPECT_NE(cstr, b_);
301 closure->Run();
302 EXPECT_EQ(789, a_);
303 EXPECT_EQ(cstr, b_);
304 a_ = 0;
305 b_ = NULL;
306 closure->Run();
307 EXPECT_EQ(789, a_);
308 EXPECT_EQ(cstr, b_);
309 delete closure;
310}
311
312TEST_F(ClosureTest, TestPermanentClosureMethod2) {
313 const char* cstr = "hello";
314 Closure* closure = NewPermanentCallback(current_instance_,
315 &ClosureTest::SetABMethod, 789, cstr);
316 EXPECT_NE(789, a_);
317 EXPECT_NE(cstr, b_);
318 closure->Run();
319 EXPECT_EQ(789, a_);
320 EXPECT_EQ(cstr, b_);
321 a_ = 0;
322 b_ = NULL;
323 closure->Run();
324 EXPECT_EQ(789, a_);
325 EXPECT_EQ(cstr, b_);
326 delete closure;
327}
328
329} // anonymous namespace
330} // namespace protobuf
331} // namespace google