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_treemap.h"
18 #include "ecmascript/ecma_runtime_call_info.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_api/js_api_tree_map.h"
21 #include "ecmascript/js_api/js_api_tree_map_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 ContainersTreeMapTest : 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 JSAPITreeMap::Set(thread, JSHandle<JSAPITreeMap>::Cast(map), key, newValue);
71 }
72 }
73 JSHandle<JSAPITreeMap> jsTreeMap(GetThis(argv));
74 JSAPITreeMap::Set(thread, jsTreeMap, key, value);
75 return JSTaggedValue::Undefined();
76 }
77
TestCompareFunction(EcmaRuntimeCallInfo * argv)78 static JSTaggedValue TestCompareFunction(EcmaRuntimeCallInfo *argv)
79 {
80 JSThread *thread = argv->GetThread();
81 JSHandle<JSTaggedValue> valueX = GetCallArg(argv, 0);
82 JSHandle<JSTaggedValue> valueY = GetCallArg(argv, 1);
83
84 if (valueX->IsString() && valueY->IsString()) {
85 auto xHandle = JSHandle<EcmaString>(valueX);
86 auto yHandle = JSHandle<EcmaString>(valueY);
87 int result = EcmaStringAccessor::Compare(thread->GetEcmaVM(), xHandle, yHandle);
88 if (result < 0) {
89 return JSTaggedValue(1);
90 }
91 if (result == 0) {
92 return JSTaggedValue(0);
93 }
94 return JSTaggedValue(-1);
95 }
96
97 if (valueX->IsNumber() && valueY->IsString()) {
98 return JSTaggedValue(1);
99 }
100 if (valueX->IsString() && valueY->IsNumber()) {
101 return JSTaggedValue(-1);
102 }
103
104 ComparisonResult res = ComparisonResult::UNDEFINED;
105 if (valueX->IsNumber() && valueY->IsNumber()) {
106 res = JSTaggedValue::StrictNumberCompare(valueY->GetNumber(), valueX->GetNumber());
107 } else {
108 res = JSTaggedValue::Compare(thread, valueY, valueX);
109 }
110 return res == ComparisonResult::GREAT ?
111 JSTaggedValue(1) : (res == ComparisonResult::LESS ? JSTaggedValue(-1) : JSTaggedValue(0));
112 }
113 };
114
115 protected:
InitializeTreeMapConstructor()116 JSTaggedValue InitializeTreeMapConstructor()
117 {
118 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
119 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
120
121 JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
122 JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
123 JSHandle<JSTaggedValue> value =
124 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
125
126 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
127 objCallInfo->SetFunction(JSTaggedValue::Undefined());
128 objCallInfo->SetThis(value.GetTaggedValue());
129 objCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(ContainerTag::TreeMap)));
130 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
131 JSTaggedValue result = ContainersPrivate::Load(objCallInfo);
132 TestHelper::TearDownFrame(thread, prev);
133
134 return result;
135 }
136
CreateJSAPITreeMap(JSTaggedValue compare=JSTaggedValue::Undefined ())137 JSHandle<JSAPITreeMap> CreateJSAPITreeMap(JSTaggedValue compare = JSTaggedValue::Undefined())
138 {
139 JSHandle<JSTaggedValue> compareHandle(thread, compare);
140 JSHandle<JSFunction> newTarget(thread, InitializeTreeMapConstructor());
141 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
142 objCallInfo->SetFunction(newTarget.GetTaggedValue());
143 objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
144 objCallInfo->SetThis(JSTaggedValue::Undefined());
145 objCallInfo->SetCallArg(0, compareHandle.GetTaggedValue());
146
147 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
148 JSTaggedValue result = ContainersTreeMap::TreeMapConstructor(objCallInfo);
149 TestHelper::TearDownFrame(thread, prev);
150 JSHandle<JSAPITreeMap> map(thread, result);
151 return map;
152 }
153 };
154
155 // new TreeMap()
HWTEST_F_L0(ContainersTreeMapTest,TreeMapConstructor)156 HWTEST_F_L0(ContainersTreeMapTest, TreeMapConstructor)
157 {
158 // Initialize twice and return directly the second time
159 InitializeTreeMapConstructor();
160 JSHandle<JSFunction> newTarget(thread, InitializeTreeMapConstructor());
161
162 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
163 objCallInfo->SetFunction(newTarget.GetTaggedValue());
164 objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
165 objCallInfo->SetThis(JSTaggedValue::Undefined());
166 objCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
167
168 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
169 JSTaggedValue result = ContainersTreeMap::TreeMapConstructor(objCallInfo);
170 TestHelper::TearDownFrame(thread, prev);
171
172 ASSERT_TRUE(result.IsJSAPITreeMap());
173 JSHandle<JSAPITreeMap> mapHandle(thread, result);
174 JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(mapHandle));
175 JSTaggedValue funcProto = newTarget->GetFunctionPrototype();
176 ASSERT_EQ(resultProto, funcProto);
177 int size = mapHandle->GetSize();
178 ASSERT_EQ(size, 0);
179
180 // test TreeMapConstructor exception
181 objCallInfo->SetCallArg(0, JSTaggedValue(0));
182 CONTAINERS_API_EXCEPTION_TEST(ContainersTreeMap, TreeMapConstructor, objCallInfo);
183 objCallInfo->SetNewTarget(JSTaggedValue::Undefined());
184 CONTAINERS_API_EXCEPTION_TEST(ContainersTreeMap, TreeMapConstructor, objCallInfo);
185 }
186
187 // treemap.set(key, value), treemap.get(key)
HWTEST_F_L0(ContainersTreeMapTest,SetAndGet)188 HWTEST_F_L0(ContainersTreeMapTest, SetAndGet)
189 {
190 constexpr int NODE_NUMBERS = 8;
191 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
192 for (int i = 0; i < NODE_NUMBERS; i++) {
193 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
194 callInfo->SetFunction(JSTaggedValue::Undefined());
195 callInfo->SetThis(tmap.GetTaggedValue());
196 callInfo->SetCallArg(0, JSTaggedValue(i));
197 callInfo->SetCallArg(1, JSTaggedValue(i));
198
199 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
200 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
201 TestHelper::TearDownFrame(thread, prev);
202 EXPECT_TRUE(result.IsJSAPITreeMap());
203 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
204 }
205
206 // test add string
207 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
208 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
209 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
210 std::string myKey("mykey");
211 std::string myValue("myvalue");
212 for (int i = 0; i < NODE_NUMBERS; i++) {
213 std::string ikey = myKey + std::to_string(i);
214 std::string ivalue = myValue + std::to_string(i);
215 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
216 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
217
218 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
219 callInfo->SetFunction(JSTaggedValue::Undefined());
220 callInfo->SetThis(tmap.GetTaggedValue());
221 callInfo->SetCallArg(0, key.GetTaggedValue());
222 callInfo->SetCallArg(1, value.GetTaggedValue());
223 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
224 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
225 TestHelper::TearDownFrame(thread, prev);
226 EXPECT_TRUE(result.IsJSAPITreeMap());
227 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
228 }
229
230 for (int i = 0; i < NODE_NUMBERS; i++) {
231 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
232 callInfo->SetFunction(JSTaggedValue::Undefined());
233 callInfo->SetThis(tmap.GetTaggedValue());
234 callInfo->SetCallArg(0, JSTaggedValue(i));
235
236 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
237 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
238 TestHelper::TearDownFrame(thread, prev);
239 EXPECT_EQ(result, JSTaggedValue(i));
240 }
241
242 for (int i = 0; i < NODE_NUMBERS; i++) {
243 std::string ikey = myKey + std::to_string(i);
244 std::string ivalue = myValue + std::to_string(i);
245 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
246 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
247
248 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
249 callInfo->SetFunction(JSTaggedValue::Undefined());
250 callInfo->SetThis(tmap.GetTaggedValue());
251 callInfo->SetCallArg(0, key.GetTaggedValue());
252 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
253 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
254 TestHelper::TearDownFrame(thread, prev);
255 EXPECT_EQ(result, value.GetTaggedValue());
256 }
257 }
258
259 // treemap.remove(key)
HWTEST_F_L0(ContainersTreeMapTest,Remove)260 HWTEST_F_L0(ContainersTreeMapTest, Remove)
261 {
262 constexpr int NODE_NUMBERS = 64;
263 constexpr int REMOVE_SIZE = 48;
264 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
265 for (int i = 0; i < NODE_NUMBERS; i++) {
266 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
267 callInfo->SetFunction(JSTaggedValue::Undefined());
268 callInfo->SetThis(tmap.GetTaggedValue());
269 callInfo->SetCallArg(0, JSTaggedValue(i));
270 callInfo->SetCallArg(1, JSTaggedValue(i));
271
272 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
273 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
274 TestHelper::TearDownFrame(thread, prev);
275 EXPECT_TRUE(result.IsJSAPITreeMap());
276 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
277 }
278
279 for (int i = 0; i < REMOVE_SIZE; i++) {
280 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
281 callInfo->SetFunction(JSTaggedValue::Undefined());
282 callInfo->SetThis(tmap.GetTaggedValue());
283 callInfo->SetCallArg(0, JSTaggedValue(i));
284
285 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
286 JSTaggedValue rvalue = ContainersTreeMap::Remove(callInfo);
287 TestHelper::TearDownFrame(thread, prev);
288 EXPECT_EQ(rvalue, JSTaggedValue(i));
289 }
290 EXPECT_EQ(tmap->GetSize(), NODE_NUMBERS - REMOVE_SIZE);
291
292 for (int i = 0; i < NODE_NUMBERS; i++) {
293 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
294 callInfo->SetFunction(JSTaggedValue::Undefined());
295 callInfo->SetThis(tmap.GetTaggedValue());
296 callInfo->SetCallArg(0, JSTaggedValue(i));
297
298 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
299 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
300 TestHelper::TearDownFrame(thread, prev);
301 if (i < REMOVE_SIZE) {
302 EXPECT_EQ(result, JSTaggedValue::Undefined());
303 } else {
304 EXPECT_EQ(result, JSTaggedValue(i));
305 }
306 }
307
308 // test add string
309 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
310 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
311 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
312 std::string myKey("mykey");
313 std::string myValue("myvalue");
314 for (int i = 0; i < NODE_NUMBERS; i++) {
315 std::string ikey = myKey + std::to_string(i);
316 std::string ivalue = myValue + std::to_string(i);
317 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
318 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
319
320 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
321 callInfo->SetFunction(JSTaggedValue::Undefined());
322 callInfo->SetThis(tmap.GetTaggedValue());
323 callInfo->SetCallArg(0, key.GetTaggedValue());
324 callInfo->SetCallArg(1, value.GetTaggedValue());
325 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
326 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
327 TestHelper::TearDownFrame(thread, prev);
328 EXPECT_TRUE(result.IsJSAPITreeMap());
329 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS - REMOVE_SIZE + i + 1);
330 }
331
332 for (int i = 0; i < REMOVE_SIZE; i++) {
333 std::string ikey = myKey + std::to_string(i);
334 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
335 std::string ivalue = myValue + std::to_string(i);
336 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
337 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
338 callInfo->SetFunction(JSTaggedValue::Undefined());
339 callInfo->SetThis(tmap.GetTaggedValue());
340 callInfo->SetCallArg(0, key.GetTaggedValue());
341
342 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
343 JSTaggedValue rvalue = ContainersTreeMap::Remove(callInfo);
344 TestHelper::TearDownFrame(thread, prev);
345 EXPECT_TRUE(JSTaggedValue::SameValue(rvalue, value.GetTaggedValue()));
346 }
347 EXPECT_EQ(tmap->GetSize(), (NODE_NUMBERS - REMOVE_SIZE) * 2);
348 }
349
350 // treemap.hasKey(key), treemap.hasValue(value)
HWTEST_F_L0(ContainersTreeMapTest,HasKeyAndHasValue)351 HWTEST_F_L0(ContainersTreeMapTest, HasKeyAndHasValue)
352 {
353 constexpr int NODE_NUMBERS = 8;
354 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
355 for (int i = 0; i < NODE_NUMBERS; i++) {
356 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
357 callInfo->SetFunction(JSTaggedValue::Undefined());
358 callInfo->SetThis(tmap.GetTaggedValue());
359 callInfo->SetCallArg(0, JSTaggedValue(i));
360 callInfo->SetCallArg(1, JSTaggedValue(i));
361
362 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
363 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
364 TestHelper::TearDownFrame(thread, prev);
365 EXPECT_TRUE(result.IsJSAPITreeMap());
366 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
367 }
368
369 for (int i = 0; i < NODE_NUMBERS; i++) {
370 // test hasKey
371 {
372 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
373 callInfo->SetFunction(JSTaggedValue::Undefined());
374 callInfo->SetThis(tmap.GetTaggedValue());
375 callInfo->SetCallArg(0, JSTaggedValue(i));
376
377 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
378 JSTaggedValue result = ContainersTreeMap::HasKey(callInfo);
379 TestHelper::TearDownFrame(thread, prev);
380 EXPECT_EQ(result, JSTaggedValue::True());
381 }
382 // test hasValue
383 {
384 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
385 callInfo->SetFunction(JSTaggedValue::Undefined());
386 callInfo->SetThis(tmap.GetTaggedValue());
387 callInfo->SetCallArg(0, JSTaggedValue(i));
388
389 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
390 JSTaggedValue result = ContainersTreeMap::HasValue(callInfo);
391 TestHelper::TearDownFrame(thread, prev);
392 EXPECT_EQ(result, JSTaggedValue::True());
393 }
394 }
395
396 // test add string
397 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
398 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
399 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
400 std::string myKey("mykey");
401 std::string myValue("myvalue");
402 for (int i = 0; i < NODE_NUMBERS; i++) {
403 std::string ikey = myKey + std::to_string(i);
404 std::string ivalue = myValue + std::to_string(i);
405 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
406 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
407
408 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
409 callInfo->SetFunction(JSTaggedValue::Undefined());
410 callInfo->SetThis(tmap.GetTaggedValue());
411 callInfo->SetCallArg(0, key.GetTaggedValue());
412 callInfo->SetCallArg(1, value.GetTaggedValue());
413 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
414 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
415 TestHelper::TearDownFrame(thread, prev);
416 EXPECT_TRUE(result.IsJSAPITreeMap());
417 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
418 }
419
420 for (int i = 0; i < NODE_NUMBERS; i++) {
421 // test hasKey
422 {
423 std::string ikey = myKey + std::to_string(i);
424 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
425 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
426 callInfo->SetFunction(JSTaggedValue::Undefined());
427 callInfo->SetThis(tmap.GetTaggedValue());
428 callInfo->SetCallArg(0, key.GetTaggedValue());
429
430 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
431 JSTaggedValue result = ContainersTreeMap::HasKey(callInfo);
432 TestHelper::TearDownFrame(thread, prev);
433 EXPECT_EQ(result, JSTaggedValue::True());
434 }
435 // test hasValue
436 {
437 std::string ivalue = myValue + std::to_string(i);
438 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
439 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
440 callInfo->SetFunction(JSTaggedValue::Undefined());
441 callInfo->SetThis(tmap.GetTaggedValue());
442 callInfo->SetCallArg(0, value.GetTaggedValue());
443
444 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
445 JSTaggedValue result = ContainersTreeMap::HasValue(callInfo);
446 TestHelper::TearDownFrame(thread, prev);
447 EXPECT_EQ(result, JSTaggedValue::True());
448 }
449 }
450 }
451
452 // treemap.getFirstKey(), treemap.getLastKey()
HWTEST_F_L0(ContainersTreeMapTest,GetFirstKeyAndGetLastKey)453 HWTEST_F_L0(ContainersTreeMapTest, GetFirstKeyAndGetLastKey)
454 {
455 constexpr int NODE_NUMBERS = 8;
456 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
457 for (int i = 0; i < NODE_NUMBERS; i++) {
458 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
459 callInfo->SetFunction(JSTaggedValue::Undefined());
460 callInfo->SetThis(tmap.GetTaggedValue());
461 callInfo->SetCallArg(0, JSTaggedValue(i));
462 callInfo->SetCallArg(1, JSTaggedValue(i));
463
464 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
465 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
466 TestHelper::TearDownFrame(thread, prev);
467 EXPECT_TRUE(result.IsJSAPITreeMap());
468 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
469 }
470 // test getFirstKey
471 {
472 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
473 callInfo->SetFunction(JSTaggedValue::Undefined());
474 callInfo->SetThis(tmap.GetTaggedValue());
475
476 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
477 JSTaggedValue result = ContainersTreeMap::GetFirstKey(callInfo);
478 TestHelper::TearDownFrame(thread, prev);
479 EXPECT_EQ(result, JSTaggedValue(0));
480 }
481 // test getLastKey
482 {
483 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
484 callInfo->SetFunction(JSTaggedValue::Undefined());
485 callInfo->SetThis(tmap.GetTaggedValue());
486
487 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
488 JSTaggedValue result = ContainersTreeMap::GetLastKey(callInfo);
489 TestHelper::TearDownFrame(thread, prev);
490 EXPECT_EQ(result, JSTaggedValue(NODE_NUMBERS - 1));
491 }
492
493 // test add string
494 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
495 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
496 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
497 std::string myKey("mykey");
498 std::string myValue("myvalue");
499 for (int i = 0; i < NODE_NUMBERS; i++) {
500 std::string ikey = myKey + std::to_string(i);
501 std::string ivalue = myValue + std::to_string(i);
502 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
503 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
504
505 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
506 callInfo->SetFunction(JSTaggedValue::Undefined());
507 callInfo->SetThis(tmap.GetTaggedValue());
508 callInfo->SetCallArg(0, key.GetTaggedValue());
509 callInfo->SetCallArg(1, value.GetTaggedValue());
510 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
511 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
512 TestHelper::TearDownFrame(thread, prev);
513 EXPECT_TRUE(result.IsJSAPITreeMap());
514 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
515 }
516
517 // test getFirstKey
518 {
519 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
520 callInfo->SetFunction(JSTaggedValue::Undefined());
521 callInfo->SetThis(tmap.GetTaggedValue());
522
523 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
524 JSTaggedValue result = ContainersTreeMap::GetFirstKey(callInfo);
525 TestHelper::TearDownFrame(thread, prev);
526 EXPECT_EQ(result, JSTaggedValue(0));
527 }
528 // test getLastKey
529 {
530 std::string ikey = myKey + std::to_string(NODE_NUMBERS - 1);
531 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
532
533 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
534 callInfo->SetFunction(JSTaggedValue::Undefined());
535 callInfo->SetThis(tmap.GetTaggedValue());
536 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
537 JSTaggedValue result = ContainersTreeMap::GetLastKey(callInfo);
538 TestHelper::TearDownFrame(thread, prev);
539 EXPECT_EQ(result, key.GetTaggedValue());
540 }
541 }
542
543 // treemap.clear()
HWTEST_F_L0(ContainersTreeMapTest,Clear)544 HWTEST_F_L0(ContainersTreeMapTest, Clear)
545 {
546 constexpr int NODE_NUMBERS = 8;
547 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
548 for (int i = 0; i < NODE_NUMBERS; i++) {
549 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
550 callInfo->SetFunction(JSTaggedValue::Undefined());
551 callInfo->SetThis(tmap.GetTaggedValue());
552 callInfo->SetCallArg(0, JSTaggedValue(i));
553 callInfo->SetCallArg(1, JSTaggedValue(i));
554
555 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
556 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
557 TestHelper::TearDownFrame(thread, prev);
558 EXPECT_TRUE(result.IsJSAPITreeMap());
559 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
560 }
561
562 // test clear
563 {
564 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
565 callInfo->SetFunction(JSTaggedValue::Undefined());
566 callInfo->SetThis(tmap.GetTaggedValue());
567
568 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
569 ContainersTreeMap::Clear(callInfo);
570 TestHelper::TearDownFrame(thread, prev);
571 EXPECT_EQ(tmap->GetSize(), 0);
572 }
573 for (int i = 0; i < NODE_NUMBERS; i++) {
574 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
575 callInfo->SetFunction(JSTaggedValue::Undefined());
576 callInfo->SetThis(tmap.GetTaggedValue());
577 callInfo->SetCallArg(0, JSTaggedValue(i));
578
579 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
580 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
581 TestHelper::TearDownFrame(thread, prev);
582 EXPECT_EQ(result, JSTaggedValue::Undefined());
583 }
584
585 // test add string
586 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
587 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
588 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
589 std::string myKey("mykey");
590 std::string myValue("myvalue");
591 for (int i = 0; i < NODE_NUMBERS; i++) {
592 std::string ikey = myKey + std::to_string(i);
593 std::string ivalue = myValue + std::to_string(i);
594 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
595 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
596
597 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
598 callInfo->SetFunction(JSTaggedValue::Undefined());
599 callInfo->SetThis(tmap.GetTaggedValue());
600 callInfo->SetCallArg(0, key.GetTaggedValue());
601 callInfo->SetCallArg(1, value.GetTaggedValue());
602 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
603 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
604 TestHelper::TearDownFrame(thread, prev);
605 EXPECT_TRUE(result.IsJSAPITreeMap());
606 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
607 }
608
609 // test clear
610 {
611 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
612 callInfo->SetFunction(JSTaggedValue::Undefined());
613 callInfo->SetThis(tmap.GetTaggedValue());
614
615 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
616 ContainersTreeMap::Clear(callInfo);
617 TestHelper::TearDownFrame(thread, prev);
618 EXPECT_EQ(tmap->GetSize(), 0);
619 }
620 for (int i = 0; i < NODE_NUMBERS; i++) {
621 std::string ikey = myKey + std::to_string(i);
622 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
623 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
624 callInfo->SetFunction(JSTaggedValue::Undefined());
625 callInfo->SetThis(tmap.GetTaggedValue());
626 callInfo->SetCallArg(0, key.GetTaggedValue());
627
628 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
629 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
630 TestHelper::TearDownFrame(thread, prev);
631 EXPECT_EQ(result, JSTaggedValue::Undefined());
632 }
633 }
634
635 // treemap.setAll(map)
HWTEST_F_L0(ContainersTreeMapTest,SetAll)636 HWTEST_F_L0(ContainersTreeMapTest, SetAll)
637 {
638 constexpr int NODE_NUMBERS = 8;
639 JSHandle<JSAPITreeMap> smap = CreateJSAPITreeMap();
640 for (int i = 0; i < NODE_NUMBERS; i++) {
641 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
642 callInfo->SetFunction(JSTaggedValue::Undefined());
643 callInfo->SetThis(smap.GetTaggedValue());
644 callInfo->SetCallArg(0, JSTaggedValue(i));
645 callInfo->SetCallArg(1, JSTaggedValue(i));
646
647 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
648 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
649 TestHelper::TearDownFrame(thread, prev);
650 EXPECT_TRUE(result.IsJSAPITreeMap());
651 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
652 }
653
654 JSHandle<JSAPITreeMap> dmap = CreateJSAPITreeMap();
655 {
656 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
657 callInfo->SetFunction(JSTaggedValue::Undefined());
658 callInfo->SetThis(dmap.GetTaggedValue());
659 callInfo->SetCallArg(0, smap.GetTaggedValue());
660
661 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
662 ContainersTreeMap::SetAll(callInfo);
663 TestHelper::TearDownFrame(thread, prev);
664 EXPECT_EQ(dmap->GetSize(), NODE_NUMBERS);
665 }
666 for (int i = 0; i < NODE_NUMBERS; i++) {
667 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
668 callInfo->SetFunction(JSTaggedValue::Undefined());
669 callInfo->SetThis(dmap.GetTaggedValue());
670 callInfo->SetCallArg(0, JSTaggedValue(i));
671
672 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
673 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
674 TestHelper::TearDownFrame(thread, prev);
675 EXPECT_EQ(result, JSTaggedValue(i));
676 }
677
678 // test add string
679 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
680 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
681 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
682 std::string myKey("mykey");
683 std::string myValue("myvalue");
684 for (int i = 0; i < NODE_NUMBERS; i++) {
685 std::string ikey = myKey + std::to_string(i);
686 std::string ivalue = myValue + std::to_string(i);
687 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
688 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
689
690 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
691 callInfo->SetFunction(JSTaggedValue::Undefined());
692 callInfo->SetThis(smap.GetTaggedValue());
693 callInfo->SetCallArg(0, key.GetTaggedValue());
694 callInfo->SetCallArg(1, value.GetTaggedValue());
695 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
696 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
697 TestHelper::TearDownFrame(thread, prev);
698 EXPECT_TRUE(result.IsJSAPITreeMap());
699 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
700 }
701 {
702 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
703 callInfo->SetFunction(JSTaggedValue::Undefined());
704 callInfo->SetThis(dmap.GetTaggedValue());
705 callInfo->SetCallArg(0, smap.GetTaggedValue());
706
707 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
708 ContainersTreeMap::SetAll(callInfo);
709 TestHelper::TearDownFrame(thread, prev);
710 EXPECT_EQ(dmap->GetSize(), NODE_NUMBERS * 2);
711 }
712 for (int i = 0; i < NODE_NUMBERS; i++) {
713 std::string ikey = myKey + std::to_string(i);
714 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
715 std::string ivalue = myValue + std::to_string(i);
716 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
717 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
718 callInfo->SetFunction(JSTaggedValue::Undefined());
719 callInfo->SetThis(dmap.GetTaggedValue());
720 callInfo->SetCallArg(0, key.GetTaggedValue());
721
722 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
723 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
724 TestHelper::TearDownFrame(thread, prev);
725 EXPECT_TRUE(JSTaggedValue::SameValue(result, value.GetTaggedValue()));
726 }
727 EXPECT_EQ(dmap->GetSize(), 2 * NODE_NUMBERS);
728 }
729
730 // treemap.getLowerKey(key), treemap.getHigherKey(key)
HWTEST_F_L0(ContainersTreeMapTest,GetLowerKeyAndGetHigherKey)731 HWTEST_F_L0(ContainersTreeMapTest, GetLowerKeyAndGetHigherKey)
732 {
733 constexpr int NODE_NUMBERS = 8;
734 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
735 for (int i = 0; i < NODE_NUMBERS; i++) {
736 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
737 callInfo->SetFunction(JSTaggedValue::Undefined());
738 callInfo->SetThis(tmap.GetTaggedValue());
739 callInfo->SetCallArg(0, JSTaggedValue(i));
740 callInfo->SetCallArg(1, JSTaggedValue(i));
741
742 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
743 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
744 TestHelper::TearDownFrame(thread, prev);
745 EXPECT_TRUE(result.IsJSAPITreeMap());
746 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
747 }
748
749 // test getLowerKey
750 for (int i = 0; i <= NODE_NUMBERS; i++) {
751 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
752 callInfo->SetFunction(JSTaggedValue::Undefined());
753 callInfo->SetThis(tmap.GetTaggedValue());
754 callInfo->SetCallArg(0, JSTaggedValue(i));
755
756 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
757 JSTaggedValue result = ContainersTreeMap::GetLowerKey(callInfo);
758 TestHelper::TearDownFrame(thread, prev);
759 if (i == 0) {
760 EXPECT_EQ(result, JSTaggedValue::Undefined());
761 } else {
762 EXPECT_EQ(result, JSTaggedValue(i - 1));
763 }
764 }
765 // test getHigherKey
766 for (int i = 0; i <= NODE_NUMBERS; i++) {
767 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
768 callInfo->SetFunction(JSTaggedValue::Undefined());
769 callInfo->SetThis(tmap.GetTaggedValue());
770 callInfo->SetCallArg(0, JSTaggedValue(i));
771
772 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
773 JSTaggedValue result = ContainersTreeMap::GetHigherKey(callInfo);
774 TestHelper::TearDownFrame(thread, prev);
775 if (i >= NODE_NUMBERS - 1) {
776 EXPECT_EQ(result, JSTaggedValue::Undefined());
777 } else {
778 EXPECT_EQ(result, JSTaggedValue(i + 1));
779 }
780 }
781
782 // test add string
783 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
784 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
785 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
786 std::string myKey("mykey");
787 std::string myValue("myvalue");
788 for (int i = 0; i < NODE_NUMBERS; i++) {
789 std::string ikey = myKey + std::to_string(i);
790 std::string ivalue = myValue + std::to_string(i);
791 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
792 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
793
794 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
795 callInfo->SetFunction(JSTaggedValue::Undefined());
796 callInfo->SetThis(tmap.GetTaggedValue());
797 callInfo->SetCallArg(0, key.GetTaggedValue());
798 callInfo->SetCallArg(1, value.GetTaggedValue());
799 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
800 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
801 TestHelper::TearDownFrame(thread, prev);
802 EXPECT_TRUE(result.IsJSAPITreeMap());
803 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
804 }
805
806 // test getLowerKey
807 for (int i = 0; i <= NODE_NUMBERS; i++) {
808 std::string ikey = myKey + std::to_string(i);
809 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
810 std::string ivalue = myKey+ std::to_string(i - 1);
811 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
812 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
813
814 callInfo->SetFunction(JSTaggedValue::Undefined());
815 callInfo->SetThis(tmap.GetTaggedValue());
816 callInfo->SetCallArg(0, key.GetTaggedValue());
817
818 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
819 JSTaggedValue result = ContainersTreeMap::GetLowerKey(callInfo);
820 TestHelper::TearDownFrame(thread, prev);
821 if (i == 0) {
822 EXPECT_EQ(result, JSTaggedValue(NODE_NUMBERS - 1));
823 } else {
824 EXPECT_TRUE(JSTaggedValue::SameValue(result, value.GetTaggedValue()));
825 }
826 }
827 // test getHigherKey
828 for (int i = 0; i <= NODE_NUMBERS; i++) {
829 std::string ikey = myKey + std::to_string(i);
830 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
831 std::string ivalue = myKey+ std::to_string(i + 1);
832 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
833
834 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
835 callInfo->SetFunction(JSTaggedValue::Undefined());
836 callInfo->SetThis(tmap.GetTaggedValue());
837 callInfo->SetCallArg(0, key.GetTaggedValue());
838
839 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
840 JSTaggedValue result = ContainersTreeMap::GetHigherKey(callInfo);
841 TestHelper::TearDownFrame(thread, prev);
842 if (i >= NODE_NUMBERS - 1) {
843 EXPECT_EQ(result, JSTaggedValue::Undefined());
844 } else {
845 EXPECT_TRUE(JSTaggedValue::SameValue(result, value.GetTaggedValue()));
846 }
847 }
848 }
849
850 // treemap.keys(), treemap.values(), treemap.entries()
HWTEST_F_L0(ContainersTreeMapTest,KeysAndValuesAndEntries)851 HWTEST_F_L0(ContainersTreeMapTest, KeysAndValuesAndEntries)
852 {
853 constexpr int NODE_NUMBERS = 8;
854 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
855 for (int i = 0; i < NODE_NUMBERS; i++) {
856 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
857 callInfo->SetFunction(JSTaggedValue::Undefined());
858 callInfo->SetThis(tmap.GetTaggedValue());
859 callInfo->SetCallArg(0, JSTaggedValue(i));
860 callInfo->SetCallArg(1, JSTaggedValue(i));
861
862 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
863 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
864 TestHelper::TearDownFrame(thread, prev);
865 EXPECT_TRUE(result.IsJSAPITreeMap());
866 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
867 }
868
869 // test keys
870 auto callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
871 callInfo1->SetFunction(JSTaggedValue::Undefined());
872 callInfo1->SetThis(tmap.GetTaggedValue());
873 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo1);
874 JSHandle<JSTaggedValue> iterKeys(thread, ContainersTreeMap::Keys(callInfo1));
875 TestHelper::TearDownFrame(thread, prev1);
876 EXPECT_TRUE(iterKeys->IsJSAPITreeMapIterator());
877
878 JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
879 for (int i = 0; i < NODE_NUMBERS; i++) {
880 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
881 callInfo->SetFunction(JSTaggedValue::Undefined());
882 callInfo->SetThis(iterKeys.GetTaggedValue());
883
884 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
885 result.Update(JSAPITreeMapIterator::Next(callInfo));
886 TestHelper::TearDownFrame(thread, prev);
887 EXPECT_EQ(i, JSIterator::IteratorValue(thread, result)->GetInt());
888 }
889
890 // test values
891 callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
892 callInfo1->SetFunction(JSTaggedValue::Undefined());
893 callInfo1->SetThis(tmap.GetTaggedValue());
894 auto prev2 = TestHelper::SetupFrame(thread, callInfo1);
895 JSHandle<JSTaggedValue> iterValues(thread, ContainersTreeMap::Values(callInfo1));
896 TestHelper::TearDownFrame(thread, prev2);
897 EXPECT_TRUE(iterValues->IsJSAPITreeMapIterator());
898
899 for (int i = 0; i < NODE_NUMBERS; i++) {
900 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
901 callInfo->SetFunction(JSTaggedValue::Undefined());
902 callInfo->SetThis(iterValues.GetTaggedValue());
903
904 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
905 result.Update(JSAPITreeMapIterator::Next(callInfo));
906 TestHelper::TearDownFrame(thread, prev);
907 EXPECT_EQ(i, JSIterator::IteratorValue(thread, result)->GetInt());
908 }
909
910 // test add string
911 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
912 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
913 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
914 std::string myKey("mykey");
915 std::string myValue("myvalue");
916 for (int i = 0; i < NODE_NUMBERS; i++) {
917 std::string ikey = myKey + std::to_string(i);
918 std::string ivalue = myValue + std::to_string(i);
919 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
920 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
921
922 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
923 callInfo->SetFunction(JSTaggedValue::Undefined());
924 callInfo->SetThis(tmap.GetTaggedValue());
925 callInfo->SetCallArg(0, key.GetTaggedValue());
926 callInfo->SetCallArg(1, value.GetTaggedValue());
927 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
928 JSTaggedValue result1 = ContainersTreeMap::Set(callInfo);
929 TestHelper::TearDownFrame(thread, prev);
930 EXPECT_TRUE(result1.IsJSAPITreeMap());
931 EXPECT_EQ(JSAPITreeMap::Cast(result1.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
932 }
933 // test keys after add
934 for (int i = 0; i < NODE_NUMBERS; i++) {
935 std::string ikey = myKey + std::to_string(i);
936 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
937
938 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
939 callInfo->SetFunction(JSTaggedValue::Undefined());
940 callInfo->SetThis(iterKeys.GetTaggedValue());
941
942 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
943 result.Update(JSAPITreeMapIterator::Next(callInfo));
944 TestHelper::TearDownFrame(thread, prev);
945 JSHandle<JSTaggedValue> itRes = JSIterator::IteratorValue(thread, result);
946 EXPECT_TRUE(JSTaggedValue::SameValue(key, itRes));
947 }
948 // test values after add
949 for (int i = 0; i < NODE_NUMBERS; i++) {
950 std::string ivalue = myValue + std::to_string(i);
951 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
952
953 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
954 callInfo->SetFunction(JSTaggedValue::Undefined());
955 callInfo->SetThis(iterValues.GetTaggedValue());
956
957 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
958 result.Update(JSAPITreeMapIterator::Next(callInfo));
959 TestHelper::TearDownFrame(thread, prev);
960 EXPECT_TRUE(JSTaggedValue::SameValue(value, JSIterator::IteratorValue(thread, result)));
961 }
962
963 // test entries
964 {
965 auto callInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
966 callInfo3->SetFunction(JSTaggedValue::Undefined());
967 callInfo3->SetThis(tmap.GetTaggedValue());
968 [[maybe_unused]] auto prev3 = TestHelper::SetupFrame(thread, callInfo3);
969 JSHandle<JSTaggedValue> iter(thread, ContainersTreeMap::Entries(callInfo3));
970 TestHelper::TearDownFrame(thread, prev3);
971 EXPECT_TRUE(iter->IsJSAPITreeMapIterator());
972
973 JSHandle<JSTaggedValue> first(thread, JSTaggedValue(0));
974 JSHandle<JSTaggedValue> second(thread, JSTaggedValue(1));
975 JSMutableHandle<JSTaggedValue> result1(thread, JSTaggedValue::Undefined());
976 JSMutableHandle<JSTaggedValue> entries(thread, JSTaggedValue::Undefined());
977 for (int i = 0; i < NODE_NUMBERS; i++) {
978 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
979 callInfo->SetFunction(JSTaggedValue::Undefined());
980 callInfo->SetThis(iter.GetTaggedValue());
981
982 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
983 result1.Update(JSAPITreeMapIterator::Next(callInfo));
984 TestHelper::TearDownFrame(thread, prev);
985 entries.Update(JSIterator::IteratorValue(thread, result1).GetTaggedValue());
986 EXPECT_EQ(i, JSObject::GetProperty(thread, entries, first).GetValue()->GetInt());
987 EXPECT_EQ(i, JSObject::GetProperty(thread, entries, second).GetValue()->GetInt());
988 }
989
990 for (int i = 0; i < NODE_NUMBERS; i++) {
991 std::string ikey = myKey + std::to_string(i);
992 std::string ivalue = myValue + std::to_string(i);
993 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
994 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
995
996 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
997 callInfo->SetFunction(JSTaggedValue::Undefined());
998 callInfo->SetThis(iter.GetTaggedValue());
999
1000 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1001 result.Update(JSAPITreeMapIterator::Next(callInfo));
1002 TestHelper::TearDownFrame(thread, prev);
1003 entries.Update(JSIterator::IteratorValue(thread, result).GetTaggedValue());
1004 EXPECT_TRUE(JSTaggedValue::SameValue(key, JSObject::GetProperty(thread, entries, first).GetValue()));
1005 EXPECT_TRUE(JSTaggedValue::SameValue(value, JSObject::GetProperty(thread, entries, second).GetValue()));
1006 }
1007 }
1008 }
1009
1010 // treemap.replace(key, value)
HWTEST_F_L0(ContainersTreeMapTest,Replace)1011 HWTEST_F_L0(ContainersTreeMapTest, Replace)
1012 {
1013 constexpr int NODE_NUMBERS = 8;
1014 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
1015 for (int i = 0; i < NODE_NUMBERS; i++) {
1016 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1017 callInfo->SetFunction(JSTaggedValue::Undefined());
1018 callInfo->SetThis(tmap.GetTaggedValue());
1019 callInfo->SetCallArg(0, JSTaggedValue(i));
1020 callInfo->SetCallArg(1, JSTaggedValue(i));
1021
1022 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1023 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1024 TestHelper::TearDownFrame(thread, prev);
1025 EXPECT_TRUE(result.IsJSAPITreeMap());
1026 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
1027 }
1028
1029 {
1030 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1031 callInfo->SetFunction(JSTaggedValue::Undefined());
1032 callInfo->SetThis(tmap.GetTaggedValue());
1033 callInfo->SetCallArg(0, JSTaggedValue(NODE_NUMBERS / 2));
1034 callInfo->SetCallArg(1, JSTaggedValue(NODE_NUMBERS));
1035
1036 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1037 JSTaggedValue result = ContainersTreeMap::Replace(callInfo);
1038 TestHelper::TearDownFrame(thread, prev);
1039 EXPECT_EQ(result, JSTaggedValue::True());
1040 EXPECT_EQ(tmap->GetSize(), NODE_NUMBERS);
1041 }
1042 for (int i = 0; i < NODE_NUMBERS; i++) {
1043 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1044 callInfo->SetFunction(JSTaggedValue::Undefined());
1045 callInfo->SetThis(tmap.GetTaggedValue());
1046 callInfo->SetCallArg(0, JSTaggedValue(i));
1047
1048 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1049 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1050 TestHelper::TearDownFrame(thread, prev);
1051 if (i == (NODE_NUMBERS / 2)) {
1052 EXPECT_EQ(result, JSTaggedValue(NODE_NUMBERS));
1053 } else {
1054 EXPECT_EQ(result, JSTaggedValue(i));
1055 }
1056 }
1057
1058 // test add string
1059 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1060 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1061 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
1062 std::string myKey("mykey");
1063 std::string myValue("myvalue");
1064 for (int i = 0; i < NODE_NUMBERS; i++) {
1065 std::string ikey = myKey + std::to_string(i);
1066 std::string ivalue = myValue + std::to_string(i);
1067 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1068 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
1069
1070 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1071 callInfo->SetFunction(JSTaggedValue::Undefined());
1072 callInfo->SetThis(tmap.GetTaggedValue());
1073 callInfo->SetCallArg(0, key.GetTaggedValue());
1074 callInfo->SetCallArg(1, value.GetTaggedValue());
1075 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1076 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1077 TestHelper::TearDownFrame(thread, prev);
1078 EXPECT_TRUE(result.IsJSAPITreeMap());
1079 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
1080 }
1081
1082 {
1083 std::string ikey = myKey + std::to_string(NODE_NUMBERS / 2);
1084 std::string ivalue = myValue + std::to_string(NODE_NUMBERS);
1085 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1086 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
1087 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1088 callInfo->SetFunction(JSTaggedValue::Undefined());
1089 callInfo->SetThis(tmap.GetTaggedValue());
1090 callInfo->SetCallArg(0, key.GetTaggedValue());
1091 callInfo->SetCallArg(1, value.GetTaggedValue());
1092
1093 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1094 JSTaggedValue result = ContainersTreeMap::Replace(callInfo);
1095 TestHelper::TearDownFrame(thread, prev);
1096 EXPECT_EQ(result, JSTaggedValue::True());
1097 EXPECT_EQ(tmap->GetSize(), NODE_NUMBERS * 2);
1098 }
1099 for (int i = 0; i < NODE_NUMBERS; i++) {
1100 std::string ikey = myKey + std::to_string(i);
1101 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1102 std::string ivalue;
1103 if (i == (NODE_NUMBERS / 2)) {
1104 ivalue = myValue + std::to_string(NODE_NUMBERS);
1105 } else {
1106 ivalue = myValue + std::to_string(i);
1107 }
1108 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
1109 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1110 callInfo->SetFunction(JSTaggedValue::Undefined());
1111 callInfo->SetThis(tmap.GetTaggedValue());
1112 callInfo->SetCallArg(0, key.GetTaggedValue());
1113
1114 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1115 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1116 TestHelper::TearDownFrame(thread, prev);
1117 EXPECT_TRUE(JSTaggedValue::SameValue(result, value.GetTaggedValue()));
1118 }
1119 }
1120
1121 // treemap.ForEach(callbackfn, this)
HWTEST_F_L0(ContainersTreeMapTest,ForEach)1122 HWTEST_F_L0(ContainersTreeMapTest, ForEach)
1123 {
1124 constexpr int NODE_NUMBERS = 8;
1125 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
1126 for (int i = 0; i < NODE_NUMBERS; i++) {
1127 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1128 callInfo->SetFunction(JSTaggedValue::Undefined());
1129 callInfo->SetThis(tmap.GetTaggedValue());
1130 callInfo->SetCallArg(0, JSTaggedValue(i));
1131 callInfo->SetCallArg(1, JSTaggedValue(i));
1132
1133 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1134 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1135 TestHelper::TearDownFrame(thread, prev);
1136 EXPECT_TRUE(result.IsJSAPITreeMap());
1137 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
1138 }
1139 // test foreach function with TestForEachFunc;
1140 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1141 JSHandle<JSAPITreeMap> dmap = CreateJSAPITreeMap();
1142 {
1143 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1144 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
1145 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1146 callInfo->SetFunction(JSTaggedValue::Undefined());
1147 callInfo->SetThis(tmap.GetTaggedValue());
1148 callInfo->SetCallArg(0, func.GetTaggedValue());
1149 callInfo->SetCallArg(1, dmap.GetTaggedValue());
1150
1151 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1152 ContainersTreeMap::ForEach(callInfo);
1153 TestHelper::TearDownFrame(thread, prev);
1154 }
1155
1156 EXPECT_EQ(dmap->GetSize(), NODE_NUMBERS);
1157 for (int i = 0; i < NODE_NUMBERS; i++) {
1158 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1159 callInfo->SetFunction(JSTaggedValue::Undefined());
1160 callInfo->SetThis(tmap.GetTaggedValue());
1161 callInfo->SetCallArg(0, JSTaggedValue(i));
1162
1163 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1164 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1165 TestHelper::TearDownFrame(thread, prev);
1166 EXPECT_EQ(result, JSTaggedValue(i * 2));
1167 }
1168
1169 for (int i = 0; i < NODE_NUMBERS; i++) {
1170 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1171 callInfo->SetFunction(JSTaggedValue::Undefined());
1172 callInfo->SetThis(dmap.GetTaggedValue());
1173 callInfo->SetCallArg(0, JSTaggedValue(i));
1174
1175 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1176 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1177 TestHelper::TearDownFrame(thread, prev);
1178 EXPECT_EQ(result, JSTaggedValue(i));
1179 }
1180
1181 // test add string
1182 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1183 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
1184 std::string myKey("mykey");
1185 std::string myValue("myvalue");
1186 for (int i = 0; i < NODE_NUMBERS; i++) {
1187 std::string ikey = myKey + std::to_string(i);
1188 std::string ivalue = myValue + std::to_string(i);
1189 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1190 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
1191
1192 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1193 callInfo->SetFunction(JSTaggedValue::Undefined());
1194 callInfo->SetThis(tmap.GetTaggedValue());
1195 callInfo->SetCallArg(0, key.GetTaggedValue());
1196 callInfo->SetCallArg(1, value.GetTaggedValue());
1197 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1198 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1199 TestHelper::TearDownFrame(thread, prev);
1200 EXPECT_TRUE(result.IsJSAPITreeMap());
1201 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
1202 }
1203
1204 // test foreach function with TestForEachFunc;
1205 {
1206 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1207 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
1208 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1209 callInfo->SetFunction(JSTaggedValue::Undefined());
1210 callInfo->SetThis(tmap.GetTaggedValue());
1211 callInfo->SetCallArg(0, func.GetTaggedValue());
1212 callInfo->SetCallArg(1, dmap.GetTaggedValue());
1213
1214 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1215 ContainersTreeMap::ForEach(callInfo);
1216 TestHelper::TearDownFrame(thread, prev);
1217 }
1218
1219 EXPECT_EQ(dmap->GetSize(), NODE_NUMBERS * 2);
1220 for (int i = 0; i < NODE_NUMBERS; i++) {
1221 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1222 callInfo->SetFunction(JSTaggedValue::Undefined());
1223 callInfo->SetThis(tmap.GetTaggedValue());
1224 callInfo->SetCallArg(0, JSTaggedValue(i));
1225
1226 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1227 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1228 TestHelper::TearDownFrame(thread, prev);
1229 EXPECT_EQ(result, JSTaggedValue(i * 4)); // 4 means 4 times
1230 }
1231
1232 for (int i = 0; i < NODE_NUMBERS; i++) {
1233 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1234 callInfo->SetFunction(JSTaggedValue::Undefined());
1235 callInfo->SetThis(dmap.GetTaggedValue());
1236 callInfo->SetCallArg(0, JSTaggedValue(i));
1237
1238 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1239 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1240 TestHelper::TearDownFrame(thread, prev);
1241 EXPECT_EQ(result, JSTaggedValue(i * 2));
1242 }
1243
1244 for (int i = 0; i < NODE_NUMBERS; i++) {
1245 std::string ikey = myKey + std::to_string(i);
1246 std::string ivalue = myValue + std::to_string(i);
1247 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1248 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
1249
1250 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1251 callInfo->SetFunction(JSTaggedValue::Undefined());
1252 callInfo->SetThis(dmap.GetTaggedValue());
1253 callInfo->SetCallArg(0, key.GetTaggedValue());
1254
1255 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1256 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1257 TestHelper::TearDownFrame(thread, prev);
1258 EXPECT_EQ(result, value.GetTaggedValue());
1259 }
1260 }
1261
HWTEST_F_L0(ContainersTreeMapTest,CustomCompareFunctionTest)1262 HWTEST_F_L0(ContainersTreeMapTest, CustomCompareFunctionTest)
1263 {
1264 constexpr int NODE_NUMBERS = 8;
1265 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1266 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1267 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestCompareFunction));
1268 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap(func.GetTaggedValue());
1269 for (int i = 0; i < NODE_NUMBERS; i++) {
1270 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1271 callInfo->SetFunction(JSTaggedValue::Undefined());
1272 callInfo->SetThis(tmap.GetTaggedValue());
1273 callInfo->SetCallArg(0, JSTaggedValue(i));
1274 callInfo->SetCallArg(1, JSTaggedValue(i));
1275 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1276 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1277 TestHelper::TearDownFrame(thread, prev);
1278 EXPECT_TRUE(result.IsJSAPITreeMap());
1279 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
1280 }
1281
1282 // test add string
1283 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1284 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
1285 std::string myKey("mykey");
1286 std::string myValue("myvalue");
1287 for (int i = 0; i < NODE_NUMBERS; i++) {
1288 std::string ikey = myKey + std::to_string(i);
1289 std::string ivalue = myValue + std::to_string(i);
1290 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1291 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
1292 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1293 callInfo->SetFunction(JSTaggedValue::Undefined());
1294 callInfo->SetThis(tmap.GetTaggedValue());
1295 callInfo->SetCallArg(0, key.GetTaggedValue());
1296 callInfo->SetCallArg(1, value.GetTaggedValue());
1297 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1298 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1299 TestHelper::TearDownFrame(thread, prev);
1300 EXPECT_TRUE(result.IsJSAPITreeMap());
1301 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), NODE_NUMBERS + i + 1);
1302 }
1303
1304 // test sort
1305 auto callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1306 callInfo1->SetFunction(JSTaggedValue::Undefined());
1307 callInfo1->SetThis(tmap.GetTaggedValue());
1308 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo1);
1309 JSHandle<JSTaggedValue> iterKeys(thread, ContainersTreeMap::Keys(callInfo1));
1310 TestHelper::TearDownFrame(thread, prev1);
1311 EXPECT_TRUE(iterKeys->IsJSAPITreeMapIterator());
1312
1313 JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
1314 for (int i = 0; i < NODE_NUMBERS; i++) {
1315 std::string ikey = myKey + std::to_string(NODE_NUMBERS - 1 - i);
1316 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1317 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1318 callInfo->SetFunction(JSTaggedValue::Undefined());
1319 callInfo->SetThis(iterKeys.GetTaggedValue());
1320
1321 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1322 result.Update(JSAPITreeMapIterator::Next(callInfo));
1323 TestHelper::TearDownFrame(thread, prev);
1324 JSHandle<JSTaggedValue> itRes = JSIterator::IteratorValue(thread, result);
1325 EXPECT_TRUE(JSTaggedValue::SameValue(key, itRes));
1326 }
1327 for (int i = 0; i < NODE_NUMBERS; i++) {
1328 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1329 callInfo->SetFunction(JSTaggedValue::Undefined());
1330 callInfo->SetThis(iterKeys.GetTaggedValue());
1331
1332 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1333 result.Update(JSAPITreeMapIterator::Next(callInfo));
1334 TestHelper::TearDownFrame(thread, prev);
1335 EXPECT_EQ((NODE_NUMBERS - 1 - i), JSIterator::IteratorValue(thread, result)->GetInt());
1336 }
1337 }
1338
1339 // treemap.isEmpty()
HWTEST_F_L0(ContainersTreeMapTest,IsEmpty)1340 HWTEST_F_L0(ContainersTreeMapTest, IsEmpty)
1341 {
1342 constexpr int NODE_NUMBERS = 8;
1343 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
1344 for (int i = 0; i < NODE_NUMBERS; i++) {
1345 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1346 callInfo->SetFunction(JSTaggedValue::Undefined());
1347 callInfo->SetThis(tmap.GetTaggedValue());
1348 callInfo->SetCallArg(0, JSTaggedValue(i));
1349 callInfo->SetCallArg(1, JSTaggedValue(i));
1350
1351 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1352 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1353 TestHelper::TearDownFrame(thread, prev);
1354 EXPECT_TRUE(result.IsJSAPITreeMap());
1355 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(), i + 1);
1356 JSTaggedValue isEmpty = ContainersTreeMap::IsEmpty(callInfo);
1357 EXPECT_EQ(isEmpty, JSTaggedValue::False());
1358 }
1359
1360 // test clear
1361 {
1362 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1363 callInfo->SetFunction(JSTaggedValue::Undefined());
1364 callInfo->SetThis(tmap.GetTaggedValue());
1365
1366 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1367 ContainersTreeMap::Clear(callInfo);
1368 TestHelper::TearDownFrame(thread, prev);
1369 JSTaggedValue isEmpty = ContainersTreeMap::IsEmpty(callInfo);
1370 EXPECT_EQ(isEmpty, JSTaggedValue::True());
1371 }
1372 }
1373
HWTEST_F_L0(ContainersTreeMapTest,ProxyOfGetLength)1374 HWTEST_F_L0(ContainersTreeMapTest, ProxyOfGetLength)
1375 {
1376 constexpr uint32_t NODE_NUMBERS = 8;
1377 JSHandle<JSAPITreeMap> treeMap = CreateJSAPITreeMap();
1378 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1379 callInfo->SetFunction(JSTaggedValue::Undefined());
1380 JSHandle<JSProxy> proxy = CreateJSProxyHandle(thread);
1381 proxy->SetTarget(thread, treeMap.GetTaggedValue());
1382 callInfo->SetThis(proxy.GetTaggedValue());
1383
1384 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
1385 callInfo->SetCallArg(0, JSTaggedValue(i));
1386 callInfo->SetCallArg(1, JSTaggedValue(i + 1));
1387 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1388 ContainersTreeMap::Set(callInfo);
1389 TestHelper::TearDownFrame(thread, prev);
1390
1391 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo);
1392 JSTaggedValue retult = ContainersTreeMap::GetLength(callInfo);
1393 TestHelper::TearDownFrame(thread, prev1);
1394 EXPECT_EQ(retult, JSTaggedValue(i + 1));
1395 }
1396 }
1397
HWTEST_F_L0(ContainersTreeMapTest,ExceptionReturn1)1398 HWTEST_F_L0(ContainersTreeMapTest, ExceptionReturn1)
1399 {
1400 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, SetAll);
1401 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, Set);
1402 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, Get);
1403 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, Remove);
1404 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, HasKey);
1405 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, HasValue);
1406 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, GetFirstKey);
1407 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, GetLastKey);
1408 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, Clear);
1409 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, GetLowerKey);
1410 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, GetHigherKey);
1411
1412 JSHandle<JSAPITreeMap> treeMap = CreateJSAPITreeMap();
1413 {
1414 auto callInfo = NewEmptyCallInfo(thread);
1415 callInfo->SetThis(treeMap.GetTaggedValue());
1416 CONTAINERS_API_EXCEPTION_TEST(ContainersTreeMap, SetAll, callInfo);
1417 }
1418 }
1419
HWTEST_F_L0(ContainersTreeMapTest,ExceptionReturn2)1420 HWTEST_F_L0(ContainersTreeMapTest, ExceptionReturn2)
1421 {
1422 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, Replace);
1423 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, ForEach);
1424 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, GetLength);
1425 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, IsEmpty);
1426 }
1427 } // namespace panda::test
1428