1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2018 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/cfx_v8.h"
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include <math.h>
8*3ac0a46fSAndroid Build Coastguard Worker
9*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
10*3ac0a46fSAndroid Build Coastguard Worker
11*3ac0a46fSAndroid Build Coastguard Worker #include "testing/fxv8_unittest.h"
12*3ac0a46fSAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
13*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-container.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-context.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-date.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-isolate.h"
17*3ac0a46fSAndroid Build Coastguard Worker
18*3ac0a46fSAndroid Build Coastguard Worker namespace {
19*3ac0a46fSAndroid Build Coastguard Worker bool getter_sentinel = false;
20*3ac0a46fSAndroid Build Coastguard Worker bool setter_sentinel = false;
21*3ac0a46fSAndroid Build Coastguard Worker } // namespace
22*3ac0a46fSAndroid Build Coastguard Worker
23*3ac0a46fSAndroid Build Coastguard Worker class CFXV8UnitTest : public FXV8UnitTest {
24*3ac0a46fSAndroid Build Coastguard Worker public:
25*3ac0a46fSAndroid Build Coastguard Worker CFXV8UnitTest() = default;
26*3ac0a46fSAndroid Build Coastguard Worker ~CFXV8UnitTest() override = default;
27*3ac0a46fSAndroid Build Coastguard Worker
28*3ac0a46fSAndroid Build Coastguard Worker // FXV8UnitTest:
SetUp()29*3ac0a46fSAndroid Build Coastguard Worker void SetUp() override {
30*3ac0a46fSAndroid Build Coastguard Worker FXV8UnitTest::SetUp();
31*3ac0a46fSAndroid Build Coastguard Worker cfx_v8_ = std::make_unique<CFX_V8>(isolate());
32*3ac0a46fSAndroid Build Coastguard Worker }
33*3ac0a46fSAndroid Build Coastguard Worker
cfx_v8() const34*3ac0a46fSAndroid Build Coastguard Worker CFX_V8* cfx_v8() const { return cfx_v8_.get(); }
35*3ac0a46fSAndroid Build Coastguard Worker
36*3ac0a46fSAndroid Build Coastguard Worker protected:
37*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<CFX_V8> cfx_v8_;
38*3ac0a46fSAndroid Build Coastguard Worker };
39*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(CFXV8UnitTest,EmptyLocal)40*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFXV8UnitTest, EmptyLocal) {
41*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate::Scope isolate_scope(isolate());
42*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope handle_scope(isolate());
43*3ac0a46fSAndroid Build Coastguard Worker v8::Context::Scope context_scope(v8::Context::New(isolate()));
44*3ac0a46fSAndroid Build Coastguard Worker
45*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value> empty;
46*3ac0a46fSAndroid Build Coastguard Worker EXPECT_FALSE(cfx_v8()->ToBoolean(empty));
47*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0, cfx_v8()->ToInt32(empty));
48*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0.0, cfx_v8()->ToDouble(empty));
49*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ("", cfx_v8()->ToByteString(empty));
50*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(L"", cfx_v8()->ToWideString(empty));
51*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToObject(empty).IsEmpty());
52*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToArray(empty).IsEmpty());
53*3ac0a46fSAndroid Build Coastguard Worker
54*3ac0a46fSAndroid Build Coastguard Worker // Can't set properties on empty objects, but does not fault.
55*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value> marker = cfx_v8()->NewNumber(2);
56*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> empty_object;
57*3ac0a46fSAndroid Build Coastguard Worker cfx_v8()->PutObjectProperty(empty_object, "clams", marker);
58*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->GetObjectProperty(empty_object, "clams").IsEmpty());
59*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0u, cfx_v8()->GetObjectPropertyNames(empty_object).size());
60*3ac0a46fSAndroid Build Coastguard Worker
61*3ac0a46fSAndroid Build Coastguard Worker // Can't set elements in empty arrays, but does not fault.
62*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Array> empty_array;
63*3ac0a46fSAndroid Build Coastguard Worker cfx_v8()->PutArrayElement(empty_array, 0, marker);
64*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->GetArrayElement(empty_array, 0).IsEmpty());
65*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0u, cfx_v8()->GetArrayLength(empty_array));
66*3ac0a46fSAndroid Build Coastguard Worker }
67*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(CFXV8UnitTest,NewNull)68*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFXV8UnitTest, NewNull) {
69*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate::Scope isolate_scope(isolate());
70*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope handle_scope(isolate());
71*3ac0a46fSAndroid Build Coastguard Worker v8::Context::Scope context_scope(v8::Context::New(isolate()));
72*3ac0a46fSAndroid Build Coastguard Worker
73*3ac0a46fSAndroid Build Coastguard Worker auto nullz = cfx_v8()->NewNull();
74*3ac0a46fSAndroid Build Coastguard Worker EXPECT_FALSE(cfx_v8()->ToBoolean(nullz));
75*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0, cfx_v8()->ToInt32(nullz));
76*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0.0, cfx_v8()->ToDouble(nullz));
77*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ("null", cfx_v8()->ToByteString(nullz));
78*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(L"null", cfx_v8()->ToWideString(nullz));
79*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToObject(nullz).IsEmpty());
80*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToArray(nullz).IsEmpty());
81*3ac0a46fSAndroid Build Coastguard Worker }
82*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(CFXV8UnitTest,NewUndefined)83*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFXV8UnitTest, NewUndefined) {
84*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate::Scope isolate_scope(isolate());
85*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope handle_scope(isolate());
86*3ac0a46fSAndroid Build Coastguard Worker v8::Context::Scope context_scope(v8::Context::New(isolate()));
87*3ac0a46fSAndroid Build Coastguard Worker
88*3ac0a46fSAndroid Build Coastguard Worker auto undef = cfx_v8()->NewUndefined();
89*3ac0a46fSAndroid Build Coastguard Worker EXPECT_FALSE(cfx_v8()->ToBoolean(undef));
90*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0, cfx_v8()->ToInt32(undef));
91*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(isnan(cfx_v8()->ToDouble(undef)));
92*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ("undefined", cfx_v8()->ToByteString(undef));
93*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(L"undefined", cfx_v8()->ToWideString(undef));
94*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToObject(undef).IsEmpty());
95*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToArray(undef).IsEmpty());
96*3ac0a46fSAndroid Build Coastguard Worker }
97*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(CFXV8UnitTest,NewBoolean)98*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFXV8UnitTest, NewBoolean) {
99*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate::Scope isolate_scope(isolate());
100*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope handle_scope(isolate());
101*3ac0a46fSAndroid Build Coastguard Worker v8::Context::Scope context_scope(v8::Context::New(isolate()));
102*3ac0a46fSAndroid Build Coastguard Worker
103*3ac0a46fSAndroid Build Coastguard Worker auto boolz = cfx_v8()->NewBoolean(true);
104*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToBoolean(boolz));
105*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(1, cfx_v8()->ToInt32(boolz));
106*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(1.0, cfx_v8()->ToDouble(boolz));
107*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ("true", cfx_v8()->ToByteString(boolz));
108*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(L"true", cfx_v8()->ToWideString(boolz));
109*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToObject(boolz).IsEmpty());
110*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToArray(boolz).IsEmpty());
111*3ac0a46fSAndroid Build Coastguard Worker
112*3ac0a46fSAndroid Build Coastguard Worker boolz = cfx_v8()->NewBoolean(false);
113*3ac0a46fSAndroid Build Coastguard Worker EXPECT_FALSE(cfx_v8()->ToBoolean(boolz));
114*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0, cfx_v8()->ToInt32(boolz));
115*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0.0, cfx_v8()->ToDouble(boolz));
116*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ("false", cfx_v8()->ToByteString(boolz));
117*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(L"false", cfx_v8()->ToWideString(boolz));
118*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToObject(boolz).IsEmpty());
119*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToArray(boolz).IsEmpty());
120*3ac0a46fSAndroid Build Coastguard Worker }
121*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(CFXV8UnitTest,NewNumber)122*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFXV8UnitTest, NewNumber) {
123*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate::Scope isolate_scope(isolate());
124*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope handle_scope(isolate());
125*3ac0a46fSAndroid Build Coastguard Worker v8::Context::Scope context_scope(v8::Context::New(isolate()));
126*3ac0a46fSAndroid Build Coastguard Worker
127*3ac0a46fSAndroid Build Coastguard Worker auto num = cfx_v8()->NewNumber(42.1);
128*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToBoolean(num));
129*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(42, cfx_v8()->ToInt32(num));
130*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(42.1, cfx_v8()->ToDouble(num));
131*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ("42.1", cfx_v8()->ToByteString(num));
132*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(L"42.1", cfx_v8()->ToWideString(num));
133*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToObject(num).IsEmpty());
134*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToArray(num).IsEmpty());
135*3ac0a46fSAndroid Build Coastguard Worker }
136*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(CFXV8UnitTest,NewString)137*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFXV8UnitTest, NewString) {
138*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate::Scope isolate_scope(isolate());
139*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope handle_scope(isolate());
140*3ac0a46fSAndroid Build Coastguard Worker v8::Context::Scope context_scope(v8::Context::New(isolate()));
141*3ac0a46fSAndroid Build Coastguard Worker
142*3ac0a46fSAndroid Build Coastguard Worker auto str = cfx_v8()->NewString("123");
143*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToBoolean(str));
144*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(123, cfx_v8()->ToInt32(str));
145*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(123, cfx_v8()->ToDouble(str));
146*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ("123", cfx_v8()->ToByteString(str));
147*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(L"123", cfx_v8()->ToWideString(str));
148*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToObject(str).IsEmpty());
149*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToArray(str).IsEmpty());
150*3ac0a46fSAndroid Build Coastguard Worker
151*3ac0a46fSAndroid Build Coastguard Worker auto str2 = cfx_v8()->NewString(L"123");
152*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToBoolean(str2));
153*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(123, cfx_v8()->ToInt32(str2));
154*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(123, cfx_v8()->ToDouble(str2));
155*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ("123", cfx_v8()->ToByteString(str2));
156*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(L"123", cfx_v8()->ToWideString(str2));
157*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToObject(str2).IsEmpty());
158*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToArray(str2).IsEmpty());
159*3ac0a46fSAndroid Build Coastguard Worker }
160*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(CFXV8UnitTest,NewDate)161*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFXV8UnitTest, NewDate) {
162*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate::Scope isolate_scope(isolate());
163*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope handle_scope(isolate());
164*3ac0a46fSAndroid Build Coastguard Worker v8::Context::Scope context_scope(v8::Context::New(isolate()));
165*3ac0a46fSAndroid Build Coastguard Worker
166*3ac0a46fSAndroid Build Coastguard Worker auto date = cfx_v8()->NewDate(1111111111);
167*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToBoolean(date));
168*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(1111111111, cfx_v8()->ToInt32(date));
169*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(1111111111.0, cfx_v8()->ToDouble(date));
170*3ac0a46fSAndroid Build Coastguard Worker EXPECT_NE("", cfx_v8()->ToByteString(date)); // exact format varies.
171*3ac0a46fSAndroid Build Coastguard Worker EXPECT_NE(L"", cfx_v8()->ToWideString(date)); // exact format varies.
172*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToObject(date)->IsObject());
173*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToArray(date).IsEmpty());
174*3ac0a46fSAndroid Build Coastguard Worker }
175*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(CFXV8UnitTest,NewArray)176*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFXV8UnitTest, NewArray) {
177*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate::Scope isolate_scope(isolate());
178*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope handle_scope(isolate());
179*3ac0a46fSAndroid Build Coastguard Worker v8::Context::Scope context_scope(v8::Context::New(isolate()));
180*3ac0a46fSAndroid Build Coastguard Worker
181*3ac0a46fSAndroid Build Coastguard Worker auto array = cfx_v8()->NewArray();
182*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0u, cfx_v8()->GetArrayLength(array));
183*3ac0a46fSAndroid Build Coastguard Worker EXPECT_FALSE(cfx_v8()->GetArrayElement(array, 2).IsEmpty());
184*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->GetArrayElement(array, 2)->IsUndefined());
185*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0u, cfx_v8()->GetArrayLength(array));
186*3ac0a46fSAndroid Build Coastguard Worker
187*3ac0a46fSAndroid Build Coastguard Worker cfx_v8()->PutArrayElement(array, 3, cfx_v8()->NewNumber(12));
188*3ac0a46fSAndroid Build Coastguard Worker EXPECT_FALSE(cfx_v8()->GetArrayElement(array, 2).IsEmpty());
189*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->GetArrayElement(array, 2)->IsUndefined());
190*3ac0a46fSAndroid Build Coastguard Worker EXPECT_FALSE(cfx_v8()->GetArrayElement(array, 3).IsEmpty());
191*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->GetArrayElement(array, 3)->IsNumber());
192*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(4u, cfx_v8()->GetArrayLength(array));
193*3ac0a46fSAndroid Build Coastguard Worker
194*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToBoolean(array));
195*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0, cfx_v8()->ToInt32(array));
196*3ac0a46fSAndroid Build Coastguard Worker double d = cfx_v8()->ToDouble(array);
197*3ac0a46fSAndroid Build Coastguard Worker EXPECT_NE(d, d); // i.e. NaN.
198*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(L",,,12", cfx_v8()->ToWideString(array));
199*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToObject(array)->IsObject());
200*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToArray(array)->IsArray());
201*3ac0a46fSAndroid Build Coastguard Worker }
202*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(CFXV8UnitTest,NewObject)203*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFXV8UnitTest, NewObject) {
204*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate::Scope isolate_scope(isolate());
205*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope handle_scope(isolate());
206*3ac0a46fSAndroid Build Coastguard Worker v8::Context::Scope context_scope(v8::Context::New(isolate()));
207*3ac0a46fSAndroid Build Coastguard Worker
208*3ac0a46fSAndroid Build Coastguard Worker auto object = cfx_v8()->NewObject();
209*3ac0a46fSAndroid Build Coastguard Worker ASSERT_FALSE(object.IsEmpty());
210*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0u, cfx_v8()->GetObjectPropertyNames(object).size());
211*3ac0a46fSAndroid Build Coastguard Worker EXPECT_FALSE(cfx_v8()->GetObjectProperty(object, "clams").IsEmpty());
212*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->GetObjectProperty(object, "clams")->IsUndefined());
213*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0u, cfx_v8()->GetObjectPropertyNames(object).size());
214*3ac0a46fSAndroid Build Coastguard Worker
215*3ac0a46fSAndroid Build Coastguard Worker cfx_v8()->PutObjectProperty(object, "clams", cfx_v8()->NewNumber(12));
216*3ac0a46fSAndroid Build Coastguard Worker EXPECT_FALSE(cfx_v8()->GetObjectProperty(object, "clams").IsEmpty());
217*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->GetObjectProperty(object, "clams")->IsNumber());
218*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(1u, cfx_v8()->GetObjectPropertyNames(object).size());
219*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(L"clams", cfx_v8()->GetObjectPropertyNames(object)[0]);
220*3ac0a46fSAndroid Build Coastguard Worker
221*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToBoolean(object));
222*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(0, cfx_v8()->ToInt32(object));
223*3ac0a46fSAndroid Build Coastguard Worker double d = cfx_v8()->ToDouble(object);
224*3ac0a46fSAndroid Build Coastguard Worker EXPECT_NE(d, d); // i.e. NaN.
225*3ac0a46fSAndroid Build Coastguard Worker EXPECT_EQ(L"[object Object]", cfx_v8()->ToWideString(object));
226*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToObject(object)->IsObject());
227*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->ToArray(object).IsEmpty());
228*3ac0a46fSAndroid Build Coastguard Worker }
229*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(CFXV8UnitTest,ThrowFromGetter)230*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFXV8UnitTest, ThrowFromGetter) {
231*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate::Scope isolate_scope(isolate());
232*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope handle_scope(isolate());
233*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Context> context = v8::Context::New(isolate());
234*3ac0a46fSAndroid Build Coastguard Worker v8::Context::Scope context_scope(context);
235*3ac0a46fSAndroid Build Coastguard Worker
236*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> object = cfx_v8()->NewObject();
237*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::String> name = cfx_v8()->NewString("clams");
238*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(
239*3ac0a46fSAndroid Build Coastguard Worker object
240*3ac0a46fSAndroid Build Coastguard Worker ->SetAccessor(context, name,
241*3ac0a46fSAndroid Build Coastguard Worker [](v8::Local<v8::Name> property,
242*3ac0a46fSAndroid Build Coastguard Worker const v8::PropertyCallbackInfo<v8::Value>& info) {
243*3ac0a46fSAndroid Build Coastguard Worker getter_sentinel = true;
244*3ac0a46fSAndroid Build Coastguard Worker info.GetIsolate()->ThrowException(property);
245*3ac0a46fSAndroid Build Coastguard Worker })
246*3ac0a46fSAndroid Build Coastguard Worker .FromJust());
247*3ac0a46fSAndroid Build Coastguard Worker getter_sentinel = false;
248*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(cfx_v8()->GetObjectProperty(object, "clams").IsEmpty());
249*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(getter_sentinel);
250*3ac0a46fSAndroid Build Coastguard Worker }
251*3ac0a46fSAndroid Build Coastguard Worker
TEST_F(CFXV8UnitTest,ThrowFromSetter)252*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFXV8UnitTest, ThrowFromSetter) {
253*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate::Scope isolate_scope(isolate());
254*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope handle_scope(isolate());
255*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Context> context = v8::Context::New(isolate());
256*3ac0a46fSAndroid Build Coastguard Worker v8::Context::Scope context_scope(context);
257*3ac0a46fSAndroid Build Coastguard Worker
258*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> object = cfx_v8()->NewObject();
259*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::String> name = cfx_v8()->NewString("clams");
260*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(object
261*3ac0a46fSAndroid Build Coastguard Worker ->SetAccessor(context, name, nullptr,
262*3ac0a46fSAndroid Build Coastguard Worker [](v8::Local<v8::Name> property,
263*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value> value,
264*3ac0a46fSAndroid Build Coastguard Worker const v8::PropertyCallbackInfo<void>& info) {
265*3ac0a46fSAndroid Build Coastguard Worker setter_sentinel = true;
266*3ac0a46fSAndroid Build Coastguard Worker info.GetIsolate()->ThrowException(property);
267*3ac0a46fSAndroid Build Coastguard Worker })
268*3ac0a46fSAndroid Build Coastguard Worker .FromJust());
269*3ac0a46fSAndroid Build Coastguard Worker setter_sentinel = false;
270*3ac0a46fSAndroid Build Coastguard Worker cfx_v8()->PutObjectProperty(object, "clams", name);
271*3ac0a46fSAndroid Build Coastguard Worker EXPECT_TRUE(setter_sentinel);
272*3ac0a46fSAndroid Build Coastguard Worker }
273