• 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/containers/containers_list.h"
17 #include "ecmascript/containers/containers_private.h"
18 #include "ecmascript/ecma_runtime_call_info.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_api/js_api_list.h"
21 #include "ecmascript/js_api/js_api_list_iterator.h"
22 #include "ecmascript/js_handle.h"
23 #include "ecmascript/js_tagged_value-inl.h"
24 #include "ecmascript/js_thread.h"
25 #include "ecmascript/object_factory.h"
26 #include "ecmascript/tests/test_helper.h"
27 #include "ecmascript/containers/tests/containers_test_helper.h"
28 
29 using namespace panda::ecmascript;
30 using namespace panda::ecmascript::containers;
31 
32 namespace panda::test {
33 class ContainersListTest : public testing::Test {
34 public:
SetUpTestCase()35     static void SetUpTestCase()
36     {
37         GTEST_LOG_(INFO) << "SetUpTestCase";
38     }
39 
TearDownTestCase()40     static void TearDownTestCase()
41     {
42         GTEST_LOG_(INFO) << "TearDownCase";
43     }
44 
SetUp()45     void SetUp() override
46     {
47         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
48     }
49 
TearDown()50     void TearDown() override
51     {
52         TestHelper::DestroyEcmaVMWithScope(instance, scope);
53     }
54 
55     EcmaVM *instance {nullptr};
56     EcmaHandleScope *scope {nullptr};
57     JSThread *thread {nullptr};
58 
59     class TestClass : public base::BuiltinsBase {
60     public:
TestForEachFunc(EcmaRuntimeCallInfo * argv)61         static JSTaggedValue TestForEachFunc(EcmaRuntimeCallInfo *argv)
62         {
63             JSThread *thread = argv->GetThread();
64             JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
65             JSHandle<JSTaggedValue> index = GetCallArg(argv, 1);
66             JSHandle<JSTaggedValue> list = GetCallArg(argv, 2); // 2 means the secode arg
67             if (!list->IsUndefined()) {
68                 if (index->IsNumber() && value->IsNumber()) {
69                     JSHandle<JSTaggedValue> newValue(thread, JSTaggedValue(value->GetInt() * 2)); // 2 means mul by 2
70                     JSAPIList::Set(thread, JSHandle<JSAPIList>::Cast(list), index->GetInt(), newValue);
71                 }
72             }
73             return JSTaggedValue::True();
74         }
75     };
76 protected:
InitializeListConstructor()77     JSTaggedValue InitializeListConstructor()
78     {
79         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
80         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
81 
82         JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
83         JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
84         JSHandle<JSTaggedValue> value =
85             JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
86 
87         auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
88         objCallInfo->SetFunction(JSTaggedValue::Undefined());
89         objCallInfo->SetThis(value.GetTaggedValue());
90         objCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(ContainerTag::List)));
91         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
92         JSTaggedValue result = ContainersPrivate::Load(objCallInfo);
93         TestHelper::TearDownFrame(thread, prev);
94 
95         return result;
96     }
97 
CreateJSAPIList(JSTaggedValue compare=JSTaggedValue::Undefined ())98     JSHandle<JSAPIList> CreateJSAPIList(JSTaggedValue compare = JSTaggedValue::Undefined())
99     {
100         JSHandle<JSTaggedValue> compareHandle(thread, compare);
101         JSHandle<JSFunction> newTarget(thread, InitializeListConstructor());
102         auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
103         objCallInfo->SetFunction(newTarget.GetTaggedValue());
104         objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
105         objCallInfo->SetThis(JSTaggedValue::Undefined());
106         objCallInfo->SetCallArg(0, compareHandle.GetTaggedValue());
107 
108         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
109         JSTaggedValue result = ContainersList::ListConstructor(objCallInfo);
110         TestHelper::TearDownFrame(thread, prev);
111         JSHandle<JSAPIList> list(thread, result);
112         return list;
113     }
114 
ListAdd(JSHandle<JSAPIList> list,JSTaggedValue value)115     JSTaggedValue ListAdd(JSHandle<JSAPIList> list, JSTaggedValue value)
116     {
117         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
118         callInfo->SetFunction(JSTaggedValue::Undefined());
119         callInfo->SetThis(list.GetTaggedValue());
120         callInfo->SetCallArg(0, value);
121 
122         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
123         JSTaggedValue result = ContainersList::Add(callInfo);
124         TestHelper::TearDownFrame(thread, prev);
125         return result;
126     }
127 
ListEqual(JSHandle<JSAPIList> list,JSHandle<JSAPIList> compareList)128     JSTaggedValue ListEqual(JSHandle<JSAPIList> list, JSHandle<JSAPIList> compareList)
129     {
130         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
131         callInfo->SetFunction(JSTaggedValue::Undefined());
132         callInfo->SetThis(list.GetTaggedValue());
133         callInfo->SetCallArg(0, compareList.GetTaggedValue());
134 
135         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
136         JSTaggedValue result = ContainersList::Equal(callInfo);
137         TestHelper::TearDownFrame(thread, prev);
138         return result;
139     }
140 };
141 
HWTEST_F_L0(ContainersListTest,ListConstructor)142 HWTEST_F_L0(ContainersListTest, ListConstructor)
143 {
144     InitializeListConstructor();
145     JSHandle<JSFunction> newTarget(thread, InitializeListConstructor());
146 
147     auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
148     objCallInfo->SetFunction(newTarget.GetTaggedValue());
149     objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
150     objCallInfo->SetThis(JSTaggedValue::Undefined());
151 
152     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
153     JSTaggedValue result = ContainersList::ListConstructor(objCallInfo);
154     TestHelper::TearDownFrame(thread, prev);
155 
156     ASSERT_TRUE(result.IsJSAPIList());
157     JSHandle<JSAPIList> list(thread, result);
158     JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(list));
159     JSTaggedValue funcProto = newTarget->GetFunctionPrototype();
160     ASSERT_EQ(resultProto, funcProto);
161     int size = list->Length();
162     ASSERT_EQ(size, 0);
163 
164     // test ListConstructor exception
165     objCallInfo->SetNewTarget(JSTaggedValue::Undefined());
166     CONTAINERS_API_EXCEPTION_TEST(ContainersList, ListConstructor, objCallInfo);
167 }
168 
HWTEST_F_L0(ContainersListTest,InsertAndGet)169 HWTEST_F_L0(ContainersListTest, InsertAndGet)
170 {
171     constexpr uint32_t NODE_NUMBERS = 8;
172     JSHandle<JSAPIList> list = CreateJSAPIList();
173     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
174         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
175         callInfo->SetFunction(JSTaggedValue::Undefined());
176         callInfo->SetThis(list.GetTaggedValue());
177         callInfo->SetCallArg(0, JSTaggedValue(i));
178         callInfo->SetCallArg(1, JSTaggedValue(i));
179 
180         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
181         JSTaggedValue result = ContainersList::Insert(callInfo);
182         TestHelper::TearDownFrame(thread, prev);
183         EXPECT_EQ(result, JSTaggedValue::True());
184         EXPECT_EQ(list->Length(), static_cast<int>(i + 1));
185     }
186 
187     {
188         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
189         callInfo->SetFunction(JSTaggedValue::Undefined());
190         callInfo->SetThis(list.GetTaggedValue());
191         callInfo->SetCallArg(0, JSTaggedValue(20));
192         callInfo->SetCallArg(1, JSTaggedValue(20));
193 
194         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
195         JSTaggedValue result = ContainersList::Insert(callInfo);
196         TestHelper::TearDownFrame(thread, prev);
197         EXPECT_EQ(result, JSTaggedValue::Exception());
198     }
199 
200     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
201         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
202         callInfo->SetFunction(JSTaggedValue::Undefined());
203         callInfo->SetThis(list.GetTaggedValue());
204         callInfo->SetCallArg(0, JSTaggedValue(i));
205 
206         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
207         JSTaggedValue result = ContainersList::Get(callInfo);
208         TestHelper::TearDownFrame(thread, prev);
209         EXPECT_EQ(result, JSTaggedValue(i));
210     }
211 }
212 
HWTEST_F_L0(ContainersListTest,Remove)213 HWTEST_F_L0(ContainersListTest, Remove)
214 {
215     constexpr uint32_t NODE_NUMBERS = 20;
216     JSHandle<JSAPIList> list = CreateJSAPIList();
217     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
218         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
219         callInfo->SetFunction(JSTaggedValue::Undefined());
220         callInfo->SetThis(list.GetTaggedValue());
221         callInfo->SetCallArg(0, JSTaggedValue(i));
222         callInfo->SetCallArg(1, JSTaggedValue(i));
223 
224         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
225         JSTaggedValue result = ContainersList::Insert(callInfo);
226         TestHelper::TearDownFrame(thread, prev);
227         EXPECT_EQ(result, JSTaggedValue::True());
228         EXPECT_EQ(list->Length(), static_cast<int>(i + 1));
229     }
230 
231     {
232         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
233         callInfo->SetFunction(JSTaggedValue::Undefined());
234         callInfo->SetThis(list.GetTaggedValue());
235         callInfo->SetCallArg(0, JSTaggedValue(NODE_NUMBERS / 2));
236 
237         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
238         JSTaggedValue rvalue = ContainersList::Remove(callInfo);
239         TestHelper::TearDownFrame(thread, prev);
240         EXPECT_EQ(rvalue, JSTaggedValue::True());
241         EXPECT_EQ(list->Length(), static_cast<int>(NODE_NUMBERS - 1));
242     }
243 
244     {
245         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
246         callInfo->SetFunction(JSTaggedValue::Undefined());
247         callInfo->SetThis(list.GetTaggedValue());
248         callInfo->SetCallArg(0, JSTaggedValue(6));
249 
250         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
251         JSTaggedValue rvalue = ContainersList::RemoveByIndex(callInfo);
252         TestHelper::TearDownFrame(thread, prev);
253         EXPECT_EQ(rvalue, JSTaggedValue(6));
254         EXPECT_EQ(list->Length(), static_cast<int>(NODE_NUMBERS - 2));
255     }
256 }
257 
HWTEST_F_L0(ContainersListTest,Equal)258 HWTEST_F_L0(ContainersListTest, Equal)
259 {
260     constexpr uint32_t NODE_NUMBERS = 8;
261     JSTaggedValue result = JSTaggedValue::Hole();
262     JSHandle<JSAPIList> list = CreateJSAPIList();
263     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
264         result = ListAdd(list, JSTaggedValue(i));
265         EXPECT_EQ(result, JSTaggedValue::True());
266         EXPECT_EQ(list->Length(), static_cast<int>(i + 1));
267     }
268     // Equal
269     JSHandle<JSAPIList> list1 = CreateJSAPIList();
270     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
271         result = ListAdd(list1, JSTaggedValue(i));
272         EXPECT_EQ(result, JSTaggedValue::True());
273         EXPECT_EQ(list1->Length(), static_cast<int>(i + 1));
274     }
275     result = ListEqual(list, list1);
276     EXPECT_EQ(result, JSTaggedValue::True());
277 
278     // Length Not Equal
279     JSHandle<JSAPIList> list2 = CreateJSAPIList();
280     for (uint32_t i = 0; i < NODE_NUMBERS / 2; i++) {
281         result = ListAdd(list2, JSTaggedValue(i));
282         EXPECT_EQ(result, JSTaggedValue::True());
283         EXPECT_EQ(result, JSTaggedValue::True());
284         EXPECT_EQ(list2->Length(), static_cast<int>(i + 1));
285     }
286     result = ListEqual(list, list2);
287     EXPECT_EQ(result, JSTaggedValue::False());
288 
289     // Value Not Equal
290     JSHandle<JSAPIList> list3 = CreateJSAPIList();
291     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
292         if (i == (NODE_NUMBERS - 1)) {
293             result = ListAdd(list3, JSTaggedValue(0));
294         } else {
295             result = ListAdd(list3, JSTaggedValue(i));
296         }
297         EXPECT_EQ(result, JSTaggedValue::True());
298         EXPECT_EQ(list3->Length(), static_cast<int>(i + 1));
299     }
300     result = ListEqual(list, list2);
301     EXPECT_EQ(result, JSTaggedValue::False());
302 }
303 
HWTEST_F_L0(ContainersListTest,GetSubList)304 HWTEST_F_L0(ContainersListTest, GetSubList)
305 {
306     constexpr uint32_t NODE_NUMBERS = 10;
307     JSHandle<JSAPIList> list = CreateJSAPIList();
308     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
309         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
310         callInfo->SetFunction(JSTaggedValue::Undefined());
311         callInfo->SetThis(list.GetTaggedValue());
312         callInfo->SetCallArg(0, JSTaggedValue(i));
313 
314         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
315         JSTaggedValue result = ContainersList::Add(callInfo);
316         TestHelper::TearDownFrame(thread, prev);
317         EXPECT_EQ(result, JSTaggedValue::True());
318         EXPECT_EQ(list->Length(), static_cast<int>(i + 1));
319     }
320 
321     {
322         auto callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
323         callInfo1->SetFunction(JSTaggedValue::Undefined());
324         callInfo1->SetThis(list.GetTaggedValue());
325         callInfo1->SetCallArg(0, JSTaggedValue(2));
326         callInfo1->SetCallArg(1, JSTaggedValue(5));
327         [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo1);
328         JSTaggedValue newList = ContainersList::GetSubList(callInfo1);
329         TestHelper::TearDownFrame(thread, prev1);
330         EXPECT_EQ(list->Length(), 10);
331         for (uint32_t i = 0; i < 3; i++) {
332             auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
333             callInfo->SetFunction(JSTaggedValue::Undefined());
334             callInfo->SetThis(newList);
335             callInfo->SetCallArg(0, JSTaggedValue(i));
336 
337             [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
338             JSTaggedValue result = ContainersList::Get(callInfo);
339             TestHelper::TearDownFrame(thread, prev);
340             EXPECT_EQ(result, JSTaggedValue(i + 2));
341         }
342     }
343 }
344 
HWTEST_F_L0(ContainersListTest,ConvertToArray)345 HWTEST_F_L0(ContainersListTest, ConvertToArray)
346 {
347     constexpr uint32_t NODE_NUMBERS = 8;
348     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
349     JSHandle<JSAPIList> list = CreateJSAPIList();
350     JSHandle<TaggedArray> oldArray(factory->NewTaggedArray(NODE_NUMBERS, JSTaggedValue::Hole()));
351     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
352         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
353         callInfo->SetFunction(JSTaggedValue::Undefined());
354         callInfo->SetThis(list.GetTaggedValue());
355         callInfo->SetCallArg(0, JSTaggedValue(i));
356 
357         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
358         JSTaggedValue result = ContainersList::Add(callInfo);
359         oldArray->Set(thread, i, JSTaggedValue(i));
360         TestHelper::TearDownFrame(thread, prev);
361         EXPECT_EQ(result, JSTaggedValue::True());
362         EXPECT_EQ(list->Length(), static_cast<int>(i + 1));
363     }
364 
365     auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
366     callInfo->SetFunction(JSTaggedValue::Undefined());
367     callInfo->SetThis(list.GetTaggedValue());
368 
369     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
370     JSTaggedValue newArray = ContainersList::ConvertToArray(callInfo);
371     TestHelper::TearDownFrame(thread, prev);
372     JSTaggedValue newArrayValue =
373         JSTaggedValue::ToObject(thread, JSHandle<JSTaggedValue>(thread, newArray))->GetElements();
374     JSHandle<TaggedArray> newArrayHandle(thread, newArrayValue);
375 
376     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
377         EXPECT_EQ(newArrayHandle->Get(i), oldArray->Get(i));
378     }
379 }
380 
HWTEST_F_L0(ContainersListTest,Clear)381 HWTEST_F_L0(ContainersListTest, Clear)
382 {
383     constexpr uint32_t NODE_NUMBERS = 8;
384     JSHandle<JSAPIList> list = CreateJSAPIList();
385     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
386         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
387         callInfo->SetFunction(JSTaggedValue::Undefined());
388         callInfo->SetThis(list.GetTaggedValue());
389         callInfo->SetCallArg(0, JSTaggedValue(i));
390 
391         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
392         JSTaggedValue result = ContainersList::Add(callInfo);
393         TestHelper::TearDownFrame(thread, prev);
394         EXPECT_EQ(result, JSTaggedValue::True());
395         EXPECT_EQ(list->Length(), static_cast<int>(i + 1));
396     }
397 
398     {
399         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
400         callInfo->SetFunction(JSTaggedValue::Undefined());
401         callInfo->SetThis(list.GetTaggedValue());
402 
403         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
404         ContainersList::Clear(callInfo);
405         TestHelper::TearDownFrame(thread, prev);
406         EXPECT_EQ(list->Length(), 0);
407     }
408 }
409 
HWTEST_F_L0(ContainersListTest,Values)410 HWTEST_F_L0(ContainersListTest, Values)
411 {
412     constexpr int NODE_NUMBERS = 8;
413     JSHandle<JSAPIList> list = CreateJSAPIList();
414     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
415         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
416         callInfo->SetFunction(JSTaggedValue::Undefined());
417         callInfo->SetThis(list.GetTaggedValue());
418         callInfo->SetCallArg(0, JSTaggedValue(i));
419         callInfo->SetCallArg(1, JSTaggedValue(i));
420 
421         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
422         JSTaggedValue result = ContainersList::Add(callInfo);
423         TestHelper::TearDownFrame(thread, prev);
424         EXPECT_EQ(result, JSTaggedValue::True());
425         EXPECT_EQ(list->Length(), static_cast<int>(i + 1));
426     }
427 
428     auto callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
429     callInfo1->SetFunction(JSTaggedValue::Undefined());
430     callInfo1->SetThis(list.GetTaggedValue());
431     [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo1);
432     JSHandle<JSTaggedValue> iterValues(thread, ContainersList::GetIteratorObj(callInfo1));
433     TestHelper::TearDownFrame(thread, prev1);
434     EXPECT_TRUE(iterValues->IsJSAPIListIterator());
435 
436     JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
437     for (int i = 0; i < NODE_NUMBERS; i++) {
438         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
439         callInfo->SetFunction(JSTaggedValue::Undefined());
440         callInfo->SetThis(iterValues.GetTaggedValue());
441 
442         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
443         result.Update(JSAPIListIterator::Next(callInfo));
444         TestHelper::TearDownFrame(thread, prev);
445         EXPECT_EQ(i, JSIterator::IteratorValue(thread, result)->GetInt());
446     }
447 }
448 
HWTEST_F_L0(ContainersListTest,ForEach)449 HWTEST_F_L0(ContainersListTest, ForEach)
450 {
451     constexpr uint32_t NODE_NUMBERS = 8;
452     JSHandle<JSAPIList> list = CreateJSAPIList();
453     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
454         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
455         callInfo->SetFunction(JSTaggedValue::Undefined());
456         callInfo->SetThis(list.GetTaggedValue());
457         callInfo->SetCallArg(0, JSTaggedValue(i));
458         callInfo->SetCallArg(1, JSTaggedValue(i));
459 
460         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
461         JSTaggedValue result = ContainersList::Add(callInfo);
462         TestHelper::TearDownFrame(thread, prev);
463         EXPECT_EQ(result, JSTaggedValue::True());
464         EXPECT_EQ(list->Length(), static_cast<int>(i + 1));
465     }
466     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
467     JSHandle<JSAPIList> dlist = CreateJSAPIList();
468     {
469         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
470         JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
471         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
472         callInfo->SetFunction(JSTaggedValue::Undefined());
473         callInfo->SetThis(list.GetTaggedValue());
474         callInfo->SetCallArg(0, func.GetTaggedValue());
475         callInfo->SetCallArg(1, dlist.GetTaggedValue());
476 
477         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
478         ContainersList::ForEach(callInfo);
479         TestHelper::TearDownFrame(thread, prev);
480     }
481 
482     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
483         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
484         callInfo->SetFunction(JSTaggedValue::Undefined());
485         callInfo->SetThis(list.GetTaggedValue());
486         callInfo->SetCallArg(0, JSTaggedValue(i));
487 
488         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
489         JSTaggedValue result = ContainersList::Get(callInfo);
490         TestHelper::TearDownFrame(thread, prev);
491         EXPECT_EQ(result, JSTaggedValue(i * 2));
492     }
493 }
494 
HWTEST_F_L0(ContainersListTest,ProxyOfLength)495 HWTEST_F_L0(ContainersListTest, ProxyOfLength)
496 {
497     constexpr uint32_t NODE_NUMBERS = 8;
498     JSHandle<JSAPIList> list = CreateJSAPIList();
499     auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
500     callInfo->SetFunction(JSTaggedValue::Undefined());
501     JSHandle<JSProxy> proxy = CreateJSProxyHandle(thread);
502     proxy->SetTarget(thread, list.GetTaggedValue());
503     callInfo->SetThis(proxy.GetTaggedValue());
504 
505     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
506         callInfo->SetCallArg(0, JSTaggedValue(i));
507         callInfo->SetCallArg(1, JSTaggedValue(i + 1));
508         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
509         ContainersList::Add(callInfo);
510         TestHelper::TearDownFrame(thread, prev);
511 
512         [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo);
513         JSTaggedValue retult = ContainersList::Length(callInfo);
514         TestHelper::TearDownFrame(thread, prev1);
515         EXPECT_EQ(retult, JSTaggedValue(i + 1));
516     }
517 }
518 
HWTEST_F_L0(ContainersListTest,ExceptionReturn)519 HWTEST_F_L0(ContainersListTest, ExceptionReturn)
520 {
521     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, Add);
522     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, Insert);
523     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, Get);
524     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, Set);
525     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, GetFirst);
526     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, GetLast);
527     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, Has);
528     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, IsEmpty);
529     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, GetIndexOf);
530     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, GetLastIndexOf);
531     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, ForEach);
532     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, Clear);
533 
534     JSHandle<JSAPIList> list = CreateJSAPIList();
535     {
536         auto callInfo = NewEmptyCallInfo(thread);
537         callInfo->SetThis(list.GetTaggedValue());
538         CONTAINERS_API_EXCEPTION_TEST(ContainersList, Insert, callInfo);
539     }
540     {
541         auto callInfo = NewEmptyCallInfo(thread);
542         callInfo->SetThis(list.GetTaggedValue());
543         CONTAINERS_API_EXCEPTION_TEST(ContainersList, Get, callInfo);
544     }
545     {
546         auto callInfo = NewEmptyCallInfo(thread);
547         callInfo->SetThis(list.GetTaggedValue());
548         CONTAINERS_API_EXCEPTION_TEST(ContainersList, Set, callInfo);
549     }
550 }
551 
HWTEST_F_L0(ContainersListTest,SpecialReturn)552 HWTEST_F_L0(ContainersListTest, SpecialReturn)
553 {
554     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, RemoveByIndex);
555     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, ReplaceAllElements);
556     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, Equal);
557     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, Sort);
558     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, Remove);
559     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, ConvertToArray);
560     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, Length);
561     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersList, GetSubList);
562 
563     JSHandle<JSAPIList> list = CreateJSAPIList();
564     {
565         auto callInfo = NewEmptyCallInfo(thread);
566         callInfo->SetThis(list.GetTaggedValue());
567         CONTAINERS_API_EXCEPTION_TEST(ContainersList, RemoveByIndex, callInfo);
568     }
569     {
570         auto callInfo = NewEmptyCallInfo(thread);
571         callInfo->SetThis(list.GetTaggedValue());
572         CONTAINERS_API_EXCEPTION_TEST(ContainersList, ReplaceAllElements, callInfo);
573     }
574     {
575         auto callInfo = NewEmptyCallInfo(thread);
576         callInfo->SetThis(list.GetTaggedValue());
577         CONTAINERS_API_EXCEPTION_TEST(ContainersList, GetSubList, callInfo);
578     }
579     {
580         auto callInfo = NewEmptyCallInfo(thread);
581         callInfo->SetThis(list.GetTaggedValue());
582         callInfo->SetCallArg(0, JSTaggedValue(0));
583         CONTAINERS_API_EXCEPTION_TEST(ContainersList, GetSubList, callInfo);
584     }
585 
586     // test equal hole and hole
587     {
588         auto callInfo = NewEmptyCallInfo(thread);
589         callInfo->SetThis(list.GetTaggedValue());
590         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
591         JSTaggedValue result = ContainersList::Equal(callInfo);
592         TestHelper::TearDownFrame(thread, prev);
593         EXPECT_EQ(result, JSTaggedValue::False());
594     }
595 }
596 }  // namespace panda::test
597