• 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(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