text:
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Google Mock - a framework for writing C++ mock classes.
//
// This file tests some commonly used argument matchers.

// Silence warning C4244: 'initializing': conversion from 'int' to 'short',
// possible loss of data and C4100, unreferenced local parameter
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4244)
#pragma warning(disable : 4100)
#endif

#include "test/gmock-matchers_test.h"

namespace testing {
namespace gmock_matchers_test {
namespace {

TEST(MonotonicMatcherTest, IsPrintable) {
  stringstream ss;
  ss << GreaterThan(5);
  EXPECT_EQ("is > 5", ss.str());
}

TEST(MatchResultListenerTest, StreamingWorks) {
  StringMatchResultListener listener;
  listener << "hi" << 5;
  EXPECT_EQ("hi5", listener.str());

  listener.Clear();
  EXPECT_EQ("", listener.str());

  listener << 42;
  EXPECT_EQ("42", listener.str());

  // Streaming shouldn't crash when the underlying ostream is NULL.
  DummyMatchResultListener dummy;
  dummy << "hi" << 5;
}

TEST(MatchResultListenerTest, CanAccessUnderlyingStream) {
  EXPECT_TRUE(DummyMatchResultListener().stream() == nullptr);
  EXPECT_TRUE(StreamMatchResultListener(nullptr).stream() == nullptr);

  EXPECT_EQ(&std::cout, StreamMatchResultListener(&std::cout).stream());
}

TEST(MatchResultListenerTest, IsInterestedWorks) {
  EXPECT_TRUE(StringMatchResultListener().IsInterested());
  EXPECT_TRUE(StreamMatchResultListener(&std::cout).IsInterested());

  EXPECT_FALSE(DummyMatchResultListener().IsInterested());
  EXPECT_FALSE(StreamMatchResultListener(nullptr).IsInterested());
}

// Makes sure that the MatcherInterface<T> interface doesn't
// change.
class EvenMatcherImpl : public MatcherInterface<int> {
 public:
  bool MatchAndExplain(int x,
                       MatchResultListener* /* listener */) const override {
    return x % 2 == 0;
  }

  void DescribeTo(ostream* os) const override { *os << "is an even number"; }

  // We deliberately don't define DescribeNegationTo() and
  // ExplainMatchResultTo() here, to make sure the definition of these
  // two methods is optional.
};

// Makes sure that the MatcherInterface API doesn't change.
TEST(MatcherInterfaceTest, CanBeImplementedUsingPublishedAPI) {
  EvenMatcherImpl m;
}

// Tests implementing a monomorphic matcher using MatchAndExplain().

class NewEvenMatcherImpl : public MatcherInterface<int> {
 public:
  bool MatchAndExplain(int x, MatchResultListener* listener) const override {
    const bool match = x % 2 == 0;
    // Verifies that we can stream to a listener directly.
    *listener << "value % " << 2;
    if (listener->stream() != nullptr) {
      // Verifies that we can stream to a listener's underlying stream
      // too.
      *listener->stream() << " == " << (x % 2);
    }
    return match;
  }

  void DescribeTo(ostream* os) const override { *os << "is an even number"; }
};

TEST(MatcherInterfaceTest, CanBeImplementedUsingNewAPI) {
  Matcher<int> m = MakeMatcher(new NewEvenMatcherImpl);
  EXPECT_TRUE(m.Matches(2));
  EXPECT_FALSE(m.Matches(3));
  EXPECT_EQ("value % 2 == 0", Explain(m, 2));
  EXPECT_EQ("value % 2 == 1", Explain(m, 3));
}

// Tests default-constructing a matcher.
TEST(MatcherTest, CanBeDefaultConstructed) { Matcher<double> m; }

// Tests that Matcher<T> can be constructed from a MatcherInterface<T>*.
TEST(MatcherTest, CanBeConstructedFromMatcherInterface) {
  const MatcherInterface<int>* impl = new EvenMatcherImpl;
  Matcher<int> m(impl);
  EXPECT_TRUE(m.Matches(4));
  EXPECT_FALSE(m.Matches(5));
}

// Tests that value can be used in place of Eq(value).
TEST(MatcherTest, CanBeImplicitlyConstructedFromValue) {
  Matcher<int> m1 = 5;
  EXPECT_TRUE(m1.Matches(5));
  EXPECT_FALSE(m1.Matches(6));
}

// Tests that NULL can be used in place of Eq(NULL).
TEST(MatcherTest, CanBeImplicitlyConstructedFromNULL) {
  Matcher<int*> m1 = nullptr;
  EXPECT_TRUE(m1.Matches(nullptr));
  int n = 0;
  EXPECT_FALSE(m1.Matches(&n));
}

// Tests that matchers can be constructed from a variable that is not properly
// defined. This should be illegal, but many users rely on this accidentally.
struct Undefined {
  virtual ~Undefined() = 0;
  static const int kInt = 1;
};

TEST(MatcherTest, CanBeConstructedFromUndefinedVariable) {
  Matcher<int> m1 = Undefined::kInt;
  EXPECT_TRUE(m1.Matches(1));
  EXPECT_FALSE(m1.Matches(2));
}

// Test that a matcher parameterized with an abstract class compiles.
TEST(MatcherTest, CanAcceptAbstractClass) { Matcher<const Undefined&> m = _; }

// Tests that matchers are copyable.
TEST(MatcherTest, IsCopyable) {
  // Tests the copy constructor.
  Matcher<bool> m1 = Eq(false);
  EXPECT_TRUE(m1.Matches(false));
  EXPECT_FALSE(m1.Matches(true));

  // Tests the assignment operator.
  m1 = Eq(true);
  EXPECT_TRUE(m1.Matches(true));
  EXPECT_FALSE(m1.Matches(false));
}

// Tests that Matcher<T>::DescribeTo() calls
// MatcherInterface<T>::DescribeTo().
TEST(MatcherTest, CanDescribeItself) {
  EXPECT_EQ("is an even number", Describe(Matcher<int>(new EvenMatcherImpl)));
}

// Tests Matcher<T>::MatchAndExplain().
TEST(MatcherTest, MatchAndExplain) {
  Matcher<int> m = GreaterThan(0);
  StringMatchResultListener listener1;
  EXPECT_TRUE(m.MatchAndExplain(42, &listener1));
  EXPECT_EQ("which is 42 more than 0", listener1.str());

  StringMatchResultListener listener2;
  EXPECT_FALSE(m.MatchAndExplain(-9, &listener2));
  EXPECT_EQ("which is 9 less than 0", listener2.str());
}

// Tests that a C-string literal can be implicitly converted to a
// Matcher<std::string> or Matcher<const std::string&>.
TEST(StringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) {
  Matcher<std::string> m1 = "hi";
  EXPECT_TRUE(m1.Matches("hi"));
  EXPECT_FALSE(m1.Matches("hello"));

  Matcher<const std::string&> m2 = "hi";
  EXPECT_TRUE(m2.Matches("hi"));
  EXPECT_FALSE(m2.Matches("hello"));
}

// Tests that a string object can be implicitly converted to a
// Matcher<std::string> or Matcher<const std::string&>.
TEST(StringMatcherTest, CanBeImplicitlyConstructedFromString) {
  Matcher<std::string> m1 = std::string("hi");
  EXPECT_TRUE(m1.Matches("hi"));
  EXPECT_FALSE(m1.Matches("hello"));

  Matcher<const std::string&> m2 = std::string("hi");
  EXPECT_TRUE(m2.Matches("hi"));
  EXPECT_FALSE(m2.Matches("hello"));
}

#if GTEST_INTERNAL_HAS_STRING_VIEW
// Tests that a C-string literal can be implicitly converted to a
// Matcher<StringView> or Matcher<const StringView&>.
TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) {
  Matcher<internal::StringView> m1 = "cats";
  EXPECT_TRUE(m1.Matches("cats"));
  EXPECT_FALSE(m1.Matches("dogs"));

  Matcher<const internal::StringView&> m2 = "cats";
  EXPECT_TRUE(m2.Matches("cats"));
  EXPECT_FALSE(m2.Matches("dogs"));
}

// Tests that a std::string object can be implicitly converted to a
// Matcher<StringView> or Matcher<const StringView&>.
TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromString) {
  Matcher<internal::StringView> m1 = std::string("cats");
  EXPECT_TRUE(m1.Matches("cats"));
  EXPECT_FALSE(m1.Matches("dogs"));

  Matcher<const internal::StringView&> m2 = std::string("cats");
  EXPECT_TRUE(m2.Matches("cats"));
  EXPECT_FALSE(m2.Matches("dogs"));
}

// Tests that a StringView object can be implicitly converted to a
// Matcher<StringView> or Matcher<const StringView&>.
TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromStringView) {
  Matcher<internal::StringView> m1 = internal::StringView("cats");
  EXPECT_TRUE(m1.Matches("cats"));
  EXPECT_FALSE(m1.Matches("dogs"));

  Matcher<const internal::StringView&> m2 = internal::StringView("cats");
  EXPECT_TRUE(m2.Matches("cats"));
  EXPECT_FALSE(m2.Matches("dogs"));
}
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW

// Tests that a std::reference_wrapper<std::string> object can be implicitly
// converted to a Matcher<std::string> or Matcher<const std::string&> via Eq().
TEST(StringMatcherTest,
     CanBeImplicitlyConstructedFromEqReferenceWrapperString) {
  std::string value = "cats";
  Matcher<std::string> m1 = Eq(std::ref(value));
  EXPECT_TRUE(m1.Matches("cats"));
  EXPECT_FALSE(m1.Matches("dogs"));

  Matcher<const std::string&> m2 = Eq(std::ref(value));
  EXPECT_TRUE(m2.Matches("cats"));
  EXPECT_FALSE(m2.Matches("dogs"));
}

// Tests that MakeMatcher() constructs a Matcher<T> from a
// MatcherInterface* without requiring the user to explicitly
// write the type.
TEST(MakeMatcherTest, ConstructsMatcherFromMatcherInterface) {
  const MatcherInterface<int>* dummy_impl = new EvenMatcherImpl;
  Matcher<int> m = MakeMatcher(dummy_impl);
}

// Tests that MakePolymorphicMatcher() can construct a polymorphic
// matcher from its implementation using the old API.
const int g_bar = 1;
class ReferencesBarOrIsZeroImpl {
 public:
  template <typename T>
  bool MatchAndExplain(const T& x, MatchResultListener* /* listener */) const {
    const void* p = &x;
    return p == &g_bar || x == 0;
  }

  void DescribeTo(ostream* os) const { *os << "g_bar or zero"; }

  void DescribeNegationTo(ostream* os) const {
    *os << "doesn't reference g_bar and is not zero";
  }
};

// This function verifies that MakePolymorphicMatcher() returns a
// PolymorphicMatcher<T> where T is the argument's type.
PolymorphicMatcher<ReferencesBarOrIsZeroImpl> ReferencesBarOrIsZero() {
  return MakePolymorphicMatcher(ReferencesBarOrIsZeroImpl());
}

TEST(MakePolymorphicMatcherTest, ConstructsMatcherUsingOldAPI) {
  // Using a polymorphic matcher to match a reference type.
  Matcher<const int&> m1 = ReferencesBarOrIsZero();
  EXPECT_TRUE(m1.Matches(0));
  // Verifies that the identity of a by-reference argument is preserved.
  EXPECT_TRUE(m1.Matches(g_bar));
  EXPECT_FALSE(m1.Matches(1));
  EXPECT_EQ("g_bar or zero", Describe(m1));

  // Using a polymorphic matcher to match a value type.
  Matcher<double> m2 = ReferencesBarOrIsZero();
  EXPECT_TRUE(m2.Matches(0.0));
  EXPECT_FALSE(m2.Matches(0.1));
  EXPECT_EQ("g_bar or zero", Describe(m2));
}

// Tests implementing a polymorphic matcher using MatchAndExplain().

class PolymorphicIsEvenImpl {
 public:
  void DescribeTo(ostream* os) const { *os << "is even"; }

  void DescribeNegationTo(ostream* os) const { *os << "is odd"; }

  template <typename T>
  bool MatchAndExplain(const T& x, MatchResultListener* listener) const {
    // Verifies that we can stream to the listener directly.
    *listener << "% " << 2;
    if (listener->stream() != nullptr) {
      // Verifies that we can stream to the listener's underlying stream
      // too.
      *listener->stream() << " == " << (x % 2);
    }
    return (x % 2) == 0;
  }
};

PolymorphicMatcher<PolymorphicIsEvenImpl> PolymorphicIsEven() {
  return MakePolymorphicMatcher(PolymorphicIsEvenImpl());
}

TEST(MakePolymorphicMatcherTest, ConstructsMatcherUsingNewAPI) {
  // Using PolymorphicIsEven() as a Matcher<int>.
  const Matcher<int> m1 = PolymorphicIsEven();
  EXPECT_TRUE(m1.Matches(42));
  EXPECT_FALSE(m1.Matches(43));
  EXPECT_EQ("is even", Describe(m1));

  const Matcher<int> not_m1 = Not(m1);
  EXPECT_EQ("is odd", Describe(not_m1));

  EXPECT_EQ("% 2 == 0", Explain(m1, 42));

  // Using PolymorphicIsEven() as a Matcher<char>.
  const Matcher<char> m2 = PolymorphicIsEven();
  EXPECT_TRUE(m2.Matches('\x42'));
  EXPECT_FALSE(m2.Matches('\x43'));
  EXPECT_EQ("is even", Describe(m2));

  const Matcher<char> not_m2 = Not(m2);
  EXPECT_EQ("is odd", Describe(not_m2));

  EXPECT_EQ("% 2 == 0", Explain(m2, '\x42'));
}

// Tests that MatcherCast<T>(m) works when m is a polymorphic matcher.
TEST(MatcherCastTest, FromPolymorphicMatcher) {
  Matcher<int> m = MatcherCast<int>(Eq(5));
  EXPECT_TRUE(m.Matches(5));
  EXPECT_FALSE(m.Matches(6));
}

// For testing casting matchers between compatible types.
class IntValue {
 public:
  // An int can be statically (although not implicitly) cast to a
  // IntValue.
  explicit IntValue(int a_value) : value_(a_value) {}

  int value() const { return value_; }

 private:
  int value_;
};

// For testing casting matchers between compatible types.
bool IsPositiveIntValue(const IntValue& foo) { return foo.value() > 0; }

