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_reflect.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_function.h"
24#include "ecmascript/js_object-inl.h"
25#include "ecmascript/js_primitive_ref.h"
26#include "ecmascript/tagged_array-inl.h"
27#include "ecmascript/object_factory.h"
28#include "ecmascript/tests/test_helper.h"
29
30using namespace panda::ecmascript;
31using namespace panda::ecmascript::builtins;
32using BuiltinsBase = panda::ecmascript::base::BuiltinsBase;
33using JSArray = panda::ecmascript::JSArray;
34
35namespace panda::test {
36class BuiltinsReflectTest : public BaseTestWithScope<false> {
37};
38
39// use for create a JSObject of test
40static JSHandle<JSFunction> TestObjectCreate(JSThread *thread)
41{
42    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
43    return JSHandle<JSFunction>::Cast(env->GetObjectFunction());
44}
45
46// native function for test Reflect.apply
47JSTaggedValue TestReflectApply(EcmaRuntimeCallInfo *argv)
48{
49    auto thread = argv->GetThread();
50    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
51
52    int result = 0;
53    for (uint32_t index = 0; index < argv->GetArgsNumber(); ++index) {
54        result += BuiltinsBase::GetCallArg(argv, index).GetTaggedValue().GetInt();
55    }
56    JSHandle<JSTaggedValue> thisValue = BuiltinsBase::GetThis(argv);
57
58    JSTaggedValue testA = JSObject::GetProperty(thread, thisValue,
59        JSHandle<JSTaggedValue>(factory->NewFromASCII("test_reflect_apply_a"))).GetValue().GetTaggedValue();
60    JSTaggedValue testB = JSObject::GetProperty(thread, thisValue,
61        JSHandle<JSTaggedValue>(factory->NewFromASCII("test_reflect_apply_b"))).GetValue().GetTaggedValue();
62
63    result = result + testA.GetInt() + testB.GetInt();
64    return BuiltinsBase::GetTaggedInt(result);
65}
66
67// Reflect.apply (target, thisArgument, argumentsList)
68HWTEST_F_L0(BuiltinsReflectTest, ReflectApply)
69{
70    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
71
72    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
73
74    // target
75    JSHandle<JSFunction> target = factory->NewJSFunction(env, reinterpret_cast<void *>(TestReflectApply));
76    // thisArgument
77    JSHandle<JSObject> thisArgument =
78        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
79    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(thisArgument),
80                          JSHandle<JSTaggedValue>(factory->NewFromASCII("test_reflect_apply_a")),
81                          JSHandle<JSTaggedValue>(thread, JSTaggedValue(11)));
82    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(thisArgument),
83                          JSHandle<JSTaggedValue>(factory->NewFromASCII("test_reflect_apply_b")),
84                          JSHandle<JSTaggedValue>(thread, JSTaggedValue(22)));
85    // argumentsList
86    JSHandle<JSObject> argumentsList(JSArray::ArrayCreate(thread, JSTaggedNumber(2)));
87    PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(33)));
88    JSArray::DefineOwnProperty(thread, argumentsList, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0)), desc);
89
90    PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(44)));
91    JSArray::DefineOwnProperty(thread, argumentsList, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), desc1);
92
93    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
94    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
95    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
96    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
97    ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(*thisArgument));
98    ecmaRuntimeCallInfo->SetCallArg(2, JSTaggedValue(*argumentsList));
99
100    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
101    JSTaggedValue result = BuiltinsReflect::ReflectApply(ecmaRuntimeCallInfo);
102    ASSERT_EQ(result.GetRawData(), JSTaggedValue(110).GetRawData());
103
104    JSObject::DeleteProperty(thread, (thisArgument),
105                             JSHandle<JSTaggedValue>(factory->NewFromASCII("test_reflect_apply_a")));
106    JSObject::DeleteProperty(thread, (thisArgument),
107                             JSHandle<JSTaggedValue>(factory->NewFromASCII("test_reflect_apply_b")));
108    TestHelper::TearDownFrame(thread, prev);
109}
110
111// Reflect.construct (target, argumentsList [ , newTarget])
112HWTEST_F_L0(BuiltinsReflectTest, ReflectConstruct)
113{
114    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
115
116    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
117
118    // target
119    JSHandle<JSFunction> target = JSHandle<JSFunction>::Cast(env->GetStringFunction());
120    // argumentsList
121    JSHandle<JSObject> argumentsList(JSArray::ArrayCreate(thread, JSTaggedNumber(1)));
122    PropertyDescriptor desc(thread,
123                            JSHandle<JSTaggedValue>::Cast(factory->NewFromASCII("ReflectConstruct")));
124    JSArray::DefineOwnProperty(thread, argumentsList, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0)), desc);
125
126    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
127    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
128    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
129    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
130    ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(*argumentsList));
131
132    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
133    JSTaggedValue result = BuiltinsReflect::ReflectConstruct(ecmaRuntimeCallInfo);
134
135    ASSERT_TRUE(result.IsECMAObject());
136    JSHandle<JSTaggedValue> taggedResult(thread, result);
137    JSHandle<JSPrimitiveRef> refResult = JSHandle<JSPrimitiveRef>::Cast(taggedResult);
138    JSHandle<EcmaString> ruler = factory->NewFromASCII("ReflectConstruct");
139    ASSERT_EQ(EcmaStringAccessor::Compare(instance,
140        JSHandle<EcmaString>(thread, EcmaString::Cast(refResult->GetValue())), ruler), 0);
141    TestHelper::TearDownFrame(thread, prev);
142}
143
144// Reflect.defineProperty (target, propertyKey, attributes)
145HWTEST_F_L0(BuiltinsReflectTest, ReflectDefineProperty)
146{
147    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
148
149    // target
150    JSHandle<JSObject> target =
151        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
152    // propertyKey
153    JSHandle<JSTaggedValue> key(factory->NewFromASCII("test_reflect_define_property"));
154    // attributes
155    JSHandle<JSObject> attributes =
156        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
157    // attributes value
158    auto globalConst = thread->GlobalConstants();
159    JSHandle<JSTaggedValue> valueKey = globalConst->GetHandledValueString();
160    JSHandle<JSTaggedValue> value(thread, JSTaggedValue(100));
161    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(attributes), valueKey, value);
162    // attributes writable
163    JSHandle<JSTaggedValue> writableKey = globalConst->GetHandledWritableString();
164    JSHandle<JSTaggedValue> writable(thread, JSTaggedValue::True());
165    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(attributes), writableKey, writable);
166    // attributes enumerable
167    JSHandle<JSTaggedValue> enumerableKey = globalConst->GetHandledEnumerableString();
168    JSHandle<JSTaggedValue> enumerable(thread, JSTaggedValue::False());
169    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(attributes), enumerableKey, enumerable);
170    // attributes configurable
171    JSHandle<JSTaggedValue> configurableKey = globalConst->GetHandledConfigurableString();
172    JSHandle<JSTaggedValue> configurable(thread, JSTaggedValue::True());
173    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(attributes), configurableKey, configurable);
174
175    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
176    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
177    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
178    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
179    ecmaRuntimeCallInfo->SetCallArg(1, key.GetTaggedValue());
180    ecmaRuntimeCallInfo->SetCallArg(2, JSTaggedValue(*attributes));
181
182    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
183    JSTaggedValue result = BuiltinsReflect::ReflectDefineProperty(ecmaRuntimeCallInfo);
184    ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
185
186    PropertyDescriptor descRuler(thread);
187    JSObject::GetOwnProperty(thread, target, key, descRuler);
188    ASSERT_EQ(descRuler.GetValue()->GetInt(), 100);
189    ASSERT_EQ(descRuler.IsWritable(), true);
190    ASSERT_EQ(descRuler.IsEnumerable(), false);
191    ASSERT_EQ(descRuler.IsConfigurable(), true);
192    TestHelper::TearDownFrame(thread, prev);
193}
194
195// Reflect.deleteProperty (target, propertyKey)
196HWTEST_F_L0(BuiltinsReflectTest, ReflectDeleteProperty)
197{
198    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
199
200    // target
201    JSHandle<JSObject> target =
202        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
203    // propertyKey
204    JSHandle<JSTaggedValue> key(factory->NewFromASCII("test_reflect_delete_property"));
205    JSHandle<JSTaggedValue> value(thread, JSTaggedValue(101));
206    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(target), key, value);
207
208    PropertyDescriptor desc(thread);
209    ASSERT_EQ(JSObject::GetOwnProperty(thread, target, key, desc), true);
210
211    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
212    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
213    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
214    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
215    ecmaRuntimeCallInfo->SetCallArg(1, key.GetTaggedValue());
216
217    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
218    JSTaggedValue result = BuiltinsReflect::ReflectDeleteProperty(ecmaRuntimeCallInfo);
219    ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
220    ASSERT_EQ(JSObject::GetOwnProperty(thread, target, key, desc), false);
221    TestHelper::TearDownFrame(thread, prev);
222}
223
224// Reflect.get (target, propertyKey [ , receiver])
225HWTEST_F_L0(BuiltinsReflectTest, ReflectGet)
226{
227    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
228
229    // target
230    JSHandle<JSObject> target =
231        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
232    // propertyKey
233    JSHandle<JSTaggedValue> key(factory->NewFromASCII("test_reflect_get"));
234    // set property
235    JSHandle<JSTaggedValue> value(thread, JSTaggedValue(101.5));
236    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(target), key, value);
237
238    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
239    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
240    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
241    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
242    ecmaRuntimeCallInfo->SetCallArg(1, key.GetTaggedValue());
243
244    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
245    JSTaggedValue result = BuiltinsReflect::ReflectGet(ecmaRuntimeCallInfo);
246
247    JSHandle<JSTaggedValue> resultValue(thread, result);
248    ASSERT_EQ(resultValue->GetDouble(), 101.5);
249    TestHelper::TearDownFrame(thread, prev);
250}
251
252// Reflect.getOwnPropertyDescriptor ( target, propertyKey )
253HWTEST_F_L0(BuiltinsReflectTest, ReflectGetOwnPropertyDescriptor)
254{
255    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
256
257    // target
258    JSHandle<JSObject> target =
259        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
260    // propertyKey
261    JSHandle<JSTaggedValue> key(factory->NewFromASCII("test_reflect_get_property_descriptor"));
262    PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(102)), true, false, true);
263    ASSERT_EQ(JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(target), key, desc), true);
264
265    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
266    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
267    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
268    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
269    ecmaRuntimeCallInfo->SetCallArg(1, key.GetTaggedValue());
270
271    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
272    JSTaggedValue result = BuiltinsReflect::ReflectGetOwnPropertyDescriptor(ecmaRuntimeCallInfo);
273
274    ASSERT_TRUE(result.IsECMAObject());
275
276    JSHandle<JSTaggedValue> resultObj(thread, result);
277    // test value
278    auto globalConst = thread->GlobalConstants();
279    JSHandle<JSTaggedValue> valueKey = globalConst->GetHandledValueString();
280    JSHandle<JSTaggedValue> resultValue = JSObject::GetProperty(thread, resultObj, valueKey).GetValue();
281    ASSERT_EQ(resultValue->GetInt(), 102);
282    // test writable
283    JSHandle<JSTaggedValue> writableKey = globalConst->GetHandledWritableString();
284    JSHandle<JSTaggedValue> resultWritable = JSObject::GetProperty(thread, resultObj, writableKey).GetValue();
285    ASSERT_EQ(resultWritable->ToBoolean(), true);
286    // test enumerable
287    JSHandle<JSTaggedValue> enumerableKey = globalConst->GetHandledEnumerableString();
288    JSHandle<JSTaggedValue> resultEnumerable = JSObject::GetProperty(thread, resultObj, enumerableKey).GetValue();
289    ASSERT_EQ(resultEnumerable->ToBoolean(), false);
290    // test configurable
291    JSHandle<JSTaggedValue> configurableKey = globalConst->GetHandledConfigurableString();
292    JSHandle<JSTaggedValue> resultConfigurable = JSObject::GetProperty(thread, resultObj, configurableKey).GetValue();
293    ASSERT_EQ(resultConfigurable->ToBoolean(), true);
294    TestHelper::TearDownFrame(thread, prev);
295}
296
297// Reflect.getPrototypeOf (target)
298HWTEST_F_L0(BuiltinsReflectTest, ReflectGetPrototypeOf)
299{
300    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
301
302    JSHandle<JSObject> target =
303        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
304    JSHandle<JSObject> proto =
305        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
306
307    ASSERT_EQ(JSObject::SetPrototype(thread, target, JSHandle<JSTaggedValue>(proto)), true);
308
309    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
310    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
311    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
312    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
313
314    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
315    JSTaggedValue result = BuiltinsReflect::ReflectGetPrototypeOf(ecmaRuntimeCallInfo);
316    ASSERT_TRUE(result.IsECMAObject());
317    JSHandle<JSTaggedValue> resultObj(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(result.GetRawData())));
318    ASSERT_EQ(JSTaggedValue::SameValue(resultObj.GetTaggedValue(), proto.GetTaggedValue()), true);
319    TestHelper::TearDownFrame(thread, prev);
320}
321
322// Reflect.has (target, propertyKey)
323HWTEST_F_L0(BuiltinsReflectTest, ReflectHas)
324{
325    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
326
327    // target
328    JSHandle<JSObject> target =
329        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
330    // propertyKey
331    JSHandle<JSTaggedValue> key(factory->NewFromASCII("test_reflect_has"));
332    JSHandle<JSTaggedValue> value(thread, JSTaggedValue(103));
333    ASSERT_EQ(JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(target), key, value), true);
334
335    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
336    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
337    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
338    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
339    ecmaRuntimeCallInfo->SetCallArg(1, key.GetTaggedValue());
340
341    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
342    JSTaggedValue result = BuiltinsReflect::ReflectHas(ecmaRuntimeCallInfo);
343
344    ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
345    TestHelper::TearDownFrame(thread, prev);
346}
347
348// Reflect.isExtensible (target)
349HWTEST_F_L0(BuiltinsReflectTest, ReflectIsExtensible)
350{
351    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
352
353    // target
354    JSHandle<JSObject> target =
355        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
356    target->GetJSHClass()->SetExtensible(false);
357
358    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
359    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
360    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
361    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
362
363    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
364    JSTaggedValue result = BuiltinsReflect::ReflectIsExtensible(ecmaRuntimeCallInfo);
365
366    ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
367    TestHelper::TearDownFrame(thread, prev);
368}
369
370// Reflect.ownKeys (target)
371HWTEST_F_L0(BuiltinsReflectTest, ReflectOwnKeys)
372{
373    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
374
375    // target
376    JSHandle<JSObject> target =
377        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
378    JSHandle<JSTaggedValue> key0(factory->NewFromASCII("test_reflect_own_keys1"));
379    JSHandle<JSTaggedValue> value0(thread, JSTaggedValue(104));
380    ASSERT_EQ(JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(target), key0, value0), true);
381    JSHandle<JSTaggedValue> key1(factory->NewFromASCII("test_reflect_own_keys2"));
382    JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(105));
383    ASSERT_EQ(JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(target), key1, value1), true);
384
385    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
386    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
387    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
388    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
389
390    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
391    JSTaggedValue result = BuiltinsReflect::ReflectOwnKeys(ecmaRuntimeCallInfo);
392
393    ASSERT_TRUE(result.IsECMAObject());
394    JSHandle<JSTaggedValue> resultTaggedValue(thread, reinterpret_cast<TaggedObject *>(result.GetRawData()));
395    JSHandle<JSArray> resultArray = JSHandle<JSArray>::Cast(resultTaggedValue);
396    // test length
397    JSHandle<JSTaggedValue> resultLengthKey = thread->GlobalConstants()->GetHandledLengthString();
398    JSHandle<JSTaggedValue> resultLength =
399        JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(resultArray), resultLengthKey).GetValue();
400    ASSERT_EQ(resultLength->GetInt(), 2);
401    // test array[0]
402    JSHandle<JSTaggedValue> resultKey0(thread, JSTaggedValue(0));
403    JSHandle<JSTaggedValue> resultValue0 =
404        JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(resultArray), resultKey0).GetValue();
405    ASSERT_EQ(EcmaStringAccessor::Compare(instance,
406        JSHandle<EcmaString>(resultValue0),
407        JSHandle<EcmaString>(key0)),
408        0);
409    // test array[1]
410    JSHandle<JSTaggedValue> resultKey1(thread, JSTaggedValue(1));
411    JSHandle<JSTaggedValue> resultValue1 =
412        JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(resultArray), resultKey1).GetValue();
413    ASSERT_EQ(EcmaStringAccessor::Compare(instance,
414        JSHandle<EcmaString>(resultValue1),
415        JSHandle<EcmaString>(key1)),
416        0);
417    TestHelper::TearDownFrame(thread, prev);
418}
419
420// Reflect.preventExtensions (target)
421HWTEST_F_L0(BuiltinsReflectTest, ReflectPreventExtensions)
422{
423    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
424
425    // target
426    JSHandle<JSObject> target =
427        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
428    target->GetJSHClass()->SetExtensible(true);
429
430    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
431    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
432    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
433    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
434
435    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
436    JSTaggedValue result = BuiltinsReflect::ReflectPreventExtensions(ecmaRuntimeCallInfo);
437
438    ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
439    ASSERT_EQ(target->IsExtensible(), false);
440    TestHelper::TearDownFrame(thread, prev);
441}
442
443// Reflect.set (target, propertyKey, V [ , receiver])
444HWTEST_F_L0(BuiltinsReflectTest, ReflectSet)
445{
446    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
447
448    // target
449    JSHandle<JSObject> target =
450        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
451    // propertyKey
452    JSHandle<JSTaggedValue> key(factory->NewFromASCII("test_reflect_set"));
453    // value
454    JSHandle<JSTaggedValue> value(thread, JSTaggedValue(106));
455
456    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
457    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
458    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
459    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
460    ecmaRuntimeCallInfo->SetCallArg(1, key.GetTaggedValue());
461    ecmaRuntimeCallInfo->SetCallArg(2, value.GetTaggedValue());
462
463    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
464    JSTaggedValue result = BuiltinsReflect::ReflectSet(ecmaRuntimeCallInfo);
465
466    ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
467
468    JSHandle<JSTaggedValue> ruler = JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(target), key).GetValue();
469    ASSERT_EQ(JSTaggedValue::ToInt32(thread, ruler), 106);
470    TestHelper::TearDownFrame(thread, prev);
471}
472
473// Reflect.setPrototypeOf (target, proto)
474HWTEST_F_L0(BuiltinsReflectTest, ReflectSetPrototypeOf)
475{
476    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
477
478    JSHandle<JSObject> target =
479        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
480    JSHandle<JSObject> proto =
481        factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle<JSTaggedValue>(TestObjectCreate(thread)));
482
483    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
484    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
485    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
486    ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
487    ecmaRuntimeCallInfo->SetCallArg(1, proto.GetTaggedValue());
488
489    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
490    JSTaggedValue result = BuiltinsReflect::ReflectSetPrototypeOf(ecmaRuntimeCallInfo);
491
492    ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
493    JSHandle<JSTaggedValue> resultObj(thread, target->GetJSHClass()->GetPrototype());
494    ASSERT_EQ(JSTaggedValue::SameValue(resultObj.GetTaggedValue(), proto.GetTaggedValue()), true);
495    TestHelper::TearDownFrame(thread, prev);
496}
497}  // namespace panda::test
498