summaryrefslogtreecommitdiff
path: root/fxjs
diff options
context:
space:
mode:
Diffstat (limited to 'fxjs')
-rw-r--r--fxjs/cfx_v8.cpp24
-rw-r--r--fxjs/cfx_v8.h7
-rw-r--r--fxjs/cfx_v8_unittest.cpp203
-rw-r--r--fxjs/fxjs_v8.cpp26
-rw-r--r--fxjs/fxjs_v8.h7
-rw-r--r--fxjs/fxjs_v8_embeddertest.cpp152
6 files changed, 236 insertions, 183 deletions
diff --git a/fxjs/cfx_v8.cpp b/fxjs/cfx_v8.cpp
index 80b9eda47c..4738030236 100644
--- a/fxjs/cfx_v8.cpp
+++ b/fxjs/cfx_v8.cpp
@@ -6,6 +6,9 @@
#include "fxjs/cfx_v8.h"
+#include "core/fxcrt/fx_memory.h"
+#include "third_party/base/allocator/partition_allocator/partition_alloc.h"
+
CFX_V8::CFX_V8(v8::Isolate* isolate) : m_isolate(isolate) {}
CFX_V8::~CFX_V8() = default;
@@ -194,3 +197,24 @@ v8::Local<v8::Array> CFX_V8::ToArray(v8::Local<v8::Value> pValue) {
v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked());
}
+
+void* CFX_V8ArrayBufferAllocator::Allocate(size_t length) {
+ if (length > kMaxAllowedBytes)
+ return nullptr;
+ void* p = AllocateUninitialized(length);
+ if (p)
+ memset(p, 0, length);
+ return p;
+}
+
+void* CFX_V8ArrayBufferAllocator::AllocateUninitialized(size_t length) {
+ if (length > kMaxAllowedBytes)
+ return nullptr;
+ return pdfium::base::PartitionAllocGeneric(
+ gArrayBufferPartitionAllocator.root(), length, "CFX_V8ArrayBuffer");
+}
+
+void CFX_V8ArrayBufferAllocator::Free(void* data, size_t length) {
+ pdfium::base::PartitionFreeGeneric(gArrayBufferPartitionAllocator.root(),
+ data);
+}
diff --git a/fxjs/cfx_v8.h b/fxjs/cfx_v8.h
index 2f9794c243..08a18935ea 100644
--- a/fxjs/cfx_v8.h
+++ b/fxjs/cfx_v8.h
@@ -65,4 +65,11 @@ class CFX_V8 {
v8::Isolate* m_isolate;
};
+class CFX_V8ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
+ static const size_t kMaxAllowedBytes = 0x10000000;
+ void* Allocate(size_t length) override;
+ void* AllocateUninitialized(size_t length) override;
+ void Free(void* data, size_t length) override;
+};
+
#endif // FXJS_CFX_V8_H_
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());
+}
diff --git a/fxjs/fxjs_v8.cpp b/fxjs/fxjs_v8.cpp
index 0e87024387..f29dca6807 100644
--- a/fxjs/fxjs_v8.cpp
+++ b/fxjs/fxjs_v8.cpp
@@ -12,7 +12,6 @@
#include "fxjs/cfxjse_runtimedata.h"
#include "fxjs/cjs_object.h"
-#include "third_party/base/allocator/partition_allocator/partition_alloc.h"
// Keep this consistent with the values defined in gin/public/context_holder.h
// (without actually requiring a dependency on gin itself for the standalone
@@ -22,7 +21,7 @@ static const unsigned int kPerContextDataIndex = 3u;
static unsigned int g_embedderDataSlot = 1u;
static v8::Isolate* g_isolate = nullptr;
static size_t g_isolate_ref_count = 0;
-static FXJS_ArrayBufferAllocator* g_arrayBufferAllocator = nullptr;
+static CFX_V8ArrayBufferAllocator* g_arrayBufferAllocator = nullptr;
static v8::Global<v8::ObjectTemplate>* g_DefaultGlobalObjectTemplate = nullptr;
static wchar_t kPerObjectDataTag[] = L"CFXJS_PerObjectData";
@@ -148,27 +147,6 @@ static v8::Local<v8::ObjectTemplate> GetGlobalObjectTemplate(
return g_DefaultGlobalObjectTemplate->Get(pIsolate);
}
-void* FXJS_ArrayBufferAllocator::Allocate(size_t length) {
- if (length > kMaxAllowedBytes)
- return nullptr;
- void* p = AllocateUninitialized(length);
- if (p)
- memset(p, 0, length);
- return p;
-}
-
-void* FXJS_ArrayBufferAllocator::AllocateUninitialized(size_t length) {
- if (length > kMaxAllowedBytes)
- return nullptr;
- return pdfium::base::PartitionAllocGeneric(
- gArrayBufferPartitionAllocator.root(), length, "FXJS_ArrayBuffer");
-}
-
-void FXJS_ArrayBufferAllocator::Free(void* data, size_t length) {
- pdfium::base::PartitionFreeGeneric(gArrayBufferPartitionAllocator.root(),
- data);
-}
-
void V8TemplateMapTraits::Dispose(v8::Isolate* isolate,
v8::Global<v8::Object> value,
void* key) {
@@ -220,7 +198,7 @@ bool FXJS_GetIsolate(v8::Isolate** pResultIsolate) {
}
// Provide backwards compatibility when no external isolate.
if (!g_arrayBufferAllocator)
- g_arrayBufferAllocator = new FXJS_ArrayBufferAllocator();
+ g_arrayBufferAllocator = new CFX_V8ArrayBufferAllocator();
v8::Isolate::CreateParams params;
params.array_buffer_allocator = g_arrayBufferAllocator;
*pResultIsolate = v8::Isolate::New(params);
diff --git a/fxjs/fxjs_v8.h b/fxjs/fxjs_v8.h
index 831f839fcc..9ef746018c 100644
--- a/fxjs/fxjs_v8.h
+++ b/fxjs/fxjs_v8.h
@@ -109,13 +109,6 @@ class FXJS_PerIsolateData {
explicit FXJS_PerIsolateData(v8::Isolate* pIsolate);
};
-class FXJS_ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
- static const size_t kMaxAllowedBytes = 0x10000000;
- void* Allocate(size_t length) override;
- void* AllocateUninitialized(size_t length) override;
- void Free(void* data, size_t length) override;
-};
-
void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate);
void FXJS_Release();
diff --git a/fxjs/fxjs_v8_embeddertest.cpp b/fxjs/fxjs_v8_embeddertest.cpp
index acc4366631..77bea86fe1 100644
--- a/fxjs/fxjs_v8_embeddertest.cpp
+++ b/fxjs/fxjs_v8_embeddertest.cpp
@@ -95,155 +95,3 @@ TEST_F(FXJSV8EmbedderTest, MultipleEngines) {
engine1.ReleaseEngine();
engine2.ReleaseEngine();
}
-
-TEST_F(FXJSV8EmbedderTest, EmptyLocal) {
- v8::Isolate::Scope isolate_scope(isolate());
- v8::HandleScope handle_scope(isolate());
- v8::Context::Scope context_scope(GetV8Context());
-
- v8::Local<v8::Value> empty;
- EXPECT_FALSE(engine()->ToBoolean(empty));
- EXPECT_EQ(0, engine()->ToInt32(empty));
- EXPECT_EQ(0.0, engine()->ToDouble(empty));
- EXPECT_EQ(L"", engine()->ToWideString(empty));
- EXPECT_TRUE(engine()->ToObject(empty).IsEmpty());
- EXPECT_TRUE(engine()->ToArray(empty).IsEmpty());
-}
-
-TEST_F(FXJSV8EmbedderTest, NewNull) {
- v8::Isolate::Scope isolate_scope(isolate());
- v8::HandleScope handle_scope(isolate());
- v8::Context::Scope context_scope(GetV8Context());
-
- auto nullz = engine()->NewNull();
- EXPECT_FALSE(engine()->ToBoolean(nullz));
- EXPECT_EQ(0, engine()->ToInt32(nullz));
- EXPECT_EQ(0.0, engine()->ToDouble(nullz));
- EXPECT_EQ(L"null", engine()->ToWideString(nullz));
- EXPECT_TRUE(engine()->ToObject(nullz).IsEmpty());
- EXPECT_TRUE(engine()->ToArray(nullz).IsEmpty());
-}
-
-TEST_F(FXJSV8EmbedderTest, NewUndefined) {
- v8::Isolate::Scope isolate_scope(isolate());
- v8::HandleScope handle_scope(isolate());
- v8::Context::Scope context_scope(GetV8Context());
-
- auto undef = engine()->NewUndefined();
- EXPECT_FALSE(engine()->ToBoolean(undef));
- EXPECT_EQ(0, engine()->ToInt32(undef));
- EXPECT_TRUE(std::isnan(engine()->ToDouble(undef)));
- EXPECT_EQ(L"undefined", engine()->ToWideString(undef));
- EXPECT_TRUE(engine()->ToObject(undef).IsEmpty());
- EXPECT_TRUE(engine()->ToArray(undef).IsEmpty());
-}
-
-TEST_F(FXJSV8EmbedderTest, NewBoolean) {
- v8::Isolate::Scope isolate_scope(isolate());
- v8::HandleScope handle_scope(isolate());
- v8::Context::Scope context_scope(GetV8Context());
-
- auto boolz = engine()->NewBoolean(true);
- EXPECT_TRUE(engine()->ToBoolean(boolz));
- EXPECT_EQ(1, engine()->ToInt32(boolz));
- EXPECT_EQ(1.0, engine()->ToDouble(boolz));
- EXPECT_EQ(L"true", engine()->ToWideString(boolz));
- EXPECT_TRUE(engine()->ToObject(boolz).IsEmpty());
- EXPECT_TRUE(engine()->ToArray(boolz).IsEmpty());
-}
-
-TEST_F(FXJSV8EmbedderTest, NewNumber) {
- v8::Isolate::Scope isolate_scope(isolate());
- v8::HandleScope handle_scope(isolate());
- v8::Context::Scope context_scope(GetV8Context());
-
- auto num = engine()->NewNumber(42.1);
- EXPECT_TRUE(engine()->ToBoolean(num));
- EXPECT_EQ(42, engine()->ToInt32(num));
- EXPECT_EQ(42.1, engine()->ToDouble(num));
- EXPECT_EQ(L"42.1", engine()->ToWideString(num));
- EXPECT_TRUE(engine()->ToObject(num).IsEmpty());
- EXPECT_TRUE(engine()->ToArray(num).IsEmpty());
-}
-
-TEST_F(FXJSV8EmbedderTest, NewString) {
- v8::Isolate::Scope isolate_scope(isolate());
- v8::HandleScope handle_scope(isolate());
- v8::Context::Scope context_scope(GetV8Context());
-
- auto str = engine()->NewString(L"123");
- EXPECT_TRUE(engine()->ToBoolean(str));
- EXPECT_EQ(123, engine()->ToInt32(str));
- EXPECT_EQ(123, engine()->ToDouble(str));
- EXPECT_EQ(L"123", engine()->ToWideString(str));
- EXPECT_TRUE(engine()->ToObject(str).IsEmpty());
- EXPECT_TRUE(engine()->ToArray(str).IsEmpty());
-}
-
-TEST_F(FXJSV8EmbedderTest, NewDate) {
- v8::Isolate::Scope isolate_scope(isolate());
- v8::HandleScope handle_scope(isolate());
- v8::Context::Scope context_scope(GetV8Context());
-
- auto date = engine()->NewDate(1111111111);
- EXPECT_TRUE(engine()->ToBoolean(date));
- EXPECT_EQ(1111111111, engine()->ToInt32(date));
- EXPECT_EQ(1111111111.0, engine()->ToDouble(date));
- EXPECT_NE(L"", engine()->ToWideString(date)); // exact format varies.
- EXPECT_TRUE(engine()->ToObject(date)->IsObject());
- EXPECT_TRUE(engine()->ToArray(date).IsEmpty());
-}
-
-TEST_F(FXJSV8EmbedderTest, NewArray) {
- v8::Isolate::Scope isolate_scope(isolate());
- v8::HandleScope handle_scope(isolate());
- v8::Context::Scope context_scope(GetV8Context());
-
- auto array = engine()->NewArray();
- EXPECT_EQ(0u, engine()->GetArrayLength(array));
- EXPECT_FALSE(engine()->GetArrayElement(array, 2).IsEmpty());
- EXPECT_TRUE(engine()->GetArrayElement(array, 2)->IsUndefined());
- EXPECT_EQ(0u, engine()->GetArrayLength(array));
-
- engine()->PutArrayElement(array, 3, engine()->NewNumber(12));
- EXPECT_FALSE(engine()->GetArrayElement(array, 2).IsEmpty());
- EXPECT_TRUE(engine()->GetArrayElement(array, 2)->IsUndefined());
- EXPECT_FALSE(engine()->GetArrayElement(array, 3).IsEmpty());
- EXPECT_TRUE(engine()->GetArrayElement(array, 3)->IsNumber());
- EXPECT_EQ(4u, engine()->GetArrayLength(array));
-
- EXPECT_TRUE(engine()->ToBoolean(array));
- EXPECT_EQ(0, engine()->ToInt32(array));
- double d = engine()->ToDouble(array);
- EXPECT_NE(d, d); // i.e. NaN.
- EXPECT_EQ(L",,,12", engine()->ToWideString(array));
- EXPECT_TRUE(engine()->ToObject(array)->IsObject());
- EXPECT_TRUE(engine()->ToArray(array)->IsArray());
-}
-
-TEST_F(FXJSV8EmbedderTest, NewObject) {
- v8::Isolate::Scope isolate_scope(isolate());
- v8::HandleScope handle_scope(isolate());
- v8::Context::Scope context_scope(GetV8Context());
-
- auto object = engine()->NewObject();
- ASSERT_FALSE(object.IsEmpty());
- EXPECT_EQ(0u, engine()->GetObjectPropertyNames(object).size());
- EXPECT_FALSE(engine()->GetObjectProperty(object, L"clams").IsEmpty());
- EXPECT_TRUE(engine()->GetObjectProperty(object, L"clams")->IsUndefined());
- EXPECT_EQ(0u, engine()->GetObjectPropertyNames(object).size());
-
- engine()->PutObjectProperty(object, L"clams", engine()->NewNumber(12));
- EXPECT_FALSE(engine()->GetObjectProperty(object, L"clams").IsEmpty());
- EXPECT_TRUE(engine()->GetObjectProperty(object, L"clams")->IsNumber());
- EXPECT_EQ(1u, engine()->GetObjectPropertyNames(object).size());
- EXPECT_EQ(L"clams", engine()->GetObjectPropertyNames(object)[0]);
-
- EXPECT_TRUE(engine()->ToBoolean(object));
- EXPECT_EQ(0, engine()->ToInt32(object));
- double d = engine()->ToDouble(object);
- EXPECT_NE(d, d); // i.e. NaN.
- EXPECT_EQ(L"[object Object]", engine()->ToWideString(object));
- EXPECT_TRUE(engine()->ToObject(object)->IsObject());
- EXPECT_TRUE(engine()->ToArray(object).IsEmpty());
-}