// Copyright 2008, 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.

#include "gmock/gmock-nice-strict.h"

#include <string>
#include <utility>

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

// This must not be defined inside the ::testing namespace, or it will
// clash with ::testing::Mock.
class Mock {
 public:
  Mock() = default;

  MOCK_METHOD0(DoThis, void());

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

namespace testing {
namespace gmock_nice_strict_test {

using testing::HasSubstr;
using testing::NaggyMock;
using testing::NiceMock;
using testing::StrictMock;

#if GTEST_HAS_STREAM_REDIRECTION
using testing::internal::CaptureStdout;
using testing::internal::GetCapturedStdout;
#endif

// Class without default constructor.
class NotDefaultConstructible {
 public:
  explicit NotDefaultConstructible(int) {}
};

class CallsMockMethodInDestructor {
 public:
  ~CallsMockMethodInDestructor() { OnDestroy(); }
  MOCK_METHOD(void, OnDestroy, ());
};

// Defines some mock classes needed by the tests.

class Foo {
 public:
  virtual ~Foo() = default;

  virtual void DoThis() = 0;
  virtual int DoThat(bool flag) = 0;
};

class MockFoo : public Foo {
 public:
  MockFoo() = default;
  void Delete() { delete this; }

  MOCK_METHOD0(DoThis, void());
  MOCK_METHOD1(DoThat, int(bool flag));
  MOCK_METHOD0(ReturnNonDefaultConstructible, NotDefaultConstructible());

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

class MockBar {
 public:
  explicit MockBar(const std::string& s) : str_(s) {}

  MockBar(char a1, char a2, std::string a3, std::string a4, int a5, int a6,
          const std::string& a7, const std::string& a8, bool a9, bool a10) {
    str_ = std::string() + a1 + a2 + a3 + a4 + static_cast<char>(a5) +
           static_cast<char>(a6) + a7 + a8 + (a9 ? 'T' : 'F') +
           (a10 ? 'T' : 'F');
  }

  virtual ~MockBar() = default;

  const std::string& str() const { return str_; }

  MOCK_METHOD0(This, int());
  MOCK_METHOD2(That, std::string(int, bool));

 private:
  std::string str_;

  MockBar(const MockBar&) = delete;
  MockBar& operator=(const MockBar&) = delete;
};

class MockBaz {
 public:
  class MoveOnly {
   public:
    MoveOnly() = default;

    MoveOnly(const MoveOnly&) = delete;
    MoveOnly& operator=(const MoveOnly&) = delete;

    MoveOnly(MoveOnly&&) = default;
    MoveOnly& operator=(MoveOnly&&) = default;
  };

