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/symbol_table.h" 17#include "ecmascript/ecma_string.h" 18#include "ecmascript/js_symbol.h" 19#include "ecmascript/object_factory.h" 20#include "ecmascript/js_tagged_value.h" 21#include "ecmascript/tagged_array-inl.h" 22#include "ecmascript/tests/test_helper.h" 23 24using namespace panda::ecmascript; 25 26namespace panda::test { 27class SymbolTableTest : public BaseTestWithScope<false> { 28}; 29 30HWTEST_F_L0(SymbolTableTest, GetKeyIndex) 31{ 32 int entry = 0; 33 EXPECT_EQ(SymbolTable::GetKeyIndex(entry), 3); 34} 35 36HWTEST_F_L0(SymbolTableTest, GetValueIndex) 37{ 38 int entry = 0; 39 EXPECT_EQ(SymbolTable::GetValueIndex(entry), 4); 40} 41 42HWTEST_F_L0(SymbolTableTest, GetEntryIndex) 43{ 44 int entry = 0; 45 EXPECT_EQ(SymbolTable::GetEntryIndex(entry), 3); 46} 47 48HWTEST_F_L0(SymbolTableTest, GetEntrySize) 49{ 50 EXPECT_EQ(SymbolTable::GetEntrySize(), 2); 51} 52 53/* 54 * Feature: SymbolTableTest 55 * Function: IsMatch 56 * SubFunction: StringsAreEqual 57 * FunctionPoints: Is Match 58 * CaseDescription: Judge whether two string variables are equal. If they are equal, 59 * it returns true, otherwise it returns false. 60 */ 61HWTEST_F_L0(SymbolTableTest, IsMatch) 62{ 63 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 64 65 JSHandle<EcmaString> symbolTableString = factory->NewFromASCII("name"); 66 JSTaggedValue symbolTableOther = symbolTableString.GetTaggedValue(); 67 68 JSTaggedValue symbolTableName1 = JSTaggedValue::Hole(); 69 EXPECT_EQ(SymbolTable::IsMatch(symbolTableName1, symbolTableOther), false); 70 71 JSTaggedValue symbolTableName2 = JSTaggedValue::Undefined(); 72 EXPECT_EQ(SymbolTable::IsMatch(symbolTableName2, symbolTableOther), false); 73 74 JSTaggedValue symbolTableName3 = symbolTableString.GetTaggedValue(); 75 EXPECT_EQ(SymbolTable::IsMatch(symbolTableName3, symbolTableOther), true); 76} 77 78/* 79 * Feature: SymbolTableTest 80 * Function: Hash_Utf8 81 * SubFunction: GetHashCode 82 * FunctionPoints: Hash 83 * CaseDescription: The hash code is obtained by passing in a character string array or an uint8_t 84 * type array through a specific calculation formula. 85 */ 86HWTEST_F_L0(SymbolTableTest, Hash_Utf8) 87{ 88 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 89 // test obj is not string 90 JSHandle<JSTaggedValue> jsObJect(factory->NewEmptyJSObject()); 91 EXPECT_EQ(SymbolTable::Hash(jsObJect.GetTaggedValue()), JSSymbol::ComputeHash()); 92 93 uint8_t utf8ArrayName1[4] = {1, 2, 3}; // The last element is "\0" 94 uint32_t utf8ArrayNameLen1 = sizeof(utf8ArrayName1) - 1; 95 JSHandle<EcmaString> nameStringUtf8Obj1 = factory->NewFromUtf8(utf8ArrayName1, utf8ArrayNameLen1); 96 EXPECT_EQ(SymbolTable::Hash(nameStringUtf8Obj1.GetTaggedValue()), 1026U); // 1026 = (1 << 5 - 1 + 2) << 5 - 2 + 3 97 98 uint8_t utf8ArrayName2[] = "key"; 99 uint32_t utf8ArrayNameLen2 = sizeof(utf8ArrayName2) - 1; 100 JSHandle<EcmaString> nameStringUtf8Obj2 = factory->NewFromUtf8(utf8ArrayName2, utf8ArrayNameLen2); 101 EXPECT_EQ(SymbolTable::Hash(nameStringUtf8Obj2.GetTaggedValue()), 106079U); 102} 103 104/* 105 * Feature: SymbolTableTest 106 * Function: Hash_Utf16 107 * SubFunction: GetHashCode 108 * FunctionPoints: Hash 109 * CaseDescription: The hash code is obtained by passing in a character string array or an uint16_t 110 * type array through a specific calculation formula. 111 */ 112HWTEST_F_L0(SymbolTableTest, Hash_Utf16) 113{ 114 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 115 116 uint16_t utf16ArrayName1[] = {1, 2, 3}; 117 uint32_t utf16ArrayNameLen1 = sizeof(utf16ArrayName1) / sizeof(utf16ArrayName1[0]); 118 JSHandle<EcmaString> nameStringUtf16Obj1 = factory->NewFromUtf16(utf16ArrayName1, utf16ArrayNameLen1); 119 EXPECT_EQ(SymbolTable::Hash(nameStringUtf16Obj1.GetTaggedValue()), 1026U); // 1026 = (1 << 5 - 1 + 2) << 5 - 2 + 3 120 121 uint16_t utf16ArrayName2[] = {0, 1, 2}; 122 uint32_t utf16ArrayNameLen2 = sizeof(utf16ArrayName2) / sizeof(utf16ArrayName2[0]); 123 JSHandle<EcmaString> nameStringUtf16Obj2 = factory->NewFromUtf16(utf16ArrayName2, utf16ArrayNameLen2); 124 EXPECT_EQ(SymbolTable::Hash(nameStringUtf16Obj2.GetTaggedValue()), 33U); // 33 = (0 << 5 - 0 + 1) << 5 - 1 + 2 125} 126 127/* 128 * Feature: SymbolTableTest 129 * Function: Create 130 * SubFunction: *Value 131 * FunctionPoints: Create 132 * CaseDescription: A pointer variable of symboltable type is obtained by changing the function, 133 * If it is created successfully, the pointer variable is not equal to null, 134 * The prerequisite for creation is that compressedstringsenabled must be true. 135 */ 136HWTEST_F_L0(SymbolTableTest, Create) 137{ 138 int numberOfElements = SymbolTable::DEFAULT_ELEMENTS_NUMBER; 139 140 JSHandle<SymbolTable> symbolTable = SymbolTable::Create(thread, numberOfElements); 141 EXPECT_TRUE(*symbolTable != nullptr); 142} 143 144/* 145 * Feature: SymbolTableTest 146 * Function: ContainsKey 147 * SubFunction: Getkey 148 * FunctionPoints: Contains Key 149 * CaseDescription: Judge whether the key value can be found in the key value in your own created symbol 150 * table.If you do not have a key value, you will return false. 151 */ 152HWTEST_F_L0(SymbolTableTest, ContainsKey) 153{ 154 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 155 JSHandle<EcmaString> symbolTableStringKey1 = factory->NewFromASCII("key"); 156 JSHandle<EcmaString> symbolTableStringKey2 = factory->NewFromASCII("key1"); 157 JSHandle<EcmaString> symbolTableStringKey3 = factory->NewFromASCII("value"); 158 159 int numberOfElements = 2; 160 JSHandle<SymbolTable> symbolTable = SymbolTable::Create(thread, numberOfElements); 161 EXPECT_EQ(symbolTable->ContainsKey(symbolTableStringKey1.GetTaggedValue()), false); 162 163 symbolTable->SetKey(thread, 1, JSTaggedValue::Hole()); 164 EXPECT_EQ(symbolTable->ContainsKey(symbolTableStringKey1.GetTaggedValue()), false); 165 166 symbolTable->SetKey(thread, 1, JSTaggedValue::Undefined()); 167 EXPECT_EQ(symbolTable->ContainsKey(symbolTableStringKey1.GetTaggedValue()), false); 168 169 symbolTable->SetKey(thread, 1, symbolTableStringKey1.GetTaggedValue()); 170 EXPECT_EQ(symbolTable->ContainsKey(symbolTableStringKey1.GetTaggedValue()), true); 171 172 // the key value has numbers 173 symbolTable->SetKey(thread, 1, symbolTableStringKey2.GetTaggedValue()); 174 EXPECT_EQ(symbolTable->ContainsKey(symbolTableStringKey2.GetTaggedValue()), false); 175 176 symbolTable->SetKey(thread, 1, symbolTableStringKey3.GetTaggedValue()); 177 EXPECT_EQ(symbolTable->ContainsKey(symbolTableStringKey3.GetTaggedValue()), true); 178} 179 180/* 181 * Feature: SymbolTableTest 182 * Function: GetSymbol 183 * SubFunction: GetValue 184 * FunctionPoints: Get Symbol 185 * CaseDescription: This function obtains the value in the key of symbol table pointer variable created 186 * by the create function. If the pointer variable has no value set, it returns false. 187 */ 188HWTEST_F_L0(SymbolTableTest, GetSymbol) 189{ 190 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 191 int numberOfElements = 2; 192 193 JSHandle<EcmaString> symbolTableStringKey = factory->NewFromASCII("key"); 194 JSHandle<SymbolTable> symbolTable = SymbolTable::Create(thread, numberOfElements); 195 196 symbolTable->SetKey(thread, 1, symbolTableStringKey.GetTaggedValue()); 197 EXPECT_EQ(symbolTable->GetSymbol(symbolTableStringKey.GetTaggedValue()), JSTaggedValue::Undefined()); 198 199 symbolTable->SetValue(thread, 0, JSTaggedValue(1)); 200 EXPECT_EQ(symbolTable->GetSymbol(symbolTableStringKey.GetTaggedValue()), JSTaggedValue::Undefined()); 201 202 symbolTable->SetValue(thread, 1, JSTaggedValue(1)); 203 EXPECT_EQ(symbolTable->GetSymbol(symbolTableStringKey.GetTaggedValue()).GetInt(), 1); 204} 205 206/* 207 * Feature: SymbolTableTest 208 * Function: FindSymbol 209 * SubFunction: GetKey 210 * FunctionPoints: Find Symbol 211 * CaseDescription: This function compares the key value in the symboltable pointer variable created by the create 212 * function with the description value in the jssymbol type variable. If they are equal, it indicates 213 * that the find symbol is successful, and the return value is the key value. Before creating the 214 * symboltable pointer, perform the NewFromASCII operation to obtain the array length. 215 */ 216HWTEST_F_L0(SymbolTableTest, FindSymbol) 217{ 218 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 219 JSHandle<JSTaggedValue> symbolTableStringKey1(factory->NewFromASCII("key")); 220 JSHandle<JSTaggedValue> symbolTableStringKey2(factory->NewFromASCII("key1")); 221 222 int numberOfElements = 2; 223 JSHandle<JSSymbol> handleSymbol = factory->NewJSSymbol(); 224 JSHandle<SymbolTable> symbolTable = SymbolTable::Create(thread, numberOfElements); 225 226 JSTaggedValue resultValue1 = symbolTable->FindSymbol(handleSymbol.GetTaggedValue()); 227 EXPECT_EQ(JSTaggedValue::SameValue(resultValue1, JSTaggedValue::Undefined()), true); 228 229 handleSymbol->SetDescription(thread, symbolTableStringKey1.GetTaggedValue()); 230 JSTaggedValue resultValue2 = symbolTable->FindSymbol(handleSymbol.GetTaggedValue()); 231 EXPECT_EQ(JSTaggedValue::SameValue(resultValue2, JSTaggedValue::Undefined()), true); 232 233 symbolTable->SetKey(thread, 1, symbolTableStringKey1.GetTaggedValue()); 234 JSTaggedValue resultValue3 = symbolTable->FindSymbol(handleSymbol.GetTaggedValue()); 235 EXPECT_EQ(resultValue3.GetRawData() == symbolTableStringKey1.GetTaggedValue().GetRawData(), true); 236 237 symbolTable->SetKey(thread, 1, symbolTableStringKey2.GetTaggedValue()); 238 JSTaggedValue resultValue4 = symbolTable->FindSymbol(handleSymbol.GetTaggedValue()); 239 EXPECT_EQ(JSTaggedValue::SameValue(resultValue4, JSTaggedValue::Undefined()), true); 240} 241} // namespace panda::test 242