• 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_treeset.h"
18 #include "ecmascript/ecma_runtime_call_info.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_api/js_api_tree_set.h"
21 #include "ecmascript/js_api/js_api_tree_set_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 ContainersTreeSetTest : 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<JSAPITreeSet> set(GetCallArg(argv, 2)); // 2 means the second arg
67             EXPECT_EQ(key.GetTaggedValue(), value.GetTaggedValue());
68             JSAPITreeSet::Delete(thread, set, key);
69 
70             JSHandle<JSAPITreeSet> jsTreeSet(GetThis(argv));
71             JSAPITreeSet::Add(thread, jsTreeSet, key);
72             return JSTaggedValue::Undefined();
73         }
74 
TestCompareFunction(EcmaRuntimeCallInfo * argv)75         static JSTaggedValue TestCompareFunction(EcmaRuntimeCallInfo *argv)
76         {
77             JSThread *thread = argv->GetThread();
78             JSHandle<JSTaggedValue> valueX = GetCallArg(argv, 0);
79             JSHandle<JSTaggedValue> valueY = GetCallArg(argv, 1);
80 
81             if (valueX->IsString() && valueY->IsString()) {
82                 auto xHandle = JSHandle<EcmaString>(valueX);
83                 auto yHandle = JSHandle<EcmaString>(valueY);
84                 int result = EcmaStringAccessor::Compare(thread->GetEcmaVM(), xHandle, yHandle);
85                 if (result < 0) {
86                     return JSTaggedValue(1);
87                 }
88                 if (result == 0) {
89                     return JSTaggedValue(0);
90                 }
91                 return JSTaggedValue(-1);
92             }
93 
94             if (valueX->IsNumber() && valueY->IsString()) {
95                 return JSTaggedValue(1);
96             }
97             if (valueX->IsString() && valueY->IsNumber()) {
98                 return JSTaggedValue(-1);
99             }
100 
101             ComparisonResult res = ComparisonResult::UNDEFINED;
102             if (valueX->IsNumber() && valueY->IsNumber()) {
103                 res = JSTaggedValue::StrictNumberCompare(valueY->GetNumber(), valueX->GetNumber());
104             } else {
105                 res = JSTaggedValue::Compare(thread, valueY, valueX);
106             }
107             return res == ComparisonResult::GREAT ?
108                 JSTaggedValue(1) : (res == ComparisonResult::LESS ? JSTaggedValue(-1) : JSTaggedValue(0));
109         }
110     };
111 
112 protected:
InitializeTreeSetConstructor()113     JSTaggedValue InitializeTreeSetConstructor()
114     {
115         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
116         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
117 
118         JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
119         JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
120         JSHandle<JSTaggedValue> value =
121             JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
122 
123         auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
124         objCallInfo->SetFunction(JSTaggedValue::Undefined());
125         objCallInfo->SetThis(value.GetTaggedValue());
126         objCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(ContainerTag::TreeSet)));
127         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
128         JSTaggedValue result = ContainersPrivate::Load(objCallInfo);
129         TestHelper::TearDownFrame(thread, prev);
130 
131         return result;
132     }
133 
CreateJSAPITreeSet(JSTaggedValue compare=JSTaggedValue::Undefined ())134     JSHandle<JSAPITreeSet> CreateJSAPITreeSet(JSTaggedValue compare = JSTaggedValue::Undefined())
135     {
136         JSHandle<JSTaggedValue> compareHandle(thread, compare);
137         JSHandle<JSFunction> newTarget(thread, InitializeTreeSetConstructor());
138         auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
139         objCallInfo->SetFunction(newTarget.GetTaggedValue());
140         objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
141         objCallInfo->SetThis(JSTaggedValue::Undefined());
142         objCallInfo->SetCallArg(0, compareHandle.GetTaggedValue());
143 
144         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
145         JSTaggedValue result = ContainersTreeSet::TreeSetConstructor(objCallInfo);
146         TestHelper::TearDownFrame(thread, prev);
147         JSHandle<JSAPITreeSet> set(thread, result);
148         return set;
149     }
150 };
151 
152 // new TreeSet()
HWTEST_F_L0(ContainersTreeSetTest,TreeSetConstructor)153 HWTEST_F_L0(ContainersTreeSetTest, TreeSetConstructor)
154 {
155     // Initialize twice and return directly the second time
156     InitializeTreeSetConstructor();
157     JSHandle<JSFunction> newTarget(thread, InitializeTreeSetConstructor());
158 
159     auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
160     objCallInfo->SetFunction(newTarget.GetTaggedValue());
161     objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
162     objCallInfo->SetThis(JSTaggedValue::Undefined());
163 
164     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
165     JSTaggedValue result = ContainersTreeSet::TreeSetConstructor(objCallInfo);
166     TestHelper::TearDownFrame(thread, prev);
167 
168     ASSERT_TRUE(result.IsJSAPITreeSet());
169     JSHandle<JSAPITreeSet> setHandle(thread, result);
170     JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(setHandle));
171     JSTaggedValue funcProto = newTarget->GetFunctionPrototype();
172     ASSERT_EQ(resultProto, funcProto);
173     int size = setHandle->GetSize();
174     ASSERT_EQ(size, 0);
175 
176     // test TreeSetConstructor exception
177     objCallInfo->SetCallArg(0, JSTaggedValue(0));
178     CONTAINERS_API_EXCEPTION_TEST(ContainersTreeSet, TreeSetConstructor, objCallInfo);
179     objCallInfo->SetNewTarget(JSTaggedValue::Undefined());
180     CONTAINERS_API_EXCEPTION_TEST(ContainersTreeSet, TreeSetConstructor, objCallInfo);
181 }
182 
183 // treeset.add(value), treeset.has(value)
HWTEST_F_L0(ContainersTreeSetTest,AddAndHas)184 HWTEST_F_L0(ContainersTreeSetTest, AddAndHas)
185 {
186     constexpr int NODE_NUMBERS = 8;
187     JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet();
188     for (int i = 0; i < NODE_NUMBERS; i++) {
189         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
190         callInfo->SetFunction(JSTaggedValue::Undefined());
191         callInfo->SetThis(tset.GetTaggedValue());
192         callInfo->SetCallArg(0, JSTaggedValue(i));
193 
194         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
195         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
196         TestHelper::TearDownFrame(thread, prev);
197         EXPECT_TRUE(result.IsTrue());
198         EXPECT_EQ(tset->GetSize(), i + 1);
199     }
200     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS);
201 
202     // test add string
203     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
204     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
205     std::string myKey("mykey");
206     for (int i = 0; i < NODE_NUMBERS; i++) {
207         std::string ikey = myKey + std::to_string(i);
208         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
209 
210         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
211         callInfo->SetFunction(JSTaggedValue::Undefined());
212         callInfo->SetThis(tset.GetTaggedValue());
213         callInfo->SetCallArg(0, key.GetTaggedValue());
214 
215         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
216         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
217         TestHelper::TearDownFrame(thread, prev);
218         EXPECT_TRUE(result.IsTrue());
219         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS + i + 1);
220     }
221     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS * 2);
222 
223     for (int i = 0; i < NODE_NUMBERS; i++) {
224         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
225         callInfo->SetFunction(JSTaggedValue::Undefined());
226         callInfo->SetThis(tset.GetTaggedValue());
227         callInfo->SetCallArg(0, JSTaggedValue(i));
228 
229         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
230         JSTaggedValue result = ContainersTreeSet::Has(callInfo);
231         TestHelper::TearDownFrame(thread, prev);
232         EXPECT_TRUE(result.IsTrue());
233     }
234     for (int i = 0; i < NODE_NUMBERS; i++) {
235         std::string ikey = myKey + std::to_string(i);
236         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
237 
238         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
239         callInfo->SetFunction(JSTaggedValue::Undefined());
240         callInfo->SetThis(tset.GetTaggedValue());
241         callInfo->SetCallArg(0, key.GetTaggedValue());
242 
243         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
244         JSTaggedValue result = ContainersTreeSet::Has(callInfo);
245         TestHelper::TearDownFrame(thread, prev);
246         EXPECT_TRUE(result.IsTrue());
247     }
248 }
249 
250 // treeset.remove(key)
HWTEST_F_L0(ContainersTreeSetTest,Remove)251 HWTEST_F_L0(ContainersTreeSetTest, Remove)
252 {
253     constexpr int NODE_NUMBERS = 64;
254     constexpr int REMOVE_SIZE = 48;
255     JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet();
256     for (int i = 0; i < NODE_NUMBERS; i++) {
257         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
258         callInfo->SetFunction(JSTaggedValue::Undefined());
259         callInfo->SetThis(tset.GetTaggedValue());
260         callInfo->SetCallArg(0, JSTaggedValue(i));
261 
262         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
263         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
264         TestHelper::TearDownFrame(thread, prev);
265         EXPECT_TRUE(result.IsTrue());
266         EXPECT_EQ(tset->GetSize(), i + 1);
267     }
268 
269     for (int i = 0; i < REMOVE_SIZE; i++) {
270         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
271         callInfo->SetFunction(JSTaggedValue::Undefined());
272         callInfo->SetThis(tset.GetTaggedValue());
273         callInfo->SetCallArg(0, JSTaggedValue(i));
274 
275         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
276         JSTaggedValue rvalue = ContainersTreeSet::Remove(callInfo);
277         TestHelper::TearDownFrame(thread, prev);
278         EXPECT_TRUE(rvalue.IsTrue());
279     }
280     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS - REMOVE_SIZE);
281 
282     for (int i = 0; i < NODE_NUMBERS; i++) {
283         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
284         callInfo->SetFunction(JSTaggedValue::Undefined());
285         callInfo->SetThis(tset.GetTaggedValue());
286         callInfo->SetCallArg(0, JSTaggedValue(i));
287 
288         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
289         JSTaggedValue result = ContainersTreeSet::Has(callInfo);
290         TestHelper::TearDownFrame(thread, prev);
291         if (i < REMOVE_SIZE) {
292             EXPECT_TRUE(result.IsFalse());
293         } else {
294             EXPECT_TRUE(result.IsTrue());
295         }
296     }
297 
298     // test add string
299     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
300     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
301     std::string myKey("mykey");
302     for (int i = 0; i < NODE_NUMBERS; i++) {
303         std::string ikey = myKey + std::to_string(i);
304         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
305 
306         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
307         callInfo->SetFunction(JSTaggedValue::Undefined());
308         callInfo->SetThis(tset.GetTaggedValue());
309         callInfo->SetCallArg(0, key.GetTaggedValue());
310 
311         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
312         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
313         TestHelper::TearDownFrame(thread, prev);
314         EXPECT_TRUE(result.IsTrue());
315         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS - REMOVE_SIZE + i + 1);
316     }
317     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS * 2 - REMOVE_SIZE);
318 
319     for (int i = 0; i < REMOVE_SIZE; i++) {
320         std::string ikey = myKey + std::to_string(i);
321         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
322 
323         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
324         callInfo->SetFunction(JSTaggedValue::Undefined());
325         callInfo->SetThis(tset.GetTaggedValue());
326         callInfo->SetCallArg(0, key.GetTaggedValue());
327 
328         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
329         JSTaggedValue rvalue = ContainersTreeSet::Remove(callInfo);
330         TestHelper::TearDownFrame(thread, prev);
331         EXPECT_TRUE(rvalue.IsTrue());
332     }
333     EXPECT_EQ(tset->GetSize(), (NODE_NUMBERS - REMOVE_SIZE) * 2);
334     for (int i = 0; i < NODE_NUMBERS; i++) {
335         std::string ikey = myKey + std::to_string(i);
336         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
337 
338         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
339         callInfo->SetFunction(JSTaggedValue::Undefined());
340         callInfo->SetThis(tset.GetTaggedValue());
341         callInfo->SetCallArg(0, key.GetTaggedValue());
342 
343         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
344         JSTaggedValue result = ContainersTreeSet::Has(callInfo);
345         TestHelper::TearDownFrame(thread, prev);
346         if (i < REMOVE_SIZE) {
347             EXPECT_TRUE(result.IsFalse());
348         } else {
349             EXPECT_TRUE(result.IsTrue());
350         }
351     }
352 }
353 
354 // treeset.getFirstValue(), treeset.getLastValue()
HWTEST_F_L0(ContainersTreeSetTest,GetFirstValueAndGetLastValue)355 HWTEST_F_L0(ContainersTreeSetTest, GetFirstValueAndGetLastValue)
356 {
357     constexpr int NODE_NUMBERS = 8;
358     JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet();
359     for (int i = 0; i < NODE_NUMBERS; i++) {
360         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
361         callInfo->SetFunction(JSTaggedValue::Undefined());
362         callInfo->SetThis(tset.GetTaggedValue());
363         callInfo->SetCallArg(0, JSTaggedValue(i));
364 
365         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
366         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
367         TestHelper::TearDownFrame(thread, prev);
368         EXPECT_TRUE(result.IsTrue());
369         EXPECT_EQ(tset->GetSize(), i + 1);
370     }
371     // test getFirstValue
372     {
373         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
374         callInfo->SetFunction(JSTaggedValue::Undefined());
375         callInfo->SetThis(tset.GetTaggedValue());
376 
377         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
378         JSTaggedValue result = ContainersTreeSet::GetFirstValue(callInfo);
379         TestHelper::TearDownFrame(thread, prev);
380         EXPECT_EQ(result, JSTaggedValue(0));
381     }
382     // test getLastValue
383     {
384         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
385         callInfo->SetFunction(JSTaggedValue::Undefined());
386         callInfo->SetThis(tset.GetTaggedValue());
387 
388         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
389         JSTaggedValue result = ContainersTreeSet::GetLastValue(callInfo);
390         TestHelper::TearDownFrame(thread, prev);
391         EXPECT_EQ(result, JSTaggedValue(NODE_NUMBERS - 1));
392     }
393 
394     // test add string
395     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
396     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
397     std::string myKey("mykey");
398     for (int i = 0; i < NODE_NUMBERS; i++) {
399         std::string ikey = myKey + std::to_string(i);
400         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
401 
402         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
403         callInfo->SetFunction(JSTaggedValue::Undefined());
404         callInfo->SetThis(tset.GetTaggedValue());
405         callInfo->SetCallArg(0, key.GetTaggedValue());
406 
407         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
408         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
409         TestHelper::TearDownFrame(thread, prev);
410         EXPECT_TRUE(result.IsTrue());
411         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS + i + 1);
412     }
413     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS * 2);
414 
415     // test getFirstValue
416     {
417         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
418         callInfo->SetFunction(JSTaggedValue::Undefined());
419         callInfo->SetThis(tset.GetTaggedValue());
420 
421         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
422         JSTaggedValue result = ContainersTreeSet::GetFirstValue(callInfo);
423         TestHelper::TearDownFrame(thread, prev);
424         EXPECT_EQ(result, JSTaggedValue(0));
425     }
426     // test getLastValue
427     {
428         std::string ikey = myKey + std::to_string(NODE_NUMBERS - 1);
429         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
430 
431         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
432         callInfo->SetFunction(JSTaggedValue::Undefined());
433         callInfo->SetThis(tset.GetTaggedValue());
434 
435         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
436         JSTaggedValue result = ContainersTreeSet::GetLastValue(callInfo);
437         TestHelper::TearDownFrame(thread, prev);
438         EXPECT_EQ(result, key.GetTaggedValue());
439     }
440 }
441 
442 // treeset.clear()
HWTEST_F_L0(ContainersTreeSetTest,Clear)443 HWTEST_F_L0(ContainersTreeSetTest, Clear)
444 {
445     constexpr int NODE_NUMBERS = 8;
446     JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet();
447     for (int i = 0; i < NODE_NUMBERS; i++) {
448         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
449         callInfo->SetFunction(JSTaggedValue::Undefined());
450         callInfo->SetThis(tset.GetTaggedValue());
451         callInfo->SetCallArg(0, JSTaggedValue(i));
452 
453         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
454         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
455         TestHelper::TearDownFrame(thread, prev);
456         EXPECT_TRUE(result.IsTrue());
457         EXPECT_EQ(tset->GetSize(), i + 1);
458     }
459     // test clear
460     {
461         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
462         callInfo->SetFunction(JSTaggedValue::Undefined());
463         callInfo->SetThis(tset.GetTaggedValue());
464 
465         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
466         ContainersTreeSet::Clear(callInfo);
467         TestHelper::TearDownFrame(thread, prev);
468         EXPECT_EQ(tset->GetSize(), 0);
469     }
470     for (int i = 0; i < NODE_NUMBERS; i++) {
471         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
472         callInfo->SetFunction(JSTaggedValue::Undefined());
473         callInfo->SetThis(tset.GetTaggedValue());
474         callInfo->SetCallArg(0, JSTaggedValue(i));
475 
476         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
477         JSTaggedValue result = ContainersTreeSet::Has(callInfo);
478         TestHelper::TearDownFrame(thread, prev);
479         EXPECT_TRUE(result.IsFalse());
480     }
481 
482     // test add string
483     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
484     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
485     std::string myKey("mykey");
486     for (int i = 0; i < NODE_NUMBERS; i++) {
487         std::string ikey = myKey + std::to_string(i);
488         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
489 
490         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
491         callInfo->SetFunction(JSTaggedValue::Undefined());
492         callInfo->SetThis(tset.GetTaggedValue());
493         callInfo->SetCallArg(0, key.GetTaggedValue());
494 
495         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
496         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
497         TestHelper::TearDownFrame(thread, prev);
498         EXPECT_TRUE(result.IsTrue());
499         EXPECT_EQ(tset->GetSize(), i + 1);
500     }
501     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS);
502     // test clear
503     {
504         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
505         callInfo->SetFunction(JSTaggedValue::Undefined());
506         callInfo->SetThis(tset.GetTaggedValue());
507 
508         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
509         ContainersTreeSet::Clear(callInfo);
510         TestHelper::TearDownFrame(thread, prev);
511         EXPECT_EQ(tset->GetSize(), 0);
512     }
513     for (int i = 0; i < NODE_NUMBERS; i++) {
514         std::string ikey = myKey + std::to_string(i);
515         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
516 
517         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
518         callInfo->SetFunction(JSTaggedValue::Undefined());
519         callInfo->SetThis(tset.GetTaggedValue());
520         callInfo->SetCallArg(0, key.GetTaggedValue());
521 
522         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
523         JSTaggedValue result = ContainersTreeSet::Has(callInfo);
524         TestHelper::TearDownFrame(thread, prev);
525         EXPECT_TRUE(result.IsFalse());
526     }
527 }
528 
529 // treeset.getLowerValue(value), treeset.getHigherValue(value)
HWTEST_F_L0(ContainersTreeSetTest,GetLowerValueAndGetHigherValue)530 HWTEST_F_L0(ContainersTreeSetTest, GetLowerValueAndGetHigherValue)
531 {
532     constexpr int NODE_NUMBERS = 8;
533     JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet();
534     for (int i = 0; i < NODE_NUMBERS; i++) {
535         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
536         callInfo->SetFunction(JSTaggedValue::Undefined());
537         callInfo->SetThis(tset.GetTaggedValue());
538         callInfo->SetCallArg(0, JSTaggedValue(i));
539 
540         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
541         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
542         TestHelper::TearDownFrame(thread, prev);
543         EXPECT_TRUE(result.IsTrue());
544         EXPECT_EQ(tset->GetSize(), i + 1);
545     }
546 
547     // test getLowerValue
548     for (int i = 0; i <= NODE_NUMBERS; i++) {
549         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
550         callInfo->SetFunction(JSTaggedValue::Undefined());
551         callInfo->SetThis(tset.GetTaggedValue());
552         callInfo->SetCallArg(0, JSTaggedValue(i));
553         if (i == NODE_NUMBERS) {
554             callInfo->SetCallArg(0, JSTaggedValue::Undefined());
555         }
556 
557         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
558         JSTaggedValue result = ContainersTreeSet::GetLowerValue(callInfo);
559         TestHelper::TearDownFrame(thread, prev);
560         if (i == 0) {
561             EXPECT_EQ(result, JSTaggedValue::Undefined());
562         } else {
563             EXPECT_EQ(result, JSTaggedValue(i - 1));
564         }
565     }
566     // test getHigherValue
567     for (int i = 0; i <= NODE_NUMBERS; i++) {
568         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
569         callInfo->SetFunction(JSTaggedValue::Undefined());
570         callInfo->SetThis(tset.GetTaggedValue());
571         callInfo->SetCallArg(0, JSTaggedValue(i));
572 
573         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
574         JSTaggedValue result = ContainersTreeSet::GetHigherValue(callInfo);
575         TestHelper::TearDownFrame(thread, prev);
576         if (i >= NODE_NUMBERS - 1) {
577             EXPECT_EQ(result, JSTaggedValue::Undefined());
578         } else {
579             EXPECT_EQ(result, JSTaggedValue(i + 1));
580         }
581     }
582 
583     // test add string
584     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
585     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
586     std::string myKey("mykey");
587     for (int i = 0; i < NODE_NUMBERS; i++) {
588         std::string ikey = myKey + std::to_string(i);
589         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
590 
591         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
592         callInfo->SetFunction(JSTaggedValue::Undefined());
593         callInfo->SetThis(tset.GetTaggedValue());
594         callInfo->SetCallArg(0, key.GetTaggedValue());
595 
596         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
597         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
598         TestHelper::TearDownFrame(thread, prev);
599         EXPECT_TRUE(result.IsTrue());
600         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS + i + 1);
601     }
602     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS * 2);
603 
604     // test getLowerValue
605     // using to compare the result of GetLowerValue
606     JSMutableHandle<JSTaggedValue> resultKey(thread, JSTaggedValue::Undefined());
607     for (int i = 0; i <= NODE_NUMBERS; i++) {
608         std::string ikey = myKey + std::to_string(i);
609         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
610         std::string rkey = myKey + std::to_string(i - 1);
611         resultKey.Update(factory->NewFromStdString(rkey).GetTaggedValue());
612 
613         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
614         callInfo->SetFunction(JSTaggedValue::Undefined());
615         callInfo->SetThis(tset.GetTaggedValue());
616         callInfo->SetCallArg(0, key.GetTaggedValue());
617 
618         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
619         JSTaggedValue result = ContainersTreeSet::GetLowerValue(callInfo);
620         TestHelper::TearDownFrame(thread, prev);
621         if (i == 0) {
622             EXPECT_EQ(result, JSTaggedValue(NODE_NUMBERS - 1));
623         } else {
624             EXPECT_EQ(result, resultKey.GetTaggedValue());
625         }
626     }
627     // test getHigherValue
628     for (int i = 0; i < NODE_NUMBERS; i++) {
629         std::string ikey = myKey + std::to_string(i);
630         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
631         std::string rkey = myKey + std::to_string(i + 1);
632         resultKey.Update(factory->NewFromStdString(rkey).GetTaggedValue());
633 
634         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
635         callInfo->SetFunction(JSTaggedValue::Undefined());
636         callInfo->SetThis(tset.GetTaggedValue());
637         callInfo->SetCallArg(0, key.GetTaggedValue());
638 
639         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
640         JSTaggedValue result = ContainersTreeSet::GetHigherValue(callInfo);
641         TestHelper::TearDownFrame(thread, prev);
642         if (i == NODE_NUMBERS - 1) {
643             EXPECT_EQ(result, JSTaggedValue::Undefined());
644         } else {
645             EXPECT_TRUE(JSTaggedValue::SameValue(result, resultKey.GetTaggedValue()));
646         }
647     }
648 }
649 
650 // treeset.popFirst(), treeset.popLast()
HWTEST_F_L0(ContainersTreeSetTest,PopFirstAndPopLast)651 HWTEST_F_L0(ContainersTreeSetTest, PopFirstAndPopLast)
652 {
653     constexpr int NODE_NUMBERS = 8;
654     JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet();
655     for (int i = 0; i < NODE_NUMBERS; i++) {
656         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
657         callInfo->SetFunction(JSTaggedValue::Undefined());
658         callInfo->SetThis(tset.GetTaggedValue());
659         callInfo->SetCallArg(0, JSTaggedValue(i));
660 
661         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
662         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
663         TestHelper::TearDownFrame(thread, prev);
664         EXPECT_TRUE(result.IsTrue());
665         EXPECT_EQ(tset->GetSize(), i + 1);
666     }
667 
668     // test popFirst
669     {
670         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
671         callInfo->SetFunction(JSTaggedValue::Undefined());
672         callInfo->SetThis(tset.GetTaggedValue());
673 
674         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
675         JSTaggedValue result = ContainersTreeSet::PopFirst(callInfo);
676         TestHelper::TearDownFrame(thread, prev);
677         EXPECT_EQ(result, JSTaggedValue(0));
678         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS - 1);
679     }
680     // test popLast
681     {
682         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
683         callInfo->SetFunction(JSTaggedValue::Undefined());
684         callInfo->SetThis(tset.GetTaggedValue());
685 
686         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
687         JSTaggedValue result = ContainersTreeSet::PopLast(callInfo);
688         TestHelper::TearDownFrame(thread, prev);
689         EXPECT_EQ(result, JSTaggedValue(NODE_NUMBERS - 1));
690         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS - 2); // 2 means two elements
691     }
692 
693     // test add string
694     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
695     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
696     std::string myKey("mykey");
697     for (int i = 0; i < NODE_NUMBERS; i++) {
698         std::string ikey = myKey + std::to_string(i);
699         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
700 
701         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
702         callInfo->SetFunction(JSTaggedValue::Undefined());
703         callInfo->SetThis(tset.GetTaggedValue());
704         callInfo->SetCallArg(0, key.GetTaggedValue());
705 
706         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
707         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
708         TestHelper::TearDownFrame(thread, prev);
709         EXPECT_TRUE(result.IsTrue());
710         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS + i - 1);
711     }
712     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS * 2 - 2);
713 
714     // test popFirst
715     {
716         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
717         callInfo->SetFunction(JSTaggedValue::Undefined());
718         callInfo->SetThis(tset.GetTaggedValue());
719 
720         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
721         JSTaggedValue result = ContainersTreeSet::PopFirst(callInfo);
722         TestHelper::TearDownFrame(thread, prev);
723         EXPECT_EQ(result, JSTaggedValue(1));
724         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS * 2 - 3); // 3 means three elements
725     }
726     // test popLast
727     {
728         std::string ikey = myKey + std::to_string(NODE_NUMBERS - 1);
729         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
730 
731         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
732         callInfo->SetFunction(JSTaggedValue::Undefined());
733         callInfo->SetThis(tset.GetTaggedValue());
734 
735         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
736         JSTaggedValue result = ContainersTreeSet::PopLast(callInfo);
737         TestHelper::TearDownFrame(thread, prev);
738         EXPECT_EQ(result, key.GetTaggedValue());
739         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS * 2 - 4); // 4 means four elements
740     }
741 }
742 
743 // testset.isEmpty()
HWTEST_F_L0(ContainersTreeSetTest,IsEmpty)744 HWTEST_F_L0(ContainersTreeSetTest, IsEmpty)
745 {
746     constexpr int NODE_NUMBERS = 8;
747     JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet();
748     // test isEmpty
749     {
750         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
751         callInfo->SetFunction(JSTaggedValue::Undefined());
752         callInfo->SetThis(tset.GetTaggedValue());
753 
754         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
755         JSTaggedValue result = ContainersTreeSet::IsEmpty(callInfo);
756         TestHelper::TearDownFrame(thread, prev);
757         EXPECT_TRUE(result.IsTrue());
758         EXPECT_EQ(tset->GetSize(), 0);
759     }
760 
761     // add elements
762     for (int i = 0; i < NODE_NUMBERS; i++) {
763         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
764         callInfo->SetFunction(JSTaggedValue::Undefined());
765         callInfo->SetThis(tset.GetTaggedValue());
766         callInfo->SetCallArg(0, JSTaggedValue(i));
767 
768         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
769         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
770         TestHelper::TearDownFrame(thread, prev);
771         EXPECT_TRUE(result.IsTrue());
772         EXPECT_EQ(tset->GetSize(), i + 1);
773     }
774     // test isEmpty
775     {
776         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
777         callInfo->SetFunction(JSTaggedValue::Undefined());
778         callInfo->SetThis(tset.GetTaggedValue());
779 
780         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
781         JSTaggedValue result = ContainersTreeSet::IsEmpty(callInfo);
782         TestHelper::TearDownFrame(thread, prev);
783         EXPECT_TRUE(result.IsFalse());
784         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS);
785     }
786 }
787 
788 // treeset.values(), treeset.entries()
HWTEST_F_L0(ContainersTreeSetTest,KeysAndValuesAndEntries)789 HWTEST_F_L0(ContainersTreeSetTest, KeysAndValuesAndEntries)
790 {
791     constexpr int NODE_NUMBERS = 8;
792     JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet();
793     for (int i = 0; i < NODE_NUMBERS; i++) {
794         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
795         callInfo->SetFunction(JSTaggedValue::Undefined());
796         callInfo->SetThis(tset.GetTaggedValue());
797         callInfo->SetCallArg(0, JSTaggedValue(i));
798 
799         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
800         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
801         TestHelper::TearDownFrame(thread, prev);
802         EXPECT_TRUE(result.IsTrue());
803         EXPECT_EQ(tset->GetSize(), i + 1);
804     }
805 
806     // test values
807     auto callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
808     callInfo1->SetFunction(JSTaggedValue::Undefined());
809     callInfo1->SetThis(tset.GetTaggedValue());
810     [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo1);
811     JSHandle<JSTaggedValue> iterValues(thread, ContainersTreeSet::Values(callInfo1));
812     TestHelper::TearDownFrame(thread, prev1);
813     EXPECT_TRUE(iterValues->IsJSAPITreeSetIterator());
814     {
815         JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
816         for (int i = 0; i < NODE_NUMBERS; i++) {
817             auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
818             callInfo->SetFunction(JSTaggedValue::Undefined());
819             callInfo->SetThis(iterValues.GetTaggedValue());
820 
821             [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
822             result.Update(JSAPITreeSetIterator::Next(callInfo));
823             TestHelper::TearDownFrame(thread, prev);
824             EXPECT_EQ(i, JSIterator::IteratorValue(thread, result)->GetInt());
825         }
826     }
827     // test add string
828     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
829     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
830     std::string myKey("mykey");
831     for (int i = 0; i < NODE_NUMBERS; i++) {
832         std::string ikey = myKey + std::to_string(i);
833         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
834 
835         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
836         callInfo->SetFunction(JSTaggedValue::Undefined());
837         callInfo->SetThis(tset.GetTaggedValue());
838         callInfo->SetCallArg(0, key.GetTaggedValue());
839 
840         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
841         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
842         TestHelper::TearDownFrame(thread, prev);
843         EXPECT_TRUE(result.IsTrue());
844         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS + i + 1);
845     }
846     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS * 2);
847     {
848         JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
849         for (int i = 0; i < NODE_NUMBERS; i++) {
850             std::string ikey = myKey + std::to_string(i);
851             key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
852 
853             auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
854             callInfo->SetFunction(JSTaggedValue::Undefined());
855             callInfo->SetThis(iterValues.GetTaggedValue());
856 
857             [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
858             result.Update(JSAPITreeSetIterator::Next(callInfo));
859             TestHelper::TearDownFrame(thread, prev);
860             JSHandle<JSTaggedValue> itRes = JSIterator::IteratorValue(thread, result);
861             EXPECT_TRUE(JSTaggedValue::SameValue(key, itRes));
862         }
863     }
864     // test entries
865     {
866         auto callInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
867         callInfo2->SetFunction(JSTaggedValue::Undefined());
868         callInfo2->SetThis(tset.GetTaggedValue());
869         [[maybe_unused]] auto prev2 = TestHelper::SetupFrame(thread, callInfo2);
870         JSHandle<JSTaggedValue> iter(thread, ContainersTreeSet::Entries(callInfo2));
871         TestHelper::TearDownFrame(thread, prev2);
872         EXPECT_TRUE(iter->IsJSAPITreeSetIterator());
873 
874         JSHandle<JSTaggedValue> first(thread, JSTaggedValue(0));
875         JSHandle<JSTaggedValue> second(thread, JSTaggedValue(1));
876         JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
877         JSMutableHandle<JSTaggedValue> entries(thread, JSTaggedValue::Undefined());
878         for (int i = 0; i < NODE_NUMBERS; i++) {
879             auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
880             callInfo->SetFunction(JSTaggedValue::Undefined());
881             callInfo->SetThis(iter.GetTaggedValue());
882 
883             [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
884             result.Update(JSAPITreeSetIterator::Next(callInfo));
885             TestHelper::TearDownFrame(thread, prev);
886             entries.Update(JSIterator::IteratorValue(thread, result).GetTaggedValue());
887             EXPECT_EQ(i, JSObject::GetProperty(thread, entries, first).GetValue()->GetInt());
888             EXPECT_EQ(i, JSObject::GetProperty(thread, entries, second).GetValue()->GetInt());
889         }
890         for (int i = 0; i < NODE_NUMBERS; i++) {
891             std::string ikey = myKey + std::to_string(i);
892             key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
893 
894             auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
895             callInfo->SetFunction(JSTaggedValue::Undefined());
896             callInfo->SetThis(iter.GetTaggedValue());
897 
898             [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
899             result.Update(JSAPITreeSetIterator::Next(callInfo));
900             TestHelper::TearDownFrame(thread, prev);
901             entries.Update(JSIterator::IteratorValue(thread, result).GetTaggedValue());
902             EXPECT_TRUE(JSTaggedValue::SameValue(key, JSObject::GetProperty(thread, entries, first).GetValue()));
903             EXPECT_TRUE(JSTaggedValue::SameValue(key, JSObject::GetProperty(thread, entries, second).GetValue()));
904         }
905     }
906 }
907 
908 // treeset.ForEach(callbackfn, this)
HWTEST_F_L0(ContainersTreeSetTest,ForEach)909 HWTEST_F_L0(ContainersTreeSetTest, ForEach)
910 {
911     constexpr int NODE_NUMBERS = 8;
912     JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet();
913     for (int i = 0; i < NODE_NUMBERS; i++) {
914         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
915         callInfo->SetFunction(JSTaggedValue::Undefined());
916         callInfo->SetThis(tset.GetTaggedValue());
917         callInfo->SetCallArg(0, JSTaggedValue(i));
918 
919         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
920         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
921         TestHelper::TearDownFrame(thread, prev);
922         EXPECT_TRUE(result.IsTrue());
923         EXPECT_EQ(tset->GetSize(), i + 1);
924     }
925 
926     // test foreach function with TestForEachFunc;
927     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
928     JSHandle<JSAPITreeSet> dset = CreateJSAPITreeSet();
929     {
930         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
931         JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
932         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
933         callInfo->SetFunction(JSTaggedValue::Undefined());
934         callInfo->SetThis(tset.GetTaggedValue());
935         callInfo->SetCallArg(0, func.GetTaggedValue());
936         callInfo->SetCallArg(1, dset.GetTaggedValue());
937 
938         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
939         ContainersTreeSet::ForEach(callInfo);
940         TestHelper::TearDownFrame(thread, prev);
941     }
942 
943     EXPECT_EQ(dset->GetSize(), NODE_NUMBERS / 2);
944     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS / 2);
945     for (int i = 0; i < NODE_NUMBERS; i += 2) {
946         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
947         callInfo->SetFunction(JSTaggedValue::Undefined());
948         callInfo->SetThis(dset.GetTaggedValue());
949         callInfo->SetCallArg(0, JSTaggedValue(i));
950 
951         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
952         JSTaggedValue result = ContainersTreeSet::Has(callInfo);
953         TestHelper::TearDownFrame(thread, prev);
954         EXPECT_TRUE(result.IsTrue());
955     }
956 
957     // test add string
958     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
959     std::string myKey("mykey");
960     for (int i = 0; i < NODE_NUMBERS; i++) {
961         std::string ikey = myKey + std::to_string(i);
962         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
963 
964         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
965         callInfo->SetFunction(JSTaggedValue::Undefined());
966         callInfo->SetThis(tset.GetTaggedValue());
967         callInfo->SetCallArg(0, key.GetTaggedValue());
968 
969         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
970         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
971         TestHelper::TearDownFrame(thread, prev);
972         EXPECT_TRUE(result.IsTrue());
973         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS / 2 + i + 1);
974     }
975     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS / 2 + NODE_NUMBERS);
976     {
977         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
978         JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
979         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
980         callInfo->SetFunction(JSTaggedValue::Undefined());
981         callInfo->SetThis(tset.GetTaggedValue());
982         callInfo->SetCallArg(0, func.GetTaggedValue());
983         callInfo->SetCallArg(1, dset.GetTaggedValue());
984 
985         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
986         ContainersTreeSet::ForEach(callInfo);
987         TestHelper::TearDownFrame(thread, prev);
988     }
989     EXPECT_EQ(dset->GetSize(), NODE_NUMBERS + 2);
990     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS - 2);
991     for (int i = 0; i < NODE_NUMBERS; i += 2) {
992         std::string ikey = myKey + std::to_string(i);
993         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
994 
995         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
996         callInfo->SetFunction(JSTaggedValue::Undefined());
997         callInfo->SetThis(dset.GetTaggedValue());
998         callInfo->SetCallArg(0, key.GetTaggedValue());
999 
1000         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1001         JSTaggedValue result = ContainersTreeSet::Has(callInfo);
1002         TestHelper::TearDownFrame(thread, prev);
1003         EXPECT_TRUE(result.IsTrue());
1004     }
1005 }
1006 
HWTEST_F_L0(ContainersTreeSetTest,CustomCompareFunctionTest)1007 HWTEST_F_L0(ContainersTreeSetTest, CustomCompareFunctionTest)
1008 {
1009     constexpr int NODE_NUMBERS = 8;
1010     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1011     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1012     JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestCompareFunction));
1013     JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet(func.GetTaggedValue());
1014     for (int i = 0; i < NODE_NUMBERS; i++) {
1015         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1016         callInfo->SetFunction(JSTaggedValue::Undefined());
1017         callInfo->SetThis(tset.GetTaggedValue());
1018         callInfo->SetCallArg(0, JSTaggedValue(i));
1019 
1020         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1021         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
1022         TestHelper::TearDownFrame(thread, prev);
1023         EXPECT_TRUE(result.IsTrue());
1024         EXPECT_EQ(tset->GetSize(), i + 1);
1025     }
1026     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS);
1027 
1028     // test add string
1029     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1030     std::string myKey("mykey");
1031     for (int i = 0; i < NODE_NUMBERS; i++) {
1032         std::string ikey = myKey + std::to_string(i);
1033         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1034 
1035         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1036         callInfo->SetFunction(JSTaggedValue::Undefined());
1037         callInfo->SetThis(tset.GetTaggedValue());
1038         callInfo->SetCallArg(0, key.GetTaggedValue());
1039 
1040         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1041         JSTaggedValue result = ContainersTreeSet::Add(callInfo);
1042         TestHelper::TearDownFrame(thread, prev);
1043         EXPECT_TRUE(result.IsTrue());
1044         EXPECT_EQ(tset->GetSize(), NODE_NUMBERS + i + 1);
1045     }
1046     EXPECT_EQ(tset->GetSize(), NODE_NUMBERS * 2);
1047 
1048     // test sort
1049     auto callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1050     callInfo1->SetFunction(JSTaggedValue::Undefined());
1051     callInfo1->SetThis(tset.GetTaggedValue());
1052     [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo1);
1053     JSHandle<JSTaggedValue> iterValues(thread, ContainersTreeSet::Values(callInfo1));
1054     TestHelper::TearDownFrame(thread, prev1);
1055     EXPECT_TRUE(iterValues->IsJSAPITreeSetIterator());
1056     JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
1057     for (int i = 0; i < NODE_NUMBERS; i++) {
1058         std::string ikey = myKey + std::to_string(NODE_NUMBERS - 1 - i);
1059         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1060 
1061         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1062         callInfo->SetFunction(JSTaggedValue::Undefined());
1063         callInfo->SetThis(iterValues.GetTaggedValue());
1064 
1065         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1066         result.Update(JSAPITreeSetIterator::Next(callInfo));
1067         TestHelper::TearDownFrame(thread, prev);
1068         JSHandle<JSTaggedValue> itRes = JSIterator::IteratorValue(thread, result);
1069         EXPECT_TRUE(JSTaggedValue::SameValue(key, itRes));
1070     }
1071     for (int i = 0; i < NODE_NUMBERS; i++) {
1072         auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1073         callInfo->SetFunction(JSTaggedValue::Undefined());
1074         callInfo->SetThis(iterValues.GetTaggedValue());
1075 
1076         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1077         result.Update(JSAPITreeSetIterator::Next(callInfo));
1078         TestHelper::TearDownFrame(thread, prev);
1079         EXPECT_EQ((NODE_NUMBERS - 1 - i), JSIterator::IteratorValue(thread, result)->GetInt());
1080     }
1081 }
1082 
HWTEST_F_L0(ContainersTreeSetTest,ProxyOfGetLength)1083 HWTEST_F_L0(ContainersTreeSetTest, ProxyOfGetLength)
1084 {
1085     constexpr uint32_t NODE_NUMBERS = 8;
1086     JSHandle<JSAPITreeSet> treeSet = CreateJSAPITreeSet();
1087     auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1088     callInfo->SetFunction(JSTaggedValue::Undefined());
1089     JSHandle<JSProxy> proxy = CreateJSProxyHandle(thread);
1090     proxy->SetTarget(thread, treeSet.GetTaggedValue());
1091     callInfo->SetThis(proxy.GetTaggedValue());
1092 
1093     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
1094         callInfo->SetCallArg(0, JSTaggedValue(i));
1095         callInfo->SetCallArg(1, JSTaggedValue(i + 1));
1096         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1097         ContainersTreeSet::Add(callInfo);
1098         TestHelper::TearDownFrame(thread, prev);
1099 
1100         [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo);
1101         JSTaggedValue retult = ContainersTreeSet::GetLength(callInfo);
1102         TestHelper::TearDownFrame(thread, prev1);
1103         EXPECT_EQ(retult, JSTaggedValue(i + 1));
1104     }
1105 }
1106 
HWTEST_F_L0(ContainersTreeSetTest,ExceptionReturn1)1107 HWTEST_F_L0(ContainersTreeSetTest, ExceptionReturn1)
1108 {
1109     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, GetHigherValue);
1110     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, Add);
1111     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, Remove);
1112     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, Has);
1113     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, GetFirstValue);
1114     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, GetLastValue);
1115     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, Clear);
1116     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, GetLowerValue);
1117 }
1118 
HWTEST_F_L0(ContainersTreeSetTest,ExceptionReturn2)1119 HWTEST_F_L0(ContainersTreeSetTest, ExceptionReturn2)
1120 {
1121     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, PopFirst);
1122     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, PopLast);
1123     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, IsEmpty);
1124     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, ForEach);
1125     CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, GetLength);
1126 }
1127 }  // namespace panda::test
1128