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