// 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.

#ifndef GOOGLEMOCK_TEST_GMOCK_MATCHERS_TEST_H_
#define GOOGLEMOCK_TEST_GMOCK_MATCHERS_TEST_H_

#include <string.h>
#include <time.h>

#include <array>
#include <cstdint>
#include <deque>
#include <forward_list>
#include <functional>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#include "gmock/gmock-matchers.h"
#include "gmock/gmock-more-matchers.h"
#include "gmock/gmock.h"
#include "gtest/gtest-spi.h"
#include "gtest/gtest.h"

namespace testing {
namespace gmock_matchers_test {

using std::greater;
using std::less;
using std::list;
using std::make_pair;
using std::map;
using std::multimap;
using std::multiset;
using std::ostream;
using std::pair;
using std::set;
using std::stringstream;
using std::vector;
using testing::internal::DummyMatchResultListener;
using testing::internal::ElementMatcherPair;
using testing::internal::ElementMatcherPairs;
using testing::internal::ElementsAreArrayMatcher;
using testing::internal::ExplainMatchFailureTupleTo;
using testing::internal::FloatingEqMatcher;
using testing::internal::FormatMatcherDescription;
using testing::internal::IsReadableTypeName;
using testing::internal::MatchMatrix;
using testing::internal::PredicateFormatterFromMatcher;
using testing::internal::RE;
using testing::internal::StreamMatchResultListener;
using testing::internal::Strings;

// Helper for testing container-valued matchers in mock method context. It is
// important to test matchers in this context, since it requires additional type
// deduction beyond what EXPECT_THAT does, thus making it more restrictive.
struct ContainerHelper {
  MOCK_METHOD1(Call, void(std::vector<std::unique_ptr<int>>));
};

// For testing ExplainMatchResultTo().
template <typename T>
struct GtestGreaterThanMatcher {
  using is_gtest_matcher = void;

  void DescribeTo(ostream* os) const { *os << "is > " << rhs; }
  void DescribeNegationTo(ostream* os) const { *os << "is <= " << rhs; }

  bool MatchAndExplain(T lhs, MatchResultListener* listener) const {
    if (lhs > rhs) {
      *listener << "which is " << (lhs - rhs) << " more than " << rhs;
    } else if (lhs == rhs) {
      *listener << "which is the same as " << rhs;
    } else {
      *listener << "which is " << (rhs - lhs) << " less than " << rhs;
    }

    return lhs > rhs;
  }

  T rhs;
};

template <typename T>
GtestGreaterThanMatcher<typename std::decay<T>::type> GtestGreaterThan(
    T&& rhs) {
  return {rhs};
}

// As the matcher above, but using the base class with virtual functions.
template <typename T>
class GreaterThanMatcher : public MatcherInterface<T> {
 public:
  explicit GreaterThanMatcher(T rhs) : impl_{rhs} {}

  void DescribeTo(ostream* os) const override { impl_.DescribeTo(os); }
  void DescribeNegationTo(ostream* os) const override {
    impl_.DescribeNegationTo(os);
  }

  bool MatchAndExplain(T lhs, MatchResultListener* listener) const override {
    return impl_.MatchAndExplain(lhs, listener);
  }

 private:
  const GtestGreaterThanMatcher<T> impl_;
};

// Names and instantiates a new instance of GTestMatcherTestP.
#define INSTANTIATE_GTEST_MATCHER_TEST_P(TestSuite)                         \
  using TestSuite##P = GTestMatcherTestP;                                   \
  INSTANTIATE_TEST_SUITE_P(MatcherInterface, TestSuite##P, Values(false));  \
  INSTANTIATE_TEST_SUITE_P(GtestMatcher, TestSuite##P, Values(true))

class GTestMatcherTestP : public testing::TestWithParam<bool> {
 public:
  template <typename T>
  Matcher<T> GreaterThan(T n) {
    if (use_gtest_matcher_) {
      return GtestGreaterThan(n);
    } else {
      return MakeMatcher(new GreaterThanMatcher<T>(n));
    }
  }
  const bool use_gtest_matcher_ = GetParam();
};

// Returns the description of the given matcher.
template <typename T>
std::string Describe(const Matcher<T>& m) {
  return DescribeMatcher<T>(m);
}

// Returns the description of the negation of the given matcher.
template <typename T>
std::string DescribeNegation(const Matcher<T>& m) {
  return DescribeMatcher<T>(m, true);
}

// Returns the reason why x matches, or doesn't match, m.
template <typename MatcherType, typename Value>
std::string Explain(const MatcherType& m, const Value& x) {
  StringMatchResultListener listener;
  ExplainMatchResult(m, x, &listener);
  return listener.str();
}

}  // namespace gmock_matchers_test
}  // namespace testing

#endif  // GOOGLEMOCK_TEST_GMOCK_MATCHERS_TEST_H_
