1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use ylong_json::{Array, JsonValue, Object};
15 
16 const RFC7159_EXAMPLE1: &str = r#"
17 {
18     "Image": {
19         "Width":  800,
20         "Height": 600,
21         "Title":  "View from 15th Floor",
22         "Thumbnail": {
23             "Url":    "http://www.example.com/image/481989943",
24             "Height": 125,
25             "Width":  100
26         },
27         "Animated" : false,
28         "IDs": [116, 943, 234, 38793]
29     }
30 }
31 "#;
32 
33 const RFC7159_EXAMPLE2: &str = r#"
34 [
35     {
36        "precision": "zip",
37        "Latitude":  37.7668,
38        "Longitude": -122.3959,
39        "Address":   "",
40        "City":      "SAN FRANCISCO",
41        "State":     "CA",
42        "Zip":       "94107",
43        "Country":   "US"
44     },
45     {
46        "precision": "zip",
47        "Latitude":  37.371991,
48        "Longitude": -122.026020,
49        "Address":   "",
50        "City":      "SUNNYVALE",
51        "State":     "CA",
52        "Zip":       "94085",
53        "Country":   "US"
54     }
55 ]
56 "#;
57 
58 const JSON_PARSE_TEST: &str = r#"
59 [
60     {
61         "null1": null
62     },
63     {
64         "boolean1": true,
65         "boolean2": false
66     },
67     {
68         "number1": 0,
69         "number2": -0,
70         "number3": 123,
71         "number4": -123,
72         "number5": 123.456,
73         "number6": -123.456,
74         "number7": 123.456e+7,
75         "number8": 123.456e-7,
76         "number9": 123.456E+7,
77         "number10": 123.456E-7,
78         "number11": -123.456e+7,
79         "number12": -123.456e-7,
80         "number13": -123.456E+7,
81         "number14": -123.456E-7,
82         "number15": 0.0,
83         "number16": -0.0e+7,
84         "number17": 3e2
85     },
86     {
87         "string1": "",
88         "string2": "Hello World",
89         "string3": "abcdefghijklmnopqrstuvwxyz",
90         "string4": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
91         "string5": "0123456789",
92         "string6": " \b\f\n\r\t",
93         "string7": "\"\\\/",
94         "string8": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
95         "string9": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A"
96     },
97     {
98         "array1": [],
99         "array2": [
100                                      ],
101         "array3": [null,true,0.0,"string",[],{}],
102         "array4": [
103                 null                    ,               true,           0.0           ,
104         "string",                            []
105                              ,        {}   ],
106         "array5": [[[[[[["nest"]]]]]]]
107     },
108     {
109         "object1": {},
110         "object2": {
111                                                    },
112         "object3": {"key1":null,"key2":true,"key3":0.0,"key4":"string","key5":[],"key6":{}},
113         "object4": {
114                 "key1"                :                 null   ,       "key2"
115                            :                  true     ,            "key3"         :
116          0.0      ,      "key4":"string"            ,
117                        "key5":                [],          "key6":            {
118                                        }
119         },
120         "object5": {"nest1": {"nest2": {"nest3": {"nest4": {}}}}}
121     },
122     {
123         "": "key1",
124         "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" : "key2"
125     },
126     {
127                                     "key_value1"
128                             :                        "value"
129                 ,         "key_value2"     :           [
130                       ]             ,                     "key_value3"                  :
131                       {}
132     }
133 ]
134 "#;
135 
136 macro_rules! rfc7159_example1_check {
137     ($json: expr) => {
138         assert_eq!($json["Image"]["Width"], 800.into());
139         assert_eq!($json["Image"]["Height"], 600.into());
140         assert_eq!($json["Image"]["Title"], "View from 15th Floor".into());
141         assert_eq!(
142             $json["Image"]["Thumbnail"]["Url"],
143             "http://www.example.com/image/481989943".into()
144         );
145         assert_eq!($json["Image"]["Thumbnail"]["Height"], 125.into());
146         assert_eq!($json["Image"]["Thumbnail"]["Width"], 100.into());
147         assert_eq!($json["Image"]["Animated"], false.into());
148         assert_eq!($json["Image"]["IDs"][0], 116.into());
149         assert_eq!($json["Image"]["IDs"][1], 943.into());
150         assert_eq!($json["Image"]["IDs"][2], 234.into());
151         assert_eq!($json["Image"]["IDs"][3], 38793.into());
152     };
153 }
154 
155 macro_rules! rfc7159_example2_check {
156     ($json: expr) => {
157         assert_eq!($json[0]["precision"], "zip".into());
158         assert_eq!($json[0]["Latitude"], 37.7668.into());
159         assert_eq!($json[0]["Longitude"], (-122.3959).into());
160         assert_eq!($json[0]["Address"], "".into());
161         assert_eq!($json[0]["City"], "SAN FRANCISCO".into());
162         assert_eq!($json[0]["State"], "CA".into());
163         assert_eq!($json[0]["Zip"], "94107".into());
164         assert_eq!($json[0]["Country"], "US".into());
165         assert_eq!($json[1]["precision"], "zip".into());
166         assert_eq!($json[1]["Latitude"], 37.371991.into());
167         assert_eq!($json[1]["Longitude"], (-122.026020).into());
168         assert_eq!($json[1]["Address"], "".into());
169         assert_eq!($json[1]["City"], "SUNNYVALE".into());
170         assert_eq!($json[1]["State"], "CA".into());
171         assert_eq!($json[1]["Zip"], "94085".into());
172         assert_eq!($json[1]["Country"], "US".into());
173     };
174 }
175 
176 macro_rules! json_parse_test_check {
177     ($json: expr) => {
178         assert_eq!($json[0]["null1"], JsonValue::new_null());
179         assert_eq!($json[1]["boolean1"], true.into());
180         assert_eq!($json[1]["boolean2"], false.into());
181         assert_eq!($json[2]["number1"], 0.into());
182         assert_eq!($json[2]["number2"], 0.into());
183         assert_eq!($json[2]["number3"], 123.into());
184         assert_eq!($json[2]["number4"], (-123).into());
185         assert_eq!($json[2]["number5"], 123.456.into());
186         assert_eq!($json[2]["number6"], (-123.456).into());
187         assert_eq!($json[2]["number7"], 1234560000.into());
188         assert_eq!($json[2]["number8"], 0.0000123456.into());
189         assert_eq!($json[2]["number9"], 1234560000.into());
190         assert_eq!($json[2]["number10"], 0.0000123456.into());
191         assert_eq!($json[2]["number11"], (-1234560000).into());
192         assert_eq!($json[2]["number12"], (-0.0000123456).into());
193         assert_eq!($json[2]["number13"], (-1234560000).into());
194         assert_eq!($json[2]["number14"], (-0.0000123456).into());
195         assert_eq!($json[2]["number15"], 0.into());
196         assert_eq!($json[2]["number16"], 0.into());
197         assert_eq!($json[2]["number17"], 300.into());
198         assert_eq!($json[3]["string1"], "".into());
199         assert_eq!($json[3]["string2"], "Hello World".into());
200         assert_eq!($json[3]["string3"], "abcdefghijklmnopqrstuvwxyz".into());
201         assert_eq!($json[3]["string4"], "ABCDEFGHIJKLMNOPQRSTUVWXYZ".into());
202         assert_eq!($json[3]["string5"], "0123456789".into());
203         assert_eq!($json[3]["string6"], " \u{0008}\u{000c}\n\r\t".into());
204         assert_eq!($json[3]["string7"], "\"\\/".into());
205         assert_eq!($json[3]["string8"], "`1~!@#$%^&*()_+-={':[,]}|;.</>?".into());
206         assert_eq!($json[3]["string9"], "\u{0123}\u{4567}\u{89AB}\u{CDEF}\u{abcd}\u{ef4A}".into());
207         assert_eq!($json[4]["array1"], Array::new().into());
208         assert_eq!($json[4]["array2"], Array::new().into());
209         assert_eq!($json[4]["array3"][0], JsonValue::new_null());
210         assert_eq!($json[4]["array3"][1], true.into());
211         assert_eq!($json[4]["array3"][2], 0.into());
212         assert_eq!($json[4]["array3"][3], "string".into());
213         assert_eq!($json[4]["array3"][4], Array::new().into());
214         assert_eq!($json[4]["array3"][5], Object::new().into());
215         assert_eq!($json[4]["array4"][0], JsonValue::new_null());
216         assert_eq!($json[4]["array4"][1], true.into());
217         assert_eq!($json[4]["array4"][2], 0.into());
218         assert_eq!($json[4]["array4"][3], "string".into());
219         assert_eq!($json[4]["array4"][4], Array::new().into());
220         assert_eq!($json[4]["array4"][5], Object::new().into());
221         assert_eq!($json[4]["array5"][0][0][0][0][0][0][0], "nest".into());
222         assert_eq!($json[5]["object1"], Object::new().into());
223         assert_eq!($json[5]["object2"], Object::new().into());
224         assert_eq!($json[5]["object3"]["key1"], JsonValue::new_null());
225         assert_eq!($json[5]["object3"]["key2"], true.into());
226         assert_eq!($json[5]["object3"]["key3"], 0.into());
227         assert_eq!($json[5]["object3"]["key4"], "string".into());
228         assert_eq!($json[5]["object3"]["key5"], Array::new().into());
229         assert_eq!($json[5]["object3"]["key6"], Object::new().into());
230         assert_eq!($json[5]["object4"]["key1"], JsonValue::new_null());
231         assert_eq!($json[5]["object4"]["key2"], true.into());
232         assert_eq!($json[5]["object4"]["key3"], 0.into());
233         assert_eq!($json[5]["object4"]["key4"], "string".into());
234         assert_eq!($json[5]["object4"]["key5"], Array::new().into());
235         assert_eq!($json[5]["object4"]["key6"], Object::new().into());
236         assert_eq!($json[5]["object5"]["nest1"]["nest2"]["nest3"]["nest4"], Object::new().into());
237         assert_eq!($json[6][""], "key1".into());
238         assert_eq!(
239             $json[6]["/\\\"\u{CAFE}\u{BABE}\u{AB98}\u{FCDE}\u{bcda}\u{ef4A}\u{0008}\u{000c}\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"],
240             "key2".into()
241         );
242         assert_eq!($json[7]["key_value1"], "value".into());
243         assert_eq!($json[7]["key_value2"], Array::new().into());
244         assert_eq!($json[7]["key_value3"], Object::new().into());
245     }
246 }
247 
248 /*
249  * @title  ylong_json sdv 测试用例
250  * @design 使用路径覆盖
251  * @precon 无
252  * @brief  1. 准备一个 json 文本
253  *         2. 根据该文本创建一个 Json 实例
254  *         3. 修改该实例中的值
255  *         4. 以字符串形式输出到指定位置
256  *         5. 校验输出结果
257  * @expect 1. 得到预期输出的字符串。
258  * @auto   是
259  */
260 #[test]
sdv_ylong_json()261 fn sdv_ylong_json() {
262     sdv_json_parse();
263     sdv_json_modify();
264     sdv_json_output();
265 }
266 
sdv_json_parse()267 fn sdv_json_parse() {
268     // 测试 RFC7159 13. Examples 里的两个 json 文本。
269     let json = JsonValue::from_text(RFC7159_EXAMPLE1).unwrap();
270     rfc7159_example1_check!(json);
271 
272     let json = JsonValue::from_text(RFC7159_EXAMPLE2).unwrap();
273     rfc7159_example2_check!(json);
274 
275     let json = JsonValue::from_text(JSON_PARSE_TEST).unwrap();
276     json_parse_test_check!(json);
277 }
278 
sdv_json_modify()279 fn sdv_json_modify() {
280     let json_text = "{}";
281     let mut json = JsonValue::from_text(json_text).unwrap();
282     // 初始时 json 为空。
283     assert!(json.try_as_object().unwrap().is_empty());
284 
285     json["null"] = JsonValue::new_null();
286     json["boolean"] = true.into();
287     json["number"] = 123.into();
288     json["string"] = "Hello World".into();
289     json["array"] = Array::new().into();
290     json["object"] = Object::new().into();
291 
292     assert!(json["null"].is_null());
293     assert_eq!(json["boolean"], true.into());
294     assert_eq!(json["number"], 123.into());
295     assert_eq!(json["string"], "Hello World".into());
296     assert_eq!(json["array"], Array::new().into());
297     assert_eq!(json["object"], Object::new().into());
298     assert_eq!(json.try_as_object().unwrap().len(), 6);
299 
300     json["array"][0] = 123.into();
301     json["array"][1] = "string".into();
302     json["array"][2] = JsonValue::new_null();
303 
304     assert_eq!(json["array"][0], 123.into());
305     assert_eq!(json["array"][1], "string".into());
306     assert_eq!(json["array"][2], JsonValue::new_null());
307     assert_eq!(json["array"].try_as_array().unwrap().len(), 3);
308 
309     json["array"] = Array::new().into();
310     assert_eq!(json["array"].try_as_array().unwrap().len(), 0);
311 
312     json["object"]["number"] = 123.into();
313     json["object"]["string"] = "string".into();
314     json["object"]["null"] = JsonValue::new_null();
315 
316     assert_eq!(json["object"]["number"], 123.into());
317     assert_eq!(json["object"]["string"], "string".into());
318     assert_eq!(json["object"]["null"], JsonValue::new_null());
319     assert_eq!(json["object"].try_as_object().unwrap().len(), 3);
320 
321     json["object"] = Object::new().into();
322     assert_eq!(json["object"].try_as_object().unwrap().len(), 0);
323 }
324 
325 #[allow(unused_assignments)]
sdv_json_output()326 fn sdv_json_output() {
327     const LOOPS_NUM: usize = 1000;
328 
329     let mut json = JsonValue::from_text(RFC7159_EXAMPLE1).unwrap();
330     let mut vec = Vec::new();
331 
332     for _ in 0..LOOPS_NUM {
333         // 将 json 内容写入 vec 中
334         vec.clear();
335         assert!(json.formatted_encode(&mut vec).is_ok());
336 
337         // 通过 vec 重新生成一个 json 实例
338         let temp = JsonValue::from_text(&vec).unwrap();
339 
340         // 比较内容是否发生变化
341         rfc7159_example1_check!(temp);
342 
343         json = temp;
344     }
345 
346     let mut json = JsonValue::from_text(RFC7159_EXAMPLE2).unwrap();
347     let mut vec = Vec::new();
348 
349     for _ in 0..LOOPS_NUM {
350         // 将 json 内容写入 vec 中
351         vec.clear();
352         assert!(json.formatted_encode(&mut vec).is_ok());
353 
354         // 通过 vec 重新生成一个 json 实例
355         let temp = JsonValue::from_text(&vec).unwrap();
356 
357         // 比较内容是否发生变化
358         rfc7159_example2_check!(temp);
359 
360         json = temp;
361     }
362 
363     let mut json = JsonValue::from_text(JSON_PARSE_TEST).unwrap();
364     let mut vec = Vec::new();
365 
366     for _ in 0..LOOPS_NUM {
367         // 将 json 内容写入 vec 中
368         vec.clear();
369         assert!(json.formatted_encode(&mut vec).is_ok());
370 
371         // 通过 vec 重新生成一个 json 实例
372         let temp = JsonValue::from_text(&vec).unwrap();
373 
374         // 比较内容是否发生变化
375         json_parse_test_check!(temp);
376 
377         json = temp;
378     }
379 }
380