// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "base/stringprintf.h"
#include "cobalt/bindings/testing/bindings_test_base.h"
#include "cobalt/bindings/testing/exception_object_interface.h"
#include "cobalt/bindings/testing/exceptions_interface.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::DoAll;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::NiceMock;
using ::testing::WithArg;

#define EXPECT_SUBSTRING(needle, haystack) \
  EXPECT_PRED_FORMAT2(::testing::IsSubstring, (needle), (haystack))

namespace cobalt {
namespace bindings {
namespace testing {
namespace {
typedef InterfaceBindingsTest<ExceptionsInterface> ExceptionsBindingsTest;

class SimpleExceptionSetter {
 public:
  explicit SimpleExceptionSetter(script::MessageType type) : type_(type) {}
  void FireException(script::ExceptionState* exception) {
    exception->SetSimpleException(type_);
  }

 private:
  script::MessageType type_;
};

class ExceptionObjectSetter {
 public:
  explicit ExceptionObjectSetter(
      const scoped_refptr<ExceptionObjectInterface>& exception)
      : exception_object_(exception) {}
  void FireException(script::ExceptionState* exception) {
    exception->SetException(exception_object_);
  }

 private:
  scoped_refptr<script::ScriptException> exception_object_;
};

}  // namespace

TEST_F(ExceptionsBindingsTest, ThrowExceptionFromConstructor) {
  SimpleExceptionSetter exception_setter(script::kSimpleError);
  EXPECT_CALL(ExceptionsInterface::constructor_implementation_mock.Get(),
              Constructor(_))
      .WillOnce(
          Invoke(&exception_setter, &SimpleExceptionSetter::FireException));

  std::string result;
  EXPECT_FALSE(EvaluateScript("var foo = new ExceptionsInterface();", &result));
  EXPECT_SUBSTRING("Error", result.c_str());
}

TEST_F(ExceptionsBindingsTest, ThrowExceptionFromOperation) {
  SimpleExceptionSetter exception_setter(script::kSimpleTypeError);
  EXPECT_CALL(test_mock(), FunctionThrowsException(_)).WillOnce(
      Invoke(&exception_setter, &SimpleExceptionSetter::FireException));

  std::string result;
  EXPECT_FALSE(EvaluateScript("test.functionThrowsException();", &result));
  EXPECT_SUBSTRING("TypeError", result.c_str());
}

TEST_F(ExceptionsBindingsTest, ThrowExceptionFromGetter) {
  SimpleExceptionSetter exception_setter(script::kSimpleRangeError);
  EXPECT_CALL(test_mock(), attribute_throws_exception(_)).WillOnce(
      DoAll(Invoke(&exception_setter, &SimpleExceptionSetter::FireException),
            Return(false)));

  std::string result;
  EXPECT_FALSE(
      EvaluateScript("var foo = test.attributeThrowsException;", &result));
  EXPECT_SUBSTRING("RangeError", result.c_str());
}

TEST_F(ExceptionsBindingsTest, ThrowExceptionFromSetter) {
  SimpleExceptionSetter exception_setter(script::kSimpleReferenceError);
  EXPECT_CALL(test_mock(), set_attribute_throws_exception(_, _))
      .WillOnce(WithArg<1>(
          Invoke(&exception_setter, &SimpleExceptionSetter::FireException)));

  std::string result;
  EXPECT_FALSE(
      EvaluateScript("test.attributeThrowsException = true;", &result));
  EXPECT_SUBSTRING("ReferenceError", result.c_str());
}

TEST_F(ExceptionsBindingsTest, ThrowExceptionObject) {
  scoped_refptr<ExceptionObjectInterface> exception_object =
      make_scoped_refptr(new NiceMock<ExceptionObjectInterface>());
  ExceptionObjectSetter exception_setter(exception_object);

  InSequence in_sequence_dummy;
  EXPECT_CALL(test_mock(), FunctionThrowsException(_)).WillOnce(
      Invoke(&exception_setter, &ExceptionObjectSetter::FireException));
  EXPECT_TRUE(EvaluateScript(
      "var error = null;"
      "try { test.functionThrowsException(); }"
      "catch(e) { error = e; }",
      NULL));

  std::string result;
  EXPECT_TRUE(EvaluateScript("error instanceof Error;", &result));
  EXPECT_STREQ("true", result.c_str());
  EXPECT_TRUE(
      EvaluateScript("error instanceof ExceptionObjectInterface;", &result));
  EXPECT_STREQ("true", result.c_str());

  EXPECT_CALL(*exception_object, error()).WillOnce(Return("the error"));
  EXPECT_TRUE(EvaluateScript("error.error;", &result));
  EXPECT_STREQ("the error", result.c_str());

  EXPECT_CALL(*exception_object, message()).WillOnce(Return("the message"));
  EXPECT_TRUE(EvaluateScript("error.message;", &result));
  EXPECT_STREQ("the message", result.c_str());
}

}  // namespace testing
}  // namespace bindings
}  // namespace cobalt
