/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ecmascript/builtins/builtins_array.h" #include "ecmascript/ecma_string.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" #include "ecmascript/js_array.h" #include "ecmascript/js_array_iterator.h" #include "ecmascript/js_handle.h" #include "ecmascript/js_hclass.h" #include "ecmascript/js_object-inl.h" #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/js_tagged_value.h" #include "ecmascript/js_thread.h" #include "ecmascript/object_factory.h" #include "ecmascript/object_operator.h" #include "ecmascript/tests/test_helper.h" using namespace panda::ecmascript; using namespace panda::ecmascript::builtins; using namespace panda::ecmascript::base; namespace panda::test { using Array = ecmascript::builtins::BuiltinsArray; class BuiltinsArrayTest : public testing::Test { public: static void SetUpTestCase() { GTEST_LOG_(INFO) << "SetUpTestCase"; } static void TearDownTestCase() { GTEST_LOG_(INFO) << "TearDownCase"; } void SetUp() override { TestHelper::CreateEcmaVMWithScope(instance, thread, scope); } void TearDown() override { TestHelper::DestroyEcmaVMWithScope(instance, scope); } EcmaVM *instance {nullptr}; EcmaHandleScope *scope {nullptr}; JSThread *thread {nullptr}; class TestClass : public base::BuiltinsBase { public: static JSTaggedValue TestForEachFunc(EcmaRuntimeCallInfo *argv) { JSHandle key = GetCallArg(argv, 0); if (key->IsUndefined()) { return JSTaggedValue::Undefined(); } JSArray *jsArray = JSArray::Cast(GetThis(argv)->GetTaggedObject()); uint32_t length = jsArray->GetArrayLength() + 1U; jsArray->SetArrayLength(argv->GetThread(), length); return JSTaggedValue::Undefined(); } static JSTaggedValue TestEveryFunc(EcmaRuntimeCallInfo *argv) { uint32_t argc = argv->GetArgsNumber(); if (argc > 0) { if (GetCallArg(argv, 0)->GetInt() > 10) { // 10 : test case return GetTaggedBoolean(true); } } return GetTaggedBoolean(false); } static JSTaggedValue TestMapFunc(EcmaRuntimeCallInfo *argv) { int accumulator = GetCallArg(argv, 0)->GetInt(); accumulator = accumulator * 2; // 2 : mapped to 2 times the original value return BuiltinsBase::GetTaggedInt(accumulator); } static JSTaggedValue TestFlatMapFunc(EcmaRuntimeCallInfo *argv) { int accumulator = GetCallArg(argv, 0)->GetInt(); accumulator = accumulator * 2; // 2 : mapped to 2 times the original value JSThread *thread = argv->GetThread(); JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); auto property = JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle); EXPECT_EQ(property.GetValue()->GetInt(), 0); JSHandle key(thread, JSTaggedValue(0)); PropertyDescriptor desc(thread, JSHandle(thread, JSTaggedValue(accumulator)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key, desc); return obj.GetTaggedValue(); } static JSTaggedValue TestFindFunc(EcmaRuntimeCallInfo *argv) { uint32_t argc = argv->GetArgsNumber(); if (argc > 0) { // 10 : test case if (GetCallArg(argv, 0)->GetInt() > 10) { return GetTaggedBoolean(true); } } return GetTaggedBoolean(false); } static JSTaggedValue TestFindIndexFunc(EcmaRuntimeCallInfo *argv) { uint32_t argc = argv->GetArgsNumber(); if (argc > 0) { // 10 : test case if (GetCallArg(argv, 0)->GetInt() > 10) { return GetTaggedBoolean(true); } } return GetTaggedBoolean(false); } static JSTaggedValue TestReduceFunc(EcmaRuntimeCallInfo *argv) { int accumulator = GetCallArg(argv, 0)->GetInt(); accumulator = accumulator + GetCallArg(argv, 1)->GetInt(); return BuiltinsBase::GetTaggedInt(accumulator); } static JSTaggedValue TestReduceRightFunc(EcmaRuntimeCallInfo *argv) { int accumulator = GetCallArg(argv, 0)->GetInt(); accumulator = accumulator + GetCallArg(argv, 1)->GetInt(); return BuiltinsBase::GetTaggedInt(accumulator); } static JSTaggedValue TestSomeFunc(EcmaRuntimeCallInfo *argv) { uint32_t argc = argv->GetArgsNumber(); if (argc > 0) { if (GetCallArg(argv, 0)->GetInt() > 10) { // 10 : test case return GetTaggedBoolean(true); } } return GetTaggedBoolean(false); } }; }; JSTaggedValue CreateBuiltinsArrayJSObject(JSThread *thread, const CString keyCStr) { EcmaVM *ecmaVM = thread->GetEcmaVM(); JSHandle globalEnv = ecmaVM->GetGlobalEnv(); JSHandle hclass = globalEnv->GetObjectFunction(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle obj(factory->NewJSObjectByConstructor(JSHandle(hclass), hclass)); JSHandle key(factory->NewFromASCII(&keyCStr[0])); JSHandle value(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, obj, key, value); return obj.GetTaggedValue(); } HWTEST_F_L0(BuiltinsArrayTest, ArrayConstructor) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); JSHandle array(env->GetArrayFunction()); JSHandle globalObject(thread, env->GetGlobalObject()); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo1->SetFunction(array.GetTaggedValue()); ecmaRuntimeCallInfo1->SetThis(globalObject.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(1))); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(3))); ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast(5))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::ArrayConstructor(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); JSHandle key0(thread, JSTaggedValue(0)); JSHandle key1(thread, JSTaggedValue(1)); JSHandle key2(thread, JSTaggedValue(2)); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(1)); JSObject::GetOwnProperty(thread, valueHandle, key1, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(3)); JSObject::GetOwnProperty(thread, valueHandle, key2, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(5)); } // 22.1.2.1 Array.from ( items [ , mapfn [ , thisArg ] ] ) HWTEST_F_L0(BuiltinsArrayTest, From) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0))->GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle key3(thread, JSTaggedValue(3)); PropertyDescriptor desc3(thread, JSHandle(thread, JSTaggedValue(4)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key3, desc3); JSHandle key4(thread, JSTaggedValue(4)); PropertyDescriptor desc4(thread, JSHandle(thread, JSTaggedValue(5)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key4, desc4); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, obj.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::From(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(1)); JSObject::GetOwnProperty(thread, valueHandle, key1, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(2)); JSObject::GetOwnProperty(thread, valueHandle, key2, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(3)); JSObject::GetOwnProperty(thread, valueHandle, key3, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(4)); JSObject::GetOwnProperty(thread, valueHandle, key4, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(5)); } // 22.1.2.2 Array.isArray(arg) HWTEST_F_L0(BuiltinsArrayTest, IsArray) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetCallArg(0, obj.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::IsArray(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData()); auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo2->SetThis(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast(1))); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2); result = Array::IsArray(ecmaRuntimeCallInfo2); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData()); } HWTEST_F_L0(BuiltinsArrayTest, Of) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); JSHandle array(env->GetArrayFunction()); JSHandle globalObject(thread, env->GetGlobalObject()); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo1->SetFunction(array.GetTaggedValue()); ecmaRuntimeCallInfo1->SetThis(globalObject.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(1))); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(3))); ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast(5))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Of(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); JSHandle key0(thread, JSTaggedValue(0)); JSHandle key1(thread, JSTaggedValue(1)); JSHandle key2(thread, JSTaggedValue(2)); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(1)); JSObject::GetOwnProperty(thread, valueHandle, key1, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(3)); JSObject::GetOwnProperty(thread, valueHandle, key2, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(5)); } HWTEST_F_L0(BuiltinsArrayTest, Species) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); JSHandle array(env->GetArrayFunction()); JSHandle globalObject(thread, env->GetGlobalObject()); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(array.GetTaggedValue()); ecmaRuntimeCallInfo1->SetThis(globalObject.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Species(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_TRUE(result.IsECMAObject()); } HWTEST_F_L0(BuiltinsArrayTest, Concat) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSArray *arr1 = JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetObject(); EXPECT_TRUE(arr1 != nullptr); JSHandle obj1(thread, arr1); JSHandle key4(thread, JSTaggedValue(0)); PropertyDescriptor desc4(thread, JSHandle(thread, JSTaggedValue(4)), true, true, true); JSArray::DefineOwnProperty(thread, obj1, key4, desc4); JSHandle key5(thread, JSTaggedValue(1)); PropertyDescriptor desc5(thread, JSHandle(thread, JSTaggedValue(5)), true, true, true); JSArray::DefineOwnProperty(thread, obj1, key5, desc5); JSHandle key6(thread, JSTaggedValue(2)); PropertyDescriptor desc6(thread, JSHandle(thread, JSTaggedValue(6)), true, true, true); JSArray::DefineOwnProperty(thread, obj1, key6, desc6); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, obj1.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Concat(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); JSHandle key7(thread, JSTaggedValue(5)); EXPECT_EQ( JSArray::GetProperty(thread, JSHandle(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 6); JSObject::GetOwnProperty(thread, valueHandle, key7, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(6)); } // 22.1.3.3 new Array(1,2,3,4,5).CopyWithin(0,3,5) HWTEST_F_L0(BuiltinsArrayTest, CopyWithin) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle key3(thread, JSTaggedValue(3)); PropertyDescriptor desc3(thread, JSHandle(thread, JSTaggedValue(4)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key3, desc3); JSHandle key4(thread, JSTaggedValue(4)); PropertyDescriptor desc4(thread, JSHandle(thread, JSTaggedValue(5)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key4, desc4); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(0))); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(3))); ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast(5))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::CopyWithin(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(4)); JSObject::GetOwnProperty(thread, valueHandle, key1, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(5)); JSObject::GetOwnProperty(thread, valueHandle, key2, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(3)); JSObject::GetOwnProperty(thread, valueHandle, key3, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(4)); JSObject::GetOwnProperty(thread, valueHandle, key4, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(5)); } HWTEST_F_L0(BuiltinsArrayTest, Every) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(100)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(200)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(300)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle jsArray = factory->NewJSArray(); JSHandle func = factory->NewJSFunction(env, reinterpret_cast(TestClass::TestEveryFunc)); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result2 = Array::Every(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result2.GetRawData(), JSTaggedValue::True().GetRawData()); } HWTEST_F_L0(BuiltinsArrayTest, Map) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(50)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(200)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0))); JSHandle func = factory->NewJSFunction(env, reinterpret_cast(TestClass::TestMapFunc)); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Map(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); EXPECT_EQ( JSArray::GetProperty(thread, JSHandle(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 3); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue()->GetInt(), 100); JSObject::GetOwnProperty(thread, valueHandle, key1, descRes); ASSERT_EQ(descRes.GetValue()->GetInt(), 400); JSObject::GetOwnProperty(thread, valueHandle, key2, descRes); ASSERT_EQ(descRes.GetValue()->GetInt(), 6); } HWTEST_F_L0(BuiltinsArrayTest, Reverse) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(50)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(200)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Reverse(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); EXPECT_EQ( JSArray::GetProperty(thread, JSHandle(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 3); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(3)); JSObject::GetOwnProperty(thread, valueHandle, key1, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(200)); JSObject::GetOwnProperty(thread, valueHandle, key2, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(50)); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 3); JSObject::GetOwnProperty(thread, obj, key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(3)); JSObject::GetOwnProperty(thread, obj, key1, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(200)); JSObject::GetOwnProperty(thread, obj, key2, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(50)); } HWTEST_F_L0(BuiltinsArrayTest, COWArrayReverse) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(50)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(200)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle cloneArray = thread->GetEcmaVM()->GetFactory()->CloneArrayLiteral(JSHandle(obj)); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(cloneArray.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Reverse(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); EXPECT_EQ( JSArray::GetProperty(thread, JSHandle(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 3); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(3)); JSObject::GetOwnProperty(thread, valueHandle, key1, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(200)); JSObject::GetOwnProperty(thread, valueHandle, key2, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(50)); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(cloneArray), lengthKeyHandle).GetValue()->GetInt(), 3); JSObject::GetOwnProperty(thread, JSHandle(cloneArray), key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(3)); JSObject::GetOwnProperty(thread, JSHandle(cloneArray), key1, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(200)); JSObject::GetOwnProperty(thread, JSHandle(cloneArray), key2, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(50)); } HWTEST_F_L0(BuiltinsArrayTest, Slice) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle key3(thread, JSTaggedValue(3)); PropertyDescriptor desc3(thread, JSHandle(thread, JSTaggedValue(4)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key3, desc3); JSHandle key4(thread, JSTaggedValue(4)); PropertyDescriptor desc4(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key4, desc4); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(1))); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(4))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Slice(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); EXPECT_EQ( JSArray::GetProperty(thread, JSHandle(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 3); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(2)); JSObject::GetOwnProperty(thread, valueHandle, key1, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(3)); JSObject::GetOwnProperty(thread, valueHandle, key2, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(4)); } HWTEST_F_L0(BuiltinsArrayTest, Splice) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle key3(thread, JSTaggedValue(3)); PropertyDescriptor desc3(thread, JSHandle(thread, JSTaggedValue(4)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key3, desc3); JSHandle key4(thread, JSTaggedValue(4)); PropertyDescriptor desc4(thread, JSHandle(thread, JSTaggedValue(5)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key4, desc4); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(1))); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(2))); ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast(100))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Splice(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 4); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); EXPECT_EQ( JSArray::GetProperty(thread, JSHandle(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 2); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(2)); } // 22.1.3.6 new Array(1,2,3,4,5).Fill(0,1,3) HWTEST_F_L0(BuiltinsArrayTest, Fill) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle key3(thread, JSTaggedValue(3)); PropertyDescriptor desc3(thread, JSHandle(thread, JSTaggedValue(4)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key3, desc3); JSHandle key4(thread, JSTaggedValue(4)); PropertyDescriptor desc4(thread, JSHandle(thread, JSTaggedValue(5)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key4, desc4); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(0))); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(1))); ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast(3))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Fill(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(1)); JSObject::GetOwnProperty(thread, valueHandle, key1, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(0)); JSObject::GetOwnProperty(thread, valueHandle, key2, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(0)); JSObject::GetOwnProperty(thread, valueHandle, key3, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(4)); JSObject::GetOwnProperty(thread, valueHandle, key4, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(5)); } // 22.1.3.6 new Array(1,2,3,4,5).Fill(0,1,3) HWTEST_F_L0(BuiltinsArrayTest, COWArrayFill) { auto ecmaVM = thread->GetEcmaVM(); ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle values(factory->NewTaggedArray(5)); for (int i = 0; i < 5; i++) { values->Set(thread, i, JSTaggedValue(i + 1)); } JSHandle array(JSArray::CreateArrayFromList(thread, values)); JSHandle cloneArray = factory->CloneArrayLiteral(array); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(cloneArray.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(0))); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(1))); ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast(3))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Fill(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); JSHandle key0(thread, JSTaggedValue(0)); JSHandle key1(thread, JSTaggedValue(1)); JSHandle key2(thread, JSTaggedValue(2)); JSHandle key3(thread, JSTaggedValue(3)); JSHandle key4(thread, JSTaggedValue(4)); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(1)); JSObject::GetOwnProperty(thread, valueHandle, key1, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(0)); JSObject::GetOwnProperty(thread, valueHandle, key2, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(0)); JSObject::GetOwnProperty(thread, valueHandle, key3, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(4)); JSObject::GetOwnProperty(thread, valueHandle, key4, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(5)); } HWTEST_F_L0(BuiltinsArrayTest, Find) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(102)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0))); JSHandle func = factory->NewJSFunction(env, reinterpret_cast(TestClass::TestFindFunc)); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result2 = Array::Find(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); EXPECT_EQ(result2.GetRawData(), JSTaggedValue(102).GetRawData()); } HWTEST_F_L0(BuiltinsArrayTest, FindIndex) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(30)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0))); JSHandle func = factory->NewJSFunction(env, reinterpret_cast(TestClass::TestFindIndexFunc)); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result2 = Array::FindIndex(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); EXPECT_EQ(result2.GetRawData(), JSTaggedValue(static_cast(2)).GetRawData()); } HWTEST_F_L0(BuiltinsArrayTest, ForEach) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0))); JSHandle func = factory->NewJSFunction(env, reinterpret_cast(TestClass::TestForEachFunc)); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result2 = Array::ForEach(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); EXPECT_EQ(result2.GetRawData(), JSTaggedValue::VALUE_UNDEFINED); EXPECT_EQ(jsArray->GetArrayLength(), 3U); } // 22.1.3.11 new Array(1,2,3,4,3).IndexOf(searchElement [ , fromIndex ]) HWTEST_F_L0(BuiltinsArrayTest, IndexOf) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle key3(thread, JSTaggedValue(3)); PropertyDescriptor desc3(thread, JSHandle(thread, JSTaggedValue(4)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key3, desc3); JSHandle key4(thread, JSTaggedValue(4)); PropertyDescriptor desc4(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key4, desc4); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(3))); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(0))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::IndexOf(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(2).GetRawData()); auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast(3))); ecmaRuntimeCallInfo2->SetCallArg(1, JSTaggedValue(static_cast(3))); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2); result = Array::IndexOf(ecmaRuntimeCallInfo2); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(4).GetRawData()); auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo3->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo3->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo3->SetCallArg(0, JSTaggedValue(static_cast(5))); ecmaRuntimeCallInfo3->SetCallArg(1, JSTaggedValue(static_cast(0))); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo3); result = Array::IndexOf(ecmaRuntimeCallInfo3); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(-1).GetRawData()); auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo4->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo4->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo4->SetCallArg(0, JSTaggedValue(static_cast(3))); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo4); result = Array::IndexOf(ecmaRuntimeCallInfo4); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(2).GetRawData()); } // 22.1.3.14 new Array(1,2,3,4,3).LastIndexOf(searchElement [ , fromIndex ]) HWTEST_F_L0(BuiltinsArrayTest, LastIndexOf) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle key3(thread, JSTaggedValue(3)); PropertyDescriptor desc3(thread, JSHandle(thread, JSTaggedValue(4)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key3, desc3); JSHandle key4(thread, JSTaggedValue(4)); PropertyDescriptor desc4(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key4, desc4); // new Array(1,2,3,4,3).LastIndexOf(3,4) auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(3))); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(4))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::LastIndexOf(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(static_cast(4)).GetRawData()); // new Array(1,2,3,4,3).LastIndexOf(3,3) auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast(3))); ecmaRuntimeCallInfo2->SetCallArg(1, JSTaggedValue(static_cast(3))); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2); result = Array::LastIndexOf(ecmaRuntimeCallInfo2); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(static_cast(2)).GetRawData()); // new Array(1,2,3,4,3).LastIndexOf(5,4) auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo3->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo3->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo3->SetCallArg(0, JSTaggedValue(static_cast(5))); ecmaRuntimeCallInfo3->SetCallArg(1, JSTaggedValue(static_cast(4))); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo3); result = Array::LastIndexOf(ecmaRuntimeCallInfo3); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(-1).GetRawData()); // new Array(1,2,3,4,3).LastIndexOf(3) auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo4->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo4->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo4->SetCallArg(0, JSTaggedValue(static_cast(3))); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo4); result = Array::LastIndexOf(ecmaRuntimeCallInfo4); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(static_cast(4)).GetRawData()); } // 22.1.3.11 new Array().Pop() HWTEST_F_L0(BuiltinsArrayTest, Pop) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Pop(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED); ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue()); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2); result = Array::Pop(ecmaRuntimeCallInfo2); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(3).GetRawData()); } // 22.1.3.11 new Array().Pop() HWTEST_F_L0(BuiltinsArrayTest, COWArrayPop) { auto ecmaVM = thread->GetEcmaVM(); ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle values(factory->NewTaggedArray(3)); for (int i = 0; i < 3; i++) { values->Set(thread, i, JSTaggedValue(i + 1)); } JSHandle array(JSArray::CreateArrayFromList(thread, values)); JSHandle cloneArray = factory->CloneArrayLiteral(array); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(cloneArray.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); auto result = Array::Pop(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(3).GetRawData()); } // 22.1.3.11 new Array(1,2,3).Push(...items) HWTEST_F_L0(BuiltinsArrayTest, Push) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(4))); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(5))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Push(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetNumber(), 5); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 5); JSHandle key3(thread, JSTaggedValue(3)); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), key3).GetValue()->GetInt(), 4); JSHandle key4(thread, JSTaggedValue(4)); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), key4).GetValue()->GetInt(), 5); } HWTEST_F_L0(BuiltinsArrayTest, Reduce) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle func = factory->NewJSFunction(env, reinterpret_cast(TestClass::TestReduceFunc)); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(10))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Reduce(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(16).GetRawData()); } HWTEST_F_L0(BuiltinsArrayTest, ReduceRight) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle func = factory->NewJSFunction(env, reinterpret_cast(TestClass::TestReduceRightFunc)); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(10))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::ReduceRight(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(16).GetRawData()); } HWTEST_F_L0(BuiltinsArrayTest, Shift) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Shift(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(1).GetRawData()); } HWTEST_F_L0(BuiltinsArrayTest, COWArrayShift) { auto ecmaVM = thread->GetEcmaVM(); ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle values(factory->NewTaggedArray(3)); for (int i = 0; i < 3; i++) { values->Set(thread, i, JSTaggedValue(i + 1)); } JSHandle array(JSArray::CreateArrayFromList(thread, values)); JSHandle cloneArray = factory->CloneArrayLiteral(array); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(cloneArray.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Shift(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(1).GetRawData()); } HWTEST_F_L0(BuiltinsArrayTest, Some) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(20)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0))); JSHandle func = factory->NewJSFunction(env, reinterpret_cast(TestClass::TestSomeFunc)); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result2 = Array::Some(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result2.GetRawData(), JSTaggedValue::True().GetRawData()); } HWTEST_F_L0(BuiltinsArrayTest, Sort) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result2 = Array::Sort(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); EXPECT_TRUE(result2.IsECMAObject()); JSHandle resultArr = JSHandle(thread, JSTaggedValue(static_cast(result2.GetRawData()))); EXPECT_EQ(JSArray::GetProperty(thread, resultArr, key0).GetValue()->GetInt(), 1); EXPECT_EQ(JSArray::GetProperty(thread, resultArr, key1).GetValue()->GetInt(), 2); EXPECT_EQ(JSArray::GetProperty(thread, resultArr, key2).GetValue()->GetInt(), 3); } HWTEST_F_L0(BuiltinsArrayTest, Unshift) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(4))); ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(5))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Unshift(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue(static_cast(5)).GetRawData()); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 5); JSHandle key3(thread, JSTaggedValue(0)); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), key3).GetValue()->GetInt(), 4); JSHandle key4(thread, JSTaggedValue(1)); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), key4).GetValue()->GetInt(), 5); } HWTEST_F_L0(BuiltinsArrayTest, Join) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, obj, lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(2))); JSArray::DefineOwnProperty(thread, JSHandle(obj), key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(3))); JSArray::DefineOwnProperty(thread, JSHandle(obj), key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(4))); JSArray::DefineOwnProperty(thread, JSHandle(obj), key2, desc2); JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("2,3,4"); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Join(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); [[maybe_unused]] auto *res = EcmaString::Cast(resultHandle.GetTaggedValue().GetTaggedObject()); ASSERT_EQ(EcmaStringAccessor::Compare(res, *str), 0); } HWTEST_F_L0(BuiltinsArrayTest, ToString) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, obj, lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(2))); JSArray::DefineOwnProperty(thread, JSHandle(obj), key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(3))); JSArray::DefineOwnProperty(thread, JSHandle(obj), key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(4))); JSArray::DefineOwnProperty(thread, JSHandle(obj), key2, desc2); JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("2,3,4"); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::ToString(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); [[maybe_unused]] auto *res = EcmaString::Cast(resultHandle.GetTaggedValue().GetTaggedObject()); ASSERT_EQ(EcmaStringAccessor::Compare(res, *str), 0); } HWTEST_F_L0(BuiltinsArrayTest, Includes) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, obj, lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(2))); JSArray::DefineOwnProperty(thread, JSHandle(obj), key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(3))); JSArray::DefineOwnProperty(thread, JSHandle(obj), key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(4))); JSArray::DefineOwnProperty(thread, JSHandle(obj), key2, desc2); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(2))); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); [[maybe_unused]] JSTaggedValue result = Array::Includes(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); ASSERT_TRUE(result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(2) auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast(1))); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2); result = Array::Includes(ecmaRuntimeCallInfo2); TestHelper::TearDownFrame(thread, prev); ASSERT_TRUE(!result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(1) auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo3->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo3->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo3->SetCallArg(0, JSTaggedValue(static_cast(3))); ecmaRuntimeCallInfo3->SetCallArg(1, JSTaggedValue(static_cast(1))); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo3); result = Array::Includes(ecmaRuntimeCallInfo3); TestHelper::TearDownFrame(thread, prev); ASSERT_TRUE(result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(3, 1) auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo4->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo4->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo4->SetCallArg(0, JSTaggedValue(static_cast(2))); ecmaRuntimeCallInfo4->SetCallArg(1, JSTaggedValue(static_cast(5))); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo4); result = Array::Includes(ecmaRuntimeCallInfo4); TestHelper::TearDownFrame(thread, prev); ASSERT_TRUE(!result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(2, 5) auto ecmaRuntimeCallInfo5 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo5->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo5->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo5->SetCallArg(0, JSTaggedValue(static_cast(2))); ecmaRuntimeCallInfo5->SetCallArg(1, JSTaggedValue(static_cast(-2))); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo5); result = Array::Includes(ecmaRuntimeCallInfo5); TestHelper::TearDownFrame(thread, prev); ASSERT_TRUE(!result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(2, -2) } // es12 23.1.3.10 new Array(1,[2,3]).flat() HWTEST_F_L0(BuiltinsArrayTest, Flat) { JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr1 = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr1 != nullptr); JSHandle obj1(thread, arr1); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj1), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj1, key0, desc0); JSArray *arr2 = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr2 != nullptr); JSHandle obj2(thread, arr2); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj2), lengthKeyHandle).GetValue()->GetInt(), 0); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(2)), true, true, true); JSArray::DefineOwnProperty(thread, obj2, key0, desc1); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj2, key1, desc2); PropertyDescriptor desc3(thread, JSHandle(thread, obj2.GetTaggedValue()), true, true, true); JSArray::DefineOwnProperty(thread, obj1, key1, desc3); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj1.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::Flat(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(1)); JSObject::GetOwnProperty(thread, valueHandle, key1, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(2)); JSHandle key2(thread, JSTaggedValue(2)); JSObject::GetOwnProperty(thread, valueHandle, key2, descRes); ASSERT_EQ(descRes.GetValue().GetTaggedValue(), JSTaggedValue(3)); } // es12 23.1.3.10 new Array(1,50,3]).flatMap(x => [x * 2]) HWTEST_F_L0(BuiltinsArrayTest, FlatMap) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject()); EXPECT_TRUE(arr != nullptr); JSHandle obj(thread, arr); EXPECT_EQ(JSArray::GetProperty(thread, JSHandle(obj), lengthKeyHandle).GetValue()->GetInt(), 0); JSHandle key0(thread, JSTaggedValue(0)); PropertyDescriptor desc0(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key0, desc0); JSHandle key1(thread, JSTaggedValue(1)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(50)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(3)), true, true, true); JSArray::DefineOwnProperty(thread, obj, key2, desc2); JSHandle jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0))); JSHandle func = factory->NewJSFunction(env, reinterpret_cast(TestClass::TestFlatMapFunc)); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue()); [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1); JSTaggedValue result = Array::FlatMap(ecmaRuntimeCallInfo1); TestHelper::TearDownFrame(thread, prev); JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); PropertyDescriptor descRes(thread); JSHandle valueHandle(thread, value); EXPECT_EQ( JSArray::GetProperty(thread, JSHandle(valueHandle), lengthKeyHandle).GetValue()->GetInt(), 3); JSObject::GetOwnProperty(thread, valueHandle, key0, descRes); ASSERT_EQ(descRes.GetValue()->GetInt(), 2); JSObject::GetOwnProperty(thread, valueHandle, key1, descRes); ASSERT_EQ(descRes.GetValue()->GetInt(), 100); JSObject::GetOwnProperty(thread, valueHandle, key2, descRes); ASSERT_EQ(descRes.GetValue()->GetInt(), 6); } } // namespace panda::test