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