• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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