// Tests that MatcherCast<T>(m) works when m is a Matcher<U> where T
// can be statically converted to U.
TEST(MatcherCastTest, FromCompatibleType) {
  Matcher<double> m1 = Eq(2.0);
  Matcher<int> m2 = MatcherCast<int>(m1);
  EXPECT_TRUE(m2.Matches(2));
  EXPECT_FALSE(m2.Matches(3));

  Matcher<IntValue> m3 = Truly(IsPositiveIntValue);
  Matcher<int> m4 = MatcherCast<int>(m3);
  // In the following, the arguments 1 and 0 are statically converted
  // to IntValue objects, and then tested by the IsPositiveIntValue()
  // predicate.
  EXPECT_TRUE(m4.Matches(1));
  EXPECT_FALSE(m4.Matches(0));
}

// Tests that MatcherCast<T>(m) works when m is a Matcher<const T&>.
TEST(MatcherCastTest, FromConstReferenceToNonReference) {
  Matcher<const int&> m1 = Eq(0);
  Matcher<int> m2 = MatcherCast<int>(m1);
  EXPECT_TRUE(m2.Matches(0));
  EXPECT_FALSE(m2.Matches(1));
}

// Tests that MatcherCast<T>(m) works when m is a Matcher<T&>.
TEST(MatcherCastTest, FromReferenceToNonReference) {
  Matcher<int&> m1 = Eq(0);
  Matcher<int> m2 = MatcherCast<int>(m1);
  EXPECT_TRUE(m2.Matches(0));
  EXPECT_FALSE(m2.Matches(1));
}

// Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>.
TEST(MatcherCastTest, FromNonReferenceToConstReference) {
  Matcher<int> m1 = Eq(0);
  Matcher<const int&> m2 = MatcherCast<const int&>(m1);
  EXPECT_TRUE(m2.Matches(0));
  EXPECT_FALSE(m2.Matches(1));
}

// Tests that MatcherCast<T&>(m) works when m is a Matcher<T>.
TEST(MatcherCastTest, FromNonReferenceToReference) {
  Matcher<int> m1 = Eq(0);
  Matcher<int&> m2 = MatcherCast<int&>(m1);
  int n = 0;
  EXPECT_TRUE(m2.Matches(n));
  n = 1;
  EXPECT_FALSE(m2.Matches(n));
}

// Tests that MatcherCast<T>(m) works when m is a Matcher<T>.
TEST(MatcherCastTest, FromSameType) {
  Matcher<int> m1 = Eq(0);
  Matcher<int> m2 = MatcherCast<int>(m1);
  EXPECT_TRUE(m2.Matches(0));
  EXPECT_FALSE(m2.Matches(1));
}

// Tests that MatcherCast<T>(m) works when m is a value of the same type as the
// value type of the Matcher.
TEST(MatcherCastTest, FromAValue) {
  Matcher<int> m = MatcherCast<int>(42);
  EXPECT_TRUE(m.Matches(42));
  EXPECT_FALSE(m.Matches(239));
}

// Tests that MatcherCast<T>(m) works when m is a value of the type implicitly
// convertible to the value type of the Matcher.
TEST(MatcherCastTest, FromAnImplicitlyConvertibleValue) {
  const int kExpected = 'c';
  Matcher<int> m = MatcherCast<int>('c');
  EXPECT_TRUE(m.Matches(kExpected));
  EXPECT_FALSE(m.Matches(kExpected + 1));
}

struct NonImplicitlyConstructibleTypeWithOperatorEq {
  friend bool operator==(
      const NonImplicitlyConstructibleTypeWithOperatorEq& /* ignored */,
      int rhs) {
    return 42 == rhs;
  }
  friend bool operator==(
      int lhs,
      const NonImplicitlyConstructibleTypeWithOperatorEq& /* ignored */) {
    return lhs == 42;
  }
};

// Tests that MatcherCast<T>(m) works when m is a neither a matcher nor
// implicitly convertible to the value type of the Matcher, but the value type
// of the matcher has operator==() overload accepting m.
TEST(MatcherCastTest, NonImplicitlyConstructibleTypeWithOperatorEq) {
  Matcher<NonImplicitlyConstructibleTypeWithOperatorEq> m1 =
      MatcherCast<NonImplicitlyConstructibleTypeWithOperatorEq>(42);
  EXPECT_TRUE(m1.Matches(NonImplicitlyConstructibleTypeWithOperatorEq()));

  Matcher<NonImplicitlyConstructibleTypeWithOperatorEq> m2 =
      MatcherCast<NonImplicitlyConstructibleTypeWithOperatorEq>(239);
  EXPECT_FALSE(m2.Matches(NonImplicitlyConstructibleTypeWithOperatorEq()));

  // When updating the following lines please also change the comment to
  // namespace convertible_from_any.
  Matcher<int> m3 =
      MatcherCast<int>(NonImplicitlyConstructibleTypeWithOperatorEq());
  EXPECT_TRUE(m3.Matches(42));
  EXPECT_FALSE(m3.Matches(239));
}

// ConvertibleFromAny does not work with MSVC. resulting in
// error C2440: 'initializing': cannot convert from 'Eq' to 'M'
// No constructor could take the source type, or constructor overload
// resolution was ambiguous

#if !defined _MSC_VER

// The below ConvertibleFromAny struct is implicitly constructible from anything
// and when in the same namespace can interact with other tests. In particular,
// if it is in the same namespace as other tests and one removes
//   NonImplicitlyConstructibleTypeWithOperatorEq::operator==(int lhs, ...);
// then the corresponding test still compiles (and it should not!) by implicitly
// converting NonImplicitlyConstructibleTypeWithOperatorEq to ConvertibleFromAny
// in m3.Matcher().
namespace convertible_from_any {
// Implicitly convertible from any type.
struct ConvertibleFromAny {
  ConvertibleFromAny(int a_value) : value(a_value) {}
  template <typename T>
  ConvertibleFromAny(const T& /*a_value*/) : value(-1) {
    ADD_FAILURE() << "Conversion constructor called";
  }
  int value;
};

bool operator==(const ConvertibleFromAny& a, const ConvertibleFromAny& b) {
  return a.value == b.value;
}

ostream& operator<<(ostream& os, const ConvertibleFromAny& a) {
  return os << a.value;
}

TEST(MatcherCastTest, ConversionConstructorIsUsed) {
  Matcher<ConvertibleFromAny> m = MatcherCast<ConvertibleFromAny>(1);
  EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
  EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}

TEST(MatcherCastTest, FromConvertibleFromAny) {
  Matcher<ConvertibleFromAny> m =
      MatcherCast<ConvertibleFromAny>(Eq(ConvertibleFromAny(1)));
  EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
  EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
}  // namespace convertible_from_any

#endif  // !defined _MSC_VER

struct IntReferenceWrapper {
  IntReferenceWrapper(const int& a_value) : value(&a_value) {}
  const int* value;
};

bool operator==(const IntReferenceWrapper& a, const IntReferenceWrapper& b) {
  return a.value == b.value;
}

TEST(MatcherCastTest, ValueIsNotCopied) {
  int n = 42;
  Matcher<IntReferenceWrapper> m = MatcherCast<IntReferenceWrapper>(n);
  // Verify that the matcher holds a reference to n, not to its temporary copy.
  EXPECT_TRUE(m.Matches(n));
}

class Base {
 public:
  virtual ~Base() {}
  Base() {}

 private:
  Base(const Base&) = delete;
  Base& operator=(const Base&) = delete;
};

class Derived : public Base {
 public:
  Derived() : Base() {}
  int i;
};

class OtherDerived : public Base {};

// Tests that SafeMatcherCast<T>(m) works when m is a polymorphic matcher.
TEST(SafeMatcherCastTest, FromPolymorphicMatcher) {
  Matcher<char> m2 = SafeMatcherCast<char>(Eq(32));
  EXPECT_TRUE(m2.Matches(' '));
  EXPECT_FALSE(m2.Matches('\n'));
}

// Tests that SafeMatcherCast<T>(m) works when m is a Matcher<U> where
// T and U are arithmetic types and T can be losslessly converted to
// U.
TEST(SafeMatcherCastTest, FromLosslesslyConvertibleArithmeticType) {
  Matcher<double> m1 = DoubleEq(1.0);
  Matcher<float> m2 = SafeMatcherCast<float>(m1);
  EXPECT_TRUE(m2.Matches(1.0f));
  EXPECT_FALSE(m2.Matches(2.0f));

  Matcher<char> m3 = SafeMatcherCast<char>(TypedEq<int>('a'));
  EXPECT_TRUE(m3.Matches('a'));
  EXPECT_FALSE(m3.Matches('b'));
}

// Tests that SafeMatcherCast<T>(m) works when m is a Matcher<U> where T and U
// are pointers or references to a derived and a base class, correspondingly.
TEST(SafeMatcherCastTest, FromBaseClass) {
  Derived d, d2;
  Matcher<Base*> m1 = Eq(&d);
  Matcher<Derived*> m2 = SafeMatcherCast<Derived*>(m1);
  EXPECT_TRUE(m2.Matches(&d));
  EXPECT_FALSE(m2.Matches(&d2));

  Matcher<Base&> m3 = Ref(d);
  Matcher<Derived&> m4 = SafeMatcherCast<Derived&>(m3);
  EXPECT_TRUE(m4.Matches(d));
  EXPECT_FALSE(m4.Matches(d2));
}

// Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<const T&>.
TEST(SafeMatcherCastTest, FromConstReferenceToReference) {
  int n = 0;
  Matcher<const int&> m1 = Ref(n);
  Matcher<int&> m2 = SafeMatcherCast<int&>(m1);
  int n1 = 0;
  EXPECT_TRUE(m2.Matches(n));
  EXPECT_FALSE(m2.Matches(n1));
}

// Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>.
TEST(SafeMatcherCastTest, FromNonReferenceToConstReference) {
  Matcher<std::unique_ptr<int>> m1 = IsNull();
  Matcher<const std::unique_ptr<int>&> m2 =
      SafeMatcherCast<const std::unique_ptr<int>&>(m1);
  EXPECT_TRUE(m2.Matches(std::unique_ptr<int>()));
  EXPECT_FALSE(m2.Matches(std::unique_ptr<int>(new int)));
}

// Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<T>.
TEST(SafeMatcherCastTest, FromNonReferenceToReference) {
  Matcher<int> m1 = Eq(0);
  Matcher<int&> m2 = SafeMatcherCast<int&>(m1);
  int n = 0;
  EXPECT_TRUE(m2.Matches(n));
  n = 1;
  EXPECT_FALSE(m2.Matches(n));
}

// Tests that SafeMatcherCast<T>(m) works when m is a Matcher<T>.
TEST(SafeMatcherCastTest, FromSameType) {
  Matcher<int> m1 = Eq(0);
  Matcher<int> m2 = SafeMatcherCast<int>(m1);
  EXPECT_TRUE(m2.Matches(0));
  EXPECT_FALSE(m2.Matches(1));
}

#if !defined _MSC_VER

namespace convertible_from_any {
TEST(SafeMatcherCastTest, ConversionConstructorIsUsed) {
  Matcher<ConvertibleFromAny> m = SafeMatcherCast<ConvertibleFromAny>(1);
  EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
  EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}

TEST(SafeMatcherCastTest, FromConvertibleFromAny) {
  Matcher<ConvertibleFromAny> m =
      SafeMatcherCast<ConvertibleFromAny>(Eq(ConvertibleFromAny(1)));
  EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
  EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
}  // namespace convertible_from_any

#endif  // !defined _MSC_VER

TEST(SafeMatcherCastTest, ValueIsNotCopied) {
  int n = 42;
  Matcher<IntReferenceWrapper> m = SafeMatcherCast<IntReferenceWrapper>(n);
  // Verify that the matcher holds a reference to n, not to its temporary copy.
  EXPECT_TRUE(m.Matches(n));
}

TEST(ExpectThat, TakesLiterals) {
  EXPECT_THAT(1, 1);
  EXPECT_THAT(1.0, 1.0);
  EXPECT_THAT(std::string(), "");
}

TEST(ExpectThat, TakesFunctions) {
  struct Helper {
    static void Func() {}
  };
  void (*func)() = Helper::Func;
  EXPECT_THAT(func, Helper::Func);
  EXPECT_THAT(func, &Helper::Func);
}

// Tests that A<T>() matches any value of type T.
TEST(ATest, MatchesAnyValue) {
  // Tests a matcher for a value type.
  Matcher<double> m1 = A<double>();
  EXPECT_TRUE(m1.Matches(91.43));
  EXPECT_TRUE(m1.Matches(-15.32));

  // Tests a matcher for a reference type.
  int a = 2;
  int b = -6;
  Matcher<int&> m2 = A<int&>();
  EXPECT_TRUE(m2.Matches(a));
  EXPECT_TRUE(m2.Matches(b));
}

TEST(ATest, WorksForDerivedClass) {
  Base base;
  Derived derived;
  EXPECT_THAT(&base, A<Base*>());
  // This shouldn't compile: EXPECT_THAT(&base, A<Derived*>());
  EXPECT_THAT(&derived, A<Base*>());
  EXPECT_THAT(&derived, A<Derived*>());
}

// Tests that A<T>() describes itself properly.
TEST(ATest, CanDescribeSelf) { EXPECT_EQ("is anything", Describe(A<bool>())); }

// Tests that An<T>() matches any value of type T.
TEST(AnTest, MatchesAnyValue) {
  // Tests a matcher for a value type.
  Matcher<int> m1 = An<int>();
  EXPECT_TRUE(m1.Matches(9143));
  EXPECT_TRUE(m1.Matches(-1532));

  // Tests a matcher for a reference type.
  int a = 2;
  int b = -6;
  Matcher<int&> m2 = An<int&>();
  EXPECT_TRUE(m2.Matches(a));
  EXPECT_TRUE(m2.Matches(b));
}

// Tests that An<T>() describes itself properly.
TEST(AnTest, CanDescribeSelf) { EXPECT_EQ("is anything", Describe(An<int>())); }

// Tests that _ can be used as a matcher for any type and matches any
// value of that type.
TEST(UnderscoreTest, MatchesAnyValue) {
  // Uses _ as a matcher for a value type.
  Matcher<int> m1 = _;
  EXPECT_TRUE(m1.Matches(123));
  EXPECT_TRUE(m1.Matches(-242));

  // Uses _ as a matcher for a reference type.
  bool a = false;
  const bool b = true;
  Matcher<const bool&> m2 = _;
  EXPECT_TRUE(m2.Matches(a));
  EXPECT_TRUE(m2.Matches(b));
}

// Tests that _ describes itself properly.
TEST(UnderscoreTest, CanDescribeSelf) {
  Matcher<int> m = _;
  EXPECT_EQ("is anything", Describe(m));
}

// Tests that Eq(x) matches any value equal to x.
TEST(EqTest, MatchesEqualValue) {
  // 2 C-strings with same content but different addresses.
  const char a1[] = "hi";
  const char a2[] = "hi";

  Matcher<const char*> m1 = Eq(a1);
  EXPECT_TRUE(m1.Matches(a1));
  EXPECT_FALSE(m1.Matches(a2));
}

// Tests that Eq(v) describes itself properly.

class Unprintable {
 public:
  Unprintable() : c_('a') {}

