// Copyright 2018 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "fxjs/cfx_v8_unittest.h"

#include <cmath>
#include <memory>

#include "fxjs/cfx_v8.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
bool getter_sentinel = false;
bool setter_sentinel = false;
}  // namespace

void FXV8UnitTest::V8IsolateDeleter::operator()(v8::Isolate* ptr) const {
  ptr->Dispose();
}

FXV8UnitTest::FXV8UnitTest() = default;

FXV8UnitTest::~FXV8UnitTest() = default;

void FXV8UnitTest::SetUp() {
  array_buffer_allocator_ = std::make_unique<CFX_V8ArrayBufferAllocator>();

  v8::Isolate::CreateParams params;
  params.array_buffer_allocator = array_buffer_allocator_.get();
  isolate_.reset(v8::Isolate::New(params));

  cfx_v8_ = std::make_unique<CFX_V8>(isolate_.get());
}

TEST_F(FXV8UnitTest, EmptyLocal) {
  v8::Isolate::Scope isolate_scope(isolate());
  v8::HandleScope handle_scope(isolate());
  v8::Context::Scope context_scope(v8::Context::New(isolate()));

  v8::Local<v8::Value> empty;
  EXPECT_FALSE(cfx_v8()->ToBoolean(empty));
  EXPECT_EQ(0, cfx_v8()->ToInt32(empty));
  EXPECT_EQ(0.0, cfx_v8()->ToDouble(empty));
  EXPECT_EQ("", cfx_v8()->ToByteString(empty));
  EXPECT_EQ(L"", cfx_v8()->ToWideString(empty));
  EXPECT_TRUE(cfx_v8()->ToObject(empty).IsEmpty());
  EXPECT_TRUE(cfx_v8()->ToArray(empty).IsEmpty());

  // Can't set properties on empty objects, but does not fault.
  v8::Local<v8::Value> marker = cfx_v8()->NewNumber(2);
  v8::Local<v8::Object> empty_object;
  EXPECT_FALSE(cfx_v8()->PutObjectProperty(empty_object, "clams", marker));
  EXPECT_TRUE(cfx_v8()->GetObjectProperty(empty_object, "clams").IsEmpty());
  EXPECT_EQ(0u, cfx_v8()->GetObjectPropertyNames(empty_object).size());

  // Can't set elements in empty arrays, but does not fault.
  v8::Local<v8::Array> empty_array;
  EXPECT_FALSE(cfx_v8()->PutArrayElement(empty_array, 0, marker));
  EXPECT_TRUE(cfx_v8()->GetArrayElement(empty_array, 0).IsEmpty());
  EXPECT_EQ(0u, cfx_v8()->GetArrayLength(empty_array));
}

TEST_F(FXV8UnitTest, NewNull) {
  v8::Isolate::Scope isolate_scope(isolate());
  v8::HandleScope handle_scope(isolate());
  v8::Context::Scope context_scope(v8::Context::New(isolate()));

  auto nullz = cfx_v8()->NewNull();
  EXPECT_FALSE(cfx_v8()->ToBoolean(nullz));
  EXPECT_EQ(0, cfx_v8()->ToInt32(nullz));
  EXPECT_EQ(0.0, cfx_v8()->ToDouble(nullz));
  EXPECT_EQ("null", cfx_v8()->ToByteString(nullz));
  EXPECT_EQ(L"null", cfx_v8()->ToWideString(nullz));
  EXPECT_TRUE(cfx_v8()->ToObject(nullz).IsEmpty());
  EXPECT_TRUE(cfx_v8()->ToArray(nullz).IsEmpty());
}

TEST_F(FXV8UnitTest, NewUndefined) {
  v8::Isolate::Scope isolate_scope(isolate());
  v8::HandleScope handle_scope(isolate());
  v8::Context::Scope context_scope(v8::Context::New(isolate()));

  auto undef = cfx_v8()->NewUndefined();
  EXPECT_FALSE(cfx_v8()->ToBoolean(undef));
  EXPECT_EQ(0, cfx_v8()->ToInt32(undef));
  EXPECT_TRUE(std::isnan(cfx_v8()->ToDouble(undef)));
  EXPECT_EQ("undefined", cfx_v8()->ToByteString(undef));
  EXPECT_EQ(L"undefined", cfx_v8()->ToWideString(undef));
  EXPECT_TRUE(cfx_v8()->ToObject(undef).IsEmpty());
  EXPECT_TRUE(cfx_v8()->ToArray(undef).IsEmpty());
}

