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_json.h"
17
18 #include <algorithm>
19 #include <iomanip>
20 #include <sstream>
21
22 #include "ecmascript/base/builtins_base.h"
23 #include "ecmascript/builtins/builtins_bigint.h"
24 #include "ecmascript/builtins/builtins_errors.h"
25 #include "ecmascript/builtins/builtins_proxy.h"
26 #include "ecmascript/builtins/builtins_typedarray.h"
27 #include "ecmascript/ecma_runtime_call_info.h"
28 #include "ecmascript/ecma_string-inl.h"
29 #include "ecmascript/ecma_vm.h"
30 #include "ecmascript/global_env.h"
31 #include "ecmascript/js_array.h"
32 #include "ecmascript/js_function.h"
33 #include "ecmascript/js_handle.h"
34 #include "ecmascript/js_object-inl.h"
35 #include "ecmascript/js_primitive_ref.h"
36 #include "ecmascript/js_tagged_value-inl.h"
37 #include "ecmascript/js_tagged_value.h"
38 #include "ecmascript/js_thread.h"
39 #include "ecmascript/object_factory.h"
40 #include "ecmascript/tests/test_helper.h"
41
42 using namespace panda::ecmascript;
43 using namespace panda::ecmascript::builtins;
44
45 namespace panda::test {
46 class BuiltinsJsonTest : public testing::Test {
47 public:
SetUpTestCase()48 static void SetUpTestCase()
49 {
50 GTEST_LOG_(INFO) << "SetUpTestCase";
51 }
52
TearDownTestCase()53 static void TearDownTestCase()
54 {
55 GTEST_LOG_(INFO) << "TearDownCase";
56 }
57
SetUp()58 void SetUp() override
59 {
60 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
61 }
62
TearDown()63 void TearDown() override
64 {
65 TestHelper::DestroyEcmaVMWithScope(instance, scope);
66 }
67
68 EcmaVM *instance {nullptr};
69 EcmaHandleScope *scope {nullptr};
70 JSThread *thread {nullptr};
71
72 class TestClass : public base::BuiltinsBase {
73 public:
TestForParse(EcmaRuntimeCallInfo * argv)74 static JSTaggedValue TestForParse(EcmaRuntimeCallInfo *argv)
75 {
76 uint32_t argc = argv->GetArgsNumber();
77 if (argc > 0) {
78 }
79 JSTaggedValue key = GetCallArg(argv, 0).GetTaggedValue();
80 if (key.IsUndefined()) {
81 return JSTaggedValue::Undefined();
82 }
83 JSTaggedValue value = GetCallArg(argv, 1).GetTaggedValue();
84 if (value.IsUndefined()) {
85 return JSTaggedValue::Undefined();
86 }
87
88 return JSTaggedValue(value);
89 }
90
TestForParse1(EcmaRuntimeCallInfo * argv)91 static JSTaggedValue TestForParse1(EcmaRuntimeCallInfo *argv)
92 {
93 uint32_t argc = argv->GetArgsNumber();
94 if (argc > 0) {
95 }
96 return JSTaggedValue::Undefined();
97 }
98
TestForStringfy(EcmaRuntimeCallInfo * argv)99 static JSTaggedValue TestForStringfy(EcmaRuntimeCallInfo *argv)
100 {
101 uint32_t argc = argv->GetArgsNumber();
102 if (argc > 0) {
103 JSTaggedValue key = GetCallArg(argv, 0).GetTaggedValue();
104 if (key.IsUndefined()) {
105 return JSTaggedValue::Undefined();
106 }
107 JSTaggedValue value = GetCallArg(argv, 1).GetTaggedValue();
108 if (value.IsUndefined()) {
109 return JSTaggedValue::Undefined();
110 }
111 return JSTaggedValue(value);
112 }
113
114 return JSTaggedValue::Undefined();
115 }
116 };
117 };
118
CreateBuiltinJSObject1(JSThread * thread,const CString keyCStr)119 JSTaggedValue CreateBuiltinJSObject1(JSThread *thread, const CString keyCStr)
120 {
121 EcmaVM *ecmaVM = thread->GetEcmaVM();
122 JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
123 ObjectFactory *factory = ecmaVM->GetFactory();
124 JSHandle<JSTaggedValue> objectFunc(globalEnv->GetObjectFunction());
125
126 JSHandle<JSObject> jsobject(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objectFunc), objectFunc));
127 EXPECT_TRUE(*jsobject != nullptr);
128
129 JSHandle<JSTaggedValue> key(factory->NewFromASCII(&keyCStr[0]));
130 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
131 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(jsobject), key, value);
132
133 CString str2 = "y";
134 JSHandle<JSTaggedValue> key2(factory->NewFromASCII(str2));
135 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2.5)); // 2.5 : test case
136 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(jsobject), key2, value2);
137
138 CString str3 = "z";
139 JSHandle<JSTaggedValue> key3(factory->NewFromASCII(str3));
140 JSHandle<JSTaggedValue> value3(factory->NewFromASCII("abc"));
141 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(jsobject), key3, value3);
142
143 return jsobject.GetTaggedValue();
144 }
145 // Math.abs(-10)
146
HWTEST_F_L0(BuiltinsJsonTest,Parse10)147 HWTEST_F_L0(BuiltinsJsonTest, Parse10)
148 {
149 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
150
151 JSHandle<JSTaggedValue> msg(factory->NewFromASCII(
152 "\t\r \n{\t\r \n \"property\"\t\r \n:\t\r \n{\t\r \n}\t\r \n,\t\r \n \"prop2\"\t\r \n:\t\r \n [\t\r \ntrue\t\r "
153 "\n,\t\r \nnull\t\r \n,123.456\t\r \n] \t\r \n}\t\r \n"));
154 JSHandle<EcmaString> str(JSTaggedValue::ToString(thread, msg));
155
156 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
157 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
158 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
159 ecmaRuntimeCallInfo->SetCallArg(0, str.GetTaggedValue());
160
161 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
162 JSTaggedValue result = BuiltinsJson::Parse(ecmaRuntimeCallInfo);
163 ASSERT_TRUE(result.IsECMAObject());
164 }
165
HWTEST_F_L0(BuiltinsJsonTest,Parse21)166 HWTEST_F_L0(BuiltinsJsonTest, Parse21)
167 {
168 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
169 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
170
171 JSHandle<JSTaggedValue> msg(factory->NewFromASCII("[100,2.5,\"abc\"]"));
172
173 JSHandle<JSFunction> handleFunc = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForParse));
174 JSHandle<EcmaString> str(JSTaggedValue::ToString(thread, msg));
175
176 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
177 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
178 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
179 ecmaRuntimeCallInfo->SetCallArg(0, str.GetTaggedValue());
180 ecmaRuntimeCallInfo->SetCallArg(1, handleFunc.GetTaggedValue());
181
182 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
183 JSTaggedValue result = BuiltinsJson::Parse(ecmaRuntimeCallInfo);
184 ASSERT_TRUE(result.IsECMAObject());
185 }
186
HWTEST_F_L0(BuiltinsJsonTest,Parse)187 HWTEST_F_L0(BuiltinsJsonTest, Parse)
188 {
189 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
190 JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
191
192 JSHandle<JSTaggedValue> msg(factory->NewFromASCII("[100,2.5,\"abc\"]"));
193 JSHandle<EcmaString> str(JSTaggedValue::ToString(thread, msg));
194
195 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
196 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
197 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
198 ecmaRuntimeCallInfo->SetCallArg(0, str.GetTaggedValue());
199
200 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
201 JSTaggedValue result = BuiltinsJson::Parse(ecmaRuntimeCallInfo);
202 JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
203 ASSERT_TRUE(value.IsECMAObject());
204 JSHandle<JSObject> valueHandle(thread, value);
205 JSHandle<JSTaggedValue> lenResult =
206 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle), lengthKeyHandle).GetValue();
207 uint32_t length = JSTaggedValue::ToLength(thread, lenResult).ToUint32();
208 EXPECT_EQ(length, 3U);
209 }
210
HWTEST_F_L0(BuiltinsJsonTest,Parse2)211 HWTEST_F_L0(BuiltinsJsonTest, Parse2)
212 {
213 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
214 JSHandle<JSTaggedValue> msg(factory->NewFromASCII("{\"epf\":100,\"key1\":200}"));
215 JSHandle<EcmaString> str(JSTaggedValue::ToString(thread, msg));
216
217 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
218 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
219 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
220 ecmaRuntimeCallInfo->SetCallArg(0, str.GetTaggedValue());
221
222 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
223 JSTaggedValue result = BuiltinsJson::Parse(ecmaRuntimeCallInfo);
224 JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
225 ASSERT_TRUE(value.IsECMAObject());
226 JSHandle<JSObject> valueHandle(thread, value);
227
228 JSHandle<TaggedArray> nameList(JSObject::EnumerableOwnNames(thread, valueHandle));
229 JSHandle<JSArray> nameResult = JSArray::CreateArrayFromList(thread, nameList);
230
231 JSHandle<JSTaggedValue> handleKey(nameResult);
232 JSHandle<JSTaggedValue> lengthKey(factory->NewFromASCII("length"));
233 JSHandle<JSTaggedValue> lenResult = JSObject::GetProperty(thread, handleKey, lengthKey).GetValue();
234 uint32_t length = JSTaggedValue::ToLength(thread, lenResult).ToUint32();
235 ASSERT_EQ(length, 2U);
236 }
237
HWTEST_F_L0(BuiltinsJsonTest,Parse3)238 HWTEST_F_L0(BuiltinsJsonTest, Parse3)
239 {
240 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
241 JSHandle<EcmaString> str = factory->NewFromStdString("\"\\u0000\"");
242
243 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
244 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
245 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
246 ecmaRuntimeCallInfo->SetCallArg(0, str.GetTaggedValue());
247
248 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
249 JSTaggedValue result = BuiltinsJson::Parse(ecmaRuntimeCallInfo);
250 uint32_t length = EcmaStringAccessor(result).GetLength();
251 ASSERT_EQ(length, 1U);
252 }
253
HWTEST_F_L0(BuiltinsJsonTest,Parse4)254 HWTEST_F_L0(BuiltinsJsonTest, Parse4)
255 {
256 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
257 JSHandle<EcmaString> str = factory->NewFromStdString("{\n\t\"on\":\t0\n}");
258 JSHandle<EcmaString> key = factory->NewFromStdString("on");
259
260 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
261 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
262 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
263 ecmaRuntimeCallInfo->SetCallArg(0, str.GetTaggedValue());
264
265 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
266 JSTaggedValue result = BuiltinsJson::Parse(ecmaRuntimeCallInfo);
267 JSHandle<JSTaggedValue> value =
268 JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>(thread, result), JSHandle<JSTaggedValue>(key))
269 .GetValue();
270 int32_t number = JSTaggedValue::ToInt32(thread, value);
271 ASSERT_EQ(number, 0);
272 }
273
274
HWTEST_F_L0(BuiltinsJsonTest,Stringify11)275 HWTEST_F_L0(BuiltinsJsonTest, Stringify11)
276 {
277 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
278 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
279 JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(thread, CreateBuiltinJSObject1(thread, "x"));
280 JSHandle<JSFunction> handleFunc =
281 factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForStringfy));
282
283 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
284 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
285 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
286 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
287 ecmaRuntimeCallInfo->SetCallArg(1, handleFunc.GetTaggedValue());
288
289 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
290 JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo);
291 ASSERT_TRUE(result.IsString());
292 }
293
HWTEST_F_L0(BuiltinsJsonTest,Stringify12)294 HWTEST_F_L0(BuiltinsJsonTest, Stringify12)
295 {
296 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
297 JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(thread, CreateBuiltinJSObject1(thread, "x"));
298 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
299 JSHandle<JSFunction> handleFunc =
300 factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForStringfy));
301
302 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
303 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
304 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
305 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
306 ecmaRuntimeCallInfo->SetCallArg(1, handleFunc.GetTaggedValue());
307 ecmaRuntimeCallInfo->SetCallArg(2, JSTaggedValue(static_cast<int32_t>(10)));
308
309 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
310 JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo);
311 ASSERT_TRUE(result.IsString());
312 }
313
HWTEST_F_L0(BuiltinsJsonTest,Stringify13)314 HWTEST_F_L0(BuiltinsJsonTest, Stringify13)
315 {
316 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
317 JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(thread, CreateBuiltinJSObject1(thread, "x"));
318 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
319 JSHandle<JSFunction> handleFunc =
320 factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForStringfy));
321 JSHandle<JSTaggedValue> msg(factory->NewFromASCII("tttt"));
322 JSHandle<EcmaString> str(JSTaggedValue::ToString(thread, msg));
323
324 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
325 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
326 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
327 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
328 ecmaRuntimeCallInfo->SetCallArg(1, handleFunc.GetTaggedValue());
329 ecmaRuntimeCallInfo->SetCallArg(2, str.GetTaggedValue());
330
331 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
332 JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo);
333 ASSERT_TRUE(result.IsString());
334 }
335
HWTEST_F_L0(BuiltinsJsonTest,Stringify14)336 HWTEST_F_L0(BuiltinsJsonTest, Stringify14)
337 {
338 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
339 JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(thread, CreateBuiltinJSObject1(thread, "x"));
340 JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
341
342 JSHandle<JSObject> obj1(thread, arr);
343 JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
344 JSHandle<JSTaggedValue> value0(factory->NewFromASCII("x"));
345 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key0, value0);
346 JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
347 JSHandle<JSTaggedValue> value1(factory->NewFromASCII("z"));
348 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key1, value1);
349
350 JSHandle<JSTaggedValue> msg(factory->NewFromASCII("tttt"));
351 JSHandle<EcmaString> str(JSTaggedValue::ToString(thread, msg));
352
353 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
354 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
355 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
356 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
357 ecmaRuntimeCallInfo->SetCallArg(1, obj1.GetTaggedValue());
358 ecmaRuntimeCallInfo->SetCallArg(2, str.GetTaggedValue());
359
360 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
361 JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo);
362 ASSERT_TRUE(result.IsString());
363 }
364
HWTEST_F_L0(BuiltinsJsonTest,Stringify)365 HWTEST_F_L0(BuiltinsJsonTest, Stringify)
366 {
367 JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(thread, CreateBuiltinJSObject1(thread, "x"));
368 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
369 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
370 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
371 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
372
373 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
374 JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo);
375 ASSERT_TRUE(result.IsString());
376 }
377
HWTEST_F_L0(BuiltinsJsonTest,Stringify1)378 HWTEST_F_L0(BuiltinsJsonTest, Stringify1)
379 {
380 auto ecmaVM = thread->GetEcmaVM();
381 ObjectFactory *factory = ecmaVM->GetFactory();
382 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
383
384 JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
385
386 EXPECT_TRUE(arr != nullptr);
387 JSHandle<JSObject> obj(thread, arr);
388 JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
389
390 JSHandle<JSTaggedValue> value(factory->NewFromASCII("def"));
391 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key0, value);
392
393 JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
394 PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(200)), true, true, true);
395 JSArray::DefineOwnProperty(thread, obj, key1, desc1);
396
397 JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
398 JSHandle<JSTaggedValue> value2(factory->NewFromASCII("abc"));
399 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2, value2);
400
401 JSHandle<JSFunction> handleFunc =
402 factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForStringfy));
403 JSHandle<JSTaggedValue> msg(factory->NewFromASCII("tttt"));
404 JSHandle<EcmaString> str(JSTaggedValue::ToString(thread, msg));
405
406 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
407 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
408 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
409 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
410 ecmaRuntimeCallInfo->SetCallArg(1, handleFunc.GetTaggedValue());
411 ecmaRuntimeCallInfo->SetCallArg(2, str.GetTaggedValue());
412
413 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
414 JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo);
415 ASSERT_TRUE(result.IsString());
416 }
417
HWTEST_F_L0(BuiltinsJsonTest,Stringify2)418 HWTEST_F_L0(BuiltinsJsonTest, Stringify2)
419 {
420 auto ecmaVM = thread->GetEcmaVM();
421 ObjectFactory *factory = ecmaVM->GetFactory();
422
423 JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
424 EXPECT_TRUE(arr != nullptr);
425 JSHandle<JSObject> obj(thread, arr);
426
427 JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
428 PropertyDescriptor desc0(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), true, true, true);
429 JSArray::DefineOwnProperty(thread, obj, key0, desc0);
430 JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
431 // 2.5 : test case
432 PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(2.5)), true, true, true);
433 JSArray::DefineOwnProperty(thread, obj, key1, desc1);
434 // 2 : test case
435 JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
436 JSHandle<JSTaggedValue> value2(factory->NewFromASCII("abc"));
437 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2, value2);
438
439 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
440 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
441 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
442 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
443
444 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
445 JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo);
446 ASSERT_TRUE(result.IsString());
447 }
448
HWTEST_F_L0(BuiltinsJsonTest,Stringify3)449 HWTEST_F_L0(BuiltinsJsonTest, Stringify3)
450 {
451 auto ecmaVM = thread->GetEcmaVM();
452 ObjectFactory *factory = ecmaVM->GetFactory();
453
454 uint16_t data[1];
455 data[0] = 0;
456 JSHandle<EcmaString> str = factory->NewFromUtf16(data, 1);
457 JSHandle<EcmaString> test = factory->NewFromStdString("\"\\u0000\"");
458
459 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
460 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
461 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
462 ecmaRuntimeCallInfo->SetCallArg(0, str.GetTaggedValue());
463
464 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
465 JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo);
466 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*test, EcmaString::Cast(result.GetTaggedObject())));
467 }
468
CreateJSObject(JSThread * thread)469 JSHandle<JSTaggedValue> CreateJSObject(JSThread *thread)
470 {
471 EcmaVM *ecmaVM = thread->GetEcmaVM();
472 JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
473 JSHandle<JSTaggedValue> objFun = globalEnv->GetObjectFunction();
474 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
475
476 JSHandle<JSTaggedValue> obj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
477 JSHandle<JSTaggedValue> key(factory->NewFromStdString("x"));
478 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
479 JSObject::SetProperty(thread, obj, key, value);
480 return obj;
481 }
482
CreateProxy(JSThread * thread)483 JSHandle<JSTaggedValue> CreateProxy(JSThread *thread)
484 {
485 JSHandle<JSTaggedValue> target = CreateJSObject(thread);
486 JSHandle<JSTaggedValue> handler = CreateJSObject(thread);
487
488 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Null(), 8);
489 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
490 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
491 ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
492 ecmaRuntimeCallInfo->SetCallArg(1, handler.GetTaggedValue());
493
494 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
495 JSTaggedValue result = BuiltinsProxy::ProxyConstructor(ecmaRuntimeCallInfo);
496 TestHelper::TearDownFrame(thread, prev);
497 return JSHandle<JSTaggedValue>(thread, result);
498 }
499
HWTEST_F_L0(BuiltinsJsonTest,Stringify4)500 HWTEST_F_L0(BuiltinsJsonTest, Stringify4) // Test for proxy object
501 {
502 auto ecmaVM = thread->GetEcmaVM();
503 ObjectFactory *factory = ecmaVM->GetFactory();
504
505 JSHandle<JSTaggedValue> proxy = CreateProxy(thread);
506 JSHandle<EcmaString> test = factory->NewFromStdString("{\"x\":1}");
507
508 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
509 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
510 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
511 ecmaRuntimeCallInfo->SetCallArg(0, proxy.GetTaggedValue());
512
513 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
514 JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo);
515 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*test, EcmaString::Cast(result.GetTaggedObject())));
516 TestHelper::TearDownFrame(thread, prev);
517 }
518
HWTEST_F_L0(BuiltinsJsonTest,Stringify5)519 HWTEST_F_L0(BuiltinsJsonTest, Stringify5) // Test for typedarray object
520 {
521 auto ecmaVM = thread->GetEcmaVM();
522 ObjectFactory *factory = ecmaVM->GetFactory();
523 [[maybe_unused]] JSHandle<TaggedArray> array(factory->NewTaggedArray(3));
524 array->Set(thread, 0, JSTaggedValue(2));
525 array->Set(thread, 1, JSTaggedValue(3));
526 array->Set(thread, 2, JSTaggedValue(4));
527
528 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
529 JSHandle<JSTaggedValue> jsArray(JSArray::CreateArrayFromList(thread, array));
530 JSHandle<JSFunction> int8Func(env->GetInt8ArrayFunction());
531 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
532 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
533 ecmaRuntimeCallInfo1->SetNewTarget(JSTaggedValue(*int8Func));
534 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue(*globalObject));
535 ecmaRuntimeCallInfo1->SetCallArg(0, jsArray.GetTaggedValue());
536
537 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
538 JSHandle<JSTaggedValue> int8Array(thread, BuiltinsTypedArray::Int8ArrayConstructor(ecmaRuntimeCallInfo1));
539 TestHelper::TearDownFrame(thread, prev);
540
541 JSHandle<EcmaString> test = factory->NewFromStdString("{\"0\":2,\"1\":3,\"2\":4}");
542
543 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
544 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
545 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
546 ecmaRuntimeCallInfo->SetCallArg(0, int8Array.GetTaggedValue());
547
548 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
549 JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo);
550 TestHelper::TearDownFrame(thread, prev);
551 ASSERT_TRUE(result.IsString());
552 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*test, EcmaString::Cast(result.GetTaggedObject())));
553 }
554
HWTEST_F_L0(BuiltinsJsonTest,Stringify6)555 HWTEST_F_L0(BuiltinsJsonTest, Stringify6) // Test for bigint object
556 {
557 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
558 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("123456789123456789"));
559
560 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
561 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
562 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
563 ecmaRuntimeCallInfo1->SetCallArg(0, numericValue.GetTaggedValue());
564
565 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
566 JSTaggedValue result1 = BuiltinsBigInt::BigIntConstructor(ecmaRuntimeCallInfo1);
567 TestHelper::TearDownFrame(thread, prev);
568
569 JSHandle<JSTaggedValue> bigIntHandle(thread, result1);
570
571 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
572 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
573 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
574 ecmaRuntimeCallInfo->SetCallArg(0, bigIntHandle.GetTaggedValue());
575
576 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
577 [[maybe_unused]] JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo);
578 bool hasPendingException = false;
579 if (thread->HasPendingException()) {
580 hasPendingException = true;
581 thread->ClearException();
582 }
583 ASSERT_TRUE(hasPendingException);
584 }
585
HWTEST_F_L0(BuiltinsJsonTest,StringifyAndParse)586 HWTEST_F_L0(BuiltinsJsonTest, StringifyAndParse)
587 {
588 auto ecmaVM = thread->GetEcmaVM();
589 ObjectFactory *factory = ecmaVM->GetFactory();
590 JSHandle<JSTaggedValue> obj = CreateJSObject(thread);
591 JSHandle<JSTaggedValue> ykey(factory->NewFromASCII("y"));
592 JSHandle<JSTaggedValue> yvalue(thread, JSTaggedValue(2.2)); // 2.2: use to test double value
593 JSObject::SetProperty(thread, obj, ykey, yvalue);
594
595 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
596 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
597 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
598 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
599 JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Hole());
600 {
601 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
602 result.Update(BuiltinsJson::Stringify(ecmaRuntimeCallInfo));
603 TestHelper::TearDownFrame(thread, prev);
604 }
605 {
606 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
607 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
608 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
609 ecmaRuntimeCallInfo->SetCallArg(0, result.GetTaggedValue());
610 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
611 result.Update(BuiltinsJson::Parse(ecmaRuntimeCallInfo));
612 TestHelper::TearDownFrame(thread, prev);
613 }
614 ASSERT_TRUE(result->IsECMAObject());
615
616 JSHandle<JSObject> resultObj(result);
617 JSHandle<JSTaggedValue> key(factory->NewFromASCII("x"));
618 JSHandle<JSTaggedValue> res = JSObject::GetProperty(thread, resultObj, key).GetValue();
619 ASSERT_TRUE(res->IsInt());
620 ASSERT_EQ(res->GetInt(), 1);
621
622 res = JSObject::GetProperty(thread, resultObj, ykey).GetValue();
623 ASSERT_TRUE(res->IsDouble());
624 ASSERT_EQ(res->GetDouble(), 2.2); // 2.2:use to test double value
625 }
626 } // namespace panda::test
627