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/base/json_parser.h"
17 #include "ecmascript/tests/test_helper.h"
18
19 using namespace panda::ecmascript;
20 using namespace panda::ecmascript::base;
21
22 namespace panda::test {
23 class JsonParserTest : public testing::Test {
24 public:
SetUpTestCase()25 static void SetUpTestCase()
26 {
27 GTEST_LOG_(INFO) << "SetUpTestCase";
28 }
29
TearDownTestCase()30 static void TearDownTestCase()
31 {
32 GTEST_LOG_(INFO) << "TearDownCase";
33 }
34
SetUp()35 void SetUp() override
36 {
37 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
38 }
39
TearDown()40 void TearDown() override
41 {
42 TestHelper::DestroyEcmaVMWithScope(instance, scope);
43 }
44
45 PandaVM *instance {nullptr};
46 EcmaHandleScope *scope {nullptr};
47 JSThread *thread {nullptr};
48 };
49
50 /**
51 * @tc.name: Parser_001
52 * @tc.desc: Passing in a character of type "uint8_t" check whether the result returned through "ParserUtf8" function
53 * Test without for no Nesting.
54 * @tc.type: FUNC
55 * @tc.requre:
56 */
HWTEST_F_L0(JsonParserTest,Parser_001)57 HWTEST_F_L0(JsonParserTest, Parser_001)
58 {
59 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
60 JsonParser<uint8_t> parser(thread);
61 // JSON Number
62 JSHandle<JSTaggedValue> handleMsg2(factory->NewFromCanBeCompressString("1234"));
63 JSHandle<EcmaString> handleStr2(JSTaggedValue::ToString(thread, handleMsg2));
64 JSHandle<JSTaggedValue> result2 = parser.ParseUtf8(*handleStr2);
65 EXPECT_EQ(result2->GetNumber(), 1234);
66 // JSON Literal
67 JSHandle<JSTaggedValue> handleMsg3(factory->NewFromCanBeCompressString("true"));
68 JSHandle<EcmaString> handleStr3(JSTaggedValue::ToString(thread, handleMsg3));
69 JSHandle<JSTaggedValue> result3 = parser.ParseUtf8(*handleStr3);
70 EXPECT_EQ(result3.GetTaggedValue(), JSTaggedValue::True());
71 // JSON Unexpected
72 JSHandle<JSTaggedValue> handleMsg4(factory->NewFromCanBeCompressString("trus"));
73 JSHandle<EcmaString> handleStr4(JSTaggedValue::ToString(thread, handleMsg4));
74 JSHandle<JSTaggedValue> result4 = parser.ParseUtf8(*handleStr4);
75 EXPECT_EQ(result4.GetTaggedValue(), JSTaggedValue::Exception());
76 }
77
78 /**
79 * @tc.name: Parser_002
80 * @tc.desc: Passing in a character of type "uint16_t" check whether the result returned through "ParseUtf16" function
81 * Test without for no Nesting.
82 * @tc.type: FUNC
83 * @tc.requre:
84 */
HWTEST_F_L0(JsonParserTest,Parser_002)85 HWTEST_F_L0(JsonParserTest, Parser_002)
86 {
87 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
88 JsonParser<uint16_t> parser(thread);
89
90 // JSON Number
91 uint16_t array1Utf16[] = {0x31, 0x32, 0x33, 0x34}; // "1234"
92 uint32_t array1Utf16Len = sizeof(array1Utf16) / sizeof(array1Utf16[0]);
93 JSHandle<JSTaggedValue> handleMsg2(factory->NewFromUtf16(&array1Utf16[0], array1Utf16Len));
94 JSHandle<EcmaString> handleStr2(JSTaggedValue::ToString(thread, handleMsg2));
95 JSHandle<JSTaggedValue> result2 = parser.ParseUtf16(*handleStr2);
96 EXPECT_EQ(result2->GetNumber(), 1234);
97 // JSON Literal
98 uint16_t array2Utf16[] = {0x74, 0x72, 0x75, 0x65}; // "true"
99 uint32_t array2Utf16Len = sizeof(array2Utf16) / sizeof(array2Utf16[0]);
100 JSHandle<JSTaggedValue> handleMsg3(factory->NewFromUtf16(&array2Utf16[0], array2Utf16Len));
101 JSHandle<EcmaString> handleStr3(JSTaggedValue::ToString(thread, handleMsg3));
102 JSHandle<JSTaggedValue> result3 = parser.ParseUtf16(*handleStr3);
103 EXPECT_EQ(result3.GetTaggedValue(), JSTaggedValue::True());
104 // JSON String
105 uint16_t array3Utf16[] = {0x22, 0x73, 0x74, 0x72, 0x69, 0x6E, 0X67, 0x22}; // "string"
106 uint32_t array3Utf16Len = sizeof(array3Utf16) / sizeof(array3Utf16[0]);
107 JSHandle<JSTaggedValue> handleMsg4(factory->NewFromUtf16(&array3Utf16[0], array3Utf16Len));
108 JSHandle<EcmaString> handleStr4(JSTaggedValue::ToString(thread, handleMsg4));
109 JSHandle<JSTaggedValue> result4 = parser.ParseUtf16(*handleStr4);
110 JSHandle<EcmaString> handleEcmaStr(result4);
111 EXPECT_STREQ("string", CString(handleEcmaStr->GetCString().get()).c_str());
112 }
113
114 /**
115 * @tc.name: Parser_003
116 * @tc.desc: Passing in a character of type "uint8_t" check whether the result returned through "ParserUtf8" function
117 * Test with for Nesting of numbers, strings, objects, arrays, Booleans.
118 * @tc.type: FUNC
119 * @tc.requre:
120 */
HWTEST_F_L0(JsonParserTest,Parser_003)121 HWTEST_F_L0(JsonParserTest, Parser_003)
122 {
123 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
124 JsonParser<uint8_t> parser(thread);
125
126 JSHandle<JSTaggedValue> handleMsg(factory->NewFromCanBeCompressString(
127 "\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"
128 "\n,\t\r \nnull\t\r \ntrue\t\r,123.456\t\r \n]\t\r \n}\t\r \n"));
129 JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg)); // JSON Object
130 JSHandle<JSTaggedValue> result = parser.ParseUtf8(*handleStr);
131 EXPECT_TRUE(result->IsECMAObject());
132 }
133
134 /**
135 * @tc.name: Parser_004
136 * @tc.desc: Passing in a character of type "uint8_t" check whether the result returned through "ParserUtf8" function
137 * Test with for Nesting of numbers, strings, arrays.
138 * @tc.type: FUNC
139 * @tc.requre:
140 */
HWTEST_F_L0(JsonParserTest,Parser_004)141 HWTEST_F_L0(JsonParserTest, Parser_004)
142 {
143 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
144 JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
145 JsonParser<uint8_t> parser(thread);
146
147 JSHandle<JSTaggedValue> handleMsg(factory->NewFromCanBeCompressString("[100,2.5,\"abc\"]"));
148 JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg)); // JSON Array
149 JSHandle<JSTaggedValue> result = parser.ParseUtf8(*handleStr);
150
151 JSTaggedValue resultValue(static_cast<JSTaggedType>(result->GetRawData()));
152 EXPECT_TRUE(resultValue.IsECMAObject());
153 JSHandle<JSObject> valueHandle(thread, resultValue);
154
155 JSHandle<JSTaggedValue> lenResult =
156 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle), lengthKeyHandle).GetValue();
157 uint32_t length = JSTaggedValue::ToLength(thread, lenResult).ToUint32();
158 EXPECT_EQ(length, 3);
159 }
160
161 /**
162 * @tc.name: Parser_005
163 * @tc.desc: Passing in a character of type "uint8_t" check whether the result returned through "ParserUtf8" function
164 * Test without for Nesting of numbers, strings, objects.
165 * @tc.type: FUNC
166 * @tc.requre:
167 */
HWTEST_F_L0(JsonParserTest,Parser_005)168 HWTEST_F_L0(JsonParserTest, Parser_005)
169 {
170 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
171 JsonParser<uint8_t> parser(thread);
172
173 JSHandle<JSTaggedValue> handleMsg(factory->NewFromCanBeCompressString("{\"epf\":100,\"key1\":400}"));
174 JSHandle<EcmaString> handleStr(JSTaggedValue::ToString(thread, handleMsg)); // JSON Object
175
176 JSHandle<JSTaggedValue> result = parser.ParseUtf8(*handleStr);
177 JSTaggedValue resultValue(static_cast<JSTaggedType>(result->GetRawData()));
178 EXPECT_TRUE(resultValue.IsECMAObject());
179
180 JSHandle<JSObject> valueHandle(thread, resultValue);
181 JSHandle<TaggedArray> nameList(JSObject::EnumerableOwnNames(thread, valueHandle));
182 JSHandle<JSArray> nameResult = JSArray::CreateArrayFromList(thread, nameList);
183
184 JSHandle<JSTaggedValue> handleKey(nameResult);
185 JSHandle<JSTaggedValue> lengthKey(factory->NewFromCanBeCompressString("length"));
186 JSHandle<JSTaggedValue> lenResult = JSObject::GetProperty(thread, handleKey, lengthKey).GetValue();
187 uint32_t length = JSTaggedValue::ToLength(thread, lenResult).ToUint32();
188 EXPECT_EQ(length, 2);
189 }
190 } // namespace panda::test