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 29using namespace panda::ecmascript; 30using namespace panda::ecmascript::containers; 31 32namespace panda::test { 33class ContainersTreeSetTest : public testing::Test { 34public: 35 static void SetUpTestCase() 36 { 37 GTEST_LOG_(INFO) << "SetUpTestCase"; 38 } 39 40 static void TearDownTestCase() 41 { 42 GTEST_LOG_(INFO) << "TearDownCase"; 43 } 44 45 void SetUp() override 46 { 47 TestHelper::CreateEcmaVMWithScope(instance, thread, scope); 48 } 49 50 void TearDown() override 51 { 52 TestHelper::DestroyEcmaVMWithScope(instance, scope); 53 } 54 55 EcmaVM *instance {nullptr}; 56 EcmaHandleScope *scope {nullptr}; 57 JSThread *thread {nullptr}; 58 59 class TestClass : public base::BuiltinsBase { 60 public: 61 static JSTaggedValue TestForEachFunc(EcmaRuntimeCallInfo *argv) 62 { 63 JSThread *thread = argv->GetThread(); 64 JSHandle<JSTaggedValue> value = GetCallArg(argv, 0); 65 JSHandle<JSTaggedValue> key = GetCallArg(argv, 1); 66 JSHandle<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 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 112protected: 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 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() 153HWTEST_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) 184HWTEST_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) 251HWTEST_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() 355HWTEST_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() 443HWTEST_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) 530HWTEST_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() 651HWTEST_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() 744HWTEST_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() 789HWTEST_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) 909HWTEST_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 1007HWTEST_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 1083HWTEST_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 1107HWTEST_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 1119HWTEST_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