• 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_linked_list.h"
21 #include "ecmascript/js_api/js_api_linked_list_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/tagged_list.h"
29 #include "ecmascript/tests/test_helper.h"
30 
31 using namespace panda;
32 
33 using namespace panda::ecmascript;
34 
35 using namespace panda::ecmascript::containers;
36 
37 namespace panda::test {
38 class JSAPILinkedListTest : public testing::Test {
39 public:
SetUpTestCase()40     static void SetUpTestCase()
41     {
42         GTEST_LOG_(INFO) << "SetUpTestCase";
43     }
44 
TearDownTestCase()45     static void TearDownTestCase()
46     {
47         GTEST_LOG_(INFO) << "TearDownCase";
48     }
49 
SetUp()50     void SetUp() override
51     {
52         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
53     }
54 
TearDown()55     void TearDown() override
56     {
57         TestHelper::DestroyEcmaVMWithScope(instance, scope);
58     }
59 
60     EcmaVM *instance {nullptr};
61     ecmascript::EcmaHandleScope *scope {nullptr};
62     JSThread *thread {nullptr};
63 
64 protected:
CreateLinkedList()65     JSAPILinkedList *CreateLinkedList()
66     {
67         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
68         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
69 
70         JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
71         JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
72         JSHandle<JSTaggedValue> value =
73             JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
74 
75         auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
76         objCallInfo->SetFunction(JSTaggedValue::Undefined());
77         objCallInfo->SetThis(value.GetTaggedValue());
78         objCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(containers::ContainerTag::LinkedList)));
79 
80         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
81         JSHandle<JSTaggedValue> contianer =
82             JSHandle<JSTaggedValue>(thread, ContainersPrivate::Load(objCallInfo));
83         JSHandle<JSAPILinkedList> linkedList =
84             JSHandle<JSAPILinkedList>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(contianer),
85                                                                               contianer));
86         JSTaggedValue doubleList = TaggedDoubleList::Create(thread);
87         linkedList->SetDoubleList(thread, doubleList);
88         return *linkedList;
89     }
90 };
91 
HWTEST_F_L0(JSAPILinkedListTest,LinkedListCreate)92 HWTEST_F_L0(JSAPILinkedListTest, LinkedListCreate)
93 {
94     JSAPILinkedList *linkedlist = CreateLinkedList();
95     EXPECT_TRUE(linkedlist != nullptr);
96 }
97 
HWTEST_F_L0(JSAPILinkedListTest,AddAndHas)98 HWTEST_F_L0(JSAPILinkedListTest, AddAndHas)
99 {
100     constexpr int NODE_NUMBERS = 9;
101     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
102     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
103 
104     JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
105 
106     std::string myValue("myvalue");
107     for (int i = 0; i < NODE_NUMBERS; i++) {
108         std::string ivalue = myValue + std::to_string(i);
109         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
110         JSAPILinkedList::Add(thread, toor, value);
111     }
112     EXPECT_EQ(toor->Length(), NODE_NUMBERS);
113 
114     for (int i = 0; i < NODE_NUMBERS; i++) {
115         std::string ivalue = myValue + std::to_string(i);
116         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
117 
118         JSTaggedValue gValue = toor->Get(i);
119         EXPECT_EQ(gValue, value.GetTaggedValue());
120     }
121     JSTaggedValue gValue = toor->Get(10);
122     EXPECT_EQ(gValue, JSTaggedValue::Undefined());
123 
124     std::string ivalue = myValue + std::to_string(1);
125     value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
126     EXPECT_TRUE(toor->Has(value.GetTaggedValue()));
127 }
128 
HWTEST_F_L0(JSAPILinkedListTest,AddFirstAndGetFirst)129 HWTEST_F_L0(JSAPILinkedListTest, AddFirstAndGetFirst)
130 {
131     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
132     JSHandle<JSAPILinkedList> list(thread, CreateLinkedList());
133     list->Add(thread, list, value);
134     EXPECT_EQ(list->Length(), 1);
135     EXPECT_EQ(list->Get(0).GetInt(), 1);
136 
137     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(2));
138     list->AddFirst(thread, list, value1);
139     EXPECT_EQ(list->Length(), 2);
140     EXPECT_EQ(list->GetFirst().GetInt(), 2);
141 }
142 
HWTEST_F_L0(JSAPILinkedListTest,InsertAndGetLast)143 HWTEST_F_L0(JSAPILinkedListTest, InsertAndGetLast)
144 {    // create jsMap
145     constexpr uint32_t NODE_NUMBERS = 9;
146     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
147 
148     JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
149     EXPECT_EQ(toor->GetLast(), JSTaggedValue::Undefined());
150     EXPECT_EQ(toor->GetFirst(), JSTaggedValue::Undefined());
151     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
152         value.Update(JSTaggedValue(i + 1));
153         JSAPILinkedList::Add(thread, toor, value);
154     }
155     EXPECT_EQ(toor->GetLast().GetInt(), 9);
156     EXPECT_EQ(toor->GetFirst().GetInt(), 1);
157 
158     value.Update(JSTaggedValue(99));
159     int len = toor->Length();
160     toor->Insert(thread, toor, value, len);
161     EXPECT_EQ(toor->GetLast().GetInt(), 99);
162     EXPECT_EQ(toor->Length(), 10);
163 
164     value.Update(JSTaggedValue(100));
165     toor->Insert(thread, toor, value, 0);
166     EXPECT_EQ(toor->GetFirst().GetInt(), 100);
167     EXPECT_EQ(toor->Length(), 11);
168 
169     toor->Dump();
170 
171     value.Update(JSTaggedValue(101));
172     toor->Insert(thread, toor, value, 5);
173     EXPECT_EQ(toor->Length(), 12);
174     toor->Dump();
175     EXPECT_EQ(toor->Get(5).GetInt(), 101);
176 }
177 
HWTEST_F_L0(JSAPILinkedListTest,GetIndexOfAndGetLastIndexOf)178 HWTEST_F_L0(JSAPILinkedListTest, GetIndexOfAndGetLastIndexOf)
179 {    // create jsMap
180     constexpr uint32_t NODE_NUMBERS = 9;
181     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
182 
183     JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
184     EXPECT_EQ(toor->GetLast(), JSTaggedValue::Undefined());
185     EXPECT_EQ(toor->GetFirst(), JSTaggedValue::Undefined());
186     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
187         value.Update(JSTaggedValue(i + 1));
188         JSAPILinkedList::Add(thread, toor, value);
189     }
190     EXPECT_EQ(toor->GetLast().GetInt(), 9);
191     EXPECT_EQ(toor->GetFirst().GetInt(), 1);
192 
193     value.Update(JSTaggedValue(99));
194     int len = toor->Length();
195     toor->Insert(thread, toor, value, len);
196     EXPECT_EQ(toor->GetIndexOf(value.GetTaggedValue()).GetInt(), 9);
197     EXPECT_EQ(toor->GetLastIndexOf(value.GetTaggedValue()).GetInt(), 9);
198     EXPECT_EQ(toor->Length(), 10);
199 
200     value.Update(JSTaggedValue(100));
201     toor->Insert(thread, toor, value, 0);
202     EXPECT_EQ(toor->GetIndexOf(value.GetTaggedValue()).GetInt(), 0);
203     EXPECT_EQ(toor->GetLastIndexOf(value.GetTaggedValue()).GetInt(), 0);
204     EXPECT_EQ(toor->Length(), 11);
205 
206     value.Update(JSTaggedValue(101));
207     toor->Insert(thread, toor, value, 5);
208     EXPECT_EQ(toor->GetIndexOf(value.GetTaggedValue()).GetInt(), 5);
209     EXPECT_EQ(toor->GetLastIndexOf(value.GetTaggedValue()).GetInt(), 5);
210     EXPECT_EQ(toor->Length(), 12);
211 
212     toor->Dump();
213 }
214 
HWTEST_F_L0(JSAPILinkedListTest,Remove)215 HWTEST_F_L0(JSAPILinkedListTest, Remove)
216 {
217     constexpr uint32_t NODE_NUMBERS = 20;
218     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
219 
220     JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
221     EXPECT_EQ(toor->GetLast(), JSTaggedValue::Undefined());
222     EXPECT_EQ(toor->GetFirst(), JSTaggedValue::Undefined());
223     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
224         value.Update(JSTaggedValue(i));
225         JSAPILinkedList::Add(thread, toor, value);
226     }
227     EXPECT_EQ(toor->Length(), 20);
228     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
229         value.Update(JSTaggedValue(i));
230         JSTaggedValue gValue = toor->Get(i);
231         EXPECT_EQ(gValue, value.GetTaggedValue());
232     }
233 
234     EXPECT_EQ(JSAPILinkedList::RemoveFirst(thread, toor), JSTaggedValue(0));
235     value.Update(JSTaggedValue(0));
236     EXPECT_EQ(toor->Has(value.GetTaggedValue()), false);
237     EXPECT_EQ(toor->Length(), 19);
238 
239     EXPECT_EQ(JSAPILinkedList::RemoveLast(thread, toor), JSTaggedValue(19));
240     value.Update(JSTaggedValue(19));
241     EXPECT_EQ(toor->Has(value.GetTaggedValue()), false);
242     EXPECT_EQ(toor->Length(), 18);
243 
244     value.Update(JSTaggedValue(5));
245     EXPECT_EQ(JSAPILinkedList::RemoveByIndex(thread, toor, 4), value.GetTaggedValue());
246     EXPECT_EQ(toor->Has(value.GetTaggedValue()), false);
247     EXPECT_EQ(toor->Length(), 17);
248 
249     value.Update(JSTaggedValue(8));
250     EXPECT_EQ(toor->Remove(thread, value.GetTaggedValue()), JSTaggedValue::True());
251     EXPECT_EQ(toor->Has(value.GetTaggedValue()), false);
252     EXPECT_EQ(toor->Length(), 16);
253 
254     value.Update(JSTaggedValue(11));
255     EXPECT_EQ(JSAPILinkedList::RemoveFirstFound(thread, toor, value.GetTaggedValue()), JSTaggedValue::True());
256     EXPECT_EQ(toor->Has(value.GetTaggedValue()), false);
257     EXPECT_EQ(toor->Length(), 15);
258 
259     value.Update(JSTaggedValue(14));
260     EXPECT_EQ(JSAPILinkedList::RemoveLastFound(thread, toor, value.GetTaggedValue()), JSTaggedValue::True());
261     EXPECT_EQ(toor->Has(value.GetTaggedValue()), false);
262     EXPECT_EQ(toor->Length(), 14);
263 
264     toor->Dump();
265 }
266 
HWTEST_F_L0(JSAPILinkedListTest,SpecialReturnOfRemove)267 HWTEST_F_L0(JSAPILinkedListTest, SpecialReturnOfRemove)
268 {
269     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
270     JSHandle<JSAPILinkedList> linkedList(thread, CreateLinkedList());
271     JSAPILinkedList::RemoveFirst(thread, linkedList);
272     EXPECT_EXCEPTION();
273 
274     JSAPILinkedList::RemoveLast(thread, linkedList);
275     EXPECT_EXCEPTION();
276 
277     JSAPILinkedList::RemoveFirstFound(thread, linkedList, value.GetTaggedValue());
278     EXPECT_EXCEPTION();
279 
280     // test Remove and RemoveLastFound linkedlist whose nodeLength less than 0
281     JSHandle<TaggedDoubleList> doubleList(thread, linkedList->GetDoubleList());
282     doubleList->SetNumberOfNodes(thread, -1);
283     EXPECT_EQ(linkedList->Remove(thread, value.GetTaggedValue()), JSTaggedValue::False());
284 
285     JSAPILinkedList::RemoveFirstFound(thread, linkedList, value.GetTaggedValue());
286     EXPECT_EXCEPTION();
287 }
288 
HWTEST_F_L0(JSAPILinkedListTest,Clear)289 HWTEST_F_L0(JSAPILinkedListTest, Clear)
290 {
291     JSAPILinkedList *linkedlist = CreateLinkedList();
292 
293     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
294     JSHandle<JSAPILinkedList> list(thread, linkedlist);
295     JSAPILinkedList::Add(thread, list, value);
296 
297     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(2));
298     JSAPILinkedList::Insert(thread, list, value1, 0);
299 
300     list->Clear(thread);
301 
302     EXPECT_EQ(list->Length(), 0);
303     EXPECT_TRUE(list->GetFirst().IsUndefined());
304 }
305 
HWTEST_F_L0(JSAPILinkedListTest,Set)306 HWTEST_F_L0(JSAPILinkedListTest, Set)
307 {
308     constexpr uint32_t NODE_NUMBERS = 20;
309     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
310 
311     JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
312     EXPECT_EQ(toor->GetLast(), JSTaggedValue::Undefined());
313     EXPECT_EQ(toor->GetFirst(), JSTaggedValue::Undefined());
314     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
315         value.Update(JSTaggedValue(i));
316         JSAPILinkedList::Add(thread, toor, value);
317     }
318     EXPECT_EQ(toor->Length(), 20);
319 
320     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
321         value.Update(JSTaggedValue(i));
322         JSTaggedValue gValue = toor->Get(i);
323         EXPECT_EQ(gValue, value.GetTaggedValue());
324     }
325 
326     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
327         value.Update(JSTaggedValue(i + 1));
328         JSAPILinkedList::Set(thread, toor, i, value);
329     }
330 
331     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
332         value.Update(JSTaggedValue(i + 1));
333         JSTaggedValue gValue = toor->Get(i);
334         EXPECT_EQ(gValue, value.GetTaggedValue());
335     }
336 }
337 
HWTEST_F_L0(JSAPILinkedListTest,GetOwnProperty)338 HWTEST_F_L0(JSAPILinkedListTest, GetOwnProperty)
339 {
340     constexpr uint32_t DEFAULT_LENGTH = 8;
341     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
342     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
343     JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
344 
345     std::string linkedListvalue("linkedListvalue");
346     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
347         std::string ivalue = linkedListvalue + std::to_string(i);
348         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
349         JSAPILinkedList::Add(thread, toor, value);
350     }
351     // test GetOwnProperty
352     int testInt = 1;
353     JSHandle<JSTaggedValue> linkedListKey1(thread, JSTaggedValue(testInt));
354     EXPECT_TRUE(JSAPILinkedList::GetOwnProperty(thread, toor, linkedListKey1));
355     testInt = 20;
356     JSHandle<JSTaggedValue> linkedListKey2(thread, JSTaggedValue(testInt));
357     EXPECT_FALSE(JSAPILinkedList::GetOwnProperty(thread, toor, linkedListKey2));
358     EXPECT_EXCEPTION();
359 
360     // test GetOwnProperty exception
361     JSHandle<JSTaggedValue> undefined(thread, JSTaggedValue::Undefined());
362     EXPECT_FALSE(JSAPILinkedList::GetOwnProperty(thread, toor, undefined));
363     EXPECT_EXCEPTION();
364 }
365 
366 /**
367  * @tc.name: GetProperty
368  * @tc.desc:
369  * @tc.type: FUNC
370  * @tc.require:
371  */
HWTEST_F_L0(JSAPILinkedListTest,GetProperty)372 HWTEST_F_L0(JSAPILinkedListTest, GetProperty)
373 {
374     JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
375     uint32_t elementsNums = 8;
376     for (uint32_t i = 0; i < elementsNums; i++) {
377         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
378         JSAPILinkedList::Add(thread, toor, value);
379     }
380     for (uint32_t i = 0; i < elementsNums; i++) {
381         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
382         OperationResult getPropertyRes = JSAPILinkedList::GetProperty(thread, toor, key);
383         EXPECT_EQ(getPropertyRes.GetValue().GetTaggedValue(), JSTaggedValue(i));
384     }
385 }
386 
387 /**
388  * @tc.name: SetProperty
389  * @tc.desc:
390  * @tc.type: FUNC
391  * @tc.require:
392  */
HWTEST_F_L0(JSAPILinkedListTest,SetProperty)393 HWTEST_F_L0(JSAPILinkedListTest, SetProperty)
394 {
395     JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
396     uint32_t elementsNums = 8;
397     for (uint32_t i = 0; i < elementsNums; i++) {
398         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
399         JSAPILinkedList::Add(thread, toor, value);
400     }
401     for (uint32_t i = 0; i < elementsNums; i++) {
402         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
403         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i * 2)); // 2 : It means double
404         bool setPropertyRes = JSAPILinkedList::SetProperty(thread, toor, key, value);
405         EXPECT_EQ(setPropertyRes, true);
406     }
407     JSHandle<JSTaggedValue> key(thread, JSTaggedValue(-1));
408     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(-1));
409     EXPECT_FALSE(JSAPILinkedList::SetProperty(thread, toor, key, value));
410     JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(elementsNums));
411     EXPECT_FALSE(JSAPILinkedList::SetProperty(thread, toor, key1, value));
412 }
413 
HWTEST_F_L0(JSAPILinkedListTest,Clone)414 HWTEST_F_L0(JSAPILinkedListTest, Clone)
415 {
416     uint32_t elementsNums = 8;
417     JSAPILinkedList *linkedlist = CreateLinkedList();
418     JSHandle<JSAPILinkedList> list(thread, linkedlist);
419     for (uint32_t i = 0; i < elementsNums; i++) {
420         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
421         JSAPILinkedList::Add(thread, list, value);
422     }
423     JSHandle<JSAPILinkedList> cloneList = JSAPILinkedList::Clone(thread, list);
424 
425     for (uint32_t i = 0; i < elementsNums; i++) {
426         EXPECT_EQ(cloneList->Get(i), list->Get(i));
427     }
428     EXPECT_EQ(list->Length(), cloneList->Length());
429 }
430 
HWTEST_F_L0(JSAPILinkedListTest,OwnKeys)431 HWTEST_F_L0(JSAPILinkedListTest, OwnKeys)
432 {
433     uint32_t elementsNums = 8;
434     JSHandle<JSAPILinkedList> linkedList(thread, CreateLinkedList());
435     for (uint32_t i = 0; i < elementsNums; i++) {
436         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
437         JSAPILinkedList::Add(thread, linkedList, value);
438     }
439     JSHandle<TaggedArray> keyArray = JSAPILinkedList::OwnKeys(thread, linkedList);
440     EXPECT_TRUE(keyArray->GetClass()->IsTaggedArray());
441     EXPECT_TRUE(keyArray->GetLength() == elementsNums);
442     for (uint32_t i = 0; i < elementsNums; i++) {
443         ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*(base::NumberHelper::NumberToString(thread, JSTaggedValue(i))),
444             EcmaString::Cast(keyArray->Get(i).GetTaggedObject())));
445     }
446 }
447 }  // namespace panda::test
448