113481Sgiacomo.travaglini@arm.com// Copyright 2008, Google Inc.
213481Sgiacomo.travaglini@arm.com// All rights reserved.
313481Sgiacomo.travaglini@arm.com//
413481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without
513481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are
613481Sgiacomo.travaglini@arm.com// met:
713481Sgiacomo.travaglini@arm.com//
813481Sgiacomo.travaglini@arm.com//     * Redistributions of source code must retain the above copyright
913481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer.
1013481Sgiacomo.travaglini@arm.com//     * Redistributions in binary form must reproduce the above
1113481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer
1213481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the
1313481Sgiacomo.travaglini@arm.com// distribution.
1413481Sgiacomo.travaglini@arm.com//     * Neither the name of Google Inc. nor the names of its
1513481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from
1613481Sgiacomo.travaglini@arm.com// this software without specific prior written permission.
1713481Sgiacomo.travaglini@arm.com//
1813481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1913481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2013481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2113481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2213481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2313481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2413481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2513481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2613481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2713481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2813481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2913481Sgiacomo.travaglini@arm.com//
3013481Sgiacomo.travaglini@arm.com// Authors: vladl@google.com (Vlad Losev), wan@google.com (Zhanyong Wan)
3113481Sgiacomo.travaglini@arm.com//
3213481Sgiacomo.travaglini@arm.com// This file tests the internal cross-platform support utilities.
3313481Sgiacomo.travaglini@arm.com
3413481Sgiacomo.travaglini@arm.com#include "gtest/internal/gtest-port.h"
3513481Sgiacomo.travaglini@arm.com
3613481Sgiacomo.travaglini@arm.com#include <stdio.h>
3713481Sgiacomo.travaglini@arm.com
3813481Sgiacomo.travaglini@arm.com#if GTEST_OS_MAC
3913481Sgiacomo.travaglini@arm.com# include <time.h>
4013481Sgiacomo.travaglini@arm.com#endif  // GTEST_OS_MAC
4113481Sgiacomo.travaglini@arm.com
4213481Sgiacomo.travaglini@arm.com#include <list>
4313481Sgiacomo.travaglini@arm.com#include <utility>  // For std::pair and std::make_pair.
4413481Sgiacomo.travaglini@arm.com#include <vector>
4513481Sgiacomo.travaglini@arm.com
4613481Sgiacomo.travaglini@arm.com#include "gtest/gtest.h"
4713481Sgiacomo.travaglini@arm.com#include "gtest/gtest-spi.h"
4813481Sgiacomo.travaglini@arm.com
4913481Sgiacomo.travaglini@arm.com// Indicates that this translation unit is part of Google Test's
5013481Sgiacomo.travaglini@arm.com// implementation.  It must come before gtest-internal-inl.h is
5113481Sgiacomo.travaglini@arm.com// included, or there will be a compiler error.  This trick is to
5213481Sgiacomo.travaglini@arm.com// prevent a user from accidentally including gtest-internal-inl.h in
5313481Sgiacomo.travaglini@arm.com// his code.
5413481Sgiacomo.travaglini@arm.com#define GTEST_IMPLEMENTATION_ 1
5513481Sgiacomo.travaglini@arm.com#include "src/gtest-internal-inl.h"
5613481Sgiacomo.travaglini@arm.com#undef GTEST_IMPLEMENTATION_
5713481Sgiacomo.travaglini@arm.com
5813481Sgiacomo.travaglini@arm.comusing std::make_pair;
5913481Sgiacomo.travaglini@arm.comusing std::pair;
6013481Sgiacomo.travaglini@arm.com
6113481Sgiacomo.travaglini@arm.comnamespace testing {
6213481Sgiacomo.travaglini@arm.comnamespace internal {
6313481Sgiacomo.travaglini@arm.com
6413481Sgiacomo.travaglini@arm.comTEST(IsXDigitTest, WorksForNarrowAscii) {
6513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsXDigit('0'));
6613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsXDigit('9'));
6713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsXDigit('A'));
6813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsXDigit('F'));
6913481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsXDigit('a'));
7013481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsXDigit('f'));
7113481Sgiacomo.travaglini@arm.com
7213481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsXDigit('-'));
7313481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsXDigit('g'));
7413481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsXDigit('G'));
7513481Sgiacomo.travaglini@arm.com}
7613481Sgiacomo.travaglini@arm.com
7713481Sgiacomo.travaglini@arm.comTEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) {
7813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsXDigit('\x80'));
7913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsXDigit(static_cast<char>('0' | '\x80')));
8013481Sgiacomo.travaglini@arm.com}
8113481Sgiacomo.travaglini@arm.com
8213481Sgiacomo.travaglini@arm.comTEST(IsXDigitTest, WorksForWideAscii) {
8313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsXDigit(L'0'));
8413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsXDigit(L'9'));
8513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsXDigit(L'A'));
8613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsXDigit(L'F'));
8713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsXDigit(L'a'));
8813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsXDigit(L'f'));
8913481Sgiacomo.travaglini@arm.com
9013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsXDigit(L'-'));
9113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsXDigit(L'g'));
9213481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsXDigit(L'G'));
9313481Sgiacomo.travaglini@arm.com}
9413481Sgiacomo.travaglini@arm.com
9513481Sgiacomo.travaglini@arm.comTEST(IsXDigitTest, ReturnsFalseForWideNonAscii) {
9613481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsXDigit(static_cast<wchar_t>(0x80)));
9713481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsXDigit(static_cast<wchar_t>(L'0' | 0x80)));
9813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsXDigit(static_cast<wchar_t>(L'0' | 0x100)));
9913481Sgiacomo.travaglini@arm.com}
10013481Sgiacomo.travaglini@arm.com
10113481Sgiacomo.travaglini@arm.comclass Base {
10213481Sgiacomo.travaglini@arm.com public:
10313481Sgiacomo.travaglini@arm.com  // Copy constructor and assignment operator do exactly what we need, so we
10413481Sgiacomo.travaglini@arm.com  // use them.
10513481Sgiacomo.travaglini@arm.com  Base() : member_(0) {}
10613481Sgiacomo.travaglini@arm.com  explicit Base(int n) : member_(n) {}
10713481Sgiacomo.travaglini@arm.com  virtual ~Base() {}
10813481Sgiacomo.travaglini@arm.com  int member() { return member_; }
10913481Sgiacomo.travaglini@arm.com
11013481Sgiacomo.travaglini@arm.com private:
11113481Sgiacomo.travaglini@arm.com  int member_;
11213481Sgiacomo.travaglini@arm.com};
11313481Sgiacomo.travaglini@arm.com
11413481Sgiacomo.travaglini@arm.comclass Derived : public Base {
11513481Sgiacomo.travaglini@arm.com public:
11613481Sgiacomo.travaglini@arm.com  explicit Derived(int n) : Base(n) {}
11713481Sgiacomo.travaglini@arm.com};
11813481Sgiacomo.travaglini@arm.com
11913481Sgiacomo.travaglini@arm.comTEST(ImplicitCastTest, ConvertsPointers) {
12013481Sgiacomo.travaglini@arm.com  Derived derived(0);
12113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(&derived == ::testing::internal::ImplicitCast_<Base*>(&derived));
12213481Sgiacomo.travaglini@arm.com}
12313481Sgiacomo.travaglini@arm.com
12413481Sgiacomo.travaglini@arm.comTEST(ImplicitCastTest, CanUseInheritance) {
12513481Sgiacomo.travaglini@arm.com  Derived derived(1);
12613481Sgiacomo.travaglini@arm.com  Base base = ::testing::internal::ImplicitCast_<Base>(derived);
12713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(derived.member(), base.member());
12813481Sgiacomo.travaglini@arm.com}
12913481Sgiacomo.travaglini@arm.com
13013481Sgiacomo.travaglini@arm.comclass Castable {
13113481Sgiacomo.travaglini@arm.com public:
13213481Sgiacomo.travaglini@arm.com  explicit Castable(bool* converted) : converted_(converted) {}
13313481Sgiacomo.travaglini@arm.com  operator Base() {
13413481Sgiacomo.travaglini@arm.com    *converted_ = true;
13513481Sgiacomo.travaglini@arm.com    return Base();
13613481Sgiacomo.travaglini@arm.com  }
13713481Sgiacomo.travaglini@arm.com
13813481Sgiacomo.travaglini@arm.com private:
13913481Sgiacomo.travaglini@arm.com  bool* converted_;
14013481Sgiacomo.travaglini@arm.com};
14113481Sgiacomo.travaglini@arm.com
14213481Sgiacomo.travaglini@arm.comTEST(ImplicitCastTest, CanUseNonConstCastOperator) {
14313481Sgiacomo.travaglini@arm.com  bool converted = false;
14413481Sgiacomo.travaglini@arm.com  Castable castable(&converted);
14513481Sgiacomo.travaglini@arm.com  Base base = ::testing::internal::ImplicitCast_<Base>(castable);
14613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(converted);
14713481Sgiacomo.travaglini@arm.com}
14813481Sgiacomo.travaglini@arm.com
14913481Sgiacomo.travaglini@arm.comclass ConstCastable {
15013481Sgiacomo.travaglini@arm.com public:
15113481Sgiacomo.travaglini@arm.com  explicit ConstCastable(bool* converted) : converted_(converted) {}
15213481Sgiacomo.travaglini@arm.com  operator Base() const {
15313481Sgiacomo.travaglini@arm.com    *converted_ = true;
15413481Sgiacomo.travaglini@arm.com    return Base();
15513481Sgiacomo.travaglini@arm.com  }
15613481Sgiacomo.travaglini@arm.com
15713481Sgiacomo.travaglini@arm.com private:
15813481Sgiacomo.travaglini@arm.com  bool* converted_;
15913481Sgiacomo.travaglini@arm.com};
16013481Sgiacomo.travaglini@arm.com
16113481Sgiacomo.travaglini@arm.comTEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) {
16213481Sgiacomo.travaglini@arm.com  bool converted = false;
16313481Sgiacomo.travaglini@arm.com  const ConstCastable const_castable(&converted);
16413481Sgiacomo.travaglini@arm.com  Base base = ::testing::internal::ImplicitCast_<Base>(const_castable);
16513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(converted);
16613481Sgiacomo.travaglini@arm.com}
16713481Sgiacomo.travaglini@arm.com
16813481Sgiacomo.travaglini@arm.comclass ConstAndNonConstCastable {
16913481Sgiacomo.travaglini@arm.com public:
17013481Sgiacomo.travaglini@arm.com  ConstAndNonConstCastable(bool* converted, bool* const_converted)
17113481Sgiacomo.travaglini@arm.com      : converted_(converted), const_converted_(const_converted) {}
17213481Sgiacomo.travaglini@arm.com  operator Base() {
17313481Sgiacomo.travaglini@arm.com    *converted_ = true;
17413481Sgiacomo.travaglini@arm.com    return Base();
17513481Sgiacomo.travaglini@arm.com  }
17613481Sgiacomo.travaglini@arm.com  operator Base() const {
17713481Sgiacomo.travaglini@arm.com    *const_converted_ = true;
17813481Sgiacomo.travaglini@arm.com    return Base();
17913481Sgiacomo.travaglini@arm.com  }
18013481Sgiacomo.travaglini@arm.com
18113481Sgiacomo.travaglini@arm.com private:
18213481Sgiacomo.travaglini@arm.com  bool* converted_;
18313481Sgiacomo.travaglini@arm.com  bool* const_converted_;
18413481Sgiacomo.travaglini@arm.com};
18513481Sgiacomo.travaglini@arm.com
18613481Sgiacomo.travaglini@arm.comTEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) {
18713481Sgiacomo.travaglini@arm.com  bool converted = false;
18813481Sgiacomo.travaglini@arm.com  bool const_converted = false;
18913481Sgiacomo.travaglini@arm.com  ConstAndNonConstCastable castable(&converted, &const_converted);
19013481Sgiacomo.travaglini@arm.com  Base base = ::testing::internal::ImplicitCast_<Base>(castable);
19113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(converted);
19213481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(const_converted);
19313481Sgiacomo.travaglini@arm.com
19413481Sgiacomo.travaglini@arm.com  converted = false;
19513481Sgiacomo.travaglini@arm.com  const_converted = false;
19613481Sgiacomo.travaglini@arm.com  const ConstAndNonConstCastable const_castable(&converted, &const_converted);
19713481Sgiacomo.travaglini@arm.com  base = ::testing::internal::ImplicitCast_<Base>(const_castable);
19813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(converted);
19913481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(const_converted);
20013481Sgiacomo.travaglini@arm.com}
20113481Sgiacomo.travaglini@arm.com
20213481Sgiacomo.travaglini@arm.comclass To {
20313481Sgiacomo.travaglini@arm.com public:
20413481Sgiacomo.travaglini@arm.com  To(bool* converted) { *converted = true; }  // NOLINT
20513481Sgiacomo.travaglini@arm.com};
20613481Sgiacomo.travaglini@arm.com
20713481Sgiacomo.travaglini@arm.comTEST(ImplicitCastTest, CanUseImplicitConstructor) {
20813481Sgiacomo.travaglini@arm.com  bool converted = false;
20913481Sgiacomo.travaglini@arm.com  To to = ::testing::internal::ImplicitCast_<To>(&converted);
21013481Sgiacomo.travaglini@arm.com  (void)to;
21113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(converted);
21213481Sgiacomo.travaglini@arm.com}
21313481Sgiacomo.travaglini@arm.com
21413481Sgiacomo.travaglini@arm.comTEST(IteratorTraitsTest, WorksForSTLContainerIterators) {
21513481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<int,
21613481Sgiacomo.travaglini@arm.com      IteratorTraits< ::std::vector<int>::const_iterator>::value_type>();
21713481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<bool,
21813481Sgiacomo.travaglini@arm.com      IteratorTraits< ::std::list<bool>::iterator>::value_type>();
21913481Sgiacomo.travaglini@arm.com}
22013481Sgiacomo.travaglini@arm.com
22113481Sgiacomo.travaglini@arm.comTEST(IteratorTraitsTest, WorksForPointerToNonConst) {
22213481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<char, IteratorTraits<char*>::value_type>();
22313481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<const void*, IteratorTraits<const void**>::value_type>();
22413481Sgiacomo.travaglini@arm.com}
22513481Sgiacomo.travaglini@arm.com
22613481Sgiacomo.travaglini@arm.comTEST(IteratorTraitsTest, WorksForPointerToConst) {
22713481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<char, IteratorTraits<const char*>::value_type>();
22813481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<const void*,
22913481Sgiacomo.travaglini@arm.com      IteratorTraits<const void* const*>::value_type>();
23013481Sgiacomo.travaglini@arm.com}
23113481Sgiacomo.travaglini@arm.com
23213481Sgiacomo.travaglini@arm.com// Tests that the element_type typedef is available in scoped_ptr and refers
23313481Sgiacomo.travaglini@arm.com// to the parameter type.
23413481Sgiacomo.travaglini@arm.comTEST(ScopedPtrTest, DefinesElementType) {
23513481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<int, ::testing::internal::scoped_ptr<int>::element_type>();
23613481Sgiacomo.travaglini@arm.com}
23713481Sgiacomo.travaglini@arm.com
23813481Sgiacomo.travaglini@arm.com// TODO(vladl@google.com): Implement THE REST of scoped_ptr tests.
23913481Sgiacomo.travaglini@arm.com
24013481Sgiacomo.travaglini@arm.comTEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) {
24113481Sgiacomo.travaglini@arm.com  if (AlwaysFalse())
24213481Sgiacomo.travaglini@arm.com    GTEST_CHECK_(false) << "This should never be executed; "
24313481Sgiacomo.travaglini@arm.com                           "It's a compilation test only.";
24413481Sgiacomo.travaglini@arm.com
24513481Sgiacomo.travaglini@arm.com  if (AlwaysTrue())
24613481Sgiacomo.travaglini@arm.com    GTEST_CHECK_(true);
24713481Sgiacomo.travaglini@arm.com  else
24813481Sgiacomo.travaglini@arm.com    ;  // NOLINT
24913481Sgiacomo.travaglini@arm.com
25013481Sgiacomo.travaglini@arm.com  if (AlwaysFalse())
25113481Sgiacomo.travaglini@arm.com    ;  // NOLINT
25213481Sgiacomo.travaglini@arm.com  else
25313481Sgiacomo.travaglini@arm.com    GTEST_CHECK_(true) << "";
25413481Sgiacomo.travaglini@arm.com}
25513481Sgiacomo.travaglini@arm.com
25613481Sgiacomo.travaglini@arm.comTEST(GtestCheckSyntaxTest, WorksWithSwitch) {
25713481Sgiacomo.travaglini@arm.com  switch (0) {
25813481Sgiacomo.travaglini@arm.com    case 1:
25913481Sgiacomo.travaglini@arm.com      break;
26013481Sgiacomo.travaglini@arm.com    default:
26113481Sgiacomo.travaglini@arm.com      GTEST_CHECK_(true);
26213481Sgiacomo.travaglini@arm.com  }
26313481Sgiacomo.travaglini@arm.com
26413481Sgiacomo.travaglini@arm.com  switch (0)
26513481Sgiacomo.travaglini@arm.com    case 0:
26613481Sgiacomo.travaglini@arm.com      GTEST_CHECK_(true) << "Check failed in switch case";
26713481Sgiacomo.travaglini@arm.com}
26813481Sgiacomo.travaglini@arm.com
26913481Sgiacomo.travaglini@arm.com// Verifies behavior of FormatFileLocation.
27013481Sgiacomo.travaglini@arm.comTEST(FormatFileLocationTest, FormatsFileLocation) {
27113481Sgiacomo.travaglini@arm.com  EXPECT_PRED_FORMAT2(IsSubstring, "foo.cc", FormatFileLocation("foo.cc", 42));
27213481Sgiacomo.travaglini@arm.com  EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation("foo.cc", 42));
27313481Sgiacomo.travaglini@arm.com}
27413481Sgiacomo.travaglini@arm.com
27513481Sgiacomo.travaglini@arm.comTEST(FormatFileLocationTest, FormatsUnknownFile) {
27613481Sgiacomo.travaglini@arm.com  EXPECT_PRED_FORMAT2(
27713481Sgiacomo.travaglini@arm.com      IsSubstring, "unknown file", FormatFileLocation(NULL, 42));
27813481Sgiacomo.travaglini@arm.com  EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation(NULL, 42));
27913481Sgiacomo.travaglini@arm.com}
28013481Sgiacomo.travaglini@arm.com
28113481Sgiacomo.travaglini@arm.comTEST(FormatFileLocationTest, FormatsUknownLine) {
28213481Sgiacomo.travaglini@arm.com  EXPECT_EQ("foo.cc:", FormatFileLocation("foo.cc", -1));
28313481Sgiacomo.travaglini@arm.com}
28413481Sgiacomo.travaglini@arm.com
28513481Sgiacomo.travaglini@arm.comTEST(FormatFileLocationTest, FormatsUknownFileAndLine) {
28613481Sgiacomo.travaglini@arm.com  EXPECT_EQ("unknown file:", FormatFileLocation(NULL, -1));
28713481Sgiacomo.travaglini@arm.com}
28813481Sgiacomo.travaglini@arm.com
28913481Sgiacomo.travaglini@arm.com// Verifies behavior of FormatCompilerIndependentFileLocation.
29013481Sgiacomo.travaglini@arm.comTEST(FormatCompilerIndependentFileLocationTest, FormatsFileLocation) {
29113481Sgiacomo.travaglini@arm.com  EXPECT_EQ("foo.cc:42", FormatCompilerIndependentFileLocation("foo.cc", 42));
29213481Sgiacomo.travaglini@arm.com}
29313481Sgiacomo.travaglini@arm.com
29413481Sgiacomo.travaglini@arm.comTEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFile) {
29513481Sgiacomo.travaglini@arm.com  EXPECT_EQ("unknown file:42",
29613481Sgiacomo.travaglini@arm.com            FormatCompilerIndependentFileLocation(NULL, 42));
29713481Sgiacomo.travaglini@arm.com}
29813481Sgiacomo.travaglini@arm.com
29913481Sgiacomo.travaglini@arm.comTEST(FormatCompilerIndependentFileLocationTest, FormatsUknownLine) {
30013481Sgiacomo.travaglini@arm.com  EXPECT_EQ("foo.cc", FormatCompilerIndependentFileLocation("foo.cc", -1));
30113481Sgiacomo.travaglini@arm.com}
30213481Sgiacomo.travaglini@arm.com
30313481Sgiacomo.travaglini@arm.comTEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) {
30413481Sgiacomo.travaglini@arm.com  EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1));
30513481Sgiacomo.travaglini@arm.com}
30613481Sgiacomo.travaglini@arm.com
30713481Sgiacomo.travaglini@arm.com#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX
30813481Sgiacomo.travaglini@arm.comvoid* ThreadFunc(void* data) {
30913481Sgiacomo.travaglini@arm.com  internal::Mutex* mutex = static_cast<internal::Mutex*>(data);
31013481Sgiacomo.travaglini@arm.com  mutex->Lock();
31113481Sgiacomo.travaglini@arm.com  mutex->Unlock();
31213481Sgiacomo.travaglini@arm.com  return NULL;
31313481Sgiacomo.travaglini@arm.com}
31413481Sgiacomo.travaglini@arm.com
31513481Sgiacomo.travaglini@arm.comTEST(GetThreadCountTest, ReturnsCorrectValue) {
31613481Sgiacomo.travaglini@arm.com  const size_t starting_count = GetThreadCount();
31713481Sgiacomo.travaglini@arm.com  pthread_t       thread_id;
31813481Sgiacomo.travaglini@arm.com
31913481Sgiacomo.travaglini@arm.com  internal::Mutex mutex;
32013481Sgiacomo.travaglini@arm.com  {
32113481Sgiacomo.travaglini@arm.com    internal::MutexLock lock(&mutex);
32213481Sgiacomo.travaglini@arm.com    pthread_attr_t  attr;
32313481Sgiacomo.travaglini@arm.com    ASSERT_EQ(0, pthread_attr_init(&attr));
32413481Sgiacomo.travaglini@arm.com    ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
32513481Sgiacomo.travaglini@arm.com
32613481Sgiacomo.travaglini@arm.com    const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex);
32713481Sgiacomo.travaglini@arm.com    ASSERT_EQ(0, pthread_attr_destroy(&attr));
32813481Sgiacomo.travaglini@arm.com    ASSERT_EQ(0, status);
32913481Sgiacomo.travaglini@arm.com    EXPECT_EQ(starting_count + 1, GetThreadCount());
33013481Sgiacomo.travaglini@arm.com  }
33113481Sgiacomo.travaglini@arm.com
33213481Sgiacomo.travaglini@arm.com  void* dummy;
33313481Sgiacomo.travaglini@arm.com  ASSERT_EQ(0, pthread_join(thread_id, &dummy));
33413481Sgiacomo.travaglini@arm.com
33513481Sgiacomo.travaglini@arm.com  // The OS may not immediately report the updated thread count after
33613481Sgiacomo.travaglini@arm.com  // joining a thread, causing flakiness in this test. To counter that, we
33713481Sgiacomo.travaglini@arm.com  // wait for up to .5 seconds for the OS to report the correct value.
33813481Sgiacomo.travaglini@arm.com  for (int i = 0; i < 5; ++i) {
33913481Sgiacomo.travaglini@arm.com    if (GetThreadCount() == starting_count)
34013481Sgiacomo.travaglini@arm.com      break;
34113481Sgiacomo.travaglini@arm.com
34213481Sgiacomo.travaglini@arm.com    SleepMilliseconds(100);
34313481Sgiacomo.travaglini@arm.com  }
34413481Sgiacomo.travaglini@arm.com
34513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(starting_count, GetThreadCount());
34613481Sgiacomo.travaglini@arm.com}
34713481Sgiacomo.travaglini@arm.com#else
34813481Sgiacomo.travaglini@arm.comTEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) {
34913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(0U, GetThreadCount());
35013481Sgiacomo.travaglini@arm.com}
35113481Sgiacomo.travaglini@arm.com#endif  // GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX
35213481Sgiacomo.travaglini@arm.com
35313481Sgiacomo.travaglini@arm.comTEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) {
35413481Sgiacomo.travaglini@arm.com  const bool a_false_condition = false;
35513481Sgiacomo.travaglini@arm.com  const char regex[] =
35613481Sgiacomo.travaglini@arm.com#ifdef _MSC_VER
35713481Sgiacomo.travaglini@arm.com     "gtest-port_test\\.cc\\(\\d+\\):"
35813481Sgiacomo.travaglini@arm.com#elif GTEST_USES_POSIX_RE
35913481Sgiacomo.travaglini@arm.com     "gtest-port_test\\.cc:[0-9]+"
36013481Sgiacomo.travaglini@arm.com#else
36113481Sgiacomo.travaglini@arm.com     "gtest-port_test\\.cc:\\d+"
36213481Sgiacomo.travaglini@arm.com#endif  // _MSC_VER
36313481Sgiacomo.travaglini@arm.com     ".*a_false_condition.*Extra info.*";
36413481Sgiacomo.travaglini@arm.com
36513481Sgiacomo.travaglini@arm.com  EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info",
36613481Sgiacomo.travaglini@arm.com                            regex);
36713481Sgiacomo.travaglini@arm.com}
36813481Sgiacomo.travaglini@arm.com
36913481Sgiacomo.travaglini@arm.com#if GTEST_HAS_DEATH_TEST
37013481Sgiacomo.travaglini@arm.com
37113481Sgiacomo.travaglini@arm.comTEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) {
37213481Sgiacomo.travaglini@arm.com  EXPECT_EXIT({
37313481Sgiacomo.travaglini@arm.com      GTEST_CHECK_(true) << "Extra info";
37413481Sgiacomo.travaglini@arm.com      ::std::cerr << "Success\n";
37513481Sgiacomo.travaglini@arm.com      exit(0); },
37613481Sgiacomo.travaglini@arm.com      ::testing::ExitedWithCode(0), "Success");
37713481Sgiacomo.travaglini@arm.com}
37813481Sgiacomo.travaglini@arm.com
37913481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_DEATH_TEST
38013481Sgiacomo.travaglini@arm.com
38113481Sgiacomo.travaglini@arm.com// Verifies that Google Test choose regular expression engine appropriate to
38213481Sgiacomo.travaglini@arm.com// the platform. The test will produce compiler errors in case of failure.
38313481Sgiacomo.travaglini@arm.com// For simplicity, we only cover the most important platforms here.
38413481Sgiacomo.travaglini@arm.comTEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) {
38513481Sgiacomo.travaglini@arm.com#if !GTEST_USES_PCRE
38613481Sgiacomo.travaglini@arm.com# if GTEST_HAS_POSIX_RE
38713481Sgiacomo.travaglini@arm.com
38813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(GTEST_USES_POSIX_RE);
38913481Sgiacomo.travaglini@arm.com
39013481Sgiacomo.travaglini@arm.com# else
39113481Sgiacomo.travaglini@arm.com
39213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(GTEST_USES_SIMPLE_RE);
39313481Sgiacomo.travaglini@arm.com
39413481Sgiacomo.travaglini@arm.com# endif
39513481Sgiacomo.travaglini@arm.com#endif  // !GTEST_USES_PCRE
39613481Sgiacomo.travaglini@arm.com}
39713481Sgiacomo.travaglini@arm.com
39813481Sgiacomo.travaglini@arm.com#if GTEST_USES_POSIX_RE
39913481Sgiacomo.travaglini@arm.com
40013481Sgiacomo.travaglini@arm.com# if GTEST_HAS_TYPED_TEST
40113481Sgiacomo.travaglini@arm.com
40213481Sgiacomo.travaglini@arm.comtemplate <typename Str>
40313481Sgiacomo.travaglini@arm.comclass RETest : public ::testing::Test {};
40413481Sgiacomo.travaglini@arm.com
40513481Sgiacomo.travaglini@arm.com// Defines StringTypes as the list of all string types that class RE
40613481Sgiacomo.travaglini@arm.com// supports.
40713481Sgiacomo.travaglini@arm.comtypedef testing::Types<
40813481Sgiacomo.travaglini@arm.com    ::std::string,
40913481Sgiacomo.travaglini@arm.com#  if GTEST_HAS_GLOBAL_STRING
41013481Sgiacomo.travaglini@arm.com    ::string,
41113481Sgiacomo.travaglini@arm.com#  endif  // GTEST_HAS_GLOBAL_STRING
41213481Sgiacomo.travaglini@arm.com    const char*> StringTypes;
41313481Sgiacomo.travaglini@arm.com
41413481Sgiacomo.travaglini@arm.comTYPED_TEST_CASE(RETest, StringTypes);
41513481Sgiacomo.travaglini@arm.com
41613481Sgiacomo.travaglini@arm.com// Tests RE's implicit constructors.
41713481Sgiacomo.travaglini@arm.comTYPED_TEST(RETest, ImplicitConstructorWorks) {
41813481Sgiacomo.travaglini@arm.com  const RE empty(TypeParam(""));
41913481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("", empty.pattern());
42013481Sgiacomo.travaglini@arm.com
42113481Sgiacomo.travaglini@arm.com  const RE simple(TypeParam("hello"));
42213481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("hello", simple.pattern());
42313481Sgiacomo.travaglini@arm.com
42413481Sgiacomo.travaglini@arm.com  const RE normal(TypeParam(".*(\\w+)"));
42513481Sgiacomo.travaglini@arm.com  EXPECT_STREQ(".*(\\w+)", normal.pattern());
42613481Sgiacomo.travaglini@arm.com}
42713481Sgiacomo.travaglini@arm.com
42813481Sgiacomo.travaglini@arm.com// Tests that RE's constructors reject invalid regular expressions.
42913481Sgiacomo.travaglini@arm.comTYPED_TEST(RETest, RejectsInvalidRegex) {
43013481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE({
43113481Sgiacomo.travaglini@arm.com    const RE invalid(TypeParam("?"));
43213481Sgiacomo.travaglini@arm.com  }, "\"?\" is not a valid POSIX Extended regular expression.");
43313481Sgiacomo.travaglini@arm.com}
43413481Sgiacomo.travaglini@arm.com
43513481Sgiacomo.travaglini@arm.com// Tests RE::FullMatch().
43613481Sgiacomo.travaglini@arm.comTYPED_TEST(RETest, FullMatchWorks) {
43713481Sgiacomo.travaglini@arm.com  const RE empty(TypeParam(""));
43813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty));
43913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty));
44013481Sgiacomo.travaglini@arm.com
44113481Sgiacomo.travaglini@arm.com  const RE re(TypeParam("a.*z"));
44213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re));
44313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re));
44413481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re));
44513481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(RE::FullMatch(TypeParam("azy"), re));
44613481Sgiacomo.travaglini@arm.com}
44713481Sgiacomo.travaglini@arm.com
44813481Sgiacomo.travaglini@arm.com// Tests RE::PartialMatch().
44913481Sgiacomo.travaglini@arm.comTYPED_TEST(RETest, PartialMatchWorks) {
45013481Sgiacomo.travaglini@arm.com  const RE empty(TypeParam(""));
45113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty));
45213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty));
45313481Sgiacomo.travaglini@arm.com
45413481Sgiacomo.travaglini@arm.com  const RE re(TypeParam("a.*z"));
45513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re));
45613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re));
45713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re));
45813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::PartialMatch(TypeParam("azy"), re));
45913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re));
46013481Sgiacomo.travaglini@arm.com}
46113481Sgiacomo.travaglini@arm.com
46213481Sgiacomo.travaglini@arm.com# endif  // GTEST_HAS_TYPED_TEST
46313481Sgiacomo.travaglini@arm.com
46413481Sgiacomo.travaglini@arm.com#elif GTEST_USES_SIMPLE_RE
46513481Sgiacomo.travaglini@arm.com
46613481Sgiacomo.travaglini@arm.comTEST(IsInSetTest, NulCharIsNotInAnySet) {
46713481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsInSet('\0', ""));
46813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsInSet('\0', "\0"));
46913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsInSet('\0', "a"));
47013481Sgiacomo.travaglini@arm.com}
47113481Sgiacomo.travaglini@arm.com
47213481Sgiacomo.travaglini@arm.comTEST(IsInSetTest, WorksForNonNulChars) {
47313481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsInSet('a', "Ab"));
47413481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsInSet('c', ""));
47513481Sgiacomo.travaglini@arm.com
47613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsInSet('b', "bcd"));
47713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsInSet('b', "ab"));
47813481Sgiacomo.travaglini@arm.com}
47913481Sgiacomo.travaglini@arm.com
48013481Sgiacomo.travaglini@arm.comTEST(IsAsciiDigitTest, IsFalseForNonDigit) {
48113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiDigit('\0'));
48213481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiDigit(' '));
48313481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiDigit('+'));
48413481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiDigit('-'));
48513481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiDigit('.'));
48613481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiDigit('a'));
48713481Sgiacomo.travaglini@arm.com}
48813481Sgiacomo.travaglini@arm.com
48913481Sgiacomo.travaglini@arm.comTEST(IsAsciiDigitTest, IsTrueForDigit) {
49013481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiDigit('0'));
49113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiDigit('1'));
49213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiDigit('5'));
49313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiDigit('9'));
49413481Sgiacomo.travaglini@arm.com}
49513481Sgiacomo.travaglini@arm.com
49613481Sgiacomo.travaglini@arm.comTEST(IsAsciiPunctTest, IsFalseForNonPunct) {
49713481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiPunct('\0'));
49813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiPunct(' '));
49913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiPunct('\n'));
50013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiPunct('a'));
50113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiPunct('0'));
50213481Sgiacomo.travaglini@arm.com}
50313481Sgiacomo.travaglini@arm.com
50413481Sgiacomo.travaglini@arm.comTEST(IsAsciiPunctTest, IsTrueForPunct) {
50513481Sgiacomo.travaglini@arm.com  for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) {
50613481Sgiacomo.travaglini@arm.com    EXPECT_PRED1(IsAsciiPunct, *p);
50713481Sgiacomo.travaglini@arm.com  }
50813481Sgiacomo.travaglini@arm.com}
50913481Sgiacomo.travaglini@arm.com
51013481Sgiacomo.travaglini@arm.comTEST(IsRepeatTest, IsFalseForNonRepeatChar) {
51113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsRepeat('\0'));
51213481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsRepeat(' '));
51313481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsRepeat('a'));
51413481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsRepeat('1'));
51513481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsRepeat('-'));
51613481Sgiacomo.travaglini@arm.com}
51713481Sgiacomo.travaglini@arm.com
51813481Sgiacomo.travaglini@arm.comTEST(IsRepeatTest, IsTrueForRepeatChar) {
51913481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsRepeat('?'));
52013481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsRepeat('*'));
52113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsRepeat('+'));
52213481Sgiacomo.travaglini@arm.com}
52313481Sgiacomo.travaglini@arm.com
52413481Sgiacomo.travaglini@arm.comTEST(IsAsciiWhiteSpaceTest, IsFalseForNonWhiteSpace) {
52513481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiWhiteSpace('\0'));
52613481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiWhiteSpace('a'));
52713481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiWhiteSpace('1'));
52813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiWhiteSpace('+'));
52913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiWhiteSpace('_'));
53013481Sgiacomo.travaglini@arm.com}
53113481Sgiacomo.travaglini@arm.com
53213481Sgiacomo.travaglini@arm.comTEST(IsAsciiWhiteSpaceTest, IsTrueForWhiteSpace) {
53313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWhiteSpace(' '));
53413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWhiteSpace('\n'));
53513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWhiteSpace('\r'));
53613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWhiteSpace('\t'));
53713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWhiteSpace('\v'));
53813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWhiteSpace('\f'));
53913481Sgiacomo.travaglini@arm.com}
54013481Sgiacomo.travaglini@arm.com
54113481Sgiacomo.travaglini@arm.comTEST(IsAsciiWordCharTest, IsFalseForNonWordChar) {
54213481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiWordChar('\0'));
54313481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiWordChar('+'));
54413481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiWordChar('.'));
54513481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiWordChar(' '));
54613481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsAsciiWordChar('\n'));
54713481Sgiacomo.travaglini@arm.com}
54813481Sgiacomo.travaglini@arm.com
54913481Sgiacomo.travaglini@arm.comTEST(IsAsciiWordCharTest, IsTrueForLetter) {
55013481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWordChar('a'));
55113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWordChar('b'));
55213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWordChar('A'));
55313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWordChar('Z'));
55413481Sgiacomo.travaglini@arm.com}
55513481Sgiacomo.travaglini@arm.com
55613481Sgiacomo.travaglini@arm.comTEST(IsAsciiWordCharTest, IsTrueForDigit) {
55713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWordChar('0'));
55813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWordChar('1'));
55913481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWordChar('7'));
56013481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWordChar('9'));
56113481Sgiacomo.travaglini@arm.com}
56213481Sgiacomo.travaglini@arm.com
56313481Sgiacomo.travaglini@arm.comTEST(IsAsciiWordCharTest, IsTrueForUnderscore) {
56413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsAsciiWordChar('_'));
56513481Sgiacomo.travaglini@arm.com}
56613481Sgiacomo.travaglini@arm.com
56713481Sgiacomo.travaglini@arm.comTEST(IsValidEscapeTest, IsFalseForNonPrintable) {
56813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsValidEscape('\0'));
56913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsValidEscape('\007'));
57013481Sgiacomo.travaglini@arm.com}
57113481Sgiacomo.travaglini@arm.com
57213481Sgiacomo.travaglini@arm.comTEST(IsValidEscapeTest, IsFalseForDigit) {
57313481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsValidEscape('0'));
57413481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsValidEscape('9'));
57513481Sgiacomo.travaglini@arm.com}
57613481Sgiacomo.travaglini@arm.com
57713481Sgiacomo.travaglini@arm.comTEST(IsValidEscapeTest, IsFalseForWhiteSpace) {
57813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsValidEscape(' '));
57913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsValidEscape('\n'));
58013481Sgiacomo.travaglini@arm.com}
58113481Sgiacomo.travaglini@arm.com
58213481Sgiacomo.travaglini@arm.comTEST(IsValidEscapeTest, IsFalseForSomeLetter) {
58313481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsValidEscape('a'));
58413481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(IsValidEscape('Z'));
58513481Sgiacomo.travaglini@arm.com}
58613481Sgiacomo.travaglini@arm.com
58713481Sgiacomo.travaglini@arm.comTEST(IsValidEscapeTest, IsTrueForPunct) {
58813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('.'));
58913481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('-'));
59013481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('^'));
59113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('$'));
59213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('('));
59313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape(']'));
59413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('{'));
59513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('|'));
59613481Sgiacomo.travaglini@arm.com}
59713481Sgiacomo.travaglini@arm.com
59813481Sgiacomo.travaglini@arm.comTEST(IsValidEscapeTest, IsTrueForSomeLetter) {
59913481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('d'));
60013481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('D'));
60113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('s'));
60213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('S'));
60313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('w'));
60413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(IsValidEscape('W'));
60513481Sgiacomo.travaglini@arm.com}
60613481Sgiacomo.travaglini@arm.com
60713481Sgiacomo.travaglini@arm.comTEST(AtomMatchesCharTest, EscapedPunct) {
60813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, '\\', '\0'));
60913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, '\\', ' '));
61013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, '_', '.'));
61113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, '.', 'a'));
61213481Sgiacomo.travaglini@arm.com
61313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, '\\', '\\'));
61413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, '_', '_'));
61513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, '+', '+'));
61613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, '.', '.'));
61713481Sgiacomo.travaglini@arm.com}
61813481Sgiacomo.travaglini@arm.com
61913481Sgiacomo.travaglini@arm.comTEST(AtomMatchesCharTest, Escaped_d) {
62013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'd', '\0'));
62113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'd', 'a'));
62213481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'd', '.'));
62313481Sgiacomo.travaglini@arm.com
62413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'd', '0'));
62513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'd', '9'));
62613481Sgiacomo.travaglini@arm.com}
62713481Sgiacomo.travaglini@arm.com
62813481Sgiacomo.travaglini@arm.comTEST(AtomMatchesCharTest, Escaped_D) {
62913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'D', '0'));
63013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'D', '9'));
63113481Sgiacomo.travaglini@arm.com
63213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'D', '\0'));
63313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'D', 'a'));
63413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'D', '-'));
63513481Sgiacomo.travaglini@arm.com}
63613481Sgiacomo.travaglini@arm.com
63713481Sgiacomo.travaglini@arm.comTEST(AtomMatchesCharTest, Escaped_s) {
63813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 's', '\0'));
63913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 's', 'a'));
64013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 's', '.'));
64113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 's', '9'));
64213481Sgiacomo.travaglini@arm.com
64313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 's', ' '));
64413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 's', '\n'));
64513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 's', '\t'));
64613481Sgiacomo.travaglini@arm.com}
64713481Sgiacomo.travaglini@arm.com
64813481Sgiacomo.travaglini@arm.comTEST(AtomMatchesCharTest, Escaped_S) {
64913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'S', ' '));
65013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'S', '\r'));
65113481Sgiacomo.travaglini@arm.com
65213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'S', '\0'));
65313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'S', 'a'));
65413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'S', '9'));
65513481Sgiacomo.travaglini@arm.com}
65613481Sgiacomo.travaglini@arm.com
65713481Sgiacomo.travaglini@arm.comTEST(AtomMatchesCharTest, Escaped_w) {
65813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'w', '\0'));
65913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'w', '+'));
66013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'w', ' '));
66113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'w', '\n'));
66213481Sgiacomo.travaglini@arm.com
66313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'w', '0'));
66413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'w', 'b'));
66513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'w', 'C'));
66613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'w', '_'));
66713481Sgiacomo.travaglini@arm.com}
66813481Sgiacomo.travaglini@arm.com
66913481Sgiacomo.travaglini@arm.comTEST(AtomMatchesCharTest, Escaped_W) {
67013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'W', 'A'));
67113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'W', 'b'));
67213481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'W', '9'));
67313481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'W', '_'));
67413481Sgiacomo.travaglini@arm.com
67513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'W', '\0'));
67613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'W', '*'));
67713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'W', '\n'));
67813481Sgiacomo.travaglini@arm.com}
67913481Sgiacomo.travaglini@arm.com
68013481Sgiacomo.travaglini@arm.comTEST(AtomMatchesCharTest, EscapedWhiteSpace) {
68113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'f', '\0'));
68213481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'f', '\n'));
68313481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'n', '\0'));
68413481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'n', '\r'));
68513481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'r', '\0'));
68613481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'r', 'a'));
68713481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 't', '\0'));
68813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 't', 't'));
68913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'v', '\0'));
69013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(true, 'v', '\f'));
69113481Sgiacomo.travaglini@arm.com
69213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'f', '\f'));
69313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'n', '\n'));
69413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'r', '\r'));
69513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 't', '\t'));
69613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(true, 'v', '\v'));
69713481Sgiacomo.travaglini@arm.com}
69813481Sgiacomo.travaglini@arm.com
69913481Sgiacomo.travaglini@arm.comTEST(AtomMatchesCharTest, UnescapedDot) {
70013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(false, '.', '\n'));
70113481Sgiacomo.travaglini@arm.com
70213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(false, '.', '\0'));
70313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(false, '.', '.'));
70413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(false, '.', 'a'));
70513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(false, '.', ' '));
70613481Sgiacomo.travaglini@arm.com}
70713481Sgiacomo.travaglini@arm.com
70813481Sgiacomo.travaglini@arm.comTEST(AtomMatchesCharTest, UnescapedChar) {
70913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(false, 'a', '\0'));
71013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(false, 'a', 'b'));
71113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(AtomMatchesChar(false, '$', 'a'));
71213481Sgiacomo.travaglini@arm.com
71313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(false, '$', '$'));
71413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(false, '5', '5'));
71513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(AtomMatchesChar(false, 'Z', 'Z'));
71613481Sgiacomo.travaglini@arm.com}
71713481Sgiacomo.travaglini@arm.com
71813481Sgiacomo.travaglini@arm.comTEST(ValidateRegexTest, GeneratesFailureAndReturnsFalseForInvalid) {
71913481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(NULL)),
72013481Sgiacomo.travaglini@arm.com                          "NULL is not a valid simple regular expression");
72113481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(
72213481Sgiacomo.travaglini@arm.com      ASSERT_FALSE(ValidateRegex("a\\")),
72313481Sgiacomo.travaglini@arm.com      "Syntax error at index 1 in simple regular expression \"a\\\": ");
72413481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a\\")),
72513481Sgiacomo.travaglini@arm.com                          "'\\' cannot appear at the end");
72613481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\n\\")),
72713481Sgiacomo.travaglini@arm.com                          "'\\' cannot appear at the end");
72813481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\s\\hb")),
72913481Sgiacomo.travaglini@arm.com                          "invalid escape sequence \"\\h\"");
73013481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^^")),
73113481Sgiacomo.travaglini@arm.com                          "'^' can only appear at the beginning");
73213481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(".*^b")),
73313481Sgiacomo.travaglini@arm.com                          "'^' can only appear at the beginning");
73413481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("$$")),
73513481Sgiacomo.travaglini@arm.com                          "'$' can only appear at the end");
73613481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^$a")),
73713481Sgiacomo.travaglini@arm.com                          "'$' can only appear at the end");
73813481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a(b")),
73913481Sgiacomo.travaglini@arm.com                          "'(' is unsupported");
74013481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("ab)")),
74113481Sgiacomo.travaglini@arm.com                          "')' is unsupported");
74213481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("[ab")),
74313481Sgiacomo.travaglini@arm.com                          "'[' is unsupported");
74413481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a{2")),
74513481Sgiacomo.travaglini@arm.com                          "'{' is unsupported");
74613481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("?")),
74713481Sgiacomo.travaglini@arm.com                          "'?' can only follow a repeatable token");
74813481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^*")),
74913481Sgiacomo.travaglini@arm.com                          "'*' can only follow a repeatable token");
75013481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("5*+")),
75113481Sgiacomo.travaglini@arm.com                          "'+' can only follow a repeatable token");
75213481Sgiacomo.travaglini@arm.com}
75313481Sgiacomo.travaglini@arm.com
75413481Sgiacomo.travaglini@arm.comTEST(ValidateRegexTest, ReturnsTrueForValid) {
75513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(ValidateRegex(""));
75613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(ValidateRegex("a"));
75713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(ValidateRegex(".*"));
75813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(ValidateRegex("^a_+"));
75913481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(ValidateRegex("^a\\t\\&?"));
76013481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(ValidateRegex("09*$"));
76113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(ValidateRegex("^Z$"));
76213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(ValidateRegex("a\\^Z\\$\\(\\)\\|\\[\\]\\{\\}"));
76313481Sgiacomo.travaglini@arm.com}
76413481Sgiacomo.travaglini@arm.com
76513481Sgiacomo.travaglini@arm.comTEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrOne) {
76613481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "a", "ba"));
76713481Sgiacomo.travaglini@arm.com  // Repeating more than once.
76813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "aab"));
76913481Sgiacomo.travaglini@arm.com
77013481Sgiacomo.travaglini@arm.com  // Repeating zero times.
77113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ba"));
77213481Sgiacomo.travaglini@arm.com  // Repeating once.
77313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ab"));
77413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '#', '?', ".", "##"));
77513481Sgiacomo.travaglini@arm.com}
77613481Sgiacomo.travaglini@arm.com
77713481Sgiacomo.travaglini@arm.comTEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrMany) {
77813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '*', "a$", "baab"));
77913481Sgiacomo.travaglini@arm.com
78013481Sgiacomo.travaglini@arm.com  // Repeating zero times.
78113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "bc"));
78213481Sgiacomo.travaglini@arm.com  // Repeating once.
78313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "abc"));
78413481Sgiacomo.travaglini@arm.com  // Repeating more than once.
78513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '*', "-", "ab_1-g"));
78613481Sgiacomo.travaglini@arm.com}
78713481Sgiacomo.travaglini@arm.com
78813481Sgiacomo.travaglini@arm.comTEST(MatchRepetitionAndRegexAtHeadTest, WorksForOneOrMany) {
78913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "a$", "baab"));
79013481Sgiacomo.travaglini@arm.com  // Repeating zero times.
79113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "bc"));
79213481Sgiacomo.travaglini@arm.com
79313481Sgiacomo.travaglini@arm.com  // Repeating once.
79413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "abc"));
79513481Sgiacomo.travaglini@arm.com  // Repeating more than once.
79613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '+', "-", "ab_1-g"));
79713481Sgiacomo.travaglini@arm.com}
79813481Sgiacomo.travaglini@arm.com
79913481Sgiacomo.travaglini@arm.comTEST(MatchRegexAtHeadTest, ReturnsTrueForEmptyRegex) {
80013481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("", ""));
80113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("", "ab"));
80213481Sgiacomo.travaglini@arm.com}
80313481Sgiacomo.travaglini@arm.com
80413481Sgiacomo.travaglini@arm.comTEST(MatchRegexAtHeadTest, WorksWhenDollarIsInRegex) {
80513481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAtHead("$", "a"));
80613481Sgiacomo.travaglini@arm.com
80713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("$", ""));
80813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("a$", "a"));
80913481Sgiacomo.travaglini@arm.com}
81013481Sgiacomo.travaglini@arm.com
81113481Sgiacomo.travaglini@arm.comTEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithEscapeSequence) {
81213481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAtHead("\\w", "+"));
81313481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAtHead("\\W", "ab"));
81413481Sgiacomo.travaglini@arm.com
81513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("\\sa", "\nab"));
81613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("\\d", "1a"));
81713481Sgiacomo.travaglini@arm.com}
81813481Sgiacomo.travaglini@arm.com
81913481Sgiacomo.travaglini@arm.comTEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) {
82013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAtHead(".+a", "abc"));
82113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAtHead("a?b", "aab"));
82213481Sgiacomo.travaglini@arm.com
82313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead(".*a", "bc12-ab"));
82413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("a?b", "b"));
82513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("a?b", "ab"));
82613481Sgiacomo.travaglini@arm.com}
82713481Sgiacomo.travaglini@arm.com
82813481Sgiacomo.travaglini@arm.comTEST(MatchRegexAtHeadTest,
82913481Sgiacomo.travaglini@arm.com     WorksWhenRegexStartsWithRepetionOfEscapeSequence) {
83013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc"));
83113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAtHead("\\s?b", "  b"));
83213481Sgiacomo.travaglini@arm.com
83313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("\\(*a", "((((ab"));
83413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("\\^?b", "^b"));
83513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "b"));
83613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "\\b"));
83713481Sgiacomo.travaglini@arm.com}
83813481Sgiacomo.travaglini@arm.com
83913481Sgiacomo.travaglini@arm.comTEST(MatchRegexAtHeadTest, MatchesSequentially) {
84013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAtHead("ab.*c", "acabc"));
84113481Sgiacomo.travaglini@arm.com
84213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAtHead("ab.*c", "ab-fsc"));
84313481Sgiacomo.travaglini@arm.com}
84413481Sgiacomo.travaglini@arm.com
84513481Sgiacomo.travaglini@arm.comTEST(MatchRegexAnywhereTest, ReturnsFalseWhenStringIsNull) {
84613481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAnywhere("", NULL));
84713481Sgiacomo.travaglini@arm.com}
84813481Sgiacomo.travaglini@arm.com
84913481Sgiacomo.travaglini@arm.comTEST(MatchRegexAnywhereTest, WorksWhenRegexStartsWithCaret) {
85013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAnywhere("^a", "ba"));
85113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAnywhere("^$", "a"));
85213481Sgiacomo.travaglini@arm.com
85313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAnywhere("^a", "ab"));
85413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAnywhere("^", "ab"));
85513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAnywhere("^$", ""));
85613481Sgiacomo.travaglini@arm.com}
85713481Sgiacomo.travaglini@arm.com
85813481Sgiacomo.travaglini@arm.comTEST(MatchRegexAnywhereTest, ReturnsFalseWhenNoMatch) {
85913481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAnywhere("a", "bcde123"));
86013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(MatchRegexAnywhere("a.+a", "--aa88888888"));
86113481Sgiacomo.travaglini@arm.com}
86213481Sgiacomo.travaglini@arm.com
86313481Sgiacomo.travaglini@arm.comTEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingPrefix) {
86413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAnywhere("\\w+", "ab1_ - 5"));
86513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAnywhere(".*=", "="));
86613481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAnywhere("x.*ab?.*bc", "xaaabc"));
86713481Sgiacomo.travaglini@arm.com}
86813481Sgiacomo.travaglini@arm.com
86913481Sgiacomo.travaglini@arm.comTEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) {
87013481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAnywhere("\\w+", "$$$ ab1_ - 5"));
87113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(MatchRegexAnywhere("\\.+=", "=  ...="));
87213481Sgiacomo.travaglini@arm.com}
87313481Sgiacomo.travaglini@arm.com
87413481Sgiacomo.travaglini@arm.com// Tests RE's implicit constructors.
87513481Sgiacomo.travaglini@arm.comTEST(RETest, ImplicitConstructorWorks) {
87613481Sgiacomo.travaglini@arm.com  const RE empty("");
87713481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("", empty.pattern());
87813481Sgiacomo.travaglini@arm.com
87913481Sgiacomo.travaglini@arm.com  const RE simple("hello");
88013481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("hello", simple.pattern());
88113481Sgiacomo.travaglini@arm.com}
88213481Sgiacomo.travaglini@arm.com
88313481Sgiacomo.travaglini@arm.com// Tests that RE's constructors reject invalid regular expressions.
88413481Sgiacomo.travaglini@arm.comTEST(RETest, RejectsInvalidRegex) {
88513481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE({
88613481Sgiacomo.travaglini@arm.com    const RE normal(NULL);
88713481Sgiacomo.travaglini@arm.com  }, "NULL is not a valid simple regular expression");
88813481Sgiacomo.travaglini@arm.com
88913481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE({
89013481Sgiacomo.travaglini@arm.com    const RE normal(".*(\\w+");
89113481Sgiacomo.travaglini@arm.com  }, "'(' is unsupported");
89213481Sgiacomo.travaglini@arm.com
89313481Sgiacomo.travaglini@arm.com  EXPECT_NONFATAL_FAILURE({
89413481Sgiacomo.travaglini@arm.com    const RE invalid("^?");
89513481Sgiacomo.travaglini@arm.com  }, "'?' can only follow a repeatable token");
89613481Sgiacomo.travaglini@arm.com}
89713481Sgiacomo.travaglini@arm.com
89813481Sgiacomo.travaglini@arm.com// Tests RE::FullMatch().
89913481Sgiacomo.travaglini@arm.comTEST(RETest, FullMatchWorks) {
90013481Sgiacomo.travaglini@arm.com  const RE empty("");
90113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::FullMatch("", empty));
90213481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(RE::FullMatch("a", empty));
90313481Sgiacomo.travaglini@arm.com
90413481Sgiacomo.travaglini@arm.com  const RE re1("a");
90513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::FullMatch("a", re1));
90613481Sgiacomo.travaglini@arm.com
90713481Sgiacomo.travaglini@arm.com  const RE re("a.*z");
90813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::FullMatch("az", re));
90913481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::FullMatch("axyz", re));
91013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(RE::FullMatch("baz", re));
91113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(RE::FullMatch("azy", re));
91213481Sgiacomo.travaglini@arm.com}
91313481Sgiacomo.travaglini@arm.com
91413481Sgiacomo.travaglini@arm.com// Tests RE::PartialMatch().
91513481Sgiacomo.travaglini@arm.comTEST(RETest, PartialMatchWorks) {
91613481Sgiacomo.travaglini@arm.com  const RE empty("");
91713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::PartialMatch("", empty));
91813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::PartialMatch("a", empty));
91913481Sgiacomo.travaglini@arm.com
92013481Sgiacomo.travaglini@arm.com  const RE re("a.*z");
92113481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::PartialMatch("az", re));
92213481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::PartialMatch("axyz", re));
92313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::PartialMatch("baz", re));
92413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(RE::PartialMatch("azy", re));
92513481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(RE::PartialMatch("zza", re));
92613481Sgiacomo.travaglini@arm.com}
92713481Sgiacomo.travaglini@arm.com
92813481Sgiacomo.travaglini@arm.com#endif  // GTEST_USES_POSIX_RE
92913481Sgiacomo.travaglini@arm.com
93013481Sgiacomo.travaglini@arm.com#if !GTEST_OS_WINDOWS_MOBILE
93113481Sgiacomo.travaglini@arm.com
93213481Sgiacomo.travaglini@arm.comTEST(CaptureTest, CapturesStdout) {
93313481Sgiacomo.travaglini@arm.com  CaptureStdout();
93413481Sgiacomo.travaglini@arm.com  fprintf(stdout, "abc");
93513481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("abc", GetCapturedStdout().c_str());
93613481Sgiacomo.travaglini@arm.com
93713481Sgiacomo.travaglini@arm.com  CaptureStdout();
93813481Sgiacomo.travaglini@arm.com  fprintf(stdout, "def%cghi", '\0');
93913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(::std::string("def\0ghi", 7), ::std::string(GetCapturedStdout()));
94013481Sgiacomo.travaglini@arm.com}
94113481Sgiacomo.travaglini@arm.com
94213481Sgiacomo.travaglini@arm.comTEST(CaptureTest, CapturesStderr) {
94313481Sgiacomo.travaglini@arm.com  CaptureStderr();
94413481Sgiacomo.travaglini@arm.com  fprintf(stderr, "jkl");
94513481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("jkl", GetCapturedStderr().c_str());
94613481Sgiacomo.travaglini@arm.com
94713481Sgiacomo.travaglini@arm.com  CaptureStderr();
94813481Sgiacomo.travaglini@arm.com  fprintf(stderr, "jkl%cmno", '\0');
94913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(::std::string("jkl\0mno", 7), ::std::string(GetCapturedStderr()));
95013481Sgiacomo.travaglini@arm.com}
95113481Sgiacomo.travaglini@arm.com
95213481Sgiacomo.travaglini@arm.com// Tests that stdout and stderr capture don't interfere with each other.
95313481Sgiacomo.travaglini@arm.comTEST(CaptureTest, CapturesStdoutAndStderr) {
95413481Sgiacomo.travaglini@arm.com  CaptureStdout();
95513481Sgiacomo.travaglini@arm.com  CaptureStderr();
95613481Sgiacomo.travaglini@arm.com  fprintf(stdout, "pqr");
95713481Sgiacomo.travaglini@arm.com  fprintf(stderr, "stu");
95813481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("pqr", GetCapturedStdout().c_str());
95913481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("stu", GetCapturedStderr().c_str());
96013481Sgiacomo.travaglini@arm.com}
96113481Sgiacomo.travaglini@arm.com
96213481Sgiacomo.travaglini@arm.comTEST(CaptureDeathTest, CannotReenterStdoutCapture) {
96313481Sgiacomo.travaglini@arm.com  CaptureStdout();
96413481Sgiacomo.travaglini@arm.com  EXPECT_DEATH_IF_SUPPORTED(CaptureStdout(),
96513481Sgiacomo.travaglini@arm.com                            "Only one stdout capturer can exist at a time");
96613481Sgiacomo.travaglini@arm.com  GetCapturedStdout();
96713481Sgiacomo.travaglini@arm.com
96813481Sgiacomo.travaglini@arm.com  // We cannot test stderr capturing using death tests as they use it
96913481Sgiacomo.travaglini@arm.com  // themselves.
97013481Sgiacomo.travaglini@arm.com}
97113481Sgiacomo.travaglini@arm.com
97213481Sgiacomo.travaglini@arm.com#endif  // !GTEST_OS_WINDOWS_MOBILE
97313481Sgiacomo.travaglini@arm.com
97413481Sgiacomo.travaglini@arm.comTEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) {
97513481Sgiacomo.travaglini@arm.com  ThreadLocal<int> t1;
97613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(0, t1.get());
97713481Sgiacomo.travaglini@arm.com
97813481Sgiacomo.travaglini@arm.com  ThreadLocal<void*> t2;
97913481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(t2.get() == NULL);
98013481Sgiacomo.travaglini@arm.com}
98113481Sgiacomo.travaglini@arm.com
98213481Sgiacomo.travaglini@arm.comTEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) {
98313481Sgiacomo.travaglini@arm.com  ThreadLocal<int> t1(123);
98413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(123, t1.get());
98513481Sgiacomo.travaglini@arm.com
98613481Sgiacomo.travaglini@arm.com  int i = 0;
98713481Sgiacomo.travaglini@arm.com  ThreadLocal<int*> t2(&i);
98813481Sgiacomo.travaglini@arm.com  EXPECT_EQ(&i, t2.get());
98913481Sgiacomo.travaglini@arm.com}
99013481Sgiacomo.travaglini@arm.com
99113481Sgiacomo.travaglini@arm.comclass NoDefaultContructor {
99213481Sgiacomo.travaglini@arm.com public:
99313481Sgiacomo.travaglini@arm.com  explicit NoDefaultContructor(const char*) {}
99413481Sgiacomo.travaglini@arm.com  NoDefaultContructor(const NoDefaultContructor&) {}
99513481Sgiacomo.travaglini@arm.com};
99613481Sgiacomo.travaglini@arm.com
99713481Sgiacomo.travaglini@arm.comTEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) {
99813481Sgiacomo.travaglini@arm.com  ThreadLocal<NoDefaultContructor> bar(NoDefaultContructor("foo"));
99913481Sgiacomo.travaglini@arm.com  bar.pointer();
100013481Sgiacomo.travaglini@arm.com}
100113481Sgiacomo.travaglini@arm.com
100213481Sgiacomo.travaglini@arm.comTEST(ThreadLocalTest, GetAndPointerReturnSameValue) {
100313481Sgiacomo.travaglini@arm.com  ThreadLocal<std::string> thread_local_string;
100413481Sgiacomo.travaglini@arm.com
100513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get()));
100613481Sgiacomo.travaglini@arm.com
100713481Sgiacomo.travaglini@arm.com  // Verifies the condition still holds after calling set.
100813481Sgiacomo.travaglini@arm.com  thread_local_string.set("foo");
100913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get()));
101013481Sgiacomo.travaglini@arm.com}
101113481Sgiacomo.travaglini@arm.com
101213481Sgiacomo.travaglini@arm.comTEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) {
101313481Sgiacomo.travaglini@arm.com  ThreadLocal<std::string> thread_local_string;
101413481Sgiacomo.travaglini@arm.com  const ThreadLocal<std::string>& const_thread_local_string =
101513481Sgiacomo.travaglini@arm.com      thread_local_string;
101613481Sgiacomo.travaglini@arm.com
101713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer());
101813481Sgiacomo.travaglini@arm.com
101913481Sgiacomo.travaglini@arm.com  thread_local_string.set("foo");
102013481Sgiacomo.travaglini@arm.com  EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer());
102113481Sgiacomo.travaglini@arm.com}
102213481Sgiacomo.travaglini@arm.com
102313481Sgiacomo.travaglini@arm.com#if GTEST_IS_THREADSAFE
102413481Sgiacomo.travaglini@arm.com
102513481Sgiacomo.travaglini@arm.comvoid AddTwo(int* param) { *param += 2; }
102613481Sgiacomo.travaglini@arm.com
102713481Sgiacomo.travaglini@arm.comTEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) {
102813481Sgiacomo.travaglini@arm.com  int i = 40;
102913481Sgiacomo.travaglini@arm.com  ThreadWithParam<int*> thread(&AddTwo, &i, NULL);
103013481Sgiacomo.travaglini@arm.com  thread.Join();
103113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(42, i);
103213481Sgiacomo.travaglini@arm.com}
103313481Sgiacomo.travaglini@arm.com
103413481Sgiacomo.travaglini@arm.comTEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) {
103513481Sgiacomo.travaglini@arm.com  // AssertHeld() is flaky only in the presence of multiple threads accessing
103613481Sgiacomo.travaglini@arm.com  // the lock. In this case, the test is robust.
103713481Sgiacomo.travaglini@arm.com  EXPECT_DEATH_IF_SUPPORTED({
103813481Sgiacomo.travaglini@arm.com    Mutex m;
103913481Sgiacomo.travaglini@arm.com    { MutexLock lock(&m); }
104013481Sgiacomo.travaglini@arm.com    m.AssertHeld();
104113481Sgiacomo.travaglini@arm.com  },
104213481Sgiacomo.travaglini@arm.com  "thread .*hold");
104313481Sgiacomo.travaglini@arm.com}
104413481Sgiacomo.travaglini@arm.com
104513481Sgiacomo.travaglini@arm.comTEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) {
104613481Sgiacomo.travaglini@arm.com  Mutex m;
104713481Sgiacomo.travaglini@arm.com  MutexLock lock(&m);
104813481Sgiacomo.travaglini@arm.com  m.AssertHeld();
104913481Sgiacomo.travaglini@arm.com}
105013481Sgiacomo.travaglini@arm.com
105113481Sgiacomo.travaglini@arm.comclass AtomicCounterWithMutex {
105213481Sgiacomo.travaglini@arm.com public:
105313481Sgiacomo.travaglini@arm.com  explicit AtomicCounterWithMutex(Mutex* mutex) :
105413481Sgiacomo.travaglini@arm.com    value_(0), mutex_(mutex), random_(42) {}
105513481Sgiacomo.travaglini@arm.com
105613481Sgiacomo.travaglini@arm.com  void Increment() {
105713481Sgiacomo.travaglini@arm.com    MutexLock lock(mutex_);
105813481Sgiacomo.travaglini@arm.com    int temp = value_;
105913481Sgiacomo.travaglini@arm.com    {
106013481Sgiacomo.travaglini@arm.com      // We need to put up a memory barrier to prevent reads and writes to
106113481Sgiacomo.travaglini@arm.com      // value_ rearranged with the call to SleepMilliseconds when observed
106213481Sgiacomo.travaglini@arm.com      // from other threads.
106313481Sgiacomo.travaglini@arm.com#if GTEST_HAS_PTHREAD
106413481Sgiacomo.travaglini@arm.com      // On POSIX, locking a mutex puts up a memory barrier.  We cannot use
106513481Sgiacomo.travaglini@arm.com      // Mutex and MutexLock here or rely on their memory barrier
106613481Sgiacomo.travaglini@arm.com      // functionality as we are testing them here.
106713481Sgiacomo.travaglini@arm.com      pthread_mutex_t memory_barrier_mutex;
106813481Sgiacomo.travaglini@arm.com      GTEST_CHECK_POSIX_SUCCESS_(
106913481Sgiacomo.travaglini@arm.com          pthread_mutex_init(&memory_barrier_mutex, NULL));
107013481Sgiacomo.travaglini@arm.com      GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex));
107113481Sgiacomo.travaglini@arm.com
107213481Sgiacomo.travaglini@arm.com      SleepMilliseconds(random_.Generate(30));
107313481Sgiacomo.travaglini@arm.com
107413481Sgiacomo.travaglini@arm.com      GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex));
107513481Sgiacomo.travaglini@arm.com      GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex));
107613481Sgiacomo.travaglini@arm.com#elif GTEST_OS_WINDOWS
107713481Sgiacomo.travaglini@arm.com      // On Windows, performing an interlocked access puts up a memory barrier.
107813481Sgiacomo.travaglini@arm.com      volatile LONG dummy = 0;
107913481Sgiacomo.travaglini@arm.com      ::InterlockedIncrement(&dummy);
108013481Sgiacomo.travaglini@arm.com      SleepMilliseconds(random_.Generate(30));
108113481Sgiacomo.travaglini@arm.com      ::InterlockedIncrement(&dummy);
108213481Sgiacomo.travaglini@arm.com#else
108313481Sgiacomo.travaglini@arm.com# error "Memory barrier not implemented on this platform."
108413481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_PTHREAD
108513481Sgiacomo.travaglini@arm.com    }
108613481Sgiacomo.travaglini@arm.com    value_ = temp + 1;
108713481Sgiacomo.travaglini@arm.com  }
108813481Sgiacomo.travaglini@arm.com  int value() const { return value_; }
108913481Sgiacomo.travaglini@arm.com
109013481Sgiacomo.travaglini@arm.com private:
109113481Sgiacomo.travaglini@arm.com  volatile int value_;
109213481Sgiacomo.travaglini@arm.com  Mutex* const mutex_;  // Protects value_.
109313481Sgiacomo.travaglini@arm.com  Random       random_;
109413481Sgiacomo.travaglini@arm.com};
109513481Sgiacomo.travaglini@arm.com
109613481Sgiacomo.travaglini@arm.comvoid CountingThreadFunc(pair<AtomicCounterWithMutex*, int> param) {
109713481Sgiacomo.travaglini@arm.com  for (int i = 0; i < param.second; ++i)
109813481Sgiacomo.travaglini@arm.com      param.first->Increment();
109913481Sgiacomo.travaglini@arm.com}
110013481Sgiacomo.travaglini@arm.com
110113481Sgiacomo.travaglini@arm.com// Tests that the mutex only lets one thread at a time to lock it.
110213481Sgiacomo.travaglini@arm.comTEST(MutexTest, OnlyOneThreadCanLockAtATime) {
110313481Sgiacomo.travaglini@arm.com  Mutex mutex;
110413481Sgiacomo.travaglini@arm.com  AtomicCounterWithMutex locked_counter(&mutex);
110513481Sgiacomo.travaglini@arm.com
110613481Sgiacomo.travaglini@arm.com  typedef ThreadWithParam<pair<AtomicCounterWithMutex*, int> > ThreadType;
110713481Sgiacomo.travaglini@arm.com  const int kCycleCount = 20;
110813481Sgiacomo.travaglini@arm.com  const int kThreadCount = 7;
110913481Sgiacomo.travaglini@arm.com  scoped_ptr<ThreadType> counting_threads[kThreadCount];
111013481Sgiacomo.travaglini@arm.com  Notification threads_can_start;
111113481Sgiacomo.travaglini@arm.com  // Creates and runs kThreadCount threads that increment locked_counter
111213481Sgiacomo.travaglini@arm.com  // kCycleCount times each.
111313481Sgiacomo.travaglini@arm.com  for (int i = 0; i < kThreadCount; ++i) {
111413481Sgiacomo.travaglini@arm.com    counting_threads[i].reset(new ThreadType(&CountingThreadFunc,
111513481Sgiacomo.travaglini@arm.com                                             make_pair(&locked_counter,
111613481Sgiacomo.travaglini@arm.com                                                       kCycleCount),
111713481Sgiacomo.travaglini@arm.com                                             &threads_can_start));
111813481Sgiacomo.travaglini@arm.com  }
111913481Sgiacomo.travaglini@arm.com  threads_can_start.Notify();
112013481Sgiacomo.travaglini@arm.com  for (int i = 0; i < kThreadCount; ++i)
112113481Sgiacomo.travaglini@arm.com    counting_threads[i]->Join();
112213481Sgiacomo.travaglini@arm.com
112313481Sgiacomo.travaglini@arm.com  // If the mutex lets more than one thread to increment the counter at a
112413481Sgiacomo.travaglini@arm.com  // time, they are likely to encounter a race condition and have some
112513481Sgiacomo.travaglini@arm.com  // increments overwritten, resulting in the lower then expected counter
112613481Sgiacomo.travaglini@arm.com  // value.
112713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value());
112813481Sgiacomo.travaglini@arm.com}
112913481Sgiacomo.travaglini@arm.com
113013481Sgiacomo.travaglini@arm.comtemplate <typename T>
113113481Sgiacomo.travaglini@arm.comvoid RunFromThread(void (func)(T), T param) {
113213481Sgiacomo.travaglini@arm.com  ThreadWithParam<T> thread(func, param, NULL);
113313481Sgiacomo.travaglini@arm.com  thread.Join();
113413481Sgiacomo.travaglini@arm.com}
113513481Sgiacomo.travaglini@arm.com
113613481Sgiacomo.travaglini@arm.comvoid RetrieveThreadLocalValue(
113713481Sgiacomo.travaglini@arm.com    pair<ThreadLocal<std::string>*, std::string*> param) {
113813481Sgiacomo.travaglini@arm.com  *param.second = param.first->get();
113913481Sgiacomo.travaglini@arm.com}
114013481Sgiacomo.travaglini@arm.com
114113481Sgiacomo.travaglini@arm.comTEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) {
114213481Sgiacomo.travaglini@arm.com  ThreadLocal<std::string> thread_local_string("foo");
114313481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("foo", thread_local_string.get().c_str());
114413481Sgiacomo.travaglini@arm.com
114513481Sgiacomo.travaglini@arm.com  thread_local_string.set("bar");
114613481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("bar", thread_local_string.get().c_str());
114713481Sgiacomo.travaglini@arm.com
114813481Sgiacomo.travaglini@arm.com  std::string result;
114913481Sgiacomo.travaglini@arm.com  RunFromThread(&RetrieveThreadLocalValue,
115013481Sgiacomo.travaglini@arm.com                make_pair(&thread_local_string, &result));
115113481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("foo", result.c_str());
115213481Sgiacomo.travaglini@arm.com}
115313481Sgiacomo.travaglini@arm.com
115413481Sgiacomo.travaglini@arm.com// Keeps track of whether of destructors being called on instances of
115513481Sgiacomo.travaglini@arm.com// DestructorTracker.  On Windows, waits for the destructor call reports.
115613481Sgiacomo.travaglini@arm.comclass DestructorCall {
115713481Sgiacomo.travaglini@arm.com public:
115813481Sgiacomo.travaglini@arm.com  DestructorCall() {
115913481Sgiacomo.travaglini@arm.com    invoked_ = false;
116013481Sgiacomo.travaglini@arm.com#if GTEST_OS_WINDOWS
116113481Sgiacomo.travaglini@arm.com    wait_event_.Reset(::CreateEvent(NULL, TRUE, FALSE, NULL));
116213481Sgiacomo.travaglini@arm.com    GTEST_CHECK_(wait_event_.Get() != NULL);
116313481Sgiacomo.travaglini@arm.com#endif
116413481Sgiacomo.travaglini@arm.com  }
116513481Sgiacomo.travaglini@arm.com
116613481Sgiacomo.travaglini@arm.com  bool CheckDestroyed() const {
116713481Sgiacomo.travaglini@arm.com#if GTEST_OS_WINDOWS
116813481Sgiacomo.travaglini@arm.com    if (::WaitForSingleObject(wait_event_.Get(), 1000) != WAIT_OBJECT_0)
116913481Sgiacomo.travaglini@arm.com      return false;
117013481Sgiacomo.travaglini@arm.com#endif
117113481Sgiacomo.travaglini@arm.com    return invoked_;
117213481Sgiacomo.travaglini@arm.com  }
117313481Sgiacomo.travaglini@arm.com
117413481Sgiacomo.travaglini@arm.com  void ReportDestroyed() {
117513481Sgiacomo.travaglini@arm.com    invoked_ = true;
117613481Sgiacomo.travaglini@arm.com#if GTEST_OS_WINDOWS
117713481Sgiacomo.travaglini@arm.com    ::SetEvent(wait_event_.Get());
117813481Sgiacomo.travaglini@arm.com#endif
117913481Sgiacomo.travaglini@arm.com  }
118013481Sgiacomo.travaglini@arm.com
118113481Sgiacomo.travaglini@arm.com  static std::vector<DestructorCall*>& List() { return *list_; }
118213481Sgiacomo.travaglini@arm.com
118313481Sgiacomo.travaglini@arm.com  static void ResetList() {
118413481Sgiacomo.travaglini@arm.com    for (size_t i = 0; i < list_->size(); ++i) {
118513481Sgiacomo.travaglini@arm.com      delete list_->at(i);
118613481Sgiacomo.travaglini@arm.com    }
118713481Sgiacomo.travaglini@arm.com    list_->clear();
118813481Sgiacomo.travaglini@arm.com  }
118913481Sgiacomo.travaglini@arm.com
119013481Sgiacomo.travaglini@arm.com private:
119113481Sgiacomo.travaglini@arm.com  bool invoked_;
119213481Sgiacomo.travaglini@arm.com#if GTEST_OS_WINDOWS
119313481Sgiacomo.travaglini@arm.com  AutoHandle wait_event_;
119413481Sgiacomo.travaglini@arm.com#endif
119513481Sgiacomo.travaglini@arm.com  static std::vector<DestructorCall*>* const list_;
119613481Sgiacomo.travaglini@arm.com
119713481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_COPY_AND_ASSIGN_(DestructorCall);
119813481Sgiacomo.travaglini@arm.com};
119913481Sgiacomo.travaglini@arm.com
120013481Sgiacomo.travaglini@arm.comstd::vector<DestructorCall*>* const DestructorCall::list_ =
120113481Sgiacomo.travaglini@arm.com    new std::vector<DestructorCall*>;
120213481Sgiacomo.travaglini@arm.com
120313481Sgiacomo.travaglini@arm.com// DestructorTracker keeps track of whether its instances have been
120413481Sgiacomo.travaglini@arm.com// destroyed.
120513481Sgiacomo.travaglini@arm.comclass DestructorTracker {
120613481Sgiacomo.travaglini@arm.com public:
120713481Sgiacomo.travaglini@arm.com  DestructorTracker() : index_(GetNewIndex()) {}
120813481Sgiacomo.travaglini@arm.com  DestructorTracker(const DestructorTracker& /* rhs */)
120913481Sgiacomo.travaglini@arm.com      : index_(GetNewIndex()) {}
121013481Sgiacomo.travaglini@arm.com  ~DestructorTracker() {
121113481Sgiacomo.travaglini@arm.com    // We never access DestructorCall::List() concurrently, so we don't need
121213481Sgiacomo.travaglini@arm.com    // to protect this acccess with a mutex.
121313481Sgiacomo.travaglini@arm.com    DestructorCall::List()[index_]->ReportDestroyed();
121413481Sgiacomo.travaglini@arm.com  }
121513481Sgiacomo.travaglini@arm.com
121613481Sgiacomo.travaglini@arm.com private:
121713481Sgiacomo.travaglini@arm.com  static size_t GetNewIndex() {
121813481Sgiacomo.travaglini@arm.com    DestructorCall::List().push_back(new DestructorCall);
121913481Sgiacomo.travaglini@arm.com    return DestructorCall::List().size() - 1;
122013481Sgiacomo.travaglini@arm.com  }
122113481Sgiacomo.travaglini@arm.com  const size_t index_;
122213481Sgiacomo.travaglini@arm.com
122313481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(DestructorTracker);
122413481Sgiacomo.travaglini@arm.com};
122513481Sgiacomo.travaglini@arm.com
122613481Sgiacomo.travaglini@arm.comtypedef ThreadLocal<DestructorTracker>* ThreadParam;
122713481Sgiacomo.travaglini@arm.com
122813481Sgiacomo.travaglini@arm.comvoid CallThreadLocalGet(ThreadParam thread_local_param) {
122913481Sgiacomo.travaglini@arm.com  thread_local_param->get();
123013481Sgiacomo.travaglini@arm.com}
123113481Sgiacomo.travaglini@arm.com
123213481Sgiacomo.travaglini@arm.com// Tests that when a ThreadLocal object dies in a thread, it destroys
123313481Sgiacomo.travaglini@arm.com// the managed object for that thread.
123413481Sgiacomo.travaglini@arm.comTEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) {
123513481Sgiacomo.travaglini@arm.com  DestructorCall::ResetList();
123613481Sgiacomo.travaglini@arm.com
123713481Sgiacomo.travaglini@arm.com  {
123813481Sgiacomo.travaglini@arm.com    ThreadLocal<DestructorTracker> thread_local_tracker;
123913481Sgiacomo.travaglini@arm.com    ASSERT_EQ(0U, DestructorCall::List().size());
124013481Sgiacomo.travaglini@arm.com
124113481Sgiacomo.travaglini@arm.com    // This creates another DestructorTracker object for the main thread.
124213481Sgiacomo.travaglini@arm.com    thread_local_tracker.get();
124313481Sgiacomo.travaglini@arm.com    ASSERT_EQ(1U, DestructorCall::List().size());
124413481Sgiacomo.travaglini@arm.com    ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed());
124513481Sgiacomo.travaglini@arm.com  }
124613481Sgiacomo.travaglini@arm.com
124713481Sgiacomo.travaglini@arm.com  // Now thread_local_tracker has died.
124813481Sgiacomo.travaglini@arm.com  ASSERT_EQ(1U, DestructorCall::List().size());
124913481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed());
125013481Sgiacomo.travaglini@arm.com
125113481Sgiacomo.travaglini@arm.com  DestructorCall::ResetList();
125213481Sgiacomo.travaglini@arm.com}
125313481Sgiacomo.travaglini@arm.com
125413481Sgiacomo.travaglini@arm.com// Tests that when a thread exits, the thread-local object for that
125513481Sgiacomo.travaglini@arm.com// thread is destroyed.
125613481Sgiacomo.travaglini@arm.comTEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) {
125713481Sgiacomo.travaglini@arm.com  DestructorCall::ResetList();
125813481Sgiacomo.travaglini@arm.com
125913481Sgiacomo.travaglini@arm.com  {
126013481Sgiacomo.travaglini@arm.com    ThreadLocal<DestructorTracker> thread_local_tracker;
126113481Sgiacomo.travaglini@arm.com    ASSERT_EQ(0U, DestructorCall::List().size());
126213481Sgiacomo.travaglini@arm.com
126313481Sgiacomo.travaglini@arm.com    // This creates another DestructorTracker object in the new thread.
126413481Sgiacomo.travaglini@arm.com    ThreadWithParam<ThreadParam> thread(
126513481Sgiacomo.travaglini@arm.com        &CallThreadLocalGet, &thread_local_tracker, NULL);
126613481Sgiacomo.travaglini@arm.com    thread.Join();
126713481Sgiacomo.travaglini@arm.com
126813481Sgiacomo.travaglini@arm.com    // The thread has exited, and we should have a DestroyedTracker
126913481Sgiacomo.travaglini@arm.com    // instance created for it. But it may not have been destroyed yet.
127013481Sgiacomo.travaglini@arm.com    ASSERT_EQ(1U, DestructorCall::List().size());
127113481Sgiacomo.travaglini@arm.com  }
127213481Sgiacomo.travaglini@arm.com
127313481Sgiacomo.travaglini@arm.com  // The thread has exited and thread_local_tracker has died.
127413481Sgiacomo.travaglini@arm.com  ASSERT_EQ(1U, DestructorCall::List().size());
127513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed());
127613481Sgiacomo.travaglini@arm.com
127713481Sgiacomo.travaglini@arm.com  DestructorCall::ResetList();
127813481Sgiacomo.travaglini@arm.com}
127913481Sgiacomo.travaglini@arm.com
128013481Sgiacomo.travaglini@arm.comTEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) {
128113481Sgiacomo.travaglini@arm.com  ThreadLocal<std::string> thread_local_string;
128213481Sgiacomo.travaglini@arm.com  thread_local_string.set("Foo");
128313481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("Foo", thread_local_string.get().c_str());
128413481Sgiacomo.travaglini@arm.com
128513481Sgiacomo.travaglini@arm.com  std::string result;
128613481Sgiacomo.travaglini@arm.com  RunFromThread(&RetrieveThreadLocalValue,
128713481Sgiacomo.travaglini@arm.com                make_pair(&thread_local_string, &result));
128813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(result.empty());
128913481Sgiacomo.travaglini@arm.com}
129013481Sgiacomo.travaglini@arm.com
129113481Sgiacomo.travaglini@arm.com#endif  // GTEST_IS_THREADSAFE
129213481Sgiacomo.travaglini@arm.com
129313481Sgiacomo.travaglini@arm.com#if GTEST_OS_WINDOWS
129413481Sgiacomo.travaglini@arm.comTEST(WindowsTypesTest, HANDLEIsVoidStar) {
129513481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<HANDLE, void*>();
129613481Sgiacomo.travaglini@arm.com}
129713481Sgiacomo.travaglini@arm.com
129813481Sgiacomo.travaglini@arm.comTEST(WindowsTypesTest, CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION) {
129913481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<CRITICAL_SECTION, _RTL_CRITICAL_SECTION>();
130013481Sgiacomo.travaglini@arm.com}
130113481Sgiacomo.travaglini@arm.com#endif  // GTEST_OS_WINDOWS
130213481Sgiacomo.travaglini@arm.com
130313481Sgiacomo.travaglini@arm.com}  // namespace internal
130413481Sgiacomo.travaglini@arm.com}  // namespace testing
1305