  bool operator==(const Unprintable& /* rhs */) const { return true; }
  // -Wunused-private-field: dummy accessor for `c_`.
  char dummy_c() { return c_; }

 private:
  char c_;
};

TEST(EqTest, CanDescribeSelf) {
  Matcher<Unprintable> m = Eq(Unprintable());
  EXPECT_EQ("is equal to 1-byte object <61>", Describe(m));
}

// Tests that Eq(v) can be used to match any type that supports
// comparing with type T, where T is v's type.
TEST(EqTest, IsPolymorphic) {
  Matcher<int> m1 = Eq(1);
  EXPECT_TRUE(m1.Matches(1));
  EXPECT_FALSE(m1.Matches(2));

  Matcher<char> m2 = Eq(1);
  EXPECT_TRUE(m2.Matches('\1'));
  EXPECT_FALSE(m2.Matches('a'));
}

// Tests that TypedEq<T>(v) matches values of type T that's equal to v.
TEST(TypedEqTest, ChecksEqualityForGivenType) {
  Matcher<char> m1 = TypedEq<char>('a');
  EXPECT_TRUE(m1.Matches('a'));
  EXPECT_FALSE(m1.Matches('b'));

  Matcher<int> m2 = TypedEq<int>(6);
  EXPECT_TRUE(m2.Matches(6));
  EXPECT_FALSE(m2.Matches(7));
}

// Tests that TypedEq(v) describes itself properly.
TEST(TypedEqTest, CanDescribeSelf) {
  EXPECT_EQ("is equal to 2", Describe(TypedEq<int>(2)));
}

// Tests that TypedEq<T>(v) has type Matcher<T>.

// Type<T>::IsTypeOf(v) compiles if and only if the type of value v is T, where
// T is a "bare" type (i.e. not in the form of const U or U&).  If v's type is
// not T, the compiler will generate a message about "undefined reference".
template <typename T>
struct Type {
  static bool IsTypeOf(const T& /* v */) { return true; }

  template <typename T2>
  static void IsTypeOf(T2 v);
};

TEST(TypedEqTest, HasSpecifiedType) {
  // Verfies that the type of TypedEq<T>(v) is Matcher<T>.
  Type<Matcher<int>>::IsTypeOf(TypedEq<int>(5));
  Type<Matcher<double>>::IsTypeOf(TypedEq<double>(5));
}

// Tests that Ge(v) matches anything >= v.
TEST(GeTest, ImplementsGreaterThanOrEqual) {
  Matcher<int> m1 = Ge(0);
  EXPECT_TRUE(m1.Matches(1));
  EXPECT_TRUE(m1.Matches(0));
  EXPECT_FALSE(m1.Matches(-1));
}

// Tests that Ge(v) describes itself properly.
TEST(GeTest, CanDescribeSelf) {
  Matcher<int> m = Ge(5);
  EXPECT_EQ("is >= 5", Describe(m));
}

// Tests that Gt(v) matches anything > v.
TEST(GtTest, ImplementsGreaterThan) {
  Matcher<double> m1 = Gt(0);
  EXPECT_TRUE(m1.Matches(1.0));
  EXPECT_FALSE(m1.Matches(0.0));
  EXPECT_FALSE(m1.Matches(-1.0));
}

// Tests that Gt(v) describes itself properly.
TEST(GtTest, CanDescribeSelf) {
  Matcher<int> m = Gt(5);
  EXPECT_EQ("is > 5", Describe(m));
}

// Tests that Le(v) matches anything <= v.
TEST(LeTest, ImplementsLessThanOrEqual) {
  Matcher<char> m1 = Le('b');
  EXPECT_TRUE(m1.Matches('a'));
  EXPECT_TRUE(m1.Matches('b'));
  EXPECT_FALSE(m1.Matches('c'));
}

// Tests that Le(v) describes itself properly.
TEST(LeTest, CanDescribeSelf) {
  Matcher<int> m = Le(5);
  EXPECT_EQ("is <= 5", Describe(m));
}

// Tests that Lt(v) matches anything < v.
TEST(LtTest, ImplementsLessThan) {
  Matcher<const std::string&> m1 = Lt("Hello");
  EXPECT_TRUE(m1.Matches("Abc"));
  EXPECT_FALSE(m1.Matches("Hello"));
  EXPECT_FALSE(m1.Matches("Hello, world!"));
}

// Tests that Lt(v) describes itself properly.
TEST(LtTest, CanDescribeSelf) {
  Matcher<int> m = Lt(5);
  EXPECT_EQ("is < 5", Describe(m));
}

// Tests that Ne(v) matches anything != v.
TEST(NeTest, ImplementsNotEqual) {
  Matcher<int> m1 = Ne(0);
  EXPECT_TRUE(m1.Matches(1));
  EXPECT_TRUE(m1.Matches(-1));
  EXPECT_FALSE(m1.Matches(0));
}

// Tests that Ne(v) describes itself properly.
TEST(NeTest, CanDescribeSelf) {
  Matcher<int> m = Ne(5);
  EXPECT_EQ("isn't equal to 5", Describe(m));
}

class MoveOnly {
 public:
  explicit MoveOnly(int i) : i_(i) {}
  MoveOnly(const MoveOnly&) = delete;
  MoveOnly(MoveOnly&&) = default;
  MoveOnly& operator=(const MoveOnly&) = delete;
  MoveOnly& operator=(MoveOnly&&) = default;

  bool operator==(const MoveOnly& other) const { return i_ == other.i_; }
  bool operator!=(const MoveOnly& other) const { return i_ != other.i_; }
  bool operator<(const MoveOnly& other) const { return i_ < other.i_; }
  bool operator<=(const MoveOnly& other) const { return i_ <= other.i_; }
  bool operator>(const MoveOnly& other) const { return i_ > other.i_; }
  bool operator>=(const MoveOnly& other) const { return i_ >= other.i_; }

