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