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
31 using namespace panda::ecmascript;
32 using namespace panda::ecmascript::builtins;
33
34 namespace panda::test {
35 class BuiltinsObjectTest : public BaseTestWithScope<false> {
36 };
37
CreateBuiltinJSObject(JSThread * thread,const CString keyCStr)38 JSTaggedValue 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
BuiltinsObjectTestCreate(JSThread * thread)52 JSFunction *BuiltinsObjectTestCreate(JSThread *thread)
53 {
54 EcmaVM *ecmaVM = thread->GetEcmaVM();
55 JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
56 return globalEnv->GetObjectFunction().GetObject<JSFunction>();
57 }
58
TestNewJSObject(JSThread * thread,const JSHandle<JSHClass> & hclass)59 JSObject *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 ] )
HWTEST_F_L0(BuiltinsObjectTest,ObjectConstructor)69 HWTEST_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 )
HWTEST_F_L0(BuiltinsObjectTest,Assign)133 HWTEST_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 ] )
HWTEST_F_L0(BuiltinsObjectTest,Create)168 HWTEST_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 )
HWTEST_F_L0(BuiltinsObjectTest,DefineProperties)231 HWTEST_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 )
HWTEST_F_L0(BuiltinsObjectTest,DefineProperty)267 HWTEST_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 )
HWTEST_F_L0(BuiltinsObjectTest,Freeze)309 HWTEST_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 )
HWTEST_F_L0(BuiltinsObjectTest,GetOwnPropertyDescriptor)333 HWTEST_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 )
HWTEST_F_L0(BuiltinsObjectTest,GetOwnPropertyNames)365 HWTEST_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 )
HWTEST_F_L0(BuiltinsObjectTest,GetOwnPropertySymbols)388 HWTEST_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 )
HWTEST_F_L0(BuiltinsObjectTest,Is)412 HWTEST_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 )
HWTEST_F_L0(BuiltinsObjectTest,IsExtensible)507 HWTEST_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 )
HWTEST_F_L0(BuiltinsObjectTest,IsFrozen)530 HWTEST_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 )
HWTEST_F_L0(BuiltinsObjectTest,IsSealed)591 HWTEST_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)
HWTEST_F_L0(BuiltinsObjectTest,Keys)611 HWTEST_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)
HWTEST_F_L0(BuiltinsObjectTest,Values)627 HWTEST_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)
HWTEST_F_L0(BuiltinsObjectTest,PreventExtensions)643 HWTEST_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)
HWTEST_F_L0(BuiltinsObjectTest,Seal)663 HWTEST_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)
HWTEST_F_L0(BuiltinsObjectTest,SetPrototypeOf)684 HWTEST_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)
HWTEST_F_L0(BuiltinsObjectTest,HasOwnProperty)708 HWTEST_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)
HWTEST_F_L0(BuiltinsObjectTest,IsPrototypeOfFalse)728 HWTEST_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
HWTEST_F_L0(BuiltinsObjectTest,IsPrototypeOfTrue)745 HWTEST_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)
HWTEST_F_L0(BuiltinsObjectTest,PropertyIsEnumerable)776 HWTEST_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()
HWTEST_F_L0(BuiltinsObjectTest,ToLocaleString)794 HWTEST_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()
HWTEST_F_L0(BuiltinsObjectTest,ToString)820 HWTEST_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()
HWTEST_F_L0(BuiltinsObjectTest,ValueOf)935 HWTEST_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)
HWTEST_F_L0(BuiltinsObjectTest,HasOwn)951 HWTEST_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