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(thread);
172 ASSERT_EQ(resultProto, funcProto);
173 int size = setHandle->GetSize(thread);
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(thread), i + 1);
199 }
200 EXPECT_EQ(tset->GetSize(thread), 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(thread), NODE_NUMBERS + i + 1);
220 }
221 EXPECT_EQ(tset->GetSize(thread), 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(thread), 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(thread), 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(thread), NODE_NUMBERS - REMOVE_SIZE + i + 1);
316 }
317 EXPECT_EQ(tset->GetSize(thread), 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(thread), (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(thread), 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(thread), NODE_NUMBERS + i + 1);
412 }
413 EXPECT_EQ(tset->GetSize(thread), 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(thread), 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(thread), 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(thread), i + 1);
500 }
501 EXPECT_EQ(tset->GetSize(thread), 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(thread), 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(thread), 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(thread), NODE_NUMBERS + i + 1);
601 }
602 EXPECT_EQ(tset->GetSize(thread), 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(thread, 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(thread), 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(thread), 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(thread), 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(thread), NODE_NUMBERS + i - 1);
711 }
712 EXPECT_EQ(tset->GetSize(thread), 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(thread), 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(thread), 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(thread), 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(thread), 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(thread), 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(thread), 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(thread), NODE_NUMBERS + i + 1);
845 }
846 EXPECT_EQ(tset->GetSize(thread), 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(thread, 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(thread, key,
903 JSObject::GetProperty(thread, entries, first).GetValue()));
904 EXPECT_TRUE(JSTaggedValue::SameValue(thread, key,
905 JSObject::GetProperty(thread, entries, second).GetValue()));
906 }
907 }
908 }
909
910 // treeset.ForEach(callbackfn, this)
HWTEST_F_L0(ContainersTreeSetTest,ForEach)911 HWTEST_F_L0(ContainersTreeSetTest, ForEach)
912 {
913 constexpr int NODE_NUMBERS = 8;
914 JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet();
915 for (int i = 0; i < NODE_NUMBERS; i++) {
916 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
917 callInfo->SetFunction(JSTaggedValue::Undefined());
918 callInfo->SetThis(tset.GetTaggedValue());
919 callInfo->SetCallArg(0, JSTaggedValue(i));
920
921 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
922 JSTaggedValue result = ContainersTreeSet::Add(callInfo);
923 TestHelper::TearDownFrame(thread, prev);
924 EXPECT_TRUE(result.IsTrue());
925 EXPECT_EQ(tset->GetSize(thread), i + 1);
926 }
927
928 // test foreach function with TestForEachFunc;
929 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
930 JSHandle<JSAPITreeSet> dset = CreateJSAPITreeSet();
931 {
932 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
933 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
934 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
935 callInfo->SetFunction(JSTaggedValue::Undefined());
936 callInfo->SetThis(tset.GetTaggedValue());
937 callInfo->SetCallArg(0, func.GetTaggedValue());
938 callInfo->SetCallArg(1, dset.GetTaggedValue());
939
940 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
941 ContainersTreeSet::ForEach(callInfo);
942 TestHelper::TearDownFrame(thread, prev);
943 }
944
945 EXPECT_EQ(dset->GetSize(thread), NODE_NUMBERS / 2);
946 EXPECT_EQ(tset->GetSize(thread), NODE_NUMBERS / 2);
947 for (int i = 0; i < NODE_NUMBERS; i += 2) {
948 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
949 callInfo->SetFunction(JSTaggedValue::Undefined());
950 callInfo->SetThis(dset.GetTaggedValue());
951 callInfo->SetCallArg(0, JSTaggedValue(i));
952
953 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
954 JSTaggedValue result = ContainersTreeSet::Has(callInfo);
955 TestHelper::TearDownFrame(thread, prev);
956 EXPECT_TRUE(result.IsTrue());
957 }
958
959 // test add string
960 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
961 std::string myKey("mykey");
962 for (int i = 0; i < NODE_NUMBERS; i++) {
963 std::string ikey = myKey + std::to_string(i);
964 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
965
966 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
967 callInfo->SetFunction(JSTaggedValue::Undefined());
968 callInfo->SetThis(tset.GetTaggedValue());
969 callInfo->SetCallArg(0, key.GetTaggedValue());
970
971 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
972 JSTaggedValue result = ContainersTreeSet::Add(callInfo);
973 TestHelper::TearDownFrame(thread, prev);
974 EXPECT_TRUE(result.IsTrue());
975 EXPECT_EQ(tset->GetSize(thread), NODE_NUMBERS / 2 + i + 1);
976 }
977 EXPECT_EQ(tset->GetSize(thread), NODE_NUMBERS / 2 + NODE_NUMBERS);
978 {
979 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
980 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
981 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
982 callInfo->SetFunction(JSTaggedValue::Undefined());
983 callInfo->SetThis(tset.GetTaggedValue());
984 callInfo->SetCallArg(0, func.GetTaggedValue());
985 callInfo->SetCallArg(1, dset.GetTaggedValue());
986
987 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
988 ContainersTreeSet::ForEach(callInfo);
989 TestHelper::TearDownFrame(thread, prev);
990 }
991 EXPECT_EQ(dset->GetSize(thread), NODE_NUMBERS + 2);
992 EXPECT_EQ(tset->GetSize(thread), NODE_NUMBERS - 2);
993 for (int i = 0; i < NODE_NUMBERS; i += 2) {
994 std::string ikey = myKey + std::to_string(i);
995 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
996
997 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
998 callInfo->SetFunction(JSTaggedValue::Undefined());
999 callInfo->SetThis(dset.GetTaggedValue());
1000 callInfo->SetCallArg(0, key.GetTaggedValue());
1001
1002 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1003 JSTaggedValue result = ContainersTreeSet::Has(callInfo);
1004 TestHelper::TearDownFrame(thread, prev);
1005 EXPECT_TRUE(result.IsTrue());
1006 }
1007 }
1008
HWTEST_F_L0(ContainersTreeSetTest,CustomCompareFunctionTest)1009 HWTEST_F_L0(ContainersTreeSetTest, CustomCompareFunctionTest)
1010 {
1011 constexpr int NODE_NUMBERS = 8;
1012 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1013 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1014 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestCompareFunction));
1015 JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet(func.GetTaggedValue());
1016 for (int i = 0; i < NODE_NUMBERS; i++) {
1017 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1018 callInfo->SetFunction(JSTaggedValue::Undefined());
1019 callInfo->SetThis(tset.GetTaggedValue());
1020 callInfo->SetCallArg(0, JSTaggedValue(i));
1021
1022 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1023 JSTaggedValue result = ContainersTreeSet::Add(callInfo);
1024 TestHelper::TearDownFrame(thread, prev);
1025 EXPECT_TRUE(result.IsTrue());
1026 EXPECT_EQ(tset->GetSize(thread), i + 1);
1027 }
1028 EXPECT_EQ(tset->GetSize(thread), NODE_NUMBERS);
1029
1030 // test add string
1031 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1032 std::string myKey("mykey");
1033 for (int i = 0; i < NODE_NUMBERS; i++) {
1034 std::string ikey = myKey + std::to_string(i);
1035 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1036
1037 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1038 callInfo->SetFunction(JSTaggedValue::Undefined());
1039 callInfo->SetThis(tset.GetTaggedValue());
1040 callInfo->SetCallArg(0, key.GetTaggedValue());
1041
1042 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1043 JSTaggedValue result = ContainersTreeSet::Add(callInfo);
1044 TestHelper::TearDownFrame(thread, prev);
1045 EXPECT_TRUE(result.IsTrue());
1046 EXPECT_EQ(tset->GetSize(thread), NODE_NUMBERS + i + 1);
1047 }
1048 EXPECT_EQ(tset->GetSize(thread), NODE_NUMBERS * 2);
1049
1050 // test sort
1051 auto callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1052 callInfo1->SetFunction(JSTaggedValue::Undefined());
1053 callInfo1->SetThis(tset.GetTaggedValue());
1054 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo1);
1055 JSHandle<JSTaggedValue> iterValues(thread, ContainersTreeSet::Values(callInfo1));
1056 TestHelper::TearDownFrame(thread, prev1);
1057 EXPECT_TRUE(iterValues->IsJSAPITreeSetIterator());
1058 JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
1059 for (int i = 0; i < NODE_NUMBERS; i++) {
1060 std::string ikey = myKey + std::to_string(NODE_NUMBERS - 1 - i);
1061 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1062
1063 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1064 callInfo->SetFunction(JSTaggedValue::Undefined());
1065 callInfo->SetThis(iterValues.GetTaggedValue());
1066
1067 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1068 result.Update(JSAPITreeSetIterator::Next(callInfo));
1069 TestHelper::TearDownFrame(thread, prev);
1070 JSHandle<JSTaggedValue> itRes = JSIterator::IteratorValue(thread, result);
1071 EXPECT_TRUE(JSTaggedValue::SameValue(thread, key, itRes));
1072 }
1073 for (int i = 0; i < NODE_NUMBERS; i++) {
1074 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1075 callInfo->SetFunction(JSTaggedValue::Undefined());
1076 callInfo->SetThis(iterValues.GetTaggedValue());
1077
1078 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1079 result.Update(JSAPITreeSetIterator::Next(callInfo));
1080 TestHelper::TearDownFrame(thread, prev);
1081 EXPECT_EQ((NODE_NUMBERS - 1 - i), JSIterator::IteratorValue(thread, result)->GetInt());
1082 }
1083 }
1084
HWTEST_F_L0(ContainersTreeSetTest,CustomCompareFunctionApi20Test)1085 HWTEST_F_L0(ContainersTreeSetTest, CustomCompareFunctionApi20Test)
1086 {
1087 constexpr int NODE_NUMBERS = 8;
1088 // 20 : Isolating version to fix comparator missing
1089 thread->GetEcmaVM()->SetVMAPIVersion(20);
1090 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1091 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1092 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestCompareFunction));
1093 JSHandle<JSAPITreeSet> tset = CreateJSAPITreeSet(func.GetTaggedValue());
1094 for (int i = 0; i < NODE_NUMBERS; i++) {
1095 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1096 callInfo->SetFunction(JSTaggedValue::Undefined());
1097 callInfo->SetThis(tset.GetTaggedValue());
1098 callInfo->SetCallArg(0, JSTaggedValue(i));
1099
1100 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1101 JSTaggedValue result = ContainersTreeSet::Add(callInfo);
1102 TestHelper::TearDownFrame(thread, prev);
1103 EXPECT_TRUE(result.IsTrue());
1104 EXPECT_EQ(tset->GetSize(thread), i + 1);
1105 }
1106 EXPECT_EQ(tset->GetSize(thread), NODE_NUMBERS);
1107
1108 // test add string
1109 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1110 std::string myKey("mykey");
1111 for (int i = 0; i < NODE_NUMBERS; i++) {
1112 std::string ikey = myKey + std::to_string(i);
1113 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1114
1115 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
1116 callInfo->SetFunction(JSTaggedValue::Undefined());
1117 callInfo->SetThis(tset.GetTaggedValue());
1118 callInfo->SetCallArg(0, key.GetTaggedValue());
1119
1120 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1121 JSTaggedValue result = ContainersTreeSet::Add(callInfo);
1122 TestHelper::TearDownFrame(thread, prev);
1123 EXPECT_TRUE(result.IsTrue());
1124 EXPECT_EQ(tset->GetSize(thread), NODE_NUMBERS + i + 1);
1125 }
1126 EXPECT_EQ(tset->GetSize(thread), NODE_NUMBERS * 2);
1127
1128 // test sort
1129 auto callInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1130 callInfo1->SetFunction(JSTaggedValue::Undefined());
1131 callInfo1->SetThis(tset.GetTaggedValue());
1132 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo1);
1133 JSHandle<JSTaggedValue> iterValues(thread, ContainersTreeSet::Values(callInfo1));
1134 TestHelper::TearDownFrame(thread, prev1);
1135 EXPECT_TRUE(iterValues->IsJSAPITreeSetIterator());
1136 JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
1137 for (int i = 0; i < NODE_NUMBERS; i++) {
1138 std::string ikey = myKey + std::to_string(NODE_NUMBERS - 1 - i);
1139 key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
1140
1141 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1142 callInfo->SetFunction(JSTaggedValue::Undefined());
1143 callInfo->SetThis(iterValues.GetTaggedValue());
1144
1145 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1146 result.Update(JSAPITreeSetIterator::Next(callInfo));
1147 TestHelper::TearDownFrame(thread, prev);
1148 JSHandle<JSTaggedValue> itRes = JSIterator::IteratorValue(thread, result);
1149 EXPECT_TRUE(JSTaggedValue::SameValue(thread, key, itRes));
1150 }
1151 for (int i = 0; i < NODE_NUMBERS; i++) {
1152 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
1153 callInfo->SetFunction(JSTaggedValue::Undefined());
1154 callInfo->SetThis(iterValues.GetTaggedValue());
1155
1156 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1157 result.Update(JSAPITreeSetIterator::Next(callInfo));
1158 TestHelper::TearDownFrame(thread, prev);
1159 EXPECT_EQ((NODE_NUMBERS - 1 - i), JSIterator::IteratorValue(thread, result)->GetInt());
1160 }
1161 }
1162
HWTEST_F_L0(ContainersTreeSetTest,ProxyOfGetLength)1163 HWTEST_F_L0(ContainersTreeSetTest, ProxyOfGetLength)
1164 {
1165 constexpr uint32_t NODE_NUMBERS = 8;
1166 JSHandle<JSAPITreeSet> treeSet = CreateJSAPITreeSet();
1167 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
1168 callInfo->SetFunction(JSTaggedValue::Undefined());
1169 JSHandle<JSProxy> proxy = CreateJSProxyHandle(thread);
1170 proxy->SetTarget(thread, treeSet.GetTaggedValue());
1171 callInfo->SetThis(proxy.GetTaggedValue());
1172
1173 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
1174 callInfo->SetCallArg(0, JSTaggedValue(i));
1175 callInfo->SetCallArg(1, JSTaggedValue(i + 1));
1176 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
1177 ContainersTreeSet::Add(callInfo);
1178 TestHelper::TearDownFrame(thread, prev);
1179
1180 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo);
1181 JSTaggedValue retult = ContainersTreeSet::GetLength(callInfo);
1182 TestHelper::TearDownFrame(thread, prev1);
1183 EXPECT_EQ(retult, JSTaggedValue(i + 1));
1184 }
1185 }
1186
HWTEST_F_L0(ContainersTreeSetTest,ExceptionReturn1)1187 HWTEST_F_L0(ContainersTreeSetTest, ExceptionReturn1)
1188 {
1189 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, GetHigherValue);
1190 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, Add);
1191 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, Remove);
1192 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, Has);
1193 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, GetFirstValue);
1194 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, GetLastValue);
1195 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, Clear);
1196 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, GetLowerValue);
1197 }
1198
HWTEST_F_L0(ContainersTreeSetTest,ExceptionReturn2)1199 HWTEST_F_L0(ContainersTreeSetTest, ExceptionReturn2)
1200 {
1201 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, PopFirst);
1202 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, PopLast);
1203 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, IsEmpty);
1204 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, ForEach);
1205 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersTreeSet, GetLength);
1206 }
1207 } // namespace panda::test
1208