1 /*
2 * Copyright (c) 2021 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/ecma_vm.h"
17 #include "ecmascript/global_env.h"
18 #include "ecmascript/js_handle.h"
19 #include "ecmascript/js_object-inl.h"
20 #include "ecmascript/js_tagged_value.h"
21 #include "ecmascript/linked_hash_table.h"
22 #include "ecmascript/linked_hash_table.h"
23 #include "ecmascript/object_factory.h"
24 #include "ecmascript/tagged_hash_table.h"
25 #include "ecmascript/tests/test_helper.h"
26
27 using namespace panda;
28
29 using namespace panda::ecmascript;
30
31 namespace panda::test {
32 class LinkedHashTableTest : public BaseTestWithScope<false> {
33 public:
GetGlobalEnv()34 JSHandle<GlobalEnv> GetGlobalEnv()
35 {
36 EcmaVM *ecma = thread->GetEcmaVM();
37 return ecma->GetGlobalEnv();
38 }
39 };
40
HWTEST_F_L0(LinkedHashTableTest,MapCreate)41 HWTEST_F_L0(LinkedHashTableTest, MapCreate)
42 {
43 int numOfElement = 64;
44 JSHandle<LinkedHashMap> dict = LinkedHashMap::Create(thread, numOfElement);
45 EXPECT_TRUE(*dict != nullptr);
46 }
47
HWTEST_F_L0(LinkedHashTableTest,SetCreate)48 HWTEST_F_L0(LinkedHashTableTest, SetCreate)
49 {
50 int numOfElement = 64;
51 JSHandle<LinkedHashSet> set = LinkedHashSet::Create(thread, numOfElement);
52 EXPECT_TRUE(*set != nullptr);
53 }
54
HWTEST_F_L0(LinkedHashTableTest,addKeyAndValue)55 HWTEST_F_L0(LinkedHashTableTest, addKeyAndValue)
56 {
57 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
58 // mock object needed in test
59 int numOfElement = 64;
60 JSHandle<LinkedHashMap> dictHandle = LinkedHashMap::Create(thread, numOfElement);
61 EXPECT_TRUE(*dictHandle != nullptr);
62 JSHandle<JSTaggedValue> objFun = GetGlobalEnv()->GetObjectFunction();
63
64 char keyArray[] = "hello";
65 JSHandle<EcmaString> stringKey1 = factory->NewFromASCII(keyArray);
66 JSHandle<JSTaggedValue> key1(stringKey1);
67 JSHandle<JSTaggedValue> value1(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
68
69 char key2Array[] = "hello2";
70 JSHandle<EcmaString> stringKey2 = factory->NewFromASCII(key2Array);
71 JSHandle<JSTaggedValue> key2(stringKey2);
72 JSHandle<JSTaggedValue> value2(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
73
74 // test set()
75 dictHandle = LinkedHashMap::Set(thread, dictHandle, key1, value1);
76 EXPECT_EQ(dictHandle->NumberOfElements(), 1);
77
78 // test find()
79 int entry1 = dictHandle->FindElement(thread, key1.GetTaggedValue());
80 EXPECT_EQ(key1.GetTaggedValue(), dictHandle->GetKey(entry1));
81 EXPECT_EQ(value1.GetTaggedValue(), dictHandle->GetValue(entry1));
82
83 dictHandle = LinkedHashMap::Set(thread, dictHandle, key2, value2);
84 EXPECT_EQ(dictHandle->NumberOfElements(), 2);
85 // test remove()
86 dictHandle = LinkedHashMap::Delete(thread, dictHandle, key1);
87 EXPECT_EQ(-1, dictHandle->FindElement(thread, key1.GetTaggedValue()));
88 EXPECT_EQ(dictHandle->NumberOfElements(), 1);
89
90 JSHandle<JSTaggedValue> undefinedKey(thread, JSTaggedValue::Undefined());
91 dictHandle = LinkedHashMap::Set(thread, dictHandle, undefinedKey, value1);
92 int entry2 = dictHandle->FindElement(thread, undefinedKey.GetTaggedValue());
93 EXPECT_EQ(value1.GetTaggedValue(), dictHandle->GetValue(entry2));
94 }
95
HWTEST_F_L0(LinkedHashTableTest,SetaddKeyAndValue)96 HWTEST_F_L0(LinkedHashTableTest, SetaddKeyAndValue)
97 {
98 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
99 // mock object needed in test
100 int numOfElement = 64;
101 JSHandle<LinkedHashSet> setHandle = LinkedHashSet::Create(thread, numOfElement);
102 EXPECT_TRUE(*setHandle != nullptr);
103 JSHandle<JSTaggedValue> objFun = GetGlobalEnv()->GetObjectFunction();
104
105 char keyArray[] = "hello";
106 JSHandle<EcmaString> stringKey1 = factory->NewFromASCII(keyArray);
107 JSHandle<JSTaggedValue> key1(stringKey1);
108 JSHandle<JSTaggedValue> value1(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
109
110 char key2Array[] = "hello2";
111 JSHandle<EcmaString> stringKey2 = factory->NewFromASCII(key2Array);
112 JSHandle<JSTaggedValue> key2(stringKey2);
113 JSHandle<JSTaggedValue> value2(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
114
115 // test set()
116 setHandle = LinkedHashSet::Add(thread, setHandle, key1);
117 EXPECT_EQ(setHandle->NumberOfElements(), 1);
118
119 // test has()
120 EXPECT_TRUE(setHandle->Has(thread, key1.GetTaggedValue()));
121
122 setHandle = LinkedHashSet::Add(thread, setHandle, key2);
123 EXPECT_EQ(setHandle->NumberOfElements(), 2);
124 // test remove()
125 setHandle = LinkedHashSet::Delete(thread, setHandle, key1);
126 EXPECT_EQ(-1, setHandle->FindElement(thread, key1.GetTaggedValue()));
127 EXPECT_EQ(setHandle->NumberOfElements(), 1);
128
129 JSHandle<JSTaggedValue> undefinedKey(thread, JSTaggedValue::Undefined());
130 setHandle = LinkedHashSet::Add(thread, setHandle, undefinedKey);
131 EXPECT_TRUE(setHandle->Has(thread, undefinedKey.GetTaggedValue()));
132 }
133
HWTEST_F_L0(LinkedHashTableTest,GrowCapacity)134 HWTEST_F_L0(LinkedHashTableTest, GrowCapacity)
135 {
136 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
137 int numOfElement = 8;
138 JSHandle<LinkedHashMap> dictHandle = LinkedHashMap::Create(thread, numOfElement);
139 EXPECT_TRUE(*dictHandle != nullptr);
140 JSHandle<JSFunction> objFun(GetGlobalEnv()->GetObjectFunction());
141 char keyArray[7] = "hello";
142 for (int i = 0; i < 33; i++) {
143 keyArray[5] = '1' + static_cast<uint32_t>(i);
144 keyArray[6] = 0;
145 JSHandle<JSTaggedValue> key(factory->NewFromASCII(keyArray));
146 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
147
148 // test insert()
149 dictHandle = LinkedHashMap::Set(thread, dictHandle, key, value);
150 EXPECT_EQ(i, dictHandle->FindElement(thread, key.GetTaggedValue()));
151 }
152
153 // test order
154 for (int i = 0; i < 33; i++) {
155 keyArray[5] = '1' + static_cast<uint32_t>(i);
156 keyArray[6] = 0;
157 JSHandle<EcmaString> stringKey = factory->NewFromASCII(keyArray);
158 // test insert()
159 EXPECT_EQ(i, dictHandle->FindElement(thread, stringKey.GetTaggedValue()));
160 }
161 EXPECT_EQ(dictHandle->NumberOfElements(), 33);
162 EXPECT_EQ(dictHandle->Capacity(), 64);
163 }
164
HWTEST_F_L0(LinkedHashTableTest,SetGrowCapacity)165 HWTEST_F_L0(LinkedHashTableTest, SetGrowCapacity)
166 {
167 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
168 int numOfElement = 8;
169 JSHandle<LinkedHashSet> setHandle = LinkedHashSet::Create(thread, numOfElement);
170 EXPECT_TRUE(*setHandle != nullptr);
171 JSHandle<JSFunction> objFun(GetGlobalEnv()->GetObjectFunction());
172 // create key and values
173 char keyArray[7] = "hello";
174 for (int i = 0; i < 33; i++) {
175 keyArray[5] = '1' + static_cast<uint32_t>(i);
176 keyArray[6] = 0;
177 JSHandle<EcmaString> stringKey = factory->NewFromASCII(keyArray);
178 JSHandle<JSTaggedValue> key(stringKey);
179
180 // test insert()
181 setHandle = LinkedHashSet::Add(thread, setHandle, key);
182 EXPECT_EQ(i, setHandle->FindElement(thread, key.GetTaggedValue()));
183 }
184
185 // test order
186 for (int i = 0; i < 33; i++) {
187 keyArray[5] = '1' + static_cast<uint32_t>(i);
188 keyArray[6] = 0;
189 JSHandle<EcmaString> stringKey = factory->NewFromASCII(keyArray);
190 // test insert()
191 EXPECT_EQ(i, setHandle->FindElement(thread, stringKey.GetTaggedValue()));
192 }
193 EXPECT_EQ(setHandle->NumberOfElements(), 33);
194 EXPECT_EQ(setHandle->Capacity(), 64);
195 }
196
HWTEST_F_L0(LinkedHashTableTest,ShrinkCapacity)197 HWTEST_F_L0(LinkedHashTableTest, ShrinkCapacity)
198 {
199 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
200 int numOfElement = 64;
201 JSHandle<LinkedHashMap> dictHandle = LinkedHashMap::Create(thread, numOfElement);
202 EXPECT_TRUE(*dictHandle != nullptr);
203 JSHandle<JSFunction> objFun(GetGlobalEnv()->GetObjectFunction());
204 char keyArray[7] = "hello";
205 for (int i = 0; i < 10; i++) {
206 keyArray[5] = '1' + static_cast<uint32_t>(i);
207 keyArray[6] = 0;
208 JSHandle<JSTaggedValue> key(factory->NewFromASCII(keyArray));
209 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
210
211 // test insert()
212 dictHandle = LinkedHashMap::Set(thread, dictHandle, key, value);
213 }
214 keyArray[5] = '1' + 9;
215 JSHandle<JSTaggedValue> key(factory->NewFromASCII(keyArray));
216 dictHandle = LinkedHashMap::Delete(thread, dictHandle, key);
217 // test order
218 for (int i = 0; i < 9; i++) {
219 keyArray[5] = '1' + static_cast<uint32_t>(i);
220 keyArray[6] = 0;
221 JSHandle<EcmaString> stringKey = factory->NewFromASCII(keyArray);
222 // test insert()
223 EXPECT_EQ(i, dictHandle->FindElement(thread, stringKey.GetTaggedValue()));
224 }
225 EXPECT_EQ(dictHandle->NumberOfElements(), 9);
226 EXPECT_EQ(dictHandle->Capacity(), 16);
227 }
228
HWTEST_F_L0(LinkedHashTableTest,SetShrinkCapacity)229 HWTEST_F_L0(LinkedHashTableTest, SetShrinkCapacity)
230 {
231 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
232 int numOfElement = 64;
233 JSHandle<LinkedHashSet> setHandle = LinkedHashSet::Create(thread, numOfElement);
234 EXPECT_TRUE(*setHandle != nullptr);
235 JSHandle<JSFunction> objFun(GetGlobalEnv()->GetObjectFunction());
236 // create key and values
237 char keyArray[7] = "hello";
238 for (int i = 0; i < 10; i++) {
239 keyArray[5] = '1' + static_cast<uint32_t>(i);
240 keyArray[6] = 0;
241 JSHandle<JSTaggedValue> key(factory->NewFromASCII(keyArray));
242
243 // test insert()
244 setHandle = LinkedHashSet::Add(thread, setHandle, key);
245 }
246 keyArray[5] = '1' + 9;
247 JSHandle<JSTaggedValue> keyHandle(factory->NewFromASCII(keyArray));
248 setHandle = LinkedHashSet::Delete(thread, setHandle, keyHandle);
249 // test order
250 for (int i = 0; i < 9; i++) {
251 keyArray[5] = '1' + static_cast<uint32_t>(i);
252 keyArray[6] = 0;
253 JSHandle<EcmaString> stringKey = factory->NewFromASCII(keyArray);
254 // test insert()
255 EXPECT_EQ(i, setHandle->FindElement(thread, stringKey.GetTaggedValue()));
256 }
257 EXPECT_EQ(setHandle->NumberOfElements(), 9);
258 EXPECT_EQ(setHandle->Capacity(), 16);
259 }
260 } // namespace panda::test
261