]>
Commit | Line | Data |
---|---|---|
e1599b0c XL |
1 | #![allow(rustc::internal)] |
2 | ||
9fa01778 | 3 | use json::DecoderError::*; |
dfeec247 XL |
4 | use json::ErrorCode::*; |
5 | use json::Json::*; | |
9fa01778 | 6 | use json::JsonEvent::*; |
dfeec247 XL |
7 | use json::ParserError::*; |
8 | use json::{ | |
9 | from_str, DecodeResult, Decoder, DecoderError, Encoder, EncoderError, Json, JsonEvent, Parser, | |
10 | StackElement, | |
11 | }; | |
3dfed10e | 12 | use rustc_macros::{Decodable, Encodable}; |
dfeec247 XL |
13 | use rustc_serialize::json; |
14 | use rustc_serialize::{Decodable, Encodable}; | |
9fa01778 | 15 | |
9fa01778 | 16 | use std::collections::BTreeMap; |
dfeec247 | 17 | use std::io::prelude::*; |
9fa01778 | 18 | use std::string; |
dfeec247 | 19 | use Animal::*; |
9fa01778 | 20 | |
3dfed10e | 21 | #[derive(Decodable, Eq, PartialEq, Debug)] |
9fa01778 XL |
22 | struct OptionData { |
23 | opt: Option<usize>, | |
24 | } | |
25 | ||
26 | #[test] | |
27 | fn test_decode_option_none() { | |
dfeec247 | 28 | let s = "{}"; |
9fa01778 XL |
29 | let obj: OptionData = json::decode(s).unwrap(); |
30 | assert_eq!(obj, OptionData { opt: None }); | |
31 | } | |
32 | ||
33 | #[test] | |
34 | fn test_decode_option_some() { | |
35 | let s = "{ \"opt\": 10 }"; | |
36 | let obj: OptionData = json::decode(s).unwrap(); | |
37 | assert_eq!(obj, OptionData { opt: Some(10) }); | |
38 | } | |
39 | ||
40 | #[test] | |
41 | fn test_decode_option_malformed() { | |
dfeec247 XL |
42 | check_err::<OptionData>( |
43 | "{ \"opt\": [] }", | |
44 | ExpectedError("Number".to_string(), "[]".to_string()), | |
45 | ); | |
46 | check_err::<OptionData>( | |
47 | "{ \"opt\": false }", | |
48 | ExpectedError("Number".to_string(), "false".to_string()), | |
49 | ); | |
9fa01778 XL |
50 | } |
51 | ||
3dfed10e | 52 | #[derive(PartialEq, Encodable, Decodable, Debug)] |
9fa01778 XL |
53 | enum Animal { |
54 | Dog, | |
dfeec247 | 55 | Frog(string::String, isize), |
9fa01778 XL |
56 | } |
57 | ||
3dfed10e | 58 | #[derive(PartialEq, Encodable, Decodable, Debug)] |
9fa01778 XL |
59 | struct Inner { |
60 | a: (), | |
61 | b: usize, | |
62 | c: Vec<string::String>, | |
63 | } | |
64 | ||
3dfed10e | 65 | #[derive(PartialEq, Encodable, Decodable, Debug)] |
9fa01778 XL |
66 | struct Outer { |
67 | inner: Vec<Inner>, | |
68 | } | |
69 | ||
70 | fn mk_object(items: &[(string::String, Json)]) -> Json { | |
71 | let mut d = BTreeMap::new(); | |
72 | ||
73 | for item in items { | |
74 | match *item { | |
dfeec247 XL |
75 | (ref key, ref value) => { |
76 | d.insert((*key).clone(), (*value).clone()); | |
77 | } | |
9fa01778 | 78 | } |
dfeec247 | 79 | } |
9fa01778 XL |
80 | |
81 | Object(d) | |
82 | } | |
83 | ||
84 | #[test] | |
85 | fn test_from_str_trait() { | |
86 | let s = "null"; | |
87 | assert!(s.parse::<Json>().unwrap() == s.parse().unwrap()); | |
88 | } | |
89 | ||
90 | #[test] | |
91 | fn test_write_null() { | |
92 | assert_eq!(Null.to_string(), "null"); | |
93 | assert_eq!(Null.pretty().to_string(), "null"); | |
94 | } | |
95 | ||
96 | #[test] | |
97 | fn test_write_i64() { | |
98 | assert_eq!(U64(0).to_string(), "0"); | |
99 | assert_eq!(U64(0).pretty().to_string(), "0"); | |
100 | ||
101 | assert_eq!(U64(1234).to_string(), "1234"); | |
102 | assert_eq!(U64(1234).pretty().to_string(), "1234"); | |
103 | ||
104 | assert_eq!(I64(-5678).to_string(), "-5678"); | |
105 | assert_eq!(I64(-5678).pretty().to_string(), "-5678"); | |
106 | ||
107 | assert_eq!(U64(7650007200025252000).to_string(), "7650007200025252000"); | |
108 | assert_eq!(U64(7650007200025252000).pretty().to_string(), "7650007200025252000"); | |
109 | } | |
110 | ||
111 | #[test] | |
112 | fn test_write_f64() { | |
113 | assert_eq!(F64(3.0).to_string(), "3.0"); | |
114 | assert_eq!(F64(3.0).pretty().to_string(), "3.0"); | |
115 | ||
116 | assert_eq!(F64(3.1).to_string(), "3.1"); | |
117 | assert_eq!(F64(3.1).pretty().to_string(), "3.1"); | |
118 | ||
119 | assert_eq!(F64(-1.5).to_string(), "-1.5"); | |
120 | assert_eq!(F64(-1.5).pretty().to_string(), "-1.5"); | |
121 | ||
122 | assert_eq!(F64(0.5).to_string(), "0.5"); | |
123 | assert_eq!(F64(0.5).pretty().to_string(), "0.5"); | |
124 | ||
125 | assert_eq!(F64(f64::NAN).to_string(), "null"); | |
126 | assert_eq!(F64(f64::NAN).pretty().to_string(), "null"); | |
127 | ||
128 | assert_eq!(F64(f64::INFINITY).to_string(), "null"); | |
129 | assert_eq!(F64(f64::INFINITY).pretty().to_string(), "null"); | |
130 | ||
131 | assert_eq!(F64(f64::NEG_INFINITY).to_string(), "null"); | |
132 | assert_eq!(F64(f64::NEG_INFINITY).pretty().to_string(), "null"); | |
133 | } | |
134 | ||
135 | #[test] | |
136 | fn test_write_str() { | |
137 | assert_eq!(String("".to_string()).to_string(), "\"\""); | |
138 | assert_eq!(String("".to_string()).pretty().to_string(), "\"\""); | |
139 | ||
140 | assert_eq!(String("homura".to_string()).to_string(), "\"homura\""); | |
141 | assert_eq!(String("madoka".to_string()).pretty().to_string(), "\"madoka\""); | |
142 | } | |
143 | ||
144 | #[test] | |
145 | fn test_write_bool() { | |
146 | assert_eq!(Boolean(true).to_string(), "true"); | |
147 | assert_eq!(Boolean(true).pretty().to_string(), "true"); | |
148 | ||
149 | assert_eq!(Boolean(false).to_string(), "false"); | |
150 | assert_eq!(Boolean(false).pretty().to_string(), "false"); | |
151 | } | |
152 | ||
153 | #[test] | |
154 | fn test_write_array() { | |
155 | assert_eq!(Array(vec![]).to_string(), "[]"); | |
156 | assert_eq!(Array(vec![]).pretty().to_string(), "[]"); | |
157 | ||
158 | assert_eq!(Array(vec![Boolean(true)]).to_string(), "[true]"); | |
159 | assert_eq!( | |
160 | Array(vec![Boolean(true)]).pretty().to_string(), | |
161 | "\ | |
162 | [\n \ | |
163 | true\n\ | |
164 | ]" | |
165 | ); | |
166 | ||
dfeec247 XL |
167 | let long_test_array = |
168 | Array(vec![Boolean(false), Null, Array(vec![String("foo\nbar".to_string()), F64(3.5)])]); | |
9fa01778 | 169 | |
dfeec247 | 170 | assert_eq!(long_test_array.to_string(), "[false,null,[\"foo\\nbar\",3.5]]"); |
9fa01778 XL |
171 | assert_eq!( |
172 | long_test_array.pretty().to_string(), | |
173 | "\ | |
174 | [\n \ | |
175 | false,\n \ | |
176 | null,\n \ | |
177 | [\n \ | |
178 | \"foo\\nbar\",\n \ | |
179 | 3.5\n \ | |
180 | ]\n\ | |
181 | ]" | |
182 | ); | |
183 | } | |
184 | ||
185 | #[test] | |
186 | fn test_write_object() { | |
187 | assert_eq!(mk_object(&[]).to_string(), "{}"); | |
188 | assert_eq!(mk_object(&[]).pretty().to_string(), "{}"); | |
189 | ||
dfeec247 | 190 | assert_eq!(mk_object(&[("a".to_string(), Boolean(true))]).to_string(), "{\"a\":true}"); |
9fa01778 XL |
191 | assert_eq!( |
192 | mk_object(&[("a".to_string(), Boolean(true))]).pretty().to_string(), | |
193 | "\ | |
194 | {\n \ | |
195 | \"a\": true\n\ | |
196 | }" | |
197 | ); | |
198 | ||
dfeec247 XL |
199 | let complex_obj = mk_object(&[( |
200 | "b".to_string(), | |
201 | Array(vec![ | |
202 | mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), | |
203 | mk_object(&[("d".to_string(), String("".to_string()))]), | |
204 | ]), | |
205 | )]); | |
9fa01778 XL |
206 | |
207 | assert_eq!( | |
208 | complex_obj.to_string(), | |
209 | "{\ | |
210 | \"b\":[\ | |
211 | {\"c\":\"\\f\\r\"},\ | |
212 | {\"d\":\"\"}\ | |
213 | ]\ | |
214 | }" | |
215 | ); | |
216 | assert_eq!( | |
217 | complex_obj.pretty().to_string(), | |
218 | "\ | |
219 | {\n \ | |
220 | \"b\": [\n \ | |
221 | {\n \ | |
222 | \"c\": \"\\f\\r\"\n \ | |
223 | },\n \ | |
224 | {\n \ | |
225 | \"d\": \"\"\n \ | |
226 | }\n \ | |
227 | ]\n\ | |
228 | }" | |
229 | ); | |
230 | ||
231 | let a = mk_object(&[ | |
232 | ("a".to_string(), Boolean(true)), | |
dfeec247 XL |
233 | ( |
234 | "b".to_string(), | |
235 | Array(vec![ | |
236 | mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), | |
237 | mk_object(&[("d".to_string(), String("".to_string()))]), | |
238 | ]), | |
239 | ), | |
9fa01778 XL |
240 | ]); |
241 | ||
242 | // We can't compare the strings directly because the object fields be | |
243 | // printed in a different order. | |
244 | assert_eq!(a.clone(), a.to_string().parse().unwrap()); | |
245 | assert_eq!(a.clone(), a.pretty().to_string().parse().unwrap()); | |
246 | } | |
247 | ||
248 | #[test] | |
249 | fn test_write_enum() { | |
250 | let animal = Dog; | |
dfeec247 XL |
251 | assert_eq!(json::as_json(&animal).to_string(), "\"Dog\""); |
252 | assert_eq!(json::as_pretty_json(&animal).to_string(), "\"Dog\""); | |
9fa01778 XL |
253 | |
254 | let animal = Frog("Henry".to_string(), 349); | |
255 | assert_eq!( | |
256 | json::as_json(&animal).to_string(), | |
257 | "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}" | |
258 | ); | |
259 | assert_eq!( | |
260 | json::as_pretty_json(&animal).to_string(), | |
261 | "{\n \ | |
262 | \"variant\": \"Frog\",\n \ | |
263 | \"fields\": [\n \ | |
264 | \"Henry\",\n \ | |
265 | 349\n \ | |
266 | ]\n\ | |
267 | }" | |
268 | ); | |
269 | } | |
270 | ||
271 | macro_rules! check_encoder_for_simple { | |
dfeec247 | 272 | ($value:expr, $expected:expr) => {{ |
9fa01778 XL |
273 | let s = json::as_json(&$value).to_string(); |
274 | assert_eq!(s, $expected); | |
275 | ||
276 | let s = json::as_pretty_json(&$value).to_string(); | |
277 | assert_eq!(s, $expected); | |
dfeec247 | 278 | }}; |
9fa01778 XL |
279 | } |
280 | ||
281 | #[test] | |
282 | fn test_write_some() { | |
283 | check_encoder_for_simple!(Some("jodhpurs".to_string()), "\"jodhpurs\""); | |
284 | } | |
285 | ||
286 | #[test] | |
287 | fn test_write_none() { | |
288 | check_encoder_for_simple!(None::<string::String>, "null"); | |
289 | } | |
290 | ||
291 | #[test] | |
292 | fn test_write_char() { | |
293 | check_encoder_for_simple!('a', "\"a\""); | |
294 | check_encoder_for_simple!('\t', "\"\\t\""); | |
295 | check_encoder_for_simple!('\u{0000}', "\"\\u0000\""); | |
296 | check_encoder_for_simple!('\u{001b}', "\"\\u001b\""); | |
297 | check_encoder_for_simple!('\u{007f}', "\"\\u007f\""); | |
298 | check_encoder_for_simple!('\u{00a0}', "\"\u{00a0}\""); | |
299 | check_encoder_for_simple!('\u{abcd}', "\"\u{abcd}\""); | |
300 | check_encoder_for_simple!('\u{10ffff}', "\"\u{10ffff}\""); | |
301 | } | |
302 | ||
303 | #[test] | |
304 | fn test_trailing_characters() { | |
dfeec247 XL |
305 | assert_eq!(from_str("nulla"), Err(SyntaxError(TrailingCharacters, 1, 5))); |
306 | assert_eq!(from_str("truea"), Err(SyntaxError(TrailingCharacters, 1, 5))); | |
9fa01778 | 307 | assert_eq!(from_str("falsea"), Err(SyntaxError(TrailingCharacters, 1, 6))); |
dfeec247 XL |
308 | assert_eq!(from_str("1a"), Err(SyntaxError(TrailingCharacters, 1, 2))); |
309 | assert_eq!(from_str("[]a"), Err(SyntaxError(TrailingCharacters, 1, 3))); | |
310 | assert_eq!(from_str("{}a"), Err(SyntaxError(TrailingCharacters, 1, 3))); | |
9fa01778 XL |
311 | } |
312 | ||
313 | #[test] | |
314 | fn test_read_identifiers() { | |
dfeec247 XL |
315 | assert_eq!(from_str("n"), Err(SyntaxError(InvalidSyntax, 1, 2))); |
316 | assert_eq!(from_str("nul"), Err(SyntaxError(InvalidSyntax, 1, 4))); | |
317 | assert_eq!(from_str("t"), Err(SyntaxError(InvalidSyntax, 1, 2))); | |
9fa01778 | 318 | assert_eq!(from_str("truz"), Err(SyntaxError(InvalidSyntax, 1, 4))); |
dfeec247 XL |
319 | assert_eq!(from_str("f"), Err(SyntaxError(InvalidSyntax, 1, 2))); |
320 | assert_eq!(from_str("faz"), Err(SyntaxError(InvalidSyntax, 1, 3))); | |
9fa01778 XL |
321 | |
322 | assert_eq!(from_str("null"), Ok(Null)); | |
323 | assert_eq!(from_str("true"), Ok(Boolean(true))); | |
324 | assert_eq!(from_str("false"), Ok(Boolean(false))); | |
325 | assert_eq!(from_str(" null "), Ok(Null)); | |
326 | assert_eq!(from_str(" true "), Ok(Boolean(true))); | |
327 | assert_eq!(from_str(" false "), Ok(Boolean(false))); | |
328 | } | |
329 | ||
330 | #[test] | |
331 | fn test_decode_identifiers() { | |
332 | let v: () = json::decode("null").unwrap(); | |
333 | assert_eq!(v, ()); | |
334 | ||
335 | let v: bool = json::decode("true").unwrap(); | |
336 | assert_eq!(v, true); | |
337 | ||
338 | let v: bool = json::decode("false").unwrap(); | |
339 | assert_eq!(v, false); | |
340 | } | |
341 | ||
342 | #[test] | |
343 | fn test_read_number() { | |
dfeec247 XL |
344 | assert_eq!(from_str("+"), Err(SyntaxError(InvalidSyntax, 1, 1))); |
345 | assert_eq!(from_str("."), Err(SyntaxError(InvalidSyntax, 1, 1))); | |
9fa01778 | 346 | assert_eq!(from_str("NaN"), Err(SyntaxError(InvalidSyntax, 1, 1))); |
dfeec247 XL |
347 | assert_eq!(from_str("-"), Err(SyntaxError(InvalidNumber, 1, 2))); |
348 | assert_eq!(from_str("00"), Err(SyntaxError(InvalidNumber, 1, 2))); | |
349 | assert_eq!(from_str("1."), Err(SyntaxError(InvalidNumber, 1, 3))); | |
350 | assert_eq!(from_str("1e"), Err(SyntaxError(InvalidNumber, 1, 3))); | |
9fa01778 XL |
351 | assert_eq!(from_str("1e+"), Err(SyntaxError(InvalidNumber, 1, 4))); |
352 | ||
353 | assert_eq!(from_str("18446744073709551616"), Err(SyntaxError(InvalidNumber, 1, 20))); | |
354 | assert_eq!(from_str("-9223372036854775809"), Err(SyntaxError(InvalidNumber, 1, 21))); | |
355 | ||
356 | assert_eq!(from_str("3"), Ok(U64(3))); | |
357 | assert_eq!(from_str("3.1"), Ok(F64(3.1))); | |
358 | assert_eq!(from_str("-1.2"), Ok(F64(-1.2))); | |
359 | assert_eq!(from_str("0.4"), Ok(F64(0.4))); | |
360 | assert_eq!(from_str("0.4e5"), Ok(F64(0.4e5))); | |
361 | assert_eq!(from_str("0.4e+15"), Ok(F64(0.4e15))); | |
362 | assert_eq!(from_str("0.4e-01"), Ok(F64(0.4e-01))); | |
363 | assert_eq!(from_str(" 3 "), Ok(U64(3))); | |
364 | ||
365 | assert_eq!(from_str("-9223372036854775808"), Ok(I64(i64::MIN))); | |
366 | assert_eq!(from_str("9223372036854775807"), Ok(U64(i64::MAX as u64))); | |
367 | assert_eq!(from_str("18446744073709551615"), Ok(U64(u64::MAX))); | |
368 | } | |
369 | ||
370 | #[test] | |
371 | fn test_decode_numbers() { | |
372 | let v: f64 = json::decode("3").unwrap(); | |
373 | assert_eq!(v, 3.0); | |
374 | ||
375 | let v: f64 = json::decode("3.1").unwrap(); | |
376 | assert_eq!(v, 3.1); | |
377 | ||
378 | let v: f64 = json::decode("-1.2").unwrap(); | |
379 | assert_eq!(v, -1.2); | |
380 | ||
381 | let v: f64 = json::decode("0.4").unwrap(); | |
382 | assert_eq!(v, 0.4); | |
383 | ||
384 | let v: f64 = json::decode("0.4e5").unwrap(); | |
385 | assert_eq!(v, 0.4e5); | |
386 | ||
387 | let v: f64 = json::decode("0.4e15").unwrap(); | |
388 | assert_eq!(v, 0.4e15); | |
389 | ||
390 | let v: f64 = json::decode("0.4e-01").unwrap(); | |
391 | assert_eq!(v, 0.4e-01); | |
392 | ||
393 | let v: u64 = json::decode("0").unwrap(); | |
394 | assert_eq!(v, 0); | |
395 | ||
396 | let v: u64 = json::decode("18446744073709551615").unwrap(); | |
397 | assert_eq!(v, u64::MAX); | |
398 | ||
399 | let v: i64 = json::decode("-9223372036854775808").unwrap(); | |
400 | assert_eq!(v, i64::MIN); | |
401 | ||
402 | let v: i64 = json::decode("9223372036854775807").unwrap(); | |
403 | assert_eq!(v, i64::MAX); | |
404 | ||
405 | let res: DecodeResult<i64> = json::decode("765.25"); | |
dfeec247 | 406 | assert_eq!(res, Err(ExpectedError("Integer".to_string(), "765.25".to_string()))); |
9fa01778 XL |
407 | } |
408 | ||
409 | #[test] | |
410 | fn test_read_str() { | |
dfeec247 | 411 | assert_eq!(from_str("\""), Err(SyntaxError(EOFWhileParsingString, 1, 2))); |
9fa01778 XL |
412 | assert_eq!(from_str("\"lol"), Err(SyntaxError(EOFWhileParsingString, 1, 5))); |
413 | ||
414 | assert_eq!(from_str("\"\""), Ok(String("".to_string()))); | |
415 | assert_eq!(from_str("\"foo\""), Ok(String("foo".to_string()))); | |
416 | assert_eq!(from_str("\"\\\"\""), Ok(String("\"".to_string()))); | |
417 | assert_eq!(from_str("\"\\b\""), Ok(String("\x08".to_string()))); | |
418 | assert_eq!(from_str("\"\\n\""), Ok(String("\n".to_string()))); | |
419 | assert_eq!(from_str("\"\\r\""), Ok(String("\r".to_string()))); | |
420 | assert_eq!(from_str("\"\\t\""), Ok(String("\t".to_string()))); | |
421 | assert_eq!(from_str(" \"foo\" "), Ok(String("foo".to_string()))); | |
422 | assert_eq!(from_str("\"\\u12ab\""), Ok(String("\u{12ab}".to_string()))); | |
423 | assert_eq!(from_str("\"\\uAB12\""), Ok(String("\u{AB12}".to_string()))); | |
424 | } | |
425 | ||
426 | #[test] | |
427 | fn test_decode_str() { | |
dfeec247 XL |
428 | let s = [ |
429 | ("\"\"", ""), | |
430 | ("\"foo\"", "foo"), | |
431 | ("\"\\\"\"", "\""), | |
432 | ("\"\\b\"", "\x08"), | |
433 | ("\"\\n\"", "\n"), | |
434 | ("\"\\r\"", "\r"), | |
435 | ("\"\\t\"", "\t"), | |
436 | ("\"\\u12ab\"", "\u{12ab}"), | |
437 | ("\"\\uAB12\"", "\u{AB12}"), | |
438 | ]; | |
9fa01778 XL |
439 | |
440 | for &(i, o) in &s { | |
441 | let v: string::String = json::decode(i).unwrap(); | |
442 | assert_eq!(v, o); | |
443 | } | |
444 | } | |
445 | ||
446 | #[test] | |
447 | fn test_read_array() { | |
dfeec247 XL |
448 | assert_eq!(from_str("["), Err(SyntaxError(EOFWhileParsingValue, 1, 2))); |
449 | assert_eq!(from_str("[1"), Err(SyntaxError(EOFWhileParsingArray, 1, 3))); | |
450 | assert_eq!(from_str("[1,"), Err(SyntaxError(EOFWhileParsingValue, 1, 4))); | |
451 | assert_eq!(from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4))); | |
452 | assert_eq!(from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4))); | |
9fa01778 XL |
453 | |
454 | assert_eq!(from_str("[]"), Ok(Array(vec![]))); | |
455 | assert_eq!(from_str("[ ]"), Ok(Array(vec![]))); | |
456 | assert_eq!(from_str("[true]"), Ok(Array(vec![Boolean(true)]))); | |
457 | assert_eq!(from_str("[ false ]"), Ok(Array(vec![Boolean(false)]))); | |
458 | assert_eq!(from_str("[null]"), Ok(Array(vec![Null]))); | |
dfeec247 XL |
459 | assert_eq!(from_str("[3, 1]"), Ok(Array(vec![U64(3), U64(1)]))); |
460 | assert_eq!(from_str("\n[3, 2]\n"), Ok(Array(vec![U64(3), U64(2)]))); | |
461 | assert_eq!(from_str("[2, [4, 1]]"), Ok(Array(vec![U64(2), Array(vec![U64(4), U64(1)])]))); | |
9fa01778 XL |
462 | } |
463 | ||
464 | #[test] | |
465 | fn test_decode_array() { | |
466 | let v: Vec<()> = json::decode("[]").unwrap(); | |
467 | assert_eq!(v, []); | |
468 | ||
469 | let v: Vec<()> = json::decode("[null]").unwrap(); | |
470 | assert_eq!(v, [()]); | |
471 | ||
472 | let v: Vec<bool> = json::decode("[true]").unwrap(); | |
473 | assert_eq!(v, [true]); | |
474 | ||
475 | let v: Vec<isize> = json::decode("[3, 1]").unwrap(); | |
476 | assert_eq!(v, [3, 1]); | |
477 | ||
478 | let v: Vec<Vec<usize>> = json::decode("[[3], [1, 2]]").unwrap(); | |
479 | assert_eq!(v, [vec![3], vec![1, 2]]); | |
480 | } | |
481 | ||
482 | #[test] | |
483 | fn test_decode_tuple() { | |
484 | let t: (usize, usize, usize) = json::decode("[1, 2, 3]").unwrap(); | |
485 | assert_eq!(t, (1, 2, 3)); | |
486 | ||
487 | let t: (usize, string::String) = json::decode("[1, \"two\"]").unwrap(); | |
488 | assert_eq!(t, (1, "two".to_string())); | |
489 | } | |
490 | ||
491 | #[test] | |
492 | fn test_decode_tuple_malformed_types() { | |
493 | assert!(json::decode::<(usize, string::String)>("[1, 2]").is_err()); | |
494 | } | |
495 | ||
496 | #[test] | |
497 | fn test_decode_tuple_malformed_length() { | |
498 | assert!(json::decode::<(usize, usize)>("[1, 2, 3]").is_err()); | |
499 | } | |
500 | ||
501 | #[test] | |
502 | fn test_read_object() { | |
dfeec247 XL |
503 | assert_eq!(from_str("{"), Err(SyntaxError(EOFWhileParsingObject, 1, 2))); |
504 | assert_eq!(from_str("{ "), Err(SyntaxError(EOFWhileParsingObject, 1, 3))); | |
505 | assert_eq!(from_str("{1"), Err(SyntaxError(KeyMustBeAString, 1, 2))); | |
9fa01778 | 506 | assert_eq!(from_str("{ \"a\""), Err(SyntaxError(EOFWhileParsingObject, 1, 6))); |
dfeec247 | 507 | assert_eq!(from_str("{\"a\""), Err(SyntaxError(EOFWhileParsingObject, 1, 5))); |
9fa01778 XL |
508 | assert_eq!(from_str("{\"a\" "), Err(SyntaxError(EOFWhileParsingObject, 1, 6))); |
509 | ||
dfeec247 XL |
510 | assert_eq!(from_str("{\"a\" 1"), Err(SyntaxError(ExpectedColon, 1, 6))); |
511 | assert_eq!(from_str("{\"a\":"), Err(SyntaxError(EOFWhileParsingValue, 1, 6))); | |
512 | assert_eq!(from_str("{\"a\":1"), Err(SyntaxError(EOFWhileParsingObject, 1, 7))); | |
513 | assert_eq!(from_str("{\"a\":1 1"), Err(SyntaxError(InvalidSyntax, 1, 8))); | |
514 | assert_eq!(from_str("{\"a\":1,"), Err(SyntaxError(EOFWhileParsingObject, 1, 8))); | |
9fa01778 XL |
515 | |
516 | assert_eq!(from_str("{}").unwrap(), mk_object(&[])); | |
dfeec247 XL |
517 | assert_eq!(from_str("{\"a\": 3}").unwrap(), mk_object(&[("a".to_string(), U64(3))])); |
518 | ||
519 | assert_eq!( | |
520 | from_str("{ \"a\": null, \"b\" : true }").unwrap(), | |
521 | mk_object(&[("a".to_string(), Null), ("b".to_string(), Boolean(true))]) | |
522 | ); | |
523 | assert_eq!( | |
524 | from_str("\n{ \"a\": null, \"b\" : true }\n").unwrap(), | |
525 | mk_object(&[("a".to_string(), Null), ("b".to_string(), Boolean(true))]) | |
526 | ); | |
527 | assert_eq!( | |
528 | from_str("{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(), | |
529 | mk_object(&[("a".to_string(), F64(1.0)), ("b".to_string(), Array(vec![Boolean(true)]))]) | |
530 | ); | |
531 | assert_eq!( | |
532 | from_str( | |
533 | "{\ | |
9fa01778 XL |
534 | \"a\": 1.0, \ |
535 | \"b\": [\ | |
536 | true,\ | |
537 | \"foo\\nbar\", \ | |
538 | { \"c\": {\"d\": null} } \ | |
539 | ]\ | |
dfeec247 XL |
540 | }" |
541 | ) | |
542 | .unwrap(), | |
543 | mk_object(&[ | |
544 | ("a".to_string(), F64(1.0)), | |
545 | ( | |
546 | "b".to_string(), | |
547 | Array(vec![ | |
548 | Boolean(true), | |
549 | String("foo\nbar".to_string()), | |
550 | mk_object(&[("c".to_string(), mk_object(&[("d".to_string(), Null)]))]) | |
551 | ]) | |
552 | ) | |
553 | ]) | |
554 | ); | |
9fa01778 XL |
555 | } |
556 | ||
557 | #[test] | |
558 | fn test_decode_struct() { | |
559 | let s = "{ | |
560 | \"inner\": [ | |
561 | { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] } | |
562 | ] | |
563 | }"; | |
564 | ||
565 | let v: Outer = json::decode(s).unwrap(); | |
566 | assert_eq!( | |
567 | v, | |
dfeec247 | 568 | Outer { inner: vec![Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] }] } |
9fa01778 XL |
569 | ); |
570 | } | |
571 | ||
3dfed10e | 572 | #[derive(Decodable)] |
9fa01778 XL |
573 | struct FloatStruct { |
574 | f: f64, | |
dfeec247 | 575 | a: Vec<f64>, |
9fa01778 XL |
576 | } |
577 | #[test] | |
578 | fn test_decode_struct_with_nan() { | |
579 | let s = "{\"f\":null,\"a\":[null,123]}"; | |
580 | let obj: FloatStruct = json::decode(s).unwrap(); | |
581 | assert!(obj.f.is_nan()); | |
582 | assert!(obj.a[0].is_nan()); | |
583 | assert_eq!(obj.a[1], 123f64); | |
584 | } | |
585 | ||
586 | #[test] | |
587 | fn test_decode_option() { | |
588 | let value: Option<string::String> = json::decode("null").unwrap(); | |
589 | assert_eq!(value, None); | |
590 | ||
591 | let value: Option<string::String> = json::decode("\"jodhpurs\"").unwrap(); | |
592 | assert_eq!(value, Some("jodhpurs".to_string())); | |
593 | } | |
594 | ||
595 | #[test] | |
596 | fn test_decode_enum() { | |
597 | let value: Animal = json::decode("\"Dog\"").unwrap(); | |
598 | assert_eq!(value, Dog); | |
599 | ||
600 | let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"; | |
601 | let value: Animal = json::decode(s).unwrap(); | |
602 | assert_eq!(value, Frog("Henry".to_string(), 349)); | |
603 | } | |
604 | ||
605 | #[test] | |
606 | fn test_decode_map() { | |
607 | let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\ | |
608 | \"fields\":[\"Henry\", 349]}}"; | |
609 | let mut map: BTreeMap<string::String, Animal> = json::decode(s).unwrap(); | |
610 | ||
611 | assert_eq!(map.remove(&"a".to_string()), Some(Dog)); | |
612 | assert_eq!(map.remove(&"b".to_string()), Some(Frog("Henry".to_string(), 349))); | |
613 | } | |
614 | ||
615 | #[test] | |
616 | fn test_multiline_errors() { | |
dfeec247 | 617 | assert_eq!(from_str("{\n \"foo\":\n \"bar\""), Err(SyntaxError(EOFWhileParsingObject, 3, 8))); |
9fa01778 XL |
618 | } |
619 | ||
3dfed10e | 620 | #[derive(Decodable)] |
9fa01778 XL |
621 | #[allow(dead_code)] |
622 | struct DecodeStruct { | |
623 | x: f64, | |
624 | y: bool, | |
625 | z: string::String, | |
dfeec247 | 626 | w: Vec<DecodeStruct>, |
9fa01778 | 627 | } |
3dfed10e | 628 | #[derive(Decodable)] |
9fa01778 XL |
629 | enum DecodeEnum { |
630 | A(f64), | |
dfeec247 | 631 | B(string::String), |
9fa01778 | 632 | } |
3dfed10e | 633 | fn check_err<T: Decodable<Decoder>>(to_parse: &'static str, expected: DecoderError) { |
9fa01778 XL |
634 | let res: DecodeResult<T> = match from_str(to_parse) { |
635 | Err(e) => Err(ParseError(e)), | |
dfeec247 | 636 | Ok(json) => Decodable::decode(&mut Decoder::new(json)), |
9fa01778 XL |
637 | }; |
638 | match res { | |
dfeec247 XL |
639 | Ok(_) => panic!("`{:?}` parsed & decoded ok, expecting error `{:?}`", to_parse, expected), |
640 | Err(ParseError(e)) => panic!("`{:?}` is not valid json: {:?}", to_parse, e), | |
9fa01778 XL |
641 | Err(e) => { |
642 | assert_eq!(e, expected); | |
643 | } | |
644 | } | |
645 | } | |
646 | #[test] | |
647 | fn test_decode_errors_struct() { | |
648 | check_err::<DecodeStruct>("[]", ExpectedError("Object".to_string(), "[]".to_string())); | |
dfeec247 XL |
649 | check_err::<DecodeStruct>( |
650 | "{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}", | |
651 | ExpectedError("Number".to_string(), "true".to_string()), | |
652 | ); | |
653 | check_err::<DecodeStruct>( | |
654 | "{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}", | |
655 | ExpectedError("Boolean".to_string(), "[]".to_string()), | |
656 | ); | |
657 | check_err::<DecodeStruct>( | |
658 | "{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}", | |
659 | ExpectedError("String".to_string(), "{}".to_string()), | |
660 | ); | |
661 | check_err::<DecodeStruct>( | |
662 | "{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}", | |
663 | ExpectedError("Array".to_string(), "null".to_string()), | |
664 | ); | |
665 | check_err::<DecodeStruct>( | |
666 | "{\"x\": 1, \"y\": true, \"z\": \"\"}", | |
667 | MissingFieldError("w".to_string()), | |
668 | ); | |
9fa01778 XL |
669 | } |
670 | #[test] | |
671 | fn test_decode_errors_enum() { | |
dfeec247 XL |
672 | check_err::<DecodeEnum>("{}", MissingFieldError("variant".to_string())); |
673 | check_err::<DecodeEnum>( | |
674 | "{\"variant\": 1}", | |
675 | ExpectedError("String".to_string(), "1".to_string()), | |
676 | ); | |
677 | check_err::<DecodeEnum>("{\"variant\": \"A\"}", MissingFieldError("fields".to_string())); | |
678 | check_err::<DecodeEnum>( | |
679 | "{\"variant\": \"A\", \"fields\": null}", | |
680 | ExpectedError("Array".to_string(), "null".to_string()), | |
681 | ); | |
682 | check_err::<DecodeEnum>( | |
683 | "{\"variant\": \"C\", \"fields\": []}", | |
684 | UnknownVariantError("C".to_string()), | |
685 | ); | |
9fa01778 XL |
686 | } |
687 | ||
688 | #[test] | |
dfeec247 | 689 | fn test_find() { |
9fa01778 XL |
690 | let json_value = from_str("{\"dog\" : \"cat\"}").unwrap(); |
691 | let found_str = json_value.find("dog"); | |
692 | assert!(found_str.unwrap().as_string().unwrap() == "cat"); | |
693 | } | |
694 | ||
695 | #[test] | |
dfeec247 | 696 | fn test_find_path() { |
9fa01778 XL |
697 | let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); |
698 | let found_str = json_value.find_path(&["dog", "cat", "mouse"]); | |
699 | assert!(found_str.unwrap().as_string().unwrap() == "cheese"); | |
700 | } | |
701 | ||
702 | #[test] | |
dfeec247 | 703 | fn test_search() { |
9fa01778 XL |
704 | let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); |
705 | let found_str = json_value.search("mouse").and_then(|j| j.as_string()); | |
706 | assert!(found_str.unwrap() == "cheese"); | |
707 | } | |
708 | ||
709 | #[test] | |
dfeec247 | 710 | fn test_index() { |
9fa01778 XL |
711 | let json_value = from_str("{\"animals\":[\"dog\",\"cat\",\"mouse\"]}").unwrap(); |
712 | let ref array = json_value["animals"]; | |
713 | assert_eq!(array[0].as_string().unwrap(), "dog"); | |
714 | assert_eq!(array[1].as_string().unwrap(), "cat"); | |
715 | assert_eq!(array[2].as_string().unwrap(), "mouse"); | |
716 | } | |
717 | ||
718 | #[test] | |
dfeec247 | 719 | fn test_is_object() { |
9fa01778 XL |
720 | let json_value = from_str("{}").unwrap(); |
721 | assert!(json_value.is_object()); | |
722 | } | |
723 | ||
724 | #[test] | |
dfeec247 | 725 | fn test_as_object() { |
9fa01778 XL |
726 | let json_value = from_str("{}").unwrap(); |
727 | let json_object = json_value.as_object(); | |
728 | assert!(json_object.is_some()); | |
729 | } | |
730 | ||
731 | #[test] | |
dfeec247 | 732 | fn test_is_array() { |
9fa01778 XL |
733 | let json_value = from_str("[1, 2, 3]").unwrap(); |
734 | assert!(json_value.is_array()); | |
735 | } | |
736 | ||
737 | #[test] | |
dfeec247 | 738 | fn test_as_array() { |
9fa01778 XL |
739 | let json_value = from_str("[1, 2, 3]").unwrap(); |
740 | let json_array = json_value.as_array(); | |
741 | let expected_length = 3; | |
742 | assert!(json_array.is_some() && json_array.unwrap().len() == expected_length); | |
743 | } | |
744 | ||
745 | #[test] | |
dfeec247 | 746 | fn test_is_string() { |
9fa01778 XL |
747 | let json_value = from_str("\"dog\"").unwrap(); |
748 | assert!(json_value.is_string()); | |
749 | } | |
750 | ||
751 | #[test] | |
dfeec247 | 752 | fn test_as_string() { |
9fa01778 XL |
753 | let json_value = from_str("\"dog\"").unwrap(); |
754 | let json_str = json_value.as_string(); | |
755 | let expected_str = "dog"; | |
756 | assert_eq!(json_str, Some(expected_str)); | |
757 | } | |
758 | ||
759 | #[test] | |
dfeec247 | 760 | fn test_is_number() { |
9fa01778 XL |
761 | let json_value = from_str("12").unwrap(); |
762 | assert!(json_value.is_number()); | |
763 | } | |
764 | ||
765 | #[test] | |
dfeec247 | 766 | fn test_is_i64() { |
9fa01778 XL |
767 | let json_value = from_str("-12").unwrap(); |
768 | assert!(json_value.is_i64()); | |
769 | ||
770 | let json_value = from_str("12").unwrap(); | |
771 | assert!(!json_value.is_i64()); | |
772 | ||
773 | let json_value = from_str("12.0").unwrap(); | |
774 | assert!(!json_value.is_i64()); | |
775 | } | |
776 | ||
777 | #[test] | |
dfeec247 | 778 | fn test_is_u64() { |
9fa01778 XL |
779 | let json_value = from_str("12").unwrap(); |
780 | assert!(json_value.is_u64()); | |
781 | ||
782 | let json_value = from_str("-12").unwrap(); | |
783 | assert!(!json_value.is_u64()); | |
784 | ||
785 | let json_value = from_str("12.0").unwrap(); | |
786 | assert!(!json_value.is_u64()); | |
787 | } | |
788 | ||
789 | #[test] | |
dfeec247 | 790 | fn test_is_f64() { |
9fa01778 XL |
791 | let json_value = from_str("12").unwrap(); |
792 | assert!(!json_value.is_f64()); | |
793 | ||
794 | let json_value = from_str("-12").unwrap(); | |
795 | assert!(!json_value.is_f64()); | |
796 | ||
797 | let json_value = from_str("12.0").unwrap(); | |
798 | assert!(json_value.is_f64()); | |
799 | ||
800 | let json_value = from_str("-12.0").unwrap(); | |
801 | assert!(json_value.is_f64()); | |
802 | } | |
803 | ||
804 | #[test] | |
dfeec247 | 805 | fn test_as_i64() { |
9fa01778 XL |
806 | let json_value = from_str("-12").unwrap(); |
807 | let json_num = json_value.as_i64(); | |
808 | assert_eq!(json_num, Some(-12)); | |
809 | } | |
810 | ||
811 | #[test] | |
dfeec247 | 812 | fn test_as_u64() { |
9fa01778 XL |
813 | let json_value = from_str("12").unwrap(); |
814 | let json_num = json_value.as_u64(); | |
815 | assert_eq!(json_num, Some(12)); | |
816 | } | |
817 | ||
818 | #[test] | |
dfeec247 | 819 | fn test_as_f64() { |
9fa01778 XL |
820 | let json_value = from_str("12.0").unwrap(); |
821 | let json_num = json_value.as_f64(); | |
822 | assert_eq!(json_num, Some(12f64)); | |
823 | } | |
824 | ||
825 | #[test] | |
dfeec247 | 826 | fn test_is_boolean() { |
9fa01778 XL |
827 | let json_value = from_str("false").unwrap(); |
828 | assert!(json_value.is_boolean()); | |
829 | } | |
830 | ||
831 | #[test] | |
dfeec247 | 832 | fn test_as_boolean() { |
9fa01778 XL |
833 | let json_value = from_str("false").unwrap(); |
834 | let json_bool = json_value.as_boolean(); | |
835 | let expected_bool = false; | |
836 | assert!(json_bool.is_some() && json_bool.unwrap() == expected_bool); | |
837 | } | |
838 | ||
839 | #[test] | |
dfeec247 | 840 | fn test_is_null() { |
9fa01778 XL |
841 | let json_value = from_str("null").unwrap(); |
842 | assert!(json_value.is_null()); | |
843 | } | |
844 | ||
845 | #[test] | |
dfeec247 | 846 | fn test_as_null() { |
9fa01778 XL |
847 | let json_value = from_str("null").unwrap(); |
848 | let json_null = json_value.as_null(); | |
849 | let expected_null = (); | |
850 | assert!(json_null.is_some() && json_null.unwrap() == expected_null); | |
851 | } | |
852 | ||
853 | #[test] | |
854 | fn test_encode_hashmap_with_numeric_key() { | |
9fa01778 | 855 | use std::collections::HashMap; |
dfeec247 | 856 | use std::str::from_utf8; |
9fa01778 XL |
857 | let mut hm: HashMap<usize, bool> = HashMap::new(); |
858 | hm.insert(1, true); | |
859 | let mut mem_buf = Vec::new(); | |
860 | write!(&mut mem_buf, "{}", json::as_pretty_json(&hm)).unwrap(); | |
861 | let json_str = from_utf8(&mem_buf[..]).unwrap(); | |
862 | match from_str(json_str) { | |
863 | Err(_) => panic!("Unable to parse json_str: {:?}", json_str), | |
864 | _ => {} // it parsed and we are good to go | |
865 | } | |
866 | } | |
867 | ||
868 | #[test] | |
869 | fn test_prettyencode_hashmap_with_numeric_key() { | |
9fa01778 | 870 | use std::collections::HashMap; |
dfeec247 | 871 | use std::str::from_utf8; |
9fa01778 XL |
872 | let mut hm: HashMap<usize, bool> = HashMap::new(); |
873 | hm.insert(1, true); | |
874 | let mut mem_buf = Vec::new(); | |
875 | write!(&mut mem_buf, "{}", json::as_pretty_json(&hm)).unwrap(); | |
876 | let json_str = from_utf8(&mem_buf[..]).unwrap(); | |
877 | match from_str(json_str) { | |
878 | Err(_) => panic!("Unable to parse json_str: {:?}", json_str), | |
879 | _ => {} // it parsed and we are good to go | |
880 | } | |
881 | } | |
882 | ||
883 | #[test] | |
884 | fn test_prettyencoder_indent_level_param() { | |
9fa01778 | 885 | use std::collections::BTreeMap; |
dfeec247 | 886 | use std::str::from_utf8; |
9fa01778 XL |
887 | |
888 | let mut tree = BTreeMap::new(); | |
889 | ||
890 | tree.insert("hello".to_string(), String("guten tag".to_string())); | |
891 | tree.insert("goodbye".to_string(), String("sayonara".to_string())); | |
892 | ||
893 | let json = Array( | |
894 | // The following layout below should look a lot like | |
895 | // the pretty-printed JSON (indent * x) | |
dfeec247 XL |
896 | vec![ |
897 | // 0x | |
9fa01778 | 898 | String("greetings".to_string()), // 1x |
dfeec247 XL |
899 | Object(tree), // 1x + 2x + 2x + 1x |
900 | ], // 0x | |
901 | // End JSON array (7 lines) | |
9fa01778 XL |
902 | ); |
903 | ||
904 | // Helper function for counting indents | |
905 | fn indents(source: &str) -> usize { | |
906 | let trimmed = source.trim_start_matches(' '); | |
907 | source.len() - trimmed.len() | |
908 | } | |
909 | ||
910 | // Test up to 4 spaces of indents (more?) | |
911 | for i in 0..4 { | |
912 | let mut writer = Vec::new(); | |
dfeec247 | 913 | write!(&mut writer, "{}", json::as_pretty_json(&json).indent(i)).unwrap(); |
9fa01778 XL |
914 | |
915 | let printed = from_utf8(&writer[..]).unwrap(); | |
916 | ||
917 | // Check for indents at each line | |
918 | let lines: Vec<&str> = printed.lines().collect(); | |
919 | assert_eq!(lines.len(), 7); // JSON should be 7 lines | |
920 | ||
921 | assert_eq!(indents(lines[0]), 0 * i); // [ | |
922 | assert_eq!(indents(lines[1]), 1 * i); // "greetings", | |
923 | assert_eq!(indents(lines[2]), 1 * i); // { | |
924 | assert_eq!(indents(lines[3]), 2 * i); // "hello": "guten tag", | |
925 | assert_eq!(indents(lines[4]), 2 * i); // "goodbye": "sayonara" | |
926 | assert_eq!(indents(lines[5]), 1 * i); // }, | |
927 | assert_eq!(indents(lines[6]), 0 * i); // ] | |
928 | ||
929 | // Finally, test that the pretty-printed JSON is valid | |
930 | from_str(printed).ok().expect("Pretty-printed JSON is invalid!"); | |
931 | } | |
932 | } | |
933 | ||
934 | #[test] | |
935 | fn test_hashmap_with_enum_key() { | |
936 | use std::collections::HashMap; | |
3dfed10e | 937 | #[derive(Encodable, Eq, Hash, PartialEq, Decodable, Debug)] |
9fa01778 XL |
938 | enum Enum { |
939 | Foo, | |
940 | #[allow(dead_code)] | |
941 | Bar, | |
942 | } | |
943 | let mut map = HashMap::new(); | |
944 | map.insert(Enum::Foo, 0); | |
945 | let result = json::encode(&map).unwrap(); | |
946 | assert_eq!(&result[..], r#"{"Foo":0}"#); | |
947 | let decoded: HashMap<Enum, _> = json::decode(&result).unwrap(); | |
948 | assert_eq!(map, decoded); | |
949 | } | |
950 | ||
951 | #[test] | |
952 | fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() { | |
953 | use std::collections::HashMap; | |
954 | let json_str = "{\"1\":true}"; | |
955 | let json_obj = match from_str(json_str) { | |
956 | Err(_) => panic!("Unable to parse json_str: {:?}", json_str), | |
dfeec247 | 957 | Ok(o) => o, |
9fa01778 XL |
958 | }; |
959 | let mut decoder = Decoder::new(json_obj); | |
960 | let _hm: HashMap<usize, bool> = Decodable::decode(&mut decoder).unwrap(); | |
961 | } | |
962 | ||
963 | #[test] | |
964 | fn test_hashmap_with_numeric_key_will_error_with_string_keys() { | |
965 | use std::collections::HashMap; | |
966 | let json_str = "{\"a\":true}"; | |
967 | let json_obj = match from_str(json_str) { | |
968 | Err(_) => panic!("Unable to parse json_str: {:?}", json_str), | |
dfeec247 | 969 | Ok(o) => o, |
9fa01778 XL |
970 | }; |
971 | let mut decoder = Decoder::new(json_obj); | |
972 | let result: Result<HashMap<usize, bool>, DecoderError> = Decodable::decode(&mut decoder); | |
973 | assert_eq!(result, Err(ExpectedError("Number".to_string(), "a".to_string()))); | |
974 | } | |
975 | ||
dfeec247 | 976 | fn assert_stream_equal(src: &str, expected: Vec<(JsonEvent, Vec<StackElement<'_>>)>) { |
9fa01778 XL |
977 | let mut parser = Parser::new(src.chars()); |
978 | let mut i = 0; | |
979 | loop { | |
980 | let evt = match parser.next() { | |
981 | Some(e) => e, | |
dfeec247 XL |
982 | None => { |
983 | break; | |
984 | } | |
9fa01778 XL |
985 | }; |
986 | let (ref expected_evt, ref expected_stack) = expected[i]; | |
987 | if !parser.stack().is_equal_to(expected_stack) { | |
988 | panic!("Parser stack is not equal to {:?}", expected_stack); | |
989 | } | |
990 | assert_eq!(&evt, expected_evt); | |
dfeec247 | 991 | i += 1; |
9fa01778 XL |
992 | } |
993 | } | |
994 | #[test] | |
995 | fn test_streaming_parser() { | |
996 | assert_stream_equal( | |
997 | r#"{ "foo":"bar", "array" : [0, 1, 2, 3, 4, 5], "idents":[null,true,false]}"#, | |
998 | vec![ | |
dfeec247 XL |
999 | (ObjectStart, vec![]), |
1000 | (StringValue("bar".to_string()), vec![StackElement::Key("foo")]), | |
1001 | (ArrayStart, vec![StackElement::Key("array")]), | |
1002 | (U64Value(0), vec![StackElement::Key("array"), StackElement::Index(0)]), | |
1003 | (U64Value(1), vec![StackElement::Key("array"), StackElement::Index(1)]), | |
1004 | (U64Value(2), vec![StackElement::Key("array"), StackElement::Index(2)]), | |
1005 | (U64Value(3), vec![StackElement::Key("array"), StackElement::Index(3)]), | |
1006 | (U64Value(4), vec![StackElement::Key("array"), StackElement::Index(4)]), | |
1007 | (U64Value(5), vec![StackElement::Key("array"), StackElement::Index(5)]), | |
1008 | (ArrayEnd, vec![StackElement::Key("array")]), | |
1009 | (ArrayStart, vec![StackElement::Key("idents")]), | |
1010 | (NullValue, vec![StackElement::Key("idents"), StackElement::Index(0)]), | |
1011 | (BooleanValue(true), vec![StackElement::Key("idents"), StackElement::Index(1)]), | |
1012 | (BooleanValue(false), vec![StackElement::Key("idents"), StackElement::Index(2)]), | |
1013 | (ArrayEnd, vec![StackElement::Key("idents")]), | |
1014 | (ObjectEnd, vec![]), | |
1015 | ], | |
9fa01778 XL |
1016 | ); |
1017 | } | |
1018 | fn last_event(src: &str) -> JsonEvent { | |
1019 | let mut parser = Parser::new(src.chars()); | |
1020 | let mut evt = NullValue; | |
1021 | loop { | |
1022 | evt = match parser.next() { | |
1023 | Some(e) => e, | |
1024 | None => return evt, | |
1025 | } | |
1026 | } | |
1027 | } | |
1028 | ||
1029 | #[test] | |
1030 | fn test_read_object_streaming() { | |
dfeec247 XL |
1031 | assert_eq!(last_event("{ "), Error(SyntaxError(EOFWhileParsingObject, 1, 3))); |
1032 | assert_eq!(last_event("{1"), Error(SyntaxError(KeyMustBeAString, 1, 2))); | |
9fa01778 | 1033 | assert_eq!(last_event("{ \"a\""), Error(SyntaxError(EOFWhileParsingObject, 1, 6))); |
dfeec247 | 1034 | assert_eq!(last_event("{\"a\""), Error(SyntaxError(EOFWhileParsingObject, 1, 5))); |
9fa01778 XL |
1035 | assert_eq!(last_event("{\"a\" "), Error(SyntaxError(EOFWhileParsingObject, 1, 6))); |
1036 | ||
dfeec247 XL |
1037 | assert_eq!(last_event("{\"a\" 1"), Error(SyntaxError(ExpectedColon, 1, 6))); |
1038 | assert_eq!(last_event("{\"a\":"), Error(SyntaxError(EOFWhileParsingValue, 1, 6))); | |
1039 | assert_eq!(last_event("{\"a\":1"), Error(SyntaxError(EOFWhileParsingObject, 1, 7))); | |
1040 | assert_eq!(last_event("{\"a\":1 1"), Error(SyntaxError(InvalidSyntax, 1, 8))); | |
1041 | assert_eq!(last_event("{\"a\":1,"), Error(SyntaxError(EOFWhileParsingObject, 1, 8))); | |
9fa01778 XL |
1042 | assert_eq!(last_event("{\"a\":1,}"), Error(SyntaxError(TrailingComma, 1, 8))); |
1043 | ||
dfeec247 | 1044 | assert_stream_equal("{}", vec![(ObjectStart, vec![]), (ObjectEnd, vec![])]); |
9fa01778 XL |
1045 | assert_stream_equal( |
1046 | "{\"a\": 3}", | |
1047 | vec![ | |
dfeec247 XL |
1048 | (ObjectStart, vec![]), |
1049 | (U64Value(3), vec![StackElement::Key("a")]), | |
1050 | (ObjectEnd, vec![]), | |
1051 | ], | |
9fa01778 XL |
1052 | ); |
1053 | assert_stream_equal( | |
1054 | "{ \"a\": null, \"b\" : true }", | |
1055 | vec![ | |
dfeec247 XL |
1056 | (ObjectStart, vec![]), |
1057 | (NullValue, vec![StackElement::Key("a")]), | |
1058 | (BooleanValue(true), vec![StackElement::Key("b")]), | |
1059 | (ObjectEnd, vec![]), | |
1060 | ], | |
9fa01778 XL |
1061 | ); |
1062 | assert_stream_equal( | |
1063 | "{\"a\" : 1.0 ,\"b\": [ true ]}", | |
1064 | vec![ | |
dfeec247 XL |
1065 | (ObjectStart, vec![]), |
1066 | (F64Value(1.0), vec![StackElement::Key("a")]), | |
1067 | (ArrayStart, vec![StackElement::Key("b")]), | |
1068 | (BooleanValue(true), vec![StackElement::Key("b"), StackElement::Index(0)]), | |
1069 | (ArrayEnd, vec![StackElement::Key("b")]), | |
1070 | (ObjectEnd, vec![]), | |
1071 | ], | |
9fa01778 XL |
1072 | ); |
1073 | assert_stream_equal( | |
1074 | r#"{ | |
1075 | "a": 1.0, | |
1076 | "b": [ | |
1077 | true, | |
1078 | "foo\nbar", | |
1079 | { "c": {"d": null} } | |
1080 | ] | |
1081 | }"#, | |
1082 | vec![ | |
dfeec247 XL |
1083 | (ObjectStart, vec![]), |
1084 | (F64Value(1.0), vec![StackElement::Key("a")]), | |
1085 | (ArrayStart, vec![StackElement::Key("b")]), | |
1086 | (BooleanValue(true), vec![StackElement::Key("b"), StackElement::Index(0)]), | |
1087 | ( | |
1088 | StringValue("foo\nbar".to_string()), | |
1089 | vec![StackElement::Key("b"), StackElement::Index(1)], | |
1090 | ), | |
1091 | (ObjectStart, vec![StackElement::Key("b"), StackElement::Index(2)]), | |
1092 | ( | |
1093 | ObjectStart, | |
1094 | vec![StackElement::Key("b"), StackElement::Index(2), StackElement::Key("c")], | |
1095 | ), | |
1096 | ( | |
1097 | NullValue, | |
1098 | vec![ | |
1099 | StackElement::Key("b"), | |
1100 | StackElement::Index(2), | |
1101 | StackElement::Key("c"), | |
1102 | StackElement::Key("d"), | |
1103 | ], | |
1104 | ), | |
1105 | ( | |
1106 | ObjectEnd, | |
1107 | vec![StackElement::Key("b"), StackElement::Index(2), StackElement::Key("c")], | |
1108 | ), | |
1109 | (ObjectEnd, vec![StackElement::Key("b"), StackElement::Index(2)]), | |
1110 | (ArrayEnd, vec![StackElement::Key("b")]), | |
1111 | (ObjectEnd, vec![]), | |
1112 | ], | |
9fa01778 XL |
1113 | ); |
1114 | } | |
1115 | #[test] | |
1116 | fn test_read_array_streaming() { | |
dfeec247 XL |
1117 | assert_stream_equal("[]", vec![(ArrayStart, vec![]), (ArrayEnd, vec![])]); |
1118 | assert_stream_equal("[ ]", vec![(ArrayStart, vec![]), (ArrayEnd, vec![])]); | |
9fa01778 XL |
1119 | assert_stream_equal( |
1120 | "[true]", | |
1121 | vec![ | |
dfeec247 XL |
1122 | (ArrayStart, vec![]), |
1123 | (BooleanValue(true), vec![StackElement::Index(0)]), | |
1124 | (ArrayEnd, vec![]), | |
1125 | ], | |
9fa01778 XL |
1126 | ); |
1127 | assert_stream_equal( | |
1128 | "[ false ]", | |
1129 | vec![ | |
dfeec247 XL |
1130 | (ArrayStart, vec![]), |
1131 | (BooleanValue(false), vec![StackElement::Index(0)]), | |
1132 | (ArrayEnd, vec![]), | |
1133 | ], | |
9fa01778 XL |
1134 | ); |
1135 | assert_stream_equal( | |
1136 | "[null]", | |
dfeec247 | 1137 | vec![(ArrayStart, vec![]), (NullValue, vec![StackElement::Index(0)]), (ArrayEnd, vec![])], |
9fa01778 XL |
1138 | ); |
1139 | assert_stream_equal( | |
1140 | "[3, 1]", | |
1141 | vec![ | |
dfeec247 XL |
1142 | (ArrayStart, vec![]), |
1143 | (U64Value(3), vec![StackElement::Index(0)]), | |
1144 | (U64Value(1), vec![StackElement::Index(1)]), | |
1145 | (ArrayEnd, vec![]), | |
1146 | ], | |
9fa01778 XL |
1147 | ); |
1148 | assert_stream_equal( | |
1149 | "\n[3, 2]\n", | |
1150 | vec![ | |
dfeec247 XL |
1151 | (ArrayStart, vec![]), |
1152 | (U64Value(3), vec![StackElement::Index(0)]), | |
1153 | (U64Value(2), vec![StackElement::Index(1)]), | |
1154 | (ArrayEnd, vec![]), | |
1155 | ], | |
9fa01778 XL |
1156 | ); |
1157 | assert_stream_equal( | |
1158 | "[2, [4, 1]]", | |
1159 | vec![ | |
dfeec247 XL |
1160 | (ArrayStart, vec![]), |
1161 | (U64Value(2), vec![StackElement::Index(0)]), | |
1162 | (ArrayStart, vec![StackElement::Index(1)]), | |
1163 | (U64Value(4), vec![StackElement::Index(1), StackElement::Index(0)]), | |
1164 | (U64Value(1), vec![StackElement::Index(1), StackElement::Index(1)]), | |
1165 | (ArrayEnd, vec![StackElement::Index(1)]), | |
1166 | (ArrayEnd, vec![]), | |
1167 | ], | |
9fa01778 XL |
1168 | ); |
1169 | ||
dfeec247 | 1170 | assert_eq!(last_event("["), Error(SyntaxError(EOFWhileParsingValue, 1, 2))); |
9fa01778 | 1171 | |
dfeec247 XL |
1172 | assert_eq!(from_str("["), Err(SyntaxError(EOFWhileParsingValue, 1, 2))); |
1173 | assert_eq!(from_str("[1"), Err(SyntaxError(EOFWhileParsingArray, 1, 3))); | |
1174 | assert_eq!(from_str("[1,"), Err(SyntaxError(EOFWhileParsingValue, 1, 4))); | |
1175 | assert_eq!(from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4))); | |
1176 | assert_eq!(from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4))); | |
9fa01778 XL |
1177 | } |
1178 | #[test] | |
1179 | fn test_trailing_characters_streaming() { | |
dfeec247 XL |
1180 | assert_eq!(last_event("nulla"), Error(SyntaxError(TrailingCharacters, 1, 5))); |
1181 | assert_eq!(last_event("truea"), Error(SyntaxError(TrailingCharacters, 1, 5))); | |
9fa01778 | 1182 | assert_eq!(last_event("falsea"), Error(SyntaxError(TrailingCharacters, 1, 6))); |
dfeec247 XL |
1183 | assert_eq!(last_event("1a"), Error(SyntaxError(TrailingCharacters, 1, 2))); |
1184 | assert_eq!(last_event("[]a"), Error(SyntaxError(TrailingCharacters, 1, 3))); | |
1185 | assert_eq!(last_event("{}a"), Error(SyntaxError(TrailingCharacters, 1, 3))); | |
9fa01778 XL |
1186 | } |
1187 | #[test] | |
1188 | fn test_read_identifiers_streaming() { | |
1189 | assert_eq!(Parser::new("null".chars()).next(), Some(NullValue)); | |
1190 | assert_eq!(Parser::new("true".chars()).next(), Some(BooleanValue(true))); | |
1191 | assert_eq!(Parser::new("false".chars()).next(), Some(BooleanValue(false))); | |
1192 | ||
dfeec247 XL |
1193 | assert_eq!(last_event("n"), Error(SyntaxError(InvalidSyntax, 1, 2))); |
1194 | assert_eq!(last_event("nul"), Error(SyntaxError(InvalidSyntax, 1, 4))); | |
1195 | assert_eq!(last_event("t"), Error(SyntaxError(InvalidSyntax, 1, 2))); | |
9fa01778 | 1196 | assert_eq!(last_event("truz"), Error(SyntaxError(InvalidSyntax, 1, 4))); |
dfeec247 XL |
1197 | assert_eq!(last_event("f"), Error(SyntaxError(InvalidSyntax, 1, 2))); |
1198 | assert_eq!(last_event("faz"), Error(SyntaxError(InvalidSyntax, 1, 3))); | |
9fa01778 XL |
1199 | } |
1200 | ||
1201 | #[test] | |
1202 | fn test_to_json() { | |
9fa01778 | 1203 | use json::ToJson; |
dfeec247 | 1204 | use std::collections::{BTreeMap, HashMap}; |
9fa01778 XL |
1205 | |
1206 | let array2 = Array(vec![U64(1), U64(2)]); | |
1207 | let array3 = Array(vec![U64(1), U64(2), U64(3)]); | |
1208 | let object = { | |
1209 | let mut tree_map = BTreeMap::new(); | |
1210 | tree_map.insert("a".to_string(), U64(1)); | |
1211 | tree_map.insert("b".to_string(), U64(2)); | |
1212 | Object(tree_map) | |
1213 | }; | |
1214 | ||
1215 | assert_eq!(array2.to_json(), array2); | |
1216 | assert_eq!(object.to_json(), object); | |
1217 | assert_eq!(3_isize.to_json(), I64(3)); | |
1218 | assert_eq!(4_i8.to_json(), I64(4)); | |
1219 | assert_eq!(5_i16.to_json(), I64(5)); | |
1220 | assert_eq!(6_i32.to_json(), I64(6)); | |
1221 | assert_eq!(7_i64.to_json(), I64(7)); | |
1222 | assert_eq!(8_usize.to_json(), U64(8)); | |
1223 | assert_eq!(9_u8.to_json(), U64(9)); | |
1224 | assert_eq!(10_u16.to_json(), U64(10)); | |
1225 | assert_eq!(11_u32.to_json(), U64(11)); | |
1226 | assert_eq!(12_u64.to_json(), U64(12)); | |
1227 | assert_eq!(13.0_f32.to_json(), F64(13.0_f64)); | |
1228 | assert_eq!(14.0_f64.to_json(), F64(14.0_f64)); | |
1229 | assert_eq!(().to_json(), Null); | |
1230 | assert_eq!(f32::INFINITY.to_json(), Null); | |
1231 | assert_eq!(f64::NAN.to_json(), Null); | |
1232 | assert_eq!(true.to_json(), Boolean(true)); | |
1233 | assert_eq!(false.to_json(), Boolean(false)); | |
1234 | assert_eq!("abc".to_json(), String("abc".to_string())); | |
1235 | assert_eq!("abc".to_string().to_json(), String("abc".to_string())); | |
1236 | assert_eq!((1_usize, 2_usize).to_json(), array2); | |
1237 | assert_eq!((1_usize, 2_usize, 3_usize).to_json(), array3); | |
1238 | assert_eq!([1_usize, 2_usize].to_json(), array2); | |
1239 | assert_eq!((&[1_usize, 2_usize, 3_usize]).to_json(), array3); | |
1240 | assert_eq!((vec![1_usize, 2_usize]).to_json(), array2); | |
1241 | assert_eq!(vec![1_usize, 2_usize, 3_usize].to_json(), array3); | |
1242 | let mut tree_map = BTreeMap::new(); | |
1243 | tree_map.insert("a".to_string(), 1 as usize); | |
1244 | tree_map.insert("b".to_string(), 2); | |
1245 | assert_eq!(tree_map.to_json(), object); | |
1246 | let mut hash_map = HashMap::new(); | |
1247 | hash_map.insert("a".to_string(), 1 as usize); | |
1248 | hash_map.insert("b".to_string(), 2); | |
1249 | assert_eq!(hash_map.to_json(), object); | |
1250 | assert_eq!(Some(15).to_json(), I64(15)); | |
1251 | assert_eq!(Some(15 as usize).to_json(), U64(15)); | |
1252 | assert_eq!(None::<isize>.to_json(), Null); | |
1253 | } | |
1254 | ||
1255 | #[test] | |
1256 | fn test_encode_hashmap_with_arbitrary_key() { | |
1257 | use std::collections::HashMap; | |
3dfed10e | 1258 | #[derive(PartialEq, Eq, Hash, Encodable)] |
9fa01778 XL |
1259 | struct ArbitraryType(usize); |
1260 | let mut hm: HashMap<ArbitraryType, bool> = HashMap::new(); | |
1261 | hm.insert(ArbitraryType(1), true); | |
1262 | let mut mem_buf = string::String::new(); | |
1263 | let mut encoder = Encoder::new(&mut mem_buf); | |
1264 | let result = hm.encode(&mut encoder); | |
1265 | match result.unwrap_err() { | |
1266 | EncoderError::BadHashmapKey => (), | |
dfeec247 | 1267 | _ => panic!("expected bad hash map key"), |
9fa01778 XL |
1268 | } |
1269 | } |