• 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,ClearAndisEmpty)134 HWTEST_F_L0(JSAPIVectorTest, ClearAndisEmpty)
135 {
136     constexpr uint32_t NODE_NUMBERS = 9;
137     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
138 
139     std::string myValue("myvalue");
140     auto toor = TestCommon(value, myValue, NODE_NUMBERS);
141 
142     JSAPIVector::Clear(thread, toor);
143     EXPECT_EQ(toor->IsEmpty(), true);
144 
145     toor->Dump();
146 }
147 
HWTEST_F_L0(JSAPIVectorTest,GetIndexOf)148 HWTEST_F_L0(JSAPIVectorTest, GetIndexOf)
149 {
150     constexpr uint32_t NODE_NUMBERS = 9;
151     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
152     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
153 
154     JSHandle<JSAPIVector> toor(thread, CreateVector());
155 
156     std::string myValue("myvalue");
157     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
158         std::string ivalue = myValue + std::to_string(i);
159         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
160         bool result = JSAPIVector::Add(thread, toor, value);
161         EXPECT_TRUE(result);
162         EXPECT_EQ(JSAPIVector::GetIndexOf(thread, toor, value), static_cast<int>(i));
163     }
164 
165     toor->Dump();
166 }
167 
HWTEST_F_L0(JSAPIVectorTest,GetOwnProperty)168 HWTEST_F_L0(JSAPIVectorTest, GetOwnProperty)
169 {
170     constexpr uint32_t DEFAULT_LENGTH = 8;
171     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
172     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
173     JSHandle<JSAPIVector> toor(thread, CreateVector());
174 
175     std::string vectorvalue("vectorvalue");
176     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
177         std::string ivalue = vectorvalue + std::to_string(i);
178         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
179         JSAPIVector::Add(thread, toor, value);
180     }
181     // test GetOwnProperty
182     int testInt = 1;
183     JSHandle<JSTaggedValue> vectorKey1(thread, JSTaggedValue(testInt));
184     EXPECT_TRUE(JSAPIVector::GetOwnProperty(thread, toor, vectorKey1));
185     testInt = 20;
186     JSHandle<JSTaggedValue> vectorKey2(thread, JSTaggedValue(testInt));
187     EXPECT_FALSE(JSAPIVector::GetOwnProperty(thread, toor, vectorKey2));
188     EXPECT_EXCEPTION();
189 
190     // test GetOwnProperty exception
191     JSHandle<JSTaggedValue> undefined(thread, JSTaggedValue::Undefined());
192     EXPECT_FALSE(JSAPIVector::GetOwnProperty(thread, toor, undefined));
193     EXPECT_EXCEPTION();
194 }
195 
196 /**
197  * @tc.name: GetProperty
198  * @tc.desc:
199  * @tc.type: FUNC
200  * @tc.require:
201  */
HWTEST_F_L0(JSAPIVectorTest,GetProperty)202 HWTEST_F_L0(JSAPIVectorTest, GetProperty)
203 {
204     JSHandle<JSAPIVector> toor(thread, CreateVector());
205     uint32_t elementsNums = 8;
206     for (uint32_t i = 0; i < elementsNums; i++) {
207         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
208         JSAPIVector::Add(thread, toor, value);
209     }
210     for (uint32_t i = 0; i < elementsNums; i++) {
211         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
212         OperationResult getPropertyRes = JSAPIVector::GetProperty(thread, toor, key);
213         EXPECT_EQ(getPropertyRes.GetValue().GetTaggedValue(), JSTaggedValue(i));
214     }
215 
216     // test GetProperty exception
217     JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(-1));
218     JSAPIVector::GetProperty(thread, toor, key1);
219     EXPECT_EXCEPTION();
220     JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(elementsNums));
221     JSAPIVector::GetProperty(thread, toor, key2);
222     EXPECT_EXCEPTION();
223 }
224 
225 /**
226  * @tc.name: SetProperty
227  * @tc.desc:
228  * @tc.type: FUNC
229  * @tc.require:
230  */
HWTEST_F_L0(JSAPIVectorTest,SetProperty)231 HWTEST_F_L0(JSAPIVectorTest, SetProperty)
232 {
233     JSHandle<JSAPIVector> toor(thread, CreateVector());
234     uint32_t elementsNums = 8;
235     for (uint32_t i = 0; i < elementsNums; i++) {
236         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
237         JSAPIVector::Add(thread, toor, value);
238     }
239     for (uint32_t i = 0; i < elementsNums; i++) {
240         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
241         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i * 2)); // 2 : It means double
242         bool setPropertyRes = JSAPIVector::SetProperty(thread, toor, key, value);
243         EXPECT_EQ(setPropertyRes, true);
244     }
245     JSHandle<JSTaggedValue> key(thread, JSTaggedValue(-1));
246     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(0));
247     EXPECT_FALSE(JSAPIVector::SetProperty(thread, toor, key, value));
248     JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(elementsNums));
249     EXPECT_FALSE(JSAPIVector::SetProperty(thread, toor, key1, value));
250 }
251 
252 /**
253  * @tc.name: TrimToCurrentLength
254  * @tc.desc:
255  * @tc.type: FUNC
256  * @tc.require:
257  */
HWTEST_F_L0(JSAPIVectorTest,IncreaseCapacityToTrimToCurrentLength)258 HWTEST_F_L0(JSAPIVectorTest, IncreaseCapacityToTrimToCurrentLength)
259 {
260     JSHandle<JSAPIVector> toor(thread, CreateVector());
261     uint32_t elementsNums = 20;
262     for (uint32_t i = 0; i < elementsNums; i++) {
263         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
264         JSAPIVector::Add(thread, toor, value);
265     }
266     JSAPIVector::IncreaseCapacityTo(thread, toor, 80);
267     JSHandle<TaggedArray> elementData(thread, toor->GetElements());
268     EXPECT_EQ(static_cast<int>(elementData->GetLength()), 80);
269     JSAPIVector::TrimToCurrentLength(thread, toor);
270     JSHandle<TaggedArray> newElementData(thread, toor->GetElements());
271     EXPECT_EQ(newElementData->GetLength(), elementsNums);
272 
273     // test IncreaseCapacityTo exception
274     JSAPIVector::IncreaseCapacityTo(thread, toor, -1);
275     EXPECT_EXCEPTION();
276 }
277 
278 /**
279  * @tc.name: Insert
280  * @tc.desc:
281  * @tc.type: FUNC
282  * @tc.require:
283  */
HWTEST_F_L0(JSAPIVectorTest,Insert)284 HWTEST_F_L0(JSAPIVectorTest, Insert)
285 {
286     JSHandle<JSAPIVector> toor(thread, CreateVector());
287     uint32_t elementsNums = 20;
288     for (uint32_t i = 0; i < elementsNums; i++) {
289         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
290         JSAPIVector::Insert(thread, toor, value, 0);
291     }
292 
293     // check
294     for (uint32_t i = 0; i < elementsNums; i++) {
295         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
296         EXPECT_EQ(JSAPIVector::Get(
297             thread, toor, static_cast<int32_t>(i)), JSTaggedValue(elementsNums - i - 1));
298     }
299 
300     // test Insert exception
301     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(elementsNums));
302     JSAPIVector::Insert(thread, toor, value, -1);
303     EXPECT_EXCEPTION();
304 
305     JSAPIVector::Insert(thread, toor, value, static_cast<int32_t>(elementsNums + 1));
306     EXPECT_EXCEPTION();
307 }
308 
309 /**
310  * @tc.name: SetLength, GetIndexFrom, GetLastElement, GetLastIndexOf and GetLastIndexFrom
311  * @tc.desc:
312  * @tc.type: FUNC
313  * @tc.require:
314  */
HWTEST_F_L0(JSAPIVectorTest,SetLengthGetIndexFromGetLastElementGetLastIndexOf)315 HWTEST_F_L0(JSAPIVectorTest, SetLengthGetIndexFromGetLastElementGetLastIndexOf)
316 {
317     JSHandle<JSAPIVector> toor(thread, CreateVector());
318 
319     // test GetLastElement of empty vector
320     EXPECT_EQ(toor->GetLastElement(), JSTaggedValue::Undefined());
321 
322     // test GetLastIndexOf of empty vector
323     uint32_t elementsNums = 20;
324     JSHandle<JSTaggedValue> obj(thread, JSTaggedValue(elementsNums - 1));
325     EXPECT_EQ(JSAPIVector::GetLastIndexOf(thread, toor, obj), -1);
326 
327     for (uint32_t i = 0; i < elementsNums; i++) {
328         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
329         JSAPIVector::Add(thread, toor, value);
330     }
331 
332     // test GetIndexFrom
333     EXPECT_EQ(JSAPIVector::GetIndexFrom(thread, toor, obj, -1), static_cast<int32_t>(elementsNums - 1));
334 
335     EXPECT_EQ(JSAPIVector::GetIndexFrom(thread, toor, obj, elementsNums), -1);
336     EXPECT_EXCEPTION();
337 
338     // test GetLastElement
339     EXPECT_EQ(toor->GetLastElement(), JSTaggedValue(elementsNums - 1));
340 
341     // test GetLastIndexOf
342     EXPECT_EQ(JSAPIVector::GetLastIndexOf(thread, toor, obj), static_cast<int32_t>(elementsNums - 1));
343 
344     // test GetLastIndexFrom
345     EXPECT_EQ(JSAPIVector::GetLastIndexFrom(
346         thread, toor, obj, elementsNums - 1), static_cast<int32_t>(elementsNums - 1));
347 
348     EXPECT_EQ(JSAPIVector::GetLastIndexFrom(thread, toor, obj, elementsNums), -1);
349     EXPECT_EXCEPTION();
350 
351     JSHandle<JSTaggedValue> obj1(thread, JSTaggedValue(-elementsNums));
352     EXPECT_EQ(JSAPIVector::GetLastIndexFrom(thread, toor, obj1, -1), -1);
353 
354     // test SetLength
355     JSAPIVector::SetLength(thread, toor, elementsNums * 3);
356     EXPECT_EQ(toor->GetLength(), static_cast<int32_t>(elementsNums * 3));
357 }
358 
359 /**
360  * @tc.name: RemoveByRange
361  * @tc.desc:
362  * @tc.type: FUNC
363  * @tc.require:
364  */
HWTEST_F_L0(JSAPIVectorTest,ExceptionOfRemoveByRange)365 HWTEST_F_L0(JSAPIVectorTest, ExceptionOfRemoveByRange)
366 {
367     JSHandle<JSAPIVector> toor(thread, CreateVector());
368     uint32_t elementsNums = 20;
369     for (uint32_t i = 0; i < elementsNums; i++) {
370         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
371         JSAPIVector::Add(thread, toor, value);
372     }
373 
374     // test RemoveByRange exception
375     // toIndex <= fromIndex
376     JSTaggedValue result1 = JSAPIVector::RemoveByRange(thread, toor, 0, 0);
377     EXPECT_EQ(result1, JSTaggedValue::Exception());
378     EXPECT_EXCEPTION();
379 
380     // from < 0
381     JSTaggedValue result2 = JSAPIVector::RemoveByRange(thread, toor, -1, 0);
382     EXPECT_EQ(result2, JSTaggedValue::Exception());
383     EXPECT_EXCEPTION();
384 
385     // fromIndex >= length
386     JSTaggedValue result3 = JSAPIVector::RemoveByRange(thread, toor, elementsNums, elementsNums * 2);
387     EXPECT_EQ(result3, JSTaggedValue::Exception());
388     EXPECT_EXCEPTION();
389 }
390 
391 /**
392  * @tc.name: SubVector
393  * @tc.desc:
394  * @tc.type: FUNC
395  * @tc.require:
396  */
HWTEST_F_L0(JSAPIVectorTest,ExceptionOfSubVector)397 HWTEST_F_L0(JSAPIVectorTest, ExceptionOfSubVector)
398 {
399     JSHandle<JSAPIVector> toor(thread, CreateVector());
400     uint32_t elementsNums = 20;
401     for (uint32_t i = 0; i < elementsNums; i++) {
402         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
403         JSAPIVector::Add(thread, toor, value);
404     }
405 
406     // test SubVector exception
407     // from < 0
408     JSAPIVector::SubVector(thread, toor, -1, 0);
409     EXPECT_EXCEPTION();
410 
411     // toIndex < 0
412     JSAPIVector::SubVector(thread, toor, 0, -1);
413     EXPECT_EXCEPTION();
414 
415     // fromIndex >= length
416     JSAPIVector::SubVector(thread, toor, elementsNums, 0);
417     EXPECT_EXCEPTION();
418 
419     // ToIndex >= length
420     JSAPIVector::SubVector(thread, toor, 0, elementsNums);
421     EXPECT_EXCEPTION();
422 
423     // toIndex <= fromIndex
424     JSAPIVector::SubVector(thread, toor, elementsNums - 1, 0);
425     EXPECT_EXCEPTION();
426 }
427 
428 /**
429  * @tc.name: OwnKeys
430  * @tc.desc:
431  * @tc.type: FUNC
432  * @tc.require:
433  */
HWTEST_F_L0(JSAPIVectorTest,OwnKeys)434 HWTEST_F_L0(JSAPIVectorTest, OwnKeys)
435 {
436     JSHandle<JSAPIVector> toor(thread, CreateVector());
437     uint32_t elementsNums = 8;
438     for (uint32_t i = 0; i < elementsNums; i++) {
439         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
440         JSAPIVector::Add(thread, toor, value);
441     }
442     JSHandle<TaggedArray> keyArray = JSAPIVector::OwnKeys(thread, toor);
443     EXPECT_TRUE(keyArray->GetClass()->IsTaggedArray());
444     EXPECT_TRUE(keyArray->GetLength() == elementsNums);
445     for (uint32_t i = 0; i < elementsNums; i++) {
446         ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(
447             *(base::NumberHelper::NumberToString(thread, JSTaggedValue(i))),
448             EcmaString::Cast(keyArray->Get(i).GetTaggedObject())
449         ));
450     }
451 }
452 
453 /**
454  * @tc.name: GetFirstElement
455  * @tc.desc:
456  * @tc.type: FUNC
457  * @tc.require:
458  */
HWTEST_F_L0(JSAPIVectorTest,GetFirstElement)459 HWTEST_F_L0(JSAPIVectorTest, GetFirstElement)
460 {
461     JSHandle<JSAPIVector> toor(thread, CreateVector());
462     EXPECT_EQ(JSAPIVector::GetFirstElement(toor), JSTaggedValue::Undefined());
463 
464     uint32_t elementsNums = 8;
465     for (uint32_t i = 0; i < elementsNums; i++) {
466         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
467         JSAPIVector::Add(thread, toor, value);
468     }
469     EXPECT_EQ(JSAPIVector::GetFirstElement(toor), JSTaggedValue(0));
470 }
471 }  // namespace panda::test
472