diff options
Diffstat (limited to 'fxjs')
-rw-r--r-- | fxjs/cfx_v8.cpp | 24 | ||||
-rw-r--r-- | fxjs/cfx_v8.h | 7 | ||||
-rw-r--r-- | fxjs/cfx_v8_unittest.cpp | 203 | ||||
-rw-r--r-- | fxjs/fxjs_v8.cpp | 26 | ||||
-rw-r--r-- | fxjs/fxjs_v8.h | 7 | ||||
-rw-r--r-- | fxjs/fxjs_v8_embeddertest.cpp | 152 |
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()); -} |