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 27using namespace panda; 28 29using namespace panda::ecmascript; 30 31namespace panda::test { 32class LinkedHashTableTest : public BaseTestWithScope<false> { 33public: 34 JSHandle<GlobalEnv> GetGlobalEnv() 35 { 36 EcmaVM *ecma = thread->GetEcmaVM(); 37 return ecma->GetGlobalEnv(); 38 } 39}; 40 41HWTEST_F_L0(LinkedHashTableTest, MapCreate) 42{ 43 int numOfElement = 64; 44 JSHandle<LinkedHashMap> dict = LinkedHashMap::Create(thread, numOfElement); 45 EXPECT_TRUE(*dict != nullptr); 46} 47 48HWTEST_F_L0(LinkedHashTableTest, SetCreate) 49{ 50 int numOfElement = 64; 51 JSHandle<LinkedHashSet> set = LinkedHashSet::Create(thread, numOfElement); 52 EXPECT_TRUE(*set != nullptr); 53} 54 55HWTEST_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 96HWTEST_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 134HWTEST_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 165HWTEST_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 197HWTEST_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 229HWTEST_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