 private:
  int i_;
};

struct MoveHelper {
  MOCK_METHOD1(Call, void(MoveOnly));
};

// Disable this test in VS 2015 (version 14), where it fails when SEH is enabled
#if defined(_MSC_VER) && (_MSC_VER < 1910)
TEST(ComparisonBaseTest, DISABLED_WorksWithMoveOnly) {
#else
TEST(ComparisonBaseTest, WorksWithMoveOnly) {
#endif
  MoveOnly m{0};
  MoveHelper helper;

  EXPECT_CALL(helper, Call(Eq(ByRef(m))));
  helper.Call(MoveOnly(0));
  EXPECT_CALL(helper, Call(Ne(ByRef(m))));
  helper.Call(MoveOnly(1));
  EXPECT_CALL(helper, Call(Le(ByRef(m))));
  helper.Call(MoveOnly(0));
  EXPECT_CALL(helper, Call(Lt(ByRef(m))));
  helper.Call(MoveOnly(-1));
  EXPECT_CALL(helper, Call(Ge(ByRef(m))));
  helper.Call(MoveOnly(0));
  EXPECT_CALL(helper, Call(Gt(ByRef(m))));
  helper.Call(MoveOnly(1));
}

// Tests that IsNull() matches any NULL pointer of any type.
TEST(IsNullTest, MatchesNullPointer) {
  Matcher<int*> m1 = IsNull();
  int* p1 = nullptr;
  int n = 0;
  EXPECT_TRUE(m1.Matches(p1));
  EXPECT_FALSE(m1.Matches(&n));

  Matcher<const char*> m2 = IsNull();
  const char* p2 = nullptr;
  EXPECT_TRUE(m2.Matches(p2));
  EXPECT_FALSE(m2.Matches("hi"));

  Matcher<void*> m3 = IsNull();
  void* p3 = nullptr;
  EXPECT_TRUE(m3.Matches(p3));
  EXPECT_FALSE(m3.Matches(reinterpret_cast<void*>(0xbeef)));
}

TEST(IsNullTest, StdFunction) {
  const Matcher<std::function<void()>> m = IsNull();

  EXPECT_TRUE(m.Matches(std::function<void()>()));
  EXPECT_FALSE(m.Matches([] {}));
}

// Tests that IsNull() describes itself properly.
TEST(IsNullTest, CanDescribeSelf) {
  Matcher<int*> m = IsNull();
  EXPECT_EQ("is NULL", Describe(m));
  EXPECT_EQ("isn't NULL", DescribeNegation(m));
}

// Tests that NotNull() matches any non-NULL pointer of any type.
TEST(NotNullTest, MatchesNonNullPointer) {
  Matcher<int*> m1 = NotNull();
  int* p1 = nullptr;
  int n = 0;
  EXPECT_FALSE(m1.Matches(p1));
  EXPECT_TRUE(m1.Matches(&n));

  Matcher<const char*> m2 = NotNull();
  const char* p2 = nullptr;
  EXPECT_FALSE(m2.Matches(p2));
  EXPECT_TRUE(m2.Matches("hi"));
}

TEST(NotNullTest, LinkedPtr) {
  const Matcher<std::shared_ptr<int>> m = NotNull();
  const std::shared_ptr<int> null_p;
  const std::shared_ptr<int> non_null_p(new int);

  EXPECT_FALSE(m.Matches(null_p));
  EXPECT_TRUE(m.Matches(non_null_p));
}

TEST(NotNullTest, ReferenceToConstLinkedPtr) {
  const Matcher<const std::shared_ptr<double>&> m = NotNull();
  const std::shared_ptr<double> null_p;
  const std::shared_ptr<double> non_null_p(new double);

  EXPECT_FALSE(m.Matches(null_p));
  EXPECT_TRUE(m.Matches(non_null_p));
}

TEST(NotNullTest, StdFunction) {
  const Matcher<std::function<void()>> m = NotNull();

  EXPECT_TRUE(m.Matches([] {}));
  EXPECT_FALSE(m.Matches(std::function<void()>()));
}

// Tests that NotNull() describes itself properly.
TEST(NotNullTest, CanDescribeSelf) {
  Matcher<int*> m = NotNull();
  EXPECT_EQ("isn't NULL", Describe(m));
}

// Tests that Ref(variable) matches an argument that references
// 'variable'.
TEST(RefTest, MatchesSameVariable) {
  int a = 0;
  int b = 0;
  Matcher<int&> m = Ref(a);
  EXPECT_TRUE(m.Matches(a));
  EXPECT_FALSE(m.Matches(b));
}

// Tests that Ref(variable) describes itself properly.
TEST(RefTest, CanDescribeSelf) {
  int n = 5;
  Matcher<int&> m = Ref(n);
  stringstream ss;
  ss << "references the variable @" << &n << " 5";
  EXPECT_EQ(ss.str(), Describe(m));
}

// Test that Ref(non_const_varialbe) can be used as a matcher for a
// const reference.
TEST(RefTest, CanBeUsedAsMatcherForConstReference) {
  int a = 0;
  int b = 0;
  Matcher<const int&> m = Ref(a);
  EXPECT_TRUE(m.Matches(a));
  EXPECT_FALSE(m.Matches(b));
}

// Tests that Ref(variable) is covariant, i.e. Ref(derived) can be
// used wherever Ref(base) can be used (Ref(derived) is a sub-type
// of Ref(base), but not vice versa.

TEST(RefTest, IsCovariant) {
  Base base, base2;
  Derived derived;
  Matcher<const Base&> m1 = Ref(base);
  EXPECT_TRUE(m1.Matches(base));
  EXPECT_FALSE(m1.Matches(base2));
  EXPECT_FALSE(m1.Matches(derived));

  m1 = Ref(derived);
  EXPECT_TRUE(m1.Matches(derived));
  EXPECT_FALSE(m1.Matches(base));
  EXPECT_FALSE(m1.Matches(base2));
}

TEST(RefTest, ExplainsResult) {
  int n = 0;
  EXPECT_THAT(Explain(Matcher<const int&>(Ref(n)), n),
              StartsWith("which is located @"));

  int m = 0;
  EXPECT_THAT(Explain(Matcher<const int&>(Ref(n)), m),
              StartsWith("which is located @"));
}

// Tests string comparison matchers.

template <typename T = std::string>
std::string FromStringLike(internal::StringLike<T> str) {
  return std::string(str);
}

TEST(StringLike, TestConversions) {
  EXPECT_EQ("foo", FromStringLike("foo"));
  EXPECT_EQ("foo", FromStringLike(std::string("foo")));
#if GTEST_INTERNAL_HAS_STRING_VIEW
  EXPECT_EQ("foo", FromStringLike(internal::StringView("foo")));
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW

  // Non deducible types.
  EXPECT_EQ("", FromStringLike({}));
  EXPECT_EQ("foo", FromStringLike({'f', 'o', 'o'}));
  const char buf[] = "foo";
  EXPECT_EQ("foo", FromStringLike({buf, buf + 3}));
}

TEST(StrEqTest, MatchesEqualString) {
  Matcher<const char*> m = StrEq(std::string("Hello"));
  EXPECT_TRUE(m.Matches("Hello"));
  EXPECT_FALSE(m.Matches("hello"));
  EXPECT_FALSE(m.Matches(nullptr));

  Matcher<const std::string&> m2 = StrEq("Hello");
  EXPECT_TRUE(m2.Matches("Hello"));
  EXPECT_FALSE(m2.Matches("Hi"));

#if GTEST_INTERNAL_HAS_STRING_VIEW
  Matcher<const internal::StringView&> m3 =
      StrEq(internal::StringView("Hello"));
  EXPECT_TRUE(m3.Matches(internal::StringView("Hello")));
  EXPECT_FALSE(m3.Matches(internal::StringView("hello")));
  EXPECT_FALSE(m3.Matches(internal::StringView()));

  Matcher<const internal::StringView&> m_empty = StrEq("");
  EXPECT_TRUE(m_empty.Matches(internal::StringView("")));
  EXPECT_TRUE(m_empty.Matches(internal::StringView()));
  EXPECT_FALSE(m_empty.Matches(internal::StringView("hello")));
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW
}

TEST(StrEqTest, CanDescribeSelf) {
  Matcher<std::string> m = StrEq("Hi-\'\"?\\\a\b\f\n\r\t\v\xD3");
  EXPECT_EQ("is equal to \"Hi-\'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\\xD3\"",
            Describe(m));

  std::string str("01204500800");
  str[3] = '\0';
  Matcher<std::string> m2 = StrEq(str);
  EXPECT_EQ("is equal to \"012\\04500800\"", Describe(m2));
  str[0] = str[6] = str[7] = str[9] = str[10] = '\0';
  Matcher<std::string> m3 = StrEq(str);
  EXPECT_EQ("is equal to \"\\012\\045\\0\\08\\0\\0\"", Describe(m3));
}

TEST(StrNeTest, MatchesUnequalString) {
  Matcher<const char*> m = StrNe("Hello");
  EXPECT_TRUE(m.Matches(""));
  EXPECT_TRUE(m.Matches(nullptr));
  EXPECT_FALSE(m.Matches("Hello"));

  Matcher<std::string> m2 = StrNe(std::string("Hello"));
  EXPECT_TRUE(m2.Matches("hello"));
  EXPECT_FALSE(m2.Matches("Hello"));

#if GTEST_INTERNAL_HAS_STRING_VIEW
  Matcher<const internal::StringView> m3 = StrNe(internal::StringView("Hello"));
  EXPECT_TRUE(m3.Matches(internal::StringView("")));
  EXPECT_TRUE(m3.Matches(internal::StringView()));
  EXPECT_FALSE(m3.Matches(internal::StringView("Hello")));
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW
}

TEST(StrNeTest, CanDescribeSelf) {
  Matcher<const char*> m = StrNe("Hi");
  EXPECT_EQ("isn't equal to \"Hi\"", Describe(m));
}

TEST(StrCaseEqTest, MatchesEqualStringIgnoringCase) {
  Matcher<const char*> m = StrCaseEq(std::string("Hello"));
  EXPECT_TRUE(m.Matches("Hello"));
  EXPECT_TRUE(m.Matches("hello"));
  EXPECT_FALSE(m.Matches("Hi"));
  EXPECT_FALSE(m.Matches(nullptr));

  Matcher<const std::string&> m2 = StrCaseEq("Hello");
  EXPECT_TRUE(m2.Matches("hello"));
  EXPECT_FALSE(m2.Matches("Hi"));

#if GTEST_INTERNAL_HAS_STRING_VIEW
  Matcher<const internal::StringView&> m3 =
      StrCaseEq(internal::StringView("Hello"));
  EXPECT_TRUE(m3.Matches(internal::StringView("Hello")));
  EXPECT_TRUE(m3.Matches(internal::StringView("hello")));
  EXPECT_FALSE(m3.Matches(internal::StringView("Hi")));
  EXPECT_FALSE(m3.Matches(internal::StringView()));
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW
}

TEST(StrCaseEqTest, MatchesEqualStringWith0IgnoringCase) {
  std::string str1("oabocdooeoo");
  std::string str2("OABOCDOOEOO");
  Matcher<const std::string&> m0 = StrCaseEq(str1);
  EXPECT_FALSE(m0.Matches(str2 + std::string(1, '\0')));

  str1[3] = str2[3] = '\0';
  Matcher<const std::string&> m1 = StrCaseEq(str1);
  EXPECT_TRUE(m1.Matches(str2));

  str1[0] = str1[6] = str1[7] = str1[10] = '\0';
  str2[0] = str2[6] = str2[7] = str2[10] = '\0';
  Matcher<const std::string&> m2 = StrCaseEq(str1);
  str1[9] = str2[9] = '\0';
  EXPECT_FALSE(m2.Matches(str2));

  Matcher<const std::string&> m3 = StrCaseEq(str1);
  EXPECT_TRUE(m3.Matches(str2));

  EXPECT_FALSE(m3.Matches(str2 + "x"));
  str2.append(1, '\0');
  EXPECT_FALSE(m3.Matches(str2));
  EXPECT_FALSE(m3.Matches(std::string(str2, 0, 9)));
}

TEST(StrCaseEqTest, CanDescribeSelf) {
  Matcher<std::string> m = StrCaseEq("Hi");
  EXPECT_EQ("is equal to (ignoring case) \"Hi\"", Describe(m));
}

TEST(StrCaseNeTest, MatchesUnequalStringIgnoringCase) {
  Matcher<const char*> m = StrCaseNe("Hello");
  EXPECT_TRUE(m.Matches("Hi"));
  EXPECT_TRUE(m.Matches(nullptr));
  EXPECT_FALSE(m.Matches("Hello"));
  EXPECT_FALSE(m.Matches("hello"));

  Matcher<std::string> m2 = StrCaseNe(std::string("Hello"));
  EXPECT_TRUE(m2.Matches(""));
  EXPECT_FALSE(m2.Matches("Hello"));

#if GTEST_INTERNAL_HAS_STRING_VIEW
  Matcher<const internal::StringView> m3 =
      StrCaseNe(internal::StringView("Hello"));
  EXPECT_TRUE(m3.Matches(internal::StringView("Hi")));
  EXPECT_TRUE(m3.Matches(internal::StringView()));
  EXPECT_FALSE(m3.Matches(internal::StringView("Hello")));
  EXPECT_FALSE(m3.Matches(internal::StringView("hello")));
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW
}

TEST(StrCaseNeTest, CanDescribeSelf) {
  Matcher<const char*> m = StrCaseNe("Hi");
  EXPECT_EQ("isn't equal to (ignoring case) \"Hi\"", Describe(m));
}

// Tests that HasSubstr() works for matching string-typed values.
TEST(HasSubstrTest, WorksForStringClasses) {
  const Matcher<std::string> m1 = HasSubstr("foo");
  EXPECT_TRUE(m1.Matches(std::string("I love food.")));
  EXPECT_FALSE(m1.Matches(std::string("tofo")));

  const Matcher<const std::string&> m2 = HasSubstr("foo");
  EXPECT_TRUE(m2.Matches(std::string("I love food.")));
  EXPECT_FALSE(m2.Matches(std::string("tofo")));

  const Matcher<std::string> m_empty = HasSubstr("");
  EXPECT_TRUE(m_empty.Matches(std::string()));
  EXPECT_TRUE(m_empty.Matches(std::string("not empty")));
}

// Tests that HasSubstr() works for matching C-string-typed values.
TEST(HasSubstrTest, WorksForCStrings) {
  const Matcher<char*> m1 = HasSubstr("foo");
  EXPECT_TRUE(m1.Matches(const_cast<char*>("I love food.")));
  EXPECT_FALSE(m1.Matches(const_cast<char*>("tofo")));
  EXPECT_FALSE(m1.Matches(nullptr));

  const Matcher<const char*> m2 = HasSubstr("foo");
  EXPECT_TRUE(m2.Matches("I love food."));
  EXPECT_FALSE(m2.Matches("tofo"));
  EXPECT_FALSE(m2.Matches(nullptr));

  const Matcher<const char*> m_empty = HasSubstr("");
  EXPECT_TRUE(m_empty.Matches("not empty"));
  EXPECT_TRUE(m_empty.Matches(""));
  EXPECT_FALSE(m_empty.Matches(nullptr));
}

#if GTEST_INTERNAL_HAS_STRING_VIEW
// Tests that HasSubstr() works for matching StringView-typed values.
TEST(HasSubstrTest, WorksForStringViewClasses) {
  const Matcher<internal::StringView> m1 =
      HasSubstr(internal::StringView("foo"));
  EXPECT_TRUE(m1.Matches(internal::StringView("I love food.")));
  EXPECT_FALSE(m1.Matches(internal::StringView("tofo")));
  EXPECT_FALSE(m1.Matches(internal::StringView()));

  const Matcher<const internal::StringView&> m2 = HasSubstr("foo");
  EXPECT_TRUE(m2.Matches(internal::StringView("I love food.")));
  EXPECT_FALSE(m2.Matches(internal::StringView("tofo")));
  EXPECT_FALSE(m2.Matches(internal::StringView()));

  const Matcher<const internal::StringView&> m3 = HasSubstr("");
  EXPECT_TRUE(m3.Matches(internal::StringView("foo")));
  EXPECT_TRUE(m3.Matches(internal::StringView("")));
  EXPECT_TRUE(m3.Matches(internal::StringView()));
}
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW

// Tests that HasSubstr(s) describes itself properly.
TEST(HasSubstrTest, CanDescribeSelf) {
  Matcher<std::string> m = HasSubstr("foo\n\"");
  EXPECT_EQ("has substring \"foo\\n\\\"\"", Describe(m));
}

TEST(KeyTest, CanDescribeSelf) {
  Matcher<const pair<std::string, int>&> m = Key("foo");
  EXPECT_EQ("has a key that is equal to \"foo\"", Describe(m));
  EXPECT_EQ("doesn't have a key that is equal to \"foo\"", DescribeNegation(m));
}

TEST(KeyTest, ExplainsResult) {
  Matcher<pair<int, bool>> m = Key(GreaterThan(10));
  EXPECT_EQ("whose first field is a value which is 5 less than 10",
            Explain(m, make_pair(5, true)));
  EXPECT_EQ("whose first field is a value which is 5 more than 10",
            Explain(m, make_pair(15, true)));
}

TEST(KeyTest, MatchesCorrectly) {
  pair<int, std::string> p(25, "foo");
  EXPECT_THAT(p, Key(25));
  EXPECT_THAT(p, Not(Key(42)));
  EXPECT_THAT(p, Key(Ge(20)));
  EXPECT_THAT(p, Not(Key(Lt(25))));
}

TEST(KeyTest, WorksWithMoveOnly) {
  pair<std::unique_ptr<int>, std::unique_ptr<int>> p;
  EXPECT_THAT(p, Key(Eq(nullptr)));
}

template <size_t I>
struct Tag {};

struct PairWithGet {
  int member_1;
  std::string member_2;
  using first_type = int;
  using second_type = std::string;

  const int& GetImpl(Tag<0>) const { return member_1; }
  const std::string& GetImpl(Tag<1>) const { return member_2; }
};
template <size_t I>
auto get(const PairWithGet& value) -> decltype(value.GetImpl(Tag<I>())) {
  return value.GetImpl(Tag<I>());
}
TEST(PairTest, MatchesPairWithGetCorrectly) {
  PairWithGet p{25, "foo"};
  EXPECT_THAT(p, Key(25));
  EXPECT_THAT(p, Not(Key(42)));
  EXPECT_THAT(p, Key(Ge(20)));
  EXPECT_THAT(p, Not(Key(Lt(25))));

  std::vector<PairWithGet> v = {{11, "Foo"}, {29, "gMockIsBestMock"}};
  EXPECT_THAT(v, Contains(Key(29)));
}

TEST(KeyTest, SafelyCastsInnerMatcher) {
  Matcher<int> is_positive = Gt(0);
  Matcher<int> is_negative = Lt(0);
  pair<char, bool> p('a', true);
  EXPECT_THAT(p, Key(is_positive));
  EXPECT_THAT(p, Not(Key(is_negative)));
}

TEST(KeyTest, InsideContainsUsingMap) {
  map<int, char> container;
  container.insert(make_pair(1, 'a'));
  container.insert(make_pair(2, 'b'));
  container.insert(make_pair(4, 'c'));
  EXPECT_THAT(container, Contains(Key(1)));
  EXPECT_THAT(container, Not(Contains(Key(3))));
}

TEST(KeyTest, InsideContainsUsingMultimap) {
  multimap<int, char> container;
  container.insert(make_pair(1, 'a'));
  container.insert(make_pair(2, 'b'));
  container.insert(make_pair(4, 'c'));

  EXPECT_THAT(container, Not(Contains(Key(25))));
  container.insert(make_pair(25, 'd'));
  EXPECT_THAT(container, Contains(Key(25)));
  container.insert(make_pair(25, 'e'));
  EXPECT_THAT(container, Contains(Key(25)));

  EXPECT_THAT(container, Contains(Key(1)));
  EXPECT_THAT(container, Not(Contains(Key(3))));
}

TEST(PairTest, Typing) {
  // Test verifies the following type conversions can be compiled.
  Matcher<const pair<const char*, int>&> m1 = Pair("foo", 42);
  Matcher<const pair<const char*, int>> m2 = Pair("foo", 42);
  Matcher<pair<const char*, int>> m3 = Pair("foo", 42);

  Matcher<pair<int, const std::string>> m4 = Pair(25, "42");
  Matcher<pair<const std::string, int>> m5 = Pair("25", 42);
}

TEST(PairTest, CanDescribeSelf) {
  Matcher<const pair<std::string, int>&> m1 = Pair("foo", 42);
  EXPECT_EQ(
      "has a first field that is equal to \"foo\""
      ", and has a second field that is equal to 42",
      Describe(m1));
  EXPECT_EQ(
      "has a first field that isn't equal to \"foo\""
      ", or has a second field that isn't equal to 42",
      DescribeNegation(m1));
  // Double and triple negation (1 or 2 times not and description of negation).
  Matcher<const pair<int, int>&> m2 = Not(Pair(Not(13), 42));
  EXPECT_EQ(
      "has a first field that isn't equal to 13"
      ", and has a second field that is equal to 42",
      DescribeNegation(m2));
}

TEST(PairTest, CanExplainMatchResultTo) {
  // If neither field matches, Pair() should explain about the first
  // field.
  const Matcher<pair<int, int>> m = Pair(GreaterThan(0), GreaterThan(0));
  EXPECT_EQ("whose first field does not match, which is 1 less than 0",
            Explain(m, make_pair(-1, -2)));

  // If the first field matches but the second doesn't, Pair() should
  // explain about the second field.
  EXPECT_EQ("whose second field does not match, which is 2 less than 0",
            Explain(m, make_pair(1, -2)));

  // If the first field doesn't match but the second does, Pair()
  // should explain about the first field.
  EXPECT_EQ("whose first field does not match, which is 1 less than 0",
            Explain(m, make_pair(-1, 2)));

  // If both fields match, Pair() should explain about them both.
  EXPECT_EQ(
      "whose both fields match, where the first field is a value "
      "which is 1 more than 0, and the second field is a value "
      "which is 2 more than 0",
      Explain(m, make_pair(1, 2)));

  // If only the first match has an explanation, only this explanation should
  // be printed.
  const Matcher<pair<int, int>> explain_first = Pair(GreaterThan(0), 0);
  EXPECT_EQ(
      "whose both fields match, where the first field is a value "
      "which is 1 more than 0",
      Explain(explain_first, make_pair(1, 0)));

  // If only the second match has an explanation, only this explanation should
  // be printed.
  const Matcher<pair<int, int>> explain_second = Pair(0, GreaterThan(0));
  EXPECT_EQ(
      "whose both fields match, where the second field is a value "
      "which is 1 more than 0",
      Explain(explain_second, make_pair(0, 1)));
}

TEST(PairTest, MatchesCorrectly) {
  pair<int, std::string> p(25, "foo");

  // Both fields match.
  EXPECT_THAT(p, Pair(25, "foo"));
  EXPECT_THAT(p, Pair(Ge(20), HasSubstr("o")));

  // 'first' doesnt' match, but 'second' matches.
  EXPECT_THAT(p, Not(Pair(42, "foo")));
  EXPECT_THAT(p, Not(Pair(Lt(25), "foo")));

  // 'first' matches, but 'second' doesn't match.
  EXPECT_THAT(p, Not(Pair(25, "bar")));
  EXPECT_THAT(p, Not(Pair(25, Not("foo"))));

  // Neither field matches.
  EXPECT_THAT(p, Not(Pair(13, "bar")));
  EXPECT_THAT(p, Not(Pair(Lt(13), HasSubstr("a"))));
}

TEST(PairTest, WorksWithMoveOnly) {
  pair<std::unique_ptr<int>, std::unique_ptr<int>> p;
  p.second.reset(new int(7));
  EXPECT_THAT(p, Pair(Eq(nullptr), Ne(nullptr)));
}

TEST(PairTest, SafelyCastsInnerMatchers) {
  Matcher<int> is_positive = Gt(0);
  Matcher<int> is_negative = Lt(0);
  pair<char, bool> p('a', true);
  EXPECT_THAT(p, Pair(is_positive, _));
  EXPECT_THAT(p, Not(Pair(is_negative, _)));
  EXPECT_THAT(p, Pair(_, is_positive));
  EXPECT_THAT(p, Not(Pair(_, is_negative)));
}

TEST(PairTest, InsideContainsUsingMap) {
  map<int, char> container;
  container.insert(make_pair(1, 'a'));
  container.insert(make_pair(2, 'b'));
  container.insert(make_pair(4, 'c'));
  EXPECT_THAT(container, Contains(Pair(1, 'a')));
  EXPECT_THAT(container, Contains(Pair(1, _)));
  EXPECT_THAT(container, Contains(Pair(_, 'a')));
  EXPECT_THAT(container, Not(Contains(Pair(3, _))));
}

TEST(FieldsAreTest, MatchesCorrectly) {
  std::tuple<int, std::string, double> p(25, "foo", .5);

  // All fields match.
  EXPECT_THAT(p, FieldsAre(25, "foo", .5));
  EXPECT_THAT(p, FieldsAre(Ge(20), HasSubstr("o"), DoubleEq(.5)));

  // Some don't match.
  EXPECT_THAT(p, Not(FieldsAre(26, "foo", .5)));
  EXPECT_THAT(p, Not(FieldsAre(25, "fo", .5)));
  EXPECT_THAT(p, Not(FieldsAre(25, "foo", .6)));
}

TEST(FieldsAreTest, CanDescribeSelf) {
  Matcher<const pair<std::string, int>&> m1 = FieldsAre("foo", 42);
  EXPECT_EQ(
      "has field #0 that is equal to \"foo\""
      ", and has field #1 that is equal to 42",
      Describe(m1));
  EXPECT_EQ(
      "has field #0 that isn't equal to \"foo\""
      ", or has field #1 that isn't equal to 42",
      DescribeNegation(m1));
}

TEST(FieldsAreTest, CanExplainMatchResultTo) {
  // The first one that fails is the one that gives the error.
  Matcher<std::tuple<int, int, int>> m =
      FieldsAre(GreaterThan(0), GreaterThan(0), GreaterThan(0));

  EXPECT_EQ("whose field #0 does not match, which is 1 less than 0",
            Explain(m, std::make_tuple(-1, -2, -3)));
  EXPECT_EQ("whose field #1 does not match, which is 2 less than 0",
            Explain(m, std::make_tuple(1, -2, -3)));
  EXPECT_EQ("whose field #2 does not match, which is 3 less than 0",
            Explain(m, std::make_tuple(1, 2, -3)));

  // If they all match, we get a long explanation of success.
  EXPECT_EQ(
      "whose all elements match, "
      "where field #0 is a value which is 1 more than 0"
      ", and field #1 is a value which is 2 more than 0"
      ", and field #2 is a value which is 3 more than 0",
      Explain(m, std::make_tuple(1, 2, 3)));

  // Only print those that have an explanation.
  m = FieldsAre(GreaterThan(0), 0, GreaterThan(0));
  EXPECT_EQ(
      "whose all elements match, "
      "where field #0 is a value which is 1 more than 0"
      ", and field #2 is a value which is 3 more than 0",
      Explain(m, std::make_tuple(1, 0, 3)));

  // If only one has an explanation, then print that one.
  m = FieldsAre(0, GreaterThan(0), 0);
  EXPECT_EQ(
      "whose all elements match, "
      "where field #1 is a value which is 1 more than 0",
      Explain(m, std::make_tuple(0, 1, 0)));
}

#if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606
TEST(FieldsAreTest, StructuredBindings) {
  // testing::FieldsAre can also match aggregates and such with C++17 and up.
  struct MyType {
    int i;
    std::string str;
  };
  EXPECT_THAT((MyType{17, "foo"}), FieldsAre(Eq(17), HasSubstr("oo")));

  // Test all the supported arities.
  struct MyVarType1 {
    int a;
  };
  EXPECT_THAT(MyVarType1{}, FieldsAre(0));
  struct MyVarType2 {
    int a, b;
  };
  EXPECT_THAT(MyVarType2{}, FieldsAre(0, 0));
  struct MyVarType3 {
    int a, b, c;
  };
  EXPECT_THAT(MyVarType3{}, FieldsAre(0, 0, 0));
  struct MyVarType4 {
    int a, b, c, d;
  };
  EXPECT_THAT(MyVarType4{}, FieldsAre(0, 0, 0, 0));
  struct MyVarType5 {
    int a, b, c, d, e;
  };
  EXPECT_THAT(MyVarType5{}, FieldsAre(0, 0, 0, 0, 0));
  struct MyVarType6 {
    int a, b, c, d, e, f;
  };
  EXPECT_THAT(MyVarType6{}, FieldsAre(0, 0, 0, 0, 0, 0));
  struct MyVarType7 {
    int a, b, c, d, e, f, g;
  };
  EXPECT_THAT(MyVarType7{}, FieldsAre(0, 0, 0, 0, 0, 0, 0));
  struct MyVarType8 {
    int a, b, c, d, e, f, g, h;
  };
  EXPECT_THAT(MyVarType8{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0));
  struct MyVarType9 {
    int a, b, c, d, e, f, g, h, i;
  };
  EXPECT_THAT(MyVarType9{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0));
  struct MyVarType10 {
    int a, b, c, d, e, f, g, h, i, j;
  };
  EXPECT_THAT(MyVarType10{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
  struct MyVarType11 {
    int a, b, c, d, e, f, g, h, i, j, k;
  };
  EXPECT_THAT(MyVarType11{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
  struct MyVarType12 {
    int a, b, c, d, e, f, g, h, i, j, k, l;
  };
  EXPECT_THAT(MyVarType12{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
  struct MyVarType13 {
    int a, b, c, d, e, f, g, h, i, j, k, l, m;
  };
  EXPECT_THAT(MyVarType13{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
  struct MyVarType14 {
    int a, b, c, d, e, f, g, h, i, j, k, l, m, n;
  };
  EXPECT_THAT(MyVarType14{},
              FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
  struct MyVarType15 {
    int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o;
  };
  EXPECT_THAT(MyVarType15{},
              FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
  struct MyVarType16 {
    int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
  };
  EXPECT_THAT(MyVarType16{},
              FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
}
#endif

TEST(PairTest, UseGetInsteadOfMembers) {
  PairWithGet pair{7, "ABC"};
  EXPECT_THAT(pair, Pair(7, "ABC"));
  EXPECT_THAT(pair, Pair(Ge(7), HasSubstr("AB")));
  EXPECT_THAT(pair, Not(Pair(Lt(7), "ABC")));

  std::vector<PairWithGet> v = {{11, "Foo"}, {29, "gMockIsBestMock"}};
  EXPECT_THAT(v,
              ElementsAre(Pair(11, std::string("Foo")), Pair(Ge(10), Not(""))));
}

// Tests StartsWith(s).

TEST(StartsWithTest, MatchesStringWithGivenPrefix) {
  const Matcher<const char*> m1 = StartsWith(std::string(""));
  EXPECT_TRUE(m1.Matches("Hi"));
  EXPECT_TRUE(m1.Matches(""));
  EXPECT_FALSE(m1.Matches(nullptr));

  const Matcher<const std::string&> m2 = StartsWith("Hi");
  EXPECT_TRUE(m2.Matches("Hi"));
  EXPECT_TRUE(m2.Matches("Hi Hi!"));
  EXPECT_TRUE(m2.Matches("High"));
  EXPECT_FALSE(m2.Matches("H"));
  EXPECT_FALSE(m2.Matches(" Hi"));

#if GTEST_INTERNAL_HAS_STRING_VIEW
  const Matcher<internal::StringView> m_empty =
      StartsWith(internal::StringView(""));
  EXPECT_TRUE(m_empty.Matches(internal::StringView()));
  EXPECT_TRUE(m_empty.Matches(internal::StringView("")));
  EXPECT_TRUE(m_empty.Matches(internal::StringView("not empty")));
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW
}

TEST(StartsWithTest, CanDescribeSelf) {
  Matcher<const std::string> m = StartsWith("Hi");
  EXPECT_EQ("starts with \"Hi\"", Describe(m));
}

// Tests EndsWith(s).

TEST(EndsWithTest, MatchesStringWithGivenSuffix) {
  const Matcher<const char*> m1 = EndsWith("");
  EXPECT_TRUE(m1.Matches("Hi"));
  EXPECT_TRUE(m1.Matches(""));
  EXPECT_FALSE(m1.Matches(nullptr));

  const Matcher<const std::string&> m2 = EndsWith(std::string("Hi"));
  EXPECT_TRUE(m2.Matches("Hi"));
  EXPECT_TRUE(m2.Matches("Wow Hi Hi"));
  EXPECT_TRUE(m2.Matches("Super Hi"));
  EXPECT_FALSE(m2.Matches("i"));
  EXPECT_FALSE(m2.Matches("Hi "));

#if GTEST_INTERNAL_HAS_STRING_VIEW
  const Matcher<const internal::StringView&> m4 =
      EndsWith(internal::StringView(""));
  EXPECT_TRUE(m4.Matches("Hi"));
  EXPECT_TRUE(m4.Matches(""));
  EXPECT_TRUE(m4.Matches(internal::StringView()));
  EXPECT_TRUE(m4.Matches(internal::StringView("")));
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW
}

TEST(EndsWithTest, CanDescribeSelf) {
  Matcher<const std::string> m = EndsWith("Hi");
  EXPECT_EQ("ends with \"Hi\"", Describe(m));
}

// Tests WhenBase64Unescaped.

TEST(WhenBase64UnescapedTest, MatchesUnescapedBase64Strings) {
  const Matcher<const char*> m1 = WhenBase64Unescaped(EndsWith("!"));
  EXPECT_FALSE(m1.Matches("invalid base64"));
  EXPECT_FALSE(m1.Matches("aGVsbG8gd29ybGQ="));  // hello world
  EXPECT_TRUE(m1.Matches("aGVsbG8gd29ybGQh"));   // hello world!

  const Matcher<const std::string&> m2 = WhenBase64Unescaped(EndsWith("!"));
  EXPECT_FALSE(m2.Matches("invalid base64"));
  EXPECT_FALSE(m2.Matches("aGVsbG8gd29ybGQ="));  // hello world
  EXPECT_TRUE(m2.Matches("aGVsbG8gd29ybGQh"));   // hello world!

#if GTEST_INTERNAL_HAS_STRING_VIEW
  const Matcher<const internal::StringView&> m3 =
      WhenBase64Unescaped(EndsWith("!"));
  EXPECT_FALSE(m3.Matches("invalid base64"));
  EXPECT_FALSE(m3.Matches("aGVsbG8gd29ybGQ="));  // hello world
  EXPECT_TRUE(m3.Matches("aGVsbG8gd29ybGQh"));   // hello world!
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW
}

TEST(WhenBase64UnescapedTest, CanDescribeSelf) {
  const Matcher<const char*> m = WhenBase64Unescaped(EndsWith("!"));
  EXPECT_EQ("matches after Base64Unescape ends with \"!\"", Describe(m));
}

// Tests MatchesRegex().

TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) {
  const Matcher<const char*> m1 = MatchesRegex("a.*z");
  EXPECT_TRUE(m1.Matches("az"));
  EXPECT_TRUE(m1.Matches("abcz"));
  EXPECT_FALSE(m1.Matches(nullptr));

  const Matcher<const std::string&> m2 = MatchesRegex(new RE("a.*z"));
  EXPECT_TRUE(m2.Matches("azbz"));
  EXPECT_FALSE(m2.Matches("az1"));
  EXPECT_FALSE(m2.Matches("1az"));

#if GTEST_INTERNAL_HAS_STRING_VIEW
  const Matcher<const internal::StringView&> m3 = MatchesRegex("a.*z");
  EXPECT_TRUE(m3.Matches(internal::StringView("az")));
  EXPECT_TRUE(m3.Matches(internal::StringView("abcz")));
  EXPECT_FALSE(m3.Matches(internal::StringView("1az")));
  EXPECT_FALSE(m3.Matches(internal::StringView()));
  const Matcher<const internal::StringView&> m4 =
      MatchesRegex(internal::StringView(""));
  EXPECT_TRUE(m4.Matches(internal::StringView("")));
  EXPECT_TRUE(m4.Matches(internal::StringView()));
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW
}

TEST(MatchesRegexTest, CanDescribeSelf) {
  Matcher<const std::string> m1 = MatchesRegex(std::string("Hi.*"));
  EXPECT_EQ("matches regular expression \"Hi.*\"", Describe(m1));

  Matcher<const char*> m2 = MatchesRegex(new RE("a.*"));
  EXPECT_EQ("matches regular expression \"a.*\"", Describe(m2));

#if GTEST_INTERNAL_HAS_STRING_VIEW
  Matcher<const internal::StringView> m3 = MatchesRegex(new RE("0.*"));
  EXPECT_EQ("matches regular expression \"0.*\"", Describe(m3));
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW
}

// Tests ContainsRegex().

TEST(ContainsRegexTest, MatchesStringContainingGivenRegex) {
  const Matcher<const char*> m1 = ContainsRegex(std::string("a.*z"));
  EXPECT_TRUE(m1.Matches("az"));
  EXPECT_TRUE(m1.Matches("0abcz1"));
  EXPECT_FALSE(m1.Matches(nullptr));

  const Matcher<const std::string&> m2 = ContainsRegex(new RE("a.*z"));
  EXPECT_TRUE(m2.Matches("azbz"));
  EXPECT_TRUE(m2.Matches("az1"));
  EXPECT_FALSE(m2.Matches("1a"));

#if GTEST_INTERNAL_HAS_STRING_VIEW
  const Matcher<const internal::StringView&> m3 = ContainsRegex(new RE("a.*z"));
  EXPECT_TRUE(m3.Matches(internal::StringView("azbz")));
  EXPECT_TRUE(m3.Matches(internal::StringView("az1")));
  EXPECT_FALSE(m3.Matches(internal::StringView("1a")));
  EXPECT_FALSE(m3.Matches(internal::StringView()));
  const Matcher<const internal::StringView&> m4 =
      ContainsRegex(internal::StringView(""));
  EXPECT_TRUE(m4.Matches(internal::StringView("")));
  EXPECT_TRUE(m4.Matches(internal::StringView()));
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW
}

TEST(ContainsRegexTest, CanDescribeSelf) {
  Matcher<const std::string> m1 = ContainsRegex("Hi.*");
  EXPECT_EQ("contains regular expression \"Hi.*\"", Describe(m1));

  Matcher<const char*> m2 = ContainsRegex(new RE("a.*"));
  EXPECT_EQ("contains regular expression \"a.*\"", Describe(m2));

#if GTEST_INTERNAL_HAS_STRING_VIEW
  Matcher<const internal::StringView> m3 = ContainsRegex(new RE("0.*"));
  EXPECT_EQ("contains regular expression \"0.*\"", Describe(m3));
#endif  // GTEST_INTERNAL_HAS_STRING_VIEW
}

// Tests for wide strings.
#if GTEST_HAS_STD_WSTRING
TEST(StdWideStrEqTest, MatchesEqual) {
  Matcher<const wchar_t*> m = StrEq(::std::wstring(L"Hello"));
  EXPECT_TRUE(m.Matches(L"Hello"));
  EXPECT_FALSE(m.Matches(L"hello"));
  EXPECT_FALSE(m.Matches(nullptr));

  Matcher<const ::std::wstring&> m2 = StrEq(L"Hello");
  EXPECT_TRUE(m2.Matches(L"Hello"));
  EXPECT_FALSE(m2.Matches(L"Hi"));

  Matcher<const ::std::wstring&> m3 = StrEq(L"\xD3\x576\x8D3\xC74D");
  EXPECT_TRUE(m3.Matches(L"\xD3\x576\x8D3\xC74D"));
  EXPECT_FALSE(m3.Matches(L"\xD3\x576\x8D3\xC74E"));

  ::std::wstring str(L"01204500800");
  str[3] = L'\0';
  Matcher<const ::std::wstring&> m4 = StrEq(str);
  EXPECT_TRUE(m4.Matches(str));
  str[0] = str[6] = str[7] = str[9] = str[10] = L'\0';
  Matcher<const ::std::wstring&> m5 = StrEq(str);
  EXPECT_TRUE(m5.Matches(str));
}

TEST(StdWideStrEqTest, CanDescribeSelf) {
  Matcher<::std::wstring> m = StrEq(L"Hi-\'\"?\\\a\b\f\n\r\t\v");
  EXPECT_EQ("is equal to L\"Hi-\'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\"",
            Describe(m));

  Matcher<::std::wstring> m2 = StrEq(L"\xD3\x576\x8D3\xC74D");
  EXPECT_EQ("is equal to L\"\\xD3\\x576\\x8D3\\xC74D\"", Describe(m2));

  ::std::wstring str(L"01204500800");
  str[3] = L'\0';
  Matcher<const ::std::wstring&> m4 = StrEq(str);
  EXPECT_EQ("is equal to L\"012\\04500800\"", Describe(m4));
  str[0] = str[6] = str[7] = str[9] = str[10] = L'\0';
  Matcher<const ::std::wstring&> m5 = StrEq(str);
  EXPECT_EQ("is equal to L\"\\012\\045\\0\\08\\0\\0\"", Describe(m5));
}

TEST(StdWideStrNeTest, MatchesUnequalString) {
  Matcher<const wchar_t*> m = StrNe(L"Hello");
  EXPECT_TRUE(m.Matches(L""));
  EXPECT_TRUE(m.Matches(nullptr));
  EXPECT_FALSE(m.Matches(L"Hello"));

  Matcher<::std::wstring> m2 = StrNe(::std::wstring(L"Hello"));
  EXPECT_TRUE(m2.Matches(L"hello"));
  EXPECT_FALSE(m2.Matches(L"Hello"));
}

TEST(StdWideStrNeTest, CanDescribeSelf) {
  Matcher<const wchar_t*> m = StrNe(L"Hi");
  EXPECT_EQ("isn't equal to L\"Hi\"", Describe(m));
}

TEST(StdWideStrCaseEqTest, MatchesEqualStringIgnoringCase) {
  Matcher<const wchar_t*> m = StrCaseEq(::std::wstring(L"Hello"));
  EXPECT_TRUE(m.Matches(L"Hello"));
  EXPECT_TRUE(m.Matches(L"hello"));
  EXPECT_FALSE(m.Matches(L"Hi"));
  EXPECT_FALSE(m.Matches(nullptr));

  Matcher<const ::std::wstring&> m2 = StrCaseEq(L"Hello");
  EXPECT_TRUE(m2.Matches(L"hello"));
  EXPECT_FALSE(m2.Matches(L"Hi"));
}

TEST(StdWideStrCaseEqTest, MatchesEqualStringWith0IgnoringCase) {
  ::std::wstring str1(L"oabocdooeoo");
  ::std::wstring str2(L"OABOCDOOEOO");
  Matcher<const ::std::wstring&> m0 = StrCaseEq(str1);
  EXPECT_FALSE(m0.Matches(str2 + ::std::wstring(1, L'\0')));

  str1[3] = str2[3] = L'\0';
  Matcher<const ::std::wstring&> m1 = StrCaseEq(str1);
  EXPECT_TRUE(m1.Matches(str2));

  str1[0] = str1[6] = str1[7] = str1[10] = L'\0';
  str2[0] = str2[6] = str2[7] = str2[10] = L'\0';
  Matcher<const ::std::wstring&> m2 = StrCaseEq(str1);
  str1[9] = str2[9] = L'\0';
  EXPECT_FALSE(m2.Matches(str2));

  Matcher<const ::std::wstring&> m3 = StrCaseEq(str1);
  EXPECT_TRUE(m3.Matches(str2));

  EXPECT_FALSE(m3.Matches(str2 + L"x"));
  str2.append(1, L'\0');
  EXPECT_FALSE(m3.Matches(str2));
  EXPECT_FALSE(m3.Matches(::std::wstring(str2, 0, 9)));
}

TEST(StdWideStrCaseEqTest, CanDescribeSelf) {
  Matcher<::std::wstring> m = StrCaseEq(L"Hi");
  EXPECT_EQ("is equal to (ignoring case) L\"Hi\"", Describe(m));
}

TEST(StdWideStrCaseNeTest, MatchesUnequalStringIgnoringCase) {
  Matcher<const wchar_t*> m = StrCaseNe(L"Hello");
  EXPECT_TRUE(m.Matches(L"Hi"));
  EXPECT_TRUE(m.Matches(nullptr));
  EXPECT_FALSE(m.Matches(L"Hello"));
  EXPECT_FALSE(m.Matches(L"hello"));

  Matcher<::std::wstring> m2 = StrCaseNe(::std::wstring(L"Hello"));
  EXPECT_TRUE(m2.Matches(L""));
  EXPECT_FALSE(m2.Matches(L"Hello"));
}

TEST(StdWideStrCaseNeTest, CanDescribeSelf) {
  Matcher<const wchar_t*> m = StrCaseNe(L"Hi");
  EXPECT_EQ("isn't equal to (ignoring case) L\"Hi\"", Describe(m));
}

// Tests that HasSubstr() works for matching wstring-typed values.
TEST(StdWideHasSubstrTest, WorksForStringClasses) {
  const Matcher<::std::wstring> m1 = HasSubstr(L"foo");
  EXPECT_TRUE(m1.Matches(::std::wstring(L"I love food.")));
  EXPECT_FALSE(m1.Matches(::std::wstring(L"tofo")));

  const Matcher<const ::std::wstring&> m2 = HasSubstr(L"foo");
  EXPECT_TRUE(m2.Matches(::std::wstring(L"I love food.")));
  EXPECT_FALSE(m2.Matches(::std::wstring(L"tofo")));
}

// Tests that HasSubstr() works for matching C-wide-string-typed values.
TEST(StdWideHasSubstrTest, WorksForCStrings) {
  const Matcher<wchar_t*> m1 = HasSubstr(L"foo");
  EXPECT_TRUE(m1.Matches(const_cast<wchar_t*>(L"I love food.")));
  EXPECT_FALSE(m1.Matches(const_cast<wchar_t*>(L"tofo")));
  EXPECT_FALSE(m1.Matches(nullptr));

  const Matcher<const wchar_t*> m2 = HasSubstr(L"foo");
  EXPECT_TRUE(m2.Matches(L"I love food."));
  EXPECT_FALSE(m2.Matches(L"tofo"));
  EXPECT_FALSE(m2.Matches(nullptr));
}

// Tests that HasSubstr(s) describes itself properly.
TEST(StdWideHasSubstrTest, CanDescribeSelf) {
  Matcher<::std::wstring> m = HasSubstr(L"foo\n\"");
  EXPECT_EQ("has substring L\"foo\\n\\\"\"", Describe(m));
}

// Tests StartsWith(s).

TEST(StdWideStartsWithTest, MatchesStringWithGivenPrefix) {
  const Matcher<const wchar_t*> m1 = StartsWith(::std::wstring(L""));
  EXPECT_TRUE(m1.Matches(L"Hi"));
  EXPECT_TRUE(m1.Matches(L""));
  EXPECT_FALSE(m1.Matches(nullptr));

  const Matcher<const ::std::wstring&> m2 = StartsWith(L"Hi");
  EXPECT_TRUE(m2.Matches(L"Hi"));
  EXPECT_TRUE(m2.Matches(L"Hi Hi!"));
  EXPECT_TRUE(m2.Matches(L"High"));
  EXPECT_FALSE(m2.Matches(L"H"));
  EXPECT_FALSE(m2.Matches(L" Hi"));
}

TEST(StdWideStartsWithTest, CanDescribeSelf) {
  Matcher<const ::std::wstring> m = StartsWith(L"Hi");
  EXPECT_EQ("starts with L\"Hi\"", Describe(m));
}

// Tests EndsWith(s).

TEST(StdWideEndsWithTest, MatchesStringWithGivenSuffix) {
  const Matcher<const wchar_t*> m1 = EndsWith(L"");
  EXPECT_TRUE(m1.Matches(L"Hi"));
  EXPECT_TRUE(m1.Matches(L""));
  EXPECT_FALSE(m1.Matches(nullptr));

  const Matcher<const ::std::wstring&> m2 = EndsWith(::std::wstring(L"Hi"));
  EXPECT_TRUE(m2.Matches(L"Hi"));
  EXPECT_TRUE(m2.Matches(L"Wow Hi Hi"));
  EXPECT_TRUE(m2.Matches(L"Super Hi"));
  EXPECT_FALSE(m2.Matches(L"i"));
  EXPECT_FALSE(m2.Matches(L"Hi "));
}

TEST(StdWideEndsWithTest, CanDescribeSelf) {
  Matcher<const ::std::wstring> m = EndsWith(L"Hi");
  EXPECT_EQ("ends with L\"Hi\"", Describe(m));
}

#endif  // GTEST_HAS_STD_WSTRING

TEST(ExplainMatchResultTest, WorksWithPolymorphicMatcher) {
  StringMatchResultListener listener1;
  EXPECT_TRUE(ExplainMatchResult(PolymorphicIsEven(), 42, &listener1));
  EXPECT_EQ("% 2 == 0", listener1.str());

  StringMatchResultListener listener2;
  EXPECT_FALSE(ExplainMatchResult(Ge(42), 1.5, &listener2));
  EXPECT_EQ("", listener2.str());
}

TEST(ExplainMatchResultTest, WorksWithMonomorphicMatcher) {
  const Matcher<int> is_even = PolymorphicIsEven();
  StringMatchResultListener listener1;
  EXPECT_TRUE(ExplainMatchResult(is_even, 42, &listener1));
  EXPECT_EQ("% 2 == 0", listener1.str());

  const Matcher<const double&> is_zero = Eq(0);
  StringMatchResultListener listener2;
  EXPECT_FALSE(ExplainMatchResult(is_zero, 1.5, &listener2));
  EXPECT_EQ("", listener2.str());
}

MATCHER(ConstructNoArg, "") { return true; }
MATCHER_P(Construct1Arg, arg1, "") { return true; }
MATCHER_P2(Construct2Args, arg1, arg2, "") { return true; }

TEST(MatcherConstruct, ExplicitVsImplicit) {
  {
    // No arg constructor can be constructed with empty brace.
    ConstructNoArgMatcher m = {};
    (void)m;
    // And with no args
    ConstructNoArgMatcher m2;
    (void)m2;
  }
  {
    // The one arg constructor has an explicit constructor.
    // This is to prevent the implicit conversion.
    using M = Construct1ArgMatcherP<int>;
    EXPECT_TRUE((std::is_constructible<M, int>::value));
    EXPECT_FALSE((std::is_convertible<int, M>::value));
  }
  {
    // Multiple arg matchers can be constructed with an implicit construction.
    Construct2ArgsMatcherP2<int, double> m = {1, 2.2};
    (void)m;
  }
}

MATCHER_P(Really, inner_matcher, "") {
  return ExplainMatchResult(inner_matcher, arg, result_listener);
}

TEST(ExplainMatchResultTest, WorksInsideMATCHER) {
  EXPECT_THAT(0, Really(Eq(0)));
}

TEST(DescribeMatcherTest, WorksWithValue) {
  EXPECT_EQ("is equal to 42", DescribeMatcher<int>(42));
  EXPECT_EQ("isn't equal to 42", DescribeMatcher<int>(42, true));
}

TEST(DescribeMatcherTest, WorksWithMonomorphicMatcher) {
  const Matcher<int> monomorphic = Le(0);
  EXPECT_EQ("is <= 0", DescribeMatcher<int>(monomorphic));
  EXPECT_EQ("isn't <= 0", DescribeMatcher<int>(monomorphic, true));
}

TEST(DescribeMatcherTest, WorksWithPolymorphicMatcher) {
  EXPECT_EQ("is even", DescribeMatcher<int>(PolymorphicIsEven()));
  EXPECT_EQ("is odd", DescribeMatcher<int>(PolymorphicIsEven(), true));
}

MATCHER_P(FieldIIs, inner_matcher, "") {
  return ExplainMatchResult(inner_matcher, arg.i, result_listener);
}

#if GTEST_HAS_RTTI
TEST(WhenDynamicCastToTest, SameType) {
  Derived derived;
  derived.i = 4;

  // Right type. A pointer is passed down.
  Base* as_base_ptr = &derived;
  EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<Derived*>(Not(IsNull())));
  EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<Derived*>(Pointee(FieldIIs(4))));
  EXPECT_THAT(as_base_ptr,
              Not(WhenDynamicCastTo<Derived*>(Pointee(FieldIIs(5)))));
}

TEST(WhenDynamicCastToTest, WrongTypes) {
  Base base;
  Derived derived;
  OtherDerived other_derived;

  // Wrong types. NULL is passed.
  EXPECT_THAT(&base, Not(WhenDynamicCastTo<Derived*>(Pointee(_))));
  EXPECT_THAT(&base, WhenDynamicCastTo<Derived*>(IsNull()));
  Base* as_base_ptr = &derived;
  EXPECT_THAT(as_base_ptr, Not(WhenDynamicCastTo<OtherDerived*>(Pointee(_))));
  EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<OtherDerived*>(IsNull()));
  as_base_ptr = &other_derived;
  EXPECT_THAT(as_base_ptr, Not(WhenDynamicCastTo<Derived*>(Pointee(_))));
  EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<Derived*>(IsNull()));
}

TEST(WhenDynamicCastToTest, AlreadyNull) {
  // Already NULL.
  Base* as_base_ptr = nullptr;
  EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<Derived*>(IsNull()));
}

struct AmbiguousCastTypes {
  class VirtualDerived : public virtual Base {};
  class DerivedSub1 : public VirtualDerived {};
  class DerivedSub2 : public VirtualDerived {};
  class ManyDerivedInHierarchy : public DerivedSub1, public DerivedSub2 {};
};

TEST(WhenDynamicCastToTest, AmbiguousCast) {
  AmbiguousCastTypes::DerivedSub1 sub1;
  AmbiguousCastTypes::ManyDerivedInHierarchy many_derived;
  // Multiply derived from Base. dynamic_cast<> returns NULL.
  Base* as_base_ptr =
      static_cast<AmbiguousCastTypes::DerivedSub1*>(&many_derived);
  EXPECT_THAT(as_base_ptr,
              WhenDynamicCastTo<AmbiguousCastTypes::VirtualDerived*>(IsNull()));
  as_base_ptr = &sub1;
  EXPECT_THAT(
      as_base_ptr,
      WhenDynamicCastTo<AmbiguousCastTypes::VirtualDerived*>(Not(IsNull())));
}

TEST(WhenDynamicCastToTest, Describe) {
  Matcher<Base*> matcher = WhenDynamicCastTo<Derived*>(Pointee(_));
  const std::string prefix =
      "when dynamic_cast to " + internal::GetTypeName<Derived*>() + ", ";
  EXPECT_EQ(prefix + "points to a value that is anything", Describe(matcher));
  EXPECT_EQ(prefix + "does not point to a value that is anything",
            DescribeNegation(matcher));
}

TEST(WhenDynamicCastToTest, Explain) {
  Matcher<Base*> matcher = WhenDynamicCastTo<Derived*>(Pointee(_));
  Base* null = nullptr;
  EXPECT_THAT(Explain(matcher, null), HasSubstr("NULL"));
  Derived derived;
  EXPECT_TRUE(matcher.Matches(&derived));
  EXPECT_THAT(Explain(matcher, &derived), HasSubstr("which points to "));

  // With references, the matcher itself can fail. Test for that one.
  Matcher<const Base&> ref_matcher = WhenDynamicCastTo<const OtherDerived&>(_);
  EXPECT_THAT(Explain(ref_matcher, derived),
              HasSubstr("which cannot be dynamic_cast"));
}

TEST(WhenDynamicCastToTest, GoodReference) {
  Derived derived;
  derived.i = 4;
  Base& as_base_ref = derived;
  EXPECT_THAT(as_base_ref, WhenDynamicCastTo<const Derived&>(FieldIIs(4)));
  EXPECT_THAT(as_base_ref, WhenDynamicCastTo<const Derived&>(Not(FieldIIs(5))));
}

TEST(WhenDynamicCastToTest, BadReference) {
  Derived derived;
  Base& as_base_ref = derived;
  EXPECT_THAT(as_base_ref, Not(WhenDynamicCastTo<const OtherDerived&>(_)));
}
#endif  // GTEST_HAS_RTTI

class DivisibleByImpl {
 public:
  explicit DivisibleByImpl(int a_divider) : divider_(a_divider) {}

  // For testing using ExplainMatchResultTo() with polymorphic matchers.
  template <typename T>
  bool MatchAndExplain(const T& n, MatchResultListener* listener) const {
    *listener << "which is " << (n % divider_) << " modulo " << divider_;
    return (n % divider_) == 0;
  }

  void DescribeTo(ostream* os) const { *os << "is divisible by " << divider_; }

  void DescribeNegationTo(ostream* os) const {
    *os << "is not divisible by " << divider_;
  }

  void set_divider(int a_divider) { divider_ = a_divider; }
  int divider() const { return divider_; }

 private:
  int divider_;
};

PolymorphicMatcher<DivisibleByImpl> DivisibleBy(int n) {
  return MakePolymorphicMatcher(DivisibleByImpl(n));
}

// Tests that when AllOf() fails, only the first failing matcher is
// asked to explain why.
TEST(ExplainMatchResultTest, AllOf_False_False) {
  const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3));
  EXPECT_EQ("which is 1 modulo 4", Explain(m, 5));
}

// Tests that when AllOf() fails, only the first failing matcher is
// asked to explain why.
TEST(ExplainMatchResultTest, AllOf_False_True) {
  const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3));
  EXPECT_EQ("which is 2 modulo 4", Explain(m, 6));
}

// Tests that when AllOf() fails, only the first failing matcher is
// asked to explain why.
TEST(ExplainMatchResultTest, AllOf_True_False) {
  const Matcher<int> m = AllOf(Ge(1), DivisibleBy(3));
  EXPECT_EQ("which is 2 modulo 3", Explain(m, 5));
}

// Tests that when AllOf() succeeds, all matchers are asked to explain
// why.
TEST(ExplainMatchResultTest, AllOf_True_True) {
  const Matcher<int> m = AllOf(DivisibleBy(2), DivisibleBy(3));
  EXPECT_EQ("which is 0 modulo 2, and which is 0 modulo 3", Explain(m, 6));
}

TEST(ExplainMatchResultTest, AllOf_True_True_2) {
  const Matcher<int> m = AllOf(Ge(2), Le(3));
  EXPECT_EQ("", Explain(m, 2));
}

TEST(ExplainmatcherResultTest, MonomorphicMatcher) {
  const Matcher<int> m = GreaterThan(5);
  EXPECT_EQ("which is 1 more than 5", Explain(m, 6));
}

// Tests PolymorphicMatcher::mutable_impl().
TEST(PolymorphicMatcherTest, CanAccessMutableImpl) {
  PolymorphicMatcher<DivisibleByImpl> m(DivisibleByImpl(42));
  DivisibleByImpl& impl = m.mutable_impl();
  EXPECT_EQ(42, impl.divider());

  impl.set_divider(0);
  EXPECT_EQ(0, m.mutable_impl().divider());
}

// Tests PolymorphicMatcher::impl().
TEST(PolymorphicMatcherTest, CanAccessImpl) {
  const PolymorphicMatcher<DivisibleByImpl> m(DivisibleByImpl(42));
  const DivisibleByImpl& impl = m.impl();
  EXPECT_EQ(42, impl.divider());
}

}  // namespace
}  // namespace gmock_matchers_test
}  // namespace testing

#ifdef _MSC_VER
#pragma warning(pop)
#endif


text:
package org.killbill.billing.junction.plumbing.billing;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.UUID;

import javax.annotation.Nullable;

import org.killbill.billing.ObjectType;
import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.account.api.ImmutableAccountData;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.BillingAlignment;
import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.CatalogService;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.StaticCatalog;
import org.killbill.billing.entitlement.api.SubscriptionEventType;
import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
import org.killbill.billing.invoice.api.DryRunArguments;
import org.killbill.billing.junction.BillingEvent;
import org.killbill.billing.junction.BillingEventSet;
import org.killbill.billing.junction.BillingInternalApi;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
import org.killbill.billing.tag.TagInternalApi;
import org.killbill.billing.util.UUIDs;
import org.killbill.billing.util.bcd.BillCycleDayCalculator;
import org.killbill.billing.util.tag.ControlTagType;
import org.killbill.billing.util.tag.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.inject.Inject;

public class DefaultInternalBillingApi implements BillingInternalApi {

