• 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/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