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 |