• 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_private.h"
17 #include "ecmascript/ecma_string.h"
18 #include "ecmascript/ecma_vm.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_api/js_api_vector.h"
21 #include "ecmascript/js_api/js_api_vector_iterator.h"
22 #include "ecmascript/js_function.h"
23 #include "ecmascript/js_handle.h"
24 #include "ecmascript/js_iterator.h"
25 #include "ecmascript/js_object-inl.h"
26 #include "ecmascript/js_tagged_value.h"
27 #include "ecmascript/object_factory.h"
28 #include "ecmascript/tests/ecma_test_common.h"
29 
30 using namespace panda;
31 
32 using namespace panda::ecmascript;
33 
34 using namespace panda::ecmascript::containers;
35 
36 namespace panda::test {
37 class JSAPIVectorTest : public BaseTestWithScope<false> {
38 protected:
CreateVector()39     JSAPIVector *CreateVector()
40     {
41         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
42         auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::Vector);
43         JSHandle<JSTaggedValue> constructor(thread, result);
44         JSHandle<JSAPIVector> vector(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
45         vector->SetLength(0);
46         return *vector;
47     }
48 
TestCommon(JSMutableHandle<JSTaggedValue> & value,std::string & myValue,uint32_t nums)49     JSHandle<JSAPIVector> TestCommon(JSMutableHandle<JSTaggedValue>& value, std::string& myValue, uint32_t nums)
50     {
51         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
52         JSHandle<JSAPIVector> toor(thread, CreateVector());
53 
54         for (uint32_t i = 0; i < nums; i++) {
55             std::string ivalue = myValue + std::to_string(i);
56             value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
57             bool result = JSAPIVector::Add(thread, toor, value);
58             EXPECT_TRUE(result);
59             EXPECT_EQ(toor->IsEmpty(), false);
60         }
61         return toor;
62     }
63 };
64 
HWTEST_F_L0(JSAPIVectorTest,vectorCreate)65 HWTEST_F_L0(JSAPIVectorTest, vectorCreate)
66 {
67     JSAPIVector *vector = CreateVector();
68     EXPECT_TRUE(vector != nullptr);
69 }
70 
HWTEST_F_L0(JSAPIVectorTest,AddGetHas)71 HWTEST_F_L0(JSAPIVectorTest, AddGetHas)
72 {
73     constexpr uint32_t NODE_NUMBERS = 9;
74     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
75     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
76 
77     JSHandle<JSAPIVector> toor(thread, CreateVector());
78 
79     // test Has of empty vector
80     value.Update(JSTaggedValue(NODE_NUMBERS));
81     EXPECT_FALSE(toor->Has(value.GetTaggedValue()));
82 
83     std::string myValue("myvalue");
84     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
85         std::string ivalue = myValue + std::to_string(i);
86         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
87         bool result = JSAPIVector::Add(thread, toor, value);
88         EXPECT_TRUE(result);
89         EXPECT_EQ(JSAPIVector::Get(thread, toor, i), value.GetTaggedValue());
90         EXPECT_TRUE(toor->Has(value.GetTaggedValue()));
91     }
92     value.Update(JSTaggedValue(NODE_NUMBERS));
93     EXPECT_FALSE(toor->Has(value.GetTaggedValue()));
94     EXPECT_EQ(static_cast<uint32_t>(toor->GetSize()), NODE_NUMBERS);
95 
96     // test Get exception
97     JSAPIVector::Get(thread, toor, -1);
98     EXPECT_EXCEPTION();
99     JSAPIVector::Get(thread, toor, static_cast<int32_t>(NODE_NUMBERS));
100     EXPECT_EXCEPTION();
101 
102     toor->Dump();
103 }
104 
HWTEST_F_L0(JSAPIVectorTest,RemoveByIndexAndRemove)105 HWTEST_F_L0(JSAPIVectorTest, RemoveByIndexAndRemove)
106 {
107     constexpr uint32_t NODE_NUMBERS = 9;
108     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
109     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
110 
111     std::string myValue("myvalue");
112     auto toor = TestCommon(value, myValue, NODE_NUMBERS);
113 
114     for (int32_t i = NODE_NUMBERS / 2; i > 0; i--) {
115         std::string ivalue = myValue + std::to_string(i);
116         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
117         JSTaggedValue gValue = JSAPIVector::RemoveByIndex(thread, toor, i);
118         EXPECT_EQ(gValue, value.GetTaggedValue());
119         bool delResult = JSAPIVector::Remove(thread, toor, value);
120         EXPECT_FALSE(delResult);
121     }
122 
123     // test RemoveByIndex exception
124     JSTaggedValue result = JSAPIVector::RemoveByIndex(thread, toor, -1);
125     EXPECT_EQ(result, JSTaggedValue::Exception());
126     EXPECT_EXCEPTION();
127     JSTaggedValue result1 = JSAPIVector::RemoveByIndex(thread, toor, NODE_NUMBERS);
128     EXPECT_EQ(result1, JSTaggedValue::Exception());
129     EXPECT_EXCEPTION();
130 
131     toor->Dump();
132 }
133 
HWTEST_F_L0(JSAPIVectorTest,RemoveByRangeAndGetHeapUsedSize)134 HWTEST_F_L0(JSAPIVectorTest, RemoveByRangeAndGetHeapUsedSize)
135 {
136     uint32_t NODE_NUMBERS = 9;
137     uint32_t fromIndex = 1;
138     uint32_t toIndex = 3;
139     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
140 
141     std::string myValue("myvalue");
142     auto toor = TestCommon(value, myValue, NODE_NUMBERS);
143     JSAPIVector::RemoveByRange(thread, toor, fromIndex, toIndex);
144     // test heap is normal after RemoveByRange, GetLiveObjectSize will iterate heap
145     instance->GetHeap()->GetLiveObjectSize();
146     EXPECT_EQ(toor->GetLength(), static_cast<int32_t>(NODE_NUMBERS - (toIndex - fromIndex)));
147 }
148 
HWTEST_F_L0(JSAPIVectorTest,ClearAndisEmpty)149 HWTEST_F_L0(JSAPIVectorTest, ClearAndisEmpty)
150 {
151     constexpr uint32_t NODE_NUMBERS = 9;
152     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
153 
154     std::string myValue("myvalue");
155     auto toor = TestCommon(value, myValue, NODE_NUMBERS);
156 
157     JSAPIVector::Clear(thread, toor);
158     EXPECT_EQ(toor->IsEmpty(), true);
159 
160     toor->Dump();
161 }
162 
HWTEST_F_L0(JSAPIVectorTest,GetIndexOf)163 HWTEST_F_L0(JSAPIVectorTest, GetIndexOf)
164 {
165     constexpr uint32_t NODE_NUMBERS = 9;
166     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
167     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
168 
169     JSHandle<JSAPIVector> toor(thread, CreateVector());
170 
171     std::string myValue("myvalue");
172     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
173         std::string ivalue = myValue + std::to_string(i);
174         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
175         bool result = JSAPIVector::Add(thread, toor, value);
176         EXPECT_TRUE(result);
177         EXPECT_EQ(JSAPIVector::GetIndexOf(thread, toor, value), static_cast<int>(i));
178     }
179 
180     toor->Dump();
181 }
182 
HWTEST_F_L0(JSAPIVectorTest,GetOwnProperty)183 HWTEST_F_L0(JSAPIVectorTest, GetOwnProperty)
184 {
185     constexpr uint32_t DEFAULT_LENGTH = 8;
186     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
187     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
188     JSHandle<JSAPIVector> toor(thread, CreateVector());
189 
190     std::string vectorvalue("vectorvalue");
191     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
192         std::string ivalue = vectorvalue + std::to_string(i);
193         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
194         JSAPIVector::Add(thread, toor, value);
195     }
196     // test GetOwnProperty
197     int testInt = 1;
198     JSHandle<JSTaggedValue> vectorKey1(thread, JSTaggedValue(testInt));
199     EXPECT_TRUE(JSAPIVector::GetOwnProperty(thread, toor, vectorKey1));
200     testInt = 20;
201     JSHandle<JSTaggedValue> vectorKey2(thread, JSTaggedValue(testInt));
202     EXPECT_FALSE(JSAPIVector::GetOwnProperty(thread, toor, vectorKey2));
203     EXPECT_EXCEPTION();
204 
205     // test GetOwnProperty exception
206     JSHandle<JSTaggedValue> undefined(thread, JSTaggedValue::Undefined());
207     EXPECT_FALSE(JSAPIVector::GetOwnProperty(thread, toor, undefined));
208     EXPECT_EXCEPTION();
209 }
210 
211 /**
212  * @tc.name: GetProperty
213  * @tc.desc:
214  * @tc.type: FUNC
215  * @tc.require:
216  */
HWTEST_F_L0(JSAPIVectorTest,GetProperty)217 HWTEST_F_L0(JSAPIVectorTest, GetProperty)
218 {
219     JSHandle<JSAPIVector> toor(thread, CreateVector());
220     uint32_t elementsNums = 8;
221     for (uint32_t i = 0; i < elementsNums; i++) {
222         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
223         JSAPIVector::Add(thread, toor, value);
224     }
225     for (uint32_t i = 0; i < elementsNums; i++) {
226         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
227         OperationResult getPropertyRes = JSAPIVector::GetProperty(thread, toor, key);
228         EXPECT_EQ(getPropertyRes.GetValue().GetTaggedValue(), JSTaggedValue(i));
229     }
230 
231     // test GetProperty exception
232     JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(-1));
233     JSAPIVector::GetProperty(thread, toor, key1);
234     EXPECT_EXCEPTION();
235     JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(elementsNums));
236     JSAPIVector::GetProperty(thread, toor, key2);
237     EXPECT_EXCEPTION();
238 }
239 
240 /**
241  * @tc.name: SetProperty
242  * @tc.desc:
243  * @tc.type: FUNC
244  * @tc.require:
245  */
HWTEST_F_L0(JSAPIVectorTest,SetProperty)246 HWTEST_F_L0(JSAPIVectorTest, SetProperty)
247 {
248     JSHandle<JSAPIVector> toor(thread, CreateVector());
249     uint32_t elementsNums = 8;
250     for (uint32_t i = 0; i < elementsNums; i++) {
251         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
252         JSAPIVector::Add(thread, toor, value);
253     }
254     for (uint32_t i = 0; i < elementsNums; i++) {
255         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
256         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i * 2)); // 2 : It means double
257         bool setPropertyRes = JSAPIVector::SetProperty(thread, toor, key, value);
258         EXPECT_EQ(setPropertyRes, true);
259     }
260     JSHandle<JSTaggedValue> key(thread, JSTaggedValue(-1));
261     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(0));
262     EXPECT_FALSE(JSAPIVector::SetProperty(thread, toor, key, value));
263     JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(elementsNums));
264     EXPECT_FALSE(JSAPIVector::SetProperty(thread, toor, key1, value));
265 }
266 
267 /**
268  * @tc.name: TrimToCurrentLength
269  * @tc.desc:
270  * @tc.type: FUNC
271  * @tc.require:
272  */
HWTEST_F_L0(JSAPIVectorTest,IncreaseCapacityToTrimToCurrentLength)273 HWTEST_F_L0(JSAPIVectorTest, IncreaseCapacityToTrimToCurrentLength)
274 {
275     JSHandle<JSAPIVector> toor(thread, CreateVector());
276     uint32_t elementsNums = 20;
277     for (uint32_t i = 0; i < elementsNums; i++) {
278         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
279         JSAPIVector::Add(thread, toor, value);
280     }
281     JSAPIVector::IncreaseCapacityTo(thread, toor, 80);
282     JSHandle<TaggedArray> elementData(thread, toor->GetElements());
283     EXPECT_EQ(static_cast<int>(elementData->GetLength()), 80);
284     JSAPIVector::TrimToCurrentLength(thread, toor);
285     JSHandle<TaggedArray> newElementData(thread, toor->GetElements());
286     EXPECT_EQ(newElementData->GetLength(), elementsNums);
287 
288     // test IncreaseCapacityTo exception
289     JSAPIVector::IncreaseCapacityTo(thread, toor, -1);
290     EXPECT_EXCEPTION();
291 }
292 
293 /**
294  * @tc.name: Insert
295  * @tc.desc:
296  * @tc.type: FUNC
297  * @tc.require:
298  */
HWTEST_F_L0(JSAPIVectorTest,Insert)299 HWTEST_F_L0(JSAPIVectorTest, Insert)
300 {
301     JSHandle<JSAPIVector> toor(thread, CreateVector());
302     uint32_t elementsNums = 20;
303     for (uint32_t i = 0; i < elementsNums; i++) {
304         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
305         JSAPIVector::Insert(thread, toor, value, 0);
306     }
307 
308     // check
309     for (uint32_t i = 0; i < elementsNums; i++) {
310         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
311         EXPECT_EQ(JSAPIVector::Get(
312             thread, toor, static_cast<int32_t>(i)), JSTaggedValue(elementsNums - i - 1));
313     }
314 
315     // test Insert exception
316     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(elementsNums));
317     JSAPIVector::Insert(thread, toor, value, -1);
318     EXPECT_EXCEPTION();
319 
320     JSAPIVector::Insert(thread, toor, value, static_cast<int32_t>(elementsNums + 1));
321     EXPECT_EXCEPTION();
322 }
323 
324 /**
325  * @tc.name: SetLength, GetIndexFrom, GetLastElement, GetLastIndexOf and GetLastIndexFrom
326  * @tc.desc:
327  * @tc.type: FUNC
328  * @tc.require:
329  */
HWTEST_F_L0(JSAPIVectorTest,SetLengthGetIndexFromGetLastElementGetLastIndexOf)330 HWTEST_F_L0(JSAPIVectorTest, SetLengthGetIndexFromGetLastElementGetLastIndexOf)
331 {
332     JSHandle<JSAPIVector> toor(thread, CreateVector());
333 
334     // test GetLastElement of empty vector
335     EXPECT_EQ(toor->GetLastElement(), JSTaggedValue::Undefined());
336 
337     // test GetLastIndexOf of empty vector
338     uint32_t elementsNums = 20;
339     JSHandle<JSTaggedValue> obj(thread, JSTaggedValue(elementsNums - 1));
340     EXPECT_EQ(JSAPIVector::GetLastIndexOf(thread, toor, obj), -1);
341 
342     for (uint32_t i = 0; i < elementsNums; i++) {
343         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
344         JSAPIVector::Add(thread, toor, value);
345     }
346 
347     // test GetIndexFrom
348     EXPECT_EQ(JSAPIVector::GetIndexFrom(thread, toor, obj, -1), static_cast<int32_t>(elementsNums - 1));
349 
350     EXPECT_EQ(JSAPIVector::GetIndexFrom(thread, toor, obj, elementsNums), -1);
351     EXPECT_EXCEPTION();
352 
353     // test GetLastElement
354     EXPECT_EQ(toor->GetLastElement(), JSTaggedValue(elementsNums - 1));
355 
356     // test GetLastIndexOf
357     EXPECT_EQ(JSAPIVector::GetLastIndexOf(thread, toor, obj), static_cast<int32_t>(elementsNums - 1));
358 
359     // test GetLastIndexFrom
360     EXPECT_EQ(JSAPIVector::GetLastIndexFrom(
361         thread, toor, obj, elementsNums - 1), static_cast<int32_t>(elementsNums - 1));
362 
363     EXPECT_EQ(JSAPIVector::GetLastIndexFrom(thread, toor, obj, elementsNums), -1);
364     EXPECT_EXCEPTION();
365 
366     JSHandle<JSTaggedValue> obj1(thread, JSTaggedValue(-elementsNums));
367     EXPECT_EQ(JSAPIVector::GetLastIndexFrom(thread, toor, obj1, -1), -1);
368 
369     // test SetLength
370     JSAPIVector::SetLength(thread, toor, elementsNums * 3);
371     EXPECT_EQ(toor->GetLength(), static_cast<int32_t>(elementsNums * 3));
372 }
373 
374 /**
375  * @tc.name: RemoveByRange
376  * @tc.desc:
377  * @tc.type: FUNC
378  * @tc.require:
379  */
HWTEST_F_L0(JSAPIVectorTest,ExceptionOfRemoveByRange)380 HWTEST_F_L0(JSAPIVectorTest, ExceptionOfRemoveByRange)
381 {
382     JSHandle<JSAPIVector> toor(thread, CreateVector());
383     uint32_t elementsNums = 20;
384     for (uint32_t i = 0; i < elementsNums; i++) {
385         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
386         JSAPIVector::Add(thread, toor, value);
387     }
388 
389     // test RemoveByRange exception
390     // toIndex <= fromIndex
391     JSTaggedValue result1 = JSAPIVector::RemoveByRange(thread, toor, 0, 0);
392     EXPECT_EQ(result1, JSTaggedValue::Exception());
393     EXPECT_EXCEPTION();
394 
395     // from < 0
396     JSTaggedValue result2 = JSAPIVector::RemoveByRange(thread, toor, -1, 0);
397     EXPECT_EQ(result2, JSTaggedValue::Exception());
398     EXPECT_EXCEPTION();
399 
400     // fromIndex >= length
401     JSTaggedValue result3 = JSAPIVector::RemoveByRange(thread, toor, elementsNums, elementsNums * 2);
402     EXPECT_EQ(result3, JSTaggedValue::Exception());
403     EXPECT_EXCEPTION();
404 }
405 
406 /**
407  * @tc.name: SubVector
408  * @tc.desc:
409  * @tc.type: FUNC
410  * @tc.require:
411  */
HWTEST_F_L0(JSAPIVectorTest,ExceptionOfSubVector)412 HWTEST_F_L0(JSAPIVectorTest, ExceptionOfSubVector)
413 {
414     JSHandle<JSAPIVector> toor(thread, CreateVector());
415     uint32_t elementsNums = 20;
416     for (uint32_t i = 0; i < elementsNums; i++) {
417         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
418         JSAPIVector::Add(thread, toor, value);
419     }
420 
421     // test SubVector exception
422     // from < 0
423     JSAPIVector::SubVector(thread, toor, -1, 0);
424     EXPECT_EXCEPTION();
425 
426     // toIndex < 0
427     JSAPIVector::SubVector(thread, toor, 0, -1);
428     EXPECT_EXCEPTION();
429 
430     // fromIndex >= length
431     JSAPIVector::SubVector(thread, toor, elementsNums, 0);
432     EXPECT_EXCEPTION();
433 
434     // ToIndex >= length
435     JSAPIVector::SubVector(thread, toor, 0, elementsNums);
436     EXPECT_EXCEPTION();
437 
438     // toIndex <= fromIndex
439     JSAPIVector::SubVector(thread, toor, elementsNums - 1, 0);
440     EXPECT_EXCEPTION();
441 }
442 
443 /**
444  * @tc.name: OwnKeys
445  * @tc.desc:
446  * @tc.type: FUNC
447  * @tc.require:
448  */
HWTEST_F_L0(JSAPIVectorTest,OwnKeys)449 HWTEST_F_L0(JSAPIVectorTest, OwnKeys)
450 {
451     JSHandle<JSAPIVector> toor(thread, CreateVector());
452     uint32_t elementsNums = 8;
453     for (uint32_t i = 0; i < elementsNums; i++) {
454         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
455         JSAPIVector::Add(thread, toor, value);
456     }
457     JSHandle<TaggedArray> keyArray = JSAPIVector::OwnKeys(thread, toor);
458     EXPECT_TRUE(keyArray->GetClass()->IsTaggedArray());
459     EXPECT_TRUE(keyArray->GetLength() == elementsNums);
460     for (uint32_t i = 0; i < elementsNums; i++) {
461         ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(
462             *(base::NumberHelper::NumberToString(thread, JSTaggedValue(i))),
463             EcmaString::Cast(keyArray->Get(i).GetTaggedObject())
464         ));
465     }
466 }
467 
468 /**
469  * @tc.name: GetFirstElement
470  * @tc.desc:
471  * @tc.type: FUNC
472  * @tc.require:
473  */
HWTEST_F_L0(JSAPIVectorTest,GetFirstElement)474 HWTEST_F_L0(JSAPIVectorTest, GetFirstElement)
475 {
476     JSHandle<JSAPIVector> toor(thread, CreateVector());
477     EXPECT_EQ(JSAPIVector::GetFirstElement(toor), JSTaggedValue::Undefined());
478 
479     uint32_t elementsNums = 8;
480     for (uint32_t i = 0; i < elementsNums; i++) {
481         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
482         JSAPIVector::Add(thread, toor, value);
483     }
484     EXPECT_EQ(JSAPIVector::GetFirstElement(toor), JSTaggedValue(0));
485 }
486 }  // namespace panda::test
487