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