    private static final Logger log = LoggerFactory.getLogger(DefaultInternalBillingApi.class);
    private final AccountInternalApi accountApi;
    private final SubscriptionBaseInternalApi subscriptionApi;
    private final CatalogService catalogService;
    private final BlockingCalculator blockCalculator;
    private final TagInternalApi tagApi;

    @Inject
    public DefaultInternalBillingApi(final AccountInternalApi accountApi,
                                     final SubscriptionBaseInternalApi subscriptionApi,
                                     final BlockingCalculator blockCalculator,
                                     final CatalogService catalogService,
                                     final TagInternalApi tagApi) {
        this.accountApi = accountApi;
        this.subscriptionApi = subscriptionApi;
        this.catalogService = catalogService;
        this.blockCalculator = blockCalculator;
        this.tagApi = tagApi;
    }

    @Override
    public BillingEventSet getBillingEventsForAccountAndUpdateAccountBCD(final UUID accountId, final DryRunArguments dryRunArguments, final InternalCallContext context) throws CatalogApiException, AccountApiException, SubscriptionBaseApiException {

        final StaticCatalog currentCatalog = catalogService.getCurrentCatalog(true, true, context);

        // Check to see if billing is off for the account
        final List<Tag> accountTags = tagApi.getTags(accountId, ObjectType.ACCOUNT, context);
        final boolean found_AUTO_INVOICING_OFF = is_AUTO_INVOICING_OFF(accountTags);

        final Set<UUID> skippedSubscriptions = new HashSet<UUID>();
        final DefaultBillingEventSet result;

        if (found_AUTO_INVOICING_OFF) {
            result = new DefaultBillingEventSet(true, currentCatalog.getRecurringBillingMode()); // billing is off, we are done
        } else {
            final List<SubscriptionBaseBundle> bundles = subscriptionApi.getBundlesForAccount(accountId, context);

            final ImmutableAccountData account = accountApi.getImmutableAccountDataById(accountId, context);
            result = new DefaultBillingEventSet(false, currentCatalog.getRecurringBillingMode());
            addBillingEventsForBundles(bundles, account, dryRunArguments, context, result, skippedSubscriptions);
        }

        if (result.isEmpty()) {
            log.info("No billing event for accountId='{}'", accountId);
            return result;
        }

        // Pretty-print the events, before and after the blocking calculator does its magic
        final StringBuilder logStringBuilder = new StringBuilder("Computed billing events for accountId='").append(accountId).append("'");
        eventsToString(logStringBuilder, result);
        if (blockCalculator.insertBlockingEvents(result, skippedSubscriptions, context)) {
            logStringBuilder.append("\nBilling Events After Blocking");
            eventsToString(logStringBuilder, result);
        }
        log.info(logStringBuilder.toString());

        return result;
    }

