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_private.h"
17 #include "ecmascript/containers/containers_hashmap.h"
18 #include "ecmascript/ecma_runtime_call_info.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_handle.h"
21 #include "ecmascript/js_tagged_value-inl.h"
22 #include "ecmascript/js_thread.h"
23 #include "ecmascript/js_api/js_api_hashmap.h"
24 #include "ecmascript/js_api/js_api_hashmap_iterator.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 ContainersHashMapTest : 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 JSHandle<JSTaggedValue> map = GetCallArg(argv, 2); // 2 means the secode arg
67 if (!map->IsUndefined()) {
68 if (value->IsNumber()) {
69 JSHandle<JSTaggedValue> newValue(thread, JSTaggedValue(value->GetInt() * 2)); // 2 means mul by 2
70 JSAPIHashMap::Set(thread, JSHandle<JSAPIHashMap>::Cast(map), key, newValue);
71 }
72 }
73 JSHandle<JSAPIHashMap> jsHashMap(GetThis(argv));
74 JSAPIHashMap::Set(thread, jsHashMap, key, value);
75 return JSTaggedValue::Undefined();
76 }
77 };
78 protected:
InitializeHashMapConstructor()79 JSTaggedValue InitializeHashMapConstructor()
80 {
81 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
82 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
83
84 JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
85 JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
86 JSHandle<JSTaggedValue> value =
87 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
88
89 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
90 objCallInfo->SetFunction(JSTaggedValue::Undefined());
91 objCallInfo->SetThis(value.GetTaggedValue());
92 objCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(ContainerTag::HashMap)));
93 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
94 JSTaggedValue result = ContainersPrivate::Load(objCallInfo);
95 TestHelper::TearDownFrame(thread, prev);
96
97 return result;
98 }
99
CreateJSAPIHashMap()100 JSHandle<JSAPIHashMap> CreateJSAPIHashMap()
101 {
102 JSHandle<JSFunction> newTarget(thread, InitializeHashMapConstructor());
103 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
104 objCallInfo->SetFunction(newTarget.GetTaggedValue());
105 objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
106 objCallInfo->SetThis(JSTaggedValue::Undefined());
107
108 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
109 JSTaggedValue result = ContainersHashMap::HashMapConstructor(objCallInfo);
110 TestHelper::TearDownFrame(thread, prev);
111 JSHandle<JSAPIHashMap> map(thread, result);
112 return map;
113 }
114 };
115
116 // new HashMap()
HWTEST_F_L0(ContainersHashMapTest,HashMapConstructor)117 HWTEST_F_L0(ContainersHashMapTest, HashMapConstructor)
118 {
119 InitializeHashMapConstructor();
120 JSHandle<JSFunction> newTarget(thread, InitializeHashMapConstructor());
121
122 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
123 objCallInfo->SetFunction(newTarget.GetTaggedValue());
124 objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
125 objCallInfo->SetThis(JSTaggedValue::Undefined());
126
127 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
128 JSTaggedValue result = ContainersHashMap::HashMapConstructor(objCallInfo);
129 TestHelper::TearDownFrame(thread, prev);
130
131 ASSERT_TRUE(result.IsJSAPIHashMap());
132 JSHandle<JSAPIHashMap> mapHandle(thread, result);
133 JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(mapHandle));
134 JSTaggedValue funcProto = newTarget->GetFunctionPrototype();
135 ASSERT_EQ(resultProto, funcProto);
136 int size = mapHandle->GetSize();
137 ASSERT_EQ(size, 0);
138
139 // test HashMapConstructor exception
140 objCallInfo->SetNewTarget(JSTaggedValue::Undefined());
141 CONTAINERS_API_EXCEPTION_TEST(ContainersHashMap, HashMapConstructor, objCallInfo);
142 }
143
144 // hashmap.set(key, value), hashmap.get(key)
HWTEST_F_L0(ContainersHashMapTest,SetAndGet)145 HWTEST_F_L0(ContainersHashMapTest, SetAndGet)
146 {
147 constexpr uint32_t NODE_NUMBERS = 8;
148 JSHandle<JSAPIHashMap> tMap = CreateJSAPIHashMap();
149 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
150 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
151 callInfo->SetFunction(JSTaggedValue::Undefined());
152 callInfo->SetThis(tMap.GetTaggedValue());
153 callInfo->SetCallArg(0, JSTaggedValue(i));
154 callInfo->SetCallArg(1, JSTaggedValue(i));
155
156 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
157 JSTaggedValue result = ContainersHashMap::Set(callInfo);
158 TestHelper::TearDownFrame(thread, prev);
159 EXPECT_TRUE(result.IsJSAPIHashMap());
160 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
161 }
162
163 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
164 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
165 callInfo->SetFunction(JSTaggedValue::Undefined());
166 callInfo->SetThis(tMap.GetTaggedValue());
167 callInfo->SetCallArg(0, JSTaggedValue(i));
168
169 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
170 JSTaggedValue result = ContainersHashMap::Get(callInfo);
171 TestHelper::TearDownFrame(thread, prev);
172 EXPECT_EQ(result, JSTaggedValue(i));
173 }
174 }
175
176 // hashmap.hasKey(key), hashmap.hasValue(value)
HWTEST_F_L0(ContainersHashMapTest,HasKeyAndHasValue)177 HWTEST_F_L0(ContainersHashMapTest, HasKeyAndHasValue)
178 {
179 constexpr uint32_t NODE_NUMBERS = 8;
180 JSHandle<JSAPIHashMap> tMap = CreateJSAPIHashMap();
181 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
182 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
183 callInfo->SetFunction(JSTaggedValue::Undefined());
184 callInfo->SetThis(tMap.GetTaggedValue());
185 callInfo->SetCallArg(0, JSTaggedValue(i));
186 callInfo->SetCallArg(1, JSTaggedValue(i));
187
188 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
189 JSTaggedValue result = ContainersHashMap::Set(callInfo);
190 TestHelper::TearDownFrame(thread, prev);
191 EXPECT_TRUE(result.IsJSAPIHashMap());
192 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
193 }
194
195 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
196 // test hasKey
197 {
198 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
199 callInfo->SetFunction(JSTaggedValue::Undefined());
200 callInfo->SetThis(tMap.GetTaggedValue());
201 callInfo->SetCallArg(0, JSTaggedValue(i));
202
203 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
204 JSTaggedValue result = ContainersHashMap::HasKey(callInfo);
205 TestHelper::TearDownFrame(thread, prev);
206 EXPECT_EQ(result, JSTaggedValue::True());
207 }
208 // test hasValue
209 {
210 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
211 callInfo->SetFunction(JSTaggedValue::Undefined());
212 callInfo->SetThis(tMap.GetTaggedValue());
213 callInfo->SetCallArg(0, JSTaggedValue(i));
214
215 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
216 JSTaggedValue result = ContainersHashMap::HasValue(callInfo);
217 TestHelper::TearDownFrame(thread, prev);
218 EXPECT_EQ(result, JSTaggedValue::True());
219 }
220 }
221
222 // test add string
223 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
224 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
225 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
226 std::string myKey("mykey");
227 std::string myValue("myvalue");
228 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
229 std::string iKey = myKey + std::to_string(i);
230 std::string iValue = myValue + std::to_string(i);
231 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
232 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
233
234 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
235 callInfo->SetFunction(JSTaggedValue::Undefined());
236 callInfo->SetThis(tMap.GetTaggedValue());
237 callInfo->SetCallArg(0, key.GetTaggedValue());
238 callInfo->SetCallArg(1, value.GetTaggedValue());
239 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
240 JSTaggedValue result = ContainersHashMap::Set(callInfo);
241 TestHelper::TearDownFrame(thread, prev);
242 EXPECT_TRUE(result.IsJSAPIHashMap());
243 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
244 }
245
246 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
247 // test hasKey
248 {
249 std::string iKey = myKey + std::to_string(i);
250 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
251 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
252 callInfo->SetFunction(JSTaggedValue::Undefined());
253 callInfo->SetThis(tMap.GetTaggedValue());
254 callInfo->SetCallArg(0, key.GetTaggedValue());
255
256 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
257 JSTaggedValue result = ContainersHashMap::HasKey(callInfo);
258 TestHelper::TearDownFrame(thread, prev);
259 EXPECT_EQ(result, JSTaggedValue::True());
260 }
261 // test hasValue
262 {
263 std::string iValue = myValue + std::to_string(i);
264 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
265 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
266 callInfo->SetFunction(JSTaggedValue::Undefined());
267 callInfo->SetThis(tMap.GetTaggedValue());
268 callInfo->SetCallArg(0, value.GetTaggedValue());
269
270 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
271 JSTaggedValue result = ContainersHashMap::HasValue(callInfo);
272 TestHelper::TearDownFrame(thread, prev);
273 EXPECT_EQ(result, JSTaggedValue::True());
274 }
275 }
276 }
277
278 // hashmap.keys(), hashmap.values(), hashmap.entries()
HWTEST_F_L0(ContainersHashMapTest,KeysAndValuesAndEntries)279 HWTEST_F_L0(ContainersHashMapTest, KeysAndValuesAndEntries)
280 {
281 constexpr uint32_t NODE_NUMBERS = 8;
282 JSHandle<JSAPIHashMap> tMap = CreateJSAPIHashMap();
283 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
284 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
285 callInfo->SetFunction(JSTaggedValue::Undefined());
286 callInfo->SetThis(tMap.GetTaggedValue());
287 callInfo->SetCallArg(0, JSTaggedValue(i));
288 callInfo->SetCallArg(1, JSTaggedValue(i));
289
290 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
291 JSTaggedValue result2 = ContainersHashMap::Set(callInfo);
292 TestHelper::TearDownFrame(thread, prev);
293 EXPECT_TRUE(result2.IsJSAPIHashMap());
294 EXPECT_EQ(JSAPIHashMap::Cast(result2.GetTaggedObject())->GetSize(), i + 1);
295 }
296
297 // test keys
298 auto callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
299 callInfo1->SetFunction(JSTaggedValue::Undefined());
300 callInfo1->SetThis(tMap.GetTaggedValue());
301 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo1);
302 JSHandle<JSTaggedValue> iterKeys(thread, ContainersHashMap::Keys(callInfo1));
303 TestHelper::TearDownFrame(thread, prev);
304 EXPECT_TRUE(iterKeys->IsJSAPIHashMapIterator());
305
306 JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
307 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
308 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
309 callInfo->SetFunction(JSTaggedValue::Undefined());
310 callInfo->SetThis(iterKeys.GetTaggedValue());
311
312 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo);
313 result.Update(JSAPIHashMapIterator::Next(callInfo));
314 TestHelper::TearDownFrame(thread, prev1);
315 JSHandle<JSTaggedValue> iterKey = JSIterator::IteratorValue(thread, result);
316 JSTaggedValue keyFlag = tMap->HasKey(thread, iterKey.GetTaggedValue());
317 EXPECT_EQ(JSTaggedValue::True(), keyFlag);
318 }
319
320 // test values
321 callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
322 callInfo1->SetFunction(JSTaggedValue::Undefined());
323 callInfo1->SetThis(tMap.GetTaggedValue());
324 prev = TestHelper::SetupFrame(thread, callInfo1);
325 JSHandle<JSTaggedValue> iterValues(thread, ContainersHashMap::Values(callInfo1));
326 TestHelper::TearDownFrame(thread, prev);
327 EXPECT_TRUE(iterValues->IsJSAPIHashMapIterator());
328
329 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
330 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
331 callInfo->SetFunction(JSTaggedValue::Undefined());
332 callInfo->SetThis(iterValues.GetTaggedValue());
333
334 [[maybe_unused]] auto prev2 = TestHelper::SetupFrame(thread, callInfo);
335 result.Update(JSAPIHashMapIterator::Next(callInfo));
336 TestHelper::TearDownFrame(thread, prev2);
337 JSHandle<JSTaggedValue> iterValue = JSIterator::IteratorValue(thread, result);
338 JSTaggedValue valueFlag = JSAPIHashMap::HasValue(thread, tMap, iterValue);
339 EXPECT_EQ(JSTaggedValue::True(), valueFlag);
340 }
341
342 // test add string
343 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
344 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
345 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
346 std::string myKey("mykey");
347 std::string myValue("myvalue");
348 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
349 std::string iKey = myKey + std::to_string(i);
350 std::string iValue = myValue + std::to_string(i);
351 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
352 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
353
354 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
355 callInfo->SetFunction(JSTaggedValue::Undefined());
356 callInfo->SetThis(tMap.GetTaggedValue());
357 callInfo->SetCallArg(0, key.GetTaggedValue());
358 callInfo->SetCallArg(1, value.GetTaggedValue());
359 [[maybe_unused]] auto prev3 = TestHelper::SetupFrame(thread, callInfo);
360 JSTaggedValue result1 = ContainersHashMap::Set(callInfo);
361 TestHelper::TearDownFrame(thread, prev3);
362 EXPECT_TRUE(result1.IsJSAPIHashMap());
363 EXPECT_EQ(JSAPIHashMap::Cast(result1.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
364 }
365 EXPECT_EQ(tMap->GetSize(), NODE_NUMBERS * 2);
366 // test keys after add
367 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
368 std::string iKey = myKey + std::to_string(i);
369 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
370 JSTaggedValue keyFlag = tMap->HasKey(thread, key.GetTaggedValue());
371 EXPECT_EQ(JSTaggedValue::True(), keyFlag);
372 }
373 // test values after add
374 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
375 std::string iValue = myValue + std::to_string(i);
376 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
377 JSTaggedValue valueFlag = JSAPIHashMap::HasValue(thread, tMap, value);
378 EXPECT_EQ(JSTaggedValue::True(), valueFlag);
379 }
380
381 // test entries
382 {
383 auto callInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
384 callInfo2->SetFunction(JSTaggedValue::Undefined());
385 callInfo2->SetThis(tMap.GetTaggedValue());
386 [[maybe_unused]] auto prev6 = TestHelper::SetupFrame(thread, callInfo2);
387 JSHandle<JSTaggedValue> iter(thread, ContainersHashMap::Entries(callInfo2));
388 TestHelper::TearDownFrame(thread, prev6);
389 EXPECT_TRUE(iter->IsJSAPIHashMapIterator());
390
391 JSHandle<JSTaggedValue> first(thread, JSTaggedValue(0));
392 JSHandle<JSTaggedValue> second(thread, JSTaggedValue(1));
393 JSMutableHandle<JSTaggedValue> result3(thread, JSTaggedValue::Undefined());
394 JSMutableHandle<JSTaggedValue> entries(thread, JSTaggedValue::Undefined());
395 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
396 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
397 callInfo->SetFunction(JSTaggedValue::Undefined());
398 callInfo->SetThis(iter.GetTaggedValue());
399
400 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo);
401 result3.Update(JSAPIHashMapIterator::Next(callInfo));
402 TestHelper::TearDownFrame(thread, prev1);
403 entries.Update(JSIterator::IteratorValue(thread, result3).GetTaggedValue());
404 JSHandle<JSTaggedValue> iterKey = JSObject::GetProperty(thread, entries, first).GetValue();
405 JSTaggedValue keyFlag = tMap->HasKey(thread, iterKey.GetTaggedValue());
406 EXPECT_EQ(JSTaggedValue::True(), keyFlag);
407 JSHandle<JSTaggedValue> iterValue = JSObject::GetProperty(thread, entries, second).GetValue();
408 JSTaggedValue valueFlag = JSAPIHashMap::HasValue(thread, tMap, iterValue);
409 EXPECT_EQ(JSTaggedValue::True(), valueFlag);
410 }
411
412 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
413 std::string iKey = myKey + std::to_string(i);
414 std::string iValue = myValue + std::to_string(i);
415 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
416 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
417 JSTaggedValue keyFlag = tMap->HasKey(thread, key.GetTaggedValue());
418 EXPECT_EQ(JSTaggedValue::True(), keyFlag);
419 JSTaggedValue valueFlag = JSAPIHashMap::HasValue(thread, tMap, value);
420 EXPECT_EQ(JSTaggedValue::True(), valueFlag);
421 }
422 }
423 }
424
425 // hashmap.remove(key)
HWTEST_F_L0(ContainersHashMapTest,Remove)426 HWTEST_F_L0(ContainersHashMapTest, Remove)
427 {
428 constexpr uint32_t NODE_NUMBERS = 8;
429 JSHandle<JSAPIHashMap> tMap = CreateJSAPIHashMap();
430 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
431 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
432 callInfo->SetFunction(JSTaggedValue::Undefined());
433 callInfo->SetThis(tMap.GetTaggedValue());
434 callInfo->SetCallArg(0, JSTaggedValue(i));
435 callInfo->SetCallArg(1, JSTaggedValue(i));
436
437 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
438 JSTaggedValue result = ContainersHashMap::Set(callInfo);
439 TestHelper::TearDownFrame(thread, prev);
440 EXPECT_TRUE(result.IsJSAPIHashMap());
441 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
442 }
443
444 {
445 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
446 callInfo->SetFunction(JSTaggedValue::Undefined());
447 callInfo->SetThis(tMap.GetTaggedValue());
448 callInfo->SetCallArg(0, JSTaggedValue(NODE_NUMBERS / 2));
449
450 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
451 JSTaggedValue rValue = ContainersHashMap::Remove(callInfo);
452 TestHelper::TearDownFrame(thread, prev);
453 EXPECT_EQ(rValue, JSTaggedValue(NODE_NUMBERS / 2));
454 EXPECT_EQ(tMap->GetSize(), NODE_NUMBERS - 1);
455 }
456
457 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
458 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
459 callInfo->SetFunction(JSTaggedValue::Undefined());
460 callInfo->SetThis(tMap.GetTaggedValue());
461 callInfo->SetCallArg(0, JSTaggedValue(i));
462
463 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
464 JSTaggedValue result = ContainersHashMap::Get(callInfo);
465 TestHelper::TearDownFrame(thread, prev);
466 if (i == (NODE_NUMBERS / 2)) {
467 EXPECT_EQ(result, JSTaggedValue::Undefined());
468 } else {
469 EXPECT_EQ(result, JSTaggedValue(i));
470 }
471 }
472
473 // test add string
474 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
475 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
476 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
477 std::string myKey("mykey");
478 std::string myValue("myvalue");
479 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
480 std::string iKey = myKey + std::to_string(i);
481 std::string iValue = myValue + std::to_string(i);
482 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
483 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
484
485 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
486 callInfo->SetFunction(JSTaggedValue::Undefined());
487 callInfo->SetThis(tMap.GetTaggedValue());
488 callInfo->SetCallArg(0, key.GetTaggedValue());
489 callInfo->SetCallArg(1, value.GetTaggedValue());
490 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
491 JSTaggedValue result = ContainersHashMap::Set(callInfo);
492 TestHelper::TearDownFrame(thread, prev);
493 EXPECT_TRUE(result.IsJSAPIHashMap());
494 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i);
495 }
496
497 {
498 std::string iKey = myKey + std::to_string(NODE_NUMBERS / 2);
499 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
500 std::string iValue = myValue + std::to_string(NODE_NUMBERS / 2);
501 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
502 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
503 callInfo->SetFunction(JSTaggedValue::Undefined());
504 callInfo->SetThis(tMap.GetTaggedValue());
505 callInfo->SetCallArg(0, key.GetTaggedValue());
506
507 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
508 JSTaggedValue rValue = ContainersHashMap::Remove(callInfo);
509 TestHelper::TearDownFrame(thread, prev);
510 EXPECT_TRUE(JSTaggedValue::SameValue(rValue, value.GetTaggedValue()));
511 EXPECT_EQ(tMap->GetSize(), NODE_NUMBERS * 2 - 2);
512 }
513 }
514
515 // hashmap.setAll(map)
HWTEST_F_L0(ContainersHashMapTest,SetAll)516 HWTEST_F_L0(ContainersHashMapTest, SetAll)
517 {
518 constexpr uint32_t NODE_NUMBERS = 8;
519 JSHandle<JSAPIHashMap> sMap = CreateJSAPIHashMap();
520 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
521 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
522 callInfo->SetFunction(JSTaggedValue::Undefined());
523 callInfo->SetThis(sMap.GetTaggedValue());
524 callInfo->SetCallArg(0, JSTaggedValue(i));
525 callInfo->SetCallArg(1, JSTaggedValue(i));
526
527 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
528 JSTaggedValue result = ContainersHashMap::Set(callInfo);
529 TestHelper::TearDownFrame(thread, prev);
530 EXPECT_TRUE(result.IsJSAPIHashMap());
531 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
532 }
533
534 JSHandle<JSAPIHashMap> dMap = CreateJSAPIHashMap();
535 {
536 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
537 callInfo->SetFunction(JSTaggedValue::Undefined());
538 callInfo->SetThis(dMap.GetTaggedValue());
539 callInfo->SetCallArg(0, sMap.GetTaggedValue());
540
541 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
542 ContainersHashMap::SetAll(callInfo);
543 TestHelper::TearDownFrame(thread, prev);
544 EXPECT_EQ(dMap->GetSize(), NODE_NUMBERS);
545 }
546 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
547 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
548 callInfo->SetFunction(JSTaggedValue::Undefined());
549 callInfo->SetThis(dMap.GetTaggedValue());
550 callInfo->SetCallArg(0, JSTaggedValue(i));
551
552 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
553 JSTaggedValue result = ContainersHashMap::Get(callInfo);
554 TestHelper::TearDownFrame(thread, prev);
555 EXPECT_EQ(result, JSTaggedValue(i));
556 }
557
558 // test add string
559 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
560 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
561 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
562 std::string myKey("mykey");
563 std::string myValue("myvalue");
564 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
565 std::string iKey = myKey + std::to_string(i);
566 std::string iValue = myValue + std::to_string(i);
567 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
568 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
569
570 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
571 callInfo->SetFunction(JSTaggedValue::Undefined());
572 callInfo->SetThis(sMap.GetTaggedValue());
573 callInfo->SetCallArg(0, key.GetTaggedValue());
574 callInfo->SetCallArg(1, value.GetTaggedValue());
575 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
576 JSTaggedValue result = ContainersHashMap::Set(callInfo);
577 TestHelper::TearDownFrame(thread, prev);
578 EXPECT_TRUE(result.IsJSAPIHashMap());
579 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
580 }
581 {
582 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
583 callInfo->SetFunction(JSTaggedValue::Undefined());
584 callInfo->SetThis(dMap.GetTaggedValue());
585 callInfo->SetCallArg(0, sMap.GetTaggedValue());
586
587 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
588 ContainersHashMap::SetAll(callInfo);
589 TestHelper::TearDownFrame(thread, prev);
590 EXPECT_EQ(dMap->GetSize(), NODE_NUMBERS * 2);
591 }
592 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
593 std::string iKey = myKey + std::to_string(i);
594 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
595 std::string iValue = myValue + std::to_string(i);
596 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
597 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
598 callInfo->SetFunction(JSTaggedValue::Undefined());
599 callInfo->SetThis(dMap.GetTaggedValue());
600 callInfo->SetCallArg(0, key.GetTaggedValue());
601
602 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
603 JSTaggedValue result = ContainersHashMap::Get(callInfo);
604 TestHelper::TearDownFrame(thread, prev);
605 EXPECT_TRUE(JSTaggedValue::SameValue(result, value.GetTaggedValue()));
606 }
607 EXPECT_EQ(dMap->GetSize(), 2 * NODE_NUMBERS);
608 }
609
610 // hashmap.clear()
HWTEST_F_L0(ContainersHashMapTest,Clear)611 HWTEST_F_L0(ContainersHashMapTest, Clear)
612 {
613 constexpr uint32_t NODE_NUMBERS = 8;
614 JSHandle<JSAPIHashMap> tMap = CreateJSAPIHashMap();
615 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
616 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
617 callInfo->SetFunction(JSTaggedValue::Undefined());
618 callInfo->SetThis(tMap.GetTaggedValue());
619 callInfo->SetCallArg(0, JSTaggedValue(i));
620 callInfo->SetCallArg(1, JSTaggedValue(i));
621
622 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
623 JSTaggedValue result = ContainersHashMap::Set(callInfo);
624 TestHelper::TearDownFrame(thread, prev);
625 EXPECT_TRUE(result.IsJSAPIHashMap());
626 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
627 }
628
629 // test clear
630 {
631 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
632 callInfo->SetFunction(JSTaggedValue::Undefined());
633 callInfo->SetThis(tMap.GetTaggedValue());
634
635 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
636 ContainersHashMap::Clear(callInfo);
637 TestHelper::TearDownFrame(thread, prev);
638 EXPECT_EQ(tMap->GetSize(), (uint32_t)0);
639 }
640 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
641 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
642 callInfo->SetFunction(JSTaggedValue::Undefined());
643 callInfo->SetThis(tMap.GetTaggedValue());
644 callInfo->SetCallArg(0, JSTaggedValue(i));
645
646 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
647 JSTaggedValue result = ContainersHashMap::Get(callInfo);
648 TestHelper::TearDownFrame(thread, prev);
649 EXPECT_EQ(result, JSTaggedValue::Undefined());
650 }
651
652 // test add string
653 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
654 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
655 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
656 std::string myKey("mykey");
657 std::string myValue("myvalue");
658 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
659 std::string iKey = myKey + std::to_string(i);
660 std::string iValue = myValue + std::to_string(i);
661 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
662 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
663
664 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
665 callInfo->SetFunction(JSTaggedValue::Undefined());
666 callInfo->SetThis(tMap.GetTaggedValue());
667 callInfo->SetCallArg(0, key.GetTaggedValue());
668 callInfo->SetCallArg(1, value.GetTaggedValue());
669 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
670 JSTaggedValue result = ContainersHashMap::Set(callInfo);
671 TestHelper::TearDownFrame(thread, prev);
672 EXPECT_TRUE(result.IsJSAPIHashMap());
673 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
674 }
675
676 // test clear
677 {
678 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
679 callInfo->SetFunction(JSTaggedValue::Undefined());
680 callInfo->SetThis(tMap.GetTaggedValue());
681
682 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
683 ContainersHashMap::Clear(callInfo);
684 TestHelper::TearDownFrame(thread, prev);
685 EXPECT_EQ(tMap->GetSize(), (uint32_t)0);
686 }
687 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
688 std::string iKey = myKey + std::to_string(i);
689 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
690 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
691 callInfo->SetFunction(JSTaggedValue::Undefined());
692 callInfo->SetThis(tMap.GetTaggedValue());
693 callInfo->SetCallArg(0, key.GetTaggedValue());
694
695 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
696 JSTaggedValue result = ContainersHashMap::Get(callInfo);
697 TestHelper::TearDownFrame(thread, prev);
698 EXPECT_EQ(result, JSTaggedValue::Undefined());
699 }
700 }
701
702 // hashmap.replace(key, value)
HWTEST_F_L0(ContainersHashMapTest,Replace)703 HWTEST_F_L0(ContainersHashMapTest, Replace)
704 {
705 constexpr uint32_t NODE_NUMBERS = 8;
706 JSHandle<JSAPIHashMap> tMap = CreateJSAPIHashMap();
707 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
708 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
709 callInfo->SetFunction(JSTaggedValue::Undefined());
710 callInfo->SetThis(tMap.GetTaggedValue());
711 callInfo->SetCallArg(0, JSTaggedValue(i));
712 callInfo->SetCallArg(1, JSTaggedValue(i));
713
714 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
715 JSTaggedValue result = ContainersHashMap::Set(callInfo);
716 TestHelper::TearDownFrame(thread, prev);
717 EXPECT_TRUE(result.IsJSAPIHashMap());
718 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
719 }
720
721 {
722 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
723 callInfo->SetFunction(JSTaggedValue::Undefined());
724 callInfo->SetThis(tMap.GetTaggedValue());
725 callInfo->SetCallArg(0, JSTaggedValue(NODE_NUMBERS / 2));
726 callInfo->SetCallArg(1, JSTaggedValue(NODE_NUMBERS));
727
728 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
729 JSTaggedValue result = ContainersHashMap::Replace(callInfo);
730 TestHelper::TearDownFrame(thread, prev);
731 EXPECT_EQ(result, JSTaggedValue::True());
732 EXPECT_EQ(tMap->GetSize(), NODE_NUMBERS);
733 }
734 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
735 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
736 callInfo->SetFunction(JSTaggedValue::Undefined());
737 callInfo->SetThis(tMap.GetTaggedValue());
738 callInfo->SetCallArg(0, JSTaggedValue(i));
739
740 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
741 JSTaggedValue result = ContainersHashMap::Get(callInfo);
742 TestHelper::TearDownFrame(thread, prev);
743 if (i == (NODE_NUMBERS / 2)) {
744 EXPECT_EQ(result, JSTaggedValue(NODE_NUMBERS));
745 } else {
746 EXPECT_EQ(result, JSTaggedValue(i));
747 }
748 }
749
750 // test add string
751 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
752 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
753 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
754 std::string myKey("mykey");
755 std::string myValue("myvalue");
756 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
757 std::string iKey = myKey + std::to_string(i);
758 std::string iValue = myValue + std::to_string(i);
759 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
760 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
761
762 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
763 callInfo->SetFunction(JSTaggedValue::Undefined());
764 callInfo->SetThis(tMap.GetTaggedValue());
765 callInfo->SetCallArg(0, key.GetTaggedValue());
766 callInfo->SetCallArg(1, value.GetTaggedValue());
767 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
768 JSTaggedValue result = ContainersHashMap::Set(callInfo);
769 TestHelper::TearDownFrame(thread, prev);
770 EXPECT_TRUE(result.IsJSAPIHashMap());
771 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
772 }
773
774 {
775 std::string iKey = myKey + std::to_string(NODE_NUMBERS / 2);
776 std::string iValue = myValue + std::to_string(NODE_NUMBERS);
777 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
778 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
779 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
780 callInfo->SetFunction(JSTaggedValue::Undefined());
781 callInfo->SetThis(tMap.GetTaggedValue());
782 callInfo->SetCallArg(0, key.GetTaggedValue());
783 callInfo->SetCallArg(1, value.GetTaggedValue());
784
785 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
786 JSTaggedValue result = ContainersHashMap::Replace(callInfo);
787 TestHelper::TearDownFrame(thread, prev);
788 EXPECT_EQ(result, JSTaggedValue::True());
789 EXPECT_EQ(tMap->GetSize(), NODE_NUMBERS * 2);
790 }
791 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
792 std::string iKey = myKey + std::to_string(i);
793 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
794 std::string iValue;
795 if (i == (NODE_NUMBERS / 2)) {
796 iValue = myValue + std::to_string(NODE_NUMBERS);
797 } else {
798 iValue = myValue + std::to_string(i);
799 }
800 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
801 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
802 callInfo->SetFunction(JSTaggedValue::Undefined());
803 callInfo->SetThis(tMap.GetTaggedValue());
804 callInfo->SetCallArg(0, key.GetTaggedValue());
805
806 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
807 JSTaggedValue result = ContainersHashMap::Get(callInfo);
808 TestHelper::TearDownFrame(thread, prev);
809 EXPECT_TRUE(JSTaggedValue::SameValue(result, value.GetTaggedValue()));
810 }
811 }
812
813 // hashmap.ForEach(callbackfn, this)
HWTEST_F_L0(ContainersHashMapTest,ForEach)814 HWTEST_F_L0(ContainersHashMapTest, ForEach)
815 {
816 constexpr uint32_t NODE_NUMBERS = 8;
817 JSHandle<JSAPIHashMap> tMap = CreateJSAPIHashMap();
818 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
819 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
820 callInfo->SetFunction(JSTaggedValue::Undefined());
821 callInfo->SetThis(tMap.GetTaggedValue());
822 callInfo->SetCallArg(0, JSTaggedValue(i));
823 callInfo->SetCallArg(1, JSTaggedValue(i));
824
825 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
826 JSTaggedValue result = ContainersHashMap::Set(callInfo);
827 TestHelper::TearDownFrame(thread, prev);
828 EXPECT_TRUE(result.IsJSAPIHashMap());
829 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
830 }
831 // test foreach function with TestForEachFunc;
832 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
833 JSHandle<JSAPIHashMap> dMap = CreateJSAPIHashMap();
834 {
835 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
836 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
837 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
838 callInfo->SetFunction(JSTaggedValue::Undefined());
839 callInfo->SetThis(tMap.GetTaggedValue());
840 callInfo->SetCallArg(0, func.GetTaggedValue());
841 callInfo->SetCallArg(1, dMap.GetTaggedValue());
842
843 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
844 ContainersHashMap::ForEach(callInfo);
845 TestHelper::TearDownFrame(thread, prev);
846 }
847 EXPECT_EQ(dMap->GetSize(), NODE_NUMBERS);
848 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
849 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
850 callInfo->SetFunction(JSTaggedValue::Undefined());
851 callInfo->SetThis(tMap.GetTaggedValue());
852 callInfo->SetCallArg(0, JSTaggedValue(i));
853
854 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
855 JSTaggedValue result = ContainersHashMap::Get(callInfo);
856 TestHelper::TearDownFrame(thread, prev);
857 EXPECT_EQ(result, JSTaggedValue(i * 2));
858 }
859
860 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
861 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
862 callInfo->SetFunction(JSTaggedValue::Undefined());
863 callInfo->SetThis(dMap.GetTaggedValue());
864 callInfo->SetCallArg(0, JSTaggedValue(i));
865
866 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
867 JSTaggedValue result = ContainersHashMap::Get(callInfo);
868 TestHelper::TearDownFrame(thread, prev);
869 EXPECT_EQ(result, JSTaggedValue(i));
870 }
871
872 // test add string
873 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
874 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
875 std::string myKey("mykey");
876 std::string myValue("myvalue");
877 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
878 std::string iKey = myKey + std::to_string(i);
879 std::string iValue = myValue + std::to_string(i);
880 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
881 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
882
883 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
884 callInfo->SetFunction(JSTaggedValue::Undefined());
885 callInfo->SetThis(tMap.GetTaggedValue());
886 callInfo->SetCallArg(0, key.GetTaggedValue());
887 callInfo->SetCallArg(1, value.GetTaggedValue());
888 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
889 JSTaggedValue result = ContainersHashMap::Set(callInfo);
890 TestHelper::TearDownFrame(thread, prev);
891 EXPECT_TRUE(result.IsJSAPIHashMap());
892 EXPECT_EQ(JSAPIHashMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
893 }
894 EXPECT_EQ(tMap->GetSize(), NODE_NUMBERS * 2);
895 EXPECT_EQ(dMap->GetSize(), NODE_NUMBERS);
896
897 // test foreach function with TestForEachFunc;
898 {
899 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
900 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
901 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
902 callInfo->SetFunction(JSTaggedValue::Undefined());
903 callInfo->SetThis(tMap.GetTaggedValue());
904 callInfo->SetCallArg(0, func.GetTaggedValue());
905 callInfo->SetCallArg(1, dMap.GetTaggedValue());
906 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
907 ContainersHashMap::ForEach(callInfo);
908 TestHelper::TearDownFrame(thread, prev);
909 }
910
911 EXPECT_EQ(dMap->GetSize(), NODE_NUMBERS * 2);
912 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
913 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
914 callInfo->SetFunction(JSTaggedValue::Undefined());
915 callInfo->SetThis(tMap.GetTaggedValue());
916 callInfo->SetCallArg(0, JSTaggedValue(i));
917
918 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
919 JSTaggedValue result = ContainersHashMap::Get(callInfo);
920 TestHelper::TearDownFrame(thread, prev);
921 EXPECT_EQ(result, JSTaggedValue(i * 4)); // 4 means 4 times
922 }
923
924 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
925 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
926 callInfo->SetFunction(JSTaggedValue::Undefined());
927 callInfo->SetThis(dMap.GetTaggedValue());
928 callInfo->SetCallArg(0, JSTaggedValue(i));
929
930 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
931 JSTaggedValue result = ContainersHashMap::Get(callInfo);
932 TestHelper::TearDownFrame(thread, prev);
933 EXPECT_EQ(result, JSTaggedValue(i * 2));
934 }
935
936 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
937 std::string iKey = myKey + std::to_string(i);
938 std::string iValue = myValue + std::to_string(i);
939 key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
940 value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
941
942 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
943 callInfo->SetFunction(JSTaggedValue::Undefined());
944 callInfo->SetThis(dMap.GetTaggedValue());
945 callInfo->SetCallArg(0, key.GetTaggedValue());
946
947 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
948 JSTaggedValue result = ContainersHashMap::Get(callInfo);
949 TestHelper::TearDownFrame(thread, prev);
950 EXPECT_EQ(result, value.GetTaggedValue());
951 }
952 }
953
HWTEST_F_L0(ContainersHashMapTest,ProxyOfGetLength)954 HWTEST_F_L0(ContainersHashMapTest, ProxyOfGetLength)
955 {
956 constexpr uint32_t NODE_NUMBERS = 8;
957 JSHandle<JSAPIHashMap> treeMap = CreateJSAPIHashMap();
958 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
959 callInfo->SetFunction(JSTaggedValue::Undefined());
960 JSHandle<JSProxy> proxy = CreateJSProxyHandle(thread);
961 proxy->SetTarget(thread, treeMap.GetTaggedValue());
962 callInfo->SetThis(proxy.GetTaggedValue());
963
964 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
965 callInfo->SetCallArg(0, JSTaggedValue(i));
966 callInfo->SetCallArg(1, JSTaggedValue(i + 1));
967 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
968 ContainersHashMap::Set(callInfo);
969 TestHelper::TearDownFrame(thread, prev);
970
971 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo);
972 JSTaggedValue retult = ContainersHashMap::GetLength(callInfo);
973 TestHelper::TearDownFrame(thread, prev1);
974 EXPECT_EQ(retult, JSTaggedValue(i + 1));
975 }
976 }
977
HWTEST_F_L0(ContainersHashMapTest,ExceptionReturn)978 HWTEST_F_L0(ContainersHashMapTest, ExceptionReturn)
979 {
980 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, SetAll);
981 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, Keys);
982 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, Values);
983 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, Entries);
984 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, ForEach);
985 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, Set);
986 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, Get);
987 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, Remove);
988 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, HasKey);
989 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, HasValue);
990 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, Replace);
991 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, Clear);
992 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersHashMap, GetLength);
993
994 JSHandle<JSAPIHashMap> treeMap = CreateJSAPIHashMap();
995 {
996 auto callInfo = NewEmptyCallInfo(thread);
997 callInfo->SetThis(treeMap.GetTaggedValue());
998 CONTAINERS_API_EXCEPTION_TEST(ContainersHashMap, SetAll, callInfo);
999 }
1000 }
1001 } // namespace panda::test
1002