1 use indoc::indoc;
2 use serde_derive::Deserialize;
3 use std::fmt::Debug;
4 
test_error<T>(yaml: &str, expected: &str) where T: serde::de::DeserializeOwned + Debug,5 fn test_error<T>(yaml: &str, expected: &str)
6 where
7     T: serde::de::DeserializeOwned + Debug,
8 {
9     let result = serde_yaml::from_str::<T>(yaml);
10     assert_eq!(expected, format!("{}", result.unwrap_err()));
11 }
12 
13 #[test]
test_incorrect_type()14 fn test_incorrect_type() {
15     let yaml = indoc! {"
16         ---
17         str
18     "};
19     let expected = "invalid type: string \"str\", expected i16 at line 2 column 1";
20     test_error::<i16>(&yaml, expected);
21 }
22 
23 #[test]
test_incorrect_nested_type()24 fn test_incorrect_nested_type() {
25     #[derive(Deserialize, Debug)]
26     struct A {
27         b: Vec<B>,
28     }
29     #[derive(Deserialize, Debug)]
30     enum B {
31         C(C),
32     }
33     #[derive(Deserialize, Debug)]
34     struct C {
35         d: bool,
36     }
37     let yaml = indoc! {"
38         ---
39         b:
40           - C:
41               d: fase
42     "};
43     let expected =
44         "b[0].C.d: invalid type: string \"fase\", expected a boolean at line 4 column 10";
45     test_error::<A>(&yaml, expected);
46 }
47 
48 #[test]
test_empty()49 fn test_empty() {
50     let expected = "EOF while parsing a value";
51     test_error::<String>("", expected);
52 }
53 
54 #[test]
test_missing_field()55 fn test_missing_field() {
56     #[derive(Deserialize, Debug)]
57     struct Basic {
58         v: bool,
59         w: bool,
60     }
61     let yaml = indoc! {"
62         ---
63         v: true
64     "};
65     let expected = "missing field `w` at line 2 column 2";
66     test_error::<Basic>(&yaml, expected);
67 }
68 
69 #[test]
test_unknown_anchor()70 fn test_unknown_anchor() {
71     let yaml = indoc! {"
72         ---
73         *some
74     "};
75     let expected = "while parsing node, found unknown anchor at line 2 column 1";
76     test_error::<String>(&yaml, expected);
77 }
78 
79 #[test]
test_ignored_unknown_anchor()80 fn test_ignored_unknown_anchor() {
81     #[derive(Deserialize, Debug)]
82     struct Wrapper {
83         c: (),
84     }
85     let yaml = indoc! {"
86         ---
87         b: [*a]
88         c: ~
89     "};
90     let expected = "while parsing node, found unknown anchor at line 2 column 5";
91     test_error::<Wrapper>(&yaml, expected);
92 }
93 
94 #[test]
test_two_documents()95 fn test_two_documents() {
96     let yaml = indoc! {"
97         ---
98         0
99         ---
100         1
101     "};
102     let expected = "deserializing from YAML containing more than one document is not supported";
103     test_error::<usize>(&yaml, expected);
104 }
105 
106 #[test]
test_variant_map_wrong_size()107 fn test_variant_map_wrong_size() {
108     #[derive(Deserialize, Debug)]
109     enum E {
110         V(usize),
111     }
112     let yaml = indoc! {r#"
113         ---
114         "V": 16
115         "other": 32
116     "#};
117     let expected = "invalid length 2, expected map containing 1 entry";
118     test_error::<E>(&yaml, expected);
119 }
120 
121 #[test]
test_variant_not_a_map()122 fn test_variant_not_a_map() {
123     #[derive(Deserialize, Debug)]
124     enum E {
125         V(usize),
126     }
127     let yaml = indoc! {r#"
128         ---
129         - "V"
130     "#};
131     let expected = "invalid type: sequence, expected string or singleton map at line 2 column 1";
132     test_error::<E>(&yaml, expected);
133 }
134 
135 #[test]
test_variant_not_string()136 fn test_variant_not_string() {
137     #[derive(Deserialize, Debug)]
138     enum E {
139         V(bool),
140     }
141     let yaml = indoc! {r#"
142         ---
143         {}: true
144     "#};
145     let expected = "invalid type: map, expected variant of enum `E` at line 2 column 1";
146     test_error::<E>(&yaml, expected);
147 }
148 
149 #[test]
test_bad_bool()150 fn test_bad_bool() {
151     let yaml = indoc! {"
152         ---
153         !!bool str
154     "};
155     let expected = "invalid value: string \"str\", expected a boolean at line 2 column 8";
156     test_error::<bool>(&yaml, expected);
157 }
158 
159 #[test]
test_bad_int()160 fn test_bad_int() {
161     let yaml = indoc! {"
162         ---
163         !!int str
164     "};
165     let expected = "invalid value: string \"str\", expected an integer at line 2 column 7";
166     test_error::<i64>(&yaml, expected);
167 }
168 
169 #[test]
test_bad_float()170 fn test_bad_float() {
171     let yaml = indoc! {"
172         ---
173         !!float str
174     "};
175     let expected = "invalid value: string \"str\", expected a float at line 2 column 9";
176     test_error::<f64>(&yaml, expected);
177 }
178 
179 #[test]
test_bad_null()180 fn test_bad_null() {
181     let yaml = indoc! {"
182         ---
183         !!null str
184     "};
185     let expected = "invalid value: string \"str\", expected null at line 2 column 8";
186     test_error::<()>(&yaml, expected);
187 }
188 
189 #[test]
test_short_tuple()190 fn test_short_tuple() {
191     let yaml = indoc! {"
192         ---
193         [0, 0]
194     "};
195     let expected = "invalid length 2, expected a tuple of size 3 at line 2 column 1";
196     test_error::<(u8, u8, u8)>(&yaml, expected);
197 }
198 
199 #[test]
test_long_tuple()200 fn test_long_tuple() {
201     let yaml = indoc! {"
202         ---
203         [0, 0, 0]
204     "};
205     let expected = "invalid length 3, expected sequence of 2 elements at line 2 column 1";
206     test_error::<(u8, u8)>(&yaml, expected);
207 }
208 
209 #[test]
test_no_location()210 fn test_no_location() {
211     let invalid_utf8: Result<serde_yaml::Value, serde_yaml::Error> =
212         serde_yaml::from_slice(b"\x80\xae");
213 
214     let utf8_location = invalid_utf8.unwrap_err().location();
215 
216     assert_eq!(utf8_location.is_none(), true);
217 }
218 
219 #[test]
test_invalid_scalar_type()220 fn test_invalid_scalar_type() {
221     #[derive(Deserialize, Debug)]
222     struct S {
223         x: [(); 1],
224     }
225 
226     let yaml = "x:\n";
227     let expected = "x: invalid type: unit value, expected an array of length 1 at line 2 column 1";
228     test_error::<S>(yaml, expected);
229 }
230 
231 #[test]
test_infinite_recursion_objects()232 fn test_infinite_recursion_objects() {
233     #[derive(Deserialize, Debug)]
234     struct S {
235         x: Option<Box<S>>,
236     }
237 
238     let yaml = "&a {x: *a}";
239     let expected = "recursion limit exceeded";
240     test_error::<S>(yaml, expected);
241 }
242 
243 #[test]
test_infinite_recursion_arrays()244 fn test_infinite_recursion_arrays() {
245     #[derive(Deserialize, Debug)]
246     struct S {
247         x: Option<Box<S>>,
248     }
249 
250     let yaml = "&a [*a]";
251     let expected = "recursion limit exceeded";
252     test_error::<S>(yaml, expected);
253 }
254 
255 #[test]
test_finite_recursion_objects()256 fn test_finite_recursion_objects() {
257     #[derive(Deserialize, Debug)]
258     struct S {
259         x: Option<Box<S>>,
260     }
261 
262     let yaml = "{x:".repeat(1_000) + &"}".repeat(1_000);
263     let expected = "recursion limit exceeded at line 1 column 766";
264     test_error::<i32>(&yaml, expected);
265 }
266 
267 #[test]
test_finite_recursion_arrays()268 fn test_finite_recursion_arrays() {
269     #[derive(Deserialize, Debug)]
270     struct S {
271         x: Option<Box<S>>,
272     }
273 
274     let yaml = "[".repeat(1_000) + &"]".repeat(1_000);
275     let expected = "recursion limit exceeded at line 1 column 256";
276     test_error::<S>(&yaml, expected);
277 }
278