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