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/builtins/builtins_symbol.h"
17
18 #include "ecmascript/ecma_runtime_call_info.h"
19 #include "ecmascript/ecma_string.h"
20 #include "ecmascript/ecma_vm.h"
21 #include "ecmascript/global_env.h"
22 #include "ecmascript/js_function.h"
23 #include "ecmascript/js_handle.h"
24 #include "ecmascript/js_hclass.h"
25 #include "ecmascript/js_object-inl.h"
26 #include "ecmascript/js_primitive_ref.h"
27 #include "ecmascript/js_tagged_value-inl.h"
28 #include "ecmascript/js_thread.h"
29 #include "ecmascript/object_factory.h"
30 #include "ecmascript/symbol_table.h"
31 #include "ecmascript/tests/test_helper.h"
32
33 using namespace panda::ecmascript;
34 using namespace panda::ecmascript::builtins;
35
36 namespace panda::test {
37 using Symbol = ecmascript::builtins::BuiltinsSymbol;
38 using BuiltinsBase = panda::ecmascript::base::BuiltinsBase;
39
40 class BuiltinsSymbolTest : public testing::Test {
41 public:
SetUpTestCase()42 static void SetUpTestCase()
43 {
44 GTEST_LOG_(INFO) << "SetUpTestCase";
45 }
46
TearDownTestCase()47 static void TearDownTestCase()
48 {
49 GTEST_LOG_(INFO) << "TearDownCase";
50 }
51
SetUp()52 void SetUp() override
53 {
54 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
55 }
56
TearDown()57 void TearDown() override
58 {
59 TestHelper::DestroyEcmaVMWithScope(instance, scope);
60 }
61
62 EcmaVM *instance {nullptr};
63 EcmaHandleScope *scope {nullptr};
64 JSThread *thread {nullptr};
65 };
66
67 // new Symbol.toString()
HWTEST_F_L0(BuiltinsSymbolTest,SymbolNoParameterToString)68 HWTEST_F_L0(BuiltinsSymbolTest, SymbolNoParameterToString)
69 {
70 auto ecmaVM = thread->GetEcmaVM();
71
72 JSHandle<JSSymbol> symbol = ecmaVM->GetFactory()->NewJSSymbol();
73
74 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
75 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
76 ecmaRuntimeCallInfo->SetThis(symbol.GetTaggedValue());
77
78 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
79 JSTaggedValue result = Symbol::ToString(ecmaRuntimeCallInfo);
80 TestHelper::TearDownFrame(thread, prev);
81 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
82 ASSERT_TRUE(result.IsString());
83
84 auto symbolValue = ecmaVM->GetFactory()->NewFromASCII("Symbol()");
85 ASSERT_EQ(EcmaStringAccessor::Compare(*symbolValue, *resultHandle), 0);
86
87 // Undefined not Object
88 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
89 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
90 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
91
92 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
93 result = Symbol::ToString(ecmaRuntimeCallInfo);
94 TestHelper::TearDownFrame(thread, prev);
95 EXPECT_TRUE(thread->HasPendingException());
96 EXPECT_EQ(result, JSTaggedValue::Exception());
97 thread->ClearException();
98
99 // No Symbol data
100 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
101 JSHandle<TaggedArray> array(factory->NewTaggedArray(3));
102 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
103 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
104 ecmaRuntimeCallInfo->SetThis(array.GetTaggedValue());
105
106 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
107 result = Symbol::ToString(ecmaRuntimeCallInfo);
108 TestHelper::TearDownFrame(thread, prev);
109 EXPECT_TRUE(thread->HasPendingException());
110 EXPECT_EQ(result, JSTaggedValue::Exception());
111 thread->ClearException();
112 }
113
114 // new Symbol("aaa").toString()
HWTEST_F_L0(BuiltinsSymbolTest,SymbolWithParameterToString)115 HWTEST_F_L0(BuiltinsSymbolTest, SymbolWithParameterToString)
116 {
117 auto ecmaVM = thread->GetEcmaVM();
118
119 JSHandle<JSSymbol> symbol = ecmaVM->GetFactory()->NewPublicSymbolWithChar("aaa");
120
121 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
122 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
123 ecmaRuntimeCallInfo->SetThis(symbol.GetTaggedValue());
124
125 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
126 JSTaggedValue result = Symbol::ToString(ecmaRuntimeCallInfo);
127 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
128 ASSERT_TRUE(result.IsString());
129
130 auto symbolValue = ecmascript::base::BuiltinsBase::GetTaggedString(thread, "Symbol(aaa)");
131 ASSERT_EQ(EcmaStringAccessor::Compare(reinterpret_cast<EcmaString *>(symbolValue.GetRawData()), *resultHandle), 0);
132 }
133
134 // new Symbol().valueOf()
HWTEST_F_L0(BuiltinsSymbolTest,SymbolNoParameterValueOf)135 HWTEST_F_L0(BuiltinsSymbolTest, SymbolNoParameterValueOf)
136 {
137 auto ecmaVM = thread->GetEcmaVM();
138 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
139
140 JSHandle<JSSymbol> symbol = ecmaVM->GetFactory()->NewJSSymbol();
141
142 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
143 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
144 ecmaRuntimeCallInfo->SetThis(symbol.GetTaggedValue());
145
146 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
147 JSTaggedValue result = BuiltinsSymbol::ValueOf(ecmaRuntimeCallInfo);
148 TestHelper::TearDownFrame(thread, prev);
149 EXPECT_TRUE(result.IsSymbol());
150 ASSERT_EQ(result.GetRawData() == (JSTaggedValue(*symbol)).GetRawData(), true);
151
152 JSHandle<JSFunction> symbolObject(env->GetSymbolFunction());
153 JSHandle<JSTaggedValue> symbolValue(symbol);
154 JSHandle<JSPrimitiveRef> symbolRef = ecmaVM->GetFactory()->NewJSPrimitiveRef(symbolObject, symbolValue);
155
156 auto otherEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
157 otherEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
158 otherEcmaRuntimeCallInfo->SetThis(symbolRef.GetTaggedValue());
159
160 prev = TestHelper::SetupFrame(thread, otherEcmaRuntimeCallInfo);
161 JSTaggedValue otherResult = BuiltinsSymbol::ValueOf(otherEcmaRuntimeCallInfo);
162 TestHelper::TearDownFrame(thread, prev);
163 EXPECT_TRUE(otherResult.IsSymbol());
164 ASSERT_EQ(otherResult.GetRawData() == (JSTaggedValue(*symbol)).GetRawData(), true);
165
166 // Undefined not Object
167 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
168 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
169 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
170
171 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
172 result = Symbol::ValueOf(ecmaRuntimeCallInfo);
173 TestHelper::TearDownFrame(thread, prev);
174 EXPECT_TRUE(thread->HasPendingException());
175 EXPECT_EQ(result, JSTaggedValue::Exception());
176 thread->ClearException();
177
178 // No Symbol data
179 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
180 JSHandle<TaggedArray> array(factory->NewTaggedArray(3));
181 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
182 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
183 ecmaRuntimeCallInfo->SetThis(array.GetTaggedValue());
184
185 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
186 result = Symbol::ValueOf(ecmaRuntimeCallInfo);
187 TestHelper::TearDownFrame(thread, prev);
188 EXPECT_TRUE(thread->HasPendingException());
189 EXPECT_EQ(result, JSTaggedValue::Exception());
190 thread->ClearException();
191 }
192
193 // new Symbol("bbb").valueOf()
HWTEST_F_L0(BuiltinsSymbolTest,SymbolWithParameterValueOf)194 HWTEST_F_L0(BuiltinsSymbolTest, SymbolWithParameterValueOf)
195 {
196 auto ecmaVM = thread->GetEcmaVM();
197 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
198
199 JSHandle<JSSymbol> symbol = ecmaVM->GetFactory()->NewPublicSymbolWithChar("bbb");
200
201 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
202 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
203 ecmaRuntimeCallInfo->SetThis(symbol.GetTaggedValue());
204
205 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
206 JSTaggedValue result = BuiltinsSymbol::ValueOf(ecmaRuntimeCallInfo);
207 TestHelper::TearDownFrame(thread, prev);
208 EXPECT_TRUE(result.IsSymbol());
209 ASSERT_EQ(result.GetRawData() == (JSTaggedValue(*symbol)).GetRawData(), true);
210
211 JSHandle<JSFunction> symbolObject(env->GetSymbolFunction());
212 JSHandle<JSTaggedValue> symbolValue(symbol);
213 JSHandle<JSPrimitiveRef> symbolRef = ecmaVM->GetFactory()->NewJSPrimitiveRef(symbolObject, symbolValue);
214
215 auto otherEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
216 otherEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
217 otherEcmaRuntimeCallInfo->SetThis(symbolRef.GetTaggedValue());
218
219 prev = TestHelper::SetupFrame(thread, otherEcmaRuntimeCallInfo);
220 JSTaggedValue otherResult = BuiltinsSymbol::ValueOf(otherEcmaRuntimeCallInfo);
221 TestHelper::TearDownFrame(thread, prev);
222 EXPECT_TRUE(otherResult.IsSymbol());
223 ASSERT_EQ(otherResult.GetRawData() == (JSTaggedValue(*symbol)).GetRawData(), true);
224 }
225
226 // new Symbol().for
HWTEST_F_L0(BuiltinsSymbolTest,SymbolWithParameterFor)227 HWTEST_F_L0(BuiltinsSymbolTest, SymbolWithParameterFor)
228 {
229 auto ecmaVM = thread->GetEcmaVM();
230 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
231
232 JSHandle<SymbolTable> tableHandle(env->GetRegisterSymbols());
233
234 JSHandle<EcmaString> string = ecmaVM->GetFactory()->NewFromASCII("ccc");
235 ASSERT_EQ(EcmaStringAccessor(string).GetLength(), 3U);
236 JSHandle<JSTaggedValue> string_handle(string);
237 ASSERT_EQ(tableHandle->ContainsKey(string_handle.GetTaggedValue()), false);
238
239 JSHandle<JSSymbol> symbol = ecmaVM->GetFactory()->NewSymbolWithTableWithChar("ccc");
240
241 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
242 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
243 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
244 ecmaRuntimeCallInfo->SetCallArg(0, string.GetTaggedValue());
245
246 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
247 JSTaggedValue result = BuiltinsSymbol::For(ecmaRuntimeCallInfo);
248 TestHelper::TearDownFrame(thread, prev);
249 ASSERT_EQ(tableHandle->ContainsKey(string_handle.GetTaggedValue()), true);
250
251 JSTaggedValue target(*symbol);
252 ASSERT_EQ(result.GetRawData() == target.GetRawData(), true);
253 }
254
255 // Symbol.keyFor (sym)
HWTEST_F_L0(BuiltinsSymbolTest,SymbolKeyFor)256 HWTEST_F_L0(BuiltinsSymbolTest, SymbolKeyFor)
257 {
258 auto ecmaVM = thread->GetEcmaVM();
259 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
260
261 JSHandle<JSSymbol> symbol = ecmaVM->GetFactory()->NewPublicSymbolWithChar("bbb");
262
263 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
264 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
265 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
266 ecmaRuntimeCallInfo->SetCallArg(0, symbol.GetTaggedValue());
267
268 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
269 JSTaggedValue result = BuiltinsSymbol::KeyFor(ecmaRuntimeCallInfo);
270 TestHelper::TearDownFrame(thread, prev);
271 ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
272
273 JSHandle<EcmaString> string = ecmaVM->GetFactory()->NewFromASCII("ccc");
274 ASSERT_EQ(EcmaStringAccessor(string).GetLength(), 3U);
275
276 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
277 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
278 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
279 ecmaRuntimeCallInfo1->SetCallArg(0, string.GetTaggedValue());
280
281 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
282 BuiltinsSymbol::For(ecmaRuntimeCallInfo1);
283 TestHelper::TearDownFrame(thread, prev);
284
285 JSHandle<JSSymbol> otherSymbol = ecmaVM->GetFactory()->NewPublicSymbolWithChar("ccc");
286 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
287 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
288 ecmaRuntimeCallInfo2->SetThis(JSTaggedValue::Undefined());
289 ecmaRuntimeCallInfo2->SetCallArg(0, otherSymbol.GetTaggedValue());
290
291 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
292 JSTaggedValue otherResult = BuiltinsSymbol::KeyFor(ecmaRuntimeCallInfo2);
293 TestHelper::TearDownFrame(thread, prev);
294 ASSERT_TRUE(otherResult.IsString());
295 JSHandle<SymbolTable> tableHandle(env->GetRegisterSymbols());
296 JSTaggedValue stringValue(*string);
297 ASSERT_EQ(tableHandle->ContainsKey(stringValue), true);
298
299 // not symbol
300 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
301 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
302 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
303 ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue::Undefined());
304
305 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
306 result = Symbol::KeyFor(ecmaRuntimeCallInfo);
307 TestHelper::TearDownFrame(thread, prev);
308 EXPECT_TRUE(thread->HasPendingException());
309 EXPECT_EQ(result, JSTaggedValue::Exception());
310 thread->ClearException();
311 }
312
313 // Symbol.ToPrimitive()
HWTEST_F_L0(BuiltinsSymbolTest,SymbolToPrimitive)314 HWTEST_F_L0(BuiltinsSymbolTest, SymbolToPrimitive)
315 {
316 auto ecmaVM = thread->GetEcmaVM();
317 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
318
319 JSHandle<JSSymbol> symbol = ecmaVM->GetFactory()->NewJSSymbol();
320
321 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
322 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
323 ecmaRuntimeCallInfo->SetThis(symbol.GetTaggedValue());
324
325 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
326 JSTaggedValue result = BuiltinsSymbol::ToPrimitive(ecmaRuntimeCallInfo);
327 TestHelper::TearDownFrame(thread, prev);
328 EXPECT_TRUE(result.IsSymbol());
329 ASSERT_EQ(result.GetRawData() == (JSTaggedValue(*symbol)).GetRawData(), true);
330
331 JSHandle<JSFunction> symbolObject(env->GetSymbolFunction());
332 JSHandle<JSTaggedValue> symbolValue(symbol);
333 JSHandle<JSPrimitiveRef> symbolRef = ecmaVM->GetFactory()->NewJSPrimitiveRef(symbolObject, symbolValue);
334
335 auto otherEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
336 otherEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
337 otherEcmaRuntimeCallInfo->SetThis(symbolRef.GetTaggedValue());
338
339 prev = TestHelper::SetupFrame(thread, otherEcmaRuntimeCallInfo);
340 JSTaggedValue otherResult = BuiltinsSymbol::ToPrimitive(otherEcmaRuntimeCallInfo);
341 TestHelper::TearDownFrame(thread, prev);
342 EXPECT_TRUE(otherResult.IsSymbol());
343 ASSERT_EQ(otherResult.GetRawData() == (JSTaggedValue(*symbol)).GetRawData(), true);
344 }
345
346 // constructor
HWTEST_F_L0(BuiltinsSymbolTest,SymbolConstructor)347 HWTEST_F_L0(BuiltinsSymbolTest, SymbolConstructor)
348 {
349 auto ecmaVM = thread->GetEcmaVM();
350
351 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
352 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
353 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
354 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
355
356 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
357 JSTaggedValue result = BuiltinsSymbol::SymbolConstructor(ecmaRuntimeCallInfo);
358 TestHelper::TearDownFrame(thread, prev);
359 EXPECT_TRUE(result.IsSymbol());
360 JSSymbol *sym = reinterpret_cast<JSSymbol *>(result.GetRawData());
361 ASSERT_EQ(sym->GetDescription().IsUndefined(), true);
362
363 JSHandle<EcmaString> string = ecmaVM->GetFactory()->NewFromASCII("ddd");
364
365 auto otherEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
366 otherEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
367 otherEcmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
368 otherEcmaRuntimeCallInfo->SetCallArg(0, string.GetTaggedValue());
369
370 prev = TestHelper::SetupFrame(thread, otherEcmaRuntimeCallInfo);
371 JSTaggedValue result1 = BuiltinsSymbol::SymbolConstructor(otherEcmaRuntimeCallInfo);
372 TestHelper::TearDownFrame(thread, prev);
373 JSHandle<EcmaString> resultString = JSTaggedValue::ToString(
374 thread, JSHandle<JSTaggedValue>(thread, reinterpret_cast<JSSymbol *>(result1.GetRawData())->GetDescription()));
375 ASSERT_EQ(EcmaStringAccessor::Compare(*resultString, *string), 0);
376 }
377
HWTEST_F_L0(BuiltinsSymbolTest,SymbolGetter)378 HWTEST_F_L0(BuiltinsSymbolTest, SymbolGetter)
379 {
380 auto ecmaVM = thread->GetEcmaVM();
381 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
382
383 JSHandle<JSSymbol> symbol = ecmaVM->GetFactory()->NewPublicSymbolWithChar("");
384 JSHandle<EcmaString> string = ecmaVM->GetFactory()->NewFromASCII("");
385
386 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
387 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
388 ecmaRuntimeCallInfo->SetThis(symbol.GetTaggedValue());
389
390 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
391 JSTaggedValue result = BuiltinsSymbol::DescriptionGetter(ecmaRuntimeCallInfo);
392 TestHelper::TearDownFrame(thread, prev);
393 ASSERT_TRUE(result.IsString());
394 EcmaString *resString = reinterpret_cast<EcmaString *>(result.GetRawData());
395 ASSERT_EQ(EcmaStringAccessor(resString).GetLength(), 0U);
396 ASSERT_EQ(EcmaStringAccessor::StringsAreEqual(resString, *string), true);
397
398 // value is not symbol
399 JSHandle<JSFunction> symbolObject(env->GetSymbolFunction());
400 JSHandle<JSTaggedValue> symbolValue(symbol);
401 JSHandle<JSPrimitiveRef> symbolRef = ecmaVM->GetFactory()->NewJSPrimitiveRef(symbolObject, symbolValue);
402 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
403 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
404 ecmaRuntimeCallInfo->SetThis(symbolRef.GetTaggedValue());
405
406 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
407 result = BuiltinsSymbol::DescriptionGetter(ecmaRuntimeCallInfo);
408 TestHelper::TearDownFrame(thread, prev);
409 ASSERT_TRUE(result.IsString());
410 resString = reinterpret_cast<EcmaString *>(result.GetRawData());
411 ASSERT_EQ(EcmaStringAccessor(resString).GetLength(), 0U);
412 ASSERT_EQ(EcmaStringAccessor::StringsAreEqual(resString, *string), true);
413
414 // Undefined
415 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
416 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
417 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
418
419 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
420 result = BuiltinsSymbol::DescriptionGetter(ecmaRuntimeCallInfo);
421 TestHelper::TearDownFrame(thread, prev);
422 EXPECT_TRUE(thread->HasPendingException());
423 EXPECT_EQ(result, JSTaggedValue::Exception());
424 thread->ClearException();
425 }
426 } // namespace panda::test
427