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