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/ecma_test_common.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 BaseTestWithScope<false> {
39 protected:
CreateLinkedList()40 JSAPILinkedList *CreateLinkedList()
41 {
42 return EcmaContainerCommon::CreateLinkedList(thread);
43 }
44 };
45
HWTEST_F_L0(JSAPILinkedListTest,LinkedListCreate)46 HWTEST_F_L0(JSAPILinkedListTest, LinkedListCreate)
47 {
48 JSAPILinkedList *linkedlist = CreateLinkedList();
49 EXPECT_TRUE(linkedlist != nullptr);
50 }
51
HWTEST_F_L0(JSAPILinkedListTest,AddAndHas)52 HWTEST_F_L0(JSAPILinkedListTest, AddAndHas)
53 {
54 constexpr int NODE_NUMBERS = 9;
55 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
56 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
57
58 JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
59
60 std::string myValue("myvalue");
61 for (int i = 0; i < NODE_NUMBERS; i++) {
62 std::string ivalue = myValue + std::to_string(i);
63 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
64 JSAPILinkedList::Add(thread, toor, value);
65 }
66 EXPECT_EQ(toor->Length(thread), NODE_NUMBERS);
67
68 EcmaTestCommon::ListAddHasCommon(thread, toor, value, myValue, NODE_NUMBERS) ;
69 }
70
HWTEST_F_L0(JSAPILinkedListTest,AddFirstAndGetFirst)71 HWTEST_F_L0(JSAPILinkedListTest, AddFirstAndGetFirst)
72 {
73 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
74 JSHandle<JSAPILinkedList> list(thread, CreateLinkedList());
75 list->Add(thread, list, value);
76 EXPECT_EQ(list->Length(thread), 1);
77 EXPECT_EQ(list->Get(thread, 0).GetInt(), 1);
78
79 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(2));
80 list->AddFirst(thread, list, value1);
81 EXPECT_EQ(list->Length(thread), 2);
82 EXPECT_EQ(list->GetFirst(thread).GetInt(), 2);
83 }
84
HWTEST_F_L0(JSAPILinkedListTest,InsertAndGetLast)85 HWTEST_F_L0(JSAPILinkedListTest, InsertAndGetLast)
86 {
87 JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
88 EcmaTestCommon::InsertAndGetLastCommon<JSAPILinkedList>(thread, toor);
89 }
90
HWTEST_F_L0(JSAPILinkedListTest,GetIndexOfAndGetLastIndexOf)91 HWTEST_F_L0(JSAPILinkedListTest, GetIndexOfAndGetLastIndexOf)
92 {
93 JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
94 EcmaTestCommon::GetIndexOfAndGetLastIndexOfCommon<JSAPILinkedList>(thread, toor);
95 }
96
HWTEST_F_L0(JSAPILinkedListTest,Remove)97 HWTEST_F_L0(JSAPILinkedListTest, Remove)
98 {
99 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
100 JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
101
102 EcmaTestCommon::ListRemoveCommon<JSAPILinkedList>(thread, toor, value);
103
104 EXPECT_EQ(JSAPILinkedList::RemoveFirst(thread, toor), JSTaggedValue(0));
105 value.Update(JSTaggedValue(0));
106 EXPECT_EQ(toor->Has(thread, value.GetTaggedValue()), false);
107 EXPECT_EQ(toor->Length(thread), 19);
108
109 EXPECT_EQ(JSAPILinkedList::RemoveLast(thread, toor), JSTaggedValue(19));
110 value.Update(JSTaggedValue(19));
111 EXPECT_EQ(toor->Has(thread, value.GetTaggedValue()), false);
112 EXPECT_EQ(toor->Length(thread), 18);
113
114 value.Update(JSTaggedValue(5));
115 EXPECT_EQ(JSAPILinkedList::RemoveByIndex(thread, toor, 4), value.GetTaggedValue());
116 EXPECT_EQ(toor->Has(thread, value.GetTaggedValue()), false);
117 EXPECT_EQ(toor->Length(thread), 17);
118
119 value.Update(JSTaggedValue(8));
120 EXPECT_EQ(toor->Remove(thread, value.GetTaggedValue()), JSTaggedValue::True());
121 EXPECT_EQ(toor->Has(thread, value.GetTaggedValue()), false);
122 EXPECT_EQ(toor->Length(thread), 16);
123
124 value.Update(JSTaggedValue(11));
125 EXPECT_EQ(JSAPILinkedList::RemoveFirstFound(thread, toor, value.GetTaggedValue()), JSTaggedValue::True());
126 EXPECT_EQ(toor->Has(thread, value.GetTaggedValue()), false);
127 EXPECT_EQ(toor->Length(thread), 15);
128
129 value.Update(JSTaggedValue(14));
130 EXPECT_EQ(JSAPILinkedList::RemoveLastFound(thread, toor, value.GetTaggedValue()), JSTaggedValue::True());
131 EXPECT_EQ(toor->Has(thread, value.GetTaggedValue()), false);
132 EXPECT_EQ(toor->Length(thread), 14);
133
134 toor->Dump(thread);
135 }
136
HWTEST_F_L0(JSAPILinkedListTest,SpecialReturnOfRemove)137 HWTEST_F_L0(JSAPILinkedListTest, SpecialReturnOfRemove)
138 {
139 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
140 JSHandle<JSAPILinkedList> linkedList(thread, CreateLinkedList());
141 JSAPILinkedList::RemoveFirst(thread, linkedList);
142 EXPECT_EXCEPTION();
143
144 JSAPILinkedList::RemoveLast(thread, linkedList);
145 EXPECT_EXCEPTION();
146
147 JSAPILinkedList::RemoveFirstFound(thread, linkedList, value.GetTaggedValue());
148 EXPECT_EXCEPTION();
149
150 // test Remove and RemoveLastFound linkedlist whose nodeLength less than 0
151 JSHandle<TaggedDoubleList> doubleList(thread, linkedList->GetDoubleList(thread));
152 doubleList->SetNumberOfNodes(thread, -1);
153 EXPECT_EQ(linkedList->Remove(thread, value.GetTaggedValue()), JSTaggedValue::False());
154
155 JSAPILinkedList::RemoveFirstFound(thread, linkedList, value.GetTaggedValue());
156 EXPECT_EXCEPTION();
157 }
158
HWTEST_F_L0(JSAPILinkedListTest,Clear)159 HWTEST_F_L0(JSAPILinkedListTest, Clear)
160 {
161 JSAPILinkedList *linkedlist = CreateLinkedList();
162
163 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
164 JSHandle<JSAPILinkedList> list(thread, linkedlist);
165 JSAPILinkedList::Add(thread, list, value);
166
167 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(2));
168 JSAPILinkedList::Insert(thread, list, value1, 0);
169
170 list->Clear(thread);
171
172 EXPECT_EQ(list->Length(thread), 0);
173 EXPECT_TRUE(list->GetFirst(thread).IsUndefined());
174 }
175
HWTEST_F_L0(JSAPILinkedListTest,Set)176 HWTEST_F_L0(JSAPILinkedListTest, Set)
177 {
178 constexpr uint32_t NODE_NUMBERS = 20;
179 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
180 JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
181
182 EcmaTestCommon::ListRemoveCommon<JSAPILinkedList>(thread, toor, value);
183
184 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
185 value.Update(JSTaggedValue(i + 1));
186 JSAPILinkedList::Set(thread, toor, i, value);
187 }
188
189 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
190 value.Update(JSTaggedValue(i + 1));
191 JSTaggedValue gValue = toor->Get(thread, i);
192 EXPECT_EQ(gValue, value.GetTaggedValue());
193 }
194 }
195
HWTEST_F_L0(JSAPILinkedListTest,GetOwnProperty)196 HWTEST_F_L0(JSAPILinkedListTest, GetOwnProperty)
197 {
198 constexpr uint32_t DEFAULT_LENGTH = 8;
199 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
200 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
201 JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
202
203 std::string linkedListvalue("linkedListvalue");
204 for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
205 std::string ivalue = linkedListvalue + std::to_string(i);
206 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
207 JSAPILinkedList::Add(thread, toor, value);
208 }
209 // test GetOwnProperty
210 int testInt = 1;
211 JSHandle<JSTaggedValue> linkedListKey1(thread, JSTaggedValue(testInt));
212 EXPECT_TRUE(JSAPILinkedList::GetOwnProperty(thread, toor, linkedListKey1));
213 testInt = 20;
214 JSHandle<JSTaggedValue> linkedListKey2(thread, JSTaggedValue(testInt));
215 EXPECT_FALSE(JSAPILinkedList::GetOwnProperty(thread, toor, linkedListKey2));
216 EXPECT_EXCEPTION();
217
218 // test GetOwnProperty exception
219 JSHandle<JSTaggedValue> undefined(thread, JSTaggedValue::Undefined());
220 EXPECT_FALSE(JSAPILinkedList::GetOwnProperty(thread, toor, undefined));
221 EXPECT_EXCEPTION();
222 }
223
224 /**
225 * @tc.name: GetProperty
226 * @tc.desc:
227 * @tc.type: FUNC
228 * @tc.require:
229 */
HWTEST_F_L0(JSAPILinkedListTest,GetProperty)230 HWTEST_F_L0(JSAPILinkedListTest, GetProperty)
231 {
232 JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
233 uint32_t elementsNums = 8;
234 for (uint32_t i = 0; i < elementsNums; i++) {
235 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
236 JSAPILinkedList::Add(thread, toor, value);
237 }
238 for (uint32_t i = 0; i < elementsNums; i++) {
239 JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
240 OperationResult getPropertyRes = JSAPILinkedList::GetProperty(thread, toor, key);
241 EXPECT_EQ(getPropertyRes.GetValue().GetTaggedValue(), JSTaggedValue(i));
242 }
243 }
244
245 /**
246 * @tc.name: SetProperty
247 * @tc.desc:
248 * @tc.type: FUNC
249 * @tc.require:
250 */
HWTEST_F_L0(JSAPILinkedListTest,SetProperty)251 HWTEST_F_L0(JSAPILinkedListTest, SetProperty)
252 {
253 JSHandle<JSAPILinkedList> toor(thread, CreateLinkedList());
254 uint32_t elementsNums = 8;
255 for (uint32_t i = 0; i < elementsNums; i++) {
256 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
257 JSAPILinkedList::Add(thread, toor, value);
258 }
259 for (uint32_t i = 0; i < elementsNums; i++) {
260 JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
261 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i * 2)); // 2 : It means double
262 bool setPropertyRes = JSAPILinkedList::SetProperty(thread, toor, key, value);
263 EXPECT_EQ(setPropertyRes, true);
264 }
265 JSHandle<JSTaggedValue> key(thread, JSTaggedValue(-1));
266 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(-1));
267 EXPECT_FALSE(JSAPILinkedList::SetProperty(thread, toor, key, value));
268 JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(elementsNums));
269 EXPECT_FALSE(JSAPILinkedList::SetProperty(thread, toor, key1, value));
270 }
271
HWTEST_F_L0(JSAPILinkedListTest,Clone)272 HWTEST_F_L0(JSAPILinkedListTest, Clone)
273 {
274 uint32_t elementsNums = 8;
275 JSAPILinkedList *linkedlist = CreateLinkedList();
276 JSHandle<JSAPILinkedList> list(thread, linkedlist);
277 for (uint32_t i = 0; i < elementsNums; i++) {
278 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
279 JSAPILinkedList::Add(thread, list, value);
280 }
281 JSHandle<JSAPILinkedList> cloneList = JSAPILinkedList::Clone(thread, list);
282
283 for (uint32_t i = 0; i < elementsNums; i++) {
284 EXPECT_EQ(cloneList->Get(thread, i), list->Get(thread, i));
285 }
286 EXPECT_EQ(list->Length(thread), cloneList->Length(thread));
287 }
288
HWTEST_F_L0(JSAPILinkedListTest,OwnKeys)289 HWTEST_F_L0(JSAPILinkedListTest, OwnKeys)
290 {
291 uint32_t elementsNums = 8;
292 JSHandle<JSAPILinkedList> linkedList(thread, CreateLinkedList());
293 for (uint32_t i = 0; i < elementsNums; i++) {
294 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
295 JSAPILinkedList::Add(thread, linkedList, value);
296 }
297 JSHandle<TaggedArray> keyArray = JSAPILinkedList::OwnKeys(thread, linkedList);
298 EXPECT_TRUE(keyArray->GetClass()->IsTaggedArray());
299 EXPECT_TRUE(keyArray->GetLength() == elementsNums);
300 for (uint32_t i = 0; i < elementsNums; i++) {
301 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(thread,
302 *(base::NumberHelper::NumberToString(thread, JSTaggedValue(i))),
303 EcmaString::Cast(keyArray->Get(thread, i).GetTaggedObject())));
304 }
305 }
306 } // namespace panda::test
307