summaryrefslogtreecommitdiff
path: root/fxjs/cfx_v8_unittest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fxjs/cfx_v8_unittest.cpp')
-rw-r--r--fxjs/cfx_v8_unittest.cpp203
1 files changed, 203 insertions, 0 deletions
diff --git a/fxjs/cfx_v8_unittest.cpp b/fxjs/cfx_v8_unittest.cpp
new file mode 100644
index 0000000000..db7da961e8
--- /dev/null
+++ b/fxjs/cfx_v8_unittest.cpp
@@ -0,0 +1,203 @@
+// 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.h"
+
+#include <memory>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/test_support.h"
+#include "third_party/base/ptr_util.h"
+
+namespace {
+
+struct V8IsolateDeleter {
+ inline void operator()(v8::Isolate* ptr) const { ptr->Dispose(); }
+};
+
+} // namespace
+
+class FXV8UnitTest : public ::testing::Test {
+ public:
+ FXV8UnitTest() = default;
+ ~FXV8UnitTest() override = default;
+
+ void SetUp() override {
+ array_buffer_allocator_ = pdfium::MakeUnique<CFX_V8ArrayBufferAllocator>();
+
+ v8::Isolate::CreateParams params;
+ params.array_buffer_allocator = array_buffer_allocator_.get();
+ isolate_.reset(v8::Isolate::New(params));
+
+ cfx_v8_ = pdfium::MakeUnique<CFX_V8>(isolate_.get());
+ }
+
+ v8::Isolate* isolate() const { return isolate_.get(); }
+ CFX_V8* cfx_v8() const { return cfx_v8_.get(); }
+
+ protected:
+ std::unique_ptr<CFX_V8ArrayBufferAllocator> array_buffer_allocator_;
+ std::unique_ptr<v8::Isolate, V8IsolateDeleter> isolate_;
+ std::unique_ptr<CFX_V8> cfx_v8_;
+};
+
+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(L"", cfx_v8()->ToWideString(empty));
+ EXPECT_TRUE(cfx_v8()->ToObject(empty).IsEmpty());
+ EXPECT_TRUE(cfx_v8()->ToArray(empty).IsEmpty());
+}
+
+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(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(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(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(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(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(L"123");
+ EXPECT_TRUE(cfx_v8()->ToBoolean(str));
+ EXPECT_EQ(123, cfx_v8()->ToInt32(str));
+ EXPECT_EQ(123, cfx_v8()->ToDouble(str));
+ EXPECT_EQ(L"123", cfx_v8()->ToWideString(str));
+ EXPECT_TRUE(cfx_v8()->ToObject(str).IsEmpty());
+ EXPECT_TRUE(cfx_v8()->ToArray(str).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(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));
+
+ 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, L"clams").IsEmpty());
+ EXPECT_TRUE(cfx_v8()->GetObjectProperty(object, L"clams")->IsUndefined());
+ EXPECT_EQ(0u, cfx_v8()->GetObjectPropertyNames(object).size());
+
+ cfx_v8()->PutObjectProperty(object, L"clams", cfx_v8()->NewNumber(12));
+ EXPECT_FALSE(cfx_v8()->GetObjectProperty(object, L"clams").IsEmpty());
+ EXPECT_TRUE(cfx_v8()->GetObjectProperty(object, L"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());
+}