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
29using namespace panda::ecmascript;
30using namespace panda::ecmascript::containers;
31
32namespace panda::test {
33class ContainersTreeMapTest : public testing::Test {
34public:
35    static void SetUpTestCase()
36    {
37        GTEST_LOG_(INFO) << "SetUpTestCase";
38    }
39
40    static void TearDownTestCase()
41    {
42        GTEST_LOG_(INFO) << "TearDownCase";
43    }
44
45    void SetUp() override
46    {
47        TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
48    }
49
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:
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
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
115protected:
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
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()
156HWTEST_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)
188HWTEST_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)
260HWTEST_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)
351HWTEST_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()
453HWTEST_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()
544HWTEST_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)
636HWTEST_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)
731HWTEST_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()
851HWTEST_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)
1011HWTEST_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)
1122HWTEST_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
1262HWTEST_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()
1340HWTEST_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
1374HWTEST_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
1398HWTEST_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
1420HWTEST_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