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
29 using namespace panda::ecmascript;
30 using namespace panda::ecmascript::containers;
31
32 namespace panda::test {
33 class ContainersPlainArrayTest : 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> 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 };
75 protected:
InitializePlainArrayConstructor()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
CreateJSAPIPlainArray()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
PlainArrayAdd(JSHandle<JSAPIPlainArray> plainArray,JSTaggedValue index,JSTaggedValue value)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
PlainArrayRemoveRangeFrom(JSHandle<JSAPIPlainArray> plainArray,JSTaggedValue index,JSTaggedValue size)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
HWTEST_F_L0(ContainersPlainArrayTest,PlainArrayConstructor)146 HWTEST_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
HWTEST_F_L0(ContainersPlainArrayTest,AddAndHas)173 HWTEST_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.IsTrue());
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.IsTrue());
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
HWTEST_F_L0(ContainersPlainArrayTest,Iterator)250 HWTEST_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.IsTrue());
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.IsTrue());
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
HWTEST_F_L0(ContainersPlainArrayTest,GetIndexOfKeyAndGetIndexOfValue)318 HWTEST_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.IsTrue());
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.IsTrue());
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
HWTEST_F_L0(ContainersPlainArrayTest,RemoveRangeFrom)413 HWTEST_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.IsTrue());
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
HWTEST_F_L0(ContainersPlainArrayTest,ProxyOfGetSize)462 HWTEST_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
HWTEST_F_L0(ContainersPlainArrayTest,ExceptionReturn1)486 HWTEST_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
HWTEST_F_L0(ContainersPlainArrayTest,ExceptionReturn2)522 HWTEST_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