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(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(i).GetNumber(), i * 10);
195 }
196 EXPECT_EQ(handleTagArr->Get(offsetStartInsert).GetNumber(),
197 handleTagValInsertElement1.GetTaggedValue().GetNumber());
198 EXPECT_EQ(handleTagArr->Get(offsetStartInsert + 1).GetNumber(),
199 handleTagValInsertElement2.GetTaggedValue().GetNumber());
200 for (int32_t i = offsetStartInsert + countInsert; i < lengthArr - actualDeleteCount + countInsert; i++) {
201 EXPECT_EQ(handleTagArr->Get(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(0), JSTaggedValue((i + 1) * 10));
233 if (i != 4) {
234 EXPECT_EQ(handleTagArr->GetLength(), static_cast<uint32_t>(lengthArr));
235 EXPECT_EQ(handleTagArr->Get(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().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().c_str(), "abc,abc,abc,abc,abc,abc,abc,abc,abc,abc");
302 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
303 }
304
305 /**
306 * @tc.name: Join_NumberElements_DefinedSep
307 * @tc.desc: Create a source Array whose elements are Numbers and an EcmaRuntimeCallInfo, define the first arg of the
308 EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through calling
309 Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
310 * @tc.type: FUNC
311 * @tc.require:
312 */
HWTEST_F_L0(JSStableArrayTest,Join_NumberElements_DefinedSep)313 HWTEST_F_L0(JSStableArrayTest, Join_NumberElements_DefinedSep)
314 {
315 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
316
317 int32_t lengthArr = 10;
318 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
319 for (int i = 0; i < lengthArr; i++) {
320 handleTagArr->Set(thread, i, JSTaggedValue(i));
321 }
322 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
323 JSHandle<JSTaggedValue> tagArrValue = JSHandle<JSTaggedValue>::Cast(handleArr);
324 std::vector<JSTaggedValue> args{JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString("^")).GetTaggedValue()};
325 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6);
326 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
327 JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
328 JSStableArray::Join(tagArrValue, ecmaRuntimeCallInfo));
329 TestHelper::TearDownFrame(thread, prev);
330
331 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
332 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(), "0^1^2^3^4^5^6^7^8^9");
333 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
334 }
335
336 /**
337 * @tc.name: Join_StringElements_DefinedSep
338 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, define the first arg of
339 the EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through
340 calling Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
341 * @tc.type: FUNC
342 * @tc.require:
343 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_DefinedSep)344 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_DefinedSep)
345 {
346 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
347
348 int32_t lengthArr = 10;
349 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
350 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(objFactory->NewFromStdString("a"));
351 for (int i = 0; i < lengthArr; i++) {
352 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
353 }
354 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
355 JSHandle<JSTaggedValue> tagArrValue = JSHandle<JSTaggedValue>::Cast(handleArr);
356 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
357 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
358 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
359 ecmaRuntimeCallInfo->SetCallArg(0,
360 JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString(" <> ")).GetTaggedValue());
361 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
362 JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
363 JSStableArray::Join(tagArrValue, ecmaRuntimeCallInfo));
364 TestHelper::TearDownFrame(thread, prev);
365
366 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
367 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(),
368 "a <> a <> a <> a <> a <> a <> a <> a <> a <> a");
369 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
370 }
371
372 /**
373 * @tc.name: Join_StringElements_ManyTiny
374 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, define the first arg of
375 the EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through
376 calling Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
377 * @tc.type: FUNC
378 * @tc.require:
379 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_ManyTiny)380 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_ManyTiny)
381 {
382 int32_t lengthArr = 256;
383 std::string sep = "";
384 // tiny string join should not use tree string.
385 ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
386 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
387 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(objFactory->NewFromStdString("a"));
388 for (int i = 0; i < lengthArr; i++) {
389 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
390 }
391 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, sep, lengthArr);
392 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
393 // 256 x a
394 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(),
395 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
396 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
397 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
398 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
399 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
400 sep = ",";
401 handleTagValEcmaStrRet = CallJoin(handleTagArr, sep, lengthArr);
402 JSHandle<EcmaString> handleEcmaStrRet2(handleTagValEcmaStrRet);
403 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet2).ToCString().c_str(),
404 "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,"
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 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet2).IsTreeString());
413 }
414
415 /**
416 * @tc.name: Join_StringElements_ManyTiny
417 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, define the first arg of
418 the EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through
419 calling Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
420 * @tc.type: FUNC
421 * @tc.require:
422 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_LargeString)423 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_LargeString)
424 {
425 int32_t lengthArr = 8;
426 std::string sep = "";
427 // large string should use tree string.
428 ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
429 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
430 // 32 x a
431 JSHandle<JSTaggedValue>
432 handleTagValElementEcmaStr(objFactory->NewFromStdString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
433 for (int i = 0; i < lengthArr; i++) {
434 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
435 }
436 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, sep, lengthArr);
437 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
438 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(),
439 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
440 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
441 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
442 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
443 EXPECT_TRUE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
444 }
445
446 /**
447 * @tc.name: Join_StringElements_ManyTiny
448 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, define the first arg of
449 the EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through
450 calling Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
451 * @tc.type: FUNC
452 * @tc.require:
453 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_LargeString2)454 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_LargeString2)
455 {
456 int32_t lengthArr = 4;
457 std::string sep = ",";
458 // large string should use tree string.
459 ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
460 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
461 // 64 x a
462 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(
463 objFactory->NewFromStdString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
464 for (int i = 0; i < lengthArr; i++) {
465 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
466 }
467 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, sep, lengthArr);
468
469 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
470 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(),
471 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
472 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
473 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
474 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
475 EXPECT_TRUE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
476 }
477
478 /**
479 * @tc.name: Join_StringElements_ManyTiny
480 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, define the first arg of
481 the EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through
482 calling Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
483 * @tc.type: FUNC
484 * @tc.require:
485 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_LargeString3)486 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_LargeString3)
487 {
488 int32_t lengthArr = 5;
489 std::string sep = ",";
490 // large string should use tree string.
491 ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
492 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
493 // 64 x a
494 JSHandle<JSTaggedValue> handleTagValElementEcmaStr0(
495 objFactory->NewFromStdString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
496 handleTagArr->Set(thread, 0, handleTagValElementEcmaStr0.GetTaggedValue());
497 JSHandle<JSTaggedValue> handleTagValElementEcmaStr1(
498 objFactory->NewFromStdString("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
499 handleTagArr->Set(thread, 1, handleTagValElementEcmaStr1.GetTaggedValue());
500 JSHandle<JSTaggedValue> handleTagValElementEcmaStr2(
501 objFactory->NewFromStdString("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"));
502 handleTagArr->Set(thread, 2, handleTagValElementEcmaStr2.GetTaggedValue());
503 JSHandle<JSTaggedValue> handleTagValElementEcmaStr3(
504 objFactory->NewFromStdString("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"));
505 handleTagArr->Set(thread, 3, handleTagValElementEcmaStr3.GetTaggedValue());
506 JSHandle<JSTaggedValue> handleTagValElementEcmaStr4(
507 objFactory->NewFromStdString("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"));
508 handleTagArr->Set(thread, 4, handleTagValElementEcmaStr4.GetTaggedValue());
509
510 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, sep, lengthArr);
511
512 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
513 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(),
514 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
515 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,"
516 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc,"
517 "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd,"
518 "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
519 EXPECT_TRUE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
520 }
521
522 /**
523 * @tc.name: Join_StringElements_Stack
524 * @tc.desc: Use stack to store the preprocessed elements of the source Array.
525 * @tc.type: FUNC
526 * @tc.require:
527 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_Stack)528 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_Stack)
529 {
530 int32_t lengthArr = 32;
531 // tiny string join should not use tree string.
532 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
533 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
534 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(objFactory->NewFromStdString("a"));
535 for (int i = 0; i < lengthArr; i++) {
536 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
537 }
538 // sep is Undefined
539 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, lengthArr);
540 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
541 // 32 x a
542 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(),
543 "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");
544 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
545 }
546
547 /**
548 * @tc.name: Join_StringElements_Stack1
549 * @tc.desc: Use stack to store the preprocessed elements of the source Array.
550 * @tc.type: FUNC
551 * @tc.require:
552 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_Stack1)553 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_Stack1)
554 {
555 int32_t lengthArr = 4;
556 // large string should use tree string.
557 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
558 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
559 // 64 x a
560 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(
561 objFactory->NewFromStdString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
562 for (int i = 0; i < lengthArr; i++) {
563 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
564 }
565 // sep is Undefined
566 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, lengthArr);
567 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
568 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(),
569 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
570 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
571 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
572 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
573 EXPECT_TRUE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
574 }
575
576 /**
577 * @tc.name: Join_StringElements_Vector
578 * @tc.desc: Use vector to store the preprocessed elements of the source Array.
579 * @tc.type: FUNC
580 * @tc.require:
581 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_Vector)582 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_Vector)
583 {
584 int32_t lengthArr = 128;
585 // tiny string join should not use tree string.
586 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
587 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
588 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(objFactory->NewFromStdString("a"));
589 for (int i = 0; i < lengthArr; i++) {
590 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
591 }
592 // sep is Undefined
593 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, lengthArr);
594 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
595 // 128 x a
596 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(),
597 "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,"
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 EXPECT_FALSE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
602 }
603
604 /**
605 * @tc.name: Join_StringElements_Vector1
606 * @tc.desc: Use vector to store the preprocessed elements of the source Array.
607 * @tc.type: FUNC
608 * @tc.require:
609 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_Vector1)610 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_Vector1)
611 {
612 int32_t lengthArr = 65;
613 std::string sep = "";
614 // large string should use tree string.
615 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
616 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
617 // 40 x a
618 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(
619 objFactory->NewFromStdString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
620 for (int i = 0; i < lengthArr; i++) {
621 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
622 }
623 JSHandle<JSTaggedValue> handleTagValEcmaStrRet = CallJoin(handleTagArr, sep, lengthArr);
624 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
625 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(),
626 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
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 EXPECT_TRUE(EcmaStringAccessor(handleEcmaStrRet).IsTreeString());
692 }
693
694 /**
695 * @tc.name: At
696 * @tc.desc: Create a source Array whose elements are Numbers and an EcmaRuntimeCallInfo, define the first arg of the
697 EcmaRuntimeCallInfo an number as the index, check whether the element returned through calling
698 At function with the source Array and the EcmaRuntimeCallInfo is within expectations.
699 * @tc.type: FUNC
700 * @tc.require:
701 */
HWTEST_F_L0(JSStableArrayTest,At_NUMBER_INDEX)702 HWTEST_F_L0(JSStableArrayTest, At_NUMBER_INDEX)
703 {
704 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
705
706 int32_t lengthArr = 10;
707 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
708 for (int i = 0; i < lengthArr; i++) {
709 handleTagArr->Set(thread, i, JSTaggedValue(i));
710 }
711 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
712 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
713 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
714 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
715 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(0));
716 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
717
718 JSTaggedValue thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo);
719 TestHelper::TearDownFrame(thread, prev);
720
721 EXPECT_EQ(thisTagValue.GetNumber(), 0);
722
723 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
724 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
725 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
726 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(9));
727 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
728
729 thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo);
730 TestHelper::TearDownFrame(thread, prev);
731
732 EXPECT_EQ(thisTagValue.GetNumber(), 9);
733
734 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
735 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
736 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
737 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(-1));
738 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
739
740 thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo);
741 TestHelper::TearDownFrame(thread, prev);
742
743 EXPECT_EQ(thisTagValue.GetNumber(), 9);
744
745 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
746 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
747 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
748 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(10));
749 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
750
751 thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo);
752 TestHelper::TearDownFrame(thread, prev);
753
754 EXPECT_EQ(thisTagValue, JSTaggedValue::Undefined());
755 }
756
757 /**
758 * @tc.name: With
759 * @tc.desc: Create a source Array whose elements are Numbers, define the first arg a thread,
760 * define the second arg as the source Array, define the third arg an number as the length of source Array
761 * define the forth arg an number as the index, define the fifth args an number as the value
762 * check whether the value returned through calling With function with the source Array
763 * and the args is within expectations.
764 * @tc.type: FUNC
765 * @tc.require:
766 */
HWTEST_F_L0(JSStableArrayTest,With)767 HWTEST_F_L0(JSStableArrayTest, With)
768 {
769 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
770 int32_t lengthArr = ARRAY_LENGTH_4;
771 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
772 for (int i = 0; i < lengthArr; i++) {
773 handleTagArr->Set(thread, i, JSTaggedValue(i));
774 }
775 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
776
777 int64_t arrayLength = ARRAY_LENGTH_4;
778 int64_t index = static_cast<int64_t>(StableArrayIndex::STABLE_ARRAY_INDEX_2);
779 JSTaggedValue resultArr = JSStableArray::With(thread, handleArr,
780 arrayLength, index,
781 JSHandle<JSTaggedValue>(thread, JSTaggedValue(INT_VALUE_666)));
782 JSHandle<JSTaggedValue> destTaggedValue(thread, resultArr);
783 JSHandle<JSArray> destArr(destTaggedValue);
784 JSHandle<TaggedArray> destTaggedArr(thread, TaggedArray::Cast(destArr->GetElements().GetTaggedObject()));
785 for (uint32_t i = 0; i < ARRAY_LENGTH_4; ++i) {
786 JSHandle<JSObject> arrObjHandle(handleArr);
787 EXPECT_EQ(ElementAccessor::Get(thread, arrObjHandle, i).GetNumber(), i);
788 }
789 for (uint32_t i = 0; i < ARRAY_LENGTH_4; ++i) {
790 JSHandle<JSObject> arrObjHandle(destArr);
791 if (i == 2) {
792 EXPECT_EQ(ElementAccessor::Get(thread, arrObjHandle, i).GetNumber(), INT_VALUE_666);
793 } else {
794 EXPECT_EQ(ElementAccessor::Get(thread, arrObjHandle, i).GetNumber(), i);
795 }
796 }
797 }
798
799 /**
800 * @tc.name: ToReversed
801 * @tc.desc: Create a source Array whose elements are Numbers and an EcmaRuntimeCallInfo, check whether the
802 value returned through calling ToReversed function with the source Array is within expectations.
803 * @tc.type: FUNC
804 * @tc.require:
805 */
HWTEST_F_L0(JSStableArrayTest,ToReversed)806 HWTEST_F_L0(JSStableArrayTest, ToReversed)
807 {
808 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
809 int32_t lengthArr = ARRAY_LENGTH_4;
810 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
811 for (int i = 0; i < lengthArr; i++) {
812 handleTagArr->Set(thread, i, JSTaggedValue(i));
813 }
814 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
815 JSHandle<JSObject> handleArrObj(handleArr);
816 JSTaggedValue resultArr =
817 JSStableArray::ToReversed(thread, handleArr, ARRAY_LENGTH_4);
818 JSHandle<JSObject> dstArrObj(thread, resultArr);
819
820 EXPECT_EQ(ElementAccessor::Get(thread, handleArrObj,
821 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_0)).GetNumber(), INT_VALUE_0);
822 EXPECT_EQ(ElementAccessor::Get(thread, handleArrObj,
823 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_1)).GetNumber(), INT_VALUE_1);
824 EXPECT_EQ(ElementAccessor::Get(thread, handleArrObj,
825 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_2)).GetNumber(), INT_VALUE_2);
826 EXPECT_EQ(ElementAccessor::Get(thread, handleArrObj,
827 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_3)).GetNumber(), INT_VALUE_3);
828
829 EXPECT_EQ(ElementAccessor::Get(thread, dstArrObj,
830 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_0)).GetNumber(), INT_VALUE_3);
831 EXPECT_EQ(ElementAccessor::Get(thread, dstArrObj,
832 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_1)).GetNumber(), INT_VALUE_2);
833 EXPECT_EQ(ElementAccessor::Get(thread, dstArrObj,
834 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_2)).GetNumber(), INT_VALUE_1);
835 EXPECT_EQ(ElementAccessor::Get(thread, dstArrObj,
836 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_3)).GetNumber(), INT_VALUE_0);
837 }
838 } // namespace panda::test
839