TEST_F(FXV8UnitTest, NewBoolean) {
  v8::Isolate::Scope isolate_scope(isolate());
  v8::HandleScope handle_scope(isolate());
  v8::Context::Scope context_scope(v8::Context::New(isolate()));

  auto boolz = cfx_v8()->NewBoolean(true);
  EXPECT_TRUE(cfx_v8()->ToBoolean(boolz));
  EXPECT_EQ(1, cfx_v8()->ToInt32(boolz));
  EXPECT_EQ(1.0, cfx_v8()->ToDouble(boolz));
  EXPECT_EQ("true", cfx_v8()->ToByteString(boolz));
  EXPECT_EQ(L"true", cfx_v8()->ToWideString(boolz));
  EXPECT_TRUE(cfx_v8()->ToObject(boolz).IsEmpty());
  EXPECT_TRUE(cfx_v8()->ToArray(boolz).IsEmpty());

  boolz = cfx_v8()->NewBoolean(false);
  EXPECT_FALSE(cfx_v8()->ToBoolean(boolz));
  EXPECT_EQ(0, cfx_v8()->ToInt32(boolz));
  EXPECT_EQ(0.0, cfx_v8()->ToDouble(boolz));
  EXPECT_EQ("false", cfx_v8()->ToByteString(boolz));
  EXPECT_EQ(L"false", cfx_v8()->ToWideString(boolz));
  EXPECT_TRUE(cfx_v8()->ToObject(boolz).IsEmpty());
  EXPECT_TRUE(cfx_v8()->ToArray(boolz).IsEmpty());
}

TEST_F(FXV8UnitTest, NewNumber) {
  v8::Isolate::Scope isolate_scope(isolate());
  v8::HandleScope handle_scope(isolate());
  v8::Context::Scope context_scope(v8::Context::New(isolate()));

  auto num = cfx_v8()->NewNumber(42.1);
  EXPECT_TRUE(cfx_v8()->ToBoolean(num));
  EXPECT_EQ(42, cfx_v8()->ToInt32(num));
  EXPECT_EQ(42.1, cfx_v8()->ToDouble(num));
  EXPECT_EQ("42.1", cfx_v8()->ToByteString(num));
  EXPECT_EQ(L"42.1", cfx_v8()->ToWideString(num));
  EXPECT_TRUE(cfx_v8()->ToObject(num).IsEmpty());
  EXPECT_TRUE(cfx_v8()->ToArray(num).IsEmpty());
}

TEST_F(FXV8UnitTest, NewString) {
  v8::Isolate::Scope isolate_scope(isolate());
  v8::HandleScope handle_scope(isolate());
  v8::Context::Scope context_scope(v8::Context::New(isolate()));

  auto str = cfx_v8()->NewString("123");
  EXPECT_TRUE(cfx_v8()->ToBoolean(str));
  EXPECT_EQ(123, cfx_v8()->ToInt32(str));
  EXPECT_EQ(123, cfx_v8()->ToDouble(str));
  EXPECT_EQ("123", cfx_v8()->ToByteString(str));
  EXPECT_EQ(L"123", cfx_v8()->ToWideString(str));
  EXPECT_TRUE(cfx_v8()->ToObject(str).IsEmpty());
  EXPECT_TRUE(cfx_v8()->ToArray(str).IsEmpty());

  auto str2 = cfx_v8()->NewString(L"123");
  EXPECT_TRUE(cfx_v8()->ToBoolean(str2));
  EXPECT_EQ(123, cfx_v8()->ToInt32(str2));
  EXPECT_EQ(123, cfx_v8()->ToDouble(str2));
  EXPECT_EQ("123", cfx_v8()->ToByteString(str2));
  EXPECT_EQ(L"123", cfx_v8()->ToWideString(str2));
  EXPECT_TRUE(cfx_v8()->ToObject(str2).IsEmpty());
  EXPECT_TRUE(cfx_v8()->ToArray(str2).IsEmpty());
}

TEST_F(FXV8UnitTest, NewDate) {
  v8::Isolate::Scope isolate_scope(isolate());
  v8::HandleScope handle_scope(isolate());
  v8::Context::Scope context_scope(v8::Context::New(isolate()));

  auto date = cfx_v8()->NewDate(1111111111);
  EXPECT_TRUE(cfx_v8()->ToBoolean(date));
  EXPECT_EQ(1111111111, cfx_v8()->ToInt32(date));
  EXPECT_EQ(1111111111.0, cfx_v8()->ToDouble(date));
  EXPECT_NE("", cfx_v8()->ToByteString(date));   // exact format varies.
  EXPECT_NE(L"", cfx_v8()->ToWideString(date));  // exact format varies.
  EXPECT_TRUE(cfx_v8()->ToObject(date)->IsObject());
  EXPECT_TRUE(cfx_v8()->ToArray(date).IsEmpty());
}

