1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "ecmascript/builtins/builtins_object.h"
17
18#include "ecmascript/ecma_runtime_call_info.h"
19#include "ecmascript/ecma_string.h"
20#include "ecmascript/ecma_vm.h"
21#include "ecmascript/global_env.h"
22#include "ecmascript/js_array.h"
23#include "ecmascript/js_handle.h"
24#include "ecmascript/js_object-inl.h"
25#include "ecmascript/js_primitive_ref.h"
26#include "ecmascript/js_tagged_value-inl.h"
27#include "ecmascript/js_thread.h"
28#include "ecmascript/object_factory.h"
29#include "ecmascript/tests/test_helper.h"
30
31using namespace panda::ecmascript;
32using namespace panda::ecmascript::builtins;
33
34namespace panda::test {
35class BuiltinsObjectTest : public BaseTestWithScope<false> {
36};
37
38JSTaggedValue CreateBuiltinJSObject(JSThread *thread, const CString keyCStr)
39{
40    EcmaVM *ecmaVM = thread->GetEcmaVM();
41    JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
42    JSHandle<JSTaggedValue> objFun = globalEnv->GetObjectFunction();
43    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
44
45    JSHandle<JSTaggedValue> obj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
46    JSHandle<JSTaggedValue> key(factory->NewFromASCII(&keyCStr[0]));
47    JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
48    JSObject::SetProperty(thread, obj, key, value);
49    return obj.GetTaggedValue();
50}
51
52JSFunction *BuiltinsObjectTestCreate(JSThread *thread)
53{
54    EcmaVM *ecmaVM = thread->GetEcmaVM();
55    JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
56    return globalEnv->GetObjectFunction().GetObject<JSFunction>();
57}
58
59JSObject *TestNewJSObject(JSThread *thread, const JSHandle<JSHClass> &hclass)
60{
61    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
62    JSObject *obj = JSObject::Cast(factory->NewObject(hclass));
63
64    obj->SetElements(thread, factory->EmptyArray().GetTaggedValue(), SKIP_BARRIER);
65    return obj;
66}
67
68// 19.1.1.1Object ( [ value ] )
69HWTEST_F_L0(BuiltinsObjectTest, ObjectConstructor)
70{
71    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
72    JSHandle<JSFunction> objectFunc(thread, BuiltinsObjectTestCreate(thread));
73    JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
74    JSHandle<JSFunction> objFun(globalEnv->GetObjectFunction());
75
76    auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
77    objCallInfo->SetFunction(JSTaggedValue::Undefined());
78    objCallInfo->SetThis(JSTaggedValue::Undefined());
79
80    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
81    JSTaggedValue result = BuiltinsObject::ObjectConstructor(objCallInfo);
82    TestHelper::TearDownFrame(thread, prev);
83
84    ASSERT_TRUE(result.IsECMAObject());
85    JSHandle<JSObject> jtHandle(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(result.GetRawData())));
86    JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(jtHandle));
87    JSTaggedValue funcProto = objectFunc->GetFunctionPrototype();
88    ASSERT_EQ(resultProto, funcProto);
89    ASSERT_TRUE(jtHandle->IsExtensible());
90
91    // num_args = 0
92    JSHandle<JSObject> object =
93        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(function), function);
94    object->GetJSHClass()->SetCallable(true);
95    auto tgObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*object), 4);
96    tgObjCallInfo->SetFunction(JSTaggedValue(*objFun));
97    tgObjCallInfo->SetThis(JSTaggedValue::Undefined());
98    tgObjCallInfo->SetNewTarget(JSTaggedValue(*objFun));
99
100    prev = TestHelper::SetupFrame(thread, tgObjCallInfo);
101    JSTaggedValue resultTg = BuiltinsObject::ObjectConstructor(tgObjCallInfo);
102    TestHelper::TearDownFrame(thread, prev);
103    ASSERT_TRUE(resultTg.IsObject());
104    JSHandle<JSObject> jtHandleTg(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(resultTg.GetRawData())));
105    JSTaggedValue resultProtoTg = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(jtHandleTg));
106    JSTaggedValue funcProtoTg = objectFunc->GetFunctionPrototype();
107    ASSERT_EQ(resultProtoTg, funcProtoTg);
108    ASSERT_TRUE(jtHandleTg->IsExtensible());
109
110    // value is null
111    JSHandle<JSObject> objectVn =
112        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(function), function);
113    objectVn->GetJSHClass()->SetCallable(true);
114    auto vnObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*objectVn), 6);
115    vnObjCallInfo->SetFunction(JSTaggedValue(*objFun));
116    vnObjCallInfo->SetThis(JSTaggedValue::Undefined());
117    vnObjCallInfo->SetCallArg(0, JSTaggedValue::Null());
118    vnObjCallInfo->SetNewTarget(JSTaggedValue(*objFun));
119
120    prev = TestHelper::SetupFrame(thread, vnObjCallInfo);
121    JSTaggedValue resultVn = BuiltinsObject::ObjectConstructor(vnObjCallInfo);
122    TestHelper::TearDownFrame(thread, prev);
123
124    ASSERT_TRUE(resultVn.IsObject());
125    JSHandle<JSObject> jtHandleVn(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(resultVn.GetRawData())));
126    JSTaggedValue resultProtoVn = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(jtHandleVn));
127    JSTaggedValue funcProtoVn = objectFunc->GetFunctionPrototype();
128    ASSERT_EQ(resultProtoVn, funcProtoVn);
129    ASSERT_TRUE(jtHandleVn->IsExtensible());
130}
131
132// 19.1.2.1Object.assign ( target, ...sources )
133HWTEST_F_L0(BuiltinsObjectTest, Assign)
134{
135    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
136    JSHandle<JSObject> objHandle1 =
137        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
138    JSHandle<JSObject> objHandle2 =
139        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
140
141    JSHandle<JSTaggedValue> key1(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
142    JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
143    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(objHandle1), key1, value1);
144    EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(objHandle1), key1).GetValue()->GetInt(), 1);
145
146    JSHandle<JSTaggedValue> key2(thread->GetEcmaVM()->GetFactory()->NewFromASCII("y"));
147    JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
148    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(objHandle2), key2, value2);
149    EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(objHandle2), key2).GetValue()->GetInt(), 2);
150
151    auto assignObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
152    assignObjCallInfo->SetFunction(JSTaggedValue::Undefined());
153    assignObjCallInfo->SetThis(JSTaggedValue::Undefined());
154    assignObjCallInfo->SetCallArg(0, objHandle1.GetTaggedValue());
155    assignObjCallInfo->SetCallArg(1, objHandle2.GetTaggedValue());
156
157    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, assignObjCallInfo);
158    JSTaggedValue result = BuiltinsObject::Assign(assignObjCallInfo);
159    TestHelper::TearDownFrame(thread, prev);
160
161    ASSERT_TRUE(result.IsECMAObject());
162    JSHandle<JSTaggedValue> jtHandle(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(result.GetRawData())));
163    EXPECT_EQ(JSObject::GetProperty(thread, jtHandle, key1).GetValue()->GetInt(), 1);
164    EXPECT_EQ(JSObject::GetProperty(thread, jtHandle, key2).GetValue()->GetInt(), 2);
165}
166
167// 19.1.2.2Object.create ( O [ , Properties ] )
168HWTEST_F_L0(BuiltinsObjectTest, Create)
169{
170    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
171    JSHandle<JSFunction> objectFunc(thread, BuiltinsObjectTestCreate(thread));
172    JSHandle<JSTaggedValue> funcProto(thread, objectFunc->GetFunctionPrototype());
173
174    // no prop
175    auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
176    objCallInfo->SetFunction(JSTaggedValue::Undefined());
177    objCallInfo->SetThis(JSTaggedValue::Undefined());
178    objCallInfo->SetCallArg(0, funcProto.GetTaggedValue());
179
180    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
181    JSTaggedValue result = BuiltinsObject::Create(objCallInfo);
182    TestHelper::TearDownFrame(thread, prev);
183
184    ASSERT_TRUE(result.IsECMAObject());
185    JSHandle<JSTaggedValue> jtHandle(thread, result);
186    JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, jtHandle);
187    ASSERT_EQ(resultProto, funcProto.GetTaggedValue());
188
189    // has prop
190    JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("prop"));
191    JSHandle<JSObject> objHandle =
192        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(function), function);
193    EXPECT_TRUE(*objHandle != nullptr);
194
195    PropertyDescriptor desc(thread);
196    desc.SetWritable(false);
197    JSHandle<JSObject> descHandle(JSObject::FromPropertyDescriptor(thread, desc));
198
199    PropertyDescriptor descNw(thread, JSHandle<JSTaggedValue>::Cast(descHandle), true, true, true);
200    JSObject::DefineOwnProperty(thread, objHandle, key, descNw);
201
202    auto hpObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
203    hpObjCallInfo->SetFunction(JSTaggedValue::Undefined());
204    hpObjCallInfo->SetThis(JSTaggedValue::Undefined());
205    hpObjCallInfo->SetCallArg(0, funcProto.GetTaggedValue());
206    hpObjCallInfo->SetCallArg(1, objHandle.GetTaggedValue());
207
208    prev = TestHelper::SetupFrame(thread, hpObjCallInfo);
209    JSTaggedValue resultHp = BuiltinsObject::Create(hpObjCallInfo);
210    TestHelper::TearDownFrame(thread, prev);
211
212    ASSERT_TRUE(resultHp.IsObject());
213    PropertyDescriptor descRes(thread);
214    bool success = JSObject::GetOwnProperty(thread, JSHandle<JSObject>(thread, resultHp), key, descRes);
215    EXPECT_TRUE(success);
216    EXPECT_TRUE(!descRes.IsWritable());
217
218    // undefined
219    auto unCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
220    unCallInfo->SetFunction(JSTaggedValue::Undefined());
221    unCallInfo->SetThis(JSTaggedValue::Undefined());
222    unCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
223
224    prev = TestHelper::SetupFrame(thread, unCallInfo);
225    JSTaggedValue resultUn = BuiltinsObject::Create(unCallInfo);
226    TestHelper::TearDownFrame(thread, prev);
227    ASSERT_EQ(resultUn.GetRawData(), JSTaggedValue::VALUE_EXCEPTION);
228}
229
230// 19.1.2.3Object.defineProperties ( O, Properties )
231HWTEST_F_L0(BuiltinsObjectTest, DefineProperties)
232{
233    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
234    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
235    JSHandle<JSFunction> objFunc(env->GetObjectFunction());
236    JSHandle<JSObject> objHandle =
237        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
238    JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("prop"));
239    JSHandle<JSObject> jsobjHandle =
240        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
241
242    PropertyDescriptor desc(thread);
243    desc.SetWritable(false);
244    JSHandle<JSObject> descHandle(JSObject::FromPropertyDescriptor(thread, desc));
245
246    PropertyDescriptor descNw(thread, JSHandle<JSTaggedValue>::Cast(descHandle), true, true, true);
247    JSObject::DefineOwnProperty(thread, jsobjHandle, key, descNw);
248
249    auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
250    objCallInfo->SetFunction(JSTaggedValue::Undefined());
251    objCallInfo->SetThis(JSTaggedValue::Undefined());
252    objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
253    objCallInfo->SetCallArg(1, jsobjHandle.GetTaggedValue());
254
255    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
256    JSTaggedValue result = BuiltinsObject::DefineProperties(objCallInfo);
257    TestHelper::TearDownFrame(thread, prev);
258
259    ASSERT_TRUE(result.IsECMAObject());
260    JSTaggedValue res(reinterpret_cast<TaggedObject *>(result.GetRawData()));
261    PropertyDescriptor descRes(thread);
262    JSObject::GetOwnProperty(thread, JSHandle<JSObject>(thread, res), key, descRes);
263    EXPECT_TRUE(!descRes.IsWritable());
264}
265
266// 19.1.2.4Object.defineProperty ( O, P, Attributes )
267HWTEST_F_L0(BuiltinsObjectTest, DefineProperty)
268{
269    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
270
271    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
272    JSHandle<JSFunction> objFunc(env->GetObjectFunction());
273    JSHandle<JSObject> attHandle =
274        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
275    JSHandle<JSObject> objHandle =
276        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
277
278    PropertyDescriptor desc(thread);
279    desc.SetWritable(true);
280    JSHandle<JSTaggedValue> writableStr = thread->GlobalConstants()->GetHandledWritableString();
281    JSHandle<JSTaggedValue> writable(thread, JSTaggedValue(desc.IsWritable()));
282    JSObject::CreateDataProperty(thread, attHandle, writableStr, writable);
283
284    JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
285
286    PropertyDescriptor descNw(thread);
287    JSObject::GetOwnProperty(thread, objHandle, key, descNw);
288    EXPECT_TRUE(!descNw.HasWritable());
289
290    auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
291    objCallInfo->SetFunction(JSTaggedValue::Undefined());
292    objCallInfo->SetThis(JSTaggedValue::Undefined());
293    objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
294    objCallInfo->SetCallArg(1, key.GetTaggedValue());
295    objCallInfo->SetCallArg(2, attHandle.GetTaggedValue());
296
297    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
298    JSTaggedValue result = BuiltinsObject::DefineProperty(objCallInfo);
299    TestHelper::TearDownFrame(thread, prev);
300
301    ASSERT_TRUE(result.IsECMAObject());
302    JSTaggedValue res(reinterpret_cast<TaggedObject *>(result.GetRawData()));
303    PropertyDescriptor descRes(thread);
304    JSObject::GetOwnProperty(thread, JSHandle<JSObject>(thread, res), key, descRes);
305    EXPECT_TRUE(descRes.HasWritable());
306}
307
308// 19.1.2.5Object.freeze ( O )
309HWTEST_F_L0(BuiltinsObjectTest, Freeze)
310{
311    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
312    // An object is extensible by default, so it is also non-frozen.
313    JSHandle<JSObject> emptyObj =
314        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
315    emptyObj->GetJSHClass()->SetExtensible(true);
316    auto nofreezeObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
317    nofreezeObjCallInfo->SetFunction(JSTaggedValue::Undefined());
318    nofreezeObjCallInfo->SetThis(JSTaggedValue::Undefined());
319    nofreezeObjCallInfo->SetCallArg(0, emptyObj.GetTaggedValue());
320
321    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, nofreezeObjCallInfo);
322    JSTaggedValue result = BuiltinsObject::IsFrozen(nofreezeObjCallInfo);
323
324    ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
325
326    BuiltinsObject::Freeze(nofreezeObjCallInfo);
327    JSTaggedValue resultIs = BuiltinsObject::IsFrozen(nofreezeObjCallInfo);
328    TestHelper::TearDownFrame(thread, prev);
329    ASSERT_EQ(resultIs.GetRawData(), JSTaggedValue::True().GetRawData());
330}
331
332// 19.1.2.6 Object.getOwnPropertyDescriptor ( O, P )
333HWTEST_F_L0(BuiltinsObjectTest, GetOwnPropertyDescriptor)
334{
335    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
336    JSHandle<JSObject> objHandle =
337        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
338
339    JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
340
341    PropertyDescriptor descEnum(thread);
342    descEnum.SetWritable(true);
343    JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(objHandle), key, descEnum);
344
345    auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
346    objCallInfo->SetFunction(JSTaggedValue::Undefined());
347    objCallInfo->SetThis(JSTaggedValue::Undefined());
348    objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
349    objCallInfo->SetCallArg(1, key.GetTaggedValue());
350
351    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
352    JSTaggedValue result = BuiltinsObject::GetOwnPropertyDescriptor(objCallInfo);
353    TestHelper::TearDownFrame(thread, prev);
354
355    ASSERT_TRUE(result.IsECMAObject());
356
357    JSHandle<JSTaggedValue> writableStr = thread->GlobalConstants()->GetHandledWritableString();
358    JSTaggedValue jt(reinterpret_cast<TaggedObject *>(result.GetRawData()));
359    PropertyDescriptor desc(thread);
360    JSObject::GetOwnProperty(thread, JSHandle<JSObject>(thread, jt), writableStr, desc);
361    ASSERT_TRUE(JSTaggedValue::SameValue(desc.GetValue().GetTaggedValue(), JSTaggedValue(true)));
362}
363
364// 19.1.2.7 Object.getOwnPropertyNames ( O )
365HWTEST_F_L0(BuiltinsObjectTest, GetOwnPropertyNames)
366{
367    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
368    JSHandle<JSObject> objHandle =
369        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
370
371    JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
372    JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
373    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(objHandle), key, value);
374
375    auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
376    objCallInfo->SetFunction(JSTaggedValue::Undefined());
377    objCallInfo->SetThis(JSTaggedValue::Undefined());
378    objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
379
380    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
381    JSTaggedValue result = BuiltinsObject::GetOwnPropertyNames(objCallInfo);
382    TestHelper::TearDownFrame(thread, prev);
383
384    ASSERT_TRUE(result.IsECMAObject());
385}
386
387// 19.1.2.8 Object.getOwnPropertySymbols ( O )
388HWTEST_F_L0(BuiltinsObjectTest, GetOwnPropertySymbols)
389{
390    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
391    JSHandle<JSObject> objHandle =
392        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
393    JSHandle<JSSymbol> symbolKey = thread->GetEcmaVM()->GetFactory()->NewJSSymbol();
394    JSHandle<JSTaggedValue> key(symbolKey);
395    JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
396    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(objHandle), key, value);
397    thread->ClearException();
398
399    auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
400    objCallInfo->SetFunction(JSTaggedValue::Undefined());
401    objCallInfo->SetThis(JSTaggedValue::Undefined());
402    objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
403
404    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
405    JSTaggedValue result = BuiltinsObject::GetOwnPropertySymbols(objCallInfo);
406    TestHelper::TearDownFrame(thread, prev);
407
408    ASSERT_TRUE(result.IsECMAObject());
409}
410
411// 19.1.2.10 Object.is ( value1, value2 )
412HWTEST_F_L0(BuiltinsObjectTest, Is)
413{
414    // js object compare
415    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
416
417    JSHandle<JSObject> obj1 =
418        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
419    JSHandle<JSObject> obj2 =
420        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
421
422    auto objCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
423    objCallInfo1->SetFunction(JSTaggedValue::Undefined());
424    objCallInfo1->SetThis(JSTaggedValue::Undefined());
425    objCallInfo1->SetCallArg(0, obj1.GetTaggedValue());
426    objCallInfo1->SetCallArg(1, obj2.GetTaggedValue());
427
428    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo1);
429    JSTaggedValue objResult1 = BuiltinsObject::Is(objCallInfo1);
430    TestHelper::TearDownFrame(thread, prev);
431
432    ASSERT_EQ(objResult1.GetRawData(), JSTaggedValue::False().GetRawData());
433
434    objCallInfo1->SetCallArg(1, obj1.GetTaggedValue());
435    JSTaggedValue objResult2 = BuiltinsObject::Is(objCallInfo1);
436    ASSERT_EQ(objResult2.GetRawData(), JSTaggedValue::True().GetRawData());
437
438    // string compare
439    JSHandle<EcmaString> testStrValue1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("helloworld");
440    JSHandle<EcmaString> testStrValue2 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("helloworld");
441
442    auto strCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
443    strCallInfo->SetFunction(JSTaggedValue::Undefined());
444    strCallInfo->SetThis(JSTaggedValue::Undefined());
445    strCallInfo->SetCallArg(0, testStrValue1.GetTaggedValue());
446    strCallInfo->SetCallArg(1, testStrValue2.GetTaggedValue());
447
448    prev = TestHelper::SetupFrame(thread, strCallInfo);
449    JSTaggedValue strResult = BuiltinsObject::Is(strCallInfo);
450    TestHelper::TearDownFrame(thread, prev);
451
452    ASSERT_EQ(strResult.GetRawData(), JSTaggedValue::True().GetRawData());
453
454    // bool compare
455    auto boolCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
456    boolCallInfo->SetFunction(JSTaggedValue::Undefined());
457    boolCallInfo->SetThis(JSTaggedValue::Undefined());
458    boolCallInfo->SetCallArg(0, JSTaggedValue::True());
459    boolCallInfo->SetCallArg(1, JSTaggedValue::False());
460
461    prev = TestHelper::SetupFrame(thread, boolCallInfo);
462    JSTaggedValue boolResult = BuiltinsObject::Is(boolCallInfo);
463    TestHelper::TearDownFrame(thread, prev);
464
465    ASSERT_EQ(boolResult.GetRawData(), JSTaggedValue::False().GetRawData());
466
467    // number compare
468    auto numCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
469    numCallInfo->SetFunction(JSTaggedValue::Undefined());
470    numCallInfo->SetThis(JSTaggedValue::Undefined());
471    numCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(0)));
472    numCallInfo->SetCallArg(1, JSTaggedValue(-0.0));
473
474    prev = TestHelper::SetupFrame(thread, numCallInfo);
475    JSTaggedValue numResult = BuiltinsObject::Is(numCallInfo);
476    TestHelper::TearDownFrame(thread, prev);
477
478    ASSERT_EQ(numResult.GetRawData(), JSTaggedValue::False().GetRawData());
479
480    // undefined or null compare
481    auto nullCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
482    nullCallInfo->SetFunction(JSTaggedValue::Undefined());
483    nullCallInfo->SetThis(JSTaggedValue::Undefined());
484    nullCallInfo->SetCallArg(0, JSTaggedValue::Null());
485    nullCallInfo->SetCallArg(1, JSTaggedValue::Null());
486
487    prev = TestHelper::SetupFrame(thread, nullCallInfo);
488    JSTaggedValue nullResult = BuiltinsObject::Is(nullCallInfo);
489    TestHelper::TearDownFrame(thread, prev);
490
491    ASSERT_EQ(nullResult.GetRawData(), JSTaggedValue::True().GetRawData());
492
493    auto undefineCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
494    undefineCallInfo->SetFunction(JSTaggedValue::Undefined());
495    undefineCallInfo->SetThis(JSTaggedValue::Undefined());
496    undefineCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
497    undefineCallInfo->SetCallArg(1, JSTaggedValue::Undefined());
498
499    prev = TestHelper::SetupFrame(thread, undefineCallInfo);
500    JSTaggedValue undefineResult = BuiltinsObject::Is(undefineCallInfo);
501    TestHelper::TearDownFrame(thread, prev);
502
503    ASSERT_EQ(undefineResult.GetRawData(), JSTaggedValue::True().GetRawData());
504}
505
506// 19.1.2.11 Object.isExtensible ( O )
507HWTEST_F_L0(BuiltinsObjectTest, IsExtensible)
508{
509    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
510
511    // New objects can be extended by default.
512    JSHandle<JSObject> emptyObj =
513        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
514    emptyObj->GetJSHClass()->SetExtensible(true);
515    std::vector<JSTaggedValue> args{emptyObj.GetTaggedValue()};
516    auto emptyObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6);
517
518    auto prev = TestHelper::SetupFrame(thread, emptyObjCallInfo);
519    JSTaggedValue result = BuiltinsObject::IsExtensible(emptyObjCallInfo);
520    TestHelper::TearDownFrame(thread, prev);
521
522    ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
523
524    emptyObj->GetJSHClass()->SetExtensible(false);
525    JSTaggedValue result2 = BuiltinsObject::IsExtensible(emptyObjCallInfo);
526    ASSERT_EQ(result2.GetRawData(), JSTaggedValue::False().GetRawData());
527}
528
529// 19.1.2.12 Object.isFrozen ( O )
530HWTEST_F_L0(BuiltinsObjectTest, IsFrozen)
531{
532    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
533    JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
534    JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
535
536    // An object is extensible by default, so it is also non-frozen.
537    JSHandle<JSObject> obj =
538        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(function), function);
539    obj->GetJSHClass()->SetExtensible(true);
540    auto emptyObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
541    emptyObjCallInfo->SetFunction(JSTaggedValue::Undefined());
542    emptyObjCallInfo->SetThis(JSTaggedValue::Undefined());
543    emptyObjCallInfo->SetCallArg(0, obj.GetTaggedValue());
544
545    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, emptyObjCallInfo);
546    JSTaggedValue result = BuiltinsObject::IsFrozen(emptyObjCallInfo);
547    TestHelper::TearDownFrame(thread, prev);
548
549    ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
550
551    obj->GetJSHClass()->SetExtensible(false);
552    prev = TestHelper::SetupFrame(thread, emptyObjCallInfo);
553    JSTaggedValue resultNex = BuiltinsObject::IsFrozen(emptyObjCallInfo);
554    TestHelper::TearDownFrame(thread, prev);
555    ASSERT_EQ(resultNex.GetRawData(), JSTaggedValue::True().GetRawData());
556
557    PropertyDescriptor descEnum(thread);
558    descEnum.SetConfigurable(true);
559    descEnum.SetWritable(false);
560    obj->GetJSHClass()->SetExtensible(true);
561    JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(obj), key, descEnum);
562    obj->GetJSHClass()->SetExtensible(false);
563    auto emptyObjCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
564    emptyObjCallInfo2->SetFunction(JSTaggedValue::Undefined());
565    emptyObjCallInfo2->SetThis(JSTaggedValue::Undefined());
566    emptyObjCallInfo2->SetCallArg(0, obj.GetTaggedValue());
567
568    prev = TestHelper::SetupFrame(thread, emptyObjCallInfo2);
569    JSTaggedValue resultNw = BuiltinsObject::IsFrozen(emptyObjCallInfo2);
570    TestHelper::TearDownFrame(thread, prev);
571
572    ASSERT_EQ(resultNw.GetRawData(), JSTaggedValue::False().GetRawData());
573
574    descEnum.SetConfigurable(false);
575    obj->GetJSHClass()->SetExtensible(true);
576    JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(obj), key, descEnum);
577    obj->GetJSHClass()->SetExtensible(false);
578    auto emptyObjCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
579    emptyObjCallInfo3->SetFunction(JSTaggedValue::Undefined());
580    emptyObjCallInfo3->SetThis(JSTaggedValue::Undefined());
581    emptyObjCallInfo3->SetCallArg(0, obj.GetTaggedValue());
582
583    prev = TestHelper::SetupFrame(thread, emptyObjCallInfo3);
584    JSTaggedValue resultNc = BuiltinsObject::IsFrozen(emptyObjCallInfo3);
585    TestHelper::TearDownFrame(thread, prev);
586
587    ASSERT_EQ(resultNc.GetRawData(), JSTaggedValue::True().GetRawData());
588}
589
590// 19.1.2.13 Object.isSealed ( O )
591HWTEST_F_L0(BuiltinsObjectTest, IsSealed)
592{
593    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
594
595    // An object is extensible by default, so it is also non-frozen.
596    JSHandle<JSObject> emptyObj =
597        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
598    emptyObj->GetJSHClass()->SetExtensible(true);
599
600    std::vector<JSTaggedValue> args{emptyObj.GetTaggedValue()};
601    auto emptyObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6);
602
603    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, emptyObjCallInfo);
604    JSTaggedValue result = BuiltinsObject::IsSealed(emptyObjCallInfo);
605    TestHelper::TearDownFrame(thread, prev);
606
607    ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
608}
609
610// Object.keys(obj)
611HWTEST_F_L0(BuiltinsObjectTest, Keys)
612{
613    JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
614    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
615    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
616    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
617    ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
618
619    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
620    JSTaggedValue result = BuiltinsObject::Keys(ecmaRuntimeCallInfo);
621    TestHelper::TearDownFrame(thread, prev);
622
623    ASSERT_TRUE(result.IsECMAObject());
624}
625
626// Object.values(obj)
627HWTEST_F_L0(BuiltinsObjectTest, Values)
628{
629    JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
630    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
631    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
632    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
633    ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
634
635    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
636    JSTaggedValue result = BuiltinsObject::Values(ecmaRuntimeCallInfo);
637    TestHelper::TearDownFrame(thread, prev);
638
639    ASSERT_TRUE(result.IsECMAObject());
640}
641
642// Object.preventExtensions(obj)
643HWTEST_F_L0(BuiltinsObjectTest, PreventExtensions)
644{
645    JSHandle<JSObject> obj(thread, CreateBuiltinJSObject(thread, "x"));
646    obj->GetJSHClass()->SetExtensible(true);
647    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
648    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
649    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
650    ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
651
652    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
653    JSTaggedValue result = BuiltinsObject::PreventExtensions(ecmaRuntimeCallInfo);
654    TestHelper::TearDownFrame(thread, prev);
655
656    ASSERT_TRUE(result.IsECMAObject());
657    JSTaggedValue jt(reinterpret_cast<TaggedObject *>(result.GetRawData()));
658    JSHandle<JSObject> jtHandle(thread, jt);
659    ASSERT_TRUE(!jtHandle->IsExtensible());
660}
661
662// Object.seal(obj)
663HWTEST_F_L0(BuiltinsObjectTest, Seal)
664{
665    JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
666    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
667    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
668    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
669    ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
670
671    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
672    JSTaggedValue result = BuiltinsObject::Seal(ecmaRuntimeCallInfo);
673
674    ASSERT_TRUE(result.IsECMAObject());
675    ASSERT_EQ(result.GetRawData(), obj->GetRawData());
676
677    // test isSealed().
678    JSTaggedValue res = BuiltinsObject::IsSealed(ecmaRuntimeCallInfo);
679    TestHelper::TearDownFrame(thread, prev);
680    ASSERT_EQ(res.GetRawData(), JSTaggedValue::True().GetRawData());
681}
682
683// Object.setPrototypeOf(obj, prototype)
684HWTEST_F_L0(BuiltinsObjectTest, SetPrototypeOf)
685{
686    JSHandle<JSObject> obj(thread, CreateBuiltinJSObject(thread, "x"));
687    JSHandle<JSObject> objFather(thread, CreateBuiltinJSObject(thread, "y"));
688
689    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
690    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
691    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
692    ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
693    ecmaRuntimeCallInfo->SetCallArg(1, objFather.GetTaggedValue());
694
695    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
696    JSTaggedValue result = BuiltinsObject::SetPrototypeOf(ecmaRuntimeCallInfo);
697    TestHelper::TearDownFrame(thread, prev);
698
699    ASSERT_TRUE(result.IsECMAObject());
700    ASSERT_EQ(result.GetRawData(), obj.GetTaggedValue().GetRawData());
701
702    // test obj has property "y".
703    JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("y"));
704    EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue()->GetInt(), 1);
705}
706
707// obj.hasOwnProperty(prop)
708HWTEST_F_L0(BuiltinsObjectTest, HasOwnProperty)
709{
710    JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
711    CString keyCStr = "x";
712    JSHandle<EcmaString> keyString = thread->GetEcmaVM()->GetFactory()->NewFromASCII(&keyCStr[0]);
713    JSHandle<JSTaggedValue> key(keyString);
714
715    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
716    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
717    ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
718    ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
719
720    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
721    JSTaggedValue result = BuiltinsObject::HasOwnProperty(ecmaRuntimeCallInfo);
722    TestHelper::TearDownFrame(thread, prev);
723
724    ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
725}
726
727// prototypeObj.isPrototypeOf(object)
728HWTEST_F_L0(BuiltinsObjectTest, IsPrototypeOfFalse)
729{
730    JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
731    JSHandle<JSTaggedValue> objFather(thread, CreateBuiltinJSObject(thread, "y"));
732
733    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
734    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
735    ecmaRuntimeCallInfo->SetThis(objFather.GetTaggedValue());
736    ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
737
738    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
739    JSTaggedValue result1 = BuiltinsObject::IsPrototypeOf(ecmaRuntimeCallInfo);
740    TestHelper::TearDownFrame(thread, prev);
741
742    ASSERT_EQ(result1.GetRawData(), JSTaggedValue::False().GetRawData());
743}
744
745HWTEST_F_L0(BuiltinsObjectTest, IsPrototypeOfTrue)
746{
747    JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
748    JSHandle<JSTaggedValue> objFather(thread, CreateBuiltinJSObject(thread, "y"));
749
750    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
751    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
752    ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
753    ecmaRuntimeCallInfo1->SetCallArg(0, obj.GetTaggedValue());
754    ecmaRuntimeCallInfo1->SetCallArg(1, objFather.GetTaggedValue());
755
756    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
757    JSTaggedValue result1 = BuiltinsObject::SetPrototypeOf(ecmaRuntimeCallInfo1);
758    TestHelper::TearDownFrame(thread, prev);
759
760    ASSERT_TRUE(result1.IsObject());
761    ASSERT_EQ(result1.GetRawData(), obj->GetRawData());
762
763    auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
764    ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
765    ecmaRuntimeCallInfo2->SetThis(objFather.GetTaggedValue());
766    ecmaRuntimeCallInfo2->SetCallArg(0, obj.GetTaggedValue());
767
768    prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
769    JSTaggedValue result2 = BuiltinsObject::IsPrototypeOf(ecmaRuntimeCallInfo2);
770    TestHelper::TearDownFrame(thread, prev);
771
772    ASSERT_EQ(result2.GetRawData(), JSTaggedValue::True().GetRawData());
773}
774
775// obj.propertyIsEnumerable(prop)
776HWTEST_F_L0(BuiltinsObjectTest, PropertyIsEnumerable)
777{
778    JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
779    JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
780
781    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
782    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
783    ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
784    ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
785
786    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
787    JSTaggedValue result = BuiltinsObject::PropertyIsEnumerable(ecmaRuntimeCallInfo);
788    TestHelper::TearDownFrame(thread, prev);
789
790    ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
791}
792
793// obj.toLocaleString()
794HWTEST_F_L0(BuiltinsObjectTest, ToLocaleString)
795{
796    JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
797    JSHandle<JSFunction> calleeFunc = thread->GetEcmaVM()->GetFactory()->NewJSFunction(
798        thread->GetEcmaVM()->GetGlobalEnv(), reinterpret_cast<void *>(BuiltinsObject::ToString));
799    calleeFunc->GetClass()->SetCallable(true);
800    JSHandle<JSTaggedValue> calleeValue(calleeFunc);
801    JSHandle<JSTaggedValue> calleeKey(thread->GetEcmaVM()->GetFactory()->NewFromASCII("toString"));
802    JSObject::SetProperty(thread, obj, calleeKey, calleeValue);
803
804    JSHandle<EcmaString> resultValue = thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Object]");
805
806    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
807    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
808    ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
809    ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
810
811    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
812    JSTaggedValue result = BuiltinsObject::ToLocaleString(ecmaRuntimeCallInfo);
813    TestHelper::TearDownFrame(thread, prev);
814
815    ASSERT_TRUE(result.IsString());
816    ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultValue, JSHandle<EcmaString>(thread, result)), 0);
817}
818
819// obj.toString()
820HWTEST_F_L0(BuiltinsObjectTest, ToString)
821{
822    JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(thread, CreateBuiltinJSObject(thread, "x"));
823
824    // object
825    JSHandle<EcmaString> resultValue = thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Object]");
826    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
827    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
828    ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
829
830    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
831    JSTaggedValue result = BuiltinsObject::ToString(ecmaRuntimeCallInfo);
832    TestHelper::TearDownFrame(thread, prev);
833
834    ASSERT_TRUE(result.IsString());
835    ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultValue, JSHandle<EcmaString>(thread, result)), 0);
836
837    // array
838    JSHandle<JSArray> arr = thread->GetEcmaVM()->GetFactory()->NewJSArray();
839    JSHandle<EcmaString> resultArrValue =
840        thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Array]");
841    auto arrEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
842    arrEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
843    arrEcmaRuntimeCallInfo->SetThis(arr.GetTaggedValue());
844
845    prev = TestHelper::SetupFrame(thread, arrEcmaRuntimeCallInfo);
846    JSTaggedValue resultArr = BuiltinsObject::ToString(arrEcmaRuntimeCallInfo);
847    TestHelper::TearDownFrame(thread, prev);
848
849    ASSERT_TRUE(resultArr.IsString());
850    ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultArrValue, JSHandle<EcmaString>(thread, resultArr)), 0);
851
852    // string
853    JSHandle<EcmaString> str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("hello");
854    JSHandle<EcmaString> resultStrValue =
855        thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object String]");
856    auto strEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
857    strEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
858    strEcmaRuntimeCallInfo->SetThis(str.GetTaggedValue());
859
860    prev = TestHelper::SetupFrame(thread, strEcmaRuntimeCallInfo);
861    JSTaggedValue resultStr = BuiltinsObject::ToString(strEcmaRuntimeCallInfo);
862    TestHelper::TearDownFrame(thread, prev);
863
864    ASSERT_TRUE(resultStr.IsString());
865    ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultStrValue, JSHandle<EcmaString>(thread, resultStr)), 0);
866
867    // function
868    JSHandle<JSFunction> func = thread->GetEcmaVM()->GetFactory()->NewJSFunction(thread->GetEcmaVM()->GetGlobalEnv());
869    JSHandle<EcmaString> resultFuncValue =
870        thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Function]");
871    auto funcEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
872    funcEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
873    funcEcmaRuntimeCallInfo->SetThis(func.GetTaggedValue());
874
875    prev = TestHelper::SetupFrame(thread, funcEcmaRuntimeCallInfo);
876    JSTaggedValue resultFunc = BuiltinsObject::ToString(funcEcmaRuntimeCallInfo);
877    TestHelper::TearDownFrame(thread, prev);
878
879    ASSERT_TRUE(resultFunc.IsString());
880    ASSERT_EQ(EcmaStringAccessor::Compare(instance,
881        resultFuncValue, JSHandle<EcmaString>(thread, resultFunc)), 0);
882
883    // error
884    auto ecmaVM = thread->GetEcmaVM();
885    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
886    JSHandle<JSTaggedValue> errorObject = env->GetErrorFunction();
887    JSHandle<JSObject> error =
888        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(errorObject), errorObject);
889    JSHandle<EcmaString> errorValue = thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Error]");
890    auto errorEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
891    errorEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
892    errorEcmaRuntimeCallInfo->SetThis(error.GetTaggedValue());
893
894    prev = TestHelper::SetupFrame(thread, errorEcmaRuntimeCallInfo);
895    JSTaggedValue resultError = BuiltinsObject::ToString(errorEcmaRuntimeCallInfo);
896    TestHelper::TearDownFrame(thread, prev);
897
898    ASSERT_TRUE(resultError.IsString());
899    ASSERT_EQ(EcmaStringAccessor::Compare(instance, errorValue, JSHandle<EcmaString>(thread, resultError)), 0);
900
901    // boolean
902    JSHandle<JSTaggedValue> value(thread, JSTaggedValue::False());
903    JSHandle<JSFunction> booleanObject(env->GetBooleanFunction());
904    JSHandle<JSPrimitiveRef> boolean = thread->GetEcmaVM()->GetFactory()->NewJSPrimitiveRef(booleanObject, value);
905    JSHandle<EcmaString> resultBoolValue =
906        thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Boolean]");
907    auto boolEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
908    boolEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
909    boolEcmaRuntimeCallInfo->SetThis(boolean.GetTaggedValue());
910
911    prev = TestHelper::SetupFrame(thread, boolEcmaRuntimeCallInfo);
912    JSTaggedValue resultBool = BuiltinsObject::ToString(boolEcmaRuntimeCallInfo);
913    TestHelper::TearDownFrame(thread, prev);
914
915    ASSERT_TRUE(resultBool.IsString());
916    ASSERT_EQ(EcmaStringAccessor::Compare(instance,
917        resultBoolValue, JSHandle<EcmaString>(thread, resultBool)), 0);
918
919    // number
920    JSHandle<EcmaString> resultNumValue =
921        thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Number]");
922    auto numEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
923    numEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
924    numEcmaRuntimeCallInfo->SetThis(JSTaggedValue(static_cast<double>(0)));
925
926    prev = TestHelper::SetupFrame(thread, numEcmaRuntimeCallInfo);
927    JSTaggedValue resultNum = BuiltinsObject::ToString(numEcmaRuntimeCallInfo);
928    TestHelper::TearDownFrame(thread, prev);
929
930    ASSERT_TRUE(resultNum.IsString());
931    ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultNumValue, JSHandle<EcmaString>(thread, resultNum)), 0);
932}
933
934// object.valueOf()
935HWTEST_F_L0(BuiltinsObjectTest, ValueOf)
936{
937    JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
938    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
939    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
940    ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
941    ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
942
943    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
944    JSTaggedValue result = BuiltinsObject::ValueOf(ecmaRuntimeCallInfo);
945    TestHelper::TearDownFrame(thread, prev);
946
947    ASSERT_TRUE(result.IsECMAObject());
948}
949
950// Object.hasOwn (O, P)
951HWTEST_F_L0(BuiltinsObjectTest, HasOwn)
952{
953    JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
954    JSHandle<JSObject> object =
955        thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
956    JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
957    JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
958    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(object), key, value);
959    EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(object), key).GetValue()->GetInt(), 1);
960
961    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
962    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
963    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
964    ecmaRuntimeCallInfo->SetCallArg(0, object.GetTaggedValue());
965    ecmaRuntimeCallInfo->SetCallArg(1, key.GetTaggedValue());
966
967    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
968    JSTaggedValue result = BuiltinsObject::HasOwn(ecmaRuntimeCallInfo);
969    TestHelper::TearDownFrame(thread, prev);
970    ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
971}
972}  // namespace panda::test
973