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_lightweightmap.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_lightweightmap.h"
21 #include "ecmascript/js_api/js_api_lightweightmap_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 ContainersLightWeightMapTest : 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> key = GetCallArg(argv, 1);
66 [[maybe_unused]] JSHandle<JSTaggedValue> map = GetCallArg(argv, 2); // 2 means the secode arg
67
68 JSHandle<JSAPILightWeightMap> jsTreeMap(GetThis(argv));
69 JSAPILightWeightMap::Set(thread, jsTreeMap, key, value);
70 return JSTaggedValue::Undefined();
71 }
72 };
73 protected:
InitializeLightWeightMapConstructor()74 JSTaggedValue InitializeLightWeightMapConstructor()
75 {
76 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
77 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
78 JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
79 JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
80 JSHandle<JSTaggedValue> value =
81 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
82 auto objCallInfo =
83 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
84 objCallInfo->SetFunction(JSTaggedValue::Undefined());
85 objCallInfo->SetThis(value.GetTaggedValue());
86 objCallInfo->SetCallArg(
87 0, JSTaggedValue(static_cast<int>(ContainerTag::LightWeightMap))); // 0 means the argument
88 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
89 JSTaggedValue result = ContainersPrivate::Load(objCallInfo);
90 TestHelper::TearDownFrame(thread, prev);
91
92 return result;
93 }
94
CreateJSAPILightWeightMap()95 JSHandle<JSAPILightWeightMap> CreateJSAPILightWeightMap()
96 {
97 JSHandle<JSFunction> newTarget(thread, InitializeLightWeightMapConstructor());
98 auto objCallInfo =
99 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
100 objCallInfo->SetFunction(newTarget.GetTaggedValue());
101 objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
102 objCallInfo->SetThis(JSTaggedValue::Undefined());
103
104 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
105 JSTaggedValue result = ContainersLightWeightMap::LightWeightMapConstructor(objCallInfo);
106 TestHelper::TearDownFrame(thread, prev);
107 JSHandle<JSAPILightWeightMap> map(thread, result);
108 return map;
109 }
110 };
111
HWTEST_F_L0(ContainersLightWeightMapTest,LightWeightMapConstructor)112 HWTEST_F_L0(ContainersLightWeightMapTest, LightWeightMapConstructor)
113 {
114 InitializeLightWeightMapConstructor();
115 JSHandle<JSFunction> newTarget(thread, InitializeLightWeightMapConstructor());
116
117 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
118 objCallInfo->SetFunction(newTarget.GetTaggedValue());
119 objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
120 objCallInfo->SetThis(JSTaggedValue::Undefined());
121
122 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
123 JSTaggedValue result = ContainersLightWeightMap::LightWeightMapConstructor(objCallInfo);
124 TestHelper::TearDownFrame(thread, prev);
125
126 ASSERT_TRUE(result.IsJSAPILightWeightMap());
127 JSHandle<JSAPILightWeightMap> mapHandle(thread, result);
128 JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(mapHandle));
129 JSTaggedValue funcProto = newTarget->GetFunctionPrototype(thread);
130 ASSERT_EQ(resultProto, funcProto);
131
132 // test PlainArrayConstructor exception
133 objCallInfo->SetNewTarget(JSTaggedValue::Undefined());
134 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightMap, LightWeightMapConstructor, objCallInfo);
135 }
136
HWTEST_F_L0(ContainersLightWeightMapTest,SetAndGet)137 HWTEST_F_L0(ContainersLightWeightMapTest, SetAndGet)
138 {
139 constexpr uint32_t NODE_NUMBERS = 8;
140 JSHandle<JSAPILightWeightMap> lightWeightMap = CreateJSAPILightWeightMap();
141 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
142 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
143 callInfo->SetFunction(JSTaggedValue::Undefined());
144 callInfo->SetThis(lightWeightMap.GetTaggedValue());
145 callInfo->SetCallArg(0, JSTaggedValue(i));
146 callInfo->SetCallArg(1, JSTaggedValue(i + 1));
147
148 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
149 JSTaggedValue result = ContainersLightWeightMap::Set(callInfo);
150 ASSERT_TRUE(result.IsJSAPILightWeightMap());
151 TestHelper::TearDownFrame(thread, prev);
152 uint32_t length = lightWeightMap->GetLength();
153 EXPECT_EQ(length, i + 1);
154 }
155
156 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
157 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
158 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
159 std::string myKey("mykey");
160 std::string myValue("myvalue");
161 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
162 std::string ikey = myKey + std::to_string(i);
163 std::string ivalue = myValue + std::to_string(i);
164 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
165 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
166
167 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
168 callInfo->SetFunction(JSTaggedValue::Undefined());
169 callInfo->SetThis(lightWeightMap.GetTaggedValue());
170 callInfo->SetCallArg(0, key.GetTaggedValue());
171 callInfo->SetCallArg(1, value.GetTaggedValue());
172 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
173 JSTaggedValue result = ContainersLightWeightMap::Set(callInfo);
174 TestHelper::TearDownFrame(thread, prev);
175 uint32_t length = lightWeightMap->GetLength();
176 ASSERT_TRUE(result.IsJSAPILightWeightMap());
177 EXPECT_EQ(length, NODE_NUMBERS + 1 + i);
178 }
179
180 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
181 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
182 callInfo->SetFunction(JSTaggedValue::Undefined());
183 callInfo->SetThis(lightWeightMap.GetTaggedValue());
184 callInfo->SetCallArg(0, JSTaggedValue(i));
185
186 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
187 JSTaggedValue result = ContainersLightWeightMap::Get(callInfo);
188 TestHelper::TearDownFrame(thread, prev);
189 EXPECT_EQ(result, JSTaggedValue(i + 1));
190 }
191
192 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
193 std::string ikey = myKey + std::to_string(i);
194 std::string ivalue = myValue + std::to_string(i);
195 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
196 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
197
198 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
199 callInfo->SetFunction(JSTaggedValue::Undefined());
200 callInfo->SetThis(lightWeightMap.GetTaggedValue());
201 callInfo->SetCallArg(0, key.GetTaggedValue());
202 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
203 JSTaggedValue result = ContainersLightWeightMap::Get(callInfo);
204 TestHelper::TearDownFrame(thread, prev);
205 EXPECT_EQ(result, value.GetTaggedValue());
206 }
207 }
208
HWTEST_F_L0(ContainersLightWeightMapTest,Remove)209 HWTEST_F_L0(ContainersLightWeightMapTest, Remove)
210 {
211 constexpr uint32_t NODE_NUMBERS = 8;
212 JSHandle<JSAPILightWeightMap> lightWeightMap = CreateJSAPILightWeightMap();
213 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
214 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
215 callInfo->SetFunction(JSTaggedValue::Undefined());
216 callInfo->SetThis(lightWeightMap.GetTaggedValue());
217 callInfo->SetCallArg(0, JSTaggedValue(i));
218 callInfo->SetCallArg(1, JSTaggedValue(i + 1));
219
220 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
221 JSTaggedValue result = ContainersLightWeightMap::Set(callInfo);
222 ASSERT_TRUE(result.IsJSAPILightWeightMap());
223 TestHelper::TearDownFrame(thread, prev);
224 uint32_t length = lightWeightMap->GetLength();
225 EXPECT_EQ(length, i + 1);
226 }
227
228 {
229 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
230 callInfo->SetFunction(JSTaggedValue::Undefined());
231 callInfo->SetThis(lightWeightMap.GetTaggedValue());
232 callInfo->SetCallArg(0, JSTaggedValue(NODE_NUMBERS / 2));
233
234 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
235 JSTaggedValue rvalue = ContainersLightWeightMap::Remove(callInfo);
236 TestHelper::TearDownFrame(thread, prev);
237 EXPECT_EQ(rvalue, JSTaggedValue(NODE_NUMBERS / 2 + 1));
238 uint32_t len = lightWeightMap->GetLength();
239 EXPECT_EQ(len, NODE_NUMBERS - 1);
240 }
241
242 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
243 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
244 callInfo->SetFunction(JSTaggedValue::Undefined());
245 callInfo->SetThis(lightWeightMap.GetTaggedValue());
246 callInfo->SetCallArg(0, JSTaggedValue(i));
247 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
248 JSTaggedValue keyResult = ContainersLightWeightMap::HasKey(callInfo);
249 TestHelper::TearDownFrame(thread, prev);
250 if (NODE_NUMBERS / 2 == i) {
251 EXPECT_EQ(keyResult, JSTaggedValue::False());
252 } else {
253 EXPECT_EQ(keyResult, JSTaggedValue::True());
254 }
255
256 callInfo->SetFunction(JSTaggedValue::Undefined());
257 callInfo->SetThis(lightWeightMap.GetTaggedValue());
258 callInfo->SetCallArg(0, JSTaggedValue(i + 1));
259 prev = TestHelper::SetupFrame(thread, callInfo);
260 JSTaggedValue valueResult = ContainersLightWeightMap::HasValue(callInfo);
261 TestHelper::TearDownFrame(thread, prev);
262 if (NODE_NUMBERS / 2 == i) {
263 EXPECT_EQ(valueResult, JSTaggedValue::False());
264 } else {
265 EXPECT_EQ(valueResult, JSTaggedValue::True());
266 }
267 }
268 }
269
HWTEST_F_L0(ContainersLightWeightMapTest,Clear)270 HWTEST_F_L0(ContainersLightWeightMapTest, Clear)
271 {
272 constexpr uint32_t NODE_NUMBERS = 8;
273 JSHandle<JSAPILightWeightMap> lightWeightMap = CreateJSAPILightWeightMap();
274 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
275 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
276 callInfo->SetFunction(JSTaggedValue::Undefined());
277 callInfo->SetThis(lightWeightMap.GetTaggedValue());
278 callInfo->SetCallArg(0, JSTaggedValue(i));
279 callInfo->SetCallArg(1, JSTaggedValue(i));
280
281 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
282 JSTaggedValue result = ContainersLightWeightMap::Set(callInfo);
283 TestHelper::TearDownFrame(thread, prev);
284 uint32_t length = lightWeightMap->GetLength();
285 ASSERT_TRUE(result.IsJSAPILightWeightMap());
286 EXPECT_EQ(length, i + 1);
287 }
288
289 {
290 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
291 callInfo->SetFunction(JSTaggedValue::Undefined());
292 callInfo->SetThis(lightWeightMap.GetTaggedValue());
293
294 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
295 ContainersLightWeightMap::Clear(callInfo);
296 TestHelper::TearDownFrame(thread, prev);
297 uint32_t len = lightWeightMap->GetLength();
298 uint32_t empty = 0;
299 EXPECT_EQ(len, empty);
300 }
301 }
302
HWTEST_F_L0(ContainersLightWeightMapTest,ToString)303 HWTEST_F_L0(ContainersLightWeightMapTest, ToString)
304 {
305 constexpr uint32_t NODE_NUMBERS = 8;
306 JSHandle<JSAPILightWeightMap> lightWeightMap = CreateJSAPILightWeightMap();
307 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
308 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
309 callInfo->SetFunction(JSTaggedValue::Undefined());
310 callInfo->SetThis(lightWeightMap.GetTaggedValue());
311 callInfo->SetCallArg(0, JSTaggedValue(i));
312 callInfo->SetCallArg(1, JSTaggedValue(i));
313
314 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
315 JSTaggedValue result = ContainersLightWeightMap::Set(callInfo);
316 TestHelper::TearDownFrame(thread, prev);
317 uint32_t length = lightWeightMap->GetLength();
318 ASSERT_TRUE(result.IsJSAPILightWeightMap());
319 EXPECT_EQ(length, i + 1);
320 }
321
322 {
323 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
324 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
325 callInfo->SetFunction(JSTaggedValue::Undefined());
326 callInfo->SetThis(lightWeightMap.GetTaggedValue());
327
328 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
329 JSTaggedValue res = ContainersLightWeightMap::ToString(callInfo);
330 JSHandle<JSTaggedValue> resHandle(thread, res);
331 TestHelper::TearDownFrame(thread, prev);
332 std::string myString("0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7");
333 JSHandle<JSTaggedValue> expectResHandle(thread, factory->NewFromStdString(myString).GetTaggedValue());
334 EXPECT_TRUE(JSTaggedValue::Equal(thread, resHandle, expectResHandle));
335 }
336 }
337
338 // LightWeightMap.setAll(map)
HWTEST_F_L0(ContainersLightWeightMapTest,SetAll)339 HWTEST_F_L0(ContainersLightWeightMapTest, SetAll)
340 {
341 constexpr uint32_t NODE_NUMBERS = 8;
342 JSHandle<JSAPILightWeightMap> oldLightWeightMap = CreateJSAPILightWeightMap();
343 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
344 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
345 callInfo->SetFunction(JSTaggedValue::Undefined());
346 callInfo->SetThis(oldLightWeightMap.GetTaggedValue());
347 callInfo->SetCallArg(0, JSTaggedValue(i));
348 callInfo->SetCallArg(1, JSTaggedValue(i));
349
350 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
351 JSTaggedValue result = ContainersLightWeightMap::Set(callInfo);
352 TestHelper::TearDownFrame(thread, prev);
353 uint32_t length = oldLightWeightMap->GetLength();
354 ASSERT_TRUE(result.IsJSAPILightWeightMap());
355 EXPECT_EQ(length, i + 1);
356 }
357
358 JSHandle<JSAPILightWeightMap> LightWeightMap = CreateJSAPILightWeightMap();
359 {
360 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
361 callInfo->SetFunction(JSTaggedValue::Undefined());
362 callInfo->SetThis(LightWeightMap.GetTaggedValue());
363 callInfo->SetCallArg(0, oldLightWeightMap.GetTaggedValue());
364
365 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
366 ContainersLightWeightMap::SetAll(callInfo);
367 TestHelper::TearDownFrame(thread, prev);
368 uint32_t length = LightWeightMap->GetLength();
369 EXPECT_EQ(length, NODE_NUMBERS);
370 }
371
372 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
373 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
374 callInfo->SetFunction(JSTaggedValue::Undefined());
375 callInfo->SetThis(LightWeightMap.GetTaggedValue());
376 callInfo->SetCallArg(0, JSTaggedValue(i));
377 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
378 JSTaggedValue keyResult = ContainersLightWeightMap::HasKey(callInfo);
379 TestHelper::TearDownFrame(thread, prev);
380 EXPECT_EQ(keyResult, JSTaggedValue::True());
381
382 prev = TestHelper::SetupFrame(thread, callInfo);
383 JSTaggedValue valueResult = ContainersLightWeightMap::HasValue(callInfo);
384 TestHelper::TearDownFrame(thread, prev);
385 EXPECT_EQ(valueResult, JSTaggedValue::True());
386 }
387 }
388
HWTEST_F_L0(ContainersLightWeightMapTest,KeysAndValuesAndEntries)389 HWTEST_F_L0(ContainersLightWeightMapTest, KeysAndValuesAndEntries)
390 {
391 constexpr uint32_t NODE_NUMBERS = 8;
392 JSHandle<JSAPILightWeightMap> lightWeightMap = CreateJSAPILightWeightMap();
393 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
394 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
395 callInfo->SetFunction(JSTaggedValue::Undefined());
396 callInfo->SetThis(lightWeightMap.GetTaggedValue());
397 callInfo->SetCallArg(0, JSTaggedValue(i));
398 callInfo->SetCallArg(1, JSTaggedValue(i));
399
400 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
401 JSTaggedValue result = ContainersLightWeightMap::Set(callInfo);
402 TestHelper::TearDownFrame(thread, prev);
403 uint32_t length = lightWeightMap->GetLength();
404 ASSERT_TRUE(result.IsJSAPILightWeightMap());
405 EXPECT_EQ(length, i + 1);
406 }
407
408 JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
409 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
410 callInfo->SetFunction(JSTaggedValue::Undefined());
411 callInfo->SetThis(lightWeightMap.GetTaggedValue());
412
413 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
414 JSHandle<JSTaggedValue> iterKeys(thread, ContainersLightWeightMap::Keys(callInfo));
415 TestHelper::TearDownFrame(thread, prev);
416 EXPECT_TRUE(iterKeys->IsJSAPILightWeightMapIterator());
417 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
418 callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
419 callInfo->SetFunction(JSTaggedValue::Undefined());
420 callInfo->SetThis(iterKeys.GetTaggedValue());
421
422 prev = TestHelper::SetupFrame(thread, callInfo);
423 result.Update(JSAPILightWeightMapIterator::Next(callInfo));
424 TestHelper::TearDownFrame(thread, prev);
425 JSHandle<JSTaggedValue> keyHandle = JSIterator::IteratorValue(thread, result);
426
427 callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
428 callInfo->SetFunction(JSTaggedValue::Undefined());
429 callInfo->SetThis(lightWeightMap.GetTaggedValue());
430 callInfo->SetCallArg(0, keyHandle.GetTaggedValue());
431
432 prev = TestHelper::SetupFrame(thread, callInfo);
433 JSTaggedValue keyResult = ContainersLightWeightMap::HasKey(callInfo);
434 TestHelper::TearDownFrame(thread, prev);
435 EXPECT_EQ(keyResult, JSTaggedValue::True());
436 }
437
438 // test values
439 callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
440 callInfo->SetFunction(JSTaggedValue::Undefined());
441 callInfo->SetThis(lightWeightMap.GetTaggedValue());
442 prev = TestHelper::SetupFrame(thread, callInfo);
443 JSHandle<JSTaggedValue> iterValues(thread, ContainersLightWeightMap::Values(callInfo));
444 TestHelper::TearDownFrame(thread, prev);
445 EXPECT_TRUE(iterValues->IsJSAPILightWeightMapIterator());
446
447 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
448 callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
449 callInfo->SetFunction(JSTaggedValue::Undefined());
450 callInfo->SetThis(iterValues.GetTaggedValue());
451
452 prev = TestHelper::SetupFrame(thread, callInfo);
453 result.Update(JSAPILightWeightMapIterator::Next(callInfo));
454 TestHelper::TearDownFrame(thread, prev);
455 JSHandle<JSTaggedValue> ValueHandle = JSIterator::IteratorValue(thread, result);
456
457 callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
458 callInfo->SetFunction(JSTaggedValue::Undefined());
459 callInfo->SetThis(lightWeightMap.GetTaggedValue());
460 callInfo->SetCallArg(0, ValueHandle.GetTaggedValue());
461
462 prev = TestHelper::SetupFrame(thread, callInfo);
463 JSTaggedValue valueResult = ContainersLightWeightMap::HasValue(callInfo);
464 TestHelper::TearDownFrame(thread, prev);
465 EXPECT_EQ(valueResult, JSTaggedValue::True());
466 }
467 // test entries
468 callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
469 callInfo->SetFunction(JSTaggedValue::Undefined());
470 callInfo->SetThis(lightWeightMap.GetTaggedValue());
471 prev = TestHelper::SetupFrame(thread, callInfo);
472 JSHandle<JSTaggedValue> iter(thread, ContainersLightWeightMap::Entries(callInfo));
473 TestHelper::TearDownFrame(thread, prev);
474 EXPECT_TRUE(iter->IsJSAPILightWeightMapIterator());
475
476 JSHandle<JSTaggedValue> first(thread, JSTaggedValue(0));
477 JSHandle<JSTaggedValue> second(thread, JSTaggedValue(1));
478 JSMutableHandle<JSTaggedValue> entries(thread, JSTaggedValue::Undefined());
479 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
480 callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
481 callInfo->SetFunction(JSTaggedValue::Undefined());
482 callInfo->SetThis(iter.GetTaggedValue());
483
484 prev = TestHelper::SetupFrame(thread, callInfo);
485 result.Update(JSAPILightWeightMapIterator::Next(callInfo));
486 TestHelper::TearDownFrame(thread, prev);
487 entries.Update(JSIterator::IteratorValue(thread, result).GetTaggedValue());
488
489 int entriesKey = JSObject::GetProperty(thread, entries, first).GetValue()->GetInt();
490 callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
491 callInfo->SetFunction(JSTaggedValue::Undefined());
492 callInfo->SetThis(lightWeightMap.GetTaggedValue());
493 callInfo->SetCallArg(0, JSTaggedValue(entriesKey));
494 prev = TestHelper::SetupFrame(thread, callInfo);
495 JSTaggedValue keyResult = ContainersLightWeightMap::HasKey(callInfo);
496 TestHelper::TearDownFrame(thread, prev);
497 EXPECT_EQ(keyResult, JSTaggedValue::True());
498
499 int entriesValue = JSObject::GetProperty(thread, entries, second).GetValue()->GetInt();
500 callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
501 callInfo->SetFunction(JSTaggedValue::Undefined());
502 callInfo->SetThis(lightWeightMap.GetTaggedValue());
503 callInfo->SetCallArg(0, JSTaggedValue(entriesValue));
504 prev = TestHelper::SetupFrame(thread, callInfo);
505 JSTaggedValue valueResult = ContainersLightWeightMap::HasValue(callInfo);
506 TestHelper::TearDownFrame(thread, prev);
507 EXPECT_EQ(valueResult, JSTaggedValue::True());
508 }
509 }
510
511 // LightWeightMap.ForEach(callbackfn, this)
HWTEST_F_L0(ContainersLightWeightMapTest,ForEach)512 HWTEST_F_L0(ContainersLightWeightMapTest, ForEach)
513 {
514 constexpr uint32_t NODE_NUMBERS = 8;
515 JSHandle<JSAPILightWeightMap> lightWeightMap = CreateJSAPILightWeightMap();
516 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
517 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
518 callInfo->SetFunction(JSTaggedValue::Undefined());
519 callInfo->SetThis(lightWeightMap.GetTaggedValue());
520 callInfo->SetCallArg(0, JSTaggedValue(i));
521 callInfo->SetCallArg(1, JSTaggedValue(i));
522
523 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
524 JSTaggedValue result = ContainersLightWeightMap::Set(callInfo);
525 TestHelper::TearDownFrame(thread, prev);
526 uint32_t len = lightWeightMap->GetLength();
527 ASSERT_TRUE(result.IsJSAPILightWeightMap());
528 EXPECT_EQ(len, i + 1);
529 }
530 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
531 JSHandle<JSAPILightWeightMap> newLightWeightMap = CreateJSAPILightWeightMap();
532 {
533 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
534 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
535 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
536 callInfo->SetFunction(JSTaggedValue::Undefined());
537 callInfo->SetThis(lightWeightMap.GetTaggedValue());
538 callInfo->SetCallArg(0, func.GetTaggedValue());
539 callInfo->SetCallArg(1, newLightWeightMap.GetTaggedValue());
540
541 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
542 ContainersLightWeightMap::ForEach(callInfo);
543 TestHelper::TearDownFrame(thread, prev);
544 }
545 EXPECT_EQ(newLightWeightMap->GetLength(), NODE_NUMBERS);
546 EXPECT_EQ(lightWeightMap->GetLength(), NODE_NUMBERS);
547
548
549 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
550 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
551 callInfo->SetFunction(JSTaggedValue::Undefined());
552 callInfo->SetThis(newLightWeightMap.GetTaggedValue());
553 callInfo->SetCallArg(0, JSTaggedValue(i));
554
555 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
556 JSTaggedValue result = ContainersLightWeightMap::HasKey(callInfo);
557 TestHelper::TearDownFrame(thread, prev);
558 EXPECT_EQ(result, JSTaggedValue::True());
559 }
560 }
561
HWTEST_F_L0(ContainersLightWeightMapTest,ProxyOfLength)562 HWTEST_F_L0(ContainersLightWeightMapTest, ProxyOfLength)
563 {
564 constexpr uint32_t NODE_NUMBERS = 8;
565 JSHandle<JSAPILightWeightMap> lightWeightMap = CreateJSAPILightWeightMap();
566 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
567 callInfo->SetFunction(JSTaggedValue::Undefined());
568 JSHandle<JSProxy> proxy = CreateJSProxyHandle(thread);
569 proxy->SetTarget(thread, lightWeightMap.GetTaggedValue());
570 callInfo->SetThis(proxy.GetTaggedValue());
571
572 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
573 callInfo->SetCallArg(0, JSTaggedValue(i));
574 callInfo->SetCallArg(1, JSTaggedValue(i + 1));
575 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
576 ContainersLightWeightMap::Set(callInfo);
577 TestHelper::TearDownFrame(thread, prev);
578
579 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo);
580 JSTaggedValue retult = ContainersLightWeightMap::Length(callInfo);
581 TestHelper::TearDownFrame(thread, prev1);
582 EXPECT_EQ(retult, JSTaggedValue(i + 1));
583 }
584 }
585
HWTEST_F_L0(ContainersLightWeightMapTest,ExceptionReturn1)586 HWTEST_F_L0(ContainersLightWeightMapTest, ExceptionReturn1)
587 {
588 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, HasAll);
589 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, IncreaseCapacityTo);
590 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, Length);
591 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, HasKey);
592 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, HasValue);
593 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, Get);
594 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, GetIndexOfKey);
595 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, GetIndexOfValue);
596 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, IsEmpty);
597
598 JSHandle<JSAPILightWeightMap> lightWeightMap = CreateJSAPILightWeightMap();
599 {
600 auto callInfo = NewEmptyCallInfo(thread);
601 callInfo->SetThis(lightWeightMap.GetTaggedValue());
602 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightMap, HasAll, callInfo);
603 }
604 {
605 auto callInfo = NewEmptyCallInfo(thread);
606 callInfo->SetThis(lightWeightMap.GetTaggedValue());
607 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightMap, IncreaseCapacityTo, callInfo);
608 }
609 }
610
HWTEST_F_L0(ContainersLightWeightMapTest,ExceptionReturn2)611 HWTEST_F_L0(ContainersLightWeightMapTest, ExceptionReturn2)
612 {
613 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, GetKeyAt);
614 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, SetAll);
615 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, RemoveAt);
616 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, SetValueAt);
617 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, GetValueAt);
618 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, Set);
619 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, Remove);
620 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, Clear);
621 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, ForEach);
622 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, ToString);
623 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, GetIndexOfValue);
624 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightMap, IsEmpty);
625
626 JSHandle<JSAPILightWeightMap> lightWeightMap = CreateJSAPILightWeightMap();
627 {
628 auto callInfo = NewEmptyCallInfo(thread);
629 callInfo->SetThis(lightWeightMap.GetTaggedValue());
630 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightMap, GetKeyAt, callInfo);
631 }
632 {
633 auto callInfo = NewEmptyCallInfo(thread);
634 callInfo->SetThis(lightWeightMap.GetTaggedValue());
635 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightMap, SetAll, callInfo);
636 }
637 {
638 auto callInfo = NewEmptyCallInfo(thread);
639 callInfo->SetThis(lightWeightMap.GetTaggedValue());
640 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightMap, RemoveAt, callInfo);
641 }
642 {
643 auto callInfo = NewEmptyCallInfo(thread);
644 callInfo->SetThis(lightWeightMap.GetTaggedValue());
645 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightMap, SetValueAt, callInfo);
646 }
647 {
648 auto callInfo = NewEmptyCallInfo(thread);
649 callInfo->SetThis(lightWeightMap.GetTaggedValue());
650 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightMap, GetValueAt, callInfo);
651 }
652 }
653 } // namespace panda::test
654