  MockBaz(MoveOnly) {}
};

#if GTEST_HAS_STREAM_REDIRECTION

// Tests that a raw mock generates warnings for uninteresting calls.
TEST(RawMockTest, WarningForUninterestingCall) {
  const std::string saved_flag = GMOCK_FLAG_GET(verbose);
  GMOCK_FLAG_SET(verbose, "warning");

  MockFoo raw_foo;

  CaptureStdout();
  raw_foo.DoThis();
  raw_foo.DoThat(true);
  EXPECT_THAT(GetCapturedStdout(),
              HasSubstr("Uninteresting mock function call"));

  GMOCK_FLAG_SET(verbose, saved_flag);
}

// Tests that a raw mock generates warnings for uninteresting calls
// that delete the mock object.
TEST(RawMockTest, WarningForUninterestingCallAfterDeath) {
  const std::string saved_flag = GMOCK_FLAG_GET(verbose);
  GMOCK_FLAG_SET(verbose, "warning");

  MockFoo* const raw_foo = new MockFoo;

  ON_CALL(*raw_foo, DoThis()).WillByDefault(Invoke(raw_foo, &MockFoo::Delete));

  CaptureStdout();
  raw_foo->DoThis();
  EXPECT_THAT(GetCapturedStdout(),
              HasSubstr("Uninteresting mock function call"));

  GMOCK_FLAG_SET(verbose, saved_flag);
}

// Tests that a raw mock generates informational logs for
// uninteresting calls.
TEST(RawMockTest, InfoForUninterestingCall) {
  MockFoo raw_foo;

  const std::string saved_flag = GMOCK_FLAG_GET(verbose);
  GMOCK_FLAG_SET(verbose, "info");
  CaptureStdout();
  raw_foo.DoThis();
  EXPECT_THAT(GetCapturedStdout(),
              HasSubstr("Uninteresting mock function call"));

  GMOCK_FLAG_SET(verbose, saved_flag);
}

TEST(RawMockTest, IsNaggy_IsNice_IsStrict) {
  MockFoo raw_foo;
  EXPECT_TRUE(Mock::IsNaggy(&raw_foo));
  EXPECT_FALSE(Mock::IsNice(&raw_foo));
  EXPECT_FALSE(Mock::IsStrict(&raw_foo));
}

// Tests that a nice mock generates no warning for uninteresting calls.
TEST(NiceMockTest, NoWarningForUninterestingCall) {
  NiceMock<MockFoo> nice_foo;

  CaptureStdout();
  nice_foo.DoThis();
  nice_foo.DoThat(true);
  EXPECT_EQ("", GetCapturedStdout());
}

// Tests that a nice mock generates no warning for uninteresting calls
// that delete the mock object.
TEST(NiceMockTest, NoWarningForUninterestingCallAfterDeath) {
  NiceMock<MockFoo>* const nice_foo = new NiceMock<MockFoo>;

  ON_CALL(*nice_foo, DoThis())
      .WillByDefault(Invoke(nice_foo, &MockFoo::Delete));

  CaptureStdout();
  nice_foo->DoThis();
  EXPECT_EQ("", GetCapturedStdout());
}

// Tests that a nice mock generates informational logs for
// uninteresting calls.
TEST(NiceMockTest, InfoForUninterestingCall) {
  NiceMock<MockFoo> nice_foo;

  const std::string saved_flag = GMOCK_FLAG_GET(verbose);
  GMOCK_FLAG_SET(verbose, "info");
  CaptureStdout();
  nice_foo.DoThis();
  EXPECT_THAT(GetCapturedStdout(),
              HasSubstr("Uninteresting mock function call"));

  GMOCK_FLAG_SET(verbose, saved_flag);
}

#endif  // GTEST_HAS_STREAM_REDIRECTION

// Tests that a nice mock allows expected calls.
TEST(NiceMockTest, AllowsExpectedCall) {
  NiceMock<MockFoo> nice_foo;

  EXPECT_CALL(nice_foo, DoThis());
  nice_foo.DoThis();
}

// Tests that an unexpected call on a nice mock which returns a
// not-default-constructible type throws an exception and the exception contains
// the method's name.
TEST(NiceMockTest, ThrowsExceptionForUnknownReturnTypes) {
  NiceMock<MockFoo> nice_foo;
#if GTEST_HAS_EXCEPTIONS
  try {
    nice_foo.ReturnNonDefaultConstructible();
    FAIL();
  } catch (const std::runtime_error& ex) {
    EXPECT_THAT(ex.what(), HasSubstr("ReturnNonDefaultConstructible"));
  }
#else
  EXPECT_DEATH_IF_SUPPORTED({ nice_foo.ReturnNonDefaultConstructible(); }, "");
#endif
}

// Tests that an unexpected call on a nice mock fails.
TEST(NiceMockTest, UnexpectedCallFails) {
  NiceMock<MockFoo> nice_foo;

  EXPECT_CALL(nice_foo, DoThis()).Times(0);
  EXPECT_NONFATAL_FAILURE(nice_foo.DoThis(), "called more times than expected");
}

// Tests that NiceMock works with a mock class that has a non-default
// constructor.
TEST(NiceMockTest, NonDefaultConstructor) {
  NiceMock<MockBar> nice_bar("hi");
  EXPECT_EQ("hi", nice_bar.str());

  nice_bar.This();
  nice_bar.That(5, true);
}

// Tests that NiceMock works with a mock class that has a 10-ary
// non-default constructor.
TEST(NiceMockTest, NonDefaultConstructor10) {
  NiceMock<MockBar> nice_bar('a', 'b', "c", "d", 'e', 'f', "g", "h", true,
                             false);
  EXPECT_EQ("abcdefghTF", nice_bar.str());

  nice_bar.This();
  nice_bar.That(5, true);
}

TEST(NiceMockTest, AllowLeak) {
  NiceMock<MockFoo>* leaked = new NiceMock<MockFoo>;
  Mock::AllowLeak(leaked);
  EXPECT_CALL(*leaked, DoThis());
  leaked->DoThis();
}

TEST(NiceMockTest, MoveOnlyConstructor) {
  NiceMock<MockBaz> nice_baz(MockBaz::MoveOnly{});
}

// Tests that NiceMock<Mock> compiles where Mock is a user-defined
// class (as opposed to ::testing::Mock).
TEST(NiceMockTest, AcceptsClassNamedMock) {
  NiceMock< ::Mock> nice;
  EXPECT_CALL(nice, DoThis());
  nice.DoThis();
}

TEST(NiceMockTest, IsNiceInDestructor) {
  {
    NiceMock<CallsMockMethodInDestructor> nice_on_destroy;
    // Don't add an expectation for the call before the mock goes out of scope.
  }
}

TEST(NiceMockTest, IsNaggy_IsNice_IsStrict) {
  NiceMock<MockFoo> nice_foo;
  EXPECT_FALSE(Mock::IsNaggy(&nice_foo));
  EXPECT_TRUE(Mock::IsNice(&nice_foo));
  EXPECT_FALSE(Mock::IsStrict(&nice_foo));
}

#if GTEST_HAS_STREAM_REDIRECTION

// Tests that a naggy mock generates warnings for uninteresting calls.
TEST(NaggyMockTest, WarningForUninterestingCall) {
  const std::string saved_flag = GMOCK_FLAG_GET(verbose);
  GMOCK_FLAG_SET(verbose, "warning");

  NaggyMock<MockFoo> naggy_foo;

  CaptureStdout();
  naggy_foo.DoThis();
  naggy_foo.DoThat(true);
  EXPECT_THAT(GetCapturedStdout(),
              HasSubstr("Uninteresting mock function call"));

  GMOCK_FLAG_SET(verbose, saved_flag);
}

// Tests that a naggy mock generates a warning for an uninteresting call
// that deletes the mock object.
TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) {
  const std::string saved_flag = GMOCK_FLAG_GET(verbose);
  GMOCK_FLAG_SET(verbose, "warning");

  NaggyMock<MockFoo>* const naggy_foo = new NaggyMock<MockFoo>;

  ON_CALL(*naggy_foo, DoThis())
      .WillByDefault(Invoke(naggy_foo, &MockFoo::Delete));

  CaptureStdout();
  naggy_foo->DoThis();
  EXPECT_THAT(GetCapturedStdout(),
              HasSubstr("Uninteresting mock function call"));

  GMOCK_FLAG_SET(verbose, saved_flag);
}

#endif  // GTEST_HAS_STREAM_REDIRECTION

// Tests that a naggy mock allows expected calls.
TEST(NaggyMockTest, AllowsExpectedCall) {
  NaggyMock<MockFoo> naggy_foo;

  EXPECT_CALL(naggy_foo, DoThis());
  naggy_foo.DoThis();
}

// Tests that an unexpected call on a naggy mock fails.
TEST(NaggyMockTest, UnexpectedCallFails) {
  NaggyMock<MockFoo> naggy_foo;

  EXPECT_CALL(naggy_foo, DoThis()).Times(0);
  EXPECT_NONFATAL_FAILURE(naggy_foo.DoThis(),
                          "called more times than expected");
}

// Tests that NaggyMock works with a mock class that has a non-default
// constructor.
TEST(NaggyMockTest, NonDefaultConstructor) {
  NaggyMock<MockBar> naggy_bar("hi");
  EXPECT_EQ("hi", naggy_bar.str());

  naggy_bar.This();
  naggy_bar.That(5, true);
}

// Tests that NaggyMock works with a mock class that has a 10-ary
// non-default constructor.
TEST(NaggyMockTest, NonDefaultConstructor10) {
  NaggyMock<MockBar> naggy_bar('0', '1', "2", "3", '4', '5', "6", "7", true,
                               false);
  EXPECT_EQ("01234567TF", naggy_bar.str());

  naggy_bar.This();
  naggy_bar.That(5, true);
}

TEST(NaggyMockTest, AllowLeak) {
  NaggyMock<MockFoo>* leaked = new NaggyMock<MockFoo>;
  Mock::AllowLeak(leaked);
  EXPECT_CALL(*leaked, DoThis());
  leaked->DoThis();
}

TEST(NaggyMockTest, MoveOnlyConstructor) {
  NaggyMock<MockBaz> naggy_baz(MockBaz::MoveOnly{});
}

// Tests that NaggyMock<Mock> compiles where Mock is a user-defined
// class (as opposed to ::testing::Mock).
TEST(NaggyMockTest, AcceptsClassNamedMock) {
  NaggyMock< ::Mock> naggy;
  EXPECT_CALL(naggy, DoThis());
  naggy.DoThis();
}

TEST(NaggyMockTest, IsNaggyInDestructor) {
  const std::string saved_flag = GMOCK_FLAG_GET(verbose);
  GMOCK_FLAG_SET(verbose, "warning");
  CaptureStdout();

  {
    NaggyMock<CallsMockMethodInDestructor> naggy_on_destroy;
    // Don't add an expectation for the call before the mock goes out of scope.
  }

  EXPECT_THAT(GetCapturedStdout(),
              HasSubstr("Uninteresting mock function call"));

  GMOCK_FLAG_SET(verbose, saved_flag);
}

TEST(NaggyMockTest, IsNaggy_IsNice_IsStrict) {
  NaggyMock<MockFoo> naggy_foo;
  EXPECT_TRUE(Mock::IsNaggy(&naggy_foo));
  EXPECT_FALSE(Mock::IsNice(&naggy_foo));
  EXPECT_FALSE(Mock::IsStrict(&naggy_foo));
}

// Tests that a strict mock allows expected calls.
TEST(StrictMockTest, AllowsExpectedCall) {
  StrictMock<MockFoo> strict_foo;

  EXPECT_CALL(strict_foo, DoThis());
  strict_foo.DoThis();
}

// Tests that an unexpected call on a strict mock fails.
TEST(StrictMockTest, UnexpectedCallFails) {
  StrictMock<MockFoo> strict_foo;

  EXPECT_CALL(strict_foo, DoThis()).Times(0);
  EXPECT_NONFATAL_FAILURE(strict_foo.DoThis(),
                          "called more times than expected");
}

// Tests that an uninteresting call on a strict mock fails.
TEST(StrictMockTest, UninterestingCallFails) {
  StrictMock<MockFoo> strict_foo;

  EXPECT_NONFATAL_FAILURE(strict_foo.DoThis(),
                          "Uninteresting mock function call");
}

// Tests that an uninteresting call on a strict mock fails, even if
// the call deletes the mock object.
TEST(StrictMockTest, UninterestingCallFailsAfterDeath) {
  StrictMock<MockFoo>* const strict_foo = new StrictMock<MockFoo>;

  ON_CALL(*strict_foo, DoThis())
      .WillByDefault(Invoke(strict_foo, &MockFoo::Delete));

  EXPECT_NONFATAL_FAILURE(strict_foo->DoThis(),
                          "Uninteresting mock function call");
}

// Tests that StrictMock works with a mock class that has a
// non-default constructor.
TEST(StrictMockTest, NonDefaultConstructor) {
  StrictMock<MockBar> strict_bar("hi");
  EXPECT_EQ("hi", strict_bar.str());

  EXPECT_NONFATAL_FAILURE(strict_bar.That(5, true),
                          "Uninteresting mock function call");
}

// Tests that StrictMock works with a mock class that has a 10-ary
// non-default constructor.
TEST(StrictMockTest, NonDefaultConstructor10) {
  StrictMock<MockBar> strict_bar('a', 'b', "c", "d", 'e', 'f', "g", "h", true,
                                 false);
  EXPECT_EQ("abcdefghTF", strict_bar.str());

  EXPECT_NONFATAL_FAILURE(strict_bar.That(5, true),
                          "Uninteresting mock function call");
}

TEST(StrictMockTest, AllowLeak) {
  StrictMock<MockFoo>* leaked = new StrictMock<MockFoo>;
  Mock::AllowLeak(leaked);
  EXPECT_CALL(*leaked, DoThis());
  leaked->DoThis();
}

TEST(StrictMockTest, MoveOnlyConstructor) {
  StrictMock<MockBaz> strict_baz(MockBaz::MoveOnly{});
}

// Tests that StrictMock<Mock> compiles where Mock is a user-defined
// class (as opposed to ::testing::Mock).
TEST(StrictMockTest, AcceptsClassNamedMock) {
  StrictMock< ::Mock> strict;
  EXPECT_CALL(strict, DoThis());
  strict.DoThis();
}

TEST(StrictMockTest, IsStrictInDestructor) {
  EXPECT_NONFATAL_FAILURE(
      {
        StrictMock<CallsMockMethodInDestructor> strict_on_destroy;
        // Don't add an expectation for the call before the mock goes out of
        // scope.
      },
      "Uninteresting mock function call");
}

TEST(StrictMockTest, IsNaggy_IsNice_IsStrict) {
  StrictMock<MockFoo> strict_foo;
  EXPECT_FALSE(Mock::IsNaggy(&strict_foo));
  EXPECT_FALSE(Mock::IsNice(&strict_foo));
  EXPECT_TRUE(Mock::IsStrict(&strict_foo));
}

}  // namespace gmock_nice_strict_test
}  // namespace testing