TEST_F(FXV8UnitTest, NewArray) {
  v8::Isolate::Scope isolate_scope(isolate());
  v8::HandleScope handle_scope(isolate());
  v8::Context::Scope context_scope(v8::Context::New(isolate()));

  auto array = cfx_v8()->NewArray();
  EXPECT_EQ(0u, cfx_v8()->GetArrayLength(array));
  EXPECT_FALSE(cfx_v8()->GetArrayElement(array, 2).IsEmpty());
  EXPECT_TRUE(cfx_v8()->GetArrayElement(array, 2)->IsUndefined());
  EXPECT_EQ(0u, cfx_v8()->GetArrayLength(array));

  EXPECT_TRUE(cfx_v8()->PutArrayElement(array, 3, cfx_v8()->NewNumber(12)));
  EXPECT_FALSE(cfx_v8()->GetArrayElement(array, 2).IsEmpty());
  EXPECT_TRUE(cfx_v8()->GetArrayElement(array, 2)->IsUndefined());
  EXPECT_FALSE(cfx_v8()->GetArrayElement(array, 3).IsEmpty());
  EXPECT_TRUE(cfx_v8()->GetArrayElement(array, 3)->IsNumber());
  EXPECT_EQ(4u, cfx_v8()->GetArrayLength(array));

  EXPECT_TRUE(cfx_v8()->ToBoolean(array));
  EXPECT_EQ(0, cfx_v8()->ToInt32(array));
  double d = cfx_v8()->ToDouble(array);
  EXPECT_NE(d, d);  // i.e. NaN.
  EXPECT_EQ(L",,,12", cfx_v8()->ToWideString(array));
  EXPECT_TRUE(cfx_v8()->ToObject(array)->IsObject());
  EXPECT_TRUE(cfx_v8()->ToArray(array)->IsArray());
}

TEST_F(FXV8UnitTest, NewObject) {
  v8::Isolate::Scope isolate_scope(isolate());
  v8::HandleScope handle_scope(isolate());
  v8::Context::Scope context_scope(v8::Context::New(isolate()));

  auto object = cfx_v8()->NewObject();
  ASSERT_FALSE(object.IsEmpty());
  EXPECT_EQ(0u, cfx_v8()->GetObjectPropertyNames(object).size());
  EXPECT_FALSE(cfx_v8()->GetObjectProperty(object, "clams").IsEmpty());
  EXPECT_TRUE(cfx_v8()->GetObjectProperty(object, "clams")->IsUndefined());
  EXPECT_EQ(0u, cfx_v8()->GetObjectPropertyNames(object).size());

  EXPECT_TRUE(
      cfx_v8()->PutObjectProperty(object, "clams", cfx_v8()->NewNumber(12)));
  EXPECT_FALSE(cfx_v8()->GetObjectProperty(object, "clams").IsEmpty());
  EXPECT_TRUE(cfx_v8()->GetObjectProperty(object, "clams")->IsNumber());
  EXPECT_EQ(1u, cfx_v8()->GetObjectPropertyNames(object).size());
  EXPECT_EQ(L"clams", cfx_v8()->GetObjectPropertyNames(object)[0]);

  EXPECT_TRUE(cfx_v8()->ToBoolean(object));
  EXPECT_EQ(0, cfx_v8()->ToInt32(object));
  double d = cfx_v8()->ToDouble(object);
  EXPECT_NE(d, d);  // i.e. NaN.
  EXPECT_EQ(L"[object Object]", cfx_v8()->ToWideString(object));
  EXPECT_TRUE(cfx_v8()->ToObject(object)->IsObject());
  EXPECT_TRUE(cfx_v8()->ToArray(object).IsEmpty());
}

TEST_F(FXV8UnitTest, ThrowFromGetter) {
  v8::Isolate::Scope isolate_scope(isolate());
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = v8::Context::New(isolate());
  v8::Context::Scope context_scope(context);

  v8::Local<v8::Object> object = cfx_v8()->NewObject();
  v8::Local<v8::String> name = cfx_v8()->NewString("clams");
  EXPECT_TRUE(
      object
          ->SetAccessor(context, name,
                        [](v8::Local<v8::Name> property,
                           const v8::PropertyCallbackInfo<v8::Value>& info) {
                          getter_sentinel = true;
                          info.GetIsolate()->ThrowException(property);
                        })
          .FromJust());
  getter_sentinel = false;
  EXPECT_TRUE(cfx_v8()->GetObjectProperty(object, "clams").IsEmpty());
  EXPECT_TRUE(getter_sentinel);
}

TEST_F(FXV8UnitTest, ThrowFromSetter) {
  v8::Isolate::Scope isolate_scope(isolate());
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = v8::Context::New(isolate());
  v8::Context::Scope context_scope(context);

  v8::Local<v8::Object> object = cfx_v8()->NewObject();
  v8::Local<v8::String> name = cfx_v8()->NewString("clams");
  EXPECT_TRUE(object
                  ->SetAccessor(context, name, nullptr,
                                [](v8::Local<v8::Name> property,
                                   v8::Local<v8::Value> value,
                                   const v8::PropertyCallbackInfo<void>& info) {
                                  setter_sentinel = true;
                                  info.GetIsolate()->ThrowException(property);
                                })
                  .FromJust());
  setter_sentinel = false;
  EXPECT_FALSE(cfx_v8()->PutObjectProperty(object, "clams", name));
  EXPECT_TRUE(setter_sentinel);
}
