• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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