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