• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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