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