1 /*
2 * Copyright (c) 2022 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/element_accessor.h"
17 #include "ecmascript/element_accessor-inl.h"
18 #include "ecmascript/js_stable_array.h"
19 #include "ecmascript/tests/test_helper.h"
20
21 using namespace panda;
22 using namespace panda::ecmascript;
23 constexpr uint32_t ARRAY_LENGTH_4 = 4;
24 constexpr int32_t INT_VALUE_0 = 0;
25 constexpr int32_t INT_VALUE_1 = 1;
26 constexpr int32_t INT_VALUE_2 = 2;
27 constexpr int32_t INT_VALUE_3 = 3;
28 constexpr int32_t INT_VALUE_666 = 666;
29
30 enum class StableArrayIndex {
31 STABLE_ARRAY_INDEX_0,
32 STABLE_ARRAY_INDEX_1,
33 STABLE_ARRAY_INDEX_2,
34 STABLE_ARRAY_INDEX_3
35 };
36
37 namespace panda::test {
38 class JSStableArrayTest : public BaseTestWithScope<false> {
39 public:
CallJoin(JSHandle<TaggedArray> handleTagArr,JSTaggedValue sepValue) const40 JSHandle<JSTaggedValue> CallJoin(JSHandle<TaggedArray> handleTagArr, JSTaggedValue sepValue) const
41 {
42 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
43 JSHandle<JSTaggedValue> tagArrValue = JSHandle<JSTaggedValue>::Cast(handleArr);
44 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
45 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
46 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
47 ecmaRuntimeCallInfo->SetCallArg(0, sepValue);
48 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
49 JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread, JSStableArray::Join(tagArrValue, ecmaRuntimeCallInfo));
50 TestHelper::TearDownFrame(thread, prev);
51 return handleTagValEcmaStrRet;
52 }
53
54 // tests for sep is Undefined
CallJoin(JSHandle<TaggedArray> handleTagArr,int64_t lengthArr) const55 JSHandle<JSTaggedValue> CallJoin(JSHandle<TaggedArray> handleTagArr, [[maybe_unused]] int64_t lengthArr) const
56 {
57 JSTaggedValue sepValue = JSTaggedValue::Undefined();
58 return CallJoin(handleTagArr, sepValue);
59 }
60
CallJoin(JSHandle<TaggedArray> handleTagArr,std::string & sep,int64_t lengthArr) const61 JSHandle<JSTaggedValue> CallJoin(JSHandle<TaggedArray> handleTagArr, std::string& sep,
62 [[maybe_unused]] int64_t lengthArr) const
63 {
64 ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
65 JSTaggedValue sepValue = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString(sep)).GetTaggedValue();
66 return CallJoin(handleTagArr, sepValue);
67 }
68 };
69
70 /**
71 * @tc.name: Push
72 * @tc.desc: Change a JSArray through calling Push function with the JSArray and a EcmaRuntimeCallInfo, check whether
73 * the TaggedArray of the JSArray is within expectations.
74 * @tc.type: FUNC
75 * @tc.require:
76 */
HWTEST_F_L0(JSStableArrayTest,Push)77 HWTEST_F_L0(JSStableArrayTest, Push)
78 {
79 int32_t lengthArr = 99;
80 int32_t numElementsPush = 9;
81 JSHandle<JSTaggedValue> handleTagValArr = JSArray::ArrayCreate(thread, JSTaggedNumber(lengthArr));
82 JSHandle<JSArray> handleArr(handleTagValArr);
83
84 auto ecmaRuntimeCallInfo =
85 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4 + 2 * numElementsPush);
86 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
87 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
88 for (int32_t i = 0; i < numElementsPush; i++) {
89 ecmaRuntimeCallInfo->SetCallArg(i, JSTaggedValue(i));
90 }
91 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
92 EXPECT_EQ(JSStableArray::Push(handleArr, ecmaRuntimeCallInfo),
93 JSTaggedValue(lengthArr + numElementsPush));
94 TestHelper::TearDownFrame(thread, prev);
95
96 JSHandle<JSObject> arrObjHandle(handleArr);
97 EXPECT_EQ(handleArr->GetArrayLength(), static_cast<size_t>(lengthArr + numElementsPush));
98 for (int32_t i = lengthArr; i < lengthArr + numElementsPush; i++) {
99 EXPECT_EQ(ElementAccessor::Get(thread, arrObjHandle, i).GetNumber(), i - lengthArr);
100 }
101 }
102
103 /**
104 * @tc.name: Pop
105 * @tc.desc: Change a JSArray through calling Pop function with the JSArray and a EcmaRuntimeCallInfo, check whether
106 * the JSArray and the TaggedArray of the JSArray are within expectations.
107 * @tc.type: FUNC
108 * @tc.require:
109 */
HWTEST_F_L0(JSStableArrayTest,Pop)110 HWTEST_F_L0(JSStableArrayTest, Pop)
111 {
112 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
113
114 int32_t lengthArr = 49;
115 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
116 for (int i = 0; i < lengthArr; i++) {
117 handleTagArr->Set(thread, i, JSTaggedValue(i));
118 }
119 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
120
121 for (int32_t i = 1; i < 6; i++) {
122 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
123 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
124 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
125 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
126 EXPECT_EQ(JSStableArray::Pop(handleArr, ecmaRuntimeCallInfo), JSTaggedValue(lengthArr - i));
127 TestHelper::TearDownFrame(thread, prev);
128
129 EXPECT_EQ(handleArr->GetArrayLength(), static_cast<uint32_t>(lengthArr - i));
130 if (i != 5) {
131 EXPECT_EQ(handleTagArr->GetLength(), static_cast<uint32_t>(lengthArr));
132 EXPECT_EQ(handleTagArr->Get(thread, lengthArr - i), JSTaggedValue::Hole());
133 } else {
134 EXPECT_EQ(handleTagArr->GetLength(), static_cast<uint32_t>(lengthArr - i));
135 }
136 }
137 }
138
139 /**
140 * @tc.name: Splice
141 * @tc.desc: Create a source TaggedArray, set value for the elements of the source TaggedArray, create an source Array
142 * through calling CreateArrayFromList function with the source TaggedArray, create a deleted Array through
143 * calling Splice function with the source Array, an EcmaRuntimeCallInfo that set Args from 2 as the
144 * delete-elements, the offsetStartInsert, the countInsert and the actualDeleteCount. Check whether the
145 * deleted Array and the source Array after change are within expectations.
146 * @tc.type: FUNC
147 * @tc.require:
148 */
HWTEST_F_L0(JSStableArrayTest,Splice)149 HWTEST_F_L0(JSStableArrayTest, Splice)
150 {
151 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
152
153 int32_t lengthArr = 49;
154
155 JSHandle<JSTaggedValue> handleTagValInsertElement1(thread, JSTaggedValue(4000));
156 JSHandle<JSTaggedValue> handleTagValInsertElement2(thread, JSTaggedValue(4100));
157 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
158 for (int i = 0; i < lengthArr; i++) {
159 handleTagArr->Set(thread, i, JSTaggedValue(i * 10));
160 }
161 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
162 double offsetStartInsert = 40;
163 double actualDeleteCount = 3;
164 double countInsert = 2;
165
166 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(),
167 4 + (2 + countInsert) * 2);
168 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
169 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
170 ecmaRuntimeCallInfo->SetCallArg(2, handleTagValInsertElement1.GetTaggedValue());
171 ecmaRuntimeCallInfo->SetCallArg(3, handleTagValInsertElement2.GetTaggedValue());
172
173 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
174 JSHandle<JSObject> thisObjHandle(handleArr);
175 JSTaggedValue newArray = JSArray::ArraySpeciesCreate(thread, thisObjHandle,
176 JSTaggedNumber(static_cast<double>(actualDeleteCount)));
177 JSHandle<JSObject> newArrayHandle(thread, newArray);
178 uint32_t len = JSHandle<JSArray>::Cast(thisObjHandle)->GetArrayLength();
179 JSHandle<JSTaggedValue> handleTagValArrCombinedOfDeletedElements(thread,
180 JSStableArray::Splice(JSHandle<JSArray>::Cast(thisObjHandle), ecmaRuntimeCallInfo, offsetStartInsert,
181 countInsert, actualDeleteCount, newArrayHandle, len));
182 TestHelper::TearDownFrame(thread, prev);
183 JSHandle<JSArray> handleArrCombinedOfDeletedElements(handleTagValArrCombinedOfDeletedElements);
184 EXPECT_EQ(handleArrCombinedOfDeletedElements->GetArrayLength(), actualDeleteCount);
185 JSHandle<JSObject> handleObjArrCombinedOfDeletedElements(handleTagValArrCombinedOfDeletedElements);
186 for (int32_t i = 0; i < actualDeleteCount; i++) {
187 EXPECT_EQ(ElementAccessor::Get(thread, handleObjArrCombinedOfDeletedElements, i).GetNumber(),
188 (offsetStartInsert + i) * 10);
189 }
190
191 // Check the JSArray(in-out-parameter) changed through calling the Splice function.
192 EXPECT_EQ(handleArr->GetArrayLength(), lengthArr - actualDeleteCount + countInsert);
193 for (int32_t i = 0; i < offsetStartInsert; i++) {
194 EXPECT_EQ(handleTagArr->Get(thread, i).GetNumber(), i * 10);
195 }
196 EXPECT_EQ(handleTagArr->Get(thread, offsetStartInsert).GetNumber(),
197 handleTagValInsertElement1.GetTaggedValue().GetNumber());
198 EXPECT_EQ(handleTagArr->Get(thread, offsetStartInsert + 1).GetNumber(),
199 handleTagValInsertElement2.GetTaggedValue().GetNumber());
200 for (int32_t i = offsetStartInsert + countInsert; i < lengthArr - actualDeleteCount + countInsert; i++) {
201 EXPECT_EQ(handleTagArr->Get(thread, i).GetNumber(), (i + actualDeleteCount - countInsert) * 10);
202 }
203 }
204
205 /**
206 * @tc.name: Shift
207 * @tc.desc: Create a source Array, set value for the elements of the source Array, call the Shift function with the
208 * source Array 5 times, check whether the returned JSTaggedValue and the changed source Array are within
209 * expectations after each call to the Shift function.
210 * @tc.type: FUNC
211 * @tc.require:
212 */
HWTEST_F_L0(JSStableArrayTest,Shift)213 HWTEST_F_L0(JSStableArrayTest, Shift)
214 {
215 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
216
217 int32_t lengthArr = 49;
218 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
219 for (int i = 0; i < lengthArr; i++) {
220 handleTagArr->Set(thread, i, JSTaggedValue(i * 10));
221 }
222 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
223
224 for (int32_t i = 0; i < 5; i++) {
225 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
226 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
227 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
228 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
229 EXPECT_EQ(JSStableArray::Shift(handleArr, ecmaRuntimeCallInfo), JSTaggedValue(i * 10));
230 TestHelper::TearDownFrame(thread, prev);
231 EXPECT_EQ(handleArr->GetArrayLength(), static_cast<uint32_t>(lengthArr - (i + 1)));
232 EXPECT_EQ(handleTagArr->Get(thread, 0), JSTaggedValue((i + 1) * 10));
233 if (i != 4) {
234 EXPECT_EQ(handleTagArr->GetLength(), static_cast<uint32_t>(lengthArr));
235 EXPECT_EQ(handleTagArr->Get(thread, lengthArr - (i + 1)), JSTaggedValue::Hole());
236 continue;
237 }
238 EXPECT_EQ(handleTagArr->GetLength(), static_cast<uint32_t>(lengthArr - (i + 1)));
239 }
240 }
241
242 /**
243 * @tc.name: Join_NumberElements_UndefinedSep
244 * @tc.desc: Create a source Array whose elements are Numbers and an EcmaRuntimeCallInfo, check whether the EcmaString
245 * returned through calling Join function with the source Array and the EcmaRuntimeCallInfo is within
246 * expectations.
247 * @tc.type: FUNC
248 * @tc.require:
249 */
HWTEST_F_L0(JSStableArrayTest,Join_NumberElements_UndefinedSep)250 HWTEST_F_L0(JSStableArrayTest, Join_NumberElements_UndefinedSep)
251 {
252 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
253
254 int32_t lengthArr = 10;
255 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
256 for (int i = 0; i < lengthArr; i++) {
257 handleTagArr->Set(thread, i, JSTaggedValue(i));
258 }
259 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
260 std::vector<JSTaggedValue> args{};
261 JSHandle<JSTaggedValue> tagArrValue = JSHandle<JSTaggedValue>::Cast(handleArr);
262 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 4);
263 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
264 JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
265 JSStableArray::Join(tagArrValue, ecmaRuntimeCallInfo));
266 TestHelper::TearDownFrame(thread, prev);
267
268 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
269 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString(thread).c_str(), "0,1,2,3,4,5,6,7,8,9");
270 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
271 }
272
273 /**
274 * @tc.name: Join_StringElements_UndefinedSep
275 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, check whether the
276 * EcmaString returned through calling Join function with the source Array and the EcmaRuntimeCallInfo is
277 * within expectations.
278 * @tc.type: FUNC
279 * @tc.require:
280 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_UndefinedSep)281 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_UndefinedSep)
282 {
283 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
284
285 int32_t lengthArr = 10;
286 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
287 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(objFactory->NewFromStdString("abc"));
288 for (int i = 0; i < lengthArr; i++) {
289 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
290 }
291 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
292 std::vector<JSTaggedValue> args{};
293 JSHandle<JSTaggedValue> tagArrValue = JSHandle<JSTaggedValue>::Cast(handleArr);
294 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 4);
295 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
296 JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
297 JSStableArray::Join(tagArrValue, ecmaRuntimeCallInfo));
298 TestHelper::TearDownFrame(thread, prev);
299
300 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
301 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString(thread).c_str(),
302 "abc,abc,abc,abc,abc,abc,abc,abc,abc,abc");
303 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
304 }
305
306 /**
307 * @tc.name: Join_NumberElements_DefinedSep
308 * @tc.desc: Create a source Array whose elements are Numbers and an EcmaRuntimeCallInfo, define the first arg of the
309 EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through calling
310 Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
311 * @tc.type: FUNC
312 * @tc.require:
313 */
HWTEST_F_L0(JSStableArrayTest,Join_NumberElements_DefinedSep)314 HWTEST_F_L0(JSStableArrayTest, Join_NumberElements_DefinedSep)
315 {
316 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
317
318 int32_t lengthArr = 10;
319 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
320 for (int i = 0; i < lengthArr; i++) {
321 handleTagArr->Set(thread, i, JSTaggedValue(i));
322 }
323 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
324 JSHandle<JSTaggedValue> tagArrValue = JSHandle<JSTaggedValue>::Cast(handleArr);
325 std::vector<JSTaggedValue> args{JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString("^")).GetTaggedValue()};
326 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6);
327 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
328 JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
329 JSStableArray::Join(tagArrValue, ecmaRuntimeCallInfo));
330 TestHelper::TearDownFrame(thread, prev);
331
332 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
333 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString(thread).c_str(), "0^1^2^3^4^5^6^7^8^9");
334 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
335 }
336
337 /**
338 * @tc.name: Join_StringElements_DefinedSep
339 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, define the first arg of
340 the EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through
341 calling Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
342 * @tc.type: FUNC
343 * @tc.require:
344 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_DefinedSep)345 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_DefinedSep)
346 {
347 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
348
349 int32_t lengthArr = 10;
350 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
351 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(objFactory->NewFromStdString("a"));
352 for (int i = 0; i < lengthArr; i++) {
353 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
354 }
355 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
356 JSHandle<JSTaggedValue> tagArrValue = JSHandle<JSTaggedValue>::Cast(handleArr);
357 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
358 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
359 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
360 ecmaRuntimeCallInfo->SetCallArg(0,
361 JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString(" <> ")).GetTaggedValue());
362 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
363 JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
364 JSStableArray::Join(tagArrValue, ecmaRuntimeCallInfo));
365 TestHelper::TearDownFrame(thread, prev);
366
367 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
368 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString(thread).c_str(),
369 "a <> a <> a <> a <> a <> a <> a <> a <> a <> a");
370 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
371 }
372
373 /**
374 * @tc.name: Join_StringElements_ManyTiny
375 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, define the first arg of
376 the EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through
377 calling Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
378 * @tc.type: FUNC
379 * @tc.require:
380 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_ManyTiny)381 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_ManyTiny)
382 {
383 int32_t lengthArr = 256;
384 std::string sep = "";
385 // tiny string join should not use tree string.
386 ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
387 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
388 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(objFactory->NewFromStdString("a"));
389 for (int i = 0; i < lengthArr; i++) {
390 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
391 }
392 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, sep, lengthArr);
393 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
394 // 256 x a
395 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString(thread).c_str(),
396 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
397 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
398 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
399 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
400 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
401 sep = ",";
402 handleTagValEcmaStrRet = CallJoin(handleTagArr, sep, lengthArr);
403 JSHandle<EcmaString> handleEcmaStrRet2(handleTagValEcmaStrRet);
404 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet2).ToCString(thread).c_str(),
405 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,"
406 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,"
407 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,"
408 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,"
409 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,"
410 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,"
411 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,"
412 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a");
413 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet2).IsTreeString());
414 }
415
416 /**
417 * @tc.name: Join_StringElements_ManyTiny
418 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, define the first arg of
419 the EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through
420 calling Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
421 * @tc.type: FUNC
422 * @tc.require:
423 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_LargeString)424 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_LargeString)
425 {
426 int32_t lengthArr = 8;
427 std::string sep = "";
428 // large string should use tree string.
429 ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
430 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
431 // 32 x a
432 JSHandle<JSTaggedValue>
433 handleTagValElementEcmaStr(objFactory->NewFromStdString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
434 for (int i = 0; i < lengthArr; i++) {
435 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
436 }
437 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, sep, lengthArr);
438 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
439 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString(thread).c_str(),
440 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
441 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
442 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
443 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
444 EXPECT_TRUE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
445 }
446
447 /**
448 * @tc.name: Join_StringElements_ManyTiny
449 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, define the first arg of
450 the EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through
451 calling Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
452 * @tc.type: FUNC
453 * @tc.require:
454 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_LargeString2)455 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_LargeString2)
456 {
457 int32_t lengthArr = 4;
458 std::string sep = ",";
459 // large string should use tree string.
460 ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
461 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
462 // 64 x a
463 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(
464 objFactory->NewFromStdString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
465 for (int i = 0; i < lengthArr; i++) {
466 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
467 }
468 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, sep, lengthArr);
469
470 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
471 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString(thread).c_str(),
472 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
473 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
474 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
475 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
476 EXPECT_TRUE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
477 }
478
479 /**
480 * @tc.name: Join_StringElements_ManyTiny
481 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, define the first arg of
482 the EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through
483 calling Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
484 * @tc.type: FUNC
485 * @tc.require:
486 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_LargeString3)487 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_LargeString3)
488 {
489 int32_t lengthArr = 5;
490 std::string sep = ",";
491 // large string should use tree string.
492 ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
493 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
494 // 64 x a
495 JSHandle<JSTaggedValue> handleTagValElementEcmaStr0(
496 objFactory->NewFromStdString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
497 handleTagArr->Set(thread, 0, handleTagValElementEcmaStr0.GetTaggedValue());
498 JSHandle<JSTaggedValue> handleTagValElementEcmaStr1(
499 objFactory->NewFromStdString("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
500 handleTagArr->Set(thread, 1, handleTagValElementEcmaStr1.GetTaggedValue());
501 JSHandle<JSTaggedValue> handleTagValElementEcmaStr2(
502 objFactory->NewFromStdString("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"));
503 handleTagArr->Set(thread, 2, handleTagValElementEcmaStr2.GetTaggedValue());
504 JSHandle<JSTaggedValue> handleTagValElementEcmaStr3(
505 objFactory->NewFromStdString("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"));
506 handleTagArr->Set(thread, 3, handleTagValElementEcmaStr3.GetTaggedValue());
507 JSHandle<JSTaggedValue> handleTagValElementEcmaStr4(
508 objFactory->NewFromStdString("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"));
509 handleTagArr->Set(thread, 4, handleTagValElementEcmaStr4.GetTaggedValue());
510
511 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, sep, lengthArr);
512
513 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
514 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString(thread).c_str(),
515 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
516 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,"
517 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc,"
518 "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd,"
519 "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
520 EXPECT_TRUE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
521 }
522
523 /**
524 * @tc.name: Join_StringElements_Stack
525 * @tc.desc: Use stack to store the preprocessed elements of the source Array.
526 * @tc.type: FUNC
527 * @tc.require:
528 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_Stack)529 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_Stack)
530 {
531 int32_t lengthArr = 32;
532 // tiny string join should not use tree string.
533 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
534 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
535 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(objFactory->NewFromStdString("a"));
536 for (int i = 0; i < lengthArr; i++) {
537 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
538 }
539 // sep is Undefined
540 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, lengthArr);
541 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
542 // 32 x a
543 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString(thread).c_str(),
544 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a");
545 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
546 }
547
548 /**
549 * @tc.name: Join_StringElements_Stack1
550 * @tc.desc: Use stack to store the preprocessed elements of the source Array.
551 * @tc.type: FUNC
552 * @tc.require:
553 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_Stack1)554 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_Stack1)
555 {
556 int32_t lengthArr = 4;
557 // large string should use tree string.
558 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
559 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
560 // 64 x a
561 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(
562 objFactory->NewFromStdString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
563 for (int i = 0; i < lengthArr; i++) {
564 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
565 }
566 // sep is Undefined
567 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, lengthArr);
568 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
569 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString(thread).c_str(),
570 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
571 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
572 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
573 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
574 EXPECT_TRUE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
575 }
576
577 /**
578 * @tc.name: Join_StringElements_Vector
579 * @tc.desc: Use vector to store the preprocessed elements of the source Array.
580 * @tc.type: FUNC
581 * @tc.require:
582 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_Vector)583 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_Vector)
584 {
585 int32_t lengthArr = 128;
586 // tiny string join should not use tree string.
587 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
588 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
589 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(objFactory->NewFromStdString("a"));
590 for (int i = 0; i < lengthArr; i++) {
591 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
592 }
593 // sep is Undefined
594 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, lengthArr);
595 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
596 // 128 x a
597 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString(thread).c_str(),
598 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,"
599 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,"
600 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,"
601 "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a");
602 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
603 }
604
605 /**
606 * @tc.name: Join_StringElements_Vector1
607 * @tc.desc: Use vector to store the preprocessed elements of the source Array.
608 * @tc.type: FUNC
609 * @tc.require:
610 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_Vector1)611 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_Vector1)
612 {
613 int32_t lengthArr = 65;
614 std::string sep = "";
615 // large string should use tree string.
616 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
617 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
618 // 40 x a
619 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(
620 objFactory->NewFromStdString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
621 for (int i = 0; i < lengthArr; i++) {
622 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
623 }
624 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, sep, lengthArr);
625 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
626 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString(thread).c_str(),
627 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
628 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
629 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
630 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
631 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
632 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
633 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
634 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
635 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
636 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
637 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
638 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
639 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
640 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
641 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
642 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
643 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
644 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
645 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
646 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
647 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
648 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
649 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
650 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
651 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
652 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
653 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
654 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
655 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
656 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
657 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
658 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
659 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
660 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
661 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
662 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
663 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
664 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
665 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
666 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
667 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
668 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
669 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
670 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
671 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
672 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
673 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
674 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
675 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
676 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
677 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
678 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
679 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
680 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
681 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
682 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
683 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
684 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
685 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
686 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
687 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
688 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
689 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
690 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
691 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
692 EXPECT_TRUE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
693 }
694
695 /**
696 * @tc.name: At
697 * @tc.desc: Create a source Array whose elements are Numbers and an EcmaRuntimeCallInfo, define the first arg of the
698 EcmaRuntimeCallInfo an number as the index, check whether the element returned through calling
699 At function with the source Array and the EcmaRuntimeCallInfo is within expectations.
700 * @tc.type: FUNC
701 * @tc.require:
702 */
HWTEST_F_L0(JSStableArrayTest,At_NUMBER_INDEX)703 HWTEST_F_L0(JSStableArrayTest, At_NUMBER_INDEX)
704 {
705 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
706
707 int32_t lengthArr = 10;
708 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
709 for (int i = 0; i < lengthArr; i++) {
710 handleTagArr->Set(thread, i, JSTaggedValue(i));
711 }
712 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
713 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
714 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
715 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
716 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(0));
717 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
718
719 JSTaggedValue thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo);
720 TestHelper::TearDownFrame(thread, prev);
721
722 EXPECT_EQ(thisTagValue.GetNumber(), 0);
723
724 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
725 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
726 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
727 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(9));
728 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
729
730 thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo);
731 TestHelper::TearDownFrame(thread, prev);
732
733 EXPECT_EQ(thisTagValue.GetNumber(), 9);
734
735 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
736 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
737 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
738 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(-1));
739 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
740
741 thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo);
742 TestHelper::TearDownFrame(thread, prev);
743
744 EXPECT_EQ(thisTagValue.GetNumber(), 9);
745
746 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
747 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
748 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
749 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(10));
750 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
751
752 thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo);
753 TestHelper::TearDownFrame(thread, prev);
754
755 EXPECT_EQ(thisTagValue, JSTaggedValue::Undefined());
756 }
757
758 /**
759 * @tc.name: With
760 * @tc.desc: Create a source Array whose elements are Numbers, define the first arg a thread,
761 * define the second arg as the source Array, define the third arg an number as the length of source Array
762 * define the forth arg an number as the index, define the fifth args an number as the value
763 * check whether the value returned through calling With function with the source Array
764 * and the args is within expectations.
765 * @tc.type: FUNC
766 * @tc.require:
767 */
HWTEST_F_L0(JSStableArrayTest,With)768 HWTEST_F_L0(JSStableArrayTest, With)
769 {
770 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
771 int32_t lengthArr = ARRAY_LENGTH_4;
772 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
773 for (int i = 0; i < lengthArr; i++) {
774 handleTagArr->Set(thread, i, JSTaggedValue(i));
775 }
776 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
777
778 int64_t arrayLength = ARRAY_LENGTH_4;
779 int64_t index = static_cast<int64_t>(StableArrayIndex::STABLE_ARRAY_INDEX_2);
780 JSTaggedValue resultArr = JSStableArray::With(thread, handleArr,
781 arrayLength, index,
782 JSHandle<JSTaggedValue>(thread, JSTaggedValue(INT_VALUE_666)));
783 JSHandle<JSTaggedValue> destTaggedValue(thread, resultArr);
784 JSHandle<JSArray> destArr(destTaggedValue);
785 JSHandle<TaggedArray> destTaggedArr(thread, TaggedArray::Cast(destArr->GetElements(thread).GetTaggedObject()));
786 for (uint32_t i = 0; i < ARRAY_LENGTH_4; ++i) {
787 JSHandle<JSObject> arrObjHandle(handleArr);
788 EXPECT_EQ(ElementAccessor::Get(thread, arrObjHandle, i).GetNumber(), i);
789 }
790 for (uint32_t i = 0; i < ARRAY_LENGTH_4; ++i) {
791 JSHandle<JSObject> arrObjHandle(destArr);
792 if (i == 2) {
793 EXPECT_EQ(ElementAccessor::Get(thread, arrObjHandle, i).GetNumber(), INT_VALUE_666);
794 } else {
795 EXPECT_EQ(ElementAccessor::Get(thread, arrObjHandle, i).GetNumber(), i);
796 }
797 }
798 }
799
800 /**
801 * @tc.name: ToReversed
802 * @tc.desc: Create a source Array whose elements are Numbers and an EcmaRuntimeCallInfo, check whether the
803 value returned through calling ToReversed function with the source Array is within expectations.
804 * @tc.type: FUNC
805 * @tc.require:
806 */
HWTEST_F_L0(JSStableArrayTest,ToReversed)807 HWTEST_F_L0(JSStableArrayTest, ToReversed)
808 {
809 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
810 int32_t lengthArr = ARRAY_LENGTH_4;
811 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
812 for (int i = 0; i < lengthArr; i++) {
813 handleTagArr->Set(thread, i, JSTaggedValue(i));
814 }
815 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
816 JSHandle<JSObject> handleArrObj(handleArr);
817 JSTaggedValue resultArr =
818 JSStableArray::ToReversed(thread, handleArr, ARRAY_LENGTH_4);
819 JSHandle<JSObject> dstArrObj(thread, resultArr);
820
821 EXPECT_EQ(ElementAccessor::Get(thread, handleArrObj,
822 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_0)).GetNumber(), INT_VALUE_0);
823 EXPECT_EQ(ElementAccessor::Get(thread, handleArrObj,
824 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_1)).GetNumber(), INT_VALUE_1);
825 EXPECT_EQ(ElementAccessor::Get(thread, handleArrObj,
826 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_2)).GetNumber(), INT_VALUE_2);
827 EXPECT_EQ(ElementAccessor::Get(thread, handleArrObj,
828 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_3)).GetNumber(), INT_VALUE_3);
829
830 EXPECT_EQ(ElementAccessor::Get(thread, dstArrObj,
831 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_0)).GetNumber(), INT_VALUE_3);
832 EXPECT_EQ(ElementAccessor::Get(thread, dstArrObj,
833 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_1)).GetNumber(), INT_VALUE_2);
834 EXPECT_EQ(ElementAccessor::Get(thread, dstArrObj,
835 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_2)).GetNumber(), INT_VALUE_1);
836 EXPECT_EQ(ElementAccessor::Get(thread, dstArrObj,
837 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_3)).GetNumber(), INT_VALUE_0);
838 }
839 } // namespace panda::test
840