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