1 /*
2 * Copyright (c) 2022 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_string_table.h"
17 #include "ecmascript/tests/test_helper.h"
18
19 using namespace panda::ecmascript;
20
21 namespace panda::test {
22 class EcmaStringTableTest : public testing::Test {
23 public:
SetUpTestCase()24 static void SetUpTestCase()
25 {
26 GTEST_LOG_(INFO) << "SetUpTestCase";
27 }
28
TearDownTestCase()29 static void TearDownTestCase()
30 {
31 GTEST_LOG_(INFO) << "TearDownCase";
32 }
33
SetUp()34 void SetUp() override
35 {
36 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
37 }
38
TearDown()39 void TearDown() override
40 {
41 TestHelper::DestroyEcmaVMWithScope(instance, scope);
42 }
43
44 EcmaVM *instance {nullptr};
45 EcmaHandleScope *scope {nullptr};
46 JSThread *thread {nullptr};
47 };
48
49 /**
50 * @tc.name: InternEmptyString
51 * @tc.desc: Write empty string emptyStr to the Intern pool and takes the hash code as its index.
52 * @tc.type: FUNC
53 * @tc.require:
54 */
HWTEST_F_L0(EcmaStringTableTest,InternEmptyString)55 HWTEST_F_L0(EcmaStringTableTest, InternEmptyString)
56 {
57 EcmaStringTable *table = thread->GetEcmaVM()->GetEcmaStringTable();
58
59 JSHandle<EcmaString> emptyEcmaStrHandle(thread, EcmaStringAccessor::CreateEmptyString(thread->GetEcmaVM()));
60 EXPECT_TRUE(!EcmaStringAccessor(emptyEcmaStrHandle).IsInternString());
61
62 table->InternEmptyString(*emptyEcmaStrHandle);
63 EXPECT_TRUE(EcmaStringAccessor(emptyEcmaStrHandle).IsInternString());
64 }
65
66 /**
67 * @tc.name: GetOrInternString
68 * @tc.desc: Obtain EcmaString string from utf8 encoded data. If the string already exists in the detention pool,
69 it will be returned directly. If not, it will be added to the detention pool and then returned.
70 * @tc.type: FUNC
71 * @tc.require:
72 */
HWTEST_F_L0(EcmaStringTableTest,GetOrInternString_utf8Data)73 HWTEST_F_L0(EcmaStringTableTest, GetOrInternString_utf8Data)
74 {
75 EcmaVM *vm = thread->GetEcmaVM();
76 EcmaStringTable *table = thread->GetEcmaVM()->GetEcmaStringTable();
77
78 uint8_t utf8Data[] = {0x68, 0x65, 0x6c, 0x6c, 0x6f}; // " hello "
79 EcmaString *ecmaStrCreatePtr = EcmaStringAccessor::CreateFromUtf8(vm, utf8Data, sizeof(utf8Data), true);
80 EXPECT_TRUE(!EcmaStringAccessor(ecmaStrCreatePtr).IsInternString());
81
82 EcmaString *ecmaStrGetPtr = table->GetOrInternString(utf8Data, sizeof(utf8Data), true);
83 EXPECT_STREQ(EcmaStringAccessor(ecmaStrGetPtr).ToCString().c_str(), "hello");
84 EXPECT_TRUE(EcmaStringAccessor(ecmaStrGetPtr).IsInternString());
85 }
86
87 /**
88 * @tc.name: GetOrInternString
89 * @tc.desc: Obtain EcmaString string from utf16 encoded data. If the string already exists in the detention pool,
90 it will be returned directly. If not, it will be added to the detention pool and then returned.
91 * @tc.type: FUNC
92 * @tc.require:
93 */
HWTEST_F_L0(EcmaStringTableTest,GetOrInternString_utf16Data)94 HWTEST_F_L0(EcmaStringTableTest, GetOrInternString_utf16Data)
95 {
96 EcmaVM *vm = thread->GetEcmaVM();
97 EcmaStringTable *table = thread->GetEcmaVM()->GetEcmaStringTable();
98
99 uint16_t utf16Data[] = {0x7F16, 0x7801, 0x89E3, 0x7801}; // “ 编码解码 ”
100 EcmaString *ecmaStrCreatePtr =
101 EcmaStringAccessor::CreateFromUtf16(vm, utf16Data, sizeof(utf16Data) / sizeof(uint16_t), false);
102 EXPECT_TRUE(!EcmaStringAccessor(ecmaStrCreatePtr).IsInternString());
103
104 EcmaString *ecmaStrGetPtr = table->GetOrInternString(utf16Data, sizeof(utf16Data) / sizeof(uint16_t), false);
105 EXPECT_STREQ(EcmaStringAccessor(ecmaStrGetPtr).ToCString().c_str(), "编码解码");
106 EXPECT_TRUE(EcmaStringAccessor(ecmaStrGetPtr).IsInternString());
107 }
108
109 /**
110 * @tc.name: GetOrInternString
111 * @tc.desc: Obtain EcmaString string from another EcmaString. If the string already exists in the detention pool,
112 it will be returned directly. If not, it will be added to the detention pool and then returned.
113 * @tc.type: FUNC
114 * @tc.require:
115 */
HWTEST_F_L0(EcmaStringTableTest,GetOrInternString_EcmaString)116 HWTEST_F_L0(EcmaStringTableTest, GetOrInternString_EcmaString)
117 {
118 EcmaVM *vm = thread->GetEcmaVM();
119 ObjectFactory *factory = vm->GetFactory();
120 EcmaStringTable *table = thread->GetEcmaVM()->GetEcmaStringTable();
121
122 JSHandle<EcmaString> ecmaStrCreateHandle = factory->NewFromASCII("hello world");
123 EXPECT_TRUE(EcmaStringAccessor(ecmaStrCreateHandle).IsInternString());
124
125 EcmaString *ecmaStrGetPtr = table->GetOrInternString(*ecmaStrCreateHandle);
126 EXPECT_STREQ(EcmaStringAccessor(ecmaStrGetPtr).ToCString().c_str(), "hello world");
127 EXPECT_TRUE(EcmaStringAccessor(ecmaStrGetPtr).IsInternString());
128 }
129
130 /**
131 * @tc.name: GetOrInternString
132 * @tc.desc: Check the uniqueness of string and its hashcode in stringtable to ensure that no two strings have
133 same contents and same hashcode
134 * @tc.type: FUNC
135 * @tc.require:
136 */
HWTEST_F_L0(EcmaStringTableTest,GetOrInternString_CheckStringTable)137 HWTEST_F_L0(EcmaStringTableTest, GetOrInternString_CheckStringTable)
138 {
139 EXPECT_TRUE(thread->GetEcmaVM()->GetEcmaStringTable()->CheckStringTableValidity());
140 }
141 } // namespace panda::test
142