14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/base/json_parser.h"
174514f5e3Sopenharmony_ci#include "ecmascript/base/json_helper.h"
184514f5e3Sopenharmony_ci#include "ecmascript/ecma_string.h"
194514f5e3Sopenharmony_ci#include "ecmascript/tests/test_helper.h"
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_ciusing namespace panda::ecmascript;
224514f5e3Sopenharmony_ciusing namespace panda::ecmascript::base;
234514f5e3Sopenharmony_ci
244514f5e3Sopenharmony_cinamespace panda::test {
254514f5e3Sopenharmony_ciclass JsonParserTest : public BaseTestWithScope<false> {
264514f5e3Sopenharmony_cipublic:
274514f5e3Sopenharmony_ci    using TransformType = base::JsonHelper::TransformType;
284514f5e3Sopenharmony_ci
294514f5e3Sopenharmony_ci    void CheckUnsupportedSendableJson(JSHandle<JSTaggedValue> &result) const
304514f5e3Sopenharmony_ci    {
314514f5e3Sopenharmony_ci        EXPECT_TRUE(result->IsException());
324514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> exceptionObj(thread, thread->GetException());
334514f5e3Sopenharmony_ci        auto messageValue =
344514f5e3Sopenharmony_ci            JSTaggedValue::GetProperty(thread, exceptionObj, thread->GlobalConstants()->GetHandledMessageString())
354514f5e3Sopenharmony_ci                .GetValue();
364514f5e3Sopenharmony_ci        EXPECT_EQ(ConvertToString(EcmaString::Cast(messageValue->GetTaggedObject())),
374514f5e3Sopenharmony_ci                  MessageString::GetMessageString(GET_MESSAGE_STRING_ID(SendableArrayForJson)).c_str());
384514f5e3Sopenharmony_ci    }
394514f5e3Sopenharmony_ci
404514f5e3Sopenharmony_ci    bool CheckSendableConstraint(JSTaggedValue value) const
414514f5e3Sopenharmony_ci    {
424514f5e3Sopenharmony_ci        if (!value.IsHeapObject()) {
434514f5e3Sopenharmony_ci            // tagged value always follow sendable constraint.
444514f5e3Sopenharmony_ci            return true;
454514f5e3Sopenharmony_ci        }
464514f5e3Sopenharmony_ci        TaggedObject *obj = value.IsWeak() ? value.GetTaggedWeakRef() : value.GetTaggedObject();
474514f5e3Sopenharmony_ci        auto *jsHClass = obj->GetClass();
484514f5e3Sopenharmony_ci        if (!jsHClass->IsJSShared()) {
494514f5e3Sopenharmony_ci            return false;
504514f5e3Sopenharmony_ci        }
514514f5e3Sopenharmony_ci        if (jsHClass->IsExtensible()) {
524514f5e3Sopenharmony_ci            LOG_ECMA(ERROR) << "sendable check failed. obj is extensible";
534514f5e3Sopenharmony_ci            value.D();
544514f5e3Sopenharmony_ci            return false;
554514f5e3Sopenharmony_ci        }
564514f5e3Sopenharmony_ci        if (!CheckSendableProps(value, obj)) {
574514f5e3Sopenharmony_ci            return false;
584514f5e3Sopenharmony_ci        }
594514f5e3Sopenharmony_ci        // trace proto chain
604514f5e3Sopenharmony_ci        auto proto = jsHClass->GetPrototype();
614514f5e3Sopenharmony_ci        if (!proto.IsNull() && !proto.IsJSShared()) {
624514f5e3Sopenharmony_ci            LOG_ECMA(ERROR) << "sendable check failed. proto is not sendable.";
634514f5e3Sopenharmony_ci            value.D();
644514f5e3Sopenharmony_ci            return false;
654514f5e3Sopenharmony_ci        }
664514f5e3Sopenharmony_ci        return true;
674514f5e3Sopenharmony_ci    }
684514f5e3Sopenharmony_ci
694514f5e3Sopenharmony_ci    bool CheckSendableProps(JSTaggedValue value, TaggedObject *obj) const
704514f5e3Sopenharmony_ci    {
714514f5e3Sopenharmony_ci        auto *jsHClass = obj->GetClass();
724514f5e3Sopenharmony_ci        auto layoutValue = jsHClass->GetLayout();
734514f5e3Sopenharmony_ci        if (layoutValue.IsNull()) {
744514f5e3Sopenharmony_ci            return true;
754514f5e3Sopenharmony_ci        }
764514f5e3Sopenharmony_ci        auto *layoutInfo = LayoutInfo::Cast(layoutValue.GetTaggedObject());
774514f5e3Sopenharmony_ci        auto *jsObj = JSObject::Cast(obj);
784514f5e3Sopenharmony_ci        auto *propsValue = TaggedArray::Cast(jsObj->GetProperties());
794514f5e3Sopenharmony_ci        if (propsValue->IsDictionaryMode()) {
804514f5e3Sopenharmony_ci            for (int idx = 0; idx < static_cast<int>(jsHClass->NumberOfProps()); idx++) {
814514f5e3Sopenharmony_ci                auto attr = layoutInfo->GetAttr(idx);
824514f5e3Sopenharmony_ci                if (attr.IsInlinedProps()) {
834514f5e3Sopenharmony_ci                    // Do not check inline props
844514f5e3Sopenharmony_ci                    continue;
854514f5e3Sopenharmony_ci                }
864514f5e3Sopenharmony_ci                if (attr.IsWritable()) {
874514f5e3Sopenharmony_ci                    LOG_ECMA(ERROR) << "sendable check failed. supposed to be un-writable. idx: " << idx;
884514f5e3Sopenharmony_ci                    value.D();
894514f5e3Sopenharmony_ci                    return false;
904514f5e3Sopenharmony_ci                }
914514f5e3Sopenharmony_ci                auto val = propsValue->Get(thread, idx - jsHClass->GetInlinedProperties());
924514f5e3Sopenharmony_ci                if (!CheckSendableConstraint(val)) {
934514f5e3Sopenharmony_ci                    LOG_ECMA(ERROR) << "sendable check failed. supposed to be sendable. idx: " << idx;
944514f5e3Sopenharmony_ci                    value.D();
954514f5e3Sopenharmony_ci                    return false;
964514f5e3Sopenharmony_ci                }
974514f5e3Sopenharmony_ci            }
984514f5e3Sopenharmony_ci        }
994514f5e3Sopenharmony_ci        return true;
1004514f5e3Sopenharmony_ci    }
1014514f5e3Sopenharmony_ci};
1024514f5e3Sopenharmony_ci
1034514f5e3Sopenharmony_ci/**
1044514f5e3Sopenharmony_ci * @tc.name: Parser_001
1054514f5e3Sopenharmony_ci * @tc.desc: Passing in a character of type "uint8_t" check whether the result returned through "ParserUtf8" function
1064514f5e3Sopenharmony_ci *           Test without for no Nesting.
1074514f5e3Sopenharmony_ci * @tc.type: FUNC
1084514f5e3Sopenharmony_ci * @tc.require:
1094514f5e3Sopenharmony_ci */
1104514f5e3Sopenharmony_ciHWTEST_F_L0(JsonParserTest, Parser_001)
1114514f5e3Sopenharmony_ci{
1124514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1134514f5e3Sopenharmony_ci    Utf8JsonParser parser(thread, TransformType::NORMAL);
1144514f5e3Sopenharmony_ci    // JSON Number
1154514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg2(factory->NewFromASCII("1234"));
1164514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr2(JSTaggedValue::ToString(thread, handleMsg2));
1174514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result2 = parser.Parse(handleStr2);
1184514f5e3Sopenharmony_ci    EXPECT_EQ(result2->GetNumber(), 1234);
1194514f5e3Sopenharmony_ci    // JSON Literal
1204514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg3(factory->NewFromASCII("true"));
1214514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr3(JSTaggedValue::ToString(thread, handleMsg3));
1224514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result3 = parser.Parse(handleStr3);
1234514f5e3Sopenharmony_ci    EXPECT_EQ(result3.GetTaggedValue(), JSTaggedValue::True());
1244514f5e3Sopenharmony_ci    // JSON Unexpected
1254514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg4(factory->NewFromASCII("trus"));
1264514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr4(JSTaggedValue::ToString(thread, handleMsg4));
1274514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result4 = parser.Parse(handleStr4);
1284514f5e3Sopenharmony_ci    EXPECT_EQ(result4.GetTaggedValue(), JSTaggedValue::Exception());
1294514f5e3Sopenharmony_ci}
1304514f5e3Sopenharmony_ci
1314514f5e3Sopenharmony_ci/**
1324514f5e3Sopenharmony_ci * @tc.name: Parser_002
1334514f5e3Sopenharmony_ci * @tc.desc: Passing in a character of type "uint16_t" check whether the result returned through "ParseUtf16" function
1344514f5e3Sopenharmony_ci *           Test without for no Nesting.
1354514f5e3Sopenharmony_ci * @tc.type: FUNC
1364514f5e3Sopenharmony_ci * @tc.require:
1374514f5e3Sopenharmony_ci */
1384514f5e3Sopenharmony_ciHWTEST_F_L0(JsonParserTest, Parser_002)
1394514f5e3Sopenharmony_ci{
1404514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1414514f5e3Sopenharmony_ci    Utf16JsonParser parser(thread, TransformType::NORMAL);
1424514f5e3Sopenharmony_ci
1434514f5e3Sopenharmony_ci    // JSON Number
1444514f5e3Sopenharmony_ci    uint16_t array1Utf16[] = {0x31, 0x32, 0x33, 0x34}; // "1234"
1454514f5e3Sopenharmony_ci    uint32_t array1Utf16Len = sizeof(array1Utf16) / sizeof(array1Utf16[0]);
1464514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg2(factory->NewFromUtf16(&array1Utf16[0], array1Utf16Len));
1474514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr2(JSTaggedValue::ToString(thread, handleMsg2));
1484514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result2 = parser.Parse(*handleStr2);
1494514f5e3Sopenharmony_ci    EXPECT_EQ(result2->GetNumber(), 1234);
1504514f5e3Sopenharmony_ci    // JSON Literal
1514514f5e3Sopenharmony_ci    uint16_t array2Utf16[] = {0x74, 0x72, 0x75, 0x65}; // "true"
1524514f5e3Sopenharmony_ci    uint32_t array2Utf16Len = sizeof(array2Utf16) / sizeof(array2Utf16[0]);
1534514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg3(factory->NewFromUtf16(&array2Utf16[0], array2Utf16Len));
1544514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr3(JSTaggedValue::ToString(thread, handleMsg3));
1554514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result3 = parser.Parse(*handleStr3);
1564514f5e3Sopenharmony_ci    EXPECT_EQ(result3.GetTaggedValue(), JSTaggedValue::True());
1574514f5e3Sopenharmony_ci    // JSON String
1584514f5e3Sopenharmony_ci    uint16_t array3Utf16[] = {0x22, 0x73, 0x74, 0x72, 0x69, 0x6E, 0X67, 0x22}; // "string"
1594514f5e3Sopenharmony_ci    uint32_t array3Utf16Len = sizeof(array3Utf16) / sizeof(array3Utf16[0]);
1604514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg4(factory->NewFromUtf16(&array3Utf16[0], array3Utf16Len));
1614514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr4(JSTaggedValue::ToString(thread, handleMsg4));
1624514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result4 = parser.Parse(*handleStr4);
1634514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleEcmaStr(result4);
1644514f5e3Sopenharmony_ci    EXPECT_STREQ("string", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
1654514f5e3Sopenharmony_ci}
1664514f5e3Sopenharmony_ci
1674514f5e3Sopenharmony_ci/**
1684514f5e3Sopenharmony_ci * @tc.name: Parser_003
1694514f5e3Sopenharmony_ci * @tc.desc: Passing in a character of type "uint8_t" check whether the result returned through "ParserUtf8" function
1704514f5e3Sopenharmony_ci *           Test with for Nesting of numbers, strings, objects, arrays, Booleans.
1714514f5e3Sopenharmony_ci * @tc.type: FUNC
1724514f5e3Sopenharmony_ci * @tc.require:
1734514f5e3Sopenharmony_ci */
1744514f5e3Sopenharmony_ciHWTEST_F_L0(JsonParserTest, Parser_003)
1754514f5e3Sopenharmony_ci{
1764514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1774514f5e3Sopenharmony_ci    Utf8JsonParser parser(thread, TransformType::NORMAL);
1784514f5e3Sopenharmony_ci
1794514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg(factory->NewFromASCII(
1804514f5e3Sopenharmony_ci        "\t\r \n{\t\r \n \"json\"\t\r\n:\t\r \n{\t\r \n}\t\r \n,\t\r \n \"prop2\"\t\r \n:\t\r \n [\t\r \nfalse\t\r"
1814514f5e3Sopenharmony_ci        "\n,\t\r \nnull\t\r, \ntrue\t\r,123.456\t\r \n]\t\r \n}\t\r \n"));
1824514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg)); // JSON Object
1834514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result = parser.Parse(handleStr);
1844514f5e3Sopenharmony_ci    EXPECT_TRUE(result->IsECMAObject());
1854514f5e3Sopenharmony_ci}
1864514f5e3Sopenharmony_ci
1874514f5e3Sopenharmony_ci/**
1884514f5e3Sopenharmony_ci * @tc.name: Parser_004
1894514f5e3Sopenharmony_ci * @tc.desc: Passing in a character of type "uint8_t" check whether the result returned through "ParserUtf8" function
1904514f5e3Sopenharmony_ci *           Test with for Nesting of numbers, strings, arrays.
1914514f5e3Sopenharmony_ci * @tc.type: FUNC
1924514f5e3Sopenharmony_ci * @tc.require:
1934514f5e3Sopenharmony_ci */
1944514f5e3Sopenharmony_ciHWTEST_F_L0(JsonParserTest, Parser_004)
1954514f5e3Sopenharmony_ci{
1964514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1974514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
1984514f5e3Sopenharmony_ci    Utf8JsonParser parser(thread, TransformType::NORMAL);
1994514f5e3Sopenharmony_ci
2004514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg(factory->NewFromASCII("[100,2.5,\"abc\"]"));
2014514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg)); // JSON Array
2024514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result = parser.Parse(handleStr);
2034514f5e3Sopenharmony_ci
2044514f5e3Sopenharmony_ci    JSTaggedValue resultValue(static_cast<JSTaggedType>(result->GetRawData()));
2054514f5e3Sopenharmony_ci    EXPECT_TRUE(resultValue.IsECMAObject());
2064514f5e3Sopenharmony_ci    JSHandle<JSObject> valueHandle(thread, resultValue);
2074514f5e3Sopenharmony_ci
2084514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> lenResult =
2094514f5e3Sopenharmony_ci        JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle), lengthKeyHandle).GetValue();
2104514f5e3Sopenharmony_ci    uint32_t length = JSTaggedValue::ToLength(thread, lenResult).ToUint32();
2114514f5e3Sopenharmony_ci    EXPECT_EQ(length, 3U);
2124514f5e3Sopenharmony_ci}
2134514f5e3Sopenharmony_ci
2144514f5e3Sopenharmony_ci/**
2154514f5e3Sopenharmony_ci * @tc.name: Parser_005
2164514f5e3Sopenharmony_ci * @tc.desc: Passing in a character of type "uint8_t" check whether the result returned through "ParserUtf8" function
2174514f5e3Sopenharmony_ci *           Test without for Nesting of numbers, strings, objects.
2184514f5e3Sopenharmony_ci * @tc.type: FUNC
2194514f5e3Sopenharmony_ci * @tc.require:
2204514f5e3Sopenharmony_ci */
2214514f5e3Sopenharmony_ciHWTEST_F_L0(JsonParserTest, Parser_005)
2224514f5e3Sopenharmony_ci{
2234514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2244514f5e3Sopenharmony_ci    Utf8JsonParser parser(thread, TransformType::NORMAL);
2254514f5e3Sopenharmony_ci
2264514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg(factory->NewFromASCII("{\"epf\":100,\"key1\":400}"));
2274514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg)); // JSON Object
2284514f5e3Sopenharmony_ci
2294514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result = parser.Parse(handleStr);
2304514f5e3Sopenharmony_ci    JSTaggedValue resultValue(static_cast<JSTaggedType>(result->GetRawData()));
2314514f5e3Sopenharmony_ci    EXPECT_TRUE(resultValue.IsECMAObject());
2324514f5e3Sopenharmony_ci
2334514f5e3Sopenharmony_ci    JSHandle<JSObject> valueHandle(thread, resultValue);
2344514f5e3Sopenharmony_ci    JSHandle<TaggedArray> nameList(JSObject::EnumerableOwnNames(thread, valueHandle));
2354514f5e3Sopenharmony_ci    JSHandle<JSArray> nameResult = JSArray::CreateArrayFromList(thread, nameList);
2364514f5e3Sopenharmony_ci
2374514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleKey(nameResult);
2384514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> lengthKey(factory->NewFromASCII("length"));
2394514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> lenResult = JSObject::GetProperty(thread, handleKey, lengthKey).GetValue();
2404514f5e3Sopenharmony_ci    uint32_t length = JSTaggedValue::ToLength(thread, lenResult).ToUint32();
2414514f5e3Sopenharmony_ci    EXPECT_EQ(length, 2U);
2424514f5e3Sopenharmony_ci}
2434514f5e3Sopenharmony_ci
2444514f5e3Sopenharmony_ci/**
2454514f5e3Sopenharmony_ci * @tc.name: Parser_006
2464514f5e3Sopenharmony_ci * @tc.desc: Try to parse a empty string.
2474514f5e3Sopenharmony_ci * @tc.type: FUNC
2484514f5e3Sopenharmony_ci * @tc.require:
2494514f5e3Sopenharmony_ci */
2504514f5e3Sopenharmony_ciHWTEST_F_L0(JsonParserTest, Parser_006)
2514514f5e3Sopenharmony_ci{
2524514f5e3Sopenharmony_ci    Utf8JsonParser parser(thread, TransformType::NORMAL);
2534514f5e3Sopenharmony_ci    JSHandle<EcmaString> emptyString(thread->GlobalConstants()->GetHandledEmptyString());
2544514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result = parser.Parse(emptyString);
2554514f5e3Sopenharmony_ci    EXPECT_TRUE(result->IsException());
2564514f5e3Sopenharmony_ci}
2574514f5e3Sopenharmony_ci
2584514f5e3Sopenharmony_ci/**
2594514f5e3Sopenharmony_ci * @tc.name: Parser_007
2604514f5e3Sopenharmony_ci * @tc.desc: Try to parse a string containing an empty string.
2614514f5e3Sopenharmony_ci * @tc.type: FUNC
2624514f5e3Sopenharmony_ci * @tc.require:
2634514f5e3Sopenharmony_ci */
2644514f5e3Sopenharmony_ciHWTEST_F_L0(JsonParserTest, Parser_007)
2654514f5e3Sopenharmony_ci{
2664514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2674514f5e3Sopenharmony_ci    Utf8JsonParser parser(thread, TransformType::NORMAL);
2684514f5e3Sopenharmony_ci
2694514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr(factory->NewFromASCII("\"\""));
2704514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result = parser.Parse(handleStr);
2714514f5e3Sopenharmony_ci    EXPECT_FALSE(result->IsException());
2724514f5e3Sopenharmony_ci}
2734514f5e3Sopenharmony_ci
2744514f5e3Sopenharmony_ci/**
2754514f5e3Sopenharmony_ci * @tc.name: Parser_008
2764514f5e3Sopenharmony_ci * @tc.desc: Try to parse a string to sendable object.
2774514f5e3Sopenharmony_ci * @tc.type: FUNC
2784514f5e3Sopenharmony_ci * @tc.require:
2794514f5e3Sopenharmony_ci */
2804514f5e3Sopenharmony_ciHWTEST_F_L0(JsonParserTest, Parser_008)
2814514f5e3Sopenharmony_ci{
2824514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2834514f5e3Sopenharmony_ci    Utf8JsonParser parser(thread, TransformType::SENDABLE);
2844514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg(
2854514f5e3Sopenharmony_ci        factory->NewFromASCII(R"({"innerEntry": {"x":1, "y":"abc", "str": "innerStr"}, "x": 1, "str": "outerStr"})"));
2864514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg));
2874514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result = parser.Parse(handleStr);
2884514f5e3Sopenharmony_ci    result->D();
2894514f5e3Sopenharmony_ci    EXPECT_FALSE(result->IsException());
2904514f5e3Sopenharmony_ci    EXPECT_TRUE(CheckSendableConstraint(result.GetTaggedValue()));
2914514f5e3Sopenharmony_ci}
2924514f5e3Sopenharmony_ci
2934514f5e3Sopenharmony_ci/**
2944514f5e3Sopenharmony_ci * @tc.name: Parser_009
2954514f5e3Sopenharmony_ci * @tc.desc: Try to parse a empty obj json string to sendable object.
2964514f5e3Sopenharmony_ci * @tc.type: FUNC
2974514f5e3Sopenharmony_ci * @tc.require:
2984514f5e3Sopenharmony_ci */
2994514f5e3Sopenharmony_ciHWTEST_F_L0(JsonParserTest, Parser_009)
3004514f5e3Sopenharmony_ci{
3014514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
3024514f5e3Sopenharmony_ci    Utf8JsonParser parser(thread, TransformType::SENDABLE);
3034514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg(factory->NewFromASCII(R"({})"));
3044514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg));
3054514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result = parser.Parse(handleStr);
3064514f5e3Sopenharmony_ci    result->D();
3074514f5e3Sopenharmony_ci    EXPECT_TRUE(CheckSendableConstraint(result.GetTaggedValue()));
3084514f5e3Sopenharmony_ci}
3094514f5e3Sopenharmony_ci
3104514f5e3Sopenharmony_ci/**
3114514f5e3Sopenharmony_ci * @tc.name: Parser_010
3124514f5e3Sopenharmony_ci * @tc.desc: Try to parse a empty array json string to sendable object.
3134514f5e3Sopenharmony_ci * @tc.type: FUNC
3144514f5e3Sopenharmony_ci * @tc.require:
3154514f5e3Sopenharmony_ci */
3164514f5e3Sopenharmony_ciHWTEST_F_L0(JsonParserTest, Parser_010)
3174514f5e3Sopenharmony_ci{
3184514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
3194514f5e3Sopenharmony_ci    Utf8JsonParser parser(thread, TransformType::SENDABLE);
3204514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg(factory->NewFromASCII(R"([])"));
3214514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg));
3224514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result = parser.Parse(handleStr);
3234514f5e3Sopenharmony_ci    result->D();
3244514f5e3Sopenharmony_ci    EXPECT_TRUE(CheckSendableConstraint(result.GetTaggedValue()));
3254514f5e3Sopenharmony_ci}
3264514f5e3Sopenharmony_ci
3274514f5e3Sopenharmony_ci/**
3284514f5e3Sopenharmony_ci * @tc.name: Parser_011
3294514f5e3Sopenharmony_ci * @tc.desc: Try to parse a simple array json string to sendable object.
3304514f5e3Sopenharmony_ci * @tc.type: FUNC
3314514f5e3Sopenharmony_ci * @tc.require:
3324514f5e3Sopenharmony_ci */
3334514f5e3Sopenharmony_ciHWTEST_F_L0(JsonParserTest, Parser_011)
3344514f5e3Sopenharmony_ci{
3354514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
3364514f5e3Sopenharmony_ci    Utf8JsonParser parser(thread, TransformType::SENDABLE);
3374514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg(factory->NewFromASCII(R"([1, 2, 3])"));
3384514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg));
3394514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result = parser.Parse(handleStr);
3404514f5e3Sopenharmony_ci    result->D();
3414514f5e3Sopenharmony_ci    EXPECT_TRUE(CheckSendableConstraint(result.GetTaggedValue()));
3424514f5e3Sopenharmony_ci}
3434514f5e3Sopenharmony_ci
3444514f5e3Sopenharmony_ci/**
3454514f5e3Sopenharmony_ci * @tc.name: Parser_012
3464514f5e3Sopenharmony_ci * @tc.desc: Try to parse a json string with array to sendable object.
3474514f5e3Sopenharmony_ci * @tc.type: FUNC
3484514f5e3Sopenharmony_ci * @tc.require:
3494514f5e3Sopenharmony_ci */
3504514f5e3Sopenharmony_ciHWTEST_F_L0(JsonParserTest, Parser_012)
3514514f5e3Sopenharmony_ci{
3524514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
3534514f5e3Sopenharmony_ci    Utf8JsonParser parser(thread, TransformType::SENDABLE);
3544514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleMsg(
3554514f5e3Sopenharmony_ci        factory->NewFromASCII(R"({"innerEntry": {"array": [1, 2, 3]}, "x": 1, "str": "outerStr"})"));
3564514f5e3Sopenharmony_ci    JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg));
3574514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> result = parser.Parse(handleStr);
3584514f5e3Sopenharmony_ci    result->D();
3594514f5e3Sopenharmony_ci    EXPECT_TRUE(CheckSendableConstraint(result.GetTaggedValue()));
3604514f5e3Sopenharmony_ci}
3614514f5e3Sopenharmony_ci} // namespace panda::test
362