| OLD | NEW |
| (Empty) |
| 1 // Copyright 2008, Google Inc. | |
| 2 // All rights reserved. | |
| 3 // | |
| 4 // Redistribution and use in source and binary forms, with or without | |
| 5 // modification, are permitted provided that the following conditions are | |
| 6 // met: | |
| 7 // | |
| 8 // * Redistributions of source code must retain the above copyright | |
| 9 // notice, this list of conditions and the following disclaimer. | |
| 10 // * Redistributions in binary form must reproduce the above | |
| 11 // copyright notice, this list of conditions and the following disclaimer | |
| 12 // in the documentation and/or other materials provided with the | |
| 13 // distribution. | |
| 14 // * Neither the name of Google Inc. nor the names of its | |
| 15 // contributors may be used to endorse or promote products derived from | |
| 16 // this software without specific prior written permission. | |
| 17 // | |
| 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 // | |
| 30 // Authors: vladl@google.com (Vlad Losev), wan@google.com (Zhanyong Wan) | |
| 31 // | |
| 32 // This file tests the internal cross-platform support utilities. | |
| 33 | |
| 34 #include "gtest/internal/gtest-port.h" | |
| 35 | |
| 36 #include <stdio.h> | |
| 37 | |
| 38 #if GTEST_OS_MAC | |
| 39 # include <time.h> | |
| 40 #endif // GTEST_OS_MAC | |
| 41 | |
| 42 #include <list> | |
| 43 #include <utility> // For std::pair and std::make_pair. | |
| 44 #include <vector> | |
| 45 | |
| 46 #include "gtest/gtest.h" | |
| 47 #include "gtest/gtest-spi.h" | |
| 48 | |
| 49 // Indicates that this translation unit is part of Google Test's | |
| 50 // implementation. It must come before gtest-internal-inl.h is | |
| 51 // included, or there will be a compiler error. This trick is to | |
| 52 // prevent a user from accidentally including gtest-internal-inl.h in | |
| 53 // his code. | |
| 54 #define GTEST_IMPLEMENTATION_ 1 | |
| 55 #include "src/gtest-internal-inl.h" | |
| 56 #undef GTEST_IMPLEMENTATION_ | |
| 57 | |
| 58 using std::make_pair; | |
| 59 using std::pair; | |
| 60 | |
| 61 namespace testing { | |
| 62 namespace internal { | |
| 63 | |
| 64 class Base { | |
| 65 public: | |
| 66 // Copy constructor and assignment operator do exactly what we need, so we | |
| 67 // use them. | |
| 68 Base() : member_(0) {} | |
| 69 explicit Base(int n) : member_(n) {} | |
| 70 virtual ~Base() {} | |
| 71 int member() { return member_; } | |
| 72 | |
| 73 private: | |
| 74 int member_; | |
| 75 }; | |
| 76 | |
| 77 class Derived : public Base { | |
| 78 public: | |
| 79 explicit Derived(int n) : Base(n) {} | |
| 80 }; | |
| 81 | |
| 82 TEST(ImplicitCastTest, ConvertsPointers) { | |
| 83 Derived derived(0); | |
| 84 EXPECT_TRUE(&derived == ::testing::internal::ImplicitCast_<Base*>(&derived)); | |
| 85 } | |
| 86 | |
| 87 TEST(ImplicitCastTest, CanUseInheritance) { | |
| 88 Derived derived(1); | |
| 89 Base base = ::testing::internal::ImplicitCast_<Base>(derived); | |
| 90 EXPECT_EQ(derived.member(), base.member()); | |
| 91 } | |
| 92 | |
| 93 class Castable { | |
| 94 public: | |
| 95 Castable(bool* converted) : converted_(converted) {} | |
| 96 operator Base() { | |
| 97 *converted_ = true; | |
| 98 return Base(); | |
| 99 } | |
| 100 | |
| 101 private: | |
| 102 bool* converted_; | |
| 103 }; | |
| 104 | |
| 105 TEST(ImplicitCastTest, CanUseNonConstCastOperator) { | |
| 106 bool converted = false; | |
| 107 Castable castable(&converted); | |
| 108 Base base = ::testing::internal::ImplicitCast_<Base>(castable); | |
| 109 EXPECT_TRUE(converted); | |
| 110 } | |
| 111 | |
| 112 class ConstCastable { | |
| 113 public: | |
| 114 ConstCastable(bool* converted) : converted_(converted) {} | |
| 115 operator Base() const { | |
| 116 *converted_ = true; | |
| 117 return Base(); | |
| 118 } | |
| 119 | |
| 120 private: | |
| 121 bool* converted_; | |
| 122 }; | |
| 123 | |
| 124 TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) { | |
| 125 bool converted = false; | |
| 126 const ConstCastable const_castable(&converted); | |
| 127 Base base = ::testing::internal::ImplicitCast_<Base>(const_castable); | |
| 128 EXPECT_TRUE(converted); | |
| 129 } | |
| 130 | |
| 131 class ConstAndNonConstCastable { | |
| 132 public: | |
| 133 ConstAndNonConstCastable(bool* converted, bool* const_converted) | |
| 134 : converted_(converted), const_converted_(const_converted) {} | |
| 135 operator Base() { | |
| 136 *converted_ = true; | |
| 137 return Base(); | |
| 138 } | |
| 139 operator Base() const { | |
| 140 *const_converted_ = true; | |
| 141 return Base(); | |
| 142 } | |
| 143 | |
| 144 private: | |
| 145 bool* converted_; | |
| 146 bool* const_converted_; | |
| 147 }; | |
| 148 | |
| 149 TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) { | |
| 150 bool converted = false; | |
| 151 bool const_converted = false; | |
| 152 ConstAndNonConstCastable castable(&converted, &const_converted); | |
| 153 Base base = ::testing::internal::ImplicitCast_<Base>(castable); | |
| 154 EXPECT_TRUE(converted); | |
| 155 EXPECT_FALSE(const_converted); | |
| 156 | |
| 157 converted = false; | |
| 158 const_converted = false; | |
| 159 const ConstAndNonConstCastable const_castable(&converted, &const_converted); | |
| 160 base = ::testing::internal::ImplicitCast_<Base>(const_castable); | |
| 161 EXPECT_FALSE(converted); | |
| 162 EXPECT_TRUE(const_converted); | |
| 163 } | |
| 164 | |
| 165 class To { | |
| 166 public: | |
| 167 To(bool* converted) { *converted = true; } // NOLINT | |
| 168 }; | |
| 169 | |
| 170 TEST(ImplicitCastTest, CanUseImplicitConstructor) { | |
| 171 bool converted = false; | |
| 172 To to = ::testing::internal::ImplicitCast_<To>(&converted); | |
| 173 (void)to; | |
| 174 EXPECT_TRUE(converted); | |
| 175 } | |
| 176 | |
| 177 TEST(IteratorTraitsTest, WorksForSTLContainerIterators) { | |
| 178 StaticAssertTypeEq<int, | |
| 179 IteratorTraits< ::std::vector<int>::const_iterator>::value_type>(); | |
| 180 StaticAssertTypeEq<bool, | |
| 181 IteratorTraits< ::std::list<bool>::iterator>::value_type>(); | |
| 182 } | |
| 183 | |
| 184 TEST(IteratorTraitsTest, WorksForPointerToNonConst) { | |
| 185 StaticAssertTypeEq<char, IteratorTraits<char*>::value_type>(); | |
| 186 StaticAssertTypeEq<const void*, IteratorTraits<const void**>::value_type>(); | |
| 187 } | |
| 188 | |
| 189 TEST(IteratorTraitsTest, WorksForPointerToConst) { | |
| 190 StaticAssertTypeEq<char, IteratorTraits<const char*>::value_type>(); | |
| 191 StaticAssertTypeEq<const void*, | |
| 192 IteratorTraits<const void* const*>::value_type>(); | |
| 193 } | |
| 194 | |
| 195 // Tests that the element_type typedef is available in scoped_ptr and refers | |
| 196 // to the parameter type. | |
| 197 TEST(ScopedPtrTest, DefinesElementType) { | |
| 198 StaticAssertTypeEq<int, ::testing::internal::scoped_ptr<int>::element_type>(); | |
| 199 } | |
| 200 | |
| 201 // TODO(vladl@google.com): Implement THE REST of scoped_ptr tests. | |
| 202 | |
| 203 TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) { | |
| 204 if (AlwaysFalse()) | |
| 205 GTEST_CHECK_(false) << "This should never be executed; " | |
| 206 "It's a compilation test only."; | |
| 207 | |
| 208 if (AlwaysTrue()) | |
| 209 GTEST_CHECK_(true); | |
| 210 else | |
| 211 ; // NOLINT | |
| 212 | |
| 213 if (AlwaysFalse()) | |
| 214 ; // NOLINT | |
| 215 else | |
| 216 GTEST_CHECK_(true) << ""; | |
| 217 } | |
| 218 | |
| 219 TEST(GtestCheckSyntaxTest, WorksWithSwitch) { | |
| 220 switch (0) { | |
| 221 case 1: | |
| 222 break; | |
| 223 default: | |
| 224 GTEST_CHECK_(true); | |
| 225 } | |
| 226 | |
| 227 switch(0) | |
| 228 case 0: | |
| 229 GTEST_CHECK_(true) << "Check failed in switch case"; | |
| 230 } | |
| 231 | |
| 232 // Verifies behavior of FormatFileLocation. | |
| 233 TEST(FormatFileLocationTest, FormatsFileLocation) { | |
| 234 EXPECT_PRED_FORMAT2(IsSubstring, "foo.cc", FormatFileLocation("foo.cc", 42)); | |
| 235 EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation("foo.cc", 42)); | |
| 236 } | |
| 237 | |
| 238 TEST(FormatFileLocationTest, FormatsUnknownFile) { | |
| 239 EXPECT_PRED_FORMAT2( | |
| 240 IsSubstring, "unknown file", FormatFileLocation(NULL, 42)); | |
| 241 EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation(NULL, 42)); | |
| 242 } | |
| 243 | |
| 244 TEST(FormatFileLocationTest, FormatsUknownLine) { | |
| 245 EXPECT_EQ("foo.cc:", FormatFileLocation("foo.cc", -1)); | |
| 246 } | |
| 247 | |
| 248 TEST(FormatFileLocationTest, FormatsUknownFileAndLine) { | |
| 249 EXPECT_EQ("unknown file:", FormatFileLocation(NULL, -1)); | |
| 250 } | |
| 251 | |
| 252 // Verifies behavior of FormatCompilerIndependentFileLocation. | |
| 253 TEST(FormatCompilerIndependentFileLocationTest, FormatsFileLocation) { | |
| 254 EXPECT_EQ("foo.cc:42", FormatCompilerIndependentFileLocation("foo.cc", 42)); | |
| 255 } | |
| 256 | |
| 257 TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFile) { | |
| 258 EXPECT_EQ("unknown file:42", | |
| 259 FormatCompilerIndependentFileLocation(NULL, 42)); | |
| 260 } | |
| 261 | |
| 262 TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownLine) { | |
| 263 EXPECT_EQ("foo.cc", FormatCompilerIndependentFileLocation("foo.cc", -1)); | |
| 264 } | |
| 265 | |
| 266 TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) { | |
| 267 EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1)); | |
| 268 } | |
| 269 | |
| 270 #if GTEST_OS_MAC | |
| 271 void* ThreadFunc(void* data) { | |
| 272 pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data); | |
| 273 pthread_mutex_lock(mutex); | |
| 274 pthread_mutex_unlock(mutex); | |
| 275 return NULL; | |
| 276 } | |
| 277 | |
| 278 TEST(GetThreadCountTest, ReturnsCorrectValue) { | |
| 279 EXPECT_EQ(1U, GetThreadCount()); | |
| 280 pthread_mutex_t mutex; | |
| 281 pthread_attr_t attr; | |
| 282 pthread_t thread_id; | |
| 283 | |
| 284 // TODO(vladl@google.com): turn mutex into internal::Mutex for automatic | |
| 285 // destruction. | |
| 286 pthread_mutex_init(&mutex, NULL); | |
| 287 pthread_mutex_lock(&mutex); | |
| 288 ASSERT_EQ(0, pthread_attr_init(&attr)); | |
| 289 ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); | |
| 290 | |
| 291 const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex); | |
| 292 ASSERT_EQ(0, pthread_attr_destroy(&attr)); | |
| 293 ASSERT_EQ(0, status); | |
| 294 EXPECT_EQ(2U, GetThreadCount()); | |
| 295 pthread_mutex_unlock(&mutex); | |
| 296 | |
| 297 void* dummy; | |
| 298 ASSERT_EQ(0, pthread_join(thread_id, &dummy)); | |
| 299 | |
| 300 // MacOS X may not immediately report the updated thread count after | |
| 301 // joining a thread, causing flakiness in this test. To counter that, we | |
| 302 // wait for up to .5 seconds for the OS to report the correct value. | |
| 303 for (int i = 0; i < 5; ++i) { | |
| 304 if (GetThreadCount() == 1) | |
| 305 break; | |
| 306 | |
| 307 SleepMilliseconds(100); | |
| 308 } | |
| 309 EXPECT_EQ(1U, GetThreadCount()); | |
| 310 pthread_mutex_destroy(&mutex); | |
| 311 } | |
| 312 #else | |
| 313 TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { | |
| 314 EXPECT_EQ(0U, GetThreadCount()); | |
| 315 } | |
| 316 #endif // GTEST_OS_MAC | |
| 317 | |
| 318 TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { | |
| 319 const bool a_false_condition = false; | |
| 320 const char regex[] = | |
| 321 #ifdef _MSC_VER | |
| 322 "gtest-port_test\\.cc\\(\\d+\\):" | |
| 323 #elif GTEST_USES_POSIX_RE | |
| 324 "gtest-port_test\\.cc:[0-9]+" | |
| 325 #else | |
| 326 "gtest-port_test\\.cc:\\d+" | |
| 327 #endif // _MSC_VER | |
| 328 ".*a_false_condition.*Extra info.*"; | |
| 329 | |
| 330 EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info", | |
| 331 regex); | |
| 332 } | |
| 333 | |
| 334 #if GTEST_HAS_DEATH_TEST | |
| 335 | |
| 336 TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { | |
| 337 EXPECT_EXIT({ | |
| 338 GTEST_CHECK_(true) << "Extra info"; | |
| 339 ::std::cerr << "Success\n"; | |
| 340 exit(0); }, | |
| 341 ::testing::ExitedWithCode(0), "Success"); | |
| 342 } | |
| 343 | |
| 344 #endif // GTEST_HAS_DEATH_TEST | |
| 345 | |
| 346 // Verifies that Google Test choose regular expression engine appropriate to | |
| 347 // the platform. The test will produce compiler errors in case of failure. | |
| 348 // For simplicity, we only cover the most important platforms here. | |
| 349 TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) { | |
| 350 #if GTEST_HAS_POSIX_RE | |
| 351 | |
| 352 EXPECT_TRUE(GTEST_USES_POSIX_RE); | |
| 353 | |
| 354 #else | |
| 355 | |
| 356 EXPECT_TRUE(GTEST_USES_SIMPLE_RE); | |
| 357 | |
| 358 #endif | |
| 359 } | |
| 360 | |
| 361 #if GTEST_USES_POSIX_RE | |
| 362 | |
| 363 # if GTEST_HAS_TYPED_TEST | |
| 364 | |
| 365 template <typename Str> | |
| 366 class RETest : public ::testing::Test {}; | |
| 367 | |
| 368 // Defines StringTypes as the list of all string types that class RE | |
| 369 // supports. | |
| 370 typedef testing::Types< | |
| 371 ::std::string, | |
| 372 # if GTEST_HAS_GLOBAL_STRING | |
| 373 ::string, | |
| 374 # endif // GTEST_HAS_GLOBAL_STRING | |
| 375 const char*> StringTypes; | |
| 376 | |
| 377 TYPED_TEST_CASE(RETest, StringTypes); | |
| 378 | |
| 379 // Tests RE's implicit constructors. | |
| 380 TYPED_TEST(RETest, ImplicitConstructorWorks) { | |
| 381 const RE empty(TypeParam("")); | |
| 382 EXPECT_STREQ("", empty.pattern()); | |
| 383 | |
| 384 const RE simple(TypeParam("hello")); | |
| 385 EXPECT_STREQ("hello", simple.pattern()); | |
| 386 | |
| 387 const RE normal(TypeParam(".*(\\w+)")); | |
| 388 EXPECT_STREQ(".*(\\w+)", normal.pattern()); | |
| 389 } | |
| 390 | |
| 391 // Tests that RE's constructors reject invalid regular expressions. | |
| 392 TYPED_TEST(RETest, RejectsInvalidRegex) { | |
| 393 EXPECT_NONFATAL_FAILURE({ | |
| 394 const RE invalid(TypeParam("?")); | |
| 395 }, "\"?\" is not a valid POSIX Extended regular expression."); | |
| 396 } | |
| 397 | |
| 398 // Tests RE::FullMatch(). | |
| 399 TYPED_TEST(RETest, FullMatchWorks) { | |
| 400 const RE empty(TypeParam("")); | |
| 401 EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty)); | |
| 402 EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty)); | |
| 403 | |
| 404 const RE re(TypeParam("a.*z")); | |
| 405 EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re)); | |
| 406 EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re)); | |
| 407 EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re)); | |
| 408 EXPECT_FALSE(RE::FullMatch(TypeParam("azy"), re)); | |
| 409 } | |
| 410 | |
| 411 // Tests RE::PartialMatch(). | |
| 412 TYPED_TEST(RETest, PartialMatchWorks) { | |
| 413 const RE empty(TypeParam("")); | |
| 414 EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty)); | |
| 415 EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty)); | |
| 416 | |
| 417 const RE re(TypeParam("a.*z")); | |
| 418 EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re)); | |
| 419 EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re)); | |
| 420 EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re)); | |
| 421 EXPECT_TRUE(RE::PartialMatch(TypeParam("azy"), re)); | |
| 422 EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re)); | |
| 423 } | |
| 424 | |
| 425 # endif // GTEST_HAS_TYPED_TEST | |
| 426 | |
| 427 #elif GTEST_USES_SIMPLE_RE | |
| 428 | |
| 429 TEST(IsInSetTest, NulCharIsNotInAnySet) { | |
| 430 EXPECT_FALSE(IsInSet('\0', "")); | |
| 431 EXPECT_FALSE(IsInSet('\0', "\0")); | |
| 432 EXPECT_FALSE(IsInSet('\0', "a")); | |
| 433 } | |
| 434 | |
| 435 TEST(IsInSetTest, WorksForNonNulChars) { | |
| 436 EXPECT_FALSE(IsInSet('a', "Ab")); | |
| 437 EXPECT_FALSE(IsInSet('c', "")); | |
| 438 | |
| 439 EXPECT_TRUE(IsInSet('b', "bcd")); | |
| 440 EXPECT_TRUE(IsInSet('b', "ab")); | |
| 441 } | |
| 442 | |
| 443 TEST(IsAsciiDigitTest, IsFalseForNonDigit) { | |
| 444 EXPECT_FALSE(IsAsciiDigit('\0')); | |
| 445 EXPECT_FALSE(IsAsciiDigit(' ')); | |
| 446 EXPECT_FALSE(IsAsciiDigit('+')); | |
| 447 EXPECT_FALSE(IsAsciiDigit('-')); | |
| 448 EXPECT_FALSE(IsAsciiDigit('.')); | |
| 449 EXPECT_FALSE(IsAsciiDigit('a')); | |
| 450 } | |
| 451 | |
| 452 TEST(IsAsciiDigitTest, IsTrueForDigit) { | |
| 453 EXPECT_TRUE(IsAsciiDigit('0')); | |
| 454 EXPECT_TRUE(IsAsciiDigit('1')); | |
| 455 EXPECT_TRUE(IsAsciiDigit('5')); | |
| 456 EXPECT_TRUE(IsAsciiDigit('9')); | |
| 457 } | |
| 458 | |
| 459 TEST(IsAsciiPunctTest, IsFalseForNonPunct) { | |
| 460 EXPECT_FALSE(IsAsciiPunct('\0')); | |
| 461 EXPECT_FALSE(IsAsciiPunct(' ')); | |
| 462 EXPECT_FALSE(IsAsciiPunct('\n')); | |
| 463 EXPECT_FALSE(IsAsciiPunct('a')); | |
| 464 EXPECT_FALSE(IsAsciiPunct('0')); | |
| 465 } | |
| 466 | |
| 467 TEST(IsAsciiPunctTest, IsTrueForPunct) { | |
| 468 for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) { | |
| 469 EXPECT_PRED1(IsAsciiPunct, *p); | |
| 470 } | |
| 471 } | |
| 472 | |
| 473 TEST(IsRepeatTest, IsFalseForNonRepeatChar) { | |
| 474 EXPECT_FALSE(IsRepeat('\0')); | |
| 475 EXPECT_FALSE(IsRepeat(' ')); | |
| 476 EXPECT_FALSE(IsRepeat('a')); | |
| 477 EXPECT_FALSE(IsRepeat('1')); | |
| 478 EXPECT_FALSE(IsRepeat('-')); | |
| 479 } | |
| 480 | |
| 481 TEST(IsRepeatTest, IsTrueForRepeatChar) { | |
| 482 EXPECT_TRUE(IsRepeat('?')); | |
| 483 EXPECT_TRUE(IsRepeat('*')); | |
| 484 EXPECT_TRUE(IsRepeat('+')); | |
| 485 } | |
| 486 | |
| 487 TEST(IsAsciiWhiteSpaceTest, IsFalseForNonWhiteSpace) { | |
| 488 EXPECT_FALSE(IsAsciiWhiteSpace('\0')); | |
| 489 EXPECT_FALSE(IsAsciiWhiteSpace('a')); | |
| 490 EXPECT_FALSE(IsAsciiWhiteSpace('1')); | |
| 491 EXPECT_FALSE(IsAsciiWhiteSpace('+')); | |
| 492 EXPECT_FALSE(IsAsciiWhiteSpace('_')); | |
| 493 } | |
| 494 | |
| 495 TEST(IsAsciiWhiteSpaceTest, IsTrueForWhiteSpace) { | |
| 496 EXPECT_TRUE(IsAsciiWhiteSpace(' ')); | |
| 497 EXPECT_TRUE(IsAsciiWhiteSpace('\n')); | |
| 498 EXPECT_TRUE(IsAsciiWhiteSpace('\r')); | |
| 499 EXPECT_TRUE(IsAsciiWhiteSpace('\t')); | |
| 500 EXPECT_TRUE(IsAsciiWhiteSpace('\v')); | |
| 501 EXPECT_TRUE(IsAsciiWhiteSpace('\f')); | |
| 502 } | |
| 503 | |
| 504 TEST(IsAsciiWordCharTest, IsFalseForNonWordChar) { | |
| 505 EXPECT_FALSE(IsAsciiWordChar('\0')); | |
| 506 EXPECT_FALSE(IsAsciiWordChar('+')); | |
| 507 EXPECT_FALSE(IsAsciiWordChar('.')); | |
| 508 EXPECT_FALSE(IsAsciiWordChar(' ')); | |
| 509 EXPECT_FALSE(IsAsciiWordChar('\n')); | |
| 510 } | |
| 511 | |
| 512 TEST(IsAsciiWordCharTest, IsTrueForLetter) { | |
| 513 EXPECT_TRUE(IsAsciiWordChar('a')); | |
| 514 EXPECT_TRUE(IsAsciiWordChar('b')); | |
| 515 EXPECT_TRUE(IsAsciiWordChar('A')); | |
| 516 EXPECT_TRUE(IsAsciiWordChar('Z')); | |
| 517 } | |
| 518 | |
| 519 TEST(IsAsciiWordCharTest, IsTrueForDigit) { | |
| 520 EXPECT_TRUE(IsAsciiWordChar('0')); | |
| 521 EXPECT_TRUE(IsAsciiWordChar('1')); | |
| 522 EXPECT_TRUE(IsAsciiWordChar('7')); | |
| 523 EXPECT_TRUE(IsAsciiWordChar('9')); | |
| 524 } | |
| 525 | |
| 526 TEST(IsAsciiWordCharTest, IsTrueForUnderscore) { | |
| 527 EXPECT_TRUE(IsAsciiWordChar('_')); | |
| 528 } | |
| 529 | |
| 530 TEST(IsValidEscapeTest, IsFalseForNonPrintable) { | |
| 531 EXPECT_FALSE(IsValidEscape('\0')); | |
| 532 EXPECT_FALSE(IsValidEscape('\007')); | |
| 533 } | |
| 534 | |
| 535 TEST(IsValidEscapeTest, IsFalseForDigit) { | |
| 536 EXPECT_FALSE(IsValidEscape('0')); | |
| 537 EXPECT_FALSE(IsValidEscape('9')); | |
| 538 } | |
| 539 | |
| 540 TEST(IsValidEscapeTest, IsFalseForWhiteSpace) { | |
| 541 EXPECT_FALSE(IsValidEscape(' ')); | |
| 542 EXPECT_FALSE(IsValidEscape('\n')); | |
| 543 } | |
| 544 | |
| 545 TEST(IsValidEscapeTest, IsFalseForSomeLetter) { | |
| 546 EXPECT_FALSE(IsValidEscape('a')); | |
| 547 EXPECT_FALSE(IsValidEscape('Z')); | |
| 548 } | |
| 549 | |
| 550 TEST(IsValidEscapeTest, IsTrueForPunct) { | |
| 551 EXPECT_TRUE(IsValidEscape('.')); | |
| 552 EXPECT_TRUE(IsValidEscape('-')); | |
| 553 EXPECT_TRUE(IsValidEscape('^')); | |
| 554 EXPECT_TRUE(IsValidEscape('$')); | |
| 555 EXPECT_TRUE(IsValidEscape('(')); | |
| 556 EXPECT_TRUE(IsValidEscape(']')); | |
| 557 EXPECT_TRUE(IsValidEscape('{')); | |
| 558 EXPECT_TRUE(IsValidEscape('|')); | |
| 559 } | |
| 560 | |
| 561 TEST(IsValidEscapeTest, IsTrueForSomeLetter) { | |
| 562 EXPECT_TRUE(IsValidEscape('d')); | |
| 563 EXPECT_TRUE(IsValidEscape('D')); | |
| 564 EXPECT_TRUE(IsValidEscape('s')); | |
| 565 EXPECT_TRUE(IsValidEscape('S')); | |
| 566 EXPECT_TRUE(IsValidEscape('w')); | |
| 567 EXPECT_TRUE(IsValidEscape('W')); | |
| 568 } | |
| 569 | |
| 570 TEST(AtomMatchesCharTest, EscapedPunct) { | |
| 571 EXPECT_FALSE(AtomMatchesChar(true, '\\', '\0')); | |
| 572 EXPECT_FALSE(AtomMatchesChar(true, '\\', ' ')); | |
| 573 EXPECT_FALSE(AtomMatchesChar(true, '_', '.')); | |
| 574 EXPECT_FALSE(AtomMatchesChar(true, '.', 'a')); | |
| 575 | |
| 576 EXPECT_TRUE(AtomMatchesChar(true, '\\', '\\')); | |
| 577 EXPECT_TRUE(AtomMatchesChar(true, '_', '_')); | |
| 578 EXPECT_TRUE(AtomMatchesChar(true, '+', '+')); | |
| 579 EXPECT_TRUE(AtomMatchesChar(true, '.', '.')); | |
| 580 } | |
| 581 | |
| 582 TEST(AtomMatchesCharTest, Escaped_d) { | |
| 583 EXPECT_FALSE(AtomMatchesChar(true, 'd', '\0')); | |
| 584 EXPECT_FALSE(AtomMatchesChar(true, 'd', 'a')); | |
| 585 EXPECT_FALSE(AtomMatchesChar(true, 'd', '.')); | |
| 586 | |
| 587 EXPECT_TRUE(AtomMatchesChar(true, 'd', '0')); | |
| 588 EXPECT_TRUE(AtomMatchesChar(true, 'd', '9')); | |
| 589 } | |
| 590 | |
| 591 TEST(AtomMatchesCharTest, Escaped_D) { | |
| 592 EXPECT_FALSE(AtomMatchesChar(true, 'D', '0')); | |
| 593 EXPECT_FALSE(AtomMatchesChar(true, 'D', '9')); | |
| 594 | |
| 595 EXPECT_TRUE(AtomMatchesChar(true, 'D', '\0')); | |
| 596 EXPECT_TRUE(AtomMatchesChar(true, 'D', 'a')); | |
| 597 EXPECT_TRUE(AtomMatchesChar(true, 'D', '-')); | |
| 598 } | |
| 599 | |
| 600 TEST(AtomMatchesCharTest, Escaped_s) { | |
| 601 EXPECT_FALSE(AtomMatchesChar(true, 's', '\0')); | |
| 602 EXPECT_FALSE(AtomMatchesChar(true, 's', 'a')); | |
| 603 EXPECT_FALSE(AtomMatchesChar(true, 's', '.')); | |
| 604 EXPECT_FALSE(AtomMatchesChar(true, 's', '9')); | |
| 605 | |
| 606 EXPECT_TRUE(AtomMatchesChar(true, 's', ' ')); | |
| 607 EXPECT_TRUE(AtomMatchesChar(true, 's', '\n')); | |
| 608 EXPECT_TRUE(AtomMatchesChar(true, 's', '\t')); | |
| 609 } | |
| 610 | |
| 611 TEST(AtomMatchesCharTest, Escaped_S) { | |
| 612 EXPECT_FALSE(AtomMatchesChar(true, 'S', ' ')); | |
| 613 EXPECT_FALSE(AtomMatchesChar(true, 'S', '\r')); | |
| 614 | |
| 615 EXPECT_TRUE(AtomMatchesChar(true, 'S', '\0')); | |
| 616 EXPECT_TRUE(AtomMatchesChar(true, 'S', 'a')); | |
| 617 EXPECT_TRUE(AtomMatchesChar(true, 'S', '9')); | |
| 618 } | |
| 619 | |
| 620 TEST(AtomMatchesCharTest, Escaped_w) { | |
| 621 EXPECT_FALSE(AtomMatchesChar(true, 'w', '\0')); | |
| 622 EXPECT_FALSE(AtomMatchesChar(true, 'w', '+')); | |
| 623 EXPECT_FALSE(AtomMatchesChar(true, 'w', ' ')); | |
| 624 EXPECT_FALSE(AtomMatchesChar(true, 'w', '\n')); | |
| 625 | |
| 626 EXPECT_TRUE(AtomMatchesChar(true, 'w', '0')); | |
| 627 EXPECT_TRUE(AtomMatchesChar(true, 'w', 'b')); | |
| 628 EXPECT_TRUE(AtomMatchesChar(true, 'w', 'C')); | |
| 629 EXPECT_TRUE(AtomMatchesChar(true, 'w', '_')); | |
| 630 } | |
| 631 | |
| 632 TEST(AtomMatchesCharTest, Escaped_W) { | |
| 633 EXPECT_FALSE(AtomMatchesChar(true, 'W', 'A')); | |
| 634 EXPECT_FALSE(AtomMatchesChar(true, 'W', 'b')); | |
| 635 EXPECT_FALSE(AtomMatchesChar(true, 'W', '9')); | |
| 636 EXPECT_FALSE(AtomMatchesChar(true, 'W', '_')); | |
| 637 | |
| 638 EXPECT_TRUE(AtomMatchesChar(true, 'W', '\0')); | |
| 639 EXPECT_TRUE(AtomMatchesChar(true, 'W', '*')); | |
| 640 EXPECT_TRUE(AtomMatchesChar(true, 'W', '\n')); | |
| 641 } | |
| 642 | |
| 643 TEST(AtomMatchesCharTest, EscapedWhiteSpace) { | |
| 644 EXPECT_FALSE(AtomMatchesChar(true, 'f', '\0')); | |
| 645 EXPECT_FALSE(AtomMatchesChar(true, 'f', '\n')); | |
| 646 EXPECT_FALSE(AtomMatchesChar(true, 'n', '\0')); | |
| 647 EXPECT_FALSE(AtomMatchesChar(true, 'n', '\r')); | |
| 648 EXPECT_FALSE(AtomMatchesChar(true, 'r', '\0')); | |
| 649 EXPECT_FALSE(AtomMatchesChar(true, 'r', 'a')); | |
| 650 EXPECT_FALSE(AtomMatchesChar(true, 't', '\0')); | |
| 651 EXPECT_FALSE(AtomMatchesChar(true, 't', 't')); | |
| 652 EXPECT_FALSE(AtomMatchesChar(true, 'v', '\0')); | |
| 653 EXPECT_FALSE(AtomMatchesChar(true, 'v', '\f')); | |
| 654 | |
| 655 EXPECT_TRUE(AtomMatchesChar(true, 'f', '\f')); | |
| 656 EXPECT_TRUE(AtomMatchesChar(true, 'n', '\n')); | |
| 657 EXPECT_TRUE(AtomMatchesChar(true, 'r', '\r')); | |
| 658 EXPECT_TRUE(AtomMatchesChar(true, 't', '\t')); | |
| 659 EXPECT_TRUE(AtomMatchesChar(true, 'v', '\v')); | |
| 660 } | |
| 661 | |
| 662 TEST(AtomMatchesCharTest, UnescapedDot) { | |
| 663 EXPECT_FALSE(AtomMatchesChar(false, '.', '\n')); | |
| 664 | |
| 665 EXPECT_TRUE(AtomMatchesChar(false, '.', '\0')); | |
| 666 EXPECT_TRUE(AtomMatchesChar(false, '.', '.')); | |
| 667 EXPECT_TRUE(AtomMatchesChar(false, '.', 'a')); | |
| 668 EXPECT_TRUE(AtomMatchesChar(false, '.', ' ')); | |
| 669 } | |
| 670 | |
| 671 TEST(AtomMatchesCharTest, UnescapedChar) { | |
| 672 EXPECT_FALSE(AtomMatchesChar(false, 'a', '\0')); | |
| 673 EXPECT_FALSE(AtomMatchesChar(false, 'a', 'b')); | |
| 674 EXPECT_FALSE(AtomMatchesChar(false, '$', 'a')); | |
| 675 | |
| 676 EXPECT_TRUE(AtomMatchesChar(false, '$', '$')); | |
| 677 EXPECT_TRUE(AtomMatchesChar(false, '5', '5')); | |
| 678 EXPECT_TRUE(AtomMatchesChar(false, 'Z', 'Z')); | |
| 679 } | |
| 680 | |
| 681 TEST(ValidateRegexTest, GeneratesFailureAndReturnsFalseForInvalid) { | |
| 682 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(NULL)), | |
| 683 "NULL is not a valid simple regular expression"); | |
| 684 EXPECT_NONFATAL_FAILURE( | |
| 685 ASSERT_FALSE(ValidateRegex("a\\")), | |
| 686 "Syntax error at index 1 in simple regular expression \"a\\\": "); | |
| 687 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a\\")), | |
| 688 "'\\' cannot appear at the end"); | |
| 689 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\n\\")), | |
| 690 "'\\' cannot appear at the end"); | |
| 691 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\s\\hb")), | |
| 692 "invalid escape sequence \"\\h\""); | |
| 693 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^^")), | |
| 694 "'^' can only appear at the beginning"); | |
| 695 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(".*^b")), | |
| 696 "'^' can only appear at the beginning"); | |
| 697 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("$$")), | |
| 698 "'$' can only appear at the end"); | |
| 699 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^$a")), | |
| 700 "'$' can only appear at the end"); | |
| 701 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a(b")), | |
| 702 "'(' is unsupported"); | |
| 703 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("ab)")), | |
| 704 "')' is unsupported"); | |
| 705 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("[ab")), | |
| 706 "'[' is unsupported"); | |
| 707 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a{2")), | |
| 708 "'{' is unsupported"); | |
| 709 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("?")), | |
| 710 "'?' can only follow a repeatable token"); | |
| 711 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^*")), | |
| 712 "'*' can only follow a repeatable token"); | |
| 713 EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("5*+")), | |
| 714 "'+' can only follow a repeatable token"); | |
| 715 } | |
| 716 | |
| 717 TEST(ValidateRegexTest, ReturnsTrueForValid) { | |
| 718 EXPECT_TRUE(ValidateRegex("")); | |
| 719 EXPECT_TRUE(ValidateRegex("a")); | |
| 720 EXPECT_TRUE(ValidateRegex(".*")); | |
| 721 EXPECT_TRUE(ValidateRegex("^a_+")); | |
| 722 EXPECT_TRUE(ValidateRegex("^a\\t\\&?")); | |
| 723 EXPECT_TRUE(ValidateRegex("09*$")); | |
| 724 EXPECT_TRUE(ValidateRegex("^Z$")); | |
| 725 EXPECT_TRUE(ValidateRegex("a\\^Z\\$\\(\\)\\|\\[\\]\\{\\}")); | |
| 726 } | |
| 727 | |
| 728 TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrOne) { | |
| 729 EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "a", "ba")); | |
| 730 // Repeating more than once. | |
| 731 EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "aab")); | |
| 732 | |
| 733 // Repeating zero times. | |
| 734 EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ba")); | |
| 735 // Repeating once. | |
| 736 EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ab")); | |
| 737 EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '#', '?', ".", "##")); | |
| 738 } | |
| 739 | |
| 740 TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrMany) { | |
| 741 EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '*', "a$", "baab")); | |
| 742 | |
| 743 // Repeating zero times. | |
| 744 EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "bc")); | |
| 745 // Repeating once. | |
| 746 EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "abc")); | |
| 747 // Repeating more than once. | |
| 748 EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '*', "-", "ab_1-g")); | |
| 749 } | |
| 750 | |
| 751 TEST(MatchRepetitionAndRegexAtHeadTest, WorksForOneOrMany) { | |
| 752 EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "a$", "baab")); | |
| 753 // Repeating zero times. | |
| 754 EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "bc")); | |
| 755 | |
| 756 // Repeating once. | |
| 757 EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "abc")); | |
| 758 // Repeating more than once. | |
| 759 EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '+', "-", "ab_1-g")); | |
| 760 } | |
| 761 | |
| 762 TEST(MatchRegexAtHeadTest, ReturnsTrueForEmptyRegex) { | |
| 763 EXPECT_TRUE(MatchRegexAtHead("", "")); | |
| 764 EXPECT_TRUE(MatchRegexAtHead("", "ab")); | |
| 765 } | |
| 766 | |
| 767 TEST(MatchRegexAtHeadTest, WorksWhenDollarIsInRegex) { | |
| 768 EXPECT_FALSE(MatchRegexAtHead("$", "a")); | |
| 769 | |
| 770 EXPECT_TRUE(MatchRegexAtHead("$", "")); | |
| 771 EXPECT_TRUE(MatchRegexAtHead("a$", "a")); | |
| 772 } | |
| 773 | |
| 774 TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithEscapeSequence) { | |
| 775 EXPECT_FALSE(MatchRegexAtHead("\\w", "+")); | |
| 776 EXPECT_FALSE(MatchRegexAtHead("\\W", "ab")); | |
| 777 | |
| 778 EXPECT_TRUE(MatchRegexAtHead("\\sa", "\nab")); | |
| 779 EXPECT_TRUE(MatchRegexAtHead("\\d", "1a")); | |
| 780 } | |
| 781 | |
| 782 TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) { | |
| 783 EXPECT_FALSE(MatchRegexAtHead(".+a", "abc")); | |
| 784 EXPECT_FALSE(MatchRegexAtHead("a?b", "aab")); | |
| 785 | |
| 786 EXPECT_TRUE(MatchRegexAtHead(".*a", "bc12-ab")); | |
| 787 EXPECT_TRUE(MatchRegexAtHead("a?b", "b")); | |
| 788 EXPECT_TRUE(MatchRegexAtHead("a?b", "ab")); | |
| 789 } | |
| 790 | |
| 791 TEST(MatchRegexAtHeadTest, | |
| 792 WorksWhenRegexStartsWithRepetionOfEscapeSequence) { | |
| 793 EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc")); | |
| 794 EXPECT_FALSE(MatchRegexAtHead("\\s?b", " b")); | |
| 795 | |
| 796 EXPECT_TRUE(MatchRegexAtHead("\\(*a", "((((ab")); | |
| 797 EXPECT_TRUE(MatchRegexAtHead("\\^?b", "^b")); | |
| 798 EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "b")); | |
| 799 EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "\\b")); | |
| 800 } | |
| 801 | |
| 802 TEST(MatchRegexAtHeadTest, MatchesSequentially) { | |
| 803 EXPECT_FALSE(MatchRegexAtHead("ab.*c", "acabc")); | |
| 804 | |
| 805 EXPECT_TRUE(MatchRegexAtHead("ab.*c", "ab-fsc")); | |
| 806 } | |
| 807 | |
| 808 TEST(MatchRegexAnywhereTest, ReturnsFalseWhenStringIsNull) { | |
| 809 EXPECT_FALSE(MatchRegexAnywhere("", NULL)); | |
| 810 } | |
| 811 | |
| 812 TEST(MatchRegexAnywhereTest, WorksWhenRegexStartsWithCaret) { | |
| 813 EXPECT_FALSE(MatchRegexAnywhere("^a", "ba")); | |
| 814 EXPECT_FALSE(MatchRegexAnywhere("^$", "a")); | |
| 815 | |
| 816 EXPECT_TRUE(MatchRegexAnywhere("^a", "ab")); | |
| 817 EXPECT_TRUE(MatchRegexAnywhere("^", "ab")); | |
| 818 EXPECT_TRUE(MatchRegexAnywhere("^$", "")); | |
| 819 } | |
| 820 | |
| 821 TEST(MatchRegexAnywhereTest, ReturnsFalseWhenNoMatch) { | |
| 822 EXPECT_FALSE(MatchRegexAnywhere("a", "bcde123")); | |
| 823 EXPECT_FALSE(MatchRegexAnywhere("a.+a", "--aa88888888")); | |
| 824 } | |
| 825 | |
| 826 TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingPrefix) { | |
| 827 EXPECT_TRUE(MatchRegexAnywhere("\\w+", "ab1_ - 5")); | |
| 828 EXPECT_TRUE(MatchRegexAnywhere(".*=", "=")); | |
| 829 EXPECT_TRUE(MatchRegexAnywhere("x.*ab?.*bc", "xaaabc")); | |
| 830 } | |
| 831 | |
| 832 TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) { | |
| 833 EXPECT_TRUE(MatchRegexAnywhere("\\w+", "$$$ ab1_ - 5")); | |
| 834 EXPECT_TRUE(MatchRegexAnywhere("\\.+=", "= ...=")); | |
| 835 } | |
| 836 | |
| 837 // Tests RE's implicit constructors. | |
| 838 TEST(RETest, ImplicitConstructorWorks) { | |
| 839 const RE empty(""); | |
| 840 EXPECT_STREQ("", empty.pattern()); | |
| 841 | |
| 842 const RE simple("hello"); | |
| 843 EXPECT_STREQ("hello", simple.pattern()); | |
| 844 } | |
| 845 | |
| 846 // Tests that RE's constructors reject invalid regular expressions. | |
| 847 TEST(RETest, RejectsInvalidRegex) { | |
| 848 EXPECT_NONFATAL_FAILURE({ | |
| 849 const RE normal(NULL); | |
| 850 }, "NULL is not a valid simple regular expression"); | |
| 851 | |
| 852 EXPECT_NONFATAL_FAILURE({ | |
| 853 const RE normal(".*(\\w+"); | |
| 854 }, "'(' is unsupported"); | |
| 855 | |
| 856 EXPECT_NONFATAL_FAILURE({ | |
| 857 const RE invalid("^?"); | |
| 858 }, "'?' can only follow a repeatable token"); | |
| 859 } | |
| 860 | |
| 861 // Tests RE::FullMatch(). | |
| 862 TEST(RETest, FullMatchWorks) { | |
| 863 const RE empty(""); | |
| 864 EXPECT_TRUE(RE::FullMatch("", empty)); | |
| 865 EXPECT_FALSE(RE::FullMatch("a", empty)); | |
| 866 | |
| 867 const RE re1("a"); | |
| 868 EXPECT_TRUE(RE::FullMatch("a", re1)); | |
| 869 | |
| 870 const RE re("a.*z"); | |
| 871 EXPECT_TRUE(RE::FullMatch("az", re)); | |
| 872 EXPECT_TRUE(RE::FullMatch("axyz", re)); | |
| 873 EXPECT_FALSE(RE::FullMatch("baz", re)); | |
| 874 EXPECT_FALSE(RE::FullMatch("azy", re)); | |
| 875 } | |
| 876 | |
| 877 // Tests RE::PartialMatch(). | |
| 878 TEST(RETest, PartialMatchWorks) { | |
| 879 const RE empty(""); | |
| 880 EXPECT_TRUE(RE::PartialMatch("", empty)); | |
| 881 EXPECT_TRUE(RE::PartialMatch("a", empty)); | |
| 882 | |
| 883 const RE re("a.*z"); | |
| 884 EXPECT_TRUE(RE::PartialMatch("az", re)); | |
| 885 EXPECT_TRUE(RE::PartialMatch("axyz", re)); | |
| 886 EXPECT_TRUE(RE::PartialMatch("baz", re)); | |
| 887 EXPECT_TRUE(RE::PartialMatch("azy", re)); | |
| 888 EXPECT_FALSE(RE::PartialMatch("zza", re)); | |
| 889 } | |
| 890 | |
| 891 #endif // GTEST_USES_POSIX_RE | |
| 892 | |
| 893 #if !GTEST_OS_WINDOWS_MOBILE | |
| 894 | |
| 895 TEST(CaptureTest, CapturesStdout) { | |
| 896 CaptureStdout(); | |
| 897 fprintf(stdout, "abc"); | |
| 898 EXPECT_STREQ("abc", GetCapturedStdout().c_str()); | |
| 899 | |
| 900 CaptureStdout(); | |
| 901 fprintf(stdout, "def%cghi", '\0'); | |
| 902 EXPECT_EQ(::std::string("def\0ghi", 7), ::std::string(GetCapturedStdout())); | |
| 903 } | |
| 904 | |
| 905 TEST(CaptureTest, CapturesStderr) { | |
| 906 CaptureStderr(); | |
| 907 fprintf(stderr, "jkl"); | |
| 908 EXPECT_STREQ("jkl", GetCapturedStderr().c_str()); | |
| 909 | |
| 910 CaptureStderr(); | |
| 911 fprintf(stderr, "jkl%cmno", '\0'); | |
| 912 EXPECT_EQ(::std::string("jkl\0mno", 7), ::std::string(GetCapturedStderr())); | |
| 913 } | |
| 914 | |
| 915 // Tests that stdout and stderr capture don't interfere with each other. | |
| 916 TEST(CaptureTest, CapturesStdoutAndStderr) { | |
| 917 CaptureStdout(); | |
| 918 CaptureStderr(); | |
| 919 fprintf(stdout, "pqr"); | |
| 920 fprintf(stderr, "stu"); | |
| 921 EXPECT_STREQ("pqr", GetCapturedStdout().c_str()); | |
| 922 EXPECT_STREQ("stu", GetCapturedStderr().c_str()); | |
| 923 } | |
| 924 | |
| 925 TEST(CaptureDeathTest, CannotReenterStdoutCapture) { | |
| 926 CaptureStdout(); | |
| 927 EXPECT_DEATH_IF_SUPPORTED(CaptureStdout();, | |
| 928 "Only one stdout capturer can exist at a time"); | |
| 929 GetCapturedStdout(); | |
| 930 | |
| 931 // We cannot test stderr capturing using death tests as they use it | |
| 932 // themselves. | |
| 933 } | |
| 934 | |
| 935 #endif // !GTEST_OS_WINDOWS_MOBILE | |
| 936 | |
| 937 TEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) { | |
| 938 ThreadLocal<int> t1; | |
| 939 EXPECT_EQ(0, t1.get()); | |
| 940 | |
| 941 ThreadLocal<void*> t2; | |
| 942 EXPECT_TRUE(t2.get() == NULL); | |
| 943 } | |
| 944 | |
| 945 TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) { | |
| 946 ThreadLocal<int> t1(123); | |
| 947 EXPECT_EQ(123, t1.get()); | |
| 948 | |
| 949 int i = 0; | |
| 950 ThreadLocal<int*> t2(&i); | |
| 951 EXPECT_EQ(&i, t2.get()); | |
| 952 } | |
| 953 | |
| 954 class NoDefaultContructor { | |
| 955 public: | |
| 956 explicit NoDefaultContructor(const char*) {} | |
| 957 NoDefaultContructor(const NoDefaultContructor&) {} | |
| 958 }; | |
| 959 | |
| 960 TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) { | |
| 961 ThreadLocal<NoDefaultContructor> bar(NoDefaultContructor("foo")); | |
| 962 bar.pointer(); | |
| 963 } | |
| 964 | |
| 965 TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { | |
| 966 ThreadLocal<String> thread_local; | |
| 967 | |
| 968 EXPECT_EQ(thread_local.pointer(), &(thread_local.get())); | |
| 969 | |
| 970 // Verifies the condition still holds after calling set. | |
| 971 thread_local.set("foo"); | |
| 972 EXPECT_EQ(thread_local.pointer(), &(thread_local.get())); | |
| 973 } | |
| 974 | |
| 975 TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { | |
| 976 ThreadLocal<String> thread_local; | |
| 977 const ThreadLocal<String>& const_thread_local = thread_local; | |
| 978 | |
| 979 EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer()); | |
| 980 | |
| 981 thread_local.set("foo"); | |
| 982 EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer()); | |
| 983 } | |
| 984 | |
| 985 #if GTEST_IS_THREADSAFE | |
| 986 | |
| 987 void AddTwo(int* param) { *param += 2; } | |
| 988 | |
| 989 TEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) { | |
| 990 int i = 40; | |
| 991 ThreadWithParam<int*> thread(&AddTwo, &i, NULL); | |
| 992 thread.Join(); | |
| 993 EXPECT_EQ(42, i); | |
| 994 } | |
| 995 | |
| 996 TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) { | |
| 997 // AssertHeld() is flaky only in the presence of multiple threads accessing | |
| 998 // the lock. In this case, the test is robust. | |
| 999 EXPECT_DEATH_IF_SUPPORTED({ | |
| 1000 Mutex m; | |
| 1001 { MutexLock lock(&m); } | |
| 1002 m.AssertHeld(); | |
| 1003 }, | |
| 1004 "thread .*hold"); | |
| 1005 } | |
| 1006 | |
| 1007 TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) { | |
| 1008 Mutex m; | |
| 1009 MutexLock lock(&m); | |
| 1010 m.AssertHeld(); | |
| 1011 } | |
| 1012 | |
| 1013 class AtomicCounterWithMutex { | |
| 1014 public: | |
| 1015 explicit AtomicCounterWithMutex(Mutex* mutex) : | |
| 1016 value_(0), mutex_(mutex), random_(42) {} | |
| 1017 | |
| 1018 void Increment() { | |
| 1019 MutexLock lock(mutex_); | |
| 1020 int temp = value_; | |
| 1021 { | |
| 1022 // Locking a mutex puts up a memory barrier, preventing reads and | |
| 1023 // writes to value_ rearranged when observed from other threads. | |
| 1024 // | |
| 1025 // We cannot use Mutex and MutexLock here or rely on their memory | |
| 1026 // barrier functionality as we are testing them here. | |
| 1027 pthread_mutex_t memory_barrier_mutex; | |
| 1028 GTEST_CHECK_POSIX_SUCCESS_( | |
| 1029 pthread_mutex_init(&memory_barrier_mutex, NULL)); | |
| 1030 GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex)); | |
| 1031 | |
| 1032 SleepMilliseconds(random_.Generate(30)); | |
| 1033 | |
| 1034 GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex)); | |
| 1035 } | |
| 1036 value_ = temp + 1; | |
| 1037 } | |
| 1038 int value() const { return value_; } | |
| 1039 | |
| 1040 private: | |
| 1041 volatile int value_; | |
| 1042 Mutex* const mutex_; // Protects value_. | |
| 1043 Random random_; | |
| 1044 }; | |
| 1045 | |
| 1046 void CountingThreadFunc(pair<AtomicCounterWithMutex*, int> param) { | |
| 1047 for (int i = 0; i < param.second; ++i) | |
| 1048 param.first->Increment(); | |
| 1049 } | |
| 1050 | |
| 1051 // Tests that the mutex only lets one thread at a time to lock it. | |
| 1052 TEST(MutexTest, OnlyOneThreadCanLockAtATime) { | |
| 1053 Mutex mutex; | |
| 1054 AtomicCounterWithMutex locked_counter(&mutex); | |
| 1055 | |
| 1056 typedef ThreadWithParam<pair<AtomicCounterWithMutex*, int> > ThreadType; | |
| 1057 const int kCycleCount = 20; | |
| 1058 const int kThreadCount = 7; | |
| 1059 scoped_ptr<ThreadType> counting_threads[kThreadCount]; | |
| 1060 Notification threads_can_start; | |
| 1061 // Creates and runs kThreadCount threads that increment locked_counter | |
| 1062 // kCycleCount times each. | |
| 1063 for (int i = 0; i < kThreadCount; ++i) { | |
| 1064 counting_threads[i].reset(new ThreadType(&CountingThreadFunc, | |
| 1065 make_pair(&locked_counter, | |
| 1066 kCycleCount), | |
| 1067 &threads_can_start)); | |
| 1068 } | |
| 1069 threads_can_start.Notify(); | |
| 1070 for (int i = 0; i < kThreadCount; ++i) | |
| 1071 counting_threads[i]->Join(); | |
| 1072 | |
| 1073 // If the mutex lets more than one thread to increment the counter at a | |
| 1074 // time, they are likely to encounter a race condition and have some | |
| 1075 // increments overwritten, resulting in the lower then expected counter | |
| 1076 // value. | |
| 1077 EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value()); | |
| 1078 } | |
| 1079 | |
| 1080 template <typename T> | |
| 1081 void RunFromThread(void (func)(T), T param) { | |
| 1082 ThreadWithParam<T> thread(func, param, NULL); | |
| 1083 thread.Join(); | |
| 1084 } | |
| 1085 | |
| 1086 void RetrieveThreadLocalValue(pair<ThreadLocal<String>*, String*> param) { | |
| 1087 *param.second = param.first->get(); | |
| 1088 } | |
| 1089 | |
| 1090 TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { | |
| 1091 ThreadLocal<String> thread_local("foo"); | |
| 1092 EXPECT_STREQ("foo", thread_local.get().c_str()); | |
| 1093 | |
| 1094 thread_local.set("bar"); | |
| 1095 EXPECT_STREQ("bar", thread_local.get().c_str()); | |
| 1096 | |
| 1097 String result; | |
| 1098 RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result)); | |
| 1099 EXPECT_STREQ("foo", result.c_str()); | |
| 1100 } | |
| 1101 | |
| 1102 // DestructorTracker keeps track of whether its instances have been | |
| 1103 // destroyed. | |
| 1104 static std::vector<bool> g_destroyed; | |
| 1105 | |
| 1106 class DestructorTracker { | |
| 1107 public: | |
| 1108 DestructorTracker() : index_(GetNewIndex()) {} | |
| 1109 DestructorTracker(const DestructorTracker& /* rhs */) | |
| 1110 : index_(GetNewIndex()) {} | |
| 1111 ~DestructorTracker() { | |
| 1112 // We never access g_destroyed concurrently, so we don't need to | |
| 1113 // protect the write operation under a mutex. | |
| 1114 g_destroyed[index_] = true; | |
| 1115 } | |
| 1116 | |
| 1117 private: | |
| 1118 static int GetNewIndex() { | |
| 1119 g_destroyed.push_back(false); | |
| 1120 return g_destroyed.size() - 1; | |
| 1121 } | |
| 1122 const int index_; | |
| 1123 }; | |
| 1124 | |
| 1125 typedef ThreadLocal<DestructorTracker>* ThreadParam; | |
| 1126 | |
| 1127 void CallThreadLocalGet(ThreadParam thread_local) { | |
| 1128 thread_local->get(); | |
| 1129 } | |
| 1130 | |
| 1131 // Tests that when a ThreadLocal object dies in a thread, it destroys | |
| 1132 // the managed object for that thread. | |
| 1133 TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) { | |
| 1134 g_destroyed.clear(); | |
| 1135 | |
| 1136 { | |
| 1137 // The next line default constructs a DestructorTracker object as | |
| 1138 // the default value of objects managed by thread_local. | |
| 1139 ThreadLocal<DestructorTracker> thread_local; | |
| 1140 ASSERT_EQ(1U, g_destroyed.size()); | |
| 1141 ASSERT_FALSE(g_destroyed[0]); | |
| 1142 | |
| 1143 // This creates another DestructorTracker object for the main thread. | |
| 1144 thread_local.get(); | |
| 1145 ASSERT_EQ(2U, g_destroyed.size()); | |
| 1146 ASSERT_FALSE(g_destroyed[0]); | |
| 1147 ASSERT_FALSE(g_destroyed[1]); | |
| 1148 } | |
| 1149 | |
| 1150 // Now thread_local has died. It should have destroyed both the | |
| 1151 // default value shared by all threads and the value for the main | |
| 1152 // thread. | |
| 1153 ASSERT_EQ(2U, g_destroyed.size()); | |
| 1154 EXPECT_TRUE(g_destroyed[0]); | |
| 1155 EXPECT_TRUE(g_destroyed[1]); | |
| 1156 | |
| 1157 g_destroyed.clear(); | |
| 1158 } | |
| 1159 | |
| 1160 // Tests that when a thread exits, the thread-local object for that | |
| 1161 // thread is destroyed. | |
| 1162 TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { | |
| 1163 g_destroyed.clear(); | |
| 1164 | |
| 1165 { | |
| 1166 // The next line default constructs a DestructorTracker object as | |
| 1167 // the default value of objects managed by thread_local. | |
| 1168 ThreadLocal<DestructorTracker> thread_local; | |
| 1169 ASSERT_EQ(1U, g_destroyed.size()); | |
| 1170 ASSERT_FALSE(g_destroyed[0]); | |
| 1171 | |
| 1172 // This creates another DestructorTracker object in the new thread. | |
| 1173 ThreadWithParam<ThreadParam> thread( | |
| 1174 &CallThreadLocalGet, &thread_local, NULL); | |
| 1175 thread.Join(); | |
| 1176 | |
| 1177 // Now the new thread has exited. The per-thread object for it | |
| 1178 // should have been destroyed. | |
| 1179 ASSERT_EQ(2U, g_destroyed.size()); | |
| 1180 ASSERT_FALSE(g_destroyed[0]); | |
| 1181 ASSERT_TRUE(g_destroyed[1]); | |
| 1182 } | |
| 1183 | |
| 1184 // Now thread_local has died. The default value should have been | |
| 1185 // destroyed too. | |
| 1186 ASSERT_EQ(2U, g_destroyed.size()); | |
| 1187 EXPECT_TRUE(g_destroyed[0]); | |
| 1188 EXPECT_TRUE(g_destroyed[1]); | |
| 1189 | |
| 1190 g_destroyed.clear(); | |
| 1191 } | |
| 1192 | |
| 1193 TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { | |
| 1194 ThreadLocal<String> thread_local; | |
| 1195 thread_local.set("Foo"); | |
| 1196 EXPECT_STREQ("Foo", thread_local.get().c_str()); | |
| 1197 | |
| 1198 String result; | |
| 1199 RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result)); | |
| 1200 EXPECT_TRUE(result.c_str() == NULL); | |
| 1201 } | |
| 1202 | |
| 1203 #endif // GTEST_IS_THREADSAFE | |
| 1204 | |
| 1205 } // namespace internal | |
| 1206 } // namespace testing | |
| OLD | NEW |