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(thread);
176 ASSERT_EQ(resultProto, funcProto);
177 int size = mapHandle->GetSize(thread);
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(thread), 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(thread), 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(thread), 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(thread), 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(thread), 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(thread, rvalue, value.GetTaggedValue()));
346 }
347 EXPECT_EQ(tmap->GetSize(thread), (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(thread), 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(thread), 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(thread), 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(thread), 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(thread), 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(thread), 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(thread), 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(thread), 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(thread), 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(thread), 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(thread), 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(thread), 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(thread, result, value.GetTaggedValue()));
726 }
727 EXPECT_EQ(dmap->GetSize(thread), 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(thread), 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(thread), 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(thread, 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(thread, 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(thread), 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(thread), 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(thread, 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(thread, 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(thread, key,
1005 JSObject::GetProperty(thread, entries, first).GetValue()));
1006 EXPECT_TRUE(JSTaggedValue::SameValue(thread, value,
1007 JSObject::GetProperty(thread, entries, second).GetValue()));
1008 }
1009 }
1010 }
1011
1012 // treemap.replace(key, value)
HWTEST_F_L0(ContainersTreeMapTest,Replace)1013 HWTEST_F_L0(ContainersTreeMapTest, Replace)
1014 {
1015 constexpr int NODE_NUMBERS = 8;
1016 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
1017 for (int i = 0; i < NODE_NUMBERS; i++) {
1018 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1019 callInfo->SetFunction(JSTaggedValue::Undefined());
1020 callInfo->SetThis(tmap.GetTaggedValue());
1021 callInfo->SetCallArg(0, JSTaggedValue(i));
1022 callInfo->SetCallArg(1, JSTaggedValue(i));
1023
1024 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1025 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1026 TestHelper::TearDownFrame(thread, prev);
1027 EXPECT_TRUE(result.IsJSAPITreeMap());
1028 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(thread), i + 1);
1029 }
1030
1031 {
1032 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1033 callInfo->SetFunction(JSTaggedValue::Undefined());
1034 callInfo->SetThis(tmap.GetTaggedValue());
1035 callInfo->SetCallArg(0, JSTaggedValue(NODE_NUMBERS / 2));
1036 callInfo->SetCallArg(1, JSTaggedValue(NODE_NUMBERS));
1037
1038 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1039 JSTaggedValue result = ContainersTreeMap::Replace(callInfo);
1040 TestHelper::TearDownFrame(thread, prev);
1041 EXPECT_EQ(result, JSTaggedValue::True());
1042 EXPECT_EQ(tmap->GetSize(thread), NODE_NUMBERS);
1043 }
1044 for (int i = 0; i < NODE_NUMBERS; i++) {
1045 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1046 callInfo->SetFunction(JSTaggedValue::Undefined());
1047 callInfo->SetThis(tmap.GetTaggedValue());
1048 callInfo->SetCallArg(0, JSTaggedValue(i));
1049
1050 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1051 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1052 TestHelper::TearDownFrame(thread, prev);
1053 if (i == (NODE_NUMBERS / 2)) {
1054 EXPECT_EQ(result, JSTaggedValue(NODE_NUMBERS));
1055 } else {
1056 EXPECT_EQ(result, JSTaggedValue(i));
1057 }
1058 }
1059
1060 // test add string
1061 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1062 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1063 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
1064 std::string myKey("mykey");
1065 std::string myValue("myvalue");
1066 for (int i = 0; i < NODE_NUMBERS; i++) {
1067 std::string ikey = myKey + std::to_string(i);
1068 std::string ivalue = myValue + std::to_string(i);
1069 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1070 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
1071
1072 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1073 callInfo->SetFunction(JSTaggedValue::Undefined());
1074 callInfo->SetThis(tmap.GetTaggedValue());
1075 callInfo->SetCallArg(0, key.GetTaggedValue());
1076 callInfo->SetCallArg(1, value.GetTaggedValue());
1077 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1078 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1079 TestHelper::TearDownFrame(thread, prev);
1080 EXPECT_TRUE(result.IsJSAPITreeMap());
1081 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(thread), NODE_NUMBERS + i + 1);
1082 }
1083
1084 {
1085 std::string ikey = myKey + std::to_string(NODE_NUMBERS / 2);
1086 std::string ivalue = myValue + std::to_string(NODE_NUMBERS);
1087 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1088 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
1089 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1090 callInfo->SetFunction(JSTaggedValue::Undefined());
1091 callInfo->SetThis(tmap.GetTaggedValue());
1092 callInfo->SetCallArg(0, key.GetTaggedValue());
1093 callInfo->SetCallArg(1, value.GetTaggedValue());
1094
1095 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1096 JSTaggedValue result = ContainersTreeMap::Replace(callInfo);
1097 TestHelper::TearDownFrame(thread, prev);
1098 EXPECT_EQ(result, JSTaggedValue::True());
1099 EXPECT_EQ(tmap->GetSize(thread), NODE_NUMBERS * 2);
1100 }
1101 for (int i = 0; i < NODE_NUMBERS; i++) {
1102 std::string ikey = myKey + std::to_string(i);
1103 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1104 std::string ivalue;
1105 if (i == (NODE_NUMBERS / 2)) {
1106 ivalue = myValue + std::to_string(NODE_NUMBERS);
1107 } else {
1108 ivalue = myValue + std::to_string(i);
1109 }
1110 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
1111 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1112 callInfo->SetFunction(JSTaggedValue::Undefined());
1113 callInfo->SetThis(tmap.GetTaggedValue());
1114 callInfo->SetCallArg(0, key.GetTaggedValue());
1115
1116 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1117 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1118 TestHelper::TearDownFrame(thread, prev);
1119 EXPECT_TRUE(JSTaggedValue::SameValue(thread, result, value.GetTaggedValue()));
1120 }
1121 }
1122
1123 // treemap.ForEach(callbackfn, this)
HWTEST_F_L0(ContainersTreeMapTest,ForEach)1124 HWTEST_F_L0(ContainersTreeMapTest, ForEach)
1125 {
1126 constexpr int NODE_NUMBERS = 8;
1127 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
1128 for (int i = 0; i < NODE_NUMBERS; i++) {
1129 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1130 callInfo->SetFunction(JSTaggedValue::Undefined());
1131 callInfo->SetThis(tmap.GetTaggedValue());
1132 callInfo->SetCallArg(0, JSTaggedValue(i));
1133 callInfo->SetCallArg(1, JSTaggedValue(i));
1134
1135 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1136 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1137 TestHelper::TearDownFrame(thread, prev);
1138 EXPECT_TRUE(result.IsJSAPITreeMap());
1139 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(thread), i + 1);
1140 }
1141 // test foreach function with TestForEachFunc;
1142 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1143 JSHandle<JSAPITreeMap> dmap = CreateJSAPITreeMap();
1144 {
1145 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1146 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
1147 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1148 callInfo->SetFunction(JSTaggedValue::Undefined());
1149 callInfo->SetThis(tmap.GetTaggedValue());
1150 callInfo->SetCallArg(0, func.GetTaggedValue());
1151 callInfo->SetCallArg(1, dmap.GetTaggedValue());
1152
1153 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1154 ContainersTreeMap::ForEach(callInfo);
1155 TestHelper::TearDownFrame(thread, prev);
1156 }
1157
1158 EXPECT_EQ(dmap->GetSize(thread), NODE_NUMBERS);
1159 for (int i = 0; i < NODE_NUMBERS; i++) {
1160 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1161 callInfo->SetFunction(JSTaggedValue::Undefined());
1162 callInfo->SetThis(tmap.GetTaggedValue());
1163 callInfo->SetCallArg(0, JSTaggedValue(i));
1164
1165 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1166 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1167 TestHelper::TearDownFrame(thread, prev);
1168 EXPECT_EQ(result, JSTaggedValue(i * 2));
1169 }
1170
1171 for (int i = 0; i < NODE_NUMBERS; i++) {
1172 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1173 callInfo->SetFunction(JSTaggedValue::Undefined());
1174 callInfo->SetThis(dmap.GetTaggedValue());
1175 callInfo->SetCallArg(0, JSTaggedValue(i));
1176
1177 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1178 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1179 TestHelper::TearDownFrame(thread, prev);
1180 EXPECT_EQ(result, JSTaggedValue(i));
1181 }
1182
1183 // test add string
1184 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1185 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
1186 std::string myKey("mykey");
1187 std::string myValue("myvalue");
1188 for (int i = 0; i < NODE_NUMBERS; i++) {
1189 std::string ikey = myKey + std::to_string(i);
1190 std::string ivalue = myValue + std::to_string(i);
1191 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1192 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
1193
1194 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1195 callInfo->SetFunction(JSTaggedValue::Undefined());
1196 callInfo->SetThis(tmap.GetTaggedValue());
1197 callInfo->SetCallArg(0, key.GetTaggedValue());
1198 callInfo->SetCallArg(1, value.GetTaggedValue());
1199 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1200 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1201 TestHelper::TearDownFrame(thread, prev);
1202 EXPECT_TRUE(result.IsJSAPITreeMap());
1203 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(thread), NODE_NUMBERS + i + 1);
1204 }
1205
1206 // test foreach function with TestForEachFunc;
1207 {
1208 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1209 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
1210 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1211 callInfo->SetFunction(JSTaggedValue::Undefined());
1212 callInfo->SetThis(tmap.GetTaggedValue());
1213 callInfo->SetCallArg(0, func.GetTaggedValue());
1214 callInfo->SetCallArg(1, dmap.GetTaggedValue());
1215
1216 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1217 ContainersTreeMap::ForEach(callInfo);
1218 TestHelper::TearDownFrame(thread, prev);
1219 }
1220
1221 EXPECT_EQ(dmap->GetSize(thread), NODE_NUMBERS * 2);
1222 for (int i = 0; i < NODE_NUMBERS; i++) {
1223 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1224 callInfo->SetFunction(JSTaggedValue::Undefined());
1225 callInfo->SetThis(tmap.GetTaggedValue());
1226 callInfo->SetCallArg(0, JSTaggedValue(i));
1227
1228 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1229 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1230 TestHelper::TearDownFrame(thread, prev);
1231 EXPECT_EQ(result, JSTaggedValue(i * 4)); // 4 means 4 times
1232 }
1233
1234 for (int i = 0; i < NODE_NUMBERS; i++) {
1235 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1236 callInfo->SetFunction(JSTaggedValue::Undefined());
1237 callInfo->SetThis(dmap.GetTaggedValue());
1238 callInfo->SetCallArg(0, JSTaggedValue(i));
1239
1240 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1241 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1242 TestHelper::TearDownFrame(thread, prev);
1243 EXPECT_EQ(result, JSTaggedValue(i * 2));
1244 }
1245
1246 for (int i = 0; i < NODE_NUMBERS; i++) {
1247 std::string ikey = myKey + std::to_string(i);
1248 std::string ivalue = myValue + std::to_string(i);
1249 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1250 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
1251
1252 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1253 callInfo->SetFunction(JSTaggedValue::Undefined());
1254 callInfo->SetThis(dmap.GetTaggedValue());
1255 callInfo->SetCallArg(0, key.GetTaggedValue());
1256
1257 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1258 JSTaggedValue result = ContainersTreeMap::Get(callInfo);
1259 TestHelper::TearDownFrame(thread, prev);
1260 EXPECT_EQ(result, value.GetTaggedValue());
1261 }
1262 }
1263
HWTEST_F_L0(ContainersTreeMapTest,CustomCompareFunctionTest)1264 HWTEST_F_L0(ContainersTreeMapTest, CustomCompareFunctionTest)
1265 {
1266 constexpr int NODE_NUMBERS = 8;
1267 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1268 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1269 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestCompareFunction));
1270 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap(func.GetTaggedValue());
1271 for (int i = 0; i < NODE_NUMBERS; i++) {
1272 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1273 callInfo->SetFunction(JSTaggedValue::Undefined());
1274 callInfo->SetThis(tmap.GetTaggedValue());
1275 callInfo->SetCallArg(0, JSTaggedValue(i));
1276 callInfo->SetCallArg(1, JSTaggedValue(i));
1277 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1278 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1279 TestHelper::TearDownFrame(thread, prev);
1280 EXPECT_TRUE(result.IsJSAPITreeMap());
1281 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(thread), i + 1);
1282 }
1283
1284 // test add string
1285 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1286 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
1287 std::string myKey("mykey");
1288 std::string myValue("myvalue");
1289 for (int i = 0; i < NODE_NUMBERS; i++) {
1290 std::string ikey = myKey + std::to_string(i);
1291 std::string ivalue = myValue + std::to_string(i);
1292 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1293 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
1294 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1295 callInfo->SetFunction(JSTaggedValue::Undefined());
1296 callInfo->SetThis(tmap.GetTaggedValue());
1297 callInfo->SetCallArg(0, key.GetTaggedValue());
1298 callInfo->SetCallArg(1, value.GetTaggedValue());
1299 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1300 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1301 TestHelper::TearDownFrame(thread, prev);
1302 EXPECT_TRUE(result.IsJSAPITreeMap());
1303 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(thread), NODE_NUMBERS + i + 1);
1304 }
1305
1306 // test sort
1307 auto callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1308 callInfo1->SetFunction(JSTaggedValue::Undefined());
1309 callInfo1->SetThis(tmap.GetTaggedValue());
1310 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo1);
1311 JSHandle<JSTaggedValue> iterKeys(thread, ContainersTreeMap::Keys(callInfo1));
1312 TestHelper::TearDownFrame(thread, prev1);
1313 EXPECT_TRUE(iterKeys->IsJSAPITreeMapIterator());
1314
1315 JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
1316 for (int i = 0; i < NODE_NUMBERS; i++) {
1317 std::string ikey = myKey + std::to_string(NODE_NUMBERS - 1 - i);
1318 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1319 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1320 callInfo->SetFunction(JSTaggedValue::Undefined());
1321 callInfo->SetThis(iterKeys.GetTaggedValue());
1322
1323 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1324 result.Update(JSAPITreeMapIterator::Next(callInfo));
1325 TestHelper::TearDownFrame(thread, prev);
1326 JSHandle<JSTaggedValue> itRes = JSIterator::IteratorValue(thread, result);
1327 EXPECT_TRUE(JSTaggedValue::SameValue(thread, key, itRes));
1328 }
1329 for (int i = 0; i < NODE_NUMBERS; i++) {
1330 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1331 callInfo->SetFunction(JSTaggedValue::Undefined());
1332 callInfo->SetThis(iterKeys.GetTaggedValue());
1333
1334 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1335 result.Update(JSAPITreeMapIterator::Next(callInfo));
1336 TestHelper::TearDownFrame(thread, prev);
1337 EXPECT_EQ((NODE_NUMBERS - 1 - i), JSIterator::IteratorValue(thread, result)->GetInt());
1338 }
1339 }
1340
1341 // treemap.isEmpty()
HWTEST_F_L0(ContainersTreeMapTest,IsEmpty)1342 HWTEST_F_L0(ContainersTreeMapTest, IsEmpty)
1343 {
1344 constexpr int NODE_NUMBERS = 8;
1345 JSHandle<JSAPITreeMap> tmap = CreateJSAPITreeMap();
1346 for (int i = 0; i < NODE_NUMBERS; i++) {
1347 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1348 callInfo->SetFunction(JSTaggedValue::Undefined());
1349 callInfo->SetThis(tmap.GetTaggedValue());
1350 callInfo->SetCallArg(0, JSTaggedValue(i));
1351 callInfo->SetCallArg(1, JSTaggedValue(i));
1352
1353 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1354 JSTaggedValue result = ContainersTreeMap::Set(callInfo);
1355 TestHelper::TearDownFrame(thread, prev);
1356 EXPECT_TRUE(result.IsJSAPITreeMap());
1357 EXPECT_EQ(JSAPITreeMap::Cast(result.GetTaggedObject())->GetSize(thread), i + 1);
1358 JSTaggedValue isEmpty = ContainersTreeMap::IsEmpty(callInfo);
1359 EXPECT_EQ(isEmpty, JSTaggedValue::False());
1360 }
1361
1362 // test clear
1363 {
1364 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1365 callInfo->SetFunction(JSTaggedValue::Undefined());
1366 callInfo->SetThis(tmap.GetTaggedValue());
1367
1368 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1369 ContainersTreeMap::Clear(callInfo);
1370 TestHelper::TearDownFrame(thread, prev);
1371 JSTaggedValue isEmpty = ContainersTreeMap::IsEmpty(callInfo);
1372 EXPECT_EQ(isEmpty, JSTaggedValue::True());
1373 }
1374 }
1375
HWTEST_F_L0(ContainersTreeMapTest,ProxyOfGetLength)1376 HWTEST_F_L0(ContainersTreeMapTest, ProxyOfGetLength)
1377 {
1378 constexpr uint32_t NODE_NUMBERS = 8;
1379 JSHandle<JSAPITreeMap> treeMap = CreateJSAPITreeMap();
1380 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1381 callInfo->SetFunction(JSTaggedValue::Undefined());
1382 JSHandle<JSProxy> proxy = CreateJSProxyHandle(thread);
1383 proxy->SetTarget(thread, treeMap.GetTaggedValue());
1384 callInfo->SetThis(proxy.GetTaggedValue());
1385
1386 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
1387 callInfo->SetCallArg(0, JSTaggedValue(i));
1388 callInfo->SetCallArg(1, JSTaggedValue(i + 1));
1389 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1390 ContainersTreeMap::Set(callInfo);
1391 TestHelper::TearDownFrame(thread, prev);
1392
1393 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo);
1394 JSTaggedValue retult = ContainersTreeMap::GetLength(callInfo);
1395 TestHelper::TearDownFrame(thread, prev1);
1396 EXPECT_EQ(retult, JSTaggedValue(i + 1));
1397 }
1398 }
1399
HWTEST_F_L0(ContainersTreeMapTest,ExceptionReturn1)1400 HWTEST_F_L0(ContainersTreeMapTest, ExceptionReturn1)
1401 {
1402 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, SetAll);
1403 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, Set);
1404 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, Get);
1405 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, Remove);
1406 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, HasKey);
1407 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, HasValue);
1408 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, GetFirstKey);
1409 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, GetLastKey);
1410 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, Clear);
1411 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, GetLowerKey);
1412 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, GetHigherKey);
1413
1414 JSHandle<JSAPITreeMap> treeMap = CreateJSAPITreeMap();
1415 {
1416 auto callInfo = NewEmptyCallInfo(thread);
1417 callInfo->SetThis(treeMap.GetTaggedValue());
1418 CONTAINERS_API_EXCEPTION_TEST(ContainersTreeMap, SetAll, callInfo);
1419 }
1420 }
1421
HWTEST_F_L0(ContainersTreeMapTest,ExceptionReturn2)1422 HWTEST_F_L0(ContainersTreeMapTest, ExceptionReturn2)
1423 {
1424 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, Replace);
1425 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, ForEach);
1426 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, GetLength);
1427 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeMap, IsEmpty);
1428 }
1429 } // namespace panda::test
1430