• 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_linked_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_linked_list.h"
21 #include "ecmascript/js_api/js_api_linked_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 ContainersLinkedListTest : 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                     JSAPILinkedList::Set(thread, JSHandle<JSAPILinkedList>::Cast(list), index->GetInt(), newValue);
71                 }
72             }
73             return JSTaggedValue::True();
74         }
75     };
76 protected:
InitializeLinkedListConstructor()77     JSTaggedValue InitializeLinkedListConstructor()
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::LinkedList)));
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 
CreateJSAPILinkedList(JSTaggedValue compare=JSTaggedValue::Undefined ())98     JSHandle<JSAPILinkedList> CreateJSAPILinkedList(JSTaggedValue compare = JSTaggedValue::Undefined())
99     {
100         JSHandle<JSTaggedValue> compareHandle(thread, compare);
101         JSHandle<JSFunction> newTarget(thread, InitializeLinkedListConstructor());
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 = ContainersLinkedList::LinkedListConstructor(objCallInfo);
110         TestHelper::TearDownFrame(thread, prev);
111         JSHandle<JSAPILinkedList> linkedlist(thread, result);
112         return linkedlist;
113     }
114 
LinkedListInsert(JSHandle<JSAPILinkedList> linkedlist,JSTaggedValue index,JSTaggedValue value)115     JSTaggedValue LinkedListInsert(JSHandle<JSAPILinkedList> linkedlist, JSTaggedValue index, JSTaggedValue value)
116     {
117         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
118         callInfo->SetFunction(JSTaggedValue::Undefined());
119         callInfo->SetThis(linkedlist.GetTaggedValue());
120         callInfo->SetCallArg(0, index);
121         callInfo->SetCallArg(1, value);
122 
123         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
124         JSTaggedValue result = ContainersLinkedList::Insert(callInfo);
125         TestHelper::TearDownFrame(thread, prev);
126         return result;
127     }
128 
LinkedListGet(JSHandle<JSAPILinkedList> linkedlist,JSTaggedValue index)129     JSTaggedValue LinkedListGet(JSHandle<JSAPILinkedList> linkedlist, JSTaggedValue index)
130     {
131         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
132         callInfo->SetFunction(JSTaggedValue::Undefined());
133         callInfo->SetThis(linkedlist.GetTaggedValue());
134         callInfo->SetCallArg(0, index);
135 
136         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
137         JSTaggedValue result = ContainersLinkedList::Get(callInfo);
138         TestHelper::TearDownFrame(thread, prev);
139         return result;
140     }
141 
LinkedListRemoveByIndex(JSHandle<JSAPILinkedList> linkedlist,JSTaggedValue index)142     JSTaggedValue LinkedListRemoveByIndex(JSHandle<JSAPILinkedList> linkedlist, JSTaggedValue index)
143     {
144         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
145         callInfo->SetFunction(JSTaggedValue::Undefined());
146         callInfo->SetThis(linkedlist.GetTaggedValue());
147         callInfo->SetCallArg(0, index);
148 
149         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
150         JSTaggedValue result = ContainersLinkedList::RemoveByIndex(callInfo);
151         TestHelper::TearDownFrame(thread, prev);
152         return result;
153     }
154 };
155 
HWTEST_F_L0(ContainersLinkedListTest,LinkedListConstructor)156 HWTEST_F_L0(ContainersLinkedListTest, LinkedListConstructor)
157 {
158     InitializeLinkedListConstructor();
159     JSHandle<JSFunction> newTarget(thread, InitializeLinkedListConstructor());
160 
161     auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
162     objCallInfo->SetFunction(newTarget.GetTaggedValue());
163     objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
164     objCallInfo->SetThis(JSTaggedValue::Undefined());
165 
166     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
167     JSTaggedValue result = ContainersLinkedList::LinkedListConstructor(objCallInfo);
168     TestHelper::TearDownFrame(thread, prev);
169 
170     ASSERT_TRUE(result.IsJSAPILinkedList());
171     JSHandle<JSAPILinkedList> list(thread, result);
172     JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(list));
173     JSTaggedValue funcProto = newTarget->GetFunctionPrototype(thread);
174     ASSERT_EQ(resultProto, funcProto);
175     int size = list->Length(thread);
176     ASSERT_EQ(size, 0);
177 
178     // test PlainArrayConstructor exception
179     objCallInfo->SetNewTarget(JSTaggedValue::Undefined());
180     CONTAINERS_API_EXCEPTION_TEST(ContainersLinkedList, LinkedListConstructor, objCallInfo);
181 }
182 
HWTEST_F_L0(ContainersLinkedListTest,InsertAndGet)183 HWTEST_F_L0(ContainersLinkedListTest, InsertAndGet)
184 {
185     constexpr uint32_t NODE_NUMBERS = 8;
186     JSTaggedValue result = JSTaggedValue::Hole();
187     JSHandle<JSAPILinkedList> linkedlist = CreateJSAPILinkedList();
188     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
189         result = LinkedListInsert(linkedlist, JSTaggedValue(i), JSTaggedValue(5));
190         EXPECT_EQ(result, JSTaggedValue::True());
191         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(i + 1));
192     }
193     // Insert in position 0(first) with value 10
194     result = LinkedListInsert(linkedlist, JSTaggedValue(0), JSTaggedValue(10));
195     EXPECT_EQ(result, JSTaggedValue::True());
196     EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(NODE_NUMBERS + 1));
197 
198     // Insert in position NODE_NUMBERS / 2(middle) with value 10
199     result = LinkedListInsert(linkedlist, JSTaggedValue(NODE_NUMBERS / 2), JSTaggedValue(10));
200     EXPECT_EQ(result, JSTaggedValue::True());
201     EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(NODE_NUMBERS + 2));
202 
203     // Insert in position NODE_NUMBERS + 2(last) with value 10
204     result = LinkedListInsert(linkedlist, JSTaggedValue(NODE_NUMBERS + 2), JSTaggedValue(10));
205     EXPECT_EQ(result, JSTaggedValue::True());
206     EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(NODE_NUMBERS + 3));
207 
208     uint32_t length = static_cast<uint32_t>(linkedlist->Length(thread));
209     for (uint32_t i = 0; i < length; i++) {
210         if (i == 0) {
211             result = LinkedListGet(linkedlist, JSTaggedValue(i));
212             EXPECT_EQ(result, JSTaggedValue(10));
213         } else if (i == NODE_NUMBERS / 2) {
214             result = LinkedListGet(linkedlist, JSTaggedValue(i));
215             EXPECT_EQ(result, JSTaggedValue(10));
216         } else if (i == NODE_NUMBERS + 2) {
217             result = LinkedListGet(linkedlist, JSTaggedValue(i));
218             EXPECT_EQ(result, JSTaggedValue(10));
219         } else {
220             result = LinkedListGet(linkedlist, JSTaggedValue(i));
221             EXPECT_EQ(result, JSTaggedValue(5));
222         }
223     }
224 }
225 
HWTEST_F_L0(ContainersLinkedListTest,Remove)226 HWTEST_F_L0(ContainersLinkedListTest, Remove)
227 {
228     constexpr uint32_t NODE_NUMBERS = 20;
229     JSTaggedValue result = JSTaggedValue::Hole();
230     JSHandle<JSAPILinkedList> linkedlist = CreateJSAPILinkedList();
231     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
232         result = LinkedListInsert(linkedlist, JSTaggedValue(i), JSTaggedValue(i));
233         EXPECT_EQ(result, JSTaggedValue::True());
234         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(i + 1));
235     }
236 
237     {
238         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
239         callInfo->SetFunction(JSTaggedValue::Undefined());
240         callInfo->SetThis(linkedlist.GetTaggedValue());
241         callInfo->SetCallArg(0, JSTaggedValue(NODE_NUMBERS / 2));
242 
243         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
244         JSTaggedValue rvalue = ContainersLinkedList::Remove(callInfo);
245         TestHelper::TearDownFrame(thread, prev);
246         EXPECT_EQ(rvalue, JSTaggedValue::True());
247         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(NODE_NUMBERS - 1));
248     }
249 }
250 
HWTEST_F_L0(ContainersLinkedListTest,RemoveByIndex)251 HWTEST_F_L0(ContainersLinkedListTest, RemoveByIndex)
252 {
253     constexpr uint32_t NODE_NUMBERS = 20;
254     JSTaggedValue result = JSTaggedValue::Hole();
255     JSHandle<JSAPILinkedList> linkedlist = CreateJSAPILinkedList();
256     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
257         result = LinkedListInsert(linkedlist, JSTaggedValue(i), JSTaggedValue(i));
258         EXPECT_EQ(result, JSTaggedValue::True());
259         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(i + 1));
260     }
261 
262     // Remove index > (NODE_NUMBERS / 2)
263     result = LinkedListRemoveByIndex(linkedlist, JSTaggedValue(16));
264     EXPECT_EQ(result, JSTaggedValue(16));
265     EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(NODE_NUMBERS - 1));
266 
267     // Remove index < (NODE_NUMBERS / 2)
268     result = LinkedListRemoveByIndex(linkedlist, JSTaggedValue(6));
269     EXPECT_EQ(result, JSTaggedValue(6));
270     EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(NODE_NUMBERS - 2));
271 }
272 
HWTEST_F_L0(ContainersLinkedListTest,RemoveFirst)273 HWTEST_F_L0(ContainersLinkedListTest, RemoveFirst)
274 {
275     constexpr uint32_t NODE_NUMBERS = 20;
276     JSTaggedValue result = JSTaggedValue::Hole();
277     JSHandle<JSAPILinkedList> linkedlist = CreateJSAPILinkedList();
278     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
279         result = LinkedListInsert(linkedlist, JSTaggedValue(i), JSTaggedValue(i));
280         EXPECT_EQ(result, JSTaggedValue::True());
281         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(i + 1));
282     }
283 
284     {
285         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
286         callInfo->SetFunction(JSTaggedValue::Undefined());
287         callInfo->SetThis(linkedlist.GetTaggedValue());
288 
289         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
290         JSTaggedValue rvalue = ContainersLinkedList::RemoveFirst(callInfo);
291         TestHelper::TearDownFrame(thread, prev);
292         EXPECT_EQ(rvalue, JSTaggedValue(0));
293         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(NODE_NUMBERS - 1));
294     }
295 
296     {
297         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
298         callInfo->SetFunction(JSTaggedValue::Undefined());
299         callInfo->SetThis(linkedlist.GetTaggedValue());
300         callInfo->SetCallArg(0, JSTaggedValue(15));
301 
302         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
303         JSTaggedValue rvalue = ContainersLinkedList::RemoveFirstFound(callInfo);
304         TestHelper::TearDownFrame(thread, prev);
305         EXPECT_EQ(rvalue, JSTaggedValue::True());
306         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(NODE_NUMBERS - 2));
307     }
308 }
309 
HWTEST_F_L0(ContainersLinkedListTest,RemoveLast)310 HWTEST_F_L0(ContainersLinkedListTest, RemoveLast)
311 {
312     constexpr uint32_t NODE_NUMBERS = 20;
313     JSTaggedValue result = JSTaggedValue::Hole();
314     JSHandle<JSAPILinkedList> linkedlist = CreateJSAPILinkedList();
315     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
316         result = LinkedListInsert(linkedlist, JSTaggedValue(i), JSTaggedValue(i));
317         EXPECT_EQ(result, JSTaggedValue::True());
318         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(i + 1));
319     }
320 
321     {
322         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
323         callInfo->SetFunction(JSTaggedValue::Undefined());
324         callInfo->SetThis(linkedlist.GetTaggedValue());
325 
326         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
327         JSTaggedValue rvalue = ContainersLinkedList::RemoveLast(callInfo);
328         TestHelper::TearDownFrame(thread, prev);
329         EXPECT_EQ(rvalue, JSTaggedValue(19));
330         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(NODE_NUMBERS - 1));
331     }
332 
333     {
334         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
335         callInfo->SetFunction(JSTaggedValue::Undefined());
336         callInfo->SetThis(linkedlist.GetTaggedValue());
337         callInfo->SetCallArg(0, JSTaggedValue(8));
338 
339         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
340         JSTaggedValue rvalue = ContainersLinkedList::RemoveLastFound(callInfo);
341         TestHelper::TearDownFrame(thread, prev);
342         EXPECT_EQ(rvalue, JSTaggedValue::True());
343         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(NODE_NUMBERS - 2));
344     }
345 }
346 
HWTEST_F_L0(ContainersLinkedListTest,Clear)347 HWTEST_F_L0(ContainersLinkedListTest, Clear)
348 {
349     constexpr uint32_t NODE_NUMBERS = 8;
350     JSHandle<JSAPILinkedList> linkedlist = CreateJSAPILinkedList();
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(linkedlist.GetTaggedValue());
355         callInfo->SetCallArg(0, JSTaggedValue(i));
356 
357         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
358         JSTaggedValue result = ContainersLinkedList::Add(callInfo);
359         TestHelper::TearDownFrame(thread, prev);
360         EXPECT_EQ(result, JSTaggedValue::True());
361         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(i + 1));
362     }
363 
364     {
365         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
366         callInfo->SetFunction(JSTaggedValue::Undefined());
367         callInfo->SetThis(linkedlist.GetTaggedValue());
368 
369         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
370         ContainersLinkedList::Clear(callInfo);
371         TestHelper::TearDownFrame(thread, prev);
372         EXPECT_EQ(linkedlist->Length(thread), 0);
373     }
374 }
375 
HWTEST_F_L0(ContainersLinkedListTest,Clone)376 HWTEST_F_L0(ContainersLinkedListTest, Clone)
377 {
378     constexpr uint32_t NODE_NUMBERS = 8;
379     JSHandle<JSAPILinkedList> linkedList = CreateJSAPILinkedList();
380     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
381         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
382         callInfo->SetFunction(JSTaggedValue::Undefined());
383         callInfo->SetThis(linkedList.GetTaggedValue());
384         callInfo->SetCallArg(0, JSTaggedValue(i));
385         callInfo->SetCallArg(1, JSTaggedValue(i));
386 
387         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
388         JSTaggedValue result = ContainersLinkedList::Add(callInfo);
389         TestHelper::TearDownFrame(thread, prev);
390         EXPECT_EQ(result, JSTaggedValue::True());
391         EXPECT_EQ(linkedList->Length(thread), static_cast<int>(i + 1));
392     }
393 
394     linkedList->Dump(thread);
395 
396     auto callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
397     callInfo1->SetFunction(JSTaggedValue::Undefined());
398     callInfo1->SetThis(linkedList.GetTaggedValue());
399     JSTaggedValue newlinkedList = ContainersLinkedList::Clone(callInfo1);
400     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
401         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
402         callInfo->SetFunction(JSTaggedValue::Undefined());
403         callInfo->SetThis(newlinkedList);
404         callInfo->SetCallArg(0, JSTaggedValue(i));
405 
406         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
407         JSTaggedValue result = ContainersLinkedList::Get(callInfo);
408         TestHelper::TearDownFrame(thread, prev);
409         EXPECT_EQ(result, JSTaggedValue(i));
410     }
411 }
412 
HWTEST_F_L0(ContainersLinkedListTest,Values)413 HWTEST_F_L0(ContainersLinkedListTest, Values)
414 {
415     constexpr uint32_t NODE_NUMBERS = 8;
416     JSHandle<JSAPILinkedList> linkedlist = CreateJSAPILinkedList();
417     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
418         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
419         callInfo->SetFunction(JSTaggedValue::Undefined());
420         callInfo->SetThis(linkedlist.GetTaggedValue());
421         callInfo->SetCallArg(0, JSTaggedValue(i));
422         callInfo->SetCallArg(1, JSTaggedValue(i));
423 
424         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
425         JSTaggedValue result = ContainersLinkedList::Add(callInfo);
426         TestHelper::TearDownFrame(thread, prev);
427         EXPECT_EQ(result, JSTaggedValue::True());
428         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(i + 1));
429     }
430 
431     // test values
432     auto callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
433     callInfo1->SetFunction(JSTaggedValue::Undefined());
434     callInfo1->SetThis(linkedlist.GetTaggedValue());
435     [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo1);
436     JSHandle<JSTaggedValue> iterValues(thread, ContainersLinkedList::GetIteratorObj(callInfo1));
437     TestHelper::TearDownFrame(thread, prev1);
438     EXPECT_TRUE(iterValues->IsJSAPILinkedListIterator());
439 
440     JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
441     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
442         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
443         callInfo->SetFunction(JSTaggedValue::Undefined());
444         callInfo->SetThis(iterValues.GetTaggedValue());
445 
446         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
447         result.Update(JSAPILinkedListIterator::Next(callInfo));
448         TestHelper::TearDownFrame(thread, prev);
449         EXPECT_EQ(static_cast<int>(i), JSIterator::IteratorValue(thread, result)->GetInt());
450     }
451 }
452 
HWTEST_F_L0(ContainersLinkedListTest,ForEach)453 HWTEST_F_L0(ContainersLinkedListTest, ForEach)
454 {
455     constexpr uint32_t NODE_NUMBERS = 8;
456     JSHandle<JSAPILinkedList> linkedlist = CreateJSAPILinkedList();
457     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
458         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
459         callInfo->SetFunction(JSTaggedValue::Undefined());
460         callInfo->SetThis(linkedlist.GetTaggedValue());
461         callInfo->SetCallArg(0, JSTaggedValue(i));
462         callInfo->SetCallArg(1, JSTaggedValue(i));
463 
464         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
465         JSTaggedValue result = ContainersLinkedList::Add(callInfo);
466         TestHelper::TearDownFrame(thread, prev);
467         EXPECT_EQ(result, JSTaggedValue::True());
468         EXPECT_EQ(linkedlist->Length(thread), static_cast<int>(i + 1));
469     }
470     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
471     JSHandle<JSAPILinkedList> newLinkedlist = CreateJSAPILinkedList();
472     {
473         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
474         JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
475         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
476         callInfo->SetFunction(JSTaggedValue::Undefined());
477         callInfo->SetThis(linkedlist.GetTaggedValue());
478         callInfo->SetCallArg(0, func.GetTaggedValue());
479         callInfo->SetCallArg(1, newLinkedlist.GetTaggedValue());
480 
481         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
482         ContainersLinkedList::ForEach(callInfo);
483         TestHelper::TearDownFrame(thread, prev);
484     }
485 
486     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
487         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
488         callInfo->SetFunction(JSTaggedValue::Undefined());
489         callInfo->SetThis(linkedlist.GetTaggedValue());
490         callInfo->SetCallArg(0, JSTaggedValue(i));
491 
492         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
493         JSTaggedValue result = ContainersLinkedList::Get(callInfo);
494         TestHelper::TearDownFrame(thread, prev);
495         EXPECT_EQ(result, JSTaggedValue(i * 2));
496     }
497 }
498 
HWTEST_F_L0(ContainersLinkedListTest,ProxyOfLength)499 HWTEST_F_L0(ContainersLinkedListTest, ProxyOfLength)
500 {
501     constexpr uint32_t NODE_NUMBERS = 8;
502     JSHandle<JSAPILinkedList> linkedlist = CreateJSAPILinkedList();
503     auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
504     callInfo->SetFunction(JSTaggedValue::Undefined());
505     JSHandle<JSProxy> proxy = CreateJSProxyHandle(thread);
506     proxy->SetTarget(thread, linkedlist.GetTaggedValue());
507     callInfo->SetThis(proxy.GetTaggedValue());
508 
509     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
510         callInfo->SetCallArg(0, JSTaggedValue(i));
511         callInfo->SetCallArg(1, JSTaggedValue(i + 1));
512         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
513         ContainersLinkedList::Add(callInfo);
514         TestHelper::TearDownFrame(thread, prev);
515 
516         [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo);
517         JSTaggedValue retult = ContainersLinkedList::Length(callInfo);
518         TestHelper::TearDownFrame(thread, prev1);
519         EXPECT_EQ(retult, JSTaggedValue(i + 1));
520     }
521 }
522 
HWTEST_F_L0(ContainersLinkedListTest,ExceptionReturn1)523 HWTEST_F_L0(ContainersLinkedListTest, ExceptionReturn1)
524 {
525     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, Insert);
526     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, Get);
527     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, Add);
528     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, AddFirst);
529     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, GetFirst);
530     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, GetLast);
531     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, Length);
532     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, Clear);
533     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, Clone);
534     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, Has);
535     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, GetIndexOf);
536     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, GetLastIndexOf);
537 
538     JSHandle<JSAPILinkedList> linkedlist = CreateJSAPILinkedList();
539     {
540         auto callInfo = NewEmptyCallInfo(thread);
541         callInfo->SetThis(linkedlist.GetTaggedValue());
542         CONTAINERS_API_EXCEPTION_TEST(ContainersLinkedList, Insert, callInfo);
543     }
544     {
545         auto callInfo = NewEmptyCallInfo(thread);
546         callInfo->SetThis(linkedlist.GetTaggedValue());
547         CONTAINERS_API_EXCEPTION_TEST(ContainersLinkedList, Get, callInfo);
548     }
549 }
550 
HWTEST_F_L0(ContainersLinkedListTest,ExceptionReturn2)551 HWTEST_F_L0(ContainersLinkedListTest, ExceptionReturn2)
552 {
553     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, RemoveByIndex);
554     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, Set);
555     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, Remove);
556     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, RemoveFirst);
557     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, RemoveFirstFound);
558     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, RemoveLast);
559     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, RemoveLastFound);
560     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, ConvertToArray);
561     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLinkedList, ForEach);
562 
563     JSHandle<JSAPILinkedList> linkedlist = CreateJSAPILinkedList();
564     {
565         auto callInfo = NewEmptyCallInfo(thread);
566         callInfo->SetThis(linkedlist.GetTaggedValue());
567         CONTAINERS_API_EXCEPTION_TEST(ContainersLinkedList, RemoveByIndex, callInfo);
568     }
569     {
570         auto callInfo = NewEmptyCallInfo(thread);
571         callInfo->SetThis(linkedlist.GetTaggedValue());
572         CONTAINERS_API_EXCEPTION_TEST(ContainersLinkedList, Set, callInfo);
573     }
574 }
575 }  // namespace panda::test
576