1/* 2 * Copyright (c) 2021-2024 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/base/array_helper.h" 17#include "ecmascript/global_env.h" 18#include "ecmascript/js_array.h" 19#include "ecmascript/tests/test_helper.h" 20#include "ecmascript/js_typed_array.h" 21 22using namespace panda::ecmascript; 23using namespace panda::ecmascript::base; 24 25namespace panda::test { 26class ArrayHelperTest : public BaseTestWithScope<false> { 27}; 28 29/** 30 * @tc.name: IsConcatSpreadable 31 * @tc.desc: Check whether the second parameter is a JsArray type through "IsConcatSpreadable" function. 32 * @tc.type: FUNC 33 * @tc.require: 34 */ 35HWTEST_F_L0(ArrayHelperTest, IsConcatSpreadable) 36{ 37 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 38 JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); 39 JSHandle<JSTaggedValue> icConcatSpreadableSymbol(factory->NewWellKnownSymbolWithChar("icConcatSpreadableSymbol")); 40 JSHandle<JSTaggedValue> icSymbolValue(thread, JSTaggedValue(1)); 41 globalEnv->SetIsConcatSpreadableSymbol(thread, icConcatSpreadableSymbol); 42 JSHandle<JSTaggedValue> objFunc(globalEnv->GetArrayFunction()); 43 44 JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1)); 45 JSHandle<JSTaggedValue> handleArray(factory->NewJSArray()); 46 JSHandle<JSTaggedValue> handleObjectArr(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc)); 47 JSObject::SetProperty(thread, handleObjectArr, icConcatSpreadableSymbol, icSymbolValue); 48 49 EXPECT_FALSE(ArrayHelper::IsConcatSpreadable(thread, handleValue)); 50 EXPECT_TRUE(ArrayHelper::IsConcatSpreadable(thread, handleArray)); 51 EXPECT_TRUE(ArrayHelper::IsConcatSpreadable(thread, handleObjectArr)); 52} 53 54/** 55 * @tc.name: SortCompare 56 * @tc.desc: Check whether the two data(X,Y) are sorted from large two smalle,both X and Y are Undefined return zero,if 57 * X or Y is Undefined return -1,if X more than the Y return 1,otherwrise return 0. 58 * @tc.type: FUNC 59 * @tc.require: 60 */ 61HWTEST_F_L0(ArrayHelperTest, SortCompare) 62{ 63 JSHandle<JSTaggedValue> callbackfnHandle(thread, JSTaggedValue::Undefined()); 64 // callbackfnHandle is Undefined 65 JSHandle<JSTaggedValue> handleValueX1(thread, JSTaggedValue::Undefined()); 66 JSHandle<JSTaggedValue> handleValueX2(thread, JSTaggedValue(11)); 67 JSHandle<JSTaggedValue> handleValueX3(thread, JSTaggedValue(12)); 68 JSHandle<JSTaggedValue> handleValueY1(thread, JSTaggedValue::Undefined()); 69 JSHandle<JSTaggedValue> handleValueY2(thread, JSTaggedValue(10)); 70 JSHandle<JSTaggedValue> handleValueY3(thread, JSTaggedValue(12)); 71 72 int32_t resultValue1 = ArrayHelper::SortCompare(thread, callbackfnHandle, handleValueX1, handleValueY1); 73 int32_t resultValue2 = ArrayHelper::SortCompare(thread, callbackfnHandle, handleValueX1, handleValueY2); 74 int32_t resultValue3 = ArrayHelper::SortCompare(thread, callbackfnHandle, handleValueX2, handleValueY1); 75 int32_t resultValue4 = ArrayHelper::SortCompare(thread, callbackfnHandle, handleValueX2, handleValueY2); 76 int32_t resultValue5 = ArrayHelper::SortCompare(thread, callbackfnHandle, handleValueX3, handleValueY3); 77 int32_t resultValue6 = ArrayHelper::SortCompare(thread, callbackfnHandle, handleValueX2, handleValueY3); 78 79 EXPECT_EQ(resultValue1, 0); // both X and Y is Undefined 80 EXPECT_EQ(resultValue2, 1); // X is Undefined 81 EXPECT_EQ(resultValue3, -1); // Y is Undefined 82 EXPECT_EQ(resultValue4, 1); // X > Y 83 EXPECT_EQ(resultValue5, 0); // X = Y 84 EXPECT_EQ(resultValue6, -1); // X < Y 85} 86 87/** 88 * @tc.name: GetLength 89 * @tc.desc: Check whether the result returned through "GetLength" function is within expectations. 90 * @tc.type: FUNC 91 * @tc.require: 92 */ 93HWTEST_F_L0(ArrayHelperTest, GetLength) 94{ 95 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 96 JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); 97 98 JSHandle<JSTaggedValue> lengthKey = thread->GlobalConstants()->GetHandledLengthString(); 99 JSHandle<JSTaggedValue> lengthValue(thread, JSTaggedValue(100.0)); 100 101 JSArray *handleArr = JSArray::ArrayCreate(thread, JSTaggedNumber(10)).GetObject<JSArray>(); 102 JSHandle<JSTaggedValue> arrayHandle(thread, handleArr); 103 EXPECT_EQ(ArrayHelper::GetLength(thread, arrayHandle), 10U); 104 105 JSHandle<JSTaggedValue> HandleInt8ArrayFunc(globalEnv->GetInt8ArrayFunction()); 106 JSHandle<JSTypedArray> handleTypeArray = JSHandle<JSTypedArray>::Cast( 107 factory->NewJSObjectByConstructor(JSHandle<JSFunction>(HandleInt8ArrayFunc), HandleInt8ArrayFunc)); 108 handleTypeArray->SetArrayLength(11); 109 JSHandle<JSTaggedValue> typeArrayHandle(handleTypeArray); 110 EXPECT_EQ(ArrayHelper::GetLength(thread, typeArrayHandle), 11U); 111 112 JSHandle<JSTaggedValue> objFunc(globalEnv->GetArrayFunction()); 113 JSHandle<JSObject> objectHandle = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc); 114 EXPECT_EQ(ArrayHelper::GetLength(thread, JSHandle<JSTaggedValue>(objectHandle)), 0U); 115 116 JSObject::SetProperty(thread, objectHandle, lengthKey, lengthValue); 117 EXPECT_EQ(ArrayHelper::GetLength(thread, JSHandle<JSTaggedValue>(objectHandle)), 118 JSTaggedNumber(100.0).GetNumber()); 119} 120 121/** 122 * @tc.name: GetArrayLength 123 * @tc.desc: Check whether the result returned through "GetArrayLength" function is within expectations. 124 * @tc.type: FUNC 125 * @tc.require: 126 */ 127HWTEST_F_L0(ArrayHelperTest, GetArrayLength) 128{ 129 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 130 JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); 131 132 JSHandle<JSTaggedValue> lengthKey = thread->GlobalConstants()->GetHandledLengthString(); 133 JSHandle<JSTaggedValue> lengthValue(thread, JSTaggedValue(10.0)); 134 135 JSArray *handleArr = JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetObject<JSArray>(); 136 JSHandle<JSTaggedValue> arrayHandle(thread, handleArr); 137 EXPECT_EQ(ArrayHelper::GetLength(thread, arrayHandle), 0U); 138 139 JSHandle<JSTaggedValue> objFunc(globalEnv->GetArrayFunction()); 140 JSHandle<JSObject> objectHandle = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc); 141 EXPECT_EQ(ArrayHelper::GetArrayLength(thread, JSHandle<JSTaggedValue>(objectHandle)), 0U); 142 143 JSObject::SetProperty(thread, objectHandle, lengthKey, lengthValue); 144 EXPECT_EQ(ArrayHelper::GetArrayLength(thread, JSHandle<JSTaggedValue>(objectHandle)), 145 JSTaggedNumber(10.0).GetNumber()); 146} 147} // namespace panda::test 148