• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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/base/json_helper.h"
17 #include "ecmascript/base/json_stringifier.h"
18 #include "ecmascript/js_api/js_api_hashmap.h"
19 #include "ecmascript/js_api/js_api_hashset.h"
20 #include "ecmascript/js_array.h"
21 #include "ecmascript/js_map.h"
22 #include "ecmascript/js_set.h"
23 #include "ecmascript/linked_hash_table.h"
24 #include "ecmascript/object_factory.h"
25 #include "ecmascript/tests/test_helper.h"
26 #include "ecmascript/shared_objects/js_shared_map.h"
27 #include "ecmascript/shared_objects/js_shared_set.h"
28 #include "ecmascript/tests/ecma_test_common.h"
29 
30 using namespace panda::ecmascript;
31 using namespace panda::ecmascript::base;
32 
33 namespace panda::test {
34 class JsonStringifierTest : public BaseTestWithScope<false> {
35 public:
36     using TransformType = base::JsonHelper::TransformType;
37 };
38 
CreateBaseJSObject(JSThread * thread,const CString keyCStr)39 static JSTaggedValue CreateBaseJSObject(JSThread *thread, const CString keyCStr)
40 {
41     EcmaVM *ecmaVM = thread->GetEcmaVM();
42     JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
43     ObjectFactory *factory = ecmaVM->GetFactory();
44     JSHandle<JSTaggedValue> objectFunc(globalEnv->GetObjectFunction());
45 
46     JSHandle<JSObject> jsObject(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objectFunc), objectFunc));
47     EXPECT_TRUE(*jsObject != nullptr);
48 
49     JSHandle<JSTaggedValue> handleKey1(factory->NewFromASCII(&keyCStr[0]));
50     JSHandle<JSTaggedValue> handleValue1(thread, JSTaggedValue(1)); // 1 : test case
51     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(jsObject), handleKey1, handleValue1);
52 
53     CString str2 = "x";
54     JSHandle<JSTaggedValue> handleKey2(factory->NewFromASCII(str2));
55     JSHandle<JSTaggedValue> handleValue2(thread, JSTaggedValue(3.6)); // 3.6 : test case
56     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(jsObject), handleKey2, handleValue2);
57 
58     CString str3 = "y";
59     JSHandle<JSTaggedValue> handleKey3(factory->NewFromASCII(str3));
60     JSHandle<JSTaggedValue> handleValue3(factory->NewFromASCII("abc"));
61     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(jsObject), handleKey3, handleValue3);
62 
63     return jsObject.GetTaggedValue();
64 }
65 
CreateSharedMap(JSThread * thread)66 static JSHandle<JSSharedMap> CreateSharedMap(JSThread *thread)
67 {
68     auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
69     JSHandle<JSTaggedValue> proto = globalEnv->GetSharedMapPrototype();
70     auto emptySLayout = thread->GlobalConstants()->GetHandledEmptySLayoutInfo();
71     auto vm = thread->GetEcmaVM();
72     ObjectFactory *factory = vm->GetFactory();
73     JSHandle<JSHClass> mapClass = factory->NewSEcmaHClass(JSSharedMap::SIZE, 0,
74                                                           JSType::JS_SHARED_MAP, proto,
75                                                           emptySLayout);
76     JSHandle<JSObject> obj = factory->NewSharedOldSpaceJSObjectWithInit(mapClass);
77     JSHandle<JSSharedMap> jsMap = JSHandle<JSSharedMap>::Cast(obj);
78     JSHandle<LinkedHashMap> linkedMap(
79         LinkedHashMap::Create(thread, LinkedHashMap::MIN_CAPACITY, MemSpaceKind::SHARED));
80     jsMap->SetLinkedMap(thread, linkedMap);
81     jsMap->SetModRecord(0);
82     return jsMap;
83 }
84 
CreateJSSharedSet(JSThread * thread)85 static JSHandle<JSSharedSet> CreateJSSharedSet(JSThread *thread)
86 {
87     auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
88     auto vm = thread->GetEcmaVM();
89     ObjectFactory *factory = vm->GetFactory();
90     JSHandle<JSTaggedValue> proto = globalEnv->GetSFunctionPrototype();
91     auto emptySLayout = thread->GlobalConstants()->GetHandledEmptySLayoutInfo();
92     JSHandle<JSHClass> setClass = factory->NewSEcmaHClass(JSSharedSet::SIZE, 0,
93         JSType::JS_SHARED_SET, proto, emptySLayout);
94     JSHandle<JSSharedSet> jsSet = JSHandle<JSSharedSet>::Cast(factory->NewSharedOldSpaceJSObjectWithInit(setClass));
95     JSHandle<LinkedHashSet> linkedSet(
96         LinkedHashSet::Create(thread, LinkedHashSet::MIN_CAPACITY, MemSpaceKind::SHARED));
97     jsSet->SetLinkedSet(thread, linkedSet);
98     jsSet->SetModRecord(0);
99     return jsSet;
100 }
101 
CreateJSMap(JSThread * thread)102 static JSHandle<JSMap> CreateJSMap(JSThread *thread)
103 {
104     auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
105     auto vm = thread->GetEcmaVM();
106     ObjectFactory *factory = vm->GetFactory();
107     JSHandle<JSTaggedValue> constructor = globalEnv->GetBuiltinsMapFunction();
108     JSHandle<JSMap> map =
109         JSHandle<JSMap>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
110     JSHandle<LinkedHashMap> linkedMap = LinkedHashMap::Create(thread);
111     map->SetLinkedMap(thread, linkedMap);
112     return JSHandle<JSMap>(thread, *map);
113 }
114 
CreateJSSet(JSThread * thread)115 static JSHandle<JSSet> CreateJSSet(JSThread *thread)
116 {
117     auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
118     JSHandle<JSTaggedValue> proto = globalEnv->GetFunctionPrototype();
119     auto vm = thread->GetEcmaVM();
120     ObjectFactory *factory = vm->GetFactory();
121     JSHandle<JSHClass> hclass = factory->NewEcmaHClass(JSSet::SIZE, JSType::JS_SET, proto);
122     JSHandle<JSObject> jsSetObject =  factory->NewJSObjectWithInit(hclass);
123     JSHandle<JSSet> jsSet = JSHandle<JSSet>::Cast(jsSetObject);
124     JSHandle<LinkedHashSet> linkedSet(LinkedHashSet::Create(thread));
125     jsSet->SetLinkedSet(thread, linkedSet);
126     return jsSet;
127 }
128 
CreateHashMap(JSThread * thread)129 static JSAPIHashMap *CreateHashMap(JSThread *thread)
130 {
131     return EcmaContainerCommon::CreateHashMap(thread);
132 }
133 
CreateHashSet(JSThread * thread)134 static JSAPIHashSet *CreateHashSet(JSThread *thread)
135 {
136     return EcmaContainerCommon::CreateHashSet(thread);
137 }
138 
TestForStringfy1(EcmaRuntimeCallInfo * argv)139 static JSTaggedValue TestForStringfy1([[maybe_unused]] EcmaRuntimeCallInfo *argv)
140 {
141     // false: test case
142     return JSTaggedValue(JSTaggedValue::False());
143 }
144 
TestForStringfy2(EcmaRuntimeCallInfo * argv)145 static JSTaggedValue TestForStringfy2([[maybe_unused]] EcmaRuntimeCallInfo *argv)
146 {
147     // 10.12: test case
148     return JSTaggedValue(10.12);
149 }
150 
151 /**
152  * @tc.name: Stringify_001
153  * @tc.desc: Check whether the result returned through "Stringify" function is within expectations
154  *           the first parameter of the ECMAObject,the second parameter is JSFunction,the third parameter
155  *           is Undefined.if the second parameter is JSFunction,the return value is the parameter stringification
156  *           after through "call" function.
157  * @tc.type: FUNC
158  * @tc.require:
159  */
HWTEST_F_L0(JsonStringifierTest,Stringify_001)160 HWTEST_F_L0(JsonStringifierTest, Stringify_001)
161 {
162     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
163     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
164 
165     JSHandle<JSTaggedValue> handleObj = JSHandle<JSTaggedValue>(thread, CreateBaseJSObject(thread, "z"));
166     JSHandle<JSFunction> handleFunc1 = factory->NewJSFunction(env, reinterpret_cast<void *>(TestForStringfy1));
167     JSHandle<JSFunction> handleFunc2 = factory->NewJSFunction(env, reinterpret_cast<void *>(TestForStringfy2));
168     JSHandle<JSTaggedValue> handleValue(thread, handleObj.GetTaggedValue());
169     JSHandle<JSTaggedValue> handleReplacer1(thread, handleFunc1.GetTaggedValue());
170     JSHandle<JSTaggedValue> handleReplacer2(thread, handleFunc2.GetTaggedValue());
171     JSHandle<JSTaggedValue> handleGap(thread, JSTaggedValue::Undefined());
172 
173     JsonStringifier stringifier1(thread);
174     JSHandle<JSTaggedValue> resultString1 = stringifier1.Stringify(handleValue, handleReplacer1, handleGap);
175     EXPECT_TRUE(resultString1->IsString());
176     JSHandle<EcmaString> handleEcmaStr1(resultString1);
177     EXPECT_STREQ("false", EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
178 
179     JsonStringifier stringifier2(thread);
180     JSHandle<JSTaggedValue> resultString2 = stringifier2.Stringify(handleValue, handleReplacer2, handleGap);
181     EXPECT_TRUE(resultString2->IsString());
182     JSHandle<EcmaString> handleEcmaStr2(resultString2);
183     EXPECT_STREQ("10.12", EcmaStringAccessor(handleEcmaStr2).ToCString(thread).c_str());
184 }
185 
186 /**
187  * @tc.name: Stringify_002
188  * @tc.desc: Check whether the result returned through "Stringify" function is within expectations
189  *           the first parameter of the ECMAObject,the second parameter is Undefined,the third parameter
190  *           is Number.This situation will stringize parameters through "SerializeJSONObject" function.
191  * @tc.type: FUNC
192  * @tc.require:
193  */
HWTEST_F_L0(JsonStringifierTest,Stringify_002)194 HWTEST_F_L0(JsonStringifierTest, Stringify_002)
195 {
196     JsonStringifier stringifier(thread);
197 
198     JSHandle<JSTaggedValue> handleObj = JSHandle<JSTaggedValue>(thread, CreateBaseJSObject(thread, "z"));
199     JSHandle<JSTaggedValue> handleValue(thread, handleObj.GetTaggedValue());
200     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
201     JSHandle<JSTaggedValue> handleGap(thread, JSTaggedValue(static_cast<int32_t>(10)));
202 
203     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleValue, handleReplacer, handleGap);
204     EXPECT_TRUE(resultString->IsString());
205     JSHandle<EcmaString> handleEcmaStr(resultString);
206     EXPECT_STREQ("{\n          \"z\": 1,\n          \"x\": 3.6,\n          \"y\": \"abc\"\n}",
207                                                      EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
208 }
209 
210 /**
211  * @tc.name: Stringify_003
212  * @tc.desc: Check whether the result returned through "Stringify" function is within expectations
213  *           the first parameter of the ECMAObject,the second parameter is Undefined,the third parameter
214  *           is String,This situation will stringize parameters through "SerializeJSONObject" function.
215  * @tc.type: FUNC
216  * @tc.require:
217  */
HWTEST_F_L0(JsonStringifierTest,Stringify_003)218 HWTEST_F_L0(JsonStringifierTest, Stringify_003)
219 {
220     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
221     JsonStringifier stringifier(thread);
222 
223     JSHandle<JSTaggedValue> handleObj = JSHandle<JSTaggedValue>(thread, CreateBaseJSObject(thread, "z"));
224     JSHandle<JSTaggedValue> handleMsg(factory->NewFromASCII("tttt"));
225     JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg));
226 
227     JSHandle<JSTaggedValue> handleValue(thread, handleObj.GetTaggedValue());
228     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
229     JSHandle<JSTaggedValue> handleGap(thread, handleStr.GetTaggedValue());
230 
231     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleValue, handleReplacer, handleGap);
232     EXPECT_TRUE(resultString->IsString());
233     JSHandle<EcmaString> resultStr =
234         factory->NewFromASCII("{\ntttt\"z\": 1,\ntttt\"x\": 3.6,\ntttt\"y\": \"abc\"\n}");
235     EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultStr, JSHandle<EcmaString>(resultString)), 0);
236 }
237 
238 /**
239  * @tc.name: Stringify_004
240  * @tc.desc: Check whether the result returned through "Stringify" function is within expectations
241  *           the first parameter of the ECMAObject,the second parameter is JSArray,the third parameter
242  *           is String.This situation will stringize parameters through "SerializeJSONObject" function.
243  * @tc.type: FUNC
244  * @tc.require:
245  */
HWTEST_F_L0(JsonStringifierTest,Stringify_004)246 HWTEST_F_L0(JsonStringifierTest, Stringify_004)
247 {
248     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
249     JsonStringifier stringifier(thread);
250 
251     JSHandle<JSTaggedValue> handleObj1 = JSHandle<JSTaggedValue>(thread, CreateBaseJSObject(thread, "z"));
252 
253     JSArray *handleArr =
254         JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
255     JSHandle<JSObject> handleObj2(thread, handleArr);
256     JSHandle<JSTaggedValue> handleKey0(thread, JSTaggedValue(0));
257     JSHandle<JSTaggedValue> handleValue0(factory->NewFromASCII("z"));
258     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObj2), handleKey0, handleValue0);
259 
260     JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
261     JSHandle<JSTaggedValue> handleValue1(factory->NewFromASCII("x"));
262     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObj2), handleKey1, handleValue1);
263 
264     JSHandle<JSTaggedValue> handleMsg(factory->NewFromASCII("tttt"));
265     JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg));
266 
267     JSHandle<JSTaggedValue> handleValue(thread, handleObj1.GetTaggedValue());
268     JSHandle<JSTaggedValue> handleReplacer(thread, handleObj2.GetTaggedValue());
269     JSHandle<JSTaggedValue> handleGap(thread, handleStr.GetTaggedValue());
270 
271     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleValue, handleReplacer, handleGap);
272     EXPECT_TRUE(resultString->IsString());
273     JSHandle<EcmaString> handleEcmaStr(resultString);
274     EXPECT_STREQ("{\ntttt\"z\": 1,\ntttt\"x\": 3.6\n}", EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
275 }
276 
277 /**
278  * @tc.name: Stringify_005
279  * @tc.desc: Check whether the result returned through "Stringify" function is within expectations
280  *           the first parameter of the ECMAObject,the second parameter is Undefined,the third parameter
281  *           is Undefined.This situation will stringize the first parameter through "SerializeJSONObject" function.
282  * @tc.type: FUNC
283  * @tc.require:
284  */
HWTEST_F_L0(JsonStringifierTest,Stringify_005)285 HWTEST_F_L0(JsonStringifierTest, Stringify_005)
286 {
287     JsonStringifier stringifier(thread);
288     JSHandle<JSTaggedValue> handleObj = JSHandle<JSTaggedValue>(thread, CreateBaseJSObject(thread, "z"));
289 
290     JSHandle<JSTaggedValue> handleValue(thread, handleObj.GetTaggedValue());
291     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
292     JSHandle<JSTaggedValue> handleGap(thread, JSTaggedValue::Undefined());
293 
294     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleValue, handleReplacer, handleGap);
295     EXPECT_TRUE(resultString->IsString());
296     JSHandle<EcmaString> handleEcmaStr(resultString);
297     EXPECT_STREQ("{\"z\":1,\"x\":3.6,\"y\":\"abc\"}", EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
298 }
299 
300 /**
301  * @tc.name: Stringify_006
302  * @tc.desc: Check whether the result returned through "Stringify" function is within expectations
303  *           the first parameter of the JSArray,the second parameter is Undefined,the third parameter
304  *           is String,This situation will stringize parameters through "SerializeJSArray" function.
305  * @tc.type: FUNC
306  * @tc.require:
307  */
HWTEST_F_L0(JsonStringifierTest,Stringify_006)308 HWTEST_F_L0(JsonStringifierTest, Stringify_006)
309 {
310     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
311     JsonStringifier stringifier(thread);
312 
313     JSArray *handleArr =
314         JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
315     JSHandle<JSObject> handleObj(thread, handleArr);
316 
317     JSHandle<JSTaggedValue> handleKey0(thread, JSTaggedValue(0));
318     JSHandle<JSTaggedValue> handleValue0(factory->NewFromASCII("json"));
319     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObj), handleKey0, handleValue0);
320 
321     JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
322     PropertyDescriptor handleDesc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(100)), true, true, true);
323     JSArray::DefineOwnProperty(thread, handleObj, handleKey1, handleDesc);
324 
325     JSHandle<JSTaggedValue> handleKey2(thread, JSTaggedValue(2));
326     JSHandle<JSTaggedValue> handleValue2(factory->NewFromASCII("abc"));
327     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObj), handleKey2, handleValue2);
328 
329     JSHandle<JSTaggedValue> handleMsg(factory->NewFromASCII("tttt"));
330     JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg));
331 
332     JSHandle<JSTaggedValue> handleValue(thread, handleObj.GetTaggedValue());
333     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
334     JSHandle<JSTaggedValue> handleGap(thread, handleStr.GetTaggedValue());
335 
336     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleValue, handleReplacer, handleGap);
337     EXPECT_TRUE(resultString->IsString());
338     JSHandle<EcmaString> handleEcmaStr(resultString);
339     EXPECT_STREQ("[\ntttt\"json\",\ntttt100,\ntttt\"abc\"\n]",
340                  EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
341 }
342 
343 /**
344  * @tc.name: Stringify_007
345  * @tc.desc: Check whether the result returned through "Stringify" function is within expectations
346  *           the first parameter of the JSObject,the second parameter is Undefined,the third parameter
347  *           is Undefined.This situation will stringize the first parameter through "SerializeJSArray" function.
348  * @tc.type: FUNC
349  * @tc.require:
350  */
HWTEST_F_L0(JsonStringifierTest,Stringify_007)351 HWTEST_F_L0(JsonStringifierTest, Stringify_007)
352 {
353     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
354     JsonStringifier stringifier(thread);
355 
356     JSArray *handleArr =
357         JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
358     JSHandle<JSObject> handleObj(thread, handleArr);
359 
360     JSHandle<JSTaggedValue> handleKey0(thread, JSTaggedValue(0));
361     PropertyDescriptor handleDesc0(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), true, true, true);
362     JSArray::DefineOwnProperty(thread, handleObj, handleKey0, handleDesc0);
363 
364     JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
365     PropertyDescriptor handleDesc1(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(3.6)), true, true, true);
366     JSArray::DefineOwnProperty(thread, handleObj, handleKey1, handleDesc1);
367 
368     JSHandle<JSTaggedValue> handleKey2(thread, JSTaggedValue(2));
369     JSHandle<JSTaggedValue> handleValue2(factory->NewFromASCII("abc"));
370     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObj), handleKey2, handleValue2);
371 
372     JSHandle<JSTaggedValue> handleValue(thread, handleObj.GetTaggedValue());
373     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
374     JSHandle<JSTaggedValue> handleGap(thread, JSTaggedValue::Undefined());
375 
376     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleValue, handleReplacer, handleGap);
377     EXPECT_TRUE(resultString->IsString());
378     JSHandle<EcmaString> handleEcmaStr(resultString);
379     EXPECT_STREQ("[1,3.6,\"abc\"]", EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
380 }
381 
382 /**
383  * @tc.name: Stringify_008
384  * @tc.desc: Check whether the result returned through "Stringify" function is within expectations
385  *           the first parameter of the JSObject,the second parameter is Undefined,the third parameter
386  *           is Undefined.This situation will stringize the first parameter through "SerializePrimitiveRef"
387  *           function.
388  * @tc.type: FUNC
389  * @tc.require:
390  */
HWTEST_F_L0(JsonStringifierTest,Stringify_008)391 HWTEST_F_L0(JsonStringifierTest, Stringify_008)
392 {
393     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
394     JsonStringifier stringifier(thread);
395 
396     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
397     JSHandle<JSTaggedValue> handleStr(factory->NewFromASCII("\"\\\b\f\n\r\t"));
398     JSHandle<JSPrimitiveRef> handlePrimitiveRef = factory->NewJSString(handleStr, undefined);
399     JSHandle<JSObject> handleObj(thread, handlePrimitiveRef.GetTaggedValue());
400 
401     JSHandle<JSTaggedValue> handleValue(thread, handleObj.GetTaggedValue());
402     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
403     JSHandle<JSTaggedValue> handleGap(thread, JSTaggedValue::Undefined());
404 
405     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleValue, handleReplacer, handleGap);
406     EXPECT_TRUE(resultString->IsString());
407     JSHandle<EcmaString> handleEcmaStr(resultString);
408     EXPECT_STREQ("\"\\\"\\\\\\b\\f\\n\\r\\t\"", EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
409 }
410 
Detach(void * param1,void * param2,void * hint,void * detachData)411 static void* Detach(void *param1, void *param2, void *hint, void *detachData)
412 {
413     GTEST_LOG_(INFO) << "detach is running";
414     if (param1 == nullptr && param2 == nullptr) {
415         GTEST_LOG_(INFO) << "detach: two params is nullptr";
416     }
417     if (hint == nullptr && detachData) {
418         GTEST_LOG_(INFO) << "detach: hint is nullptr";
419     }
420     return nullptr;
421 }
422 
Attach(void * enginePointer,void * buffer,void * hint,void * attachData)423 static void* Attach([[maybe_unused]] void *enginePointer, [[maybe_unused]] void *buffer, [[maybe_unused]] void *hint,
424                     [[maybe_unused]] void *attachData)
425 {
426     GTEST_LOG_(INFO) << "attach is running";
427     return nullptr;
428 }
429 
CreateNativeBindingInfo(void * attach,void * detach)430 static panda::JSNApi::NativeBindingInfo* CreateNativeBindingInfo(void* attach, void* detach)
431 {
432     GTEST_LOG_(INFO) << "CreateNativeBindingInfo";
433     auto info = panda::JSNApi::NativeBindingInfo::CreateNewInstance();
434     info->attachFunc = attach;
435     info->detachFunc = detach;
436     return info;
437 }
438 
HWTEST_F_L0(JsonStringifierTest,Stringify_009)439 HWTEST_F_L0(JsonStringifierTest, Stringify_009)
440 {
441     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
442     JsonStringifier stringifier(thread);
443 
444     EcmaVM *ecmaVM = thread->GetEcmaVM();
445     JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
446     JSHandle<JSTaggedValue> objectFunc(globalEnv->GetObjectFunction());
447     JSHandle<JSObject> jsObject(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objectFunc), objectFunc));
448     EXPECT_TRUE(*jsObject != nullptr);
449 
450     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("key1"));
451     auto info = CreateNativeBindingInfo(reinterpret_cast<void*>(Attach), reinterpret_cast<void*>(Detach));
452     JSHandle<JSTaggedValue> value1(factory->NewJSNativePointer(reinterpret_cast<void*>(info)));
453     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(jsObject), key1, value1);
454 
455     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("key2"));
456     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("abc"));
457     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(jsObject), key2, value2);
458 
459     JSHandle<JSTaggedValue> handleValue(thread, jsObject.GetTaggedValue());
460     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
461     JSHandle<JSTaggedValue> handleGap(thread, JSTaggedValue::Undefined());
462 
463     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleValue, handleReplacer, handleGap);
464     EXPECT_TRUE(resultString->IsString());
465     JSHandle<EcmaString> handleEcmaStr(resultString);
466     EXPECT_STREQ("{\"key1\":{},\"key2\":\"abc\"}", EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
467 }
468 
HWTEST_F_L0(JsonStringifierTest,Stringify_010)469 HWTEST_F_L0(JsonStringifierTest, Stringify_010)
470 {
471     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
472     JsonStringifier stringifier(thread, TransformType::SENDABLE);
473     JSHandle<JSSharedMap> sharedMap = CreateSharedMap(thread);
474     JSHandle<JSTaggedValue> handleMap = JSHandle<JSTaggedValue>(sharedMap);
475     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
476     JSHandle<JSTaggedValue> handleGap(thread, JSTaggedValue::Undefined());
477     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleMap, handleReplacer, handleGap);
478     EXPECT_TRUE(resultString->IsString());
479     JSHandle<EcmaString> handleEcmaStr(resultString);
480     EXPECT_STREQ("{}", EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
481 
482     JsonStringifier stringifier1(thread, TransformType::SENDABLE);
483     JSHandle<JSSharedMap> sharedMap1 = CreateSharedMap(thread);
484     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("key1"));
485     JSHandle<JSTaggedValue> value1(factory->NewFromASCII("abc"));
486     JSSharedMap::Set(thread, sharedMap1, key1, value1);
487 
488     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("key2"));
489     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("val"));
490     JSSharedMap::Set(thread, sharedMap1, key2, value2);
491 
492     JSHandle<JSTaggedValue> handleMap1 = JSHandle<JSTaggedValue>(sharedMap1);
493     JSHandle<JSTaggedValue> handleReplacer1(thread, JSTaggedValue::Undefined());
494     JSHandle<JSTaggedValue> handleGap1(thread, JSTaggedValue::Undefined());
495     EXPECT_TRUE(*handleMap1 != nullptr);
496     JSHandle<JSTaggedValue> resultString1 = stringifier1.Stringify(handleMap1, handleReplacer1, handleGap1);
497     EXPECT_TRUE(resultString1->IsString());
498     JSHandle<EcmaString> handleEcmaStr1(resultString1);
499     EXPECT_STREQ("{\"key1\":\"abc\",\"key2\":\"val\"}", EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
500 }
501 
HWTEST_F_L0(JsonStringifierTest,Stringify_011)502 HWTEST_F_L0(JsonStringifierTest, Stringify_011)
503 {
504     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
505     JsonStringifier stringifier(thread, TransformType::SENDABLE);
506     JSHandle<JSMap> jsMap = CreateJSMap(thread);
507     JSHandle<JSTaggedValue> handleMap = JSHandle<JSTaggedValue>(jsMap);
508     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
509     JSHandle<JSTaggedValue> handleGap(thread, JSTaggedValue::Undefined());
510     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleMap, handleReplacer, handleGap);
511     EXPECT_TRUE(resultString->IsString());
512     JSHandle<EcmaString> handleEcmaStr(resultString);
513     EXPECT_STREQ("{}", EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
514 
515     JsonStringifier stringifier1(thread, TransformType::SENDABLE);
516     JSHandle<JSMap> jsMap1 = CreateJSMap(thread);
517     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("key1"));
518     JSHandle<JSTaggedValue> value1(factory->NewFromASCII("abc"));
519     JSMap::Set(thread, jsMap1, key1, value1);
520 
521     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("key2"));
522     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("val"));
523     JSMap::Set(thread, jsMap1, key2, value2);
524 
525     JSHandle<JSTaggedValue> handleMap1 = JSHandle<JSTaggedValue>(jsMap1);
526     JSHandle<JSTaggedValue> handleReplacer1(thread, JSTaggedValue::Undefined());
527     JSHandle<JSTaggedValue> handleGap1(thread, JSTaggedValue::Undefined());
528     EXPECT_TRUE(*handleMap1 != nullptr);
529     JSHandle<JSTaggedValue> resultString1 = stringifier1.Stringify(handleMap1, handleReplacer1, handleGap1);
530     EXPECT_TRUE(resultString1->IsString());
531     JSHandle<EcmaString> handleEcmaStr1(resultString1);
532     EXPECT_STREQ("{\"key1\":\"abc\",\"key2\":\"val\"}", EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
533 }
534 
HWTEST_F_L0(JsonStringifierTest,Stringify_012)535 HWTEST_F_L0(JsonStringifierTest, Stringify_012)
536 {
537     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
538     JsonStringifier stringifier(thread, TransformType::SENDABLE);
539     JSHandle<JSSharedSet> sharedSet = CreateJSSharedSet(thread);
540     JSHandle<JSTaggedValue> handleSet = JSHandle<JSTaggedValue>(sharedSet);
541     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
542     JSHandle<JSTaggedValue> handleGap(thread, JSTaggedValue::Undefined());
543     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleSet, handleReplacer, handleGap);
544     EXPECT_TRUE(resultString->IsString());
545     JSHandle<EcmaString> handleEcmaStr(resultString);
546     EXPECT_STREQ("[]", EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
547 
548     JsonStringifier stringifier1(thread, TransformType::SENDABLE);
549     JSHandle<JSSharedSet> sharedSet1 = CreateJSSharedSet(thread);
550     JSHandle<JSTaggedValue> value1(factory->NewFromASCII("abc"));
551     JSSharedSet::Add(thread, sharedSet1, value1);
552 
553     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("val"));
554     JSSharedSet::Add(thread, sharedSet1, value2);
555 
556     JSHandle<JSTaggedValue> handleSet1 = JSHandle<JSTaggedValue>(sharedSet1);
557     JSHandle<JSTaggedValue> handleReplacer1(thread, JSTaggedValue::Undefined());
558     JSHandle<JSTaggedValue> handleGap1(thread, JSTaggedValue::Undefined());
559     EXPECT_TRUE(*handleSet1 != nullptr);
560     JSHandle<JSTaggedValue> resultString1 = stringifier1.Stringify(handleSet1, handleReplacer1, handleGap1);
561     EXPECT_TRUE(resultString1->IsString());
562     JSHandle<EcmaString> handleEcmaStr1(resultString1);
563     EXPECT_STREQ("[\"abc\",\"val\"]", EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
564 }
565 
HWTEST_F_L0(JsonStringifierTest,Stringify_013)566 HWTEST_F_L0(JsonStringifierTest, Stringify_013)
567 {
568     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
569     JsonStringifier stringifier(thread, TransformType::SENDABLE);
570     JSHandle<JSSet> jsSet = CreateJSSet(thread);
571     JSHandle<JSTaggedValue> handleSet = JSHandle<JSTaggedValue>(jsSet);
572     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
573     JSHandle<JSTaggedValue> handleGap(thread, JSTaggedValue::Undefined());
574     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleSet, handleReplacer, handleGap);
575     EXPECT_TRUE(resultString->IsString());
576     JSHandle<EcmaString> handleEcmaStr(resultString);
577     EXPECT_STREQ("[]", EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
578 
579     JsonStringifier stringifier1(thread, TransformType::SENDABLE);
580     JSHandle<JSSet> jsSet1 = CreateJSSet(thread);
581     JSHandle<JSTaggedValue> value1(factory->NewFromASCII("abc"));
582     JSSet::Add(thread, jsSet1, value1);
583 
584     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("val"));
585     JSSet::Add(thread, jsSet1, value2);
586 
587     JSHandle<JSTaggedValue> handleSet1 = JSHandle<JSTaggedValue>(jsSet1);
588     JSHandle<JSTaggedValue> handleReplacer1(thread, JSTaggedValue::Undefined());
589     JSHandle<JSTaggedValue> handleGap1(thread, JSTaggedValue::Undefined());
590     EXPECT_TRUE(*handleSet1 != nullptr);
591     JSHandle<JSTaggedValue> resultString1 = stringifier1.Stringify(handleSet1, handleReplacer1, handleGap1);
592     EXPECT_TRUE(resultString1->IsString());
593     JSHandle<EcmaString> handleEcmaStr1(resultString1);
594     EXPECT_STREQ("[\"abc\",\"val\"]", EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
595 }
596 
HWTEST_F_L0(JsonStringifierTest,Stringify_014)597 HWTEST_F_L0(JsonStringifierTest, Stringify_014)
598 {
599     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
600     JsonStringifier stringifier(thread, TransformType::SENDABLE);
601     JSHandle<JSAPIHashMap> hashMap(thread, CreateHashMap(thread));
602     JSHandle<JSTaggedValue> handleMap = JSHandle<JSTaggedValue>(hashMap);
603     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
604     JSHandle<JSTaggedValue> handleGap(thread, JSTaggedValue::Undefined());
605     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleMap, handleReplacer, handleGap);
606     EXPECT_TRUE(resultString->IsString());
607     JSHandle<EcmaString> handleEcmaStr(resultString);
608     EXPECT_STREQ("{}", EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
609 
610     JsonStringifier stringifier1(thread, TransformType::SENDABLE);
611     JSHandle<JSAPIHashMap> hashMap1(thread, CreateHashMap(thread));
612     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("key1"));
613     JSHandle<JSTaggedValue> value1(factory->NewFromASCII("abc"));
614     JSAPIHashMap::Set(thread, hashMap1, key1, value1);
615 
616     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("key2"));
617     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("val"));
618     JSAPIHashMap::Set(thread, hashMap1, key2, value2);
619 
620     JSHandle<JSTaggedValue> handleMap1 = JSHandle<JSTaggedValue>(hashMap1);
621     JSHandle<JSTaggedValue> handleReplacer1(thread, JSTaggedValue::Undefined());
622     JSHandle<JSTaggedValue> handleGap1(thread, JSTaggedValue::Undefined());
623     EXPECT_TRUE(*handleMap1 != nullptr);
624     JSHandle<JSTaggedValue> resultString1 = stringifier1.Stringify(handleMap1, handleReplacer1, handleGap1);
625     EXPECT_TRUE(resultString1->IsString());
626     JSHandle<EcmaString> handleEcmaStr1(resultString1);
627     EXPECT_STRNE("{}", EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
628 }
629 
HWTEST_F_L0(JsonStringifierTest,Stringify_015)630 HWTEST_F_L0(JsonStringifierTest, Stringify_015)
631 {
632     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
633     JsonStringifier stringifier(thread, TransformType::SENDABLE);
634     JSHandle<JSAPIHashSet> hashSet(thread, CreateHashSet(thread));
635     JSHandle<JSTaggedValue> handleSet = JSHandle<JSTaggedValue>(hashSet);
636     JSHandle<JSTaggedValue> handleReplacer(thread, JSTaggedValue::Undefined());
637     JSHandle<JSTaggedValue> handleGap(thread, JSTaggedValue::Undefined());
638     JSHandle<JSTaggedValue> resultString = stringifier.Stringify(handleSet, handleReplacer, handleGap);
639     EXPECT_TRUE(resultString->IsString());
640     JSHandle<EcmaString> handleEcmaStr(resultString);
641     EXPECT_STREQ("[]", EcmaStringAccessor(handleEcmaStr).ToCString(thread).c_str());
642 
643     JsonStringifier stringifier1(thread, TransformType::SENDABLE);
644     JSHandle<JSAPIHashSet> hashSet1(thread, CreateHashSet(thread));
645     JSHandle<JSTaggedValue> value1(factory->NewFromASCII("abc"));
646     JSAPIHashSet::Add(thread, hashSet1, value1);
647 
648     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("val"));
649     JSAPIHashSet::Add(thread, hashSet1, value2);
650 
651     JSHandle<JSTaggedValue> handleSet1 = JSHandle<JSTaggedValue>(hashSet1);
652     JSHandle<JSTaggedValue> handleReplacer1(thread, JSTaggedValue::Undefined());
653     JSHandle<JSTaggedValue> handleGap1(thread, JSTaggedValue::Undefined());
654     EXPECT_TRUE(*handleSet1 != nullptr);
655     JSHandle<JSTaggedValue> resultString1 = stringifier1.Stringify(handleSet1, handleReplacer1, handleGap1);
656     EXPECT_TRUE(resultString1->IsString());
657     JSHandle<EcmaString> handleEcmaStr1(resultString1);
658     EXPECT_STRNE("[]", EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
659 }
660 
HWTEST_F_L0(JsonStringifierTest,Stringify_016)661 HWTEST_F_L0(JsonStringifierTest, Stringify_016)
662 {
663     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
664 
665     JsonStringifier stringifier(thread, TransformType::SENDABLE);
666     JSHandle<JSSharedMap> sharedMap1 = CreateSharedMap(thread);
667     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("key1"));
668     JSHandle<JSTaggedValue> value1(factory->NewFromASCII("abc"));
669     JSSharedMap::Set(thread, sharedMap1, key1, value1);
670     JSSharedMap::Clear(thread, sharedMap1);
671 
672     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("key2"));
673     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("val"));
674     JSSharedMap::Set(thread, sharedMap1, key2, value2);
675     JSSharedMap::Set(thread, sharedMap1, key1, value1);
676 
677     JSHandle<JSTaggedValue> handleMap1 = JSHandle<JSTaggedValue>(sharedMap1);
678     JSHandle<JSTaggedValue> handleReplacer1(thread, JSTaggedValue::Undefined());
679     JSHandle<JSTaggedValue> handleGap1(thread, JSTaggedValue::Undefined());
680     EXPECT_TRUE(*handleMap1 != nullptr);
681     JSHandle<JSTaggedValue> resultString1 = stringifier.Stringify(handleMap1, handleReplacer1, handleGap1);
682     EXPECT_TRUE(resultString1->IsString());
683     JSHandle<EcmaString> handleEcmaStr1(resultString1);
684     EXPECT_STREQ("{\"key2\":\"val\",\"key1\":\"abc\"}", EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
685 }
686 
HWTEST_F_L0(JsonStringifierTest,Stringify_017)687 HWTEST_F_L0(JsonStringifierTest, Stringify_017)
688 {
689     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
690     JsonStringifier stringifier(thread, TransformType::SENDABLE);
691     JSHandle<JSSharedSet> sharedSet1 = CreateJSSharedSet(thread);
692     JSHandle<JSTaggedValue> value1(factory->NewFromASCII("abc"));
693     JSSharedSet::Add(thread, sharedSet1, value1);
694     JSSharedSet::Clear(thread, sharedSet1);
695 
696     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("val"));
697     JSSharedSet::Add(thread, sharedSet1, value2);
698     JSSharedSet::Add(thread, sharedSet1, value1);
699 
700     JSHandle<JSTaggedValue> handleSet1 = JSHandle<JSTaggedValue>(sharedSet1);
701     JSHandle<JSTaggedValue> handleReplacer1(thread, JSTaggedValue::Undefined());
702     JSHandle<JSTaggedValue> handleGap1(thread, JSTaggedValue::Undefined());
703     EXPECT_TRUE(*handleSet1 != nullptr);
704     JSHandle<JSTaggedValue> resultString1 = stringifier.Stringify(handleSet1, handleReplacer1, handleGap1);
705     EXPECT_TRUE(resultString1->IsString());
706     JSHandle<EcmaString> handleEcmaStr1(resultString1);
707     EXPECT_STREQ("[\"val\",\"abc\"]", EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
708 }
709 
HWTEST_F_L0(JsonStringifierTest,Stringify_018)710 HWTEST_F_L0(JsonStringifierTest, Stringify_018)
711 {
712     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
713 
714     JsonStringifier stringifier(thread, TransformType::SENDABLE);
715     JSHandle<JSSharedMap> sharedMap1 = CreateSharedMap(thread);
716     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("key1"));
717     JSHandle<JSTaggedValue> value1(factory->NewFromASCII("abc"));
718     JSSharedMap::Set(thread, sharedMap1, key1, value1);
719 
720     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("key2"));
721     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("val"));
722     JSHandle<JSTaggedValue> undefined(thread, JSTaggedValue::Undefined());
723     JSSharedMap::Set(thread, sharedMap1, key2, undefined);
724     JSSharedMap::Set(thread, sharedMap1, undefined, value2);
725 
726     JSHandle<JSTaggedValue> handleMap1 = JSHandle<JSTaggedValue>(sharedMap1);
727     JSHandle<JSTaggedValue> handleReplacer1(thread, JSTaggedValue::Undefined());
728     JSHandle<JSTaggedValue> handleGap1(thread, JSTaggedValue::Undefined());
729     EXPECT_TRUE(*handleMap1 != nullptr);
730     JSHandle<JSTaggedValue> resultString1 = stringifier.Stringify(handleMap1, handleReplacer1, handleGap1);
731     EXPECT_TRUE(resultString1->IsString());
732     JSHandle<EcmaString> handleEcmaStr1(resultString1);
733     EXPECT_STREQ("{\"key1\":\"abc\",\"undefined\":\"val\"}",
734                  EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
735 }
736 
HWTEST_F_L0(JsonStringifierTest,Stringify_019)737 HWTEST_F_L0(JsonStringifierTest, Stringify_019)
738 {
739     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
740     JsonStringifier stringifier(thread, TransformType::SENDABLE);
741     JSHandle<JSSharedSet> sharedSet1 = CreateJSSharedSet(thread);
742     JSHandle<JSTaggedValue> value1(factory->NewFromASCII("abc"));
743     JSSharedSet::Add(thread, sharedSet1, value1);
744 
745     JSHandle<JSTaggedValue> value2(factory->NewFromASCII("val"));
746     JSSharedSet::Add(thread, sharedSet1, value2);
747 
748     JSHandle<JSTaggedValue> undefined(thread, JSTaggedValue::Undefined());
749     JSSharedSet::Add(thread, sharedSet1, undefined);
750 
751     JSHandle<JSTaggedValue> handleSet1 = JSHandle<JSTaggedValue>(sharedSet1);
752     JSHandle<JSTaggedValue> handleReplacer1(thread, JSTaggedValue::Undefined());
753     JSHandle<JSTaggedValue> handleGap1(thread, JSTaggedValue::Undefined());
754     EXPECT_TRUE(*handleSet1 != nullptr);
755     JSHandle<JSTaggedValue> resultString1 = stringifier.Stringify(handleSet1, handleReplacer1, handleGap1);
756     EXPECT_TRUE(resultString1->IsString());
757     JSHandle<EcmaString> handleEcmaStr1(resultString1);
758     EXPECT_STREQ("[\"abc\",\"val\",null]", EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
759 }
760 
HWTEST_F_L0(JsonStringifierTest,Stringify_020)761 HWTEST_F_L0(JsonStringifierTest, Stringify_020)
762 {
763     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
764     JsonStringifier stringifier1(thread, TransformType::SENDABLE);
765     JSHandle<JSAPIHashMap> hashMap1(thread, CreateHashMap(thread));
766     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("key1"));
767     JSHandle<JSTaggedValue> value1(factory->NewFromASCII("abc"));
768     JSAPIHashMap::Set(thread, hashMap1, key1, value1);
769 
770     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("key2"));
771     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue::Undefined());
772     JSAPIHashMap::Set(thread, hashMap1, key2, value2);
773 
774     JSHandle<JSTaggedValue> handleMap1 = JSHandle<JSTaggedValue>(hashMap1);
775     JSHandle<JSTaggedValue> handleReplacer1(thread, JSTaggedValue::Undefined());
776     JSHandle<JSTaggedValue> handleGap1(thread, JSTaggedValue::Undefined());
777     EXPECT_TRUE(*handleMap1 != nullptr);
778     JSHandle<JSTaggedValue> resultString1 = stringifier1.Stringify(handleMap1, handleReplacer1, handleGap1);
779     EXPECT_TRUE(resultString1->IsString());
780     JSHandle<EcmaString> handleEcmaStr1(resultString1);
781     EXPECT_STREQ("{\"key1\":\"abc\"}", EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
782 }
783 
HWTEST_F_L0(JsonStringifierTest,Stringify_021)784 HWTEST_F_L0(JsonStringifierTest, Stringify_021)
785 {
786     JsonStringifier stringifier1(thread, TransformType::SENDABLE);
787     JSHandle<JSAPIHashSet> hashSet1(thread, CreateHashSet(thread));
788     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue::Undefined());
789     JSAPIHashSet::Add(thread, hashSet1, value1);
790 
791     JSHandle<JSTaggedValue> handleSet1 = JSHandle<JSTaggedValue>(hashSet1);
792     JSHandle<JSTaggedValue> handleReplacer1(thread, JSTaggedValue::Undefined());
793     JSHandle<JSTaggedValue> handleGap1(thread, JSTaggedValue::Undefined());
794     EXPECT_TRUE(*handleSet1 != nullptr);
795     JSHandle<JSTaggedValue> resultString1 = stringifier1.Stringify(handleSet1, handleReplacer1, handleGap1);
796     EXPECT_TRUE(resultString1->IsString());
797     JSHandle<EcmaString> handleEcmaStr1(resultString1);
798     EXPECT_STREQ("[null]", EcmaStringAccessor(handleEcmaStr1).ToCString(thread).c_str());
799 }
800 
801 #if ENABLE_NEXT_OPTIMIZATION
HWTEST_F_L0(JsonStringifierTest,AppendSpecialDouble_01)802 HWTEST_F_L0(JsonStringifierTest, AppendSpecialDouble_01)
803 {
804     struct TestCase {
805         double value;
806         const char* expected;
807     };
808     TestCase testCases[] = {
809         { 0.0, "0" },
810         { NAN, "NaN" },
811         { INFINITY, "Infinity" },
812         { -INFINITY, "-Infinity" },
813     };
814     CString str;
815     for (const auto& testCase : testCases) {
816         bool appended = AppendSpecialDouble(str, testCase.value);
817         ASSERT_TRUE(appended);
818         EXPECT_STREQ(testCase.expected, str.c_str());
819         str.clear();
820     }
821 }
822 
HWTEST_F_L0(JsonStringifierTest,AppendDoubleToString_01)823 HWTEST_F_L0(JsonStringifierTest, AppendDoubleToString_01)
824 {
825     struct TestCase {
826         double value;
827         const char* expected;
828     };
829     TestCase testCases[] = {
830         { 123000.0, "123000" },
831         { -456000.0, "-456000" },
832         { 1234.5678, "1234.5678" },
833         { -8765.4321, "-8765.4321" },
834         { 0.00123, "0.00123" },
835         { -0.0456, "-0.0456" },
836         { 1.2345e24, "1.2345e+24" },
837         { -6.789e22, "-6.789e+22" },
838         { 0.00000000123, "1.23e-9" },
839         { -0.0000000456, "-4.56e-8" }
840     };
841     CString str;
842     for (const auto& testCase : testCases) {
843         AppendDoubleToString(str, testCase.value);
844         EXPECT_STREQ(testCase.expected, str.c_str());
845         str.clear();
846     }
847 }
848 
HWTEST_F_L0(JsonStringifierTest,ConvertToCStringAndAppend_01)849 HWTEST_F_L0(JsonStringifierTest, ConvertToCStringAndAppend_01)
850 {
851     struct TestCase {
852         JSTaggedValue value;
853         const char* expected;
854     };
855     TestCase testCases[] = {
856         { JSTaggedValue(NAN), "NaN" },
857         { JSTaggedValue(INFINITY), "Infinity" },
858         { JSTaggedValue(42), "42" },
859         { JSTaggedValue(-3.14), "-3.14" }
860     };
861     CString str;
862     for (const auto& testCase : testCases) {
863         ConvertNumberToCStringAndAppend(str, testCase.value);
864         EXPECT_STREQ(testCase.expected, str.c_str());
865         str.clear();
866     }
867 }
868 #endif
869 }  // namespace panda::test
870