1
2 use config::{Config};
3 use serde_derive::Deserialize;
4 use std::env;
5
6 /// Reminder that tests using env variables need to use different env variable names, since
7 /// tests can be run in parallel
8
9
10 #[test]
test_parse_int()11 fn test_parse_int() {
12 // using a struct in an enum here to make serde use `deserialize_any`
13 #[derive(Deserialize, Debug)]
14 #[serde(tag = "tag")]
15 enum TestIntEnum {
16 Int(TestInt),
17 }
18
19 #[derive(Deserialize, Debug)]
20 struct TestInt {
21 int_val: i32,
22 }
23
24 env::set_var("INT_VAL", "42");
25
26 let environment = Environment::new().try_parsing(true);
27 let mut config = Config::default();
28
29 config.set("tag", "Int").unwrap();
30
31 config.merge(environment).unwrap();
32
33 let config: TestIntEnum = config.try_deserialize().unwrap();
34
35 assert!(matches!(config, TestIntEnum::Int(TestInt { int_val: 42 })));
36
37 env::remove_var("INT_VAL");
38 }
39
40 #[test]
test_parse_float()41 fn test_parse_float() {
42 // using a struct in an enum here to make serde use `deserialize_any`
43 #[derive(Deserialize, Debug)]
44 #[serde(tag = "tag")]
45 enum TestFloatEnum {
46 Float(TestFloat),
47 }
48
49 #[derive(Deserialize, Debug)]
50 struct TestFloat {
51 float_val: f64,
52 }
53
54 env::set_var("FLOAT_VAL", "42.3");
55
56 let environment = Environment::new().try_parsing(true);
57 let mut config = Config::default();
58
59 config.set("tag", "Float").unwrap();
60
61 config.merge(environment).unwrap();
62
63 let config: TestFloatEnum = config.try_deserialize().unwrap();
64
65 // can't use `matches!` because of float value
66 match config {
67 TestFloatEnum::Float(TestFloat { float_val }) => assert_eq!(float_val, 42.3),
68 }
69
70 env::remove_var("FLOAT_VAL");
71 }
72
73 #[test]
test_parse_bool()74 fn test_parse_bool() {
75 // using a struct in an enum here to make serde use `deserialize_any`
76 #[derive(Deserialize, Debug)]
77 #[serde(tag = "tag")]
78 enum TestBoolEnum {
79 Bool(TestBool),
80 }
81
82 #[derive(Deserialize, Debug)]
83 struct TestBool {
84 bool_val: bool,
85 }
86
87 env::set_var("BOOL_VAL", "true");
88
89 let environment = Environment::new().try_parsing(true);
90 let mut config = Config::default();
91
92 config.set("tag", "Bool").unwrap();
93
94 config.merge(environment).unwrap();
95
96 let config: TestBoolEnum = config.try_deserialize().unwrap();
97
98 assert!(matches!(
99 config,
100 TestBoolEnum::Bool(TestBool { bool_val: true }),
101 ));
102
103 env::remove_var("BOOL_VAL");
104 }
105
106 #[test]
107 #[should_panic(expected = "invalid type: string \"42\", expected i32")]
test_parse_off_int()108 fn test_parse_off_int() {
109 // using a struct in an enum here to make serde use `deserialize_any`
110 #[derive(Deserialize, Debug)]
111 #[serde(tag = "tag")]
112 enum TestIntEnum {
113 Int(TestInt),
114 }
115
116 #[derive(Deserialize, Debug)]
117 struct TestInt {
118 int_val_1: i32,
119 }
120
121 env::set_var("INT_VAL_1", "42");
122
123 let environment = Environment::new().try_parsing(false);
124 let mut config = Config::default();
125
126 config.set("tag", "Int").unwrap();
127
128 config.merge(environment).unwrap();
129
130 env::remove_var("INT_VAL_1");
131
132 config.try_deserialize::<TestIntEnum>().unwrap();
133 }
134
135 #[test]
136 #[should_panic(expected = "invalid type: string \"42.3\", expected f64")]
test_parse_off_float()137 fn test_parse_off_float() {
138 // using a struct in an enum here to make serde use `deserialize_any`
139 #[derive(Deserialize, Debug)]
140 #[serde(tag = "tag")]
141 enum TestFloatEnum {
142 Float(TestFloat),
143 }
144
145 #[derive(Deserialize, Debug)]
146 struct TestFloat {
147 float_val_1: f64,
148 }
149
150 env::set_var("FLOAT_VAL_1", "42.3");
151
152 let environment = Environment::new().try_parsing(false);
153 let mut config = Config::default();
154
155 config.set("tag", "Float").unwrap();
156
157 config.merge(environment).unwrap();
158
159 env::remove_var("FLOAT_VAL_1");
160
161 config.try_deserialize::<TestFloatEnum>().unwrap();
162 }
163
164 #[test]
165 #[should_panic(expected = "invalid type: string \"true\", expected a boolean")]
test_parse_off_bool()166 fn test_parse_off_bool() {
167 // using a struct in an enum here to make serde use `deserialize_any`
168 #[derive(Deserialize, Debug)]
169 #[serde(tag = "tag")]
170 enum TestBoolEnum {
171 Bool(TestBool),
172 }
173
174 #[derive(Deserialize, Debug)]
175 struct TestBool {
176 bool_val_1: bool,
177 }
178
179 env::set_var("BOOL_VAL_1", "true");
180
181 let environment = Environment::new().try_parsing(false);
182 let mut config = Config::default();
183
184 config.set("tag", "Bool").unwrap();
185
186 config.merge(environment).unwrap();
187
188 env::remove_var("BOOL_VAL_1");
189
190 config.try_deserialize::<TestBoolEnum>().unwrap();
191 }
192
193 #[test]
194 #[should_panic(expected = "invalid type: string \"not an int\", expected i32")]
test_parse_int_fail()195 fn test_parse_int_fail() {
196 // using a struct in an enum here to make serde use `deserialize_any`
197 #[derive(Deserialize, Debug)]
198 #[serde(tag = "tag")]
199 enum TestIntEnum {
200 Int(TestInt),
201 }
202
203 #[derive(Deserialize, Debug)]
204 struct TestInt {
205 int_val_2: i32,
206 }
207
208 env::set_var("INT_VAL_2", "not an int");
209
210 let environment = Environment::new().try_parsing(true);
211 let mut config = Config::default();
212
213 config.set("tag", "Int").unwrap();
214
215 config.merge(environment).unwrap();
216
217 env::remove_var("INT_VAL_2");
218
219 config.try_deserialize::<TestIntEnum>().unwrap();
220 }
221
222 #[test]
223 #[should_panic(expected = "invalid type: string \"not a float\", expected f64")]
test_parse_float_fail()224 fn test_parse_float_fail() {
225 // using a struct in an enum here to make serde use `deserialize_any`
226 #[derive(Deserialize, Debug)]
227 #[serde(tag = "tag")]
228 enum TestFloatEnum {
229 Float(TestFloat),
230 }
231
232 #[derive(Deserialize, Debug)]
233 struct TestFloat {
234 float_val_2: f64,
235 }
236
237 env::set_var("FLOAT_VAL_2", "not a float");
238
239 let environment = Environment::new().try_parsing(true);
240 let mut config = Config::default();
241
242 config.set("tag", "Float").unwrap();
243
244 config.merge(environment).unwrap();
245
246 env::remove_var("FLOAT_VAL_2");
247
248 config.try_deserialize::<TestFloatEnum>().unwrap();
249 }
250
251 #[test]
252 #[should_panic(expected = "invalid type: string \"not a bool\", expected a boolean")]
test_parse_bool_fail()253 fn test_parse_bool_fail() {
254 // using a struct in an enum here to make serde use `deserialize_any`
255 #[derive(Deserialize, Debug)]
256 #[serde(tag = "tag")]
257 enum TestBoolEnum {
258 Bool(TestBool),
259 }
260
261 #[derive(Deserialize, Debug)]
262 struct TestBool {
263 bool_val_2: bool,
264 }
265
266 env::set_var("BOOL_VAL_2", "not a bool");
267
268 let environment = Environment::new().try_parsing(true);
269 let mut config = Config::default();
270
271 config.set("tag", "Bool").unwrap();
272
273 config.merge(environment).unwrap();
274
275 env::remove_var("BOOL_VAL_2");
276
277 config.try_deserialize::<TestBoolEnum>().unwrap();
278 }
279
280 #[test]
test_parse_string()281 fn test_parse_string() {
282 // using a struct in an enum here to make serde use `deserialize_any`
283 #[derive(Deserialize, Debug)]
284 #[serde(tag = "tag")]
285 enum TestStringEnum {
286 String(TestString),
287 }
288
289 #[derive(Deserialize, Debug)]
290 struct TestString {
291 string_val: String,
292 }
293
294 env::set_var("STRING_VAL", "test string");
295
296 let environment = Environment::new().try_parsing(true);
297 let mut config = Config::default();
298
299 config.set("tag", "String").unwrap();
300
301 config.merge(environment).unwrap();
302
303 let config: TestStringEnum = config.try_deserialize().unwrap();
304
305 let test_string = String::from("test string");
306
307 match config {
308 TestStringEnum::String(TestString { string_val }) => assert_eq!(test_string, string_val),
309 }
310
311 env::remove_var("STRING_VAL");
312 }
313
314 #[test]
test_parse_off_string()315 fn test_parse_off_string() {
316 // using a struct in an enum here to make serde use `deserialize_any`
317 #[derive(Deserialize, Debug)]
318 #[serde(tag = "tag")]
319 enum TestStringEnum {
320 String(TestString),
321 }
322
323 #[derive(Deserialize, Debug)]
324 struct TestString {
325 string_val_1: String,
326 }
327
328 env::set_var("STRING_VAL_1", "test string");
329
330 let environment = Environment::new().try_parsing(false);
331 let mut config = Config::default();
332
333 config.set("tag", "String").unwrap();
334
335 config.merge(environment).unwrap();
336
337 let config: TestStringEnum = config.try_deserialize().unwrap();
338
339 let test_string = String::from("test string");
340
341 match config {
342 TestStringEnum::String(TestString { string_val_1 }) => {
343 assert_eq!(test_string, string_val_1)
344 }
345 }
346
347 env::remove_var("STRING_VAL_1");
348 }
349