    private void eventsToString(final StringBuilder stringBuilder, final SortedSet<BillingEvent> events) {
        for (final BillingEvent event : events) {
            stringBuilder.append("\n").append(event.toString());
        }
    }

    private void addBillingEventsForBundles(final List<SubscriptionBaseBundle> bundles, final ImmutableAccountData account, final DryRunArguments dryRunArguments, final InternalCallContext context,
                                            final DefaultBillingEventSet result, final Set<UUID> skipSubscriptionsSet) throws AccountApiException, CatalogApiException, SubscriptionBaseApiException {

        final boolean dryRunMode = dryRunArguments != null;

        // In dryRun mode, when we care about invoice generated for new BASE subscription, no such bundle exists yet; we still
        // want to tap into subscriptionBase logic, so we make up a bundleId
        if (dryRunArguments != null &&
            dryRunArguments.getAction() == SubscriptionEventType.START_BILLING &&
            dryRunArguments.getBundleId() == null) {
            final UUID fakeBundleId = UUIDs.randomUUID();
            final List<SubscriptionBase> subscriptions = subscriptionApi.getSubscriptionsForBundle(fakeBundleId, dryRunArguments, context);

            addBillingEventsForSubscription(account, subscriptions, null, dryRunMode, context, result, skipSubscriptionsSet);

        }

        for (final SubscriptionBaseBundle bundle : bundles) {
            final DryRunArguments dryRunArgumentsForBundle = (dryRunArguments != null &&
                                                              dryRunArguments.getBundleId() != null &&
                                                              dryRunArguments.getBundleId().equals(bundle.getId())) ?
                                                             dryRunArguments : null;
            final List<SubscriptionBase> subscriptions = subscriptionApi.getSubscriptionsForBundle(bundle.getId(), dryRunArgumentsForBundle, context);

            //Check if billing is off for the bundle
            final List<Tag> bundleTags = tagApi.getTags(bundle.getId(), ObjectType.BUNDLE, context);
            boolean found_AUTO_INVOICING_OFF = is_AUTO_INVOICING_OFF(bundleTags);
            if (found_AUTO_INVOICING_OFF) {
                for (final SubscriptionBase subscription : subscriptions) { // billing is off so list sub ids in set to be excluded
                    result.getSubscriptionIdsWithAutoInvoiceOff().add(subscription.getId());
                }
            } else { // billing is not off
                final SubscriptionBase baseSubscription = !subscriptions.isEmpty() ? subscriptions.get(0) : null;
                addBillingEventsForSubscription(account, subscriptions, baseSubscription, dryRunMode, context, result, skipSubscriptionsSet);
            }
        }
    }

