1f904a612d9444ab36c07a8e619c113432e046f49vladlosev// Copyright 2008, Google Inc.
2f904a612d9444ab36c07a8e619c113432e046f49vladlosev// All rights reserved.
3f904a612d9444ab36c07a8e619c113432e046f49vladlosev//
4f904a612d9444ab36c07a8e619c113432e046f49vladlosev// Redistribution and use in source and binary forms, with or without
5f904a612d9444ab36c07a8e619c113432e046f49vladlosev// modification, are permitted provided that the following conditions are
6f904a612d9444ab36c07a8e619c113432e046f49vladlosev// met:
7f904a612d9444ab36c07a8e619c113432e046f49vladlosev//
8f904a612d9444ab36c07a8e619c113432e046f49vladlosev//     * Redistributions of source code must retain the above copyright
9f904a612d9444ab36c07a8e619c113432e046f49vladlosev// notice, this list of conditions and the following disclaimer.
10f904a612d9444ab36c07a8e619c113432e046f49vladlosev//     * Redistributions in binary form must reproduce the above
11f904a612d9444ab36c07a8e619c113432e046f49vladlosev// copyright notice, this list of conditions and the following disclaimer
12f904a612d9444ab36c07a8e619c113432e046f49vladlosev// in the documentation and/or other materials provided with the
13f904a612d9444ab36c07a8e619c113432e046f49vladlosev// distribution.
14f904a612d9444ab36c07a8e619c113432e046f49vladlosev//     * Neither the name of Google Inc. nor the names of its
15f904a612d9444ab36c07a8e619c113432e046f49vladlosev// contributors may be used to endorse or promote products derived from
16f904a612d9444ab36c07a8e619c113432e046f49vladlosev// this software without specific prior written permission.
17f904a612d9444ab36c07a8e619c113432e046f49vladlosev//
18f904a612d9444ab36c07a8e619c113432e046f49vladlosev// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19f904a612d9444ab36c07a8e619c113432e046f49vladlosev// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20f904a612d9444ab36c07a8e619c113432e046f49vladlosev// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21f904a612d9444ab36c07a8e619c113432e046f49vladlosev// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22f904a612d9444ab36c07a8e619c113432e046f49vladlosev// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23f904a612d9444ab36c07a8e619c113432e046f49vladlosev// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24f904a612d9444ab36c07a8e619c113432e046f49vladlosev// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25f904a612d9444ab36c07a8e619c113432e046f49vladlosev// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26f904a612d9444ab36c07a8e619c113432e046f49vladlosev// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27f904a612d9444ab36c07a8e619c113432e046f49vladlosev// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28f904a612d9444ab36c07a8e619c113432e046f49vladlosev// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29f904a612d9444ab36c07a8e619c113432e046f49vladlosev//
30d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan// Authors: vladl@google.com (Vlad Losev), wan@google.com (Zhanyong Wan)
31f904a612d9444ab36c07a8e619c113432e046f49vladlosev//
32f904a612d9444ab36c07a8e619c113432e046f49vladlosev// This file tests the internal cross-platform support utilities.
33f904a612d9444ab36c07a8e619c113432e046f49vladlosev
342620c79810d4741922e9fa89050c0af564994f24zhanyong.wan#include "gtest/internal/gtest-port.h"
351b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan
3641ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan#include <stdio.h>
3741ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan
381b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan#if GTEST_OS_MAC
39733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan# include <time.h>
401b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan#endif  // GTEST_OS_MAC
411b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan
426624187c3141f7ca403056062c440582630cd909zhanyong.wan#include <list>
43050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan#include <utility>  // For std::pair and std::make_pair.
446624187c3141f7ca403056062c440582630cd909zhanyong.wan#include <vector>
45050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
462620c79810d4741922e9fa89050c0af564994f24zhanyong.wan#include "gtest/gtest.h"
472620c79810d4741922e9fa89050c0af564994f24zhanyong.wan#include "gtest/gtest-spi.h"
48f904a612d9444ab36c07a8e619c113432e046f49vladlosev
49d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan// Indicates that this translation unit is part of Google Test's
50d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan// implementation.  It must come before gtest-internal-inl.h is
51d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan// included, or there will be a compiler error.  This trick is to
52d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan// prevent a user from accidentally including gtest-internal-inl.h in
53d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan// his code.
544cd62602913a032a7aec091d4c8055ff9af95e37zhanyong.wan#define GTEST_IMPLEMENTATION_ 1
55d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan#include "src/gtest-internal-inl.h"
564cd62602913a032a7aec091d4c8055ff9af95e37zhanyong.wan#undef GTEST_IMPLEMENTATION_
57d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
58050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanusing std::make_pair;
59050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanusing std::pair;
60050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
61d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wannamespace testing {
62d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wannamespace internal {
63d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
646b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wanTEST(IsXDigitTest, WorksForNarrowAscii) {
656b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_TRUE(IsXDigit('0'));
666b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_TRUE(IsXDigit('9'));
676b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_TRUE(IsXDigit('A'));
686b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_TRUE(IsXDigit('F'));
696b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_TRUE(IsXDigit('a'));
706b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_TRUE(IsXDigit('f'));
716b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan
726b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_FALSE(IsXDigit('-'));
736b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_FALSE(IsXDigit('g'));
746b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_FALSE(IsXDigit('G'));
756b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan}
766b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan
776b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wanTEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) {
786b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_FALSE(IsXDigit(static_cast<char>(0x80)));
796b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_FALSE(IsXDigit(static_cast<char>('0' | 0x80)));
806b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan}
816b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan
826b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wanTEST(IsXDigitTest, WorksForWideAscii) {
836b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_TRUE(IsXDigit(L'0'));
846b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_TRUE(IsXDigit(L'9'));
856b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_TRUE(IsXDigit(L'A'));
866b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_TRUE(IsXDigit(L'F'));
876b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_TRUE(IsXDigit(L'a'));
886b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_TRUE(IsXDigit(L'f'));
896b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan
906b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_FALSE(IsXDigit(L'-'));
916b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_FALSE(IsXDigit(L'g'));
926b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_FALSE(IsXDigit(L'G'));
936b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan}
946b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan
956b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wanTEST(IsXDigitTest, ReturnsFalseForWideNonAscii) {
966b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_FALSE(IsXDigit(static_cast<wchar_t>(0x80)));
976b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_FALSE(IsXDigit(static_cast<wchar_t>(L'0' | 0x80)));
986b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan  EXPECT_FALSE(IsXDigit(static_cast<wchar_t>(L'0' | 0x100)));
996b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan}
1006b625a794e8a0e314f3ccc2f6a892f4a40a7e788zhanyong.wan
101678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanclass Base {
102678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan public:
103678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  // Copy constructor and assignment operator do exactly what we need, so we
104678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  // use them.
105678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Base() : member_(0) {}
106678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  explicit Base(int n) : member_(n) {}
107678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  virtual ~Base() {}
108678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  int member() { return member_; }
109678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
110678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan private:
111678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  int member_;
112678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan};
113678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
114678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanclass Derived : public Base {
115678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan public:
116678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  explicit Derived(int n) : Base(n) {}
117678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan};
118678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
119678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanTEST(ImplicitCastTest, ConvertsPointers) {
120678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Derived derived(0);
1211c4ce7fee11ccb20dd062db9e564fb3a68ae26dcvladlosev  EXPECT_TRUE(&derived == ::testing::internal::ImplicitCast_<Base*>(&derived));
122678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
123678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
124678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanTEST(ImplicitCastTest, CanUseInheritance) {
125678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Derived derived(1);
1261c4ce7fee11ccb20dd062db9e564fb3a68ae26dcvladlosev  Base base = ::testing::internal::ImplicitCast_<Base>(derived);
127678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  EXPECT_EQ(derived.member(), base.member());
128678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
129678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
130678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanclass Castable {
131678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan public:
13293fed47dbf8e6bc3d39d3f769cb5039551747257vladlosev  explicit Castable(bool* converted) : converted_(converted) {}
133678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  operator Base() {
134678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    *converted_ = true;
135678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    return Base();
136678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  }
137678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
138678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan private:
139678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  bool* converted_;
140678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan};
141678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
142678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanTEST(ImplicitCastTest, CanUseNonConstCastOperator) {
143678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  bool converted = false;
144678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  Castable castable(&converted);
1451c4ce7fee11ccb20dd062db9e564fb3a68ae26dcvladlosev  Base base = ::testing::internal::ImplicitCast_<Base>(castable);
146678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  EXPECT_TRUE(converted);
147678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
148678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
149678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanclass ConstCastable {
150678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan public:
15193fed47dbf8e6bc3d39d3f769cb5039551747257vladlosev  explicit ConstCastable(bool* converted) : converted_(converted) {}
152678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  operator Base() const {
153678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    *converted_ = true;
154678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    return Base();
155678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  }
156678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
157678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan private:
158678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  bool* converted_;
159678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan};
160678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
161678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanTEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) {
162678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  bool converted = false;
163678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  const ConstCastable const_castable(&converted);
1641c4ce7fee11ccb20dd062db9e564fb3a68ae26dcvladlosev  Base base = ::testing::internal::ImplicitCast_<Base>(const_castable);
165678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  EXPECT_TRUE(converted);
166678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
167678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
168678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanclass ConstAndNonConstCastable {
169678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan public:
170678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  ConstAndNonConstCastable(bool* converted, bool* const_converted)
171678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan      : converted_(converted), const_converted_(const_converted) {}
172678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  operator Base() {
173678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    *converted_ = true;
174678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    return Base();
175678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  }
176678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  operator Base() const {
177678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    *const_converted_ = true;
178678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan    return Base();
179678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  }
180678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
181678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan private:
182678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  bool* converted_;
183678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  bool* const_converted_;
184678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan};
185678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
186678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanTEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) {
187678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  bool converted = false;
188678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  bool const_converted = false;
189678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  ConstAndNonConstCastable castable(&converted, &const_converted);
1901c4ce7fee11ccb20dd062db9e564fb3a68ae26dcvladlosev  Base base = ::testing::internal::ImplicitCast_<Base>(castable);
191678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  EXPECT_TRUE(converted);
192678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  EXPECT_FALSE(const_converted);
193678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
194678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  converted = false;
195678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  const_converted = false;
196678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  const ConstAndNonConstCastable const_castable(&converted, &const_converted);
1971c4ce7fee11ccb20dd062db9e564fb3a68ae26dcvladlosev  base = ::testing::internal::ImplicitCast_<Base>(const_castable);
198678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  EXPECT_FALSE(converted);
199678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  EXPECT_TRUE(const_converted);
200678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
201678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
202678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanclass To {
203678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan public:
204678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  To(bool* converted) { *converted = true; }  // NOLINT
205678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan};
206678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
207678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wanTEST(ImplicitCastTest, CanUseImplicitConstructor) {
208678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  bool converted = false;
2091c4ce7fee11ccb20dd062db9e564fb3a68ae26dcvladlosev  To to = ::testing::internal::ImplicitCast_<To>(&converted);
2105e255e0b6affbdc56718d81f0bb5d1b802a1c6c2zhanyong.wan  (void)to;
211678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan  EXPECT_TRUE(converted);
212678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan}
213678f92b8f17c8edf1a21efb401c91b355fe7bb2bzhanyong.wan
2146624187c3141f7ca403056062c440582630cd909zhanyong.wanTEST(IteratorTraitsTest, WorksForSTLContainerIterators) {
2156624187c3141f7ca403056062c440582630cd909zhanyong.wan  StaticAssertTypeEq<int,
2166624187c3141f7ca403056062c440582630cd909zhanyong.wan      IteratorTraits< ::std::vector<int>::const_iterator>::value_type>();
2176624187c3141f7ca403056062c440582630cd909zhanyong.wan  StaticAssertTypeEq<bool,
2186624187c3141f7ca403056062c440582630cd909zhanyong.wan      IteratorTraits< ::std::list<bool>::iterator>::value_type>();
2196624187c3141f7ca403056062c440582630cd909zhanyong.wan}
2206624187c3141f7ca403056062c440582630cd909zhanyong.wan
2216624187c3141f7ca403056062c440582630cd909zhanyong.wanTEST(IteratorTraitsTest, WorksForPointerToNonConst) {
2226624187c3141f7ca403056062c440582630cd909zhanyong.wan  StaticAssertTypeEq<char, IteratorTraits<char*>::value_type>();
2236624187c3141f7ca403056062c440582630cd909zhanyong.wan  StaticAssertTypeEq<const void*, IteratorTraits<const void**>::value_type>();
2246624187c3141f7ca403056062c440582630cd909zhanyong.wan}
2256624187c3141f7ca403056062c440582630cd909zhanyong.wan
2266624187c3141f7ca403056062c440582630cd909zhanyong.wanTEST(IteratorTraitsTest, WorksForPointerToConst) {
2276624187c3141f7ca403056062c440582630cd909zhanyong.wan  StaticAssertTypeEq<char, IteratorTraits<const char*>::value_type>();
2286624187c3141f7ca403056062c440582630cd909zhanyong.wan  StaticAssertTypeEq<const void*,
2296624187c3141f7ca403056062c440582630cd909zhanyong.wan      IteratorTraits<const void* const*>::value_type>();
2306624187c3141f7ca403056062c440582630cd909zhanyong.wan}
2316624187c3141f7ca403056062c440582630cd909zhanyong.wan
232c23fd197eec5a5bd471cc19ebadcd248dfcad16cvladlosev// Tests that the element_type typedef is available in scoped_ptr and refers
233c23fd197eec5a5bd471cc19ebadcd248dfcad16cvladlosev// to the parameter type.
234c23fd197eec5a5bd471cc19ebadcd248dfcad16cvladlosevTEST(ScopedPtrTest, DefinesElementType) {
235c23fd197eec5a5bd471cc19ebadcd248dfcad16cvladlosev  StaticAssertTypeEq<int, ::testing::internal::scoped_ptr<int>::element_type>();
236c23fd197eec5a5bd471cc19ebadcd248dfcad16cvladlosev}
237c23fd197eec5a5bd471cc19ebadcd248dfcad16cvladlosev
238c23fd197eec5a5bd471cc19ebadcd248dfcad16cvladlosev// TODO(vladl@google.com): Implement THE REST of scoped_ptr tests.
239c23fd197eec5a5bd471cc19ebadcd248dfcad16cvladlosev
240f904a612d9444ab36c07a8e619c113432e046f49vladlosevTEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) {
241f6d087b78d230d875bf5d8281112662795044680zhanyong.wan  if (AlwaysFalse())
242f904a612d9444ab36c07a8e619c113432e046f49vladlosev    GTEST_CHECK_(false) << "This should never be executed; "
243f904a612d9444ab36c07a8e619c113432e046f49vladlosev                           "It's a compilation test only.";
244f904a612d9444ab36c07a8e619c113432e046f49vladlosev
245f6d087b78d230d875bf5d8281112662795044680zhanyong.wan  if (AlwaysTrue())
246f904a612d9444ab36c07a8e619c113432e046f49vladlosev    GTEST_CHECK_(true);
247f904a612d9444ab36c07a8e619c113432e046f49vladlosev  else
248f904a612d9444ab36c07a8e619c113432e046f49vladlosev    ;  // NOLINT
249f904a612d9444ab36c07a8e619c113432e046f49vladlosev
250f6d087b78d230d875bf5d8281112662795044680zhanyong.wan  if (AlwaysFalse())
251f904a612d9444ab36c07a8e619c113432e046f49vladlosev    ;  // NOLINT
252f904a612d9444ab36c07a8e619c113432e046f49vladlosev  else
253f904a612d9444ab36c07a8e619c113432e046f49vladlosev    GTEST_CHECK_(true) << "";
254f904a612d9444ab36c07a8e619c113432e046f49vladlosev}
255f904a612d9444ab36c07a8e619c113432e046f49vladlosev
256f904a612d9444ab36c07a8e619c113432e046f49vladlosevTEST(GtestCheckSyntaxTest, WorksWithSwitch) {
257f904a612d9444ab36c07a8e619c113432e046f49vladlosev  switch (0) {
258f904a612d9444ab36c07a8e619c113432e046f49vladlosev    case 1:
259f904a612d9444ab36c07a8e619c113432e046f49vladlosev      break;
260f904a612d9444ab36c07a8e619c113432e046f49vladlosev    default:
261f904a612d9444ab36c07a8e619c113432e046f49vladlosev      GTEST_CHECK_(true);
262f904a612d9444ab36c07a8e619c113432e046f49vladlosev  }
263f904a612d9444ab36c07a8e619c113432e046f49vladlosev
26493fed47dbf8e6bc3d39d3f769cb5039551747257vladlosev  switch (0)
265f904a612d9444ab36c07a8e619c113432e046f49vladlosev    case 0:
266f904a612d9444ab36c07a8e619c113432e046f49vladlosev      GTEST_CHECK_(true) << "Check failed in switch case";
267f904a612d9444ab36c07a8e619c113432e046f49vladlosev}
268f904a612d9444ab36c07a8e619c113432e046f49vladlosev
26930552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev// Verifies behavior of FormatFileLocation.
27030552030bea75bf2d27c49437e757b8a5d3b2e98vladlosevTEST(FormatFileLocationTest, FormatsFileLocation) {
27130552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev  EXPECT_PRED_FORMAT2(IsSubstring, "foo.cc", FormatFileLocation("foo.cc", 42));
27230552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev  EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation("foo.cc", 42));
27330552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev}
27430552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev
27530552030bea75bf2d27c49437e757b8a5d3b2e98vladlosevTEST(FormatFileLocationTest, FormatsUnknownFile) {
27630552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev  EXPECT_PRED_FORMAT2(
27730552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev      IsSubstring, "unknown file", FormatFileLocation(NULL, 42));
27830552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev  EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation(NULL, 42));
27930552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev}
28030552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev
28130552030bea75bf2d27c49437e757b8a5d3b2e98vladlosevTEST(FormatFileLocationTest, FormatsUknownLine) {
28230552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev  EXPECT_EQ("foo.cc:", FormatFileLocation("foo.cc", -1));
28330552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev}
28430552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev
28530552030bea75bf2d27c49437e757b8a5d3b2e98vladlosevTEST(FormatFileLocationTest, FormatsUknownFileAndLine) {
28630552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev  EXPECT_EQ("unknown file:", FormatFileLocation(NULL, -1));
28730552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev}
28830552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev
28930552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev// Verifies behavior of FormatCompilerIndependentFileLocation.
29030552030bea75bf2d27c49437e757b8a5d3b2e98vladlosevTEST(FormatCompilerIndependentFileLocationTest, FormatsFileLocation) {
29130552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev  EXPECT_EQ("foo.cc:42", FormatCompilerIndependentFileLocation("foo.cc", 42));
29230552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev}
29330552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev
29430552030bea75bf2d27c49437e757b8a5d3b2e98vladlosevTEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFile) {
29530552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev  EXPECT_EQ("unknown file:42",
29630552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev            FormatCompilerIndependentFileLocation(NULL, 42));
29730552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev}
29830552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev
29930552030bea75bf2d27c49437e757b8a5d3b2e98vladlosevTEST(FormatCompilerIndependentFileLocationTest, FormatsUknownLine) {
30030552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev  EXPECT_EQ("foo.cc", FormatCompilerIndependentFileLocation("foo.cc", -1));
30130552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev}
30230552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev
30330552030bea75bf2d27c49437e757b8a5d3b2e98vladlosevTEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) {
30430552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev  EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1));
30530552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev}
30630552030bea75bf2d27c49437e757b8a5d3b2e98vladlosev
307105b1431c37c159892cc0983dd0bc2411c6f0c96vladlosev#if GTEST_OS_MAC || GTEST_OS_QNX
3081b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wanvoid* ThreadFunc(void* data) {
309050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data);
3101b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  pthread_mutex_lock(mutex);
3111b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  pthread_mutex_unlock(mutex);
3121b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  return NULL;
3131b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan}
3141b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan
3151b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wanTEST(GetThreadCountTest, ReturnsCorrectValue) {
316a773ef8a3b70936450c94bdcba1e6345a980244ezhanyong.wan  EXPECT_EQ(1U, GetThreadCount());
3171b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  pthread_mutex_t mutex;
3181b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  pthread_attr_t  attr;
3191b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  pthread_t       thread_id;
3201b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan
3211b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  // TODO(vladl@google.com): turn mutex into internal::Mutex for automatic
3221b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  // destruction.
3231b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  pthread_mutex_init(&mutex, NULL);
3241b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  pthread_mutex_lock(&mutex);
3251b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  ASSERT_EQ(0, pthread_attr_init(&attr));
3261b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
3271b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan
3281b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex);
3291b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  ASSERT_EQ(0, pthread_attr_destroy(&attr));
3301b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  ASSERT_EQ(0, status);
331a773ef8a3b70936450c94bdcba1e6345a980244ezhanyong.wan  EXPECT_EQ(2U, GetThreadCount());
3321b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  pthread_mutex_unlock(&mutex);
3331b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan
3341b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  void* dummy;
3351b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  ASSERT_EQ(0, pthread_join(thread_id, &dummy));
336b7ec0f7b3b21338babc9a6ab5a593a40634a8062zhanyong.wan
337105b1431c37c159892cc0983dd0bc2411c6f0c96vladlosev# if GTEST_OS_MAC
338105b1431c37c159892cc0983dd0bc2411c6f0c96vladlosev
339b7ec0f7b3b21338babc9a6ab5a593a40634a8062zhanyong.wan  // MacOS X may not immediately report the updated thread count after
340b7ec0f7b3b21338babc9a6ab5a593a40634a8062zhanyong.wan  // joining a thread, causing flakiness in this test. To counter that, we
341b7ec0f7b3b21338babc9a6ab5a593a40634a8062zhanyong.wan  // wait for up to .5 seconds for the OS to report the correct value.
342b7ec0f7b3b21338babc9a6ab5a593a40634a8062zhanyong.wan  for (int i = 0; i < 5; ++i) {
343b7ec0f7b3b21338babc9a6ab5a593a40634a8062zhanyong.wan    if (GetThreadCount() == 1)
344b7ec0f7b3b21338babc9a6ab5a593a40634a8062zhanyong.wan      break;
345b7ec0f7b3b21338babc9a6ab5a593a40634a8062zhanyong.wan
346472e403d10909ef3d98039def981a75376a4bb54zhanyong.wan    SleepMilliseconds(100);
347b7ec0f7b3b21338babc9a6ab5a593a40634a8062zhanyong.wan  }
348105b1431c37c159892cc0983dd0bc2411c6f0c96vladlosev
349105b1431c37c159892cc0983dd0bc2411c6f0c96vladlosev# endif  // GTEST_OS_MAC
350105b1431c37c159892cc0983dd0bc2411c6f0c96vladlosev
351a773ef8a3b70936450c94bdcba1e6345a980244ezhanyong.wan  EXPECT_EQ(1U, GetThreadCount());
3521b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan  pthread_mutex_destroy(&mutex);
3531b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan}
3541b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan#else
3551b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wanTEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) {
356a773ef8a3b70936450c94bdcba1e6345a980244ezhanyong.wan  EXPECT_EQ(0U, GetThreadCount());
3571b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan}
358105b1431c37c159892cc0983dd0bc2411c6f0c96vladlosev#endif  // GTEST_OS_MAC || GTEST_OS_QNX
3591b171100b3341c01fb377f8202d9eaccbeec1f55zhanyong.wan
360f904a612d9444ab36c07a8e619c113432e046f49vladlosevTEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) {
361f904a612d9444ab36c07a8e619c113432e046f49vladlosev  const bool a_false_condition = false;
362c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan  const char regex[] =
363f904a612d9444ab36c07a8e619c113432e046f49vladlosev#ifdef _MSC_VER
364c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan     "gtest-port_test\\.cc\\(\\d+\\):"
365edea1b14488a67ca7cbc11545a35250e2492da9fvladlosev#elif GTEST_USES_POSIX_RE
366c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan     "gtest-port_test\\.cc:[0-9]+"
367edea1b14488a67ca7cbc11545a35250e2492da9fvladlosev#else
368edea1b14488a67ca7cbc11545a35250e2492da9fvladlosev     "gtest-port_test\\.cc:\\d+"
369f904a612d9444ab36c07a8e619c113432e046f49vladlosev#endif  // _MSC_VER
370c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan     ".*a_false_condition.*Extra info.*";
371c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan
372d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info",
373d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan                            regex);
374f904a612d9444ab36c07a8e619c113432e046f49vladlosev}
375f904a612d9444ab36c07a8e619c113432e046f49vladlosev
376d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan#if GTEST_HAS_DEATH_TEST
377d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
378f904a612d9444ab36c07a8e619c113432e046f49vladlosevTEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) {
379f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_EXIT({
380f904a612d9444ab36c07a8e619c113432e046f49vladlosev      GTEST_CHECK_(true) << "Extra info";
381f904a612d9444ab36c07a8e619c113432e046f49vladlosev      ::std::cerr << "Success\n";
382f904a612d9444ab36c07a8e619c113432e046f49vladlosev      exit(0); },
383f904a612d9444ab36c07a8e619c113432e046f49vladlosev      ::testing::ExitedWithCode(0), "Success");
384f904a612d9444ab36c07a8e619c113432e046f49vladlosev}
385f904a612d9444ab36c07a8e619c113432e046f49vladlosev
386f904a612d9444ab36c07a8e619c113432e046f49vladlosev#endif  // GTEST_HAS_DEATH_TEST
387f904a612d9444ab36c07a8e619c113432e046f49vladlosev
38872cb271b4a97e1bfd26397bb188673ed3b359de1vladlosev// Verifies that Google Test choose regular expression engine appropriate to
38972cb271b4a97e1bfd26397bb188673ed3b359de1vladlosev// the platform. The test will produce compiler errors in case of failure.
39072cb271b4a97e1bfd26397bb188673ed3b359de1vladlosev// For simplicity, we only cover the most important platforms here.
39172cb271b4a97e1bfd26397bb188673ed3b359de1vladlosevTEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) {
39272cb271b4a97e1bfd26397bb188673ed3b359de1vladlosev#if GTEST_HAS_POSIX_RE
393733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan
39472cb271b4a97e1bfd26397bb188673ed3b359de1vladlosev  EXPECT_TRUE(GTEST_USES_POSIX_RE);
395733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan
39672cb271b4a97e1bfd26397bb188673ed3b359de1vladlosev#else
397733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan
39872cb271b4a97e1bfd26397bb188673ed3b359de1vladlosev  EXPECT_TRUE(GTEST_USES_SIMPLE_RE);
399733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan
40072cb271b4a97e1bfd26397bb188673ed3b359de1vladlosev#endif
40172cb271b4a97e1bfd26397bb188673ed3b359de1vladlosev}
40272cb271b4a97e1bfd26397bb188673ed3b359de1vladlosev
403d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan#if GTEST_USES_POSIX_RE
404f904a612d9444ab36c07a8e619c113432e046f49vladlosev
405733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan# if GTEST_HAS_TYPED_TEST
406fe755181fa89a06351489bcaf9258f5a4f9f5381zhanyong.wan
407f904a612d9444ab36c07a8e619c113432e046f49vladlosevtemplate <typename Str>
408f904a612d9444ab36c07a8e619c113432e046f49vladlosevclass RETest : public ::testing::Test {};
409f904a612d9444ab36c07a8e619c113432e046f49vladlosev
410f904a612d9444ab36c07a8e619c113432e046f49vladlosev// Defines StringTypes as the list of all string types that class RE
411f904a612d9444ab36c07a8e619c113432e046f49vladlosev// supports.
412f904a612d9444ab36c07a8e619c113432e046f49vladlosevtypedef testing::Types<
413f904a612d9444ab36c07a8e619c113432e046f49vladlosev    ::std::string,
414733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan#  if GTEST_HAS_GLOBAL_STRING
415f904a612d9444ab36c07a8e619c113432e046f49vladlosev    ::string,
416733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan#  endif  // GTEST_HAS_GLOBAL_STRING
417f904a612d9444ab36c07a8e619c113432e046f49vladlosev    const char*> StringTypes;
418f904a612d9444ab36c07a8e619c113432e046f49vladlosev
419f904a612d9444ab36c07a8e619c113432e046f49vladlosevTYPED_TEST_CASE(RETest, StringTypes);
420f904a612d9444ab36c07a8e619c113432e046f49vladlosev
421f904a612d9444ab36c07a8e619c113432e046f49vladlosev// Tests RE's implicit constructors.
422f904a612d9444ab36c07a8e619c113432e046f49vladlosevTYPED_TEST(RETest, ImplicitConstructorWorks) {
423d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  const RE empty(TypeParam(""));
424f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_STREQ("", empty.pattern());
425f904a612d9444ab36c07a8e619c113432e046f49vladlosev
426d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  const RE simple(TypeParam("hello"));
427f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_STREQ("hello", simple.pattern());
428f904a612d9444ab36c07a8e619c113432e046f49vladlosev
429d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  const RE normal(TypeParam(".*(\\w+)"));
430f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_STREQ(".*(\\w+)", normal.pattern());
431f904a612d9444ab36c07a8e619c113432e046f49vladlosev}
432f904a612d9444ab36c07a8e619c113432e046f49vladlosev
433f904a612d9444ab36c07a8e619c113432e046f49vladlosev// Tests that RE's constructors reject invalid regular expressions.
434f904a612d9444ab36c07a8e619c113432e046f49vladlosevTYPED_TEST(RETest, RejectsInvalidRegex) {
435f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_NONFATAL_FAILURE({
436d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan    const RE invalid(TypeParam("?"));
437f904a612d9444ab36c07a8e619c113432e046f49vladlosev  }, "\"?\" is not a valid POSIX Extended regular expression.");
438f904a612d9444ab36c07a8e619c113432e046f49vladlosev}
439f904a612d9444ab36c07a8e619c113432e046f49vladlosev
440f904a612d9444ab36c07a8e619c113432e046f49vladlosev// Tests RE::FullMatch().
441f904a612d9444ab36c07a8e619c113432e046f49vladlosevTYPED_TEST(RETest, FullMatchWorks) {
442d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  const RE empty(TypeParam(""));
443f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty));
444f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty));
445f904a612d9444ab36c07a8e619c113432e046f49vladlosev
446d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  const RE re(TypeParam("a.*z"));
447f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re));
448f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re));
449f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re));
450f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_FALSE(RE::FullMatch(TypeParam("azy"), re));
451f904a612d9444ab36c07a8e619c113432e046f49vladlosev}
452f904a612d9444ab36c07a8e619c113432e046f49vladlosev
453f904a612d9444ab36c07a8e619c113432e046f49vladlosev// Tests RE::PartialMatch().
454f904a612d9444ab36c07a8e619c113432e046f49vladlosevTYPED_TEST(RETest, PartialMatchWorks) {
455d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  const RE empty(TypeParam(""));
456f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty));
457f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty));
458f904a612d9444ab36c07a8e619c113432e046f49vladlosev
459d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  const RE re(TypeParam("a.*z"));
460f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re));
461f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re));
462f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re));
463f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_TRUE(RE::PartialMatch(TypeParam("azy"), re));
464f904a612d9444ab36c07a8e619c113432e046f49vladlosev  EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re));
465f904a612d9444ab36c07a8e619c113432e046f49vladlosev}
466f904a612d9444ab36c07a8e619c113432e046f49vladlosev
467733a54a398766289b74cf3daebe083d7115cf388zhanyong.wan# endif  // GTEST_HAS_TYPED_TEST
468fe755181fa89a06351489bcaf9258f5a4f9f5381zhanyong.wan
469d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan#elif GTEST_USES_SIMPLE_RE
470d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
471d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(IsInSetTest, NulCharIsNotInAnySet) {
472d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsInSet('\0', ""));
473d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsInSet('\0', "\0"));
474d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsInSet('\0', "a"));
475d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
476d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
477d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(IsInSetTest, WorksForNonNulChars) {
478d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsInSet('a', "Ab"));
479d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsInSet('c', ""));
480d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
481d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsInSet('b', "bcd"));
482d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsInSet('b', "ab"));
483d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
484d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
4855d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wanTEST(IsAsciiDigitTest, IsFalseForNonDigit) {
4865d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiDigit('\0'));
4875d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiDigit(' '));
4885d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiDigit('+'));
4895d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiDigit('-'));
4905d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiDigit('.'));
4915d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiDigit('a'));
492d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
493d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
4945d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wanTEST(IsAsciiDigitTest, IsTrueForDigit) {
4955d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiDigit('0'));
4965d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiDigit('1'));
4975d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiDigit('5'));
4985d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiDigit('9'));
499d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
500d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
5015d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wanTEST(IsAsciiPunctTest, IsFalseForNonPunct) {
5025d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiPunct('\0'));
5035d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiPunct(' '));
5045d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiPunct('\n'));
5055d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiPunct('a'));
5065d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiPunct('0'));
507d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
508d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
5095d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wanTEST(IsAsciiPunctTest, IsTrueForPunct) {
510d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) {
5115d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan    EXPECT_PRED1(IsAsciiPunct, *p);
512d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  }
513d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
514d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
515d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(IsRepeatTest, IsFalseForNonRepeatChar) {
516d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsRepeat('\0'));
517d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsRepeat(' '));
518d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsRepeat('a'));
519d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsRepeat('1'));
520d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsRepeat('-'));
521d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
522d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
523d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(IsRepeatTest, IsTrueForRepeatChar) {
524d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsRepeat('?'));
525d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsRepeat('*'));
526d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsRepeat('+'));
527d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
528d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
5295d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wanTEST(IsAsciiWhiteSpaceTest, IsFalseForNonWhiteSpace) {
5305d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiWhiteSpace('\0'));
5315d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiWhiteSpace('a'));
5325d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiWhiteSpace('1'));
5335d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiWhiteSpace('+'));
5345d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiWhiteSpace('_'));
535d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
536d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
5375d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wanTEST(IsAsciiWhiteSpaceTest, IsTrueForWhiteSpace) {
5385d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWhiteSpace(' '));
5395d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWhiteSpace('\n'));
5405d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWhiteSpace('\r'));
5415d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWhiteSpace('\t'));
5425d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWhiteSpace('\v'));
5435d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWhiteSpace('\f'));
544d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
545d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
5465d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wanTEST(IsAsciiWordCharTest, IsFalseForNonWordChar) {
5475d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiWordChar('\0'));
5485d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiWordChar('+'));
5495d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiWordChar('.'));
5505d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiWordChar(' '));
5515d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_FALSE(IsAsciiWordChar('\n'));
552d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
553d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
5545d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wanTEST(IsAsciiWordCharTest, IsTrueForLetter) {
5555d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWordChar('a'));
5565d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWordChar('b'));
5575d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWordChar('A'));
5585d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWordChar('Z'));
559d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
560d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
5615d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wanTEST(IsAsciiWordCharTest, IsTrueForDigit) {
5625d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWordChar('0'));
5635d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWordChar('1'));
5645d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWordChar('7'));
5655d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWordChar('9'));
566d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
567d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
5685d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wanTEST(IsAsciiWordCharTest, IsTrueForUnderscore) {
5695d0c3dc09ece41c649deea59f975d0ff5548424azhanyong.wan  EXPECT_TRUE(IsAsciiWordChar('_'));
570d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
571d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
572d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(IsValidEscapeTest, IsFalseForNonPrintable) {
573d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsValidEscape('\0'));
574d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsValidEscape('\007'));
575d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
576d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
577d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(IsValidEscapeTest, IsFalseForDigit) {
578d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsValidEscape('0'));
579d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsValidEscape('9'));
580d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
581d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
582d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(IsValidEscapeTest, IsFalseForWhiteSpace) {
583d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsValidEscape(' '));
584d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsValidEscape('\n'));
585d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
586d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
587d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(IsValidEscapeTest, IsFalseForSomeLetter) {
588d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsValidEscape('a'));
589d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(IsValidEscape('Z'));
590d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
591d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
592d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(IsValidEscapeTest, IsTrueForPunct) {
593d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('.'));
594d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('-'));
595d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('^'));
596d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('$'));
597d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('('));
598d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape(']'));
599d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('{'));
600d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('|'));
601d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
602d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
603d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(IsValidEscapeTest, IsTrueForSomeLetter) {
604d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('d'));
605d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('D'));
606d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('s'));
607d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('S'));
608d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('w'));
609d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(IsValidEscape('W'));
610d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
611d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
612d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(AtomMatchesCharTest, EscapedPunct) {
613d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, '\\', '\0'));
614d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, '\\', ' '));
615d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, '_', '.'));
616d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, '.', 'a'));
617d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
618d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, '\\', '\\'));
619d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, '_', '_'));
620d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, '+', '+'));
621d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, '.', '.'));
622d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
623d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
624d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(AtomMatchesCharTest, Escaped_d) {
625d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'd', '\0'));
626d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'd', 'a'));
627d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'd', '.'));
628d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
629d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'd', '0'));
630d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'd', '9'));
631d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
632d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
633d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(AtomMatchesCharTest, Escaped_D) {
634d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'D', '0'));
635d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'D', '9'));
636d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
637d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'D', '\0'));
638d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'D', 'a'));
639d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'D', '-'));
640d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
641d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
642d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(AtomMatchesCharTest, Escaped_s) {
643d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 's', '\0'));
644d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 's', 'a'));
645d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 's', '.'));
646d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 's', '9'));
647d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
648d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 's', ' '));
649d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 's', '\n'));
650d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 's', '\t'));
651d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
652d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
653d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(AtomMatchesCharTest, Escaped_S) {
654d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'S', ' '));
655d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'S', '\r'));
656d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
657d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'S', '\0'));
658d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'S', 'a'));
659d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'S', '9'));
660d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
661d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
662d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(AtomMatchesCharTest, Escaped_w) {
663d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'w', '\0'));
664d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'w', '+'));
665d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'w', ' '));
666d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'w', '\n'));
667d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
668d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'w', '0'));
669d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'w', 'b'));
670d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'w', 'C'));
671d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'w', '_'));
672d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
673d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
674d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(AtomMatchesCharTest, Escaped_W) {
675d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'W', 'A'));
676d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'W', 'b'));
677d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'W', '9'));
678d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'W', '_'));
679d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
680d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'W', '\0'));
681d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'W', '*'));
682d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'W', '\n'));
683d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
684d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
685d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(AtomMatchesCharTest, EscapedWhiteSpace) {
686d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'f', '\0'));
687d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'f', '\n'));
688d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'n', '\0'));
689d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'n', '\r'));
690d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'r', '\0'));
691d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'r', 'a'));
692d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 't', '\0'));
693d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 't', 't'));
694d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'v', '\0'));
695d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(true, 'v', '\f'));
696d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
697d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'f', '\f'));
698d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'n', '\n'));
699d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'r', '\r'));
700d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 't', '\t'));
701d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(true, 'v', '\v'));
702d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
703d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
704d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(AtomMatchesCharTest, UnescapedDot) {
705d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(false, '.', '\n'));
706d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
707d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(false, '.', '\0'));
708d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(false, '.', '.'));
709d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(false, '.', 'a'));
710d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(false, '.', ' '));
711d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
712d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
713d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(AtomMatchesCharTest, UnescapedChar) {
714d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(false, 'a', '\0'));
715d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(false, 'a', 'b'));
716d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(AtomMatchesChar(false, '$', 'a'));
717d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
718d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(false, '$', '$'));
719d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(false, '5', '5'));
720d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(AtomMatchesChar(false, 'Z', 'Z'));
721d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
722d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
723d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(ValidateRegexTest, GeneratesFailureAndReturnsFalseForInvalid) {
724d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(NULL)),
725d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "NULL is not a valid simple regular expression");
726d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(
727d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan      ASSERT_FALSE(ValidateRegex("a\\")),
728d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan      "Syntax error at index 1 in simple regular expression \"a\\\": ");
729d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a\\")),
730d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "'\\' cannot appear at the end");
731d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\n\\")),
732d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "'\\' cannot appear at the end");
733d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\s\\hb")),
734d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "invalid escape sequence \"\\h\"");
735d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^^")),
736d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "'^' can only appear at the beginning");
737d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(".*^b")),
738d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "'^' can only appear at the beginning");
739d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("$$")),
740d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "'$' can only appear at the end");
741d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^$a")),
742d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "'$' can only appear at the end");
743d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a(b")),
744d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "'(' is unsupported");
745d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("ab)")),
746d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "')' is unsupported");
747d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("[ab")),
748d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "'[' is unsupported");
749d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a{2")),
750d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "'{' is unsupported");
751d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("?")),
752d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "'?' can only follow a repeatable token");
753d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^*")),
754d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "'*' can only follow a repeatable token");
755d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("5*+")),
756d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan                          "'+' can only follow a repeatable token");
757d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
758d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
759d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(ValidateRegexTest, ReturnsTrueForValid) {
760d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(ValidateRegex(""));
761d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(ValidateRegex("a"));
762d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(ValidateRegex(".*"));
763d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(ValidateRegex("^a_+"));
764d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(ValidateRegex("^a\\t\\&?"));
765d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(ValidateRegex("09*$"));
766d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(ValidateRegex("^Z$"));
767d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(ValidateRegex("a\\^Z\\$\\(\\)\\|\\[\\]\\{\\}"));
768d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
769d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
770d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrOne) {
771d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "a", "ba"));
772d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  // Repeating more than once.
773d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "aab"));
774d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
775d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  // Repeating zero times.
776d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ba"));
777d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  // Repeating once.
778d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ab"));
779d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '#', '?', ".", "##"));
780d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
781d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
782d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrMany) {
783d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '*', "a$", "baab"));
784d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
785d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  // Repeating zero times.
786d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "bc"));
787d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  // Repeating once.
788d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "abc"));
789d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  // Repeating more than once.
790d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '*', "-", "ab_1-g"));
791d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
792d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
793d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRepetitionAndRegexAtHeadTest, WorksForOneOrMany) {
794d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "a$", "baab"));
795d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  // Repeating zero times.
796d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "bc"));
797d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
798d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  // Repeating once.
799d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "abc"));
800d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  // Repeating more than once.
801d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '+', "-", "ab_1-g"));
802d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
803d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
804d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRegexAtHeadTest, ReturnsTrueForEmptyRegex) {
805d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("", ""));
806d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("", "ab"));
807d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
808d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
809d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRegexAtHeadTest, WorksWhenDollarIsInRegex) {
810d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAtHead("$", "a"));
811d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
812d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("$", ""));
813d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("a$", "a"));
814d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
815d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
816d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithEscapeSequence) {
817d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAtHead("\\w", "+"));
818d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAtHead("\\W", "ab"));
819d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
820d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("\\sa", "\nab"));
821d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("\\d", "1a"));
822d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
823d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
824d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) {
825d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAtHead(".+a", "abc"));
826d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAtHead("a?b", "aab"));
827d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
828d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead(".*a", "bc12-ab"));
829d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("a?b", "b"));
830d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("a?b", "ab"));
831d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
832d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
833d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRegexAtHeadTest,
834d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan     WorksWhenRegexStartsWithRepetionOfEscapeSequence) {
835d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc"));
836d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAtHead("\\s?b", "  b"));
837d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
838d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("\\(*a", "((((ab"));
839d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("\\^?b", "^b"));
840d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "b"));
841d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "\\b"));
842d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
843d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
844d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRegexAtHeadTest, MatchesSequentially) {
845d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAtHead("ab.*c", "acabc"));
846d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
847d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAtHead("ab.*c", "ab-fsc"));
848d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
849d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
850d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRegexAnywhereTest, ReturnsFalseWhenStringIsNull) {
851d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAnywhere("", NULL));
852d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
853d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
854d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRegexAnywhereTest, WorksWhenRegexStartsWithCaret) {
855d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAnywhere("^a", "ba"));
856d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAnywhere("^$", "a"));
857d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
858d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAnywhere("^a", "ab"));
859d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAnywhere("^", "ab"));
860d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAnywhere("^$", ""));
861d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
862d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
863d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRegexAnywhereTest, ReturnsFalseWhenNoMatch) {
864d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAnywhere("a", "bcde123"));
865d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(MatchRegexAnywhere("a.+a", "--aa88888888"));
866d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
867d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
868d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingPrefix) {
869d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAnywhere("\\w+", "ab1_ - 5"));
870d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAnywhere(".*=", "="));
871d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAnywhere("x.*ab?.*bc", "xaaabc"));
872d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
873d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
874d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) {
875d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAnywhere("\\w+", "$$$ ab1_ - 5"));
876d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(MatchRegexAnywhere("\\.+=", "=  ...="));
877d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
878d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
879d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan// Tests RE's implicit constructors.
880d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(RETest, ImplicitConstructorWorks) {
881c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan  const RE empty("");
882d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_STREQ("", empty.pattern());
883d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
884c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan  const RE simple("hello");
885d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_STREQ("hello", simple.pattern());
886d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
887d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
888d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan// Tests that RE's constructors reject invalid regular expressions.
889d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(RETest, RejectsInvalidRegex) {
890d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE({
891c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan    const RE normal(NULL);
892d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  }, "NULL is not a valid simple regular expression");
893d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
894d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE({
895c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan    const RE normal(".*(\\w+");
896d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  }, "'(' is unsupported");
897d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
898d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_NONFATAL_FAILURE({
899c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan    const RE invalid("^?");
900d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  }, "'?' can only follow a repeatable token");
901d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
902d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
903d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan// Tests RE::FullMatch().
904d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(RETest, FullMatchWorks) {
905d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  const RE empty("");
906d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(RE::FullMatch("", empty));
907d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(RE::FullMatch("a", empty));
908d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
909c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan  const RE re1("a");
910d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(RE::FullMatch("a", re1));
911d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
912c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan  const RE re("a.*z");
913d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(RE::FullMatch("az", re));
914d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(RE::FullMatch("axyz", re));
915d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(RE::FullMatch("baz", re));
916d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(RE::FullMatch("azy", re));
917d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
918d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
919d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan// Tests RE::PartialMatch().
920d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wanTEST(RETest, PartialMatchWorks) {
921c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan  const RE empty("");
922d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(RE::PartialMatch("", empty));
923d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(RE::PartialMatch("a", empty));
924d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
925c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan  const RE re("a.*z");
926d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(RE::PartialMatch("az", re));
927d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(RE::PartialMatch("axyz", re));
928d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(RE::PartialMatch("baz", re));
929d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_TRUE(RE::PartialMatch("azy", re));
930d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan  EXPECT_FALSE(RE::PartialMatch("zza", re));
931d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}
932d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
933f904a612d9444ab36c07a8e619c113432e046f49vladlosev#endif  // GTEST_USES_POSIX_RE
934d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan
93541ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan#if !GTEST_OS_WINDOWS_MOBILE
93641ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan
93741ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wanTEST(CaptureTest, CapturesStdout) {
93841ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  CaptureStdout();
93941ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  fprintf(stdout, "abc");
94041ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  EXPECT_STREQ("abc", GetCapturedStdout().c_str());
94141ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan
94241ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  CaptureStdout();
94341ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  fprintf(stdout, "def%cghi", '\0');
94441ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  EXPECT_EQ(::std::string("def\0ghi", 7), ::std::string(GetCapturedStdout()));
94541ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan}
94641ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan
94741ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wanTEST(CaptureTest, CapturesStderr) {
94841ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  CaptureStderr();
94941ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  fprintf(stderr, "jkl");
95041ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  EXPECT_STREQ("jkl", GetCapturedStderr().c_str());
95141ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan
952c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan  CaptureStderr();
95341ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  fprintf(stderr, "jkl%cmno", '\0');
95441ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  EXPECT_EQ(::std::string("jkl\0mno", 7), ::std::string(GetCapturedStderr()));
955c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan}
956c85c0c20322a1f36113cf4d6282908e16ca32669zhanyong.wan
95741ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan// Tests that stdout and stderr capture don't interfere with each other.
95841ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wanTEST(CaptureTest, CapturesStdoutAndStderr) {
95941ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  CaptureStdout();
96041ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  CaptureStderr();
96141ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  fprintf(stdout, "pqr");
96241ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  fprintf(stderr, "stu");
96341ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  EXPECT_STREQ("pqr", GetCapturedStdout().c_str());
96441ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  EXPECT_STREQ("stu", GetCapturedStderr().c_str());
96541ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan}
96641ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan
96741ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wanTEST(CaptureDeathTest, CannotReenterStdoutCapture) {
96841ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  CaptureStdout();
96993fed47dbf8e6bc3d39d3f769cb5039551747257vladlosev  EXPECT_DEATH_IF_SUPPORTED(CaptureStdout(),
97041ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan                            "Only one stdout capturer can exist at a time");
97141ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  GetCapturedStdout();
97241ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan
97341ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  // We cannot test stderr capturing using death tests as they use it
97441ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan  // themselves.
97541ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan}
97641ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan
97741ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan#endif  // !GTEST_OS_WINDOWS_MOBILE
97841ca36a861d462e22daf25e8f0fc3e32682ec618zhanyong.wan
979050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanTEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) {
980050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  ThreadLocal<int> t1;
981050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  EXPECT_EQ(0, t1.get());
982050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
983050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  ThreadLocal<void*> t2;
984050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  EXPECT_TRUE(t2.get() == NULL);
985050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
986050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
987050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanTEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) {
988050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  ThreadLocal<int> t1(123);
989050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  EXPECT_EQ(123, t1.get());
990050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
991050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  int i = 0;
992050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  ThreadLocal<int*> t2(&i);
993050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  EXPECT_EQ(&i, t2.get());
994050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
995050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
996050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanclass NoDefaultContructor {
997050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan public:
998050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  explicit NoDefaultContructor(const char*) {}
999050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  NoDefaultContructor(const NoDefaultContructor&) {}
1000050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan};
1001050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1002050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanTEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) {
1003050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  ThreadLocal<NoDefaultContructor> bar(NoDefaultContructor("foo"));
1004050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  bar.pointer();
1005050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
1006050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1007050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanTEST(ThreadLocalTest, GetAndPointerReturnSameValue) {
100803c314931649a999b0cf5deb0a434a1009157416jgm@google.com  ThreadLocal<std::string> thread_local_string;
1009050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1010524cc4e19491029979f7b18b9451b2a6105131edvladlosev  EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get()));
1011050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1012050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  // Verifies the condition still holds after calling set.
1013524cc4e19491029979f7b18b9451b2a6105131edvladlosev  thread_local_string.set("foo");
1014524cc4e19491029979f7b18b9451b2a6105131edvladlosev  EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get()));
1015050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
1016050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1017050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanTEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) {
101803c314931649a999b0cf5deb0a434a1009157416jgm@google.com  ThreadLocal<std::string> thread_local_string;
101903c314931649a999b0cf5deb0a434a1009157416jgm@google.com  const ThreadLocal<std::string>& const_thread_local_string =
102003c314931649a999b0cf5deb0a434a1009157416jgm@google.com      thread_local_string;
1021050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1022524cc4e19491029979f7b18b9451b2a6105131edvladlosev  EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer());
1023050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1024524cc4e19491029979f7b18b9451b2a6105131edvladlosev  thread_local_string.set("foo");
1025524cc4e19491029979f7b18b9451b2a6105131edvladlosev  EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer());
1026050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
1027050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1028050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan#if GTEST_IS_THREADSAFE
102907fe60097dcd59d43d1accc826dc4081b0f11f58vladlosev
103007fe60097dcd59d43d1accc826dc4081b0f11f58vladlosevvoid AddTwo(int* param) { *param += 2; }
103107fe60097dcd59d43d1accc826dc4081b0f11f58vladlosev
103207fe60097dcd59d43d1accc826dc4081b0f11f58vladlosevTEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) {
103307fe60097dcd59d43d1accc826dc4081b0f11f58vladlosev  int i = 40;
103407fe60097dcd59d43d1accc826dc4081b0f11f58vladlosev  ThreadWithParam<int*> thread(&AddTwo, &i, NULL);
103507fe60097dcd59d43d1accc826dc4081b0f11f58vladlosev  thread.Join();
103607fe60097dcd59d43d1accc826dc4081b0f11f58vladlosev  EXPECT_EQ(42, i);
103707fe60097dcd59d43d1accc826dc4081b0f11f58vladlosev}
103807fe60097dcd59d43d1accc826dc4081b0f11f58vladlosev
1039472e403d10909ef3d98039def981a75376a4bb54zhanyong.wanTEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) {
1040050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  // AssertHeld() is flaky only in the presence of multiple threads accessing
1041050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  // the lock. In this case, the test is robust.
1042050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  EXPECT_DEATH_IF_SUPPORTED({
1043050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan    Mutex m;
1044050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan    { MutexLock lock(&m); }
1045050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan    m.AssertHeld();
1046050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  },
1047f6fb532f0825024feda89c863e33a51b6ff377f5zhanyong.wan  "thread .*hold");
1048050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
1049050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1050472e403d10909ef3d98039def981a75376a4bb54zhanyong.wanTEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) {
1051472e403d10909ef3d98039def981a75376a4bb54zhanyong.wan  Mutex m;
1052472e403d10909ef3d98039def981a75376a4bb54zhanyong.wan  MutexLock lock(&m);
1053472e403d10909ef3d98039def981a75376a4bb54zhanyong.wan  m.AssertHeld();
1054050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
1055050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1056050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanclass AtomicCounterWithMutex {
1057050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan public:
1058050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  explicit AtomicCounterWithMutex(Mutex* mutex) :
1059050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan    value_(0), mutex_(mutex), random_(42) {}
1060050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1061050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  void Increment() {
1062050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan    MutexLock lock(mutex_);
1063050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan    int temp = value_;
1064050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan    {
1065d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      // We need to put up a memory barrier to prevent reads and writes to
1066d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      // value_ rearranged with the call to SleepMilliseconds when observed
1067d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      // from other threads.
1068d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#if GTEST_HAS_PTHREAD
1069d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      // On POSIX, locking a mutex puts up a memory barrier.  We cannot use
1070d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      // Mutex and MutexLock here or rely on their memory barrier
1071d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      // functionality as we are testing them here.
1072050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan      pthread_mutex_t memory_barrier_mutex;
1073f33b34537347ac5f16774649f79cd5b5b9128b13zhanyong.wan      GTEST_CHECK_POSIX_SUCCESS_(
1074f33b34537347ac5f16774649f79cd5b5b9128b13zhanyong.wan          pthread_mutex_init(&memory_barrier_mutex, NULL));
1075f33b34537347ac5f16774649f79cd5b5b9128b13zhanyong.wan      GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex));
1076050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1077050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan      SleepMilliseconds(random_.Generate(30));
1078050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1079f33b34537347ac5f16774649f79cd5b5b9128b13zhanyong.wan      GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex));
10808757774c346ee23a9405cbd7171514cdcb65eac6vladlosev      GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex));
1081d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#elif GTEST_OS_WINDOWS
1082d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      // On Windows, performing an interlocked access puts up a memory barrier.
1083d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      volatile LONG dummy = 0;
1084d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      ::InterlockedIncrement(&dummy);
1085d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      SleepMilliseconds(random_.Generate(30));
1086d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      ::InterlockedIncrement(&dummy);
1087d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#else
1088d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com# error "Memory barrier not implemented on this platform."
1089d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#endif  // GTEST_HAS_PTHREAD
1090050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan    }
1091050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan    value_ = temp + 1;
1092050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  }
1093050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  int value() const { return value_; }
1094050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1095050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan private:
1096050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  volatile int value_;
1097050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  Mutex* const mutex_;  // Protects value_.
1098050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  Random       random_;
1099050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan};
1100050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1101050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanvoid CountingThreadFunc(pair<AtomicCounterWithMutex*, int> param) {
1102050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  for (int i = 0; i < param.second; ++i)
1103050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan      param.first->Increment();
1104050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
1105050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1106050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan// Tests that the mutex only lets one thread at a time to lock it.
1107050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanTEST(MutexTest, OnlyOneThreadCanLockAtATime) {
1108050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  Mutex mutex;
1109050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  AtomicCounterWithMutex locked_counter(&mutex);
1110050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1111050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  typedef ThreadWithParam<pair<AtomicCounterWithMutex*, int> > ThreadType;
1112050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  const int kCycleCount = 20;
1113050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  const int kThreadCount = 7;
1114050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  scoped_ptr<ThreadType> counting_threads[kThreadCount];
1115f6fb532f0825024feda89c863e33a51b6ff377f5zhanyong.wan  Notification threads_can_start;
1116050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  // Creates and runs kThreadCount threads that increment locked_counter
1117050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  // kCycleCount times each.
1118050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  for (int i = 0; i < kThreadCount; ++i) {
1119050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan    counting_threads[i].reset(new ThreadType(&CountingThreadFunc,
1120050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan                                             make_pair(&locked_counter,
1121050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan                                                       kCycleCount),
1122f6fb532f0825024feda89c863e33a51b6ff377f5zhanyong.wan                                             &threads_can_start));
1123050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  }
1124f6fb532f0825024feda89c863e33a51b6ff377f5zhanyong.wan  threads_can_start.Notify();
1125050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  for (int i = 0; i < kThreadCount; ++i)
1126050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan    counting_threads[i]->Join();
1127050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1128050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  // If the mutex lets more than one thread to increment the counter at a
1129050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  // time, they are likely to encounter a race condition and have some
1130050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  // increments overwritten, resulting in the lower then expected counter
1131050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  // value.
1132050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value());
1133050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
1134050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1135050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wantemplate <typename T>
1136050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanvoid RunFromThread(void (func)(T), T param) {
1137050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  ThreadWithParam<T> thread(func, param, NULL);
1138050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  thread.Join();
1139050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
1140050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
114103c314931649a999b0cf5deb0a434a1009157416jgm@google.comvoid RetrieveThreadLocalValue(
114203c314931649a999b0cf5deb0a434a1009157416jgm@google.com    pair<ThreadLocal<std::string>*, std::string*> param) {
1143050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  *param.second = param.first->get();
1144050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
1145050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1146050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanTEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) {
114703c314931649a999b0cf5deb0a434a1009157416jgm@google.com  ThreadLocal<std::string> thread_local_string("foo");
1148524cc4e19491029979f7b18b9451b2a6105131edvladlosev  EXPECT_STREQ("foo", thread_local_string.get().c_str());
1149050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1150524cc4e19491029979f7b18b9451b2a6105131edvladlosev  thread_local_string.set("bar");
1151524cc4e19491029979f7b18b9451b2a6105131edvladlosev  EXPECT_STREQ("bar", thread_local_string.get().c_str());
1152050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
115303c314931649a999b0cf5deb0a434a1009157416jgm@google.com  std::string result;
1154524cc4e19491029979f7b18b9451b2a6105131edvladlosev  RunFromThread(&RetrieveThreadLocalValue,
1155524cc4e19491029979f7b18b9451b2a6105131edvladlosev                make_pair(&thread_local_string, &result));
1156050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  EXPECT_STREQ("foo", result.c_str());
1157050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
1158050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1159d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com// Keeps track of whether of destructors being called on instances of
1160d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com// DestructorTracker.  On Windows, waits for the destructor call reports.
1161d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.comclass DestructorCall {
1162d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com public:
1163d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  DestructorCall() {
1164d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    invoked_ = false;
1165d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#if GTEST_OS_WINDOWS
1166d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    wait_event_.Reset(::CreateEvent(NULL, TRUE, FALSE, NULL));
1167d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    GTEST_CHECK_(wait_event_.Get() != NULL);
1168d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#endif
1169d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  }
1170d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com
1171d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  bool CheckDestroyed() const {
1172d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#if GTEST_OS_WINDOWS
1173d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    if (::WaitForSingleObject(wait_event_.Get(), 1000) != WAIT_OBJECT_0)
1174d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      return false;
1175d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#endif
1176d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    return invoked_;
1177d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  }
1178d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com
1179d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  void ReportDestroyed() {
1180d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    invoked_ = true;
1181d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#if GTEST_OS_WINDOWS
1182d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    ::SetEvent(wait_event_.Get());
1183d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#endif
1184d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  }
1185d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com
1186d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  static std::vector<DestructorCall*>& List() { return *list_; }
1187d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com
1188d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  static void ResetList() {
1189d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    for (size_t i = 0; i < list_->size(); ++i) {
1190d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com      delete list_->at(i);
1191d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    }
1192d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    list_->clear();
1193d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  }
1194d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com
1195d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com private:
1196d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  bool invoked_;
1197d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#if GTEST_OS_WINDOWS
1198d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  AutoHandle wait_event_;
1199d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#endif
1200d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  static std::vector<DestructorCall*>* const list_;
1201d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com
1202d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  GTEST_DISALLOW_COPY_AND_ASSIGN_(DestructorCall);
1203d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com};
1204d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com
1205d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.comstd::vector<DestructorCall*>* const DestructorCall::list_ =
1206d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    new std::vector<DestructorCall*>;
1207d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com
12082d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan// DestructorTracker keeps track of whether its instances have been
12092d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan// destroyed.
1210f6fb532f0825024feda89c863e33a51b6ff377f5zhanyong.wanclass DestructorTracker {
1211050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan public:
1212f6fb532f0825024feda89c863e33a51b6ff377f5zhanyong.wan  DestructorTracker() : index_(GetNewIndex()) {}
12132d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan  DestructorTracker(const DestructorTracker& /* rhs */)
12142d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan      : index_(GetNewIndex()) {}
1215f6fb532f0825024feda89c863e33a51b6ff377f5zhanyong.wan  ~DestructorTracker() {
1216d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    // We never access DestructorCall::List() concurrently, so we don't need
1217d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    // to protect this acccess with a mutex.
1218d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    DestructorCall::List()[index_]->ReportDestroyed();
1219f6fb532f0825024feda89c863e33a51b6ff377f5zhanyong.wan  }
1220050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1221050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan private:
1222f6fb532f0825024feda89c863e33a51b6ff377f5zhanyong.wan  static int GetNewIndex() {
1223d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    DestructorCall::List().push_back(new DestructorCall);
1224d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    return DestructorCall::List().size() - 1;
1225f6fb532f0825024feda89c863e33a51b6ff377f5zhanyong.wan  }
1226f6fb532f0825024feda89c863e33a51b6ff377f5zhanyong.wan  const int index_;
1227d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com
1228d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  GTEST_DISALLOW_ASSIGN_(DestructorTracker);
1229050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan};
1230050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
12312d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wantypedef ThreadLocal<DestructorTracker>* ThreadParam;
12322d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan
1233524cc4e19491029979f7b18b9451b2a6105131edvladlosevvoid CallThreadLocalGet(ThreadParam thread_local_param) {
1234524cc4e19491029979f7b18b9451b2a6105131edvladlosev  thread_local_param->get();
12352d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan}
12362d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan
12372d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan// Tests that when a ThreadLocal object dies in a thread, it destroys
12382d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan// the managed object for that thread.
12392d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wanTEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) {
1240d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  DestructorCall::ResetList();
12412d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan
12422d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan  {
12432d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan    // The next line default constructs a DestructorTracker object as
1244524cc4e19491029979f7b18b9451b2a6105131edvladlosev    // the default value of objects managed by thread_local_tracker.
1245524cc4e19491029979f7b18b9451b2a6105131edvladlosev    ThreadLocal<DestructorTracker> thread_local_tracker;
1246d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    ASSERT_EQ(1U, DestructorCall::List().size());
1247d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed());
12482d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan
12492d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan    // This creates another DestructorTracker object for the main thread.
1250524cc4e19491029979f7b18b9451b2a6105131edvladlosev    thread_local_tracker.get();
1251d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    ASSERT_EQ(2U, DestructorCall::List().size());
1252d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed());
1253d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    ASSERT_FALSE(DestructorCall::List()[1]->CheckDestroyed());
12542d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan  }
12552d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan
1256524cc4e19491029979f7b18b9451b2a6105131edvladlosev  // Now thread_local_tracker has died.  It should have destroyed both the
12572d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan  // default value shared by all threads and the value for the main
12582d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan  // thread.
1259d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  ASSERT_EQ(2U, DestructorCall::List().size());
1260d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed());
1261d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  EXPECT_TRUE(DestructorCall::List()[1]->CheckDestroyed());
12622d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan
1263d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  DestructorCall::ResetList();
1264050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
1265050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
12662d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan// Tests that when a thread exits, the thread-local object for that
12672d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan// thread is destroyed.
12682d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wanTEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) {
1269d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  DestructorCall::ResetList();
12702d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan
1271050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  {
12722d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan    // The next line default constructs a DestructorTracker object as
1273524cc4e19491029979f7b18b9451b2a6105131edvladlosev    // the default value of objects managed by thread_local_tracker.
1274524cc4e19491029979f7b18b9451b2a6105131edvladlosev    ThreadLocal<DestructorTracker> thread_local_tracker;
1275d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    ASSERT_EQ(1U, DestructorCall::List().size());
1276d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed());
12772d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan
12782d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan    // This creates another DestructorTracker object in the new thread.
12792d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan    ThreadWithParam<ThreadParam> thread(
1280524cc4e19491029979f7b18b9451b2a6105131edvladlosev        &CallThreadLocalGet, &thread_local_tracker, NULL);
1281050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan    thread.Join();
12822d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan
1283d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    // The thread has exited, and we should have another DestroyedTracker
1284d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    // instance created for it. But it may not have been destroyed yet.
1285d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    // The instance for the main thread should still persist.
1286d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    ASSERT_EQ(2U, DestructorCall::List().size());
1287d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com    ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed());
1288050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan  }
12892d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan
1290d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  // The thread has exited and thread_local_tracker has died.  The default
1291d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  // value should have been destroyed too.
1292d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  ASSERT_EQ(2U, DestructorCall::List().size());
1293d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed());
1294d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  EXPECT_TRUE(DestructorCall::List()[1]->CheckDestroyed());
1295f6fb532f0825024feda89c863e33a51b6ff377f5zhanyong.wan
1296d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  DestructorCall::ResetList();
1297050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
1298050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1299050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wanTEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) {
130003c314931649a999b0cf5deb0a434a1009157416jgm@google.com  ThreadLocal<std::string> thread_local_string;
1301524cc4e19491029979f7b18b9451b2a6105131edvladlosev  thread_local_string.set("Foo");
1302524cc4e19491029979f7b18b9451b2a6105131edvladlosev  EXPECT_STREQ("Foo", thread_local_string.get().c_str());
1303050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
130403c314931649a999b0cf5deb0a434a1009157416jgm@google.com  std::string result;
1305524cc4e19491029979f7b18b9451b2a6105131edvladlosev  RunFromThread(&RetrieveThreadLocalValue,
1306524cc4e19491029979f7b18b9451b2a6105131edvladlosev                make_pair(&thread_local_string, &result));
130703c314931649a999b0cf5deb0a434a1009157416jgm@google.com  EXPECT_TRUE(result.empty());
1308050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan}
13092d9d6341c1db471ce1520decd58fbdc39e46a457zhanyong.wan
1310050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan#endif  // GTEST_IS_THREADSAFE
1311050a520ddf9a34b93a3b41704fa2450d7450783fzhanyong.wan
1312d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#if GTEST_OS_WINDOWS
1313d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.comTEST(WindowsTypesTest, HANDLEIsVoidStar) {
1314d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  StaticAssertTypeEq<HANDLE, void*>();
1315d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com}
1316d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com
1317d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.comTEST(WindowsTypesTest, CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION) {
1318d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com  StaticAssertTypeEq<CRITICAL_SECTION, _RTL_CRITICAL_SECTION>();
1319d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com}
1320d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com#endif  // GTEST_OS_WINDOWS
1321d132283f055f07588d82ad43fbf501645cb39c9dkosak@google.com
1322d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}  // namespace internal
1323d40d06d49055d6286a0a9fead61c0f86d94bc557zhanyong.wan}  // namespace testing
1324