diff options
author | John Brandt <johnb0@outlook.com> | 2021-03-22 19:57:56 -0600 |
---|---|---|
committer | John Brandt <johnb0@outlook.com> | 2021-05-04 10:31:53 -0600 |
commit | ab8d0064cb1cabe930d7f91e3f1194696f2e1f06 (patch) | |
tree | d391959f01f98919c12fce08ad0150a5b3d9e196 | |
parent | 320b841c808b130aab506c1bf57f372b7de95090 (diff) |
more environment variable parsing tests
-rw-r--r-- | tests/env.rs | 352 |
1 files changed, 334 insertions, 18 deletions
diff --git a/tests/env.rs b/tests/env.rs index 3f649c7..58f2dc6 100644 --- a/tests/env.rs +++ b/tests/env.rs @@ -1,8 +1,12 @@ extern crate config; +extern crate serde_derive; use std::env; - use config::*; +use serde_derive::Deserialize; + +/// Reminder that tests using env variables need to use different env variable names, since +/// tests can be run in parallel #[test] fn test_default() { @@ -84,29 +88,341 @@ fn test_custom_separator_behavior() { env::remove_var("C.B.A"); } -fn test_parse_numbers() { +fn test_parse_int() { + // using a struct in an enum here to make serde use `deserialize_any` + #[derive(Deserialize, Debug)] + #[serde(tag = "tag")] + enum TestIntEnum { + Int(TestInt), + } + + #[derive(Deserialize, Debug)] + struct TestInt { + int_val: i32, + } + env::set_var("INT_VAL", "42"); - env::set_var("FLOAT_VAL", "42.2"); - env::set_var("BOOL_VAL", "true"); let environment = Environment::new().try_parsing(true); + let mut config = Config::new(); + + config.set("tag", "Int").unwrap(); + + config.merge(environment).unwrap(); + + let config: TestIntEnum = config.try_into().unwrap(); - let values = environment.collect().unwrap(); - - assert_eq!( - values.get("int_val").unwrap().clone().into_int().ok(), - Some(42) - ); - assert_eq!( - values.get("float_val").unwrap().clone().into_float().ok(), - Some(42.2) - ); - assert_eq!( - values.get("bool_val").unwrap().clone().into_bool().ok(), - Some(true) - ); + assert!(matches!(config, TestIntEnum::Int(TestInt { int_val: 42 }))); env::remove_var("INT_VAL"); +} + +#[test] +fn test_parse_float() { + // using a struct in an enum here to make serde use `deserialize_any` + #[derive(Deserialize, Debug)] + #[serde(tag = "tag")] + enum TestFloatEnum { + Float(TestFloat), + } + + #[derive(Deserialize, Debug)] + struct TestFloat { + float_val: f64, + } + + env::set_var("FLOAT_VAL", "42.3"); + + let environment = Environment::new().try_parsing(true); + let mut config = Config::new(); + + config.set("tag", "Float").unwrap(); + + config.merge(environment).unwrap(); + + let config: TestFloatEnum = config.try_into().unwrap(); + + // can't use `matches!` because of float value + match config { + TestFloatEnum::Float(TestFloat { float_val }) => assert_eq!(float_val, 42.3), + } + env::remove_var("FLOAT_VAL"); +} + +#[test] +fn test_parse_bool() { + // using a struct in an enum here to make serde use `deserialize_any` + #[derive(Deserialize, Debug)] + #[serde(tag = "tag")] + enum TestBoolEnum { + Bool(TestBool), + } + + #[derive(Deserialize, Debug)] + struct TestBool { + bool_val: bool, + } + + env::set_var("BOOL_VAL", "true"); + + let environment = Environment::new().try_parsing(true); + let mut config = Config::new(); + + config.set("tag", "Bool").unwrap(); + + config.merge(environment).unwrap(); + + let config: TestBoolEnum = config.try_into().unwrap(); + + assert!(matches!( + config, + TestBoolEnum::Bool(TestBool { bool_val: true }), + )); + env::remove_var("BOOL_VAL"); } + +#[test] +#[should_panic(expected = "invalid type: string \"42\", expected i32")] +fn test_parse_off_int() { + // using a struct in an enum here to make serde use `deserialize_any` + #[derive(Deserialize, Debug)] + #[serde(tag = "tag")] + enum TestIntEnum { + Int(TestInt), + } + + #[derive(Deserialize, Debug)] + struct TestInt { + int_val_1: i32, + } + + env::set_var("INT_VAL_1", "42"); + + let environment = Environment::new().try_parsing(false); + let mut config = Config::new(); + + config.set("tag", "Int").unwrap(); + + config.merge(environment).unwrap(); + + env::remove_var("INT_VAL_1"); + + config.try_into::<TestIntEnum>().unwrap(); +} + +#[test] +#[should_panic(expected = "invalid type: string \"42.3\", expected f64")] +fn test_parse_off_float() { + // using a struct in an enum here to make serde use `deserialize_any` + #[derive(Deserialize, Debug)] + #[serde(tag = "tag")] + enum TestFloatEnum { + Float(TestFloat), + } + + #[derive(Deserialize, Debug)] + struct TestFloat { + float_val_1: f64, + } + + env::set_var("FLOAT_VAL_1", "42.3"); + + let environment = Environment::new().try_parsing(false); + let mut config = Config::new(); + + config.set("tag", "Float").unwrap(); + + config.merge(environment).unwrap(); + + env::remove_var("FLOAT_VAL_1"); + + config.try_into::<TestFloatEnum>().unwrap(); +} + +#[test] +#[should_panic(expected = "invalid type: string \"true\", expected a boolean")] +fn test_parse_off_bool() { + // using a struct in an enum here to make serde use `deserialize_any` + #[derive(Deserialize, Debug)] + #[serde(tag = "tag")] + enum TestBoolEnum { + Bool(TestBool), + } + + #[derive(Deserialize, Debug)] + struct TestBool { + bool_val_1: bool, + } + + env::set_var("BOOL_VAL_1", "true"); + + let environment = Environment::new().try_parsing(false); + let mut config = Config::new(); + + config.set("tag", "Bool").unwrap(); + + config.merge(environment).unwrap(); + + env::remove_var("BOOL_VAL_1"); + + config.try_into::<TestBoolEnum>().unwrap(); +} + +#[test] +#[should_panic(expected = "invalid type: string \"not an int\", expected i32")] +fn test_parse_int_fail() { + // using a struct in an enum here to make serde use `deserialize_any` + #[derive(Deserialize, Debug)] + #[serde(tag = "tag")] + enum TestIntEnum { + Int(TestInt), + } + + #[derive(Deserialize, Debug)] + struct TestInt { + int_val_2: i32, + } + + env::set_var("INT_VAL_2", "not an int"); + + let environment = Environment::new().try_parsing(true); + let mut config = Config::new(); + + config.set("tag", "Int").unwrap(); + + config.merge(environment).unwrap(); + + env::remove_var("INT_VAL_2"); + + config.try_into::<TestIntEnum>().unwrap(); +} + +#[test] +#[should_panic(expected = "invalid type: string \"not a float\", expected f64")] +fn test_parse_float_fail() { + // using a struct in an enum here to make serde use `deserialize_any` + #[derive(Deserialize, Debug)] + #[serde(tag = "tag")] + enum TestFloatEnum { + Float(TestFloat), + } + + #[derive(Deserialize, Debug)] + struct TestFloat { + float_val_2: f64, + } + + env::set_var("FLOAT_VAL_2", "not a float"); + + let environment = Environment::new().try_parsing(true); + let mut config = Config::new(); + + config.set("tag", "Float").unwrap(); + + config.merge(environment).unwrap(); + + env::remove_var("FLOAT_VAL_2"); + + config.try_into::<TestFloatEnum>().unwrap(); +} + +#[test] +#[should_panic(expected = "invalid type: string \"not a bool\", expected a boolean")] +fn test_parse_bool_fail() { + // using a struct in an enum here to make serde use `deserialize_any` + #[derive(Deserialize, Debug)] + #[serde(tag = "tag")] + enum TestBoolEnum { + Bool(TestBool), + } + + #[derive(Deserialize, Debug)] + struct TestBool { + bool_val_2: bool, + } + + env::set_var("BOOL_VAL_2", "not a bool"); + + let environment = Environment::new().try_parsing(true); + let mut config = Config::new(); + + config.set("tag", "Bool").unwrap(); + + config.merge(environment).unwrap(); + + env::remove_var("BOOL_VAL_2"); + + config.try_into::<TestBoolEnum>().unwrap(); +} + +#[test] +fn test_parse_string() { + // using a struct in an enum here to make serde use `deserialize_any` + #[derive(Deserialize, Debug)] + #[serde(tag = "tag")] + enum TestStringEnum { + String(TestString), + } + + #[derive(Deserialize, Debug)] + struct TestString { + string_val: String, + } + + env::set_var("STRING_VAL", "test string"); + + let environment = Environment::new().try_parsing(true); + let mut config = Config::new(); + + config.set("tag", "String").unwrap(); + + config.merge(environment).unwrap(); + + let config: TestStringEnum = config.try_into().unwrap(); + + let test_string = String::from("test string"); + + match config { + TestStringEnum::String(TestString { string_val }) => assert_eq!(test_string, string_val), + } + + env::remove_var("STRING_VAL"); +} + +#[test] +fn test_parse_off_string() { + // using a struct in an enum here to make serde use `deserialize_any` + #[derive(Deserialize, Debug)] + #[serde(tag = "tag")] + enum TestStringEnum { + String(TestString), + } + + #[derive(Deserialize, Debug)] + struct TestString { + string_val_1: String, + } + + env::set_var("STRING_VAL_1", "test string"); + + let environment = Environment::new().try_parsing(false); + let mut config = Config::new(); + + config.set("tag", "String").unwrap(); + + config.merge(environment).unwrap(); + + let config: TestStringEnum = config.try_into().unwrap(); + + let test_string = String::from("test string"); + + match config { + TestStringEnum::String(TestString { string_val_1 }) => { + assert_eq!(test_string, string_val_1) + } + } + + env::remove_var("STRING_VAL_1"); +} |