    private void addBillingEventsForSubscription(final ImmutableAccountData account,
                                                 final List<SubscriptionBase> subscriptions,
                                                 final SubscriptionBase baseSubscription,
                                                 final boolean dryRunMode,
                                                 final InternalCallContext context,
                                                 final DefaultBillingEventSet result,
                                                 final Set<UUID> skipSubscriptionsSet) throws AccountApiException, CatalogApiException, SubscriptionBaseApiException {

        // If dryRun is specified, we don't want to to update the account BCD value, so we initialize the flag updatedAccountBCD to true
        boolean updatedAccountBCD = dryRunMode;

        final Map<UUID, Integer> bcdCache = new HashMap<UUID, Integer>();

        int currentAccountBCD = accountApi.getBCD(account.getId(), context);

        for (final SubscriptionBase subscription : subscriptions) {

            final List<EffectiveSubscriptionInternalEvent> billingTransitions = subscriptionApi.getBillingTransitions(subscription, context);
            if (billingTransitions.isEmpty() ||
                (billingTransitions.get(0).getTransitionType() != SubscriptionBaseTransitionType.CREATE &&
                 billingTransitions.get(0).getTransitionType() != SubscriptionBaseTransitionType.TRANSFER)) {
                log.warn("Skipping billing events for subscription " + subscription.getId() + ": Does not start with a valid CREATE transition");
                skipSubscriptionsSet.add(subscription.getId());
                return;
            }

            final Catalog catalog = catalogService.getFullCatalog(true, true, context);

            Integer overridenBCD = null;
            for (final EffectiveSubscriptionInternalEvent transition : billingTransitions) {
                //
                // A BCD_CHANGE transition defines a new billCycleDayLocal for the subscription and this overrides whatever computation
                // occurs below (which is based on billing alignment policy). Also multiple of those BCD_CHANGE transitions could occur,
                // to define different intervals with different billing cycle days.
                //
                overridenBCD = transition.getNextBillCycleDayLocal() != null ? transition.getNextBillCycleDayLocal() : overridenBCD;
                final int bcdLocal = overridenBCD != null ?
                                     overridenBCD :
                                     calculateBcdForTransition(catalog, bcdCache, baseSubscription, subscription, currentAccountBCD, transition, context);

                if (currentAccountBCD == 0 && !updatedAccountBCD) {
                    log.info("Setting account BCD='{}', accountId='{}'", bcdLocal, account.getId());
                    accountApi.updateBCD(account.getExternalKey(), bcdLocal, context);
                    updatedAccountBCD = true;
                }

                final BillingEvent event = new DefaultBillingEvent(transition, subscription, bcdLocal, account.getCurrency(), catalog);
                result.add(event);
            }
        }
    }

