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_array.h"
17
18#include "ecmascript/ecma_string.h"
19#include "ecmascript/ecma_vm.h"
20#include "ecmascript/global_env.h"
21#include "ecmascript/js_array.h"
22#include "ecmascript/js_array_iterator.h"
23
24#include "ecmascript/js_handle.h"
25#include "ecmascript/js_hclass.h"
26#include "ecmascript/js_object-inl.h"
27#include "ecmascript/js_tagged_value-inl.h"
28#include "ecmascript/js_tagged_value.h"
29#include "ecmascript/js_thread.h"
30
31#include "ecmascript/object_factory.h"
32#include "ecmascript/object_operator.h"
33#include "ecmascript/tests/test_helper.h"
34
35using namespace panda::ecmascript;
36using namespace panda::ecmascript::builtins;
37using namespace panda::ecmascript::base;
38constexpr int32_t INT_VALUE_0 = 0;
39constexpr int32_t INT_VALUE_1 = 1;
40constexpr int32_t INT_VALUE_2 = 2;
41constexpr int32_t INT_VALUE_3 = 3;
42constexpr int32_t INT_VALUE_4 = 4;
43constexpr int32_t INT_VALUE_666 = 666;
44constexpr uint32_t RUNTIME_CALL_INFO_PARA_0 = 0;
45constexpr uint32_t RUNTIME_CALL_INFO_PARA_1 = 1;
46constexpr uint32_t RUNTIME_CALL_INFO_PARA_NUM_4 = 4;
47constexpr uint32_t RUNTIME_CALL_INFO_PARA_NUM_8 = 8;
48constexpr uint32_t RUNTIME_CALL_INFO_PARA_NUM_10 = 10;
49
50enum class ArrayIndex {
51    ARRAY_INDEX_0,
52    ARRAY_INDEX_1,
53    ARRAY_INDEX_2,
54    ARRAY_INDEX_3
55};
56
57namespace panda::test {
58using Array = ecmascript::builtins::BuiltinsArray;
59class BuiltinsArrayTest : public BaseTestWithScope<false> {
60public:
61    class TestClass : public base::BuiltinsBase {
62    public:
63        static JSTaggedValue TestForEachFunc(EcmaRuntimeCallInfo *argv)
64        {
65            JSHandle<JSTaggedValue> key = GetCallArg(argv, 0);
66            if (key->IsUndefined()) {
67                return JSTaggedValue::Undefined();
68            }
69            JSArray *jsArray = JSArray::Cast(GetThis(argv)->GetTaggedObject());
70            uint32_t length = jsArray->GetArrayLength() + 1U;
71            jsArray->SetArrayLength(argv->GetThread(), length);
72            return JSTaggedValue::Undefined();
73        }
74
75        static JSTaggedValue TestEveryFunc(EcmaRuntimeCallInfo *argv)
76        {
77            uint32_t argc = argv->GetArgsNumber();
78            if (argc > 0) {
79                if (GetCallArg(argv, 0)->GetInt() > 10) { // 10 : test case
80                    return GetTaggedBoolean(true);
81                }
82            }
83            return GetTaggedBoolean(false);
84        }
85
86        static JSTaggedValue TestMapFunc(EcmaRuntimeCallInfo *argv)
87        {
88            int accumulator = GetCallArg(argv, 0)->GetInt();
89            accumulator = accumulator * 2; // 2 : mapped to 2 times the original value
90            return BuiltinsBase::GetTaggedInt(accumulator);
91        }
92
93        static JSTaggedValue TestFlatMapFunc(EcmaRuntimeCallInfo *argv)
94        {
95            int accumulator = GetCallArg(argv, 0)->GetInt();
96            accumulator = accumulator * 2; // 2 : mapped to 2 times the original value
97
98            JSThread *thread = argv->GetThread();
99            JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
100            JSArray *arr =
101                JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
102            EXPECT_TRUE(arr != nullptr);
103            JSHandle<JSObject> obj(thread, arr);
104            auto property = JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle);
105            EXPECT_EQ(property.GetValue()->GetInt(), 0);
106
107            JSHandle<JSTaggedValue> key(thread, JSTaggedValue(0));
108            PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(accumulator)),
109                                                                    true, true, true);
110            JSArray::DefineOwnProperty(thread, obj, key, desc);
111            return obj.GetTaggedValue();
112        }
113
114        static JSTaggedValue TestFindFunc(EcmaRuntimeCallInfo *argv)
115        {
116            uint32_t argc = argv->GetArgsNumber();
117            if (argc > 0) {
118                // 10 : test case
119                if (GetCallArg(argv, 0)->GetInt() > 10) {
120                    return GetTaggedBoolean(true);
121                }
122            }
123            return GetTaggedBoolean(false);
124        }
125
126        static JSTaggedValue TestFindIndexFunc(EcmaRuntimeCallInfo *argv)
127        {
128            uint32_t argc = argv->GetArgsNumber();
129            if (argc > 0) {
130                // 10 : test case
131                if (GetCallArg(argv, 0)->GetInt() > 10) {
132                    return GetTaggedBoolean(true);
133                }
134            }
135            return GetTaggedBoolean(false);
136        }
137
138        static JSTaggedValue TestFindLastFunc(EcmaRuntimeCallInfo *argv)
139        {
140            uint32_t argc = argv->GetArgsNumber();
141            if (argc > 0) {
142                // 20 : test case
143                if (GetCallArg(argv, 0)->GetInt() > 20) {
144                    return GetTaggedBoolean(true);
145                }
146            }
147            return GetTaggedBoolean(false);
148        }
149
150        static JSTaggedValue TestFindLastIndexFunc(EcmaRuntimeCallInfo *argv)
151        {
152            uint32_t argc = argv->GetArgsNumber();
153            if (argc > 0) {
154                // 20 : test case
155                if (GetCallArg(argv, 0)->GetInt() > 20) {
156                    return GetTaggedBoolean(true);
157                }
158            }
159            return GetTaggedBoolean(false);
160        }
161
162        static JSTaggedValue TestReduceFunc(EcmaRuntimeCallInfo *argv)
163        {
164            int accumulator = GetCallArg(argv, 0)->GetInt();
165            accumulator = accumulator + GetCallArg(argv, 1)->GetInt();
166            return BuiltinsBase::GetTaggedInt(accumulator);
167        }
168
169        static JSTaggedValue TestReduceRightFunc(EcmaRuntimeCallInfo *argv)
170        {
171            int accumulator = GetCallArg(argv, 0)->GetInt();
172            accumulator = accumulator + GetCallArg(argv, 1)->GetInt();
173            return BuiltinsBase::GetTaggedInt(accumulator);
174        }
175
176        static JSTaggedValue TestSomeFunc(EcmaRuntimeCallInfo *argv)
177        {
178            uint32_t argc = argv->GetArgsNumber();
179            if (argc > 0) {
180                if (GetCallArg(argv, 0)->GetInt() > 10) { // 10 : test case
181                    return GetTaggedBoolean(true);
182                }
183            }
184            return GetTaggedBoolean(false);
185        }
186    };
187};
188
189JSTaggedValue CreateBuiltinsArrayJSObject(JSThread *thread, const CString keyCStr)
190{
191    EcmaVM *ecmaVM = thread->GetEcmaVM();
192    JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
193
194    JSHandle<JSTaggedValue> hclass = globalEnv->GetObjectFunction();
195    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
196
197    JSHandle<JSTaggedValue> obj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
198    JSHandle<JSTaggedValue> key(factory->NewFromASCII(&keyCStr[0]));
199    JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
200    JSObject::SetProperty(thread, obj, key, value);
201    return obj.GetTaggedValue();
202}
203
204HWTEST_F_L0(BuiltinsArrayTest, ArrayConstructor)
205{
206    JSHandle<JSFunction> array(thread->GetEcmaVM()->GetGlobalEnv()->GetArrayFunction());
207    JSHandle<JSObject> globalObject(thread, thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject());
208
209    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
210    ecmaRuntimeCallInfo1->SetFunction(array.GetTaggedValue());
211    ecmaRuntimeCallInfo1->SetThis(globalObject.GetTaggedValue());
212    ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(1)));
213    ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(3)));
214    ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast<int32_t>(5)));
215
216    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
217    JSTaggedValue result = Array::ArrayConstructor(ecmaRuntimeCallInfo1);
218    TestHelper::TearDownFrame(thread, prev);
219    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
220    ASSERT_TRUE(value.IsECMAObject());
221    PropertyDescriptor descRes(thread);
222    JSHandle<JSObject> valueHandle(thread, value);
223    JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
224    JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
225    JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
226    JSObject::GetOwnProperty(thread, valueHandle, key0, descRes);
227    ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(1));
228    JSObject::GetOwnProperty(thread, valueHandle, key1, descRes);
229    ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(3));
230    JSObject::GetOwnProperty(thread, valueHandle, key2, descRes);
231    ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(5));
232}
233
234std::vector<JSHandle<JSTaggedValue>> DefineOwnPropertyCommonTest(JSThread* thread, JSHandle<JSObject>& obj,
235    std::vector<int>& vals)
236{
237    std::vector<JSHandle<JSTaggedValue>> keys;
238    for (size_t i = 0; i < vals.size(); i++) {
239        keys.push_back(JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<int>(i))));
240        PropertyDescriptor desc0(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(vals[i])), true, true, true);
241        JSArray::DefineOwnProperty(thread, obj, keys[i], desc0);
242    }
243    return keys;
244}
245
246std::vector<JSHandle<JSTaggedValue>> DefineOwnPropertyCommonTest(JSThread* thread, JSHandle<JSTaggedValue>& obj,
247    std::vector<int>& vals)
248{
249    JSHandle<JSObject> jsObj(obj);
250    std::vector<JSHandle<JSTaggedValue>> keys;
251    for (size_t i = 0; i < vals.size(); i++) {
252        keys.push_back(JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<int>(i))));
253        PropertyDescriptor desc0(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(vals[i])), true, true, true);
254        JSArray::DefineOwnProperty(thread, jsObj, keys[i], desc0);
255    }
256    return keys;
257}
258
259void CheckKeyValueCommon(JSThread* thread, JSHandle<JSObject>& valueHandle, PropertyDescriptor& descRes,
260    std::vector<JSHandle<JSTaggedValue>>& keys, std::vector<int32_t>& vals)
261{
262    for (size_t i = 0; i < vals.size(); i++) {
263        JSObject::GetOwnProperty(thread, valueHandle, keys[i], descRes);
264        ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(vals[i]));
265    }
266}
267
268// 22.1.2.1 Array.from ( items [ , mapfn [ , thisArg ] ] )
269HWTEST_F_L0(BuiltinsArrayTest, From)
270{
271    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
272    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0))->GetTaggedObject());
273    EXPECT_TRUE(arr != nullptr);
274    JSHandle<JSObject> obj(thread, arr);
275    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
276
277    std::vector<int> descVals{1, 2, 3, 4, 5};
278    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
279
280    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
281    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
282    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
283    ecmaRuntimeCallInfo1->SetCallArg(0, obj.GetTaggedValue());
284
285    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
286    JSTaggedValue result = Array::From(ecmaRuntimeCallInfo1);
287    TestHelper::TearDownFrame(thread, prev);
288    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
289    ASSERT_TRUE(value.IsECMAObject());
290    PropertyDescriptor descRes(thread);
291    JSHandle<JSObject> valueHandle(thread, value);
292    std::vector<int> vals{1, 2, 3, 4, 5};
293    CheckKeyValueCommon(thread, valueHandle, descRes, keys, vals);
294}
295
296// 22.1.2.2 Array.isArray(arg)
297HWTEST_F_L0(BuiltinsArrayTest, IsArray)
298{
299    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
300    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
301    EXPECT_TRUE(arr != nullptr);
302    JSHandle<JSObject> obj(thread, arr);
303    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
304
305    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
306    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
307    ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
308    ecmaRuntimeCallInfo1->SetCallArg(0, obj.GetTaggedValue());
309
310    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
311    JSTaggedValue result = Array::IsArray(ecmaRuntimeCallInfo1);
312    TestHelper::TearDownFrame(thread, prev);
313    ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
314
315    auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
316    ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
317    ecmaRuntimeCallInfo2->SetThis(JSTaggedValue::Undefined());
318    ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(1)));
319
320    prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
321    result = Array::IsArray(ecmaRuntimeCallInfo2);
322    TestHelper::TearDownFrame(thread, prev);
323    ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
324}
325
326HWTEST_F_L0(BuiltinsArrayTest, Of)
327{
328    auto ecmaVM = thread->GetEcmaVM();
329    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
330    JSHandle<JSFunction> array(env->GetArrayFunction());
331    JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
332
333    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
334    ecmaRuntimeCallInfo1->SetFunction(array.GetTaggedValue());
335    ecmaRuntimeCallInfo1->SetThis(globalObject.GetTaggedValue());
336    ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(1)));
337    ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(3)));
338    ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast<int32_t>(5)));
339
340    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
341    JSTaggedValue result = Array::Of(ecmaRuntimeCallInfo1);
342    TestHelper::TearDownFrame(thread, prev);
343    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
344    ASSERT_TRUE(value.IsECMAObject());
345    PropertyDescriptor descRes(thread);
346    JSHandle<JSObject> valueHandle(thread, value);
347    JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
348    JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
349    JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
350    std::vector<JSHandle<JSTaggedValue>> keys{key0, key1, key2};
351    std::vector<int> vals{1, 3, 5};
352    CheckKeyValueCommon(thread, valueHandle, descRes, keys, vals);
353}
354
355HWTEST_F_L0(BuiltinsArrayTest, Species)
356{
357    auto ecmaVM = thread->GetEcmaVM();
358    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
359    JSHandle<JSFunction> array(env->GetArrayFunction());
360    JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
361
362    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
363    ecmaRuntimeCallInfo1->SetFunction(array.GetTaggedValue());
364    ecmaRuntimeCallInfo1->SetThis(globalObject.GetTaggedValue());
365
366    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
367    JSTaggedValue result = Array::Species(ecmaRuntimeCallInfo1);
368    TestHelper::TearDownFrame(thread, prev);
369    ASSERT_TRUE(result.IsECMAObject());
370}
371
372HWTEST_F_L0(BuiltinsArrayTest, Concat)
373{
374    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
375    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
376    EXPECT_TRUE(arr != nullptr);
377    JSHandle<JSObject> obj(thread, arr);
378
379    std::vector<int> descVals{1, 2, 3};
380    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
381
382    JSArray *arr1 = JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetObject<JSArray>();
383    EXPECT_TRUE(arr1 != nullptr);
384    JSHandle<JSObject> obj1(thread, arr1);
385
386    std::vector<int> descVals2{4, 5, 6};
387    keys = DefineOwnPropertyCommonTest(thread, obj1, descVals2);
388
389    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
390    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
391    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
392    ecmaRuntimeCallInfo1->SetCallArg(0, obj1.GetTaggedValue());
393
394    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
395    JSTaggedValue result = Array::Concat(ecmaRuntimeCallInfo1);
396    TestHelper::TearDownFrame(thread, prev);
397    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
398    ASSERT_TRUE(value.IsECMAObject());
399
400    PropertyDescriptor descRes(thread);
401    JSHandle<JSObject> valueHandle(thread, value);
402    JSHandle<JSTaggedValue> key7(thread, JSTaggedValue(5));
403    EXPECT_EQ(
404        JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 6);
405    JSObject::GetOwnProperty(thread, valueHandle, key7, descRes);
406    ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(6));
407}
408
409// 22.1.3.3 new Array(1,2,3,4,5).CopyWithin(0,3,5)
410HWTEST_F_L0(BuiltinsArrayTest, CopyWithin)
411{
412    std::vector<int> descVals{1, 2, 3, 4, 5};
413    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
414    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
415    EXPECT_TRUE(arr != nullptr);
416    JSHandle<JSObject> obj(thread, arr);
417    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
418    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
419
420    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
421    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
422    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
423    ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(0)));
424    ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(3)));
425    ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast<int32_t>(5)));
426
427    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
428    JSTaggedValue result = Array::CopyWithin(ecmaRuntimeCallInfo1);
429    TestHelper::TearDownFrame(thread, prev);
430    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
431    ASSERT_TRUE(value.IsECMAObject());
432    PropertyDescriptor descRes(thread);
433    JSHandle<JSObject> valueHandle(thread, value);
434    std::vector<int> vals{4, 5, 3, 4, 5};
435    CheckKeyValueCommon(thread, valueHandle, descRes, keys, vals);
436}
437
438HWTEST_F_L0(BuiltinsArrayTest, Every)
439{
440    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
441    auto ecmaVM = thread->GetEcmaVM();
442    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
443
444    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
445    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
446    EXPECT_TRUE(arr != nullptr);
447    JSHandle<JSObject> obj(thread, arr);
448    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
449
450    std::vector<int> descVals{100, 200, 300};
451    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
452
453    JSHandle<JSArray> jsArray = factory->NewJSArray();
454    JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestEveryFunc));
455
456    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
457    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
458    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
459    ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
460    ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue());
461
462    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
463    JSTaggedValue result2 = Array::Every(ecmaRuntimeCallInfo1);
464    TestHelper::TearDownFrame(thread, prev);
465
466    ASSERT_EQ(result2.GetRawData(), JSTaggedValue::True().GetRawData());
467}
468
469HWTEST_F_L0(BuiltinsArrayTest, Map)
470{
471    auto ecmaVM = thread->GetEcmaVM();
472    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
473    ObjectFactory *factory = ecmaVM->GetFactory();
474
475    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
476    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
477    EXPECT_TRUE(arr != nullptr);
478    JSHandle<JSObject> obj(thread, arr);
479    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
480
481    std::vector<int> descVals{50, 200, 3};
482    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
483
484    JSHandle<JSArray> jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0)));
485    JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestMapFunc));
486
487    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
488    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
489    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
490    ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
491    ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue());
492
493    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
494    JSTaggedValue result = Array::Map(ecmaRuntimeCallInfo1);
495    TestHelper::TearDownFrame(thread, prev);
496    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
497    ASSERT_TRUE(value.IsECMAObject());
498
499    PropertyDescriptor descRes(thread);
500    JSHandle<JSObject> valueHandle(thread, value);
501    std::vector<int> vals{100, 400, 6};
502    EXPECT_EQ(
503        JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 3);
504    CheckKeyValueCommon(thread, valueHandle, descRes, keys, vals);
505}
506
507HWTEST_F_L0(BuiltinsArrayTest, Reverse)
508{
509    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
510    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
511    EXPECT_TRUE(arr != nullptr);
512    JSHandle<JSObject> obj(thread, arr);
513    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
514
515    std::vector<int> descVals{50, 200, 3};
516    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
517
518    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
519    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
520    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
521
522    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
523    JSTaggedValue result = Array::Reverse(ecmaRuntimeCallInfo1);
524    TestHelper::TearDownFrame(thread, prev);
525    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
526    ASSERT_TRUE(value.IsECMAObject());
527
528    PropertyDescriptor descRes(thread);
529    JSHandle<JSObject> valueHandle(thread, value);
530    EXPECT_EQ(
531        JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 3);
532    std::vector<int> vals{3, 200, 50};
533    CheckKeyValueCommon(thread, valueHandle, descRes, keys, vals);
534    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 3);
535    CheckKeyValueCommon(thread, obj, descRes, keys, vals);
536}
537
538HWTEST_F_L0(BuiltinsArrayTest, COWArrayReverse)
539{
540    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
541    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
542    EXPECT_TRUE(arr != nullptr);
543    JSHandle<JSObject> obj(thread, arr);
544    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
545
546    std::vector<int> descVals{50, 200, 3};
547    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
548
549    JSHandle<JSArray> cloneArray = thread->GetEcmaVM()->GetFactory()->CloneArrayLiteral(JSHandle<JSArray>(obj));
550
551    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
552    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
553    ecmaRuntimeCallInfo1->SetThis(cloneArray.GetTaggedValue());
554
555    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
556    JSTaggedValue result = Array::Reverse(ecmaRuntimeCallInfo1);
557    TestHelper::TearDownFrame(thread, prev);
558    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
559    ASSERT_TRUE(value.IsECMAObject());
560
561    PropertyDescriptor descRes(thread);
562    JSHandle<JSObject> valueHandle(thread, value);
563    EXPECT_EQ(
564        JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 3);
565
566    std::vector<int> vals{3, 200, 50};
567    CheckKeyValueCommon(thread, valueHandle, descRes, keys, vals);
568
569    JSHandle<JSObject> cloneHandle(cloneArray);
570    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(cloneArray),
571        lengthKeyHandle).GetValue()->GetInt(), 3);
572    CheckKeyValueCommon(thread, cloneHandle, descRes, keys, vals);
573}
574
575HWTEST_F_L0(BuiltinsArrayTest, Slice)
576{
577    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
578    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
579    EXPECT_TRUE(arr != nullptr);
580    JSHandle<JSObject> obj(thread, arr);
581    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
582    std::vector<int> descVals{1, 2, 3, 4, 5};
583    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
584
585    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
586    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
587    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
588    ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(1)));
589    ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(4)));
590
591    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
592    JSTaggedValue result = Array::Slice(ecmaRuntimeCallInfo1);
593    TestHelper::TearDownFrame(thread, prev);
594    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
595    ASSERT_TRUE(value.IsECMAObject());
596
597    PropertyDescriptor descRes(thread);
598    JSHandle<JSObject> valueHandle(thread, value);
599    EXPECT_EQ(
600        JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 3);
601    std::vector<int> vals{2, 3, 4};
602    CheckKeyValueCommon(thread, valueHandle, descRes, keys, vals);
603}
604
605HWTEST_F_L0(BuiltinsArrayTest, Splice)
606{
607    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
608    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
609    EXPECT_TRUE(arr != nullptr);
610    JSHandle<JSObject> obj(thread, arr);
611    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
612    std::vector<int> descVals{1, 2, 3, 4, 5};
613    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
614
615    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
616    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
617    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
618    ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(1)));
619    ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(2)));
620    ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast<int32_t>(100)));
621
622    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
623    JSTaggedValue result = Array::Splice(ecmaRuntimeCallInfo1);
624    TestHelper::TearDownFrame(thread, prev);
625    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
626    ASSERT_TRUE(value.IsECMAObject());
627    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 4);
628
629    PropertyDescriptor descRes(thread);
630    JSHandle<JSObject> valueHandle(thread, value);
631    EXPECT_EQ(
632        JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 2);
633    JSObject::GetOwnProperty(thread, valueHandle, keys[0], descRes);
634    ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(2));
635}
636
637// 22.1.3.6 new Array(1,2,3,4,5).Fill(0,1,3)
638HWTEST_F_L0(BuiltinsArrayTest, Fill)
639{
640    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
641    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
642    EXPECT_TRUE(arr != nullptr);
643    JSHandle<JSObject> obj(thread, arr);
644    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
645
646    std::vector<int> descVals{1, 2, 3, 4, 5};
647    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
648
649    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
650    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
651    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
652    ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(0)));
653    ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(1)));
654    ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast<int32_t>(3)));
655
656    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
657    JSTaggedValue result = Array::Fill(ecmaRuntimeCallInfo1);
658    TestHelper::TearDownFrame(thread, prev);
659    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
660    ASSERT_TRUE(value.IsECMAObject());
661    PropertyDescriptor descRes(thread);
662    JSHandle<JSObject> valueHandle(thread, value);
663    std::vector<int32_t> vals{1, 0, 0, 4, 5};
664    CheckKeyValueCommon(thread, valueHandle, descRes, keys, vals);
665}
666
667// 22.1.3.6 new Array(1,2,3,4,5).Fill(0,1,3)
668HWTEST_F_L0(BuiltinsArrayTest, COWArrayFill)
669{
670    auto ecmaVM = thread->GetEcmaVM();
671    ObjectFactory *factory = ecmaVM->GetFactory();
672
673    JSHandle<TaggedArray> values(factory->NewTaggedArray(5));
674
675    for (int i = 0; i < 5; i++) {
676        values->Set(thread, i, JSTaggedValue(i + 1));
677    }
678    JSHandle<JSArray> array(JSArray::CreateArrayFromList(thread, values));
679    JSHandle<JSArray> cloneArray = factory->CloneArrayLiteral(array);
680
681    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
682    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
683    ecmaRuntimeCallInfo1->SetThis(cloneArray.GetTaggedValue());
684    ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(0)));
685    ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(1)));
686    ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast<int32_t>(3)));
687
688    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
689    JSTaggedValue result = Array::Fill(ecmaRuntimeCallInfo1);
690    TestHelper::TearDownFrame(thread, prev);
691    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
692    ASSERT_TRUE(value.IsECMAObject());
693    PropertyDescriptor descRes(thread);
694    JSHandle<JSObject> valueHandle(thread, value);
695    JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
696    JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
697    JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
698    JSHandle<JSTaggedValue> key3(thread, JSTaggedValue(3));
699    JSHandle<JSTaggedValue> key4(thread, JSTaggedValue(4));
700
701    std::vector<JSHandle<JSTaggedValue>> keys{key0, key1, key2, key3, key4};
702    std::vector<int32_t> vals{1, 0, 0, 4, 5};
703    CheckKeyValueCommon(thread, valueHandle, descRes, keys, vals);
704}
705
706HWTEST_F_L0(BuiltinsArrayTest, Find)
707{
708    auto ecmaVM = thread->GetEcmaVM();
709    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
710    ObjectFactory *factory = ecmaVM->GetFactory();
711
712    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
713    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
714    EXPECT_TRUE(arr != nullptr);
715    JSHandle<JSObject> obj(thread, arr);
716    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
717
718    std::vector<int> vals{1, 102, 3};
719    auto keys = DefineOwnPropertyCommonTest(thread, obj, vals);
720    JSHandle<JSArray> jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0)));
721    JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestFindFunc));
722
723    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
724    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
725    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
726    ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
727    ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue());
728
729    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
730    JSTaggedValue result2 = Array::Find(ecmaRuntimeCallInfo1);
731    TestHelper::TearDownFrame(thread, prev);
732
733    EXPECT_EQ(result2.GetRawData(), JSTaggedValue(102).GetRawData());
734}
735
736HWTEST_F_L0(BuiltinsArrayTest, FindIndex)
737{
738    auto ecmaVM = thread->GetEcmaVM();
739    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
740    ObjectFactory *factory = ecmaVM->GetFactory();
741
742    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
743    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
744    EXPECT_TRUE(arr != nullptr);
745    JSHandle<JSObject> obj(thread, arr);
746    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
747
748    std::vector<int> descVals{1, 2, 30};
749    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
750
751    JSHandle<JSArray> jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0)));
752    JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestFindIndexFunc));
753
754    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
755    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
756    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
757    ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
758    ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue());
759
760    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
761    JSTaggedValue result2 = Array::FindIndex(ecmaRuntimeCallInfo1);
762    TestHelper::TearDownFrame(thread, prev);
763
764    EXPECT_EQ(result2.GetRawData(), JSTaggedValue(static_cast<double>(2)).GetRawData());
765}
766
767HWTEST_F_L0(BuiltinsArrayTest, ForEach)
768{
769    auto ecmaVM = thread->GetEcmaVM();
770    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
771    ObjectFactory *factory = ecmaVM->GetFactory();
772
773    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
774    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
775    EXPECT_TRUE(arr != nullptr);
776    JSHandle<JSObject> obj(thread, arr);
777    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
778
779    std::vector<int> descVals{1, 2, 3};
780    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
781
782    JSHandle<JSArray> jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0)));
783    JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
784
785    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
786    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
787    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
788    ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
789    ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue());
790
791    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
792    JSTaggedValue result2 = Array::ForEach(ecmaRuntimeCallInfo1);
793    TestHelper::TearDownFrame(thread, prev);
794    EXPECT_EQ(result2.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
795    EXPECT_EQ(jsArray->GetArrayLength(), 3U);
796}
797
798#define ARRAY_DEFINE_OWN_PROPERTY(dest, index, value)                                                               \
799    do {                                                                                                            \
800        JSHandle<JSTaggedValue> key(thread, JSTaggedValue(index));                                                  \
801        PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(value)), true, true, true);   \
802        JSArray::DefineOwnProperty(thread, dest, key, desc);                                                        \
803    } while (false)
804
805#define ARRAY_BUILTIN_METHOD_TEST_CASE_ARG0(method, target, expected)                                               \
806    do {                                                                                                            \
807        auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);    \
808        ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());                                               \
809        ecmaRuntimeCallInfo->SetThis((target).GetTaggedValue());                                                    \
810                                                                                                                    \
811        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);                           \
812        JSTaggedValue result = Array::method(ecmaRuntimeCallInfo);                                                  \
813        TestHelper::TearDownFrame(thread, prev);                                                                    \
814        ASSERT_TRUE(JSTaggedValue::StrictEqual(result, JSTaggedValue(expected)));                                   \
815    } while (false)
816
817#define ARRAY_BUILTIN_METHOD_TEST_CASE_ARG1(method, target, expected, arg0)                                         \
818    do {                                                                                                            \
819        auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);    \
820        ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());                                               \
821        ecmaRuntimeCallInfo->SetThis((target).GetTaggedValue());                                                    \
822        ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(arg0));                                                    \
823                                                                                                                    \
824        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);                           \
825        JSTaggedValue result = Array::method(ecmaRuntimeCallInfo);                                                  \
826        TestHelper::TearDownFrame(thread, prev);                                                                    \
827        ASSERT_TRUE(JSTaggedValue::StrictEqual(result, JSTaggedValue(expected)));                                   \
828    } while (false)
829
830#define ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(method, target, expected, arg0, arg1)                                   \
831    do {                                                                                                            \
832        auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);    \
833        ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());                                               \
834        ecmaRuntimeCallInfo->SetThis((target).GetTaggedValue());                                                    \
835        ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(arg0));                                                    \
836        ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(arg1));                                                    \
837                                                                                                                    \
838        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);                           \
839        JSTaggedValue result = Array::method(ecmaRuntimeCallInfo);                                                  \
840        TestHelper::TearDownFrame(thread, prev);                                                                    \
841        ASSERT_TRUE(JSTaggedValue::StrictEqual(result, JSTaggedValue(expected)));                                   \
842    } while (false)
843
844// 22.1.3.11 Array.IndexOf(searchElement [ , fromIndex ])
845HWTEST_F_L0(BuiltinsArrayTest, IndexOf)
846{
847    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
848    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
849    EXPECT_TRUE(arr != nullptr);
850    JSHandle<JSObject> obj(thread, arr);
851    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
852
853    // arr = [1, 2, 3, 4, 3, 0, 2.0, +0.0, 3.0, -0.0, <hole>, <hole>, undefined]
854    ARRAY_DEFINE_OWN_PROPERTY(obj, 0, 1);
855    ARRAY_DEFINE_OWN_PROPERTY(obj, 1, 2);
856    ARRAY_DEFINE_OWN_PROPERTY(obj, 2, 3);
857    ARRAY_DEFINE_OWN_PROPERTY(obj, 3, 4);
858    ARRAY_DEFINE_OWN_PROPERTY(obj, 4, 3);
859    ARRAY_DEFINE_OWN_PROPERTY(obj, 5, 0);
860    ARRAY_DEFINE_OWN_PROPERTY(obj, 6, 2.0);
861    ARRAY_DEFINE_OWN_PROPERTY(obj, 7, +0.0);
862    ARRAY_DEFINE_OWN_PROPERTY(obj, 8, 3.0);
863    ARRAY_DEFINE_OWN_PROPERTY(obj, 9, -0.0);
864    ARRAY_DEFINE_OWN_PROPERTY(obj, 12, JSTaggedValue::Undefined());
865
866    // arr.indexOf(3, 0) == 2
867    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(IndexOf, obj, 2, 3, 0);
868    // arr.indexOf(3, 3) == 4
869    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(IndexOf, obj, 4, 3, 3);
870    // arr.indexOf(5, 0) == -1
871    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(IndexOf, obj, -1, 5, 0);
872    // arr.indexOf(3) == 2
873    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG1(IndexOf, obj, 2, 3);
874
875    // Expects int32_t(x) and double(x) to be strictly equal
876    // arr.indexOf(3.0) == 2
877    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG1(IndexOf, obj, 2, 3.0);
878    // arr.indexOf(3, 5) == 8
879    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(IndexOf, obj, 8, 3, 5);
880
881    // Expects 0, +0.0, -0.0 to be strictly equal
882    // arr.indexOf(+0.0) == 5
883    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG1(IndexOf, obj, 5, +0.0);
884    // arr.indexOf(-0.0) == 5
885    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG1(IndexOf, obj, 5, -0.0);
886    // arr.indexOf(0, 6) == 7
887    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(IndexOf, obj, 7, 0, 6);
888    // arr.indexOf(-0.0, 6) == 7
889    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(IndexOf, obj, 7, -0.0, 6);
890    // arr.indexOf(0, 8) == 9
891    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(IndexOf, obj, 9, 0, 8);
892    // arr.indexOf(+0.0, 8) == 9
893    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(IndexOf, obj, 9, +0.0, 8);
894
895    // Expects undefined to be found
896    // arr.indexOf() == 12, where the first argument is undefined
897    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG0(IndexOf, obj, 12);
898}
899
900// 22.1.3.14 Array.LastIndexOf(searchElement [ , fromIndex ])
901HWTEST_F_L0(BuiltinsArrayTest, LastIndexOf)
902{
903    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
904    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
905    EXPECT_TRUE(arr != nullptr);
906    JSHandle<JSObject> obj(thread, arr);
907    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
908
909    // arr = [1, 2, 3, 4, 3, 0, 2.0, +0.0, 3.0, -0.0, <hole>, <hole>, undefined, <hole>, <hole>, -1]
910    ARRAY_DEFINE_OWN_PROPERTY(obj, 0, 1);
911    ARRAY_DEFINE_OWN_PROPERTY(obj, 1, 2);
912    ARRAY_DEFINE_OWN_PROPERTY(obj, 2, 3);
913    ARRAY_DEFINE_OWN_PROPERTY(obj, 3, 4);
914    ARRAY_DEFINE_OWN_PROPERTY(obj, 4, 3);
915    ARRAY_DEFINE_OWN_PROPERTY(obj, 5, 0);
916    ARRAY_DEFINE_OWN_PROPERTY(obj, 6, 2.0);
917    ARRAY_DEFINE_OWN_PROPERTY(obj, 7, +0.0);
918    ARRAY_DEFINE_OWN_PROPERTY(obj, 8, 3.0);
919    ARRAY_DEFINE_OWN_PROPERTY(obj, 9, -0.0);
920    ARRAY_DEFINE_OWN_PROPERTY(obj, 12, JSTaggedValue::Undefined());
921    ARRAY_DEFINE_OWN_PROPERTY(obj, 15, -1);
922
923    // arr.lastIndexOf(3, 4) == 4
924    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(LastIndexOf, obj, 4, 3, 4);
925    // arr.lastIndexOf(3, 3) == 2
926    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(LastIndexOf, obj, 2, 3, 3);
927    // arr.lastIndexOf(5, 4) == -1
928    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(LastIndexOf, obj, -1, 5, 4);
929
930    // Expects int32_t(x) and double(x) to be strictly equal
931    // arr.lastIndexOf(3) == 8
932    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG1(LastIndexOf, obj, 8, 3);
933    // arr.lastIndexOf(1.0) == 0
934    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG1(LastIndexOf, obj, 0, 1.0);
935
936    // Expects 0, +0.0, -0.0 to be strictly equal
937    // arr.indexOf(+0.0) == 9
938    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG1(LastIndexOf, obj, 9, +0.0);
939    // arr.indexOf(0) == 9
940    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG1(LastIndexOf, obj, 9, 0);
941    // arr.indexOf(0, 8) == 7
942    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(LastIndexOf, obj, 7, 0, 8);
943    // arr.indexOf(-0.0, 8) == 7
944    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(LastIndexOf, obj, 7, -0.0, 8);
945    // arr.indexOf(-0.0, 6) == 5
946    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(LastIndexOf, obj, 5, -0.0, 6);
947    // arr.indexOf(+0.0, 6) == 5
948    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG2(LastIndexOf, obj, 5, +0.0, 6);
949
950    // Expects undefined to be found
951    // arr.indexOf() == 12, where the first argument is undefined
952    ARRAY_BUILTIN_METHOD_TEST_CASE_ARG0(LastIndexOf, obj, 12);
953}
954
955// 22.1.3.11 new Array().Pop()
956HWTEST_F_L0(BuiltinsArrayTest, Pop)
957{
958    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
959    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
960    EXPECT_TRUE(arr != nullptr);
961    JSHandle<JSObject> obj(thread, arr);
962    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
963
964    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
965    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
966    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
967
968    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
969    JSTaggedValue result = Array::Pop(ecmaRuntimeCallInfo1);
970    TestHelper::TearDownFrame(thread, prev);
971    ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
972    ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
973
974    JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
975    PropertyDescriptor desc0(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), true, true, true);
976    JSArray::DefineOwnProperty(thread, obj, key0, desc0);
977    JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
978    PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(2)), true, true, true);
979    JSArray::DefineOwnProperty(thread, obj, key1, desc1);
980    JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
981    PropertyDescriptor desc2(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(3)), true, true, true);
982    JSArray::DefineOwnProperty(thread, obj, key2, desc2);
983
984    auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
985    ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
986    ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue());
987
988    prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
989    result = Array::Pop(ecmaRuntimeCallInfo2);
990    TestHelper::TearDownFrame(thread, prev);
991    ASSERT_EQ(result.GetRawData(), JSTaggedValue(3).GetRawData());
992}
993
994// 22.1.3.11 new Array().Pop()
995HWTEST_F_L0(BuiltinsArrayTest, COWArrayPop)
996{
997    auto ecmaVM = thread->GetEcmaVM();
998    ObjectFactory *factory = ecmaVM->GetFactory();
999
1000    JSHandle<TaggedArray> values(factory->NewTaggedArray(3));
1001
1002    for (int i = 0; i < 3; i++) {
1003        values->Set(thread, i, JSTaggedValue(i + 1));
1004    }
1005    JSHandle<JSArray> array(JSArray::CreateArrayFromList(thread, values));
1006    JSHandle<JSArray> cloneArray = factory->CloneArrayLiteral(array);
1007
1008    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1009    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1010    ecmaRuntimeCallInfo1->SetThis(cloneArray.GetTaggedValue());
1011
1012    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1013    auto result = Array::Pop(ecmaRuntimeCallInfo1);
1014    TestHelper::TearDownFrame(thread, prev);
1015    ASSERT_EQ(result.GetRawData(), JSTaggedValue(3).GetRawData());
1016}
1017
1018// 22.1.3.11 new Array(1,2,3).Push(...items)
1019HWTEST_F_L0(BuiltinsArrayTest, Push)
1020{
1021    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1022    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1023    EXPECT_TRUE(arr != nullptr);
1024    JSHandle<JSObject> obj(thread, arr);
1025    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
1026
1027    JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
1028    PropertyDescriptor desc0(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), true, true, true);
1029    JSArray::DefineOwnProperty(thread, obj, key0, desc0);
1030    JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
1031    PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(2)), true, true, true);
1032    JSArray::DefineOwnProperty(thread, obj, key1, desc1);
1033    JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
1034    PropertyDescriptor desc2(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(3)), true, true, true);
1035    JSArray::DefineOwnProperty(thread, obj, key2, desc2);
1036
1037    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1038    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1039    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1040    ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(4)));
1041    ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(5)));
1042
1043    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1044    JSTaggedValue result = Array::Push(ecmaRuntimeCallInfo1);
1045    TestHelper::TearDownFrame(thread, prev);
1046    ASSERT_EQ(result.GetNumber(), 5);
1047
1048    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 5);
1049    JSHandle<JSTaggedValue> key3(thread, JSTaggedValue(3));
1050    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key3).GetValue()->GetInt(), 4);
1051    JSHandle<JSTaggedValue> key4(thread, JSTaggedValue(4));
1052    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key4).GetValue()->GetInt(), 5);
1053}
1054
1055HWTEST_F_L0(BuiltinsArrayTest, Reduce)
1056{
1057    auto ecmaVM = thread->GetEcmaVM();
1058    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
1059    ObjectFactory *factory = ecmaVM->GetFactory();
1060
1061    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1062    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1063    EXPECT_TRUE(arr != nullptr);
1064    JSHandle<JSObject> obj(thread, arr);
1065    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
1066
1067    std::vector<int> descVals{1, 2, 3};
1068    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1069
1070    JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestReduceFunc));
1071
1072    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1073    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1074    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1075    ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
1076    ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(10)));
1077
1078    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1079    JSTaggedValue result = Array::Reduce(ecmaRuntimeCallInfo1);
1080    TestHelper::TearDownFrame(thread, prev);
1081    ASSERT_EQ(result.GetRawData(), JSTaggedValue(16).GetRawData());
1082}
1083
1084HWTEST_F_L0(BuiltinsArrayTest, ReduceRight)
1085{
1086    auto ecmaVM = thread->GetEcmaVM();
1087    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
1088    ObjectFactory *factory = ecmaVM->GetFactory();
1089
1090    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1091    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1092    EXPECT_TRUE(arr != nullptr);
1093    JSHandle<JSObject> obj(thread, arr);
1094    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
1095
1096    std::vector<int> descVals{1, 2, 3};
1097    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1098
1099    JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestReduceRightFunc));
1100
1101    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1102    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1103    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1104    ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
1105    ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(10)));
1106
1107    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1108    JSTaggedValue result = Array::ReduceRight(ecmaRuntimeCallInfo1);
1109    TestHelper::TearDownFrame(thread, prev);
1110    ASSERT_EQ(result.GetRawData(), JSTaggedValue(16).GetRawData());
1111}
1112
1113HWTEST_F_L0(BuiltinsArrayTest, Shift)
1114{
1115    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1116    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1117    EXPECT_TRUE(arr != nullptr);
1118    JSHandle<JSObject> obj(thread, arr);
1119    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
1120
1121    std::vector<int> descVals{1, 2, 3};
1122    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1123
1124    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1125    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1126    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1127
1128    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1129    JSTaggedValue result = Array::Shift(ecmaRuntimeCallInfo1);
1130    TestHelper::TearDownFrame(thread, prev);
1131    ASSERT_EQ(result.GetRawData(), JSTaggedValue(1).GetRawData());
1132}
1133
1134HWTEST_F_L0(BuiltinsArrayTest, COWArrayShift)
1135{
1136    auto ecmaVM = thread->GetEcmaVM();
1137    ObjectFactory *factory = ecmaVM->GetFactory();
1138
1139    JSHandle<TaggedArray> values(factory->NewTaggedArray(3));
1140
1141    for (int i = 0; i < 3; i++) {
1142        values->Set(thread, i, JSTaggedValue(i + 1));
1143    }
1144    JSHandle<JSArray> array(JSArray::CreateArrayFromList(thread, values));
1145    JSHandle<JSArray> cloneArray = factory->CloneArrayLiteral(array);
1146
1147    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1148    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1149    ecmaRuntimeCallInfo1->SetThis(cloneArray.GetTaggedValue());
1150
1151    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1152    JSTaggedValue result = Array::Shift(ecmaRuntimeCallInfo1);
1153    TestHelper::TearDownFrame(thread, prev);
1154    ASSERT_EQ(result.GetRawData(), JSTaggedValue(1).GetRawData());
1155}
1156
1157HWTEST_F_L0(BuiltinsArrayTest, Some)
1158{
1159    auto ecmaVM = thread->GetEcmaVM();
1160    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
1161    ObjectFactory *factory = ecmaVM->GetFactory();
1162
1163    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1164    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1165    EXPECT_TRUE(arr != nullptr);
1166    JSHandle<JSObject> obj(thread, arr);
1167    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
1168
1169    std::vector<int> descVals{1, 20, 3};
1170    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1171
1172    JSHandle<JSArray> jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0)));
1173    JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestSomeFunc));
1174
1175    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1176    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1177    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1178    ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
1179    ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue());
1180
1181    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1182    JSTaggedValue result2 = Array::Some(ecmaRuntimeCallInfo1);
1183    TestHelper::TearDownFrame(thread, prev);
1184    ASSERT_EQ(result2.GetRawData(), JSTaggedValue::True().GetRawData());
1185}
1186
1187HWTEST_F_L0(BuiltinsArrayTest, Sort)
1188{
1189    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1190    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1191    EXPECT_TRUE(arr != nullptr);
1192    JSHandle<JSObject> obj(thread, arr);
1193    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
1194
1195    std::vector<int> descVals{3, 2, 1};
1196    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1197
1198    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1199    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1200    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1201
1202    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1203    JSTaggedValue result2 = Array::Sort(ecmaRuntimeCallInfo1);
1204    TestHelper::TearDownFrame(thread, prev);
1205
1206    EXPECT_TRUE(result2.IsECMAObject());
1207    JSHandle<JSTaggedValue> resultArr =
1208        JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result2.GetRawData())));
1209    EXPECT_EQ(JSArray::GetProperty(thread, resultArr, keys[0]).GetValue()->GetInt(), 1);
1210    EXPECT_EQ(JSArray::GetProperty(thread, resultArr, keys[1]).GetValue()->GetInt(), 2);
1211    EXPECT_EQ(JSArray::GetProperty(thread, resultArr, keys[2]).GetValue()->GetInt(), 3);
1212}
1213
1214HWTEST_F_L0(BuiltinsArrayTest, Unshift)
1215{
1216    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1217    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1218    EXPECT_TRUE(arr != nullptr);
1219    JSHandle<JSObject> obj(thread, arr);
1220    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
1221
1222    std::vector<int> descVals{1, 2, 3};
1223    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1224
1225    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1226    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1227    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1228    ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(4)));
1229    ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(5)));
1230
1231    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1232    JSTaggedValue result = Array::Unshift(ecmaRuntimeCallInfo1);
1233    TestHelper::TearDownFrame(thread, prev);
1234
1235    ASSERT_EQ(result.GetRawData(), JSTaggedValue(static_cast<double>(5)).GetRawData());
1236
1237    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 5);
1238    JSHandle<JSTaggedValue> key3(thread, JSTaggedValue(0));
1239    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key3).GetValue()->GetInt(), 4);
1240    JSHandle<JSTaggedValue> key4(thread, JSTaggedValue(1));
1241    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key4).GetValue()->GetInt(), 5);
1242}
1243
1244HWTEST_F_L0(BuiltinsArrayTest, Join)
1245{
1246    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1247    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1248    EXPECT_TRUE(arr != nullptr);
1249    JSHandle<JSTaggedValue> obj(thread, arr);
1250    EXPECT_EQ(JSArray::GetProperty(thread, obj, lengthKeyHandle).GetValue()->GetInt(), 0);
1251
1252    std::vector<int> descVals{2, 3, 4};
1253    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1254
1255    JSHandle<EcmaString> str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("2,3,4");
1256    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1257    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1258    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1259
1260    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1261    JSTaggedValue result = Array::Join(ecmaRuntimeCallInfo1);
1262    TestHelper::TearDownFrame(thread, prev);
1263    JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
1264
1265    ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, str), 0);
1266}
1267
1268HWTEST_F_L0(BuiltinsArrayTest, ToString)
1269{
1270    std::vector<int> descVals{2, 3, 4};
1271    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1272    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1273    EXPECT_TRUE(arr != nullptr);
1274    JSHandle<JSTaggedValue> obj(thread, arr);
1275    EXPECT_EQ(JSArray::GetProperty(thread, obj, lengthKeyHandle).GetValue()->GetInt(), 0);
1276    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1277
1278    JSHandle<EcmaString> str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("2,3,4");
1279    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1280    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1281    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1282
1283    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1284    JSTaggedValue result = Array::ToString(ecmaRuntimeCallInfo1);
1285    TestHelper::TearDownFrame(thread, prev);
1286    JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
1287
1288    ASSERT_EQ(EcmaStringAccessor::Compare(instance, resultHandle, str), 0);
1289}
1290
1291HWTEST_F_L0(BuiltinsArrayTest, Includes)
1292{
1293    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1294    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1295    EXPECT_TRUE(arr != nullptr);
1296    JSHandle<JSTaggedValue> obj(thread, arr);
1297    std::vector<int> descVals{2, 3, 4};
1298    EXPECT_EQ(JSArray::GetProperty(thread, obj, lengthKeyHandle).GetValue()->GetInt(), 0);
1299    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1300
1301    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1302    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1303    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1304    ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(2)));
1305
1306    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1307    [[maybe_unused]] JSTaggedValue result = Array::Includes(ecmaRuntimeCallInfo1);
1308    TestHelper::TearDownFrame(thread, prev);
1309
1310    ASSERT_TRUE(result.JSTaggedValue::ToBoolean());  // new Int8Array[2,3,4].includes(2)
1311
1312    auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1313    ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
1314    ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue());
1315    ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(1)));
1316
1317    prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
1318    result = Array::Includes(ecmaRuntimeCallInfo2);
1319    TestHelper::TearDownFrame(thread, prev);
1320
1321    ASSERT_TRUE(!result.JSTaggedValue::ToBoolean());  // new Int8Array[2,3,4].includes(1)
1322
1323    auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1324    ecmaRuntimeCallInfo3->SetFunction(JSTaggedValue::Undefined());
1325    ecmaRuntimeCallInfo3->SetThis(obj.GetTaggedValue());
1326    ecmaRuntimeCallInfo3->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(3)));
1327    ecmaRuntimeCallInfo3->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(1)));
1328
1329    prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo3);
1330    result = Array::Includes(ecmaRuntimeCallInfo3);
1331    TestHelper::TearDownFrame(thread, prev);
1332
1333    ASSERT_TRUE(result.JSTaggedValue::ToBoolean());  // new Int8Array[2,3,4].includes(3, 1)
1334
1335    auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1336    ecmaRuntimeCallInfo4->SetFunction(JSTaggedValue::Undefined());
1337    ecmaRuntimeCallInfo4->SetThis(obj.GetTaggedValue());
1338    ecmaRuntimeCallInfo4->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(2)));
1339    ecmaRuntimeCallInfo4->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(5)));
1340
1341    prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo4);
1342    result = Array::Includes(ecmaRuntimeCallInfo4);
1343    TestHelper::TearDownFrame(thread, prev);
1344
1345    ASSERT_TRUE(!result.JSTaggedValue::ToBoolean());  // new Int8Array[2,3,4].includes(2, 5)
1346
1347    auto ecmaRuntimeCallInfo5 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1348    ecmaRuntimeCallInfo5->SetFunction(JSTaggedValue::Undefined());
1349    ecmaRuntimeCallInfo5->SetThis(obj.GetTaggedValue());
1350    ecmaRuntimeCallInfo5->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(2)));
1351    ecmaRuntimeCallInfo5->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(-2)));
1352
1353    prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo5);
1354    result = Array::Includes(ecmaRuntimeCallInfo5);
1355    TestHelper::TearDownFrame(thread, prev);
1356
1357    ASSERT_TRUE(!result.JSTaggedValue::ToBoolean());  // new Int8Array[2,3,4].includes(2, -2)
1358}
1359
1360// es12 23.1.3.10 new Array(1,[2,3]).flat()
1361HWTEST_F_L0(BuiltinsArrayTest, Flat)
1362{
1363    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1364    JSArray *arr1 = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1365    EXPECT_TRUE(arr1 != nullptr);
1366    JSHandle<JSObject> obj1(thread, arr1);
1367    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj1), lengthKeyHandle).GetValue()->GetInt(), 0);
1368
1369    JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
1370    PropertyDescriptor desc0(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), true, true, true);
1371    JSArray::DefineOwnProperty(thread, obj1, key0, desc0);
1372
1373    JSArray *arr2 = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1374    EXPECT_TRUE(arr2 != nullptr);
1375    JSHandle<JSObject> obj2(thread, arr2);
1376    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj2), lengthKeyHandle).GetValue()->GetInt(), 0);
1377
1378    PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(2)), true, true, true);
1379    JSArray::DefineOwnProperty(thread, obj2, key0, desc1);
1380
1381    JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
1382    PropertyDescriptor desc2(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(3)), true, true, true);
1383    JSArray::DefineOwnProperty(thread, obj2, key1, desc2);
1384
1385    PropertyDescriptor desc3(thread, JSHandle<JSTaggedValue>(thread, obj2.GetTaggedValue()), true, true, true);
1386    JSArray::DefineOwnProperty(thread, obj1, key1, desc3);
1387
1388    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1389    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1390    ecmaRuntimeCallInfo1->SetThis(obj1.GetTaggedValue());
1391    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1392    JSTaggedValue result = Array::Flat(ecmaRuntimeCallInfo1);
1393    TestHelper::TearDownFrame(thread, prev);
1394    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
1395    ASSERT_TRUE(value.IsECMAObject());
1396    PropertyDescriptor descRes(thread);
1397    JSHandle<JSObject> valueHandle(thread, value);
1398    JSObject::GetOwnProperty(thread, valueHandle, key0, descRes);
1399    ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(1));
1400    JSObject::GetOwnProperty(thread, valueHandle, key1, descRes);
1401    ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(2));
1402    JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
1403    JSObject::GetOwnProperty(thread, valueHandle, key2, descRes);
1404    ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(3));
1405}
1406
1407// es12 23.1.3.10 new Array(1,50,3]).flatMap(x => [x * 2])
1408HWTEST_F_L0(BuiltinsArrayTest, FlatMap)
1409{
1410    auto ecmaVM = thread->GetEcmaVM();
1411    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
1412    ObjectFactory *factory = ecmaVM->GetFactory();
1413
1414    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1415    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1416    EXPECT_TRUE(arr != nullptr);
1417    JSHandle<JSObject> obj(thread, arr);
1418    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
1419
1420    std::vector<int> descVals{1, 50, 3};
1421    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1422
1423    JSHandle<JSArray> jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0)));
1424    JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestFlatMapFunc));
1425
1426    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1427    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1428    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1429    ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
1430    ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue());
1431
1432    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1433    JSTaggedValue result = Array::FlatMap(ecmaRuntimeCallInfo1);
1434    TestHelper::TearDownFrame(thread, prev);
1435    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
1436    ASSERT_TRUE(value.IsECMAObject());
1437
1438    PropertyDescriptor descRes(thread);
1439    JSHandle<JSObject> valueHandle(thread, value);
1440    EXPECT_EQ(
1441        JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 3);
1442    std::vector<int> vals{2, 100, 6};
1443    CheckKeyValueCommon(thread, valueHandle, descRes, keys, vals);
1444}
1445
1446HWTEST_F_L0(BuiltinsArrayTest, At)
1447{
1448    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1449    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1450    EXPECT_TRUE(arr != nullptr);
1451    std::vector<int> descVals{2, 3, 4};
1452    JSHandle<JSTaggedValue> obj(thread, arr);
1453    EXPECT_EQ(JSArray::GetProperty(thread, obj, lengthKeyHandle).GetValue()->GetInt(), 0);
1454
1455    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1456
1457    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1458    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1459    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1460    ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(0)));
1461    [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1462    JSTaggedValue result = Array::At(ecmaRuntimeCallInfo1);
1463    TestHelper::TearDownFrame(thread, prev1);
1464    ASSERT_EQ(result.GetRawData(), JSTaggedValue(2).GetRawData());
1465
1466    auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1467    ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
1468    ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue());
1469    ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(2)));
1470    [[maybe_unused]] auto prev2 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
1471    result = Array::At(ecmaRuntimeCallInfo2);
1472    TestHelper::TearDownFrame(thread, prev2);
1473    ASSERT_EQ(result.GetRawData(), JSTaggedValue(4).GetRawData());
1474
1475    auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1476    ecmaRuntimeCallInfo3->SetFunction(JSTaggedValue::Undefined());
1477    ecmaRuntimeCallInfo3->SetThis(obj.GetTaggedValue());
1478    ecmaRuntimeCallInfo3->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(3)));
1479    [[maybe_unused]] auto prev3 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo3);
1480    result = Array::At(ecmaRuntimeCallInfo3);
1481    TestHelper::TearDownFrame(thread, prev3);
1482    ASSERT_EQ(result, JSTaggedValue::Undefined());
1483
1484    auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1485    ecmaRuntimeCallInfo4->SetFunction(JSTaggedValue::Undefined());
1486    ecmaRuntimeCallInfo4->SetThis(obj.GetTaggedValue());
1487    ecmaRuntimeCallInfo4->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(-1)));
1488    [[maybe_unused]] auto prev4 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo4);
1489    result = Array::At(ecmaRuntimeCallInfo4);
1490    TestHelper::TearDownFrame(thread, prev4);
1491    ASSERT_EQ(result.GetRawData(), JSTaggedValue(4).GetRawData());
1492
1493    auto ecmaRuntimeCallInfo5 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1494    ecmaRuntimeCallInfo5->SetFunction(JSTaggedValue::Undefined());
1495    ecmaRuntimeCallInfo5->SetThis(obj.GetTaggedValue());
1496    ecmaRuntimeCallInfo5->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(-3)));
1497    [[maybe_unused]] auto prev5 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo5);
1498    result = Array::At(ecmaRuntimeCallInfo5);
1499    TestHelper::TearDownFrame(thread, prev5);
1500    ASSERT_EQ(result.GetRawData(), JSTaggedValue(2).GetRawData());
1501
1502    auto ecmaRuntimeCallInfo6 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1503    ecmaRuntimeCallInfo6->SetFunction(JSTaggedValue::Undefined());
1504    ecmaRuntimeCallInfo6->SetThis(obj.GetTaggedValue());
1505    ecmaRuntimeCallInfo6->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(-4)));
1506    [[maybe_unused]] auto prev6 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo6);
1507    result = Array::At(ecmaRuntimeCallInfo6);
1508    TestHelper::TearDownFrame(thread, prev6);
1509    ASSERT_EQ(result, JSTaggedValue::Undefined());
1510}
1511
1512HWTEST_F_L0(BuiltinsArrayTest, With)
1513{
1514    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1515    JSArray *arr =
1516        JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(INT_VALUE_0)).GetTaggedValue().GetTaggedObject());
1517    EXPECT_TRUE(arr != nullptr);
1518    JSHandle<JSObject> obj(thread, arr);
1519    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj),
1520                                   lengthKeyHandle).GetValue()->GetInt(), INT_VALUE_0);
1521
1522    std::vector<int> descVals{0, 1, 2};
1523    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1524
1525    auto ecmaRuntimeCallInfo1 =
1526        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), RUNTIME_CALL_INFO_PARA_NUM_8);
1527    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1528    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1529    ecmaRuntimeCallInfo1->SetCallArg(RUNTIME_CALL_INFO_PARA_0,
1530        JSTaggedValue(static_cast<uint32_t>((ArrayIndex::ARRAY_INDEX_1))));
1531    ecmaRuntimeCallInfo1->SetCallArg(RUNTIME_CALL_INFO_PARA_1, JSTaggedValue(INT_VALUE_3));
1532
1533    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1534    JSTaggedValue result = Array::With(ecmaRuntimeCallInfo1);
1535    TestHelper::TearDownFrame(thread, prev);
1536
1537    EXPECT_TRUE(result.IsECMAObject());
1538    JSHandle<JSTaggedValue> resultArr =
1539        JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result.GetRawData())));
1540    EXPECT_EQ(JSArray::GetProperty(thread, resultArr, keys[0]).GetValue()->GetInt(), INT_VALUE_0);
1541    EXPECT_EQ(JSArray::GetProperty(thread, resultArr, keys[1]).GetValue()->GetInt(), INT_VALUE_3);
1542    EXPECT_EQ(JSArray::GetProperty(thread, resultArr, keys[2]).GetValue()->GetInt(), INT_VALUE_2);
1543}
1544
1545HWTEST_F_L0(BuiltinsArrayTest, ToSorted)
1546{
1547    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1548    JSArray *arr =
1549        JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(INT_VALUE_0)).GetTaggedValue().GetTaggedObject());
1550    EXPECT_TRUE(arr != nullptr);
1551    JSHandle<JSObject> obj(thread, arr);
1552    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj),
1553                                   lengthKeyHandle).GetValue()->GetInt(), INT_VALUE_0);
1554    std::vector<int> descVals{3, 2, 1};
1555    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1556
1557    auto ecmaRuntimeCallInfo1 =
1558        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), RUNTIME_CALL_INFO_PARA_NUM_4);
1559    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1560    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1561
1562    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1563    JSTaggedValue result2 = Array::ToSorted(ecmaRuntimeCallInfo1);
1564    TestHelper::TearDownFrame(thread, prev);
1565
1566    EXPECT_TRUE(result2.IsECMAObject());
1567    JSHandle<JSTaggedValue> resultArr =
1568        JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result2.GetRawData())));
1569    EXPECT_EQ(JSArray::GetProperty(thread, resultArr, keys[0]).GetValue()->GetInt(), INT_VALUE_1);
1570    EXPECT_EQ(JSArray::GetProperty(thread, resultArr, keys[1]).GetValue()->GetInt(), INT_VALUE_2);
1571    EXPECT_EQ(JSArray::GetProperty(thread, resultArr, keys[2]).GetValue()->GetInt(), INT_VALUE_3);
1572}
1573
1574HWTEST_F_L0(BuiltinsArrayTest, ToSpliced)
1575{
1576    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1577    JSArray *arr =
1578        JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(INT_VALUE_0)).GetTaggedValue().GetTaggedObject());
1579    EXPECT_TRUE(arr != nullptr);
1580    JSHandle<JSObject> obj(thread, arr);
1581    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj),
1582                                   lengthKeyHandle).GetValue()->GetInt(), INT_VALUE_0);
1583    std::vector<int> descVals{0, 1, 2};
1584    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1585
1586    auto ecmaRuntimeCallInfo1 =
1587        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), RUNTIME_CALL_INFO_PARA_NUM_10);
1588    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1589    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1590    ecmaRuntimeCallInfo1->SetCallArg(INT_VALUE_0, JSTaggedValue(INT_VALUE_1));
1591    ecmaRuntimeCallInfo1->SetCallArg(INT_VALUE_1, JSTaggedValue(INT_VALUE_1));
1592    ecmaRuntimeCallInfo1->SetCallArg(INT_VALUE_2, JSTaggedValue(INT_VALUE_666));
1593
1594    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1595    JSTaggedValue result2 = Array::ToSpliced(ecmaRuntimeCallInfo1);
1596    TestHelper::TearDownFrame(thread, prev);
1597
1598    EXPECT_TRUE(result2.IsECMAObject());
1599    JSHandle<JSTaggedValue> resultArr =
1600        JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result2.GetRawData())));
1601    EXPECT_EQ(JSArray::GetProperty(thread, resultArr, keys[0]).GetValue()->GetInt(), INT_VALUE_0);
1602    EXPECT_EQ(JSArray::GetProperty(thread, resultArr, keys[1]).GetValue()->GetInt(), INT_VALUE_666);
1603    EXPECT_EQ(JSArray::GetProperty(thread, resultArr, keys[2]).GetValue()->GetInt(), INT_VALUE_2);
1604}
1605
1606HWTEST_F_L0(BuiltinsArrayTest, FindLast)
1607{
1608    auto ecmaVM = thread->GetEcmaVM();
1609    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
1610    ObjectFactory *factory = ecmaVM->GetFactory();
1611
1612    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1613    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1614    EXPECT_TRUE(arr != nullptr);
1615    JSHandle<JSObject> obj(thread, arr);
1616    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
1617    // arr [50, 40, 2]
1618    std::vector<int> descVals{50, 40, 2};
1619    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1620
1621    JSHandle<JSArray> jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0)));
1622    JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestFindLastFunc));
1623
1624    auto ecmaRuntimeCallInfo1 =
1625        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means 2 call args
1626    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1627    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1628    ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
1629    ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue());
1630
1631    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1632    JSTaggedValue result = Array::FindLast(ecmaRuntimeCallInfo1);
1633    TestHelper::TearDownFrame(thread, prev);
1634
1635    EXPECT_EQ(result.GetRawData(), JSTaggedValue(40).GetRawData());
1636}
1637
1638HWTEST_F_L0(BuiltinsArrayTest, FindLastIndex)
1639{
1640    auto ecmaVM = thread->GetEcmaVM();
1641    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
1642    ObjectFactory *factory = ecmaVM->GetFactory();
1643
1644    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1645    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1646    EXPECT_TRUE(arr != nullptr);
1647    JSHandle<JSObject> obj(thread, arr);
1648    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle).GetValue()->GetInt(), 0);
1649
1650    // arr [50, 40, 30]
1651    std::vector<int> descVals{50, 40, 30};
1652    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1653
1654    JSHandle<JSArray> jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0)));
1655    JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestFindLastIndexFunc));
1656
1657    auto ecmaRuntimeCallInfo1 =
1658        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means 2 call args
1659    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1660    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1661    ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
1662    ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue());
1663
1664    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1665    JSTaggedValue result = Array::FindLastIndex(ecmaRuntimeCallInfo1);
1666    TestHelper::TearDownFrame(thread, prev);
1667
1668    EXPECT_EQ(result.GetRawData(), JSTaggedValue(static_cast<double>(2)).GetRawData());
1669}
1670
1671HWTEST_F_L0(BuiltinsArrayTest, ToReversed)
1672{
1673    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1674    JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
1675    EXPECT_TRUE(arr != nullptr);
1676    JSHandle<JSObject> obj(thread, arr);
1677    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj),
1678                                   lengthKeyHandle).GetValue()->GetInt(), INT_VALUE_0);
1679
1680    std::vector<int> descVals{50, 200, 3};
1681    auto keys = DefineOwnPropertyCommonTest(thread, obj, descVals);
1682
1683    auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), INT_VALUE_4);
1684    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
1685    ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
1686
1687    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
1688    JSTaggedValue result = Array::ToReversed(ecmaRuntimeCallInfo1);
1689    TestHelper::TearDownFrame(thread, prev);
1690    JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
1691    ASSERT_TRUE(value.IsECMAObject());
1692
1693    PropertyDescriptor descRes(thread);
1694    JSHandle<JSObject> valueHandle(thread, value);
1695    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle),
1696                                   lengthKeyHandle).GetValue()->GetInt(), INT_VALUE_3);
1697
1698    std::vector<int> vals2{3, 200, 50};
1699    CheckKeyValueCommon(thread, valueHandle, descRes, keys, vals2);
1700    EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj),
1701                                   lengthKeyHandle).GetValue()->GetInt(), INT_VALUE_3);
1702
1703    std::vector<int> vals{50, 200, 3};
1704    CheckKeyValueCommon(thread, obj, descRes, keys, vals);
1705}
1706}  // namespace panda::test
1707