// Copyright (c) 2022, 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.
//
// Author: Zhanyong Wan

// Tests the ScopedMockLog class.

#include "mock-log.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <string>

namespace {

using google::GLOG_ERROR;
using google::GLOG_INFO;
using google::GLOG_WARNING;
using google::glog_testing::ScopedMockLog;
using std::string;
using testing::_;
using testing::EndsWith;
using testing::InSequence;
using testing::InvokeWithoutArgs;

// Tests that ScopedMockLog intercepts LOG()s when it's alive.
TEST(ScopedMockLogTest, InterceptsLog) {
  ScopedMockLog log;

  InSequence s;
  EXPECT_CALL(log,
              Log(GLOG_WARNING, EndsWith("mock-log_unittest.cc"), "Fishy."));
  EXPECT_CALL(log, Log(GLOG_INFO, _, "Working...")).Times(2);
  EXPECT_CALL(log, Log(GLOG_ERROR, _, "Bad!!"));

  LOG(WARNING) << "Fishy.";
  LOG(INFO) << "Working...";
  LOG(INFO) << "Working...";
  LOG(ERROR) << "Bad!!";
}

void LogBranch() { LOG(INFO) << "Logging a branch..."; }

void LogTree() { LOG(INFO) << "Logging the whole tree..."; }

void LogForest() {
  LOG(INFO) << "Logging the entire forest.";
  LOG(INFO) << "Logging the entire forest..";
  LOG(INFO) << "Logging the entire forest...";
}

// The purpose of the following test is to verify that intercepting logging
// continues to work properly if a LOG statement is executed within the scope
// of a mocked call.
TEST(ScopedMockLogTest, LogDuringIntercept) {
  ScopedMockLog log;
  InSequence s;
  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging a branch..."))
      .WillOnce(InvokeWithoutArgs(LogTree));
  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the whole tree..."))
      .WillOnce(InvokeWithoutArgs(LogForest));
  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the entire forest."));
  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the entire forest.."));
  EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the entire forest..."));
  LogBranch();
}

}  // namespace

int main(int argc, char** argv) {
  google::InitGoogleLogging(argv[0]);
  testing::InitGoogleTest(&argc, argv);
  testing::InitGoogleMock(&argc, argv);

  return RUN_ALL_TESTS();
}