    private int calculateBcdForTransition(final Catalog catalog, final Map<UUID, Integer> bcdCache, final SubscriptionBase baseSubscription, final SubscriptionBase subscription, final int accountBillCycleDayLocal, final EffectiveSubscriptionInternalEvent transition, final InternalTenantContext internalTenantContext)
            throws CatalogApiException, AccountApiException, SubscriptionBaseApiException {
        final BillingAlignment alignment = catalog.billingAlignment(getPlanPhaseSpecifierFromTransition(catalog, transition), transition.getEffectiveTransitionTime());
        return BillCycleDayCalculator.calculateBcdForAlignment(bcdCache, subscription, baseSubscription, alignment, internalTenantContext, accountBillCycleDayLocal);
    }

    private PlanPhaseSpecifier getPlanPhaseSpecifierFromTransition(final Catalog catalog, final EffectiveSubscriptionInternalEvent transition) throws CatalogApiException {
        final Plan prevPlan = (transition.getPreviousPlan() != null) ? catalog.findPlan(transition.getPreviousPlan(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
        final Plan nextPlan = (transition.getNextPlan() != null) ? catalog.findPlan(transition.getNextPlan(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;

        final Plan plan = (transition.getTransitionType() != SubscriptionBaseTransitionType.CANCEL) ? nextPlan : prevPlan;

        final PlanPhase prevPhase = (transition.getPreviousPhase() != null) ? catalog.findPhase(transition.getPreviousPhase(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
        final PlanPhase nextPhase = (transition.getNextPhase() != null) ? catalog.findPhase(transition.getNextPhase(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
        final PlanPhase phase = (transition.getTransitionType() != SubscriptionBaseTransitionType.CANCEL) ? nextPhase : prevPhase;

        return new PlanPhaseSpecifier(plan.getName(), phase.getPhaseType());

    }

    private boolean is_AUTO_INVOICING_OFF(final List<Tag> tags) {
        return ControlTagType.isAutoInvoicingOff(Collections2.transform(tags, new Function<Tag, UUID>() {
            @Nullable
            @Override
            public UUID apply(@Nullable final Tag tag) {
                return tag.getTagDefinitionId();
            }
        }));
    }
}

redpajama_set_name: RedPajamaGithub


text:
layout: default
ref: aboutus
lang: en
---
## Who are we?

{::options parse_block_html="true" /}

The Slavonic Computing Initiative brings together volunteers who are interested in Church Slavonic
and dedicated to the philosophy of standards compliance and free and open source software.
The project depends entirely on the work of volunteers like you.

### Active Project Members

* [Aleksandr Andreev](https://orthodoxtheologicalschool.academia.edu/AleksandrAndreev).
  PhD in Theology, Associate Professor of Classical Languages at St. Petersburg Theological Academy, also part of the [Ponomar Project](https://www.ponomar.net/)

* [Mike Kroutikov](https://github.com/pgmmpk). Software developer and Church Slavonic enthusiast.

* Nikita Simmons. Independent researcher, musicologist and font designer,
  also part of the [Synaxis.info project](http://www.synaxis.info/).

If you share our passion for Church Slavonic, join us!

### Ongoing Projects

Here are some projects that we are working on right now:

* [Design of Unicode-compliant fonts for Znamenny Notation](music.html)

* Adding more features to the [cu-tex package](https://github.com/slavonic/cu-tex).

* Developing Church Slavonic spell checking for [Hunspell](https://hunspell.github.io/),
which can be used in LibreOffice, Mozilla Firefox, and other applications.

* Developing Church Slavonic OCR (optical character recognition) using the
[Tesseract software](https://github.com/tesseract-ocr/tesseract).

* Digitizing [even more Church Slavonic liturgical books](http://minei.ru/minea/advanced).

[Contact us](https://www.ponomar.net/mailman/listinfo/sci-users_ponomar.net)
to join the Slavonic Computing Initiative.

![Sample Slavonic](https://www.ponomar.net/images/sample_page.png)
{: .featurette-image }


text:
package edu.utdallas.netsec.sfts.packets;

import edu.utdallas.netsec.sfts.crypt.RandomUtils;
import org.testng.Assert;
import org.testng.annotations.Test;

/**
 * @author Fahad Shaon
 */
public class MasterServerTicketTest {

    @Test
    public void testEncodeDecode() throws Exception {

        MasterServerTicket masterServerTicket = new MasterServerTicket();
        masterServerTicket.clientName = "First client";
        masterServerTicket.departServer = "finance";
        masterServerTicket.sessionKeyClientMaster = RandomUtils.getSecureRandomBytes(64);
        masterServerTicket.sessionKeyMasterDepartment = RandomUtils.getSecureRandomBytes(64);

        DepartmentServerTicket dst = new DepartmentServerTicket();

        dst.clientName = "First Client";
        dst.sessionKeyClientDepartment = RandomUtils.getSecureRandomBytes(64);
        dst.sessionKeyMasterDepartment = RandomUtils.getSecureRandomBytes(64);
        dst.nonce = RandomUtils.getSecureRandomBytes(8);

        byte[] encodedDST = dst.encode();

        masterServerTicket.departmentServerToken = encodedDST;
        masterServerTicket.nonce = RandomUtils.getSecureRandomBytes(8);

        byte[] encoded = masterServerTicket.encode();

        MasterServerTicket masterServerTicketDecoded = new MasterServerTicket();
        masterServerTicketDecoded.decode(encoded);

        Assert.assertEquals(masterServerTicketDecoded.clientName, masterServerTicket.clientName);
        Assert.assertEquals(masterServerTicketDecoded.departServer, masterServerTicket.departServer);
        Assert.assertEquals(masterServerTicketDecoded.sessionKeyClientMaster, masterServerTicket.sessionKeyClientMaster);
        Assert.assertEquals(masterServerTicketDecoded.sessionKeyMasterDepartment, masterServerTicket.sessionKeyMasterDepartment);
        Assert.assertEquals(masterServerTicketDecoded.departmentServerToken, masterServerTicket.departmentServerToken);
        Assert.assertEquals(masterServerTicketDecoded.departmentServerToken, encodedDST);
        Assert.assertEquals(masterServerTicketDecoded.nonce, masterServerTicket.nonce);

        System.out.println("Master Server Ticket Size: " + encoded.length);
    }
}


text:
package ru.frostman.web.dispatch.url;

/**
 * @author slukjanov aka Frostman
 */
public interface UrlPattern {
    boolean matches(String url);

    UrlPatternType getType();
}


text:
void getPointsFromBezier(void *info, const CGPathElement *element);
NSArray *pointsFromBezierPath(UIBezierPath *bpath);

#define VALUE(_INDEX_) [NSValue valueWithCGPoint:points[_INDEX_]]
#define POINT(_INDEX_) [(NSValue *)[points objectAtIndex:_INDEX_] CGPointValue]

@implementation UIBezierPath (Smoothing)

// Get points from Bezier Curve
void getPointsFromBezier(void *info, const CGPathElement *element)
{
    NSMutableArray *bezierPoints = (__bridge NSMutableArray *)info;

    // Retrieve the path element type and its points
    CGPathElementType type = element->type;
    CGPoint *points = element->points;

    // Add the points if they're available (per type)
    if (type != kCGPathElementCloseSubpath)
    {
        [bezierPoints addObject:VALUE(0)];
        if ((type != kCGPathElementAddLineToPoint) &&
            (type != kCGPathElementMoveToPoint))
            [bezierPoints addObject:VALUE(1)];
    }
    if (type == kCGPathElementAddCurveToPoint)
        [bezierPoints addObject:VALUE(2)];
}

NSArray *pointsFromBezierPath(UIBezierPath *bpath)
{
    NSMutableArray *points = [NSMutableArray array];
    CGPathApply(bpath.CGPath, (__bridge void *)points, getPointsFromBezier);
    return points;
}

- (UIBezierPath*)smoothedPathWithGranularity:(NSInteger)granularity minY:(CGFloat)minY maxY:(CGFloat)maxY
{

    NSMutableArray *points = [pointsFromBezierPath(self) mutableCopy];

    if (points.count < 4) return [self copy];

    // Add control points to make the math make sense
    [points insertObject:[points objectAtIndex:0] atIndex:0];
    [points addObject:[points lastObject]];

    UIBezierPath *smoothedPath = [self copy];
    [smoothedPath removeAllPoints];

    [smoothedPath moveToPoint:POINT(0)];

    for (NSUInteger index = 1; index < points.count - 2; index++)
    {
        CGPoint p0 = POINT(index - 1);
        CGPoint p1 = POINT(index);
        CGPoint p2 = POINT(index + 1);
        CGPoint p3 = POINT(index + 2);

        // now add n points starting at p1 + dx/dy up until p2 using Catmull-Rom splines
        for (int i = 1; i < granularity; i++)
        {
            float t = (float) i * (1.0f / (float) granularity);
            float tt = t * t;
            float ttt = tt * t;

            CGPoint pi; // intermediate point
            pi.x = 0.5 * (2*p1.x+(p2.x-p0.x)*t + (2*p0.x-5*p1.x+4*p2.x-p3.x)*tt + (3*p1.x-p0.x-3*p2.x+p3.x)*ttt);
            pi.y = 0.5 * (2*p1.y+(p2.y-p0.y)*t + (2*p0.y-5*p1.y+4*p2.y-p3.y)*tt + (3*p1.y-p0.y-3*p2.y+p3.y)*ttt);

            if(pi.y > maxY){

                pi.y = maxY;
            }
            else if(pi.y < minY){

                pi.y = minY;
            }

            if(pi.x > p0.x){

                [smoothedPath addLineToPoint:pi];
            }
        }

        // Now add p2
        [smoothedPath addLineToPoint:p2];
    }

    // finish by adding the last point
    [smoothedPath addLineToPoint:POINT(points.count - 1)];

    return smoothedPath;
}

@end


text:
public_vmodl_filename = ARGV[0] or abort "public vmodl filename required"
internal_vmodl_filename = ARGV[1] or abort "internal vmodl filename required"
output_vmodl_filename = ARGV[2] or abort "output vmodl filename required"

public_vmodl = File.open(public_vmodl_filename, 'r') { |io| Marshal.load io }
internal_vmodl = File.open(internal_vmodl_filename, 'r') { |io| Marshal.load io }

db = {}
tn = {}
public_vmodl.each do |k,v|
  unless k == '_typenames'
    db[k] = v
  else
    tn['_typenames'] = v
  end
end

internal_vmodl.each do |k, v|
  unless k == '_typenames'
    db[k] = v unless db[k]
  else
    tn['_typenames'] = tn['_typenames'] + v
  end
end

db['_typenames'] = tn

File.open(output_vmodl_filename, 'w') { |io| Marshal.dump db, io }


text:
package org.apache.phoenix.expression.function;

import java.sql.SQLException;
import java.util.List;

import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.phoenix.cache.JodaTimezoneCache;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.parse.FunctionParseNode;
import org.apache.phoenix.schema.tuple.Tuple;
import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.schema.types.PDate;
import org.apache.phoenix.schema.types.PInteger;
import org.apache.phoenix.schema.types.PVarchar;
import org.joda.time.DateTimeZone;

/**
 * Returns offset (shift in minutes) of timezone at particular datetime in minutes.
 */
@FunctionParseNode.BuiltInFunction(name = TimezoneOffsetFunction.NAME, args = {
    @FunctionParseNode.Argument(allowedTypes = {PVarchar.class}),
    @FunctionParseNode.Argument(allowedTypes = {PDate.class})})
public class TimezoneOffsetFunction extends ScalarFunction {

    public static final String NAME = "TIMEZONE_OFFSET";
    private static final int MILLIS_TO_MINUTES = 60 * 1000;

    public TimezoneOffsetFunction() {
    }

    public TimezoneOffsetFunction(List<Expression> children) throws SQLException {
        super(children);
    }

    @Override
    public String getName() {
        return NAME;
    }

    @Override
    public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
        if (!children.get(0).evaluate(tuple, ptr)) {
            return false;
        }
        if (ptr.getLength() == 0) {
            return true;
        }
        DateTimeZone timezoneInstance = JodaTimezoneCache.getInstance(ptr);

        if (!children.get(1).evaluate(tuple, ptr)) {
            return false;
        }
        if (ptr.getLength() == 0) {
            return true;
        }
        long date = PDate.INSTANCE.getCodec().decodeLong(ptr, children.get(1).getSortOrder());

        int offset = timezoneInstance.getOffset(date);
        ptr.set(PInteger.INSTANCE.toBytes(offset / MILLIS_TO_MINUTES));
        return true;
    }

    @Override
    public PDataType getDataType() {
        return PInteger.INSTANCE;
    }

	@Override
    public boolean isNullable() {
        return children.get(0).isNullable() || children.get(1).isNullable();
    }

}