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/js_stable_array.h"
17 #include "ecmascript/tests/test_helper.h"
18
19 using namespace panda;
20 using namespace panda::ecmascript;
21 constexpr uint32_t ARRAY_LENGTH_4 = 4;
22 constexpr int32_t INT_VALUE_0 = 0;
23 constexpr int32_t INT_VALUE_1 = 1;
24 constexpr int32_t INT_VALUE_2 = 2;
25 constexpr int32_t INT_VALUE_3 = 3;
26 constexpr int32_t INT_VALUE_666 = 666;
27
28 enum class StableArrayIndex {
29 STABLE_ARRAY_INDEX_0,
30 STABLE_ARRAY_INDEX_1,
31 STABLE_ARRAY_INDEX_2,
32 STABLE_ARRAY_INDEX_3
33 };
34
35 namespace panda::test {
36 class JSStableArrayTest : public testing::Test {
37 public:
SetUpTestCase()38 static void SetUpTestCase()
39 {
40 GTEST_LOG_(INFO) << "SetUpTestCase";
41 }
42
TearDownTestCase()43 static void TearDownTestCase()
44 {
45 GTEST_LOG_(INFO) << "TearDownCase";
46 }
47
SetUp()48 void SetUp() override
49 {
50 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
51 }
52
TearDown()53 void TearDown() override
54 {
55 TestHelper::DestroyEcmaVMWithScope(instance, scope);
56 }
57
58 EcmaVM *instance {nullptr};
59 EcmaHandleScope *scope {nullptr};
60 JSThread *thread {nullptr};
61 };
62
63 /**
64 * @tc.name: Push
65 * @tc.desc: Change a JSArray through calling Push function with the JSArray and a EcmaRuntimeCallInfo, check whether
66 * the TaggedArray of the JSArray is within expectations.
67 * @tc.type: FUNC
68 * @tc.require:
69 */
HWTEST_F_L0(JSStableArrayTest,Push)70 HWTEST_F_L0(JSStableArrayTest, Push)
71 {
72 int32_t lengthArr = 99;
73 int32_t numElementsPush = 9;
74 JSHandle<JSTaggedValue> handleTagValArr = JSArray::ArrayCreate(thread, JSTaggedNumber(lengthArr));
75 JSHandle<JSArray> handleArr(handleTagValArr);
76
77 auto ecmaRuntimeCallInfo =
78 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4 + 2 * numElementsPush);
79 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
80 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
81 for (int32_t i = 0; i < numElementsPush; i++) {
82 ecmaRuntimeCallInfo->SetCallArg(i, JSTaggedValue(i));
83 }
84 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
85 EXPECT_EQ(JSStableArray::Push(handleArr, ecmaRuntimeCallInfo),
86 JSTaggedValue(lengthArr + numElementsPush));
87 TestHelper::TearDownFrame(thread, prev);
88
89 JSHandle<TaggedArray> handleTagArr(thread, TaggedArray::Cast(handleArr->GetElements().GetTaggedObject()));
90 EXPECT_EQ(handleArr->GetArrayLength(), static_cast<size_t>(lengthArr + numElementsPush));
91 for (int32_t i = lengthArr; i < lengthArr + numElementsPush; i++) {
92 EXPECT_EQ(handleTagArr->Get(i).GetNumber(), i - lengthArr);
93 }
94 }
95
96 /**
97 * @tc.name: Pop
98 * @tc.desc: Change a JSArray through calling Pop function with the JSArray and a EcmaRuntimeCallInfo, check whether
99 * the JSArray and the TaggedArray of the JSArray are within expectations.
100 * @tc.type: FUNC
101 * @tc.require:
102 */
HWTEST_F_L0(JSStableArrayTest,Pop)103 HWTEST_F_L0(JSStableArrayTest, Pop)
104 {
105 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
106
107 int32_t lengthArr = 49;
108 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
109 for (int i = 0; i < lengthArr; i++) {
110 handleTagArr->Set(thread, i, JSTaggedValue(i));
111 }
112 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
113
114 for (int32_t i = 1; i < 6; i++) {
115 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
116 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
117 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
118 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
119 EXPECT_EQ(JSStableArray::Pop(handleArr, ecmaRuntimeCallInfo), JSTaggedValue(lengthArr - i));
120 TestHelper::TearDownFrame(thread, prev);
121
122 EXPECT_EQ(handleArr->GetArrayLength(), static_cast<uint32_t>(lengthArr - i));
123 if (i != 5) {
124 EXPECT_EQ(handleTagArr->GetLength(), static_cast<uint32_t>(lengthArr));
125 EXPECT_EQ(handleTagArr->Get(lengthArr - i), JSTaggedValue::Hole());
126 } else {
127 EXPECT_EQ(handleTagArr->GetLength(), static_cast<uint32_t>(lengthArr - i));
128 }
129 }
130 }
131
132 /**
133 * @tc.name: Splice
134 * @tc.desc: Create a source TaggedArray, set value for the elements of the source TaggedArray, create an source Array
135 * through calling CreateArrayFromList function with the source TaggedArray, create a deleted Array through
136 * calling Splice function with the source Array, an EcmaRuntimeCallInfo that set Args from 2 as the
137 * delete-elements, the offsetStartInsert, the countInsert and the actualDeleteCount. Check whether the
138 * deleted Array and the source Array after change are within expectations.
139 * @tc.type: FUNC
140 * @tc.require:
141 */
HWTEST_F_L0(JSStableArrayTest,Splice)142 HWTEST_F_L0(JSStableArrayTest, Splice)
143 {
144 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
145
146 int32_t lengthArr = 49;
147
148 JSHandle<JSTaggedValue> handleTagValInsertElement1(thread, JSTaggedValue(4000));
149 JSHandle<JSTaggedValue> handleTagValInsertElement2(thread, JSTaggedValue(4100));
150 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
151 for (int i = 0; i < lengthArr; i++) {
152 handleTagArr->Set(thread, i, JSTaggedValue(i * 10));
153 }
154 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
155 double offsetStartInsert = 40;
156 double actualDeleteCount = 3;
157 double countInsert = 2;
158
159 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(),
160 4 + (2 + countInsert) * 2);
161 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
162 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
163 ecmaRuntimeCallInfo->SetCallArg(2, handleTagValInsertElement1.GetTaggedValue());
164 ecmaRuntimeCallInfo->SetCallArg(3, handleTagValInsertElement2.GetTaggedValue());
165
166 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
167 JSHandle<JSTaggedValue> handleTagValArrCombinedOfDeletedElements(thread,
168 JSStableArray::Splice(handleArr, ecmaRuntimeCallInfo, offsetStartInsert, countInsert,
169 actualDeleteCount));
170 TestHelper::TearDownFrame(thread, prev);
171 JSHandle<JSArray> handleArrCombinedOfDeletedElements(handleTagValArrCombinedOfDeletedElements);
172 EXPECT_EQ(handleArrCombinedOfDeletedElements->GetArrayLength(), actualDeleteCount);
173 JSHandle<JSObject> handleObjArrCombinedOfDeletedElements(handleTagValArrCombinedOfDeletedElements);
174 JSHandle<JSTaggedValue> handleTagValTagArrCombinedOfDeletedElements(thread,
175 handleObjArrCombinedOfDeletedElements->GetElements());
176 JSHandle<TaggedArray> handleTagArrCombinedOfDeletedElements(handleTagValTagArrCombinedOfDeletedElements);
177 for (int32_t i = 0; i < actualDeleteCount; i++) {
178 EXPECT_EQ(handleTagArrCombinedOfDeletedElements->Get(i).GetNumber(), (offsetStartInsert + i) * 10);
179 }
180
181 // Check the JSArray(in-out-parameter) changed through calling the Splice function.
182 EXPECT_EQ(handleArr->GetArrayLength(), lengthArr - actualDeleteCount + countInsert);
183 for (int32_t i = 0; i < offsetStartInsert; i++) {
184 EXPECT_EQ(handleTagArr->Get(i).GetNumber(), i * 10);
185 }
186 EXPECT_EQ(handleTagArr->Get(offsetStartInsert).GetNumber(),
187 handleTagValInsertElement1.GetTaggedValue().GetNumber());
188 EXPECT_EQ(handleTagArr->Get(offsetStartInsert + 1).GetNumber(),
189 handleTagValInsertElement2.GetTaggedValue().GetNumber());
190 for (int32_t i = offsetStartInsert + countInsert; i < lengthArr - actualDeleteCount + countInsert; i++) {
191 EXPECT_EQ(handleTagArr->Get(i).GetNumber(), (i + actualDeleteCount - countInsert) * 10);
192 }
193 }
194
195 /**
196 * @tc.name: Shift
197 * @tc.desc: Create a source Array, set value for the elements of the source Array, call the Shift function with the
198 * source Array 5 times, check whether the returned JSTaggedValue and the changed source Array are within
199 * expectations after each call to the Shift function.
200 * @tc.type: FUNC
201 * @tc.require:
202 */
HWTEST_F_L0(JSStableArrayTest,Shift)203 HWTEST_F_L0(JSStableArrayTest, Shift)
204 {
205 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
206
207 int32_t lengthArr = 49;
208 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
209 for (int i = 0; i < lengthArr; i++) {
210 handleTagArr->Set(thread, i, JSTaggedValue(i * 10));
211 }
212 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
213
214 for (int32_t i = 0; i < 5; i++) {
215 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
216 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
217 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
218 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
219 EXPECT_EQ(JSStableArray::Shift(handleArr, ecmaRuntimeCallInfo), JSTaggedValue(i * 10));
220 TestHelper::TearDownFrame(thread, prev);
221 EXPECT_EQ(handleArr->GetArrayLength(), static_cast<uint32_t>(lengthArr - (i + 1)));
222 EXPECT_EQ(handleTagArr->Get(0), JSTaggedValue((i + 1) * 10));
223 if (i != 4) {
224 EXPECT_EQ(handleTagArr->GetLength(), static_cast<uint32_t>(lengthArr));
225 EXPECT_EQ(handleTagArr->Get(lengthArr - (i + 1)), JSTaggedValue::Hole());
226 continue;
227 }
228 EXPECT_EQ(handleTagArr->GetLength(), static_cast<uint32_t>(lengthArr - (i + 1)));
229 }
230 }
231
232 /**
233 * @tc.name: Join_NumberElements_UndefinedSep
234 * @tc.desc: Create a source Array whose elements are Numbers and an EcmaRuntimeCallInfo, check whether the EcmaString
235 * returned through calling Join function with the source Array and the EcmaRuntimeCallInfo is within
236 * expectations.
237 * @tc.type: FUNC
238 * @tc.require:
239 */
HWTEST_F_L0(JSStableArrayTest,Join_NumberElements_UndefinedSep)240 HWTEST_F_L0(JSStableArrayTest, Join_NumberElements_UndefinedSep)
241 {
242 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
243
244 int32_t lengthArr = 10;
245 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
246 for (int i = 0; i < lengthArr; i++) {
247 handleTagArr->Set(thread, i, JSTaggedValue(i));
248 }
249 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
250 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
251 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
252 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
253 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
254 JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
255 JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
256 TestHelper::TearDownFrame(thread, prev);
257
258 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
259 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(), "0,1,2,3,4,5,6,7,8,9");
260 }
261
262 /**
263 * @tc.name: Join_StringElements_UndefinedSep
264 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, check whether the
265 * EcmaString returned through calling Join function with the source Array and the EcmaRuntimeCallInfo is
266 * within expectations.
267 * @tc.type: FUNC
268 * @tc.require:
269 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_UndefinedSep)270 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_UndefinedSep)
271 {
272 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
273
274 int32_t lengthArr = 10;
275 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
276 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(objFactory->NewFromStdString("abc"));
277 for (int i = 0; i < lengthArr; i++) {
278 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
279 }
280 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
281 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
282 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
283 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
284 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
285 JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
286 JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
287 TestHelper::TearDownFrame(thread, prev);
288
289 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
290 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(), "abc,abc,abc,abc,abc,abc,abc,abc,abc,abc");
291 }
292
293 /**
294 * @tc.name: Join_NumberElements_DefinedSep
295 * @tc.desc: Create a source Array whose elements are Numbers and an EcmaRuntimeCallInfo, define the first arg of the
296 EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through calling
297 Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
298 * @tc.type: FUNC
299 * @tc.require:
300 */
HWTEST_F_L0(JSStableArrayTest,Join_NumberElements_DefinedSep)301 HWTEST_F_L0(JSStableArrayTest, Join_NumberElements_DefinedSep)
302 {
303 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
304
305 int32_t lengthArr = 10;
306 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
307 for (int i = 0; i < lengthArr; i++) {
308 handleTagArr->Set(thread, i, JSTaggedValue(i));
309 }
310 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
311 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
312 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
313 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
314 ecmaRuntimeCallInfo->SetCallArg(0,
315 JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString("^")).GetTaggedValue());
316 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
317 JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
318 JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
319 TestHelper::TearDownFrame(thread, prev);
320
321 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
322 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(), "0^1^2^3^4^5^6^7^8^9");
323 }
324
325 /**
326 * @tc.name: Join_StringElements_DefinedSep
327 * @tc.desc: Create a source Array whose elements are EcmaStrings and an EcmaRuntimeCallInfo, define the first arg of
328 the EcmaRuntimeCallInfo an EcmaString as the seperator, check whether the EcmaString returned through
329 calling Join function with the source Array and the EcmaRuntimeCallInfo is within expectations.
330 * @tc.type: FUNC
331 * @tc.require:
332 */
HWTEST_F_L0(JSStableArrayTest,Join_StringElements_DefinedSep)333 HWTEST_F_L0(JSStableArrayTest, Join_StringElements_DefinedSep)
334 {
335 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
336
337 int32_t lengthArr = 10;
338 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
339 JSHandle<JSTaggedValue> handleTagValElementEcmaStr(objFactory->NewFromStdString("a"));
340 for (int i = 0; i < lengthArr; i++) {
341 handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
342 }
343 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
344 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
345 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
346 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
347 ecmaRuntimeCallInfo->SetCallArg(0,
348 JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString(" <> ")).GetTaggedValue());
349 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
350 JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
351 JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
352 TestHelper::TearDownFrame(thread, prev);
353
354 JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
355 EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(),
356 "a <> a <> a <> a <> a <> a <> a <> a <> a <> a");
357 }
358
359 /**
360 * @tc.name: At
361 * @tc.desc: Create a source Array whose elements are Numbers and an EcmaRuntimeCallInfo, define the first arg of the
362 EcmaRuntimeCallInfo an number as the index, check whether the element returned through calling
363 At function with the source Array and the EcmaRuntimeCallInfo is within expectations.
364 * @tc.type: FUNC
365 * @tc.require:
366 */
HWTEST_F_L0(JSStableArrayTest,At_NUMBER_INDEX)367 HWTEST_F_L0(JSStableArrayTest, At_NUMBER_INDEX)
368 {
369 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
370
371 int32_t lengthArr = 10;
372 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
373 for (int i = 0; i < lengthArr; i++) {
374 handleTagArr->Set(thread, i, JSTaggedValue(i));
375 }
376 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
377 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
378 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
379 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
380 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(0));
381 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
382
383 JSTaggedValue thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo);
384 TestHelper::TearDownFrame(thread, prev);
385
386 EXPECT_EQ(thisTagValue.GetNumber(), 0);
387
388 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
389 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
390 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
391 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(9));
392 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
393
394 thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo);
395 TestHelper::TearDownFrame(thread, prev);
396
397 EXPECT_EQ(thisTagValue.GetNumber(), 9);
398
399 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
400 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
401 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
402 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(-1));
403 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
404
405 thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo);
406 TestHelper::TearDownFrame(thread, prev);
407
408 EXPECT_EQ(thisTagValue.GetNumber(), 9);
409
410 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
411 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
412 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
413 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(10));
414 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
415
416 thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo);
417 TestHelper::TearDownFrame(thread, prev);
418
419 EXPECT_EQ(thisTagValue, JSTaggedValue::Undefined());
420 }
421
422 /**
423 * @tc.name: With
424 * @tc.desc: Create a source Array whose elements are Numbers, define the first arg a thread,
425 * define the second arg as the source Array, define the third arg an number as the length of source Array
426 * define the forth arg an number as the index, define the fifth args an number as the value
427 * check whether the value returned through calling With function with the source Array
428 * and the args is within expectations.
429 * @tc.type: FUNC
430 * @tc.require:
431 */
HWTEST_F_L0(JSStableArrayTest,With)432 HWTEST_F_L0(JSStableArrayTest, With)
433 {
434 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
435 int32_t lengthArr = ARRAY_LENGTH_4;
436 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
437 for (int i = 0; i < lengthArr; i++) {
438 handleTagArr->Set(thread, i, JSTaggedValue(i));
439 }
440 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
441
442 int64_t arrayLength = ARRAY_LENGTH_4;
443 int64_t index = static_cast<int64_t>(StableArrayIndex::STABLE_ARRAY_INDEX_2);
444 JSTaggedValue resultArr = JSStableArray::With(thread, handleArr,
445 arrayLength, index,
446 JSHandle<JSTaggedValue>(thread, JSTaggedValue(INT_VALUE_666)));
447 JSHandle<JSTaggedValue> destTaggedValue(thread, resultArr);
448 JSHandle<JSArray> destArr(destTaggedValue);
449 JSHandle<TaggedArray> destTaggedArr(thread, TaggedArray::Cast(destArr->GetElements().GetTaggedObject()));
450 EXPECT_EQ(handleTagArr->Get(
451 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_0)).GetNumber(), INT_VALUE_0);
452 EXPECT_EQ(handleTagArr->Get(
453 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_1)).GetNumber(), INT_VALUE_1);
454 EXPECT_EQ(handleTagArr->Get(
455 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_2)).GetNumber(), INT_VALUE_2);
456 EXPECT_EQ(handleTagArr->Get(
457 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_3)).GetNumber(), INT_VALUE_3);
458 EXPECT_EQ(destTaggedArr->Get(
459 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_0)).GetNumber(), INT_VALUE_0);
460 EXPECT_EQ(destTaggedArr->Get(
461 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_1)).GetNumber(), INT_VALUE_1);
462 EXPECT_EQ(destTaggedArr->Get(
463 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_2)).GetNumber(), INT_VALUE_666);
464 EXPECT_EQ(destTaggedArr->Get(
465 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_3)).GetNumber(), INT_VALUE_3);
466 }
467
468 /**
469 * @tc.name: ToReversed
470 * @tc.desc: Create a source Array whose elements are Numbers and an EcmaRuntimeCallInfo, check whether the
471 value returned through calling ToReversed function with the source Array is within expectations.
472 * @tc.type: FUNC
473 * @tc.require:
474 */
HWTEST_F_L0(JSStableArrayTest,ToReversed)475 HWTEST_F_L0(JSStableArrayTest, ToReversed)
476 {
477 ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory();
478 int32_t lengthArr = ARRAY_LENGTH_4;
479 JSHandle<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
480 for (int i = 0; i < lengthArr; i++) {
481 handleTagArr->Set(thread, i, JSTaggedValue(i));
482 }
483 JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
484 JSTaggedValue resultArr =
485 JSStableArray::ToReversed(thread, handleArr, ARRAY_LENGTH_4);
486 JSHandle<JSTaggedValue> destTaggedValue(thread, resultArr);
487 JSHandle<JSArray> destArr(destTaggedValue);
488 JSHandle<TaggedArray> destTaggedArr(thread, TaggedArray::Cast(destArr->GetElements().GetTaggedObject()));
489
490 EXPECT_EQ(handleTagArr->Get(
491 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_0)).GetNumber(), INT_VALUE_0);
492 EXPECT_EQ(handleTagArr->Get(
493 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_1)).GetNumber(), INT_VALUE_1);
494 EXPECT_EQ(handleTagArr->Get(
495 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_2)).GetNumber(), INT_VALUE_2);
496 EXPECT_EQ(handleTagArr->Get(
497 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_3)).GetNumber(), INT_VALUE_3);
498 EXPECT_EQ(destTaggedArr->Get(
499 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_0)).GetNumber(), INT_VALUE_3);
500 EXPECT_EQ(destTaggedArr->Get(
501 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_1)).GetNumber(), INT_VALUE_2);
502 EXPECT_EQ(destTaggedArr->Get(
503 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_2)).GetNumber(), INT_VALUE_1);
504 EXPECT_EQ(destTaggedArr->Get(
505 static_cast<uint32_t>(StableArrayIndex::STABLE_ARRAY_INDEX_3)).GetNumber(), INT_VALUE_0);
506 }
507 } // namespace panda::test
508