diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Settings-invalid.json | 4 | ||||
-rw-r--r-- | tests/Settings-invalid.toml | 2 | ||||
-rw-r--r-- | tests/Settings-invalid.yaml | 2 | ||||
-rw-r--r-- | tests/Settings-production.toml | 8 | ||||
-rw-r--r-- | tests/Settings.json | 16 | ||||
-rw-r--r-- | tests/Settings.toml | 20 | ||||
-rw-r--r-- | tests/Settings.yaml | 12 | ||||
-rw-r--r-- | tests/errors.rs | 47 | ||||
-rw-r--r-- | tests/file.rs | 51 | ||||
-rw-r--r-- | tests/file_json.rs | 71 | ||||
-rw-r--r-- | tests/file_toml.rs | 71 | ||||
-rw-r--r-- | tests/file_yaml.rs | 71 | ||||
-rw-r--r-- | tests/get.rs | 181 | ||||
-rw-r--r-- | tests/merge.rs | 24 | ||||
-rw-r--r-- | tests/set.rs | 56 |
15 files changed, 636 insertions, 0 deletions
diff --git a/tests/Settings-invalid.json b/tests/Settings-invalid.json new file mode 100644 index 0000000..ba2d7cb --- /dev/null +++ b/tests/Settings-invalid.json @@ -0,0 +1,4 @@ +{ + "ok": true, + "error" +} diff --git a/tests/Settings-invalid.toml b/tests/Settings-invalid.toml new file mode 100644 index 0000000..4d159a4 --- /dev/null +++ b/tests/Settings-invalid.toml @@ -0,0 +1,2 @@ +ok = true +error = tru diff --git a/tests/Settings-invalid.yaml b/tests/Settings-invalid.yaml new file mode 100644 index 0000000..070ff1b --- /dev/null +++ b/tests/Settings-invalid.yaml @@ -0,0 +1,2 @@ +ok: true +error false diff --git a/tests/Settings-production.toml b/tests/Settings-production.toml new file mode 100644 index 0000000..6545b4c --- /dev/null +++ b/tests/Settings-production.toml @@ -0,0 +1,8 @@ +debug = false +production = true + +[place] +rating = 4.9 + +[place.creator] +name = "Somebody New" diff --git a/tests/Settings.json b/tests/Settings.json new file mode 100644 index 0000000..c8b72c5 --- /dev/null +++ b/tests/Settings.json @@ -0,0 +1,16 @@ +{ + "debug": true, + "production": false, + "arr": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + "place": { + "name": "Torre di Pisa", + "longitude": 43.7224985, + "latitude": 10.3970522, + "favorite": false, + "reviews": 3866, + "rating": 4.5, + "creator": { + "name": "John Smith" + } + } +} diff --git a/tests/Settings.toml b/tests/Settings.toml new file mode 100644 index 0000000..b7fc7e9 --- /dev/null +++ b/tests/Settings.toml @@ -0,0 +1,20 @@ +debug = true +debug_s = "true" +production = false +production_s = "false" + +# errors +boolean_s_parse = "fals" + +arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + +[place] +name = "Torre di Pisa" +longitude = 43.7224985 +latitude = 10.3970522 +favorite = false +reviews = 3866 +rating = 4.5 + +[place.creator] +name = "John Smith" diff --git a/tests/Settings.yaml b/tests/Settings.yaml new file mode 100644 index 0000000..c92fcb0 --- /dev/null +++ b/tests/Settings.yaml @@ -0,0 +1,12 @@ +debug: true +production: false +arr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +place: + name: Torre di Pisa + longitude: 43.7224985 + latitude: 10.3970522 + favorite: false + reviews: 3866 + rating: 4.5 + creator: + name: John Smith diff --git a/tests/errors.rs b/tests/errors.rs new file mode 100644 index 0000000..fa3b5ca --- /dev/null +++ b/tests/errors.rs @@ -0,0 +1,47 @@ +extern crate config; + +use config::*; + +fn make() -> Config { + let mut c = Config::default(); + c.merge(File::new("tests/Settings", FileFormat::Toml)) + .unwrap(); + + c +} + +#[test] +fn test_error_parse() { + let mut c = Config::default(); + let res = c.merge(File::new("tests/Settings-invalid", FileFormat::Toml)); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err().to_string(), + "invalid number at line 2 in tests/Settings-invalid.toml" + .to_string()); +} + +#[test] +fn test_error_type() { + let c = make(); + + let res = c.get::<bool>("boolean_s_parse"); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err().to_string(), + "invalid type: string \"fals\", expected a boolean for key `boolean_s_parse` in tests/Settings.toml" + .to_string()); +} + +#[test] +fn test_error_type_detached() { + let c = make(); + + let value = c.get::<Value>("boolean_s_parse").unwrap(); + let res = value.try_into::<bool>(); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err().to_string(), + "invalid type: string \"fals\", expected a boolean" + .to_string()); +} diff --git a/tests/file.rs b/tests/file.rs new file mode 100644 index 0000000..04a7361 --- /dev/null +++ b/tests/file.rs @@ -0,0 +1,51 @@ +extern crate config; + +use config::*; + +#[test] +fn test_file_not_required() { + let mut c = Config::default(); + let res = c.merge(File::new("tests/NoSettings", FileFormat::Yaml).required(false)); + + assert!(res.is_ok()); +} + +#[test] +fn test_file_required_not_found() { + let mut c = Config::default(); + let res = c.merge(File::new("tests/NoSettings", FileFormat::Yaml)); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err().to_string(), + "configuration file \"tests/NoSettings\" not found" + .to_string()); +} + +#[test] +fn test_file_auto() { + let mut c = Config::default(); + c.merge(File::with_name("tests/Settings-production")).unwrap(); + + assert_eq!(c.get("debug").ok(), Some(false)); + assert_eq!(c.get("production").ok(), Some(true)); +} + +#[test] +fn test_file_auto_not_found() { + let mut c = Config::default(); + let res = c.merge(File::with_name("tests/NoSettings")); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err().to_string(), + "configuration file \"tests/NoSettings\" not found" + .to_string()); +} + +#[test] +fn test_file_ext() { + let mut c = Config::default(); + c.merge(File::with_name("tests/Settings.json")).unwrap(); + + assert_eq!(c.get("debug").ok(), Some(true)); + assert_eq!(c.get("production").ok(), Some(false)); +} diff --git a/tests/file_json.rs b/tests/file_json.rs new file mode 100644 index 0000000..983be86 --- /dev/null +++ b/tests/file_json.rs @@ -0,0 +1,71 @@ +extern crate config; +extern crate serde; +extern crate float_cmp; + +#[macro_use] +extern crate serde_derive; + +use std::collections::HashMap; +use float_cmp::ApproxEqUlps; +use config::*; + +#[derive(Debug, Deserialize)] +struct Place { + name: String, + longitude: f64, + latitude: f64, + favorite: bool, + telephone: Option<String>, + reviews: u64, + creator: HashMap<String, Value>, + rating: Option<f32>, +} + +#[derive(Debug, Deserialize)] +struct Settings { + debug: f64, + production: Option<String>, + place: Place, + #[serde(rename = "arr")] + elements: Vec<String>, +} + +fn make() -> Config { + let mut c = Config::default(); + c.merge(File::new("tests/Settings", FileFormat::Json)) + .unwrap(); + + c +} + +#[test] +fn test_file() { + let c = make(); + + // Deserialize the entire file as single struct + let s: Settings = c.deserialize().unwrap(); + + assert!(s.debug.approx_eq_ulps(&1.0, 2)); + assert_eq!(s.production, Some("false".to_string())); + assert_eq!(s.place.name, "Torre di Pisa"); + assert!(s.place.longitude.approx_eq_ulps(&43.7224985, 2)); + assert!(s.place.latitude.approx_eq_ulps(&10.3970522, 2)); + assert_eq!(s.place.favorite, false); + assert_eq!(s.place.reviews, 3866); + assert_eq!(s.place.rating, Some(4.5)); + assert_eq!(s.place.telephone, None); + assert_eq!(s.elements.len(), 10); + assert_eq!(s.elements[3], "4".to_string()); + assert_eq!(s.place.creator["name"].clone().into_str().unwrap(), "John Smith".to_string()); +} + +#[test] +fn test_error_parse() { + let mut c = Config::default(); + let res = c.merge(File::new("tests/Settings-invalid", FileFormat::Json)); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err().to_string(), + "expected `:` at line 4 column 1 in tests/Settings-invalid.json" + .to_string()); +} diff --git a/tests/file_toml.rs b/tests/file_toml.rs new file mode 100644 index 0000000..a46e808 --- /dev/null +++ b/tests/file_toml.rs @@ -0,0 +1,71 @@ +extern crate config; +extern crate serde; +extern crate float_cmp; + +#[macro_use] +extern crate serde_derive; + +use std::collections::HashMap; +use float_cmp::ApproxEqUlps; +use config::*; + +#[derive(Debug, Deserialize)] +struct Place { + name: String, + longitude: f64, + latitude: f64, + favorite: bool, + telephone: Option<String>, + reviews: u64, + creator: HashMap<String, Value>, + rating: Option<f32>, +} + +#[derive(Debug, Deserialize)] +struct Settings { + debug: f64, + production: Option<String>, + place: Place, + #[serde(rename = "arr")] + elements: Vec<String>, +} + +fn make() -> Config { + let mut c = Config::default(); + c.merge(File::new("tests/Settings", FileFormat::Toml)) + .unwrap(); + + c +} + +#[test] +fn test_file() { + let c = make(); + + // Deserialize the entire file as single struct + let s: Settings = c.deserialize().unwrap(); + + assert!(s.debug.approx_eq_ulps(&1.0, 2)); + assert_eq!(s.production, Some("false".to_string())); + assert_eq!(s.place.name, "Torre di Pisa"); + assert!(s.place.longitude.approx_eq_ulps(&43.7224985, 2)); + assert!(s.place.latitude.approx_eq_ulps(&10.3970522, 2)); + assert_eq!(s.place.favorite, false); + assert_eq!(s.place.reviews, 3866); + assert_eq!(s.place.rating, Some(4.5)); + assert_eq!(s.place.telephone, None); + assert_eq!(s.elements.len(), 10); + assert_eq!(s.elements[3], "4".to_string()); + assert_eq!(s.place.creator["name"].clone().into_str().unwrap(), "John Smith".to_string()); +} + +#[test] +fn test_error_parse() { + let mut c = Config::default(); + let res = c.merge(File::new("tests/Settings-invalid", FileFormat::Toml)); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err().to_string(), + "invalid number at line 2 in tests/Settings-invalid.toml" + .to_string()); +} diff --git a/tests/file_yaml.rs b/tests/file_yaml.rs new file mode 100644 index 0000000..4ca5557 --- /dev/null +++ b/tests/file_yaml.rs @@ -0,0 +1,71 @@ +extern crate config; +extern crate serde; +extern crate float_cmp; + +#[macro_use] +extern crate serde_derive; + +use std::collections::HashMap; +use float_cmp::ApproxEqUlps; +use config::*; + +#[derive(Debug, Deserialize)] +struct Place { + name: String, + longitude: f64, + latitude: f64, + favorite: bool, + telephone: Option<String>, + reviews: u64, + creator: HashMap<String, Value>, + rating: Option<f32>, +} + +#[derive(Debug, Deserialize)] +struct Settings { + debug: f64, + production: Option<String>, + place: Place, + #[serde(rename = "arr")] + elements: Vec<String>, +} + +fn make() -> Config { + let mut c = Config::default(); + c.merge(File::new("tests/Settings", FileFormat::Yaml)) + .unwrap(); + + c +} + +#[test] +fn test_file() { + let c = make(); + + // Deserialize the entire file as single struct + let s: Settings = c.deserialize().unwrap(); + + assert!(s.debug.approx_eq_ulps(&1.0, 2)); + assert_eq!(s.production, Some("false".to_string())); + assert_eq!(s.place.name, "Torre di Pisa"); + assert!(s.place.longitude.approx_eq_ulps(&43.7224985, 2)); + assert!(s.place.latitude.approx_eq_ulps(&10.3970522, 2)); + assert_eq!(s.place.favorite, false); + assert_eq!(s.place.reviews, 3866); + assert_eq!(s.place.rating, Some(4.5)); + assert_eq!(s.place.telephone, None); + assert_eq!(s.elements.len(), 10); + assert_eq!(s.elements[3], "4".to_string()); + assert_eq!(s.place.creator["name"].clone().into_str().unwrap(), "John Smith".to_string()); +} + +#[test] +fn test_error_parse() { + let mut c = Config::default(); + let res = c.merge(File::new("tests/Settings-invalid", FileFormat::Yaml)); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err().to_string(), + "while parsing a block mapping, did not find expected key at line 2 column 1 in tests/Settings-invalid.yaml" + .to_string()); +} diff --git a/tests/get.rs b/tests/get.rs new file mode 100644 index 0000000..2df50a5 --- /dev/null +++ b/tests/get.rs @@ -0,0 +1,181 @@ +extern crate config; +extern crate serde; +extern crate float_cmp; + +#[macro_use] +extern crate serde_derive; + +use std::collections::HashMap; +use float_cmp::ApproxEqUlps; +use config::*; + +#[derive(Debug, Deserialize)] +struct Place { + name: String, + longitude: f64, + latitude: f64, + favorite: bool, + telephone: Option<String>, + reviews: u64, + rating: Option<f32>, +} + +#[derive(Debug, Deserialize)] +struct Settings { + debug: f64, + production: Option<String>, + place: Place, +} + +fn make() -> Config { + let mut c = Config::default(); + c.merge(File::new("tests/Settings", FileFormat::Toml)) + .unwrap(); + + c +} + +#[test] +fn test_not_found() { + let c = make(); + let res = c.get::<bool>("not_found"); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err().to_string(), + "configuration property \"not_found\" not found" + .to_string()); +} + +#[test] +fn test_scalar() { + let c = make(); + + assert_eq!(c.get("debug").ok(), Some(true)); + assert_eq!(c.get("production").ok(), Some(false)); +} + +#[test] +fn test_scalar_type_loose() { + let c = make(); + + assert_eq!(c.get("debug").ok(), Some(true)); + assert_eq!(c.get("debug").ok(), Some("true".to_string())); + assert_eq!(c.get("debug").ok(), Some(1)); + assert_eq!(c.get("debug").ok(), Some(1.0)); + + assert_eq!(c.get("debug_s").ok(), Some(true)); + assert_eq!(c.get("debug_s").ok(), Some("true".to_string())); + assert_eq!(c.get("debug_s").ok(), Some(1)); + assert_eq!(c.get("debug_s").ok(), Some(1.0)); + + assert_eq!(c.get("production").ok(), Some(false)); + assert_eq!(c.get("production").ok(), Some("false".to_string())); + assert_eq!(c.get("production").ok(), Some(0)); + assert_eq!(c.get("production").ok(), Some(0.0)); + + assert_eq!(c.get("production_s").ok(), Some(false)); + assert_eq!(c.get("production_s").ok(), Some("false".to_string())); + assert_eq!(c.get("production_s").ok(), Some(0)); + assert_eq!(c.get("production_s").ok(), Some(0.0)); +} + +#[test] +fn test_get_scalar_path() { + let c = make(); + + assert_eq!(c.get("place.favorite").ok(), Some(false)); + assert_eq!(c.get("place.creator.name").ok(), Some("John Smith".to_string())); +} + +#[test] +fn test_map() { + let c = make(); + let m: HashMap<String, Value> = c.get("place").unwrap(); + + assert_eq!(m.len(), 7); + assert_eq!(m["name"].clone().into_str().unwrap(), "Torre di Pisa".to_string()); + assert_eq!(m["reviews"].clone().into_int().unwrap(), 3866); +} + +#[test] +fn test_map_str() { + let c = make(); + let m: HashMap<String, String> = c.get("place.creator").unwrap(); + + assert_eq!(m.len(), 1); + assert_eq!(m["name"], "John Smith".to_string()); +} + +#[test] +fn test_map_struct() { + #[derive(Debug, Deserialize)] + struct Settings { + place: HashMap<String, Value>, + } + + let c = make(); + let s: Settings = c.deserialize().unwrap(); + + assert_eq!(s.place.len(), 7); + assert_eq!(s.place["name"].clone().into_str().unwrap(), "Torre di Pisa".to_string()); + assert_eq!(s.place["reviews"].clone().into_int().unwrap(), 3866); +} + +#[test] +fn test_file_struct() { + let c = make(); + + // Deserialize the entire file as single struct + let s: Settings = c.deserialize().unwrap(); + + assert!(s.debug.approx_eq_ulps(&1.0, 2)); + assert_eq!(s.production, Some("false".to_string())); + assert_eq!(s.place.name, "Torre di Pisa"); + assert!(s.place.longitude.approx_eq_ulps(&43.7224985, 2)); + assert!(s.place.latitude.approx_eq_ulps(&10.3970522, 2)); + assert_eq!(s.place.favorite, false); + assert_eq!(s.place.reviews, 3866); + assert_eq!(s.place.rating, Some(4.5)); + assert_eq!(s.place.telephone, None); +} + +#[test] +fn test_scalar_struct() { + let c = make(); + + // Deserialize a scalar struct that has lots of different + // data types + let p: Place = c.get("place").unwrap(); + + assert_eq!(p.name, "Torre di Pisa"); + assert!(p.longitude.approx_eq_ulps(&43.7224985, 2)); + assert!(p.latitude.approx_eq_ulps(&10.3970522, 2)); + assert_eq!(p.favorite, false); + assert_eq!(p.reviews, 3866); + assert_eq!(p.rating, Some(4.5)); + assert_eq!(p.telephone, None); +} + +#[test] +fn test_array_scalar() { + let c = make(); + let arr: Vec<i64> = c.get("arr").unwrap(); + + assert_eq!(arr.len(), 10); + assert_eq!(arr[3], 4); +} + +#[test] +fn test_struct_array() { + #[derive(Debug, Deserialize)] + struct Settings { + #[serde(rename = "arr")] + elements: Vec<String>, + } + + let c = make(); + let s: Settings = c.deserialize().unwrap(); + + assert_eq!(s.elements.len(), 10); + assert_eq!(s.elements[3], "4".to_string()); +} diff --git a/tests/merge.rs b/tests/merge.rs new file mode 100644 index 0000000..4a42d6a --- /dev/null +++ b/tests/merge.rs @@ -0,0 +1,24 @@ +extern crate config; + +use config::*; + +fn make() -> Config { + let mut c = Config::default(); + c.merge(File::new("tests/Settings", FileFormat::Toml)) + .unwrap(); + + c.merge(File::new("tests/Settings-production", FileFormat::Toml)) + .unwrap(); + + c +} + +#[test] +fn test_merge() { + let c = make(); + + assert_eq!(c.get("debug").ok(), Some(false)); + assert_eq!(c.get("production").ok(), Some(true)); + assert_eq!(c.get("place.creator.name").ok(), Some("Somebody New".to_string())); + assert_eq!(c.get("place.rating").ok(), Some(4.9)); +} diff --git a/tests/set.rs b/tests/set.rs new file mode 100644 index 0000000..e02814b --- /dev/null +++ b/tests/set.rs @@ -0,0 +1,56 @@ +extern crate config; + +use config::*; + +#[test] +fn test_set_scalar() { + let mut c = Config::default(); + + c.set("value", true).unwrap(); + + assert_eq!(c.get("value").ok(), Some(true)); +} + +#[test] +fn test_set_scalar_default() { + let mut c = Config::default(); + + c.merge(File::new("tests/Settings", FileFormat::Toml)) + .unwrap(); + + c.set_default("debug", false).unwrap(); + c.set_default("staging", false).unwrap(); + + assert_eq!(c.get("debug").ok(), Some(true)); + assert_eq!(c.get("staging").ok(), Some(false)); +} + +#[test] +fn test_set_scalar_path() { + let mut c = Config::default(); + + c.merge(File::new("tests/Settings", FileFormat::Toml)) + .unwrap(); + + c.set_default("place.favorite", true).unwrap(); + c.set_default("place.blocked", true).unwrap(); + + assert_eq!(c.get("place.favorite").ok(), Some(false)); + assert_eq!(c.get("place.blocked").ok(), Some(true)); +} + +#[test] +fn test_set_capital() { + let mut c = Config::default(); + + c.set_default("tHiS", false).unwrap(); + c.set("THAT", true).unwrap(); + c.merge(File::from_str("{\"loGleVel\": 5}", FileFormat::Json)).unwrap(); + + assert_eq!(c.get("this").ok(), Some(false)); + assert_eq!(c.get("ThIs").ok(), Some(false)); + assert_eq!(c.get("that").ok(), Some(true)); + assert_eq!(c.get("THAT").ok(), Some(true)); + assert_eq!(c.get("logLevel").ok(), Some(5)); + assert_eq!(c.get("loglevel").ok(), Some(5)); +} |