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_plainarray.h" 17#include "ecmascript/containers/containers_private.h" 18#include "ecmascript/ecma_runtime_call_info.h" 19#include "ecmascript/global_env.h" 20#include "ecmascript/js_api/js_api_plain_array_iterator.h" 21#include "ecmascript/js_api/js_api_plain_array.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 ContainersPlainArrayTest : 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> key = GetCallArg(argv, 0); // 0 means the value 65 JSHandle<JSTaggedValue> value = GetCallArg(argv, 1); // 1 means the value 66 JSHandle<JSAPIPlainArray> plainArray(GetCallArg(argv, 2)); // 2 means the value 67 if (key->IsNumber()) { 68 JSHandle<JSTaggedValue> newValue(thread, JSTaggedValue(value->GetInt() * 2)); // 2 means the value 69 JSAPIPlainArray::Add(thread, plainArray, key, newValue); 70 } 71 72 return JSTaggedValue::True(); 73 } 74 }; 75protected: 76 JSTaggedValue InitializePlainArrayConstructor() 77 { 78 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 79 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 80 81 JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject(); 82 JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate")); 83 JSHandle<JSTaggedValue> value = 84 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue(); 85 86 auto objCallInfo = 87 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value 88 objCallInfo->SetFunction(JSTaggedValue::Undefined()); 89 objCallInfo->SetThis(value.GetTaggedValue()); 90 objCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(ContainerTag::PlainArray))); 91 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo); 92 JSTaggedValue result = ContainersPrivate::Load(objCallInfo); 93 TestHelper::TearDownFrame(thread, prev); 94 95 return result; 96 } 97 98 JSHandle<JSAPIPlainArray> CreateJSAPIPlainArray() 99 { 100 JSHandle<JSFunction> newTarget(thread, InitializePlainArrayConstructor()); 101 auto objCallInfo = 102 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); // 4 means the value 103 objCallInfo->SetFunction(newTarget.GetTaggedValue()); 104 objCallInfo->SetNewTarget(newTarget.GetTaggedValue()); 105 objCallInfo->SetThis(JSTaggedValue::Undefined()); 106 107 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo); 108 JSTaggedValue result = ContainersPlainArray::PlainArrayConstructor(objCallInfo); 109 TestHelper::TearDownFrame(thread, prev); 110 JSHandle<JSAPIPlainArray> plain(thread, result); 111 return plain; 112 } 113 114 JSTaggedValue PlainArrayAdd(JSHandle<JSAPIPlainArray> plainArray, JSTaggedValue index, JSTaggedValue value) 115 { 116 auto callInfo = 117 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 4 means the value 118 callInfo->SetFunction(JSTaggedValue::Undefined()); 119 callInfo->SetThis(plainArray.GetTaggedValue()); 120 callInfo->SetCallArg(0, index); 121 callInfo->SetCallArg(1, value); 122 123 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 124 JSTaggedValue result = ContainersPlainArray::Add(callInfo); 125 TestHelper::TearDownFrame(thread, prev); 126 return result; 127 } 128 129 JSTaggedValue PlainArrayRemoveRangeFrom(JSHandle<JSAPIPlainArray> plainArray, JSTaggedValue index, 130 JSTaggedValue size) 131 { 132 auto callInfo = 133 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means the value 134 callInfo->SetFunction(JSTaggedValue::Undefined()); 135 callInfo->SetThis(plainArray.GetTaggedValue()); 136 callInfo->SetCallArg(0, index); 137 callInfo->SetCallArg(1, size); 138 139 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 140 JSTaggedValue result = ContainersPlainArray::RemoveRangeFrom(callInfo); 141 TestHelper::TearDownFrame(thread, prev); 142 return result; 143 } 144}; 145 146HWTEST_F_L0(ContainersPlainArrayTest, PlainArrayConstructor) 147{ 148 InitializePlainArrayConstructor(); 149 JSHandle<JSFunction> newTarget(thread, InitializePlainArrayConstructor()); 150 auto objCallInfo = 151 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); // 4 means the value 152 objCallInfo->SetFunction(newTarget.GetTaggedValue()); 153 objCallInfo->SetNewTarget(newTarget.GetTaggedValue()); 154 objCallInfo->SetThis(JSTaggedValue::Undefined()); 155 156 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo); 157 JSTaggedValue result = ContainersPlainArray::PlainArrayConstructor(objCallInfo); 158 TestHelper::TearDownFrame(thread, prev); 159 160 ASSERT_TRUE(result.IsJSAPIPlainArray()); 161 JSHandle<JSAPIPlainArray> arrayHandle(thread, result); 162 JSTaggedValue resultProto = JSObject::GetPrototype(JSHandle<JSObject>::Cast(arrayHandle)); 163 JSTaggedValue funcProto = newTarget->GetFunctionPrototype(); 164 ASSERT_EQ(resultProto, funcProto); 165 int size = arrayHandle->GetSize(); 166 ASSERT_EQ(size, 0); 167 168 // test PlainArrayConstructor exception 169 objCallInfo->SetNewTarget(JSTaggedValue::Undefined()); 170 CONTAINERS_API_EXCEPTION_TEST(ContainersPlainArray, PlainArrayConstructor, objCallInfo); 171} 172 173HWTEST_F_L0(ContainersPlainArrayTest, AddAndHas) 174{ 175 constexpr uint32_t NODE_NUMBERS = 8; // 8 means the value 176 177 JSHandle<JSAPIPlainArray> tArray1 = CreateJSAPIPlainArray(); 178 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 179 auto callInfo = 180 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means the value 181 callInfo->SetFunction(JSTaggedValue::Undefined()); 182 callInfo->SetThis(tArray1.GetTaggedValue()); 183 callInfo->SetCallArg(0, JSTaggedValue(i)); 184 callInfo->SetCallArg(1, JSTaggedValue(i + 1)); 185 186 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 187 JSTaggedValue result = ContainersPlainArray::Add(callInfo); 188 TestHelper::TearDownFrame(thread, prev); 189 EXPECT_TRUE(result.IsUndefined()); 190 EXPECT_EQ(tArray1->GetSize(), static_cast<int>(i + 1)); 191 } 192 EXPECT_EQ(tArray1->GetSize(), static_cast<int>(NODE_NUMBERS)); 193 // test has 194 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 195 auto callInfo = 196 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means the value 197 callInfo->SetFunction(JSTaggedValue::Undefined()); 198 callInfo->SetThis(tArray1.GetTaggedValue()); 199 callInfo->SetCallArg(0, JSTaggedValue(i)); 200 201 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 202 JSTaggedValue result = ContainersPlainArray::Has(callInfo); 203 TestHelper::TearDownFrame(thread, prev); 204 EXPECT_TRUE(result.IsTrue()); 205 } 206 EXPECT_EQ(tArray1->GetSize(), static_cast<int>(NODE_NUMBERS)); 207 // test add string 208 JSHandle<JSAPIPlainArray> tArray = CreateJSAPIPlainArray(); 209 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 210 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined()); 211 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined()); 212 std::string myValue("myvalue"); 213 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 214 std::string ivalue = myValue + std::to_string(i); 215 key.Update(JSTaggedValue(i)); 216 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); 217 218 auto callInfo = 219 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means the value 220 callInfo->SetFunction(JSTaggedValue::Undefined()); 221 callInfo->SetThis(tArray.GetTaggedValue()); 222 callInfo->SetCallArg(0, key.GetTaggedValue()); 223 callInfo->SetCallArg(1, value.GetTaggedValue()); 224 225 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 226 JSTaggedValue result = ContainersPlainArray::Add(callInfo); 227 TestHelper::TearDownFrame(thread, prev); 228 EXPECT_TRUE(result.IsUndefined()); 229 } 230 EXPECT_EQ(tArray->GetSize(), static_cast<int>(NODE_NUMBERS)); 231 // test get 232 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 233 std::string ivalue = myValue + std::to_string(i); 234 key.Update(JSTaggedValue(i)); 235 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); 236 237 auto callInfo = 238 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means the value 239 callInfo->SetFunction(JSTaggedValue::Undefined()); 240 callInfo->SetThis(tArray.GetTaggedValue()); 241 callInfo->SetCallArg(0, key.GetTaggedValue()); 242 243 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 244 JSTaggedValue result = ContainersPlainArray::Get(callInfo); 245 TestHelper::TearDownFrame(thread, prev); 246 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result), value)); 247 } 248} 249 250HWTEST_F_L0(ContainersPlainArrayTest, Iterator) 251{ 252 constexpr uint32_t NODE_NUMBERS = 8; 253 JSHandle<JSAPIPlainArray> array = CreateJSAPIPlainArray(); 254 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 255 auto callInfo = 256 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means the value 257 callInfo->SetFunction(JSTaggedValue::Undefined()); 258 callInfo->SetThis(array.GetTaggedValue()); 259 callInfo->SetCallArg(0, JSTaggedValue(i)); 260 callInfo->SetCallArg(1, JSTaggedValue(i + 1)); 261 262 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 263 JSTaggedValue result = ContainersPlainArray::Add(callInfo); 264 TestHelper::TearDownFrame(thread, prev); 265 EXPECT_TRUE(result.IsUndefined()); 266 EXPECT_EQ(array->GetSize(), static_cast<int>(i + 1)); 267 } 268 // test iterator 269 { 270 auto callInf = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); 271 callInf->SetFunction(JSTaggedValue::Undefined()); 272 callInf->SetThis(array.GetTaggedValue()); 273 [[maybe_unused]] auto pre = TestHelper::SetupFrame(thread, callInf); 274 JSHandle<JSTaggedValue> iter(thread, ContainersPlainArray::GetIteratorObj(callInf)); 275 TestHelper::TearDownFrame(thread, pre); 276 EXPECT_TRUE(iter->IsJSAPIPlainArrayIterator()); 277 278 JSHandle<JSTaggedValue> first(thread, JSTaggedValue(0)); 279 JSHandle<JSTaggedValue> second(thread, JSTaggedValue(1)); 280 JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined()); 281 JSMutableHandle<JSTaggedValue> entries(thread, JSTaggedValue::Undefined()); 282 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 283 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); 284 callInfo->SetFunction(JSTaggedValue::Undefined()); 285 callInfo->SetThis(iter.GetTaggedValue()); 286 287 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 288 result.Update(JSAPIPlainArrayIterator::Next(callInfo)); 289 TestHelper::TearDownFrame(thread, prev); 290 entries.Update(JSIterator::IteratorValue(thread, result).GetTaggedValue()); 291 EXPECT_EQ(static_cast<int>(i), JSObject::GetProperty(thread, entries, first).GetValue()->GetInt()); 292 EXPECT_EQ(static_cast<int>(i + 1), JSObject::GetProperty(thread, entries, second).GetValue()->GetInt()); 293 } 294 } 295 // test add string 296 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 297 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined()); 298 std::string myValue("myvalue"); 299 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 300 std::string iValue = myValue + std::to_string(i); 301 value.Update(factory->NewFromStdString(iValue).GetTaggedValue()); 302 auto callInfo = 303 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means the value 304 callInfo->SetFunction(JSTaggedValue::Undefined()); 305 callInfo->SetThis(array.GetTaggedValue()); 306 callInfo->SetCallArg(0, JSTaggedValue(100 + i)); 307 callInfo->SetCallArg(1, value.GetTaggedValue()); 308 309 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 310 JSTaggedValue result = ContainersPlainArray::Add(callInfo); 311 TestHelper::TearDownFrame(thread, prev); 312 EXPECT_TRUE(result.IsUndefined()); 313 EXPECT_EQ(array->GetSize(), static_cast<int>(NODE_NUMBERS + i + 1)); 314 } 315 EXPECT_EQ(array->GetSize(), static_cast<int>(NODE_NUMBERS * 2)); 316} 317 318HWTEST_F_L0(ContainersPlainArrayTest, GetIndexOfKeyAndGetIndexOfValue) 319{ 320 constexpr uint32_t NODE_NUMBERS = 8; 321 JSHandle<JSAPIPlainArray> pArray = CreateJSAPIPlainArray(); 322 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 323 auto callInfo = 324 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 4 means the value 325 callInfo->SetFunction(JSTaggedValue::Undefined()); 326 callInfo->SetThis(pArray.GetTaggedValue()); 327 callInfo->SetCallArg(0, JSTaggedValue(i)); 328 callInfo->SetCallArg(1, JSTaggedValue(i + 1)); 329 330 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 331 JSTaggedValue result = ContainersPlainArray::Add(callInfo); 332 TestHelper::TearDownFrame(thread, prev); 333 EXPECT_TRUE(result.IsUndefined()); 334 EXPECT_EQ(pArray->GetSize(), static_cast<int>(i + 1)); 335 } 336 // test GetIndexOfKey 337 { 338 auto callInfo = 339 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value 340 callInfo->SetFunction(JSTaggedValue::Undefined()); 341 callInfo->SetThis(pArray.GetTaggedValue()); 342 callInfo->SetCallArg(0, JSTaggedValue(2)); 343 344 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 345 JSTaggedValue result = ContainersPlainArray::GetIndexOfKey(callInfo); 346 TestHelper::TearDownFrame(thread, prev); 347 EXPECT_EQ(result, JSTaggedValue(2)); 348 } 349 // test GetIndexOfValue 350 { 351 auto callInfo = 352 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value 353 callInfo->SetFunction(JSTaggedValue::Undefined()); 354 callInfo->SetThis(pArray.GetTaggedValue()); 355 callInfo->SetCallArg(0, JSTaggedValue(4)); 356 357 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 358 JSTaggedValue result = ContainersPlainArray::GetIndexOfValue(callInfo); 359 TestHelper::TearDownFrame(thread, prev); 360 EXPECT_EQ(result, JSTaggedValue(3)); 361 } 362 // test add string 363 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 364 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined()); 365 std::string myValue("myvalue"); 366 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 367 std::string iValue = myValue + std::to_string(i); 368 value.Update(factory->NewFromStdString(iValue).GetTaggedValue()); 369 auto callInfo = 370 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means the value 371 callInfo->SetFunction(JSTaggedValue::Undefined()); 372 callInfo->SetThis(pArray.GetTaggedValue()); 373 callInfo->SetCallArg(0, JSTaggedValue(100 + i)); 374 callInfo->SetCallArg(1, value.GetTaggedValue()); 375 376 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 377 JSTaggedValue result = ContainersPlainArray::Add(callInfo); 378 TestHelper::TearDownFrame(thread, prev); 379 EXPECT_TRUE(result.IsUndefined()); 380 EXPECT_EQ(pArray->GetSize(), static_cast<int>(NODE_NUMBERS + i + 1)); 381 } 382 EXPECT_EQ(pArray->GetSize(), static_cast<int>(NODE_NUMBERS * 2)); 383 // test GetIndexOfKey 384 { 385 auto callInfo = 386 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value 387 callInfo->SetFunction(JSTaggedValue::Undefined()); 388 callInfo->SetThis(pArray.GetTaggedValue()); 389 callInfo->SetCallArg(0, JSTaggedValue(102)); 390 391 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 392 JSTaggedValue result = ContainersPlainArray::GetIndexOfKey(callInfo); 393 TestHelper::TearDownFrame(thread, prev); 394 EXPECT_EQ(result, JSTaggedValue(10)); 395 } 396 // test GetIndexOfValue 397 { 398 std::string tValue("myvalue3"); 399 value.Update(factory->NewFromStdString(tValue).GetTaggedValue()); 400 auto callInfo = 401 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value 402 callInfo->SetFunction(JSTaggedValue::Undefined()); 403 callInfo->SetThis(pArray.GetTaggedValue()); 404 callInfo->SetCallArg(0, value.GetTaggedValue()); 405 406 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 407 JSTaggedValue result = ContainersPlainArray::GetIndexOfValue(callInfo); 408 TestHelper::TearDownFrame(thread, prev); 409 EXPECT_EQ(result, JSTaggedValue(11)); 410 } 411} 412 413HWTEST_F_L0(ContainersPlainArrayTest, RemoveRangeFrom) 414{ 415 constexpr uint32_t NODE_NUMBERS = 8; 416 JSHandle<JSAPIPlainArray> pArray = CreateJSAPIPlainArray(); 417 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 418 JSTaggedValue result = PlainArrayAdd(pArray, JSTaggedValue(i), JSTaggedValue(i + 1)); 419 EXPECT_TRUE(result.IsUndefined()); 420 EXPECT_EQ(pArray->GetSize(), static_cast<int>(i + 1)); 421 } 422 423 // remove success 424 { 425 JSTaggedValue result = PlainArrayRemoveRangeFrom(pArray, JSTaggedValue(2), JSTaggedValue(2)); 426 EXPECT_EQ(result, JSTaggedValue(2)); 427 EXPECT_EQ(pArray->GetSize(), static_cast<int>(NODE_NUMBERS - 2)); 428 for (uint32_t i = 0; i < NODE_NUMBERS - 2; i++) { 429 if (i < 2) { 430 EXPECT_EQ(pArray->Get(JSTaggedValue(i)), JSTaggedValue(i + 1)); 431 } else { 432 EXPECT_EQ(pArray->Get(JSTaggedValue(i + 2)), JSTaggedValue(i + 3)); 433 } 434 } 435 } 436 437 // input index type error 438 { 439 JSTaggedValue result = PlainArrayRemoveRangeFrom(pArray, JSTaggedValue::Undefined(), JSTaggedValue(2)); 440 EXPECT_TRUE(thread->HasPendingException()); 441 EXPECT_EQ(result, JSTaggedValue::Exception()); 442 thread->ClearException(); 443 } 444 445 // input size type error 446 { 447 JSTaggedValue result = PlainArrayRemoveRangeFrom(pArray, JSTaggedValue(2), JSTaggedValue::Undefined()); 448 EXPECT_TRUE(thread->HasPendingException()); 449 EXPECT_EQ(result, JSTaggedValue::Exception()); 450 thread->ClearException(); 451 } 452 453 // input index out of range 454 { 455 JSTaggedValue result = PlainArrayRemoveRangeFrom(pArray, JSTaggedValue(NODE_NUMBERS + 1), JSTaggedValue(2)); 456 EXPECT_TRUE(thread->HasPendingException()); 457 EXPECT_EQ(result, JSTaggedValue::Exception()); 458 thread->ClearException(); 459 } 460} 461 462HWTEST_F_L0(ContainersPlainArrayTest, ProxyOfGetSize) 463{ 464 constexpr uint32_t NODE_NUMBERS = 8; 465 JSHandle<JSAPIPlainArray> proxyArrayList = CreateJSAPIPlainArray(); 466 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); 467 callInfo->SetFunction(JSTaggedValue::Undefined()); 468 JSHandle<JSProxy> proxy = CreateJSProxyHandle(thread); 469 proxy->SetTarget(thread, proxyArrayList.GetTaggedValue()); 470 callInfo->SetThis(proxy.GetTaggedValue()); 471 472 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 473 callInfo->SetCallArg(0, JSTaggedValue(i)); 474 callInfo->SetCallArg(1, JSTaggedValue(i + 1)); 475 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 476 ContainersPlainArray::Add(callInfo); 477 TestHelper::TearDownFrame(thread, prev); 478 479 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo); 480 JSTaggedValue retult = ContainersPlainArray::GetSize(callInfo); 481 TestHelper::TearDownFrame(thread, prev1); 482 EXPECT_EQ(retult, JSTaggedValue(i + 1)); 483 } 484} 485 486HWTEST_F_L0(ContainersPlainArrayTest, ExceptionReturn1) 487{ 488 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, Add); 489 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, Has); 490 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, Get); 491 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, GetIndexOfKey); 492 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, Clear); 493 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, Clone); 494 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, GetIteratorObj); 495 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, ForEach); 496 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, ToString); 497 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, GetIndexOfValue); 498 499 JSHandle<JSAPIPlainArray> plianArray = CreateJSAPIPlainArray(); 500 { 501 auto callInfo = NewEmptyCallInfo(thread); 502 callInfo->SetThis(plianArray.GetTaggedValue()); 503 CONTAINERS_API_EXCEPTION_TEST(ContainersPlainArray, Add, callInfo); 504 } 505 { 506 auto callInfo = NewEmptyCallInfo(thread); 507 callInfo->SetThis(plianArray.GetTaggedValue()); 508 CONTAINERS_API_EXCEPTION_TEST(ContainersPlainArray, Has, callInfo); 509 } 510 { 511 auto callInfo = NewEmptyCallInfo(thread); 512 callInfo->SetThis(plianArray.GetTaggedValue()); 513 CONTAINERS_API_EXCEPTION_TEST(ContainersPlainArray, Get, callInfo); 514 } 515 { 516 auto callInfo = NewEmptyCallInfo(thread); 517 callInfo->SetThis(plianArray.GetTaggedValue()); 518 CONTAINERS_API_EXCEPTION_TEST(ContainersPlainArray, GetIndexOfKey, callInfo); 519 } 520} 521 522HWTEST_F_L0(ContainersPlainArrayTest, ExceptionReturn2) 523{ 524 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, GetKeyAt); 525 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, Remove); 526 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, RemoveAt); 527 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, SetValueAt); 528 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, GetValueAt); 529 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, IsEmpty); 530 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, RemoveRangeFrom); 531 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersPlainArray, GetSize); 532 533 JSHandle<JSAPIPlainArray> plianArray = CreateJSAPIPlainArray(); 534 { 535 auto callInfo = NewEmptyCallInfo(thread); 536 callInfo->SetThis(plianArray.GetTaggedValue()); 537 CONTAINERS_API_EXCEPTION_TEST(ContainersPlainArray, GetKeyAt, callInfo); 538 } 539 { 540 auto callInfo = NewEmptyCallInfo(thread); 541 callInfo->SetThis(plianArray.GetTaggedValue()); 542 CONTAINERS_API_EXCEPTION_TEST(ContainersPlainArray, Remove, callInfo); 543 } 544 { 545 auto callInfo = NewEmptyCallInfo(thread); 546 callInfo->SetThis(plianArray.GetTaggedValue()); 547 CONTAINERS_API_EXCEPTION_TEST(ContainersPlainArray, RemoveAt, callInfo); 548 } 549 { 550 auto callInfo = NewEmptyCallInfo(thread); 551 callInfo->SetThis(plianArray.GetTaggedValue()); 552 CONTAINERS_API_EXCEPTION_TEST(ContainersPlainArray, SetValueAt, callInfo); 553 } 554 { 555 auto callInfo = NewEmptyCallInfo(thread); 556 callInfo->SetThis(plianArray.GetTaggedValue()); 557 CONTAINERS_API_EXCEPTION_TEST(ContainersPlainArray, GetValueAt, callInfo); 558 } 559} 560} 561