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