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