temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 1 | // 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 | |
| 29 | namespace google { |
| 30 | namespace protobuf { |
| 31 | namespace { |
| 32 | |
| 33 | // TODO(kenton): More tests. |
| 34 | |
| 35 | #ifdef PACKAGE_VERSION // only defined when using automake, not MSVC |
| 36 | |
| 37 | TEST(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 |
temporal | dd681ad | 2008-08-18 22:55:31 +0000 | [diff] [blame^] | 40 | // like "beta" or "rc1", so we remove that. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 41 | string version = PACKAGE_VERSION; |
temporal | dd681ad | 2008-08-18 22:55:31 +0000 | [diff] [blame^] | 42 | int pos = 0; |
| 43 | while (pos < version.size() && |
| 44 | (ascii_isdigit(version[pos]) || version[pos] == '.')) { |
| 45 | ++pos; |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 46 | } |
| 47 | version.erase(pos); |
| 48 | |
| 49 | EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION)); |
| 50 | } |
| 51 | |
| 52 | #endif // PACKAGE_VERSION |
| 53 | |
temporal | cc93043 | 2008-07-21 20:28:30 +0000 | [diff] [blame] | 54 | TEST(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 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 65 | vector<string> captured_messages_; |
| 66 | |
| 67 | void 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 | |
| 74 | TEST(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 | |
| 89 | TEST(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 | |
| 103 | TEST(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 | |
| 123 | TEST(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 | |
| 149 | class 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 | |
| 180 | ClosureTest* ClosureTest::current_instance_ = NULL; |
| 181 | |
| 182 | TEST_F(ClosureTest, TestClosureFunction0) { |
| 183 | Closure* closure = NewCallback(&SetA123Function); |
| 184 | EXPECT_NE(123, a_); |
| 185 | closure->Run(); |
| 186 | EXPECT_EQ(123, a_); |
| 187 | } |
| 188 | |
| 189 | TEST_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 | |
| 197 | TEST_F(ClosureTest, TestClosureFunction1) { |
| 198 | Closure* closure = NewCallback(&SetAFunction, 456); |
| 199 | EXPECT_NE(456, a_); |
| 200 | closure->Run(); |
| 201 | EXPECT_EQ(456, a_); |
| 202 | } |
| 203 | |
| 204 | TEST_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 | |
| 212 | TEST_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 | |
| 219 | TEST_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 | |
| 227 | TEST_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 | |
| 237 | TEST_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 | |
| 250 | TEST_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 | |
| 261 | TEST_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 | |
| 273 | TEST_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 | |
| 284 | TEST_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 | |
| 296 | TEST_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 | |
| 312 | TEST_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 |