use config::{mem, prelude::*};
use std::collections::HashMap;
use test_case::test_case;
#[test]
fn build_should_load_and_combine_different_configuration_sources() {
let source1 = mem::Provider::new(&[("Mem1:KeyInMem1", "ValueInMem1")]);
let source2 = mem::Provider::new(&[("Mem2:KeyInMem2", "ValueInMem2")]);
let source3 = mem::Provider::new(&[("Mem3:KeyInMem3", "ValueInMem3")]);
let mut builder = config::builder();
builder.add(source1);
builder.add(source2);
builder.add(source3);
let config = builder.build().unwrap();
assert_eq!(config.get("mem1:keyinmem1"), Some("ValueInMem1"));
assert_eq!(config.get("Mem2:KeyInMem2"), Some("ValueInMem2"));
assert_eq!(config.get("MEM3:KEYINMEM3"), Some("ValueInMem3"));
}
#[test]
fn add_configuration_should_chain_configurations() {
let source1 = mem::Provider::new(&[("Mem1:KeyInMem1", "ValueInMem1")]);
let source2 = mem::Provider::new(&[("Mem2:KeyInMem2", "ValueInMem2")]);
let source3 = mem::Provider::new(&[("Mem3:KeyInMem3", "ValueInMem3")]);
let mut builder = config::builder();
builder.add(source1);
builder.add(source2);
builder.add(source3);
let other = builder.build().unwrap();
let builder = config::builder().add_configuration(other);
let config = builder.build().unwrap();
assert_eq!(config.get("mem1:keyinmem1"), Some("ValueInMem1"));
assert_eq!(config.get("Mem2:KeyInMem2"), Some("ValueInMem2"));
assert_eq!(config.get("MEM3:KEYINMEM3"), Some("ValueInMem3"));
assert_eq!(config.get("Nonexistent"), None);
}
#[test]
fn iter_should_flatten_into_hashmap() {
let source1 = mem::Provider::new(&[
("Mem1", "Value1"),
("Mem1:", "NoKeyValue1"),
("Mem1:KeyInMem1", "ValueInMem1"),
("Mem1:KeyInMem1:Deep1", "ValueDeep1"),
]);
let source2 = mem::Provider::new(&[
("Mem2", "Value2"),
("Mem2:", "NoKeyValue2"),
("Mem2:KeyInMem2", "ValueInMem2"),
("Mem2:KeyInMem2:Deep2", "ValueDeep2"),
]);
let source3 = mem::Provider::new(&[
("Mem3", "Value3"),
("Mem3:", "NoKeyValue3"),
("Mem3:KeyInMem3", "ValueInMem3"),
("Mem3:KeyInMem3:Deep3", "ValueDeep3"),
]);
let mut builder = config::builder();
builder.add(source1);
builder.add(source2);
builder.add(source3);
let config = builder.build().unwrap();
let map = config.into_iter().collect::<HashMap<_, _>>();
assert_eq!(map["Mem1"], "Value1");
assert_eq!(map["Mem1:"], "NoKeyValue1");
assert_eq!(map["Mem1:KeyInMem1"], "ValueInMem1");
assert_eq!(map["Mem1:KeyInMem1:Deep1"], "ValueDeep1");
assert_eq!(map["Mem2"], "Value2");
assert_eq!(map["Mem2:"], "NoKeyValue2");
assert_eq!(map["Mem2:KeyInMem2"], "ValueInMem2");
assert_eq!(map["Mem2:KeyInMem2:Deep2"], "ValueDeep2");
assert_eq!(map["Mem3"], "Value3");
assert_eq!(map["Mem3:"], "NoKeyValue3");
assert_eq!(map["Mem3:KeyInMem3"], "ValueInMem3");
assert_eq!(map["Mem3:KeyInMem3:Deep3"], "ValueDeep3");
}
#[test]
fn chained_iter_should_flatten_into_hashmap() {
let source1 = mem::Provider::new(&[
("Mem1", "Value1"),
("Mem1:", "NoKeyValue1"),
("Mem1:KeyInMem1", "ValueInMem1"),
("Mem1:KeyInMem1:Deep1", "ValueDeep1"),
]);
let source2 = mem::Provider::new(&[
("Mem2", "Value2"),
("Mem2:", "NoKeyValue2"),
("Mem2:KeyInMem2", "ValueInMem2"),
("Mem2:KeyInMem2:Deep2", "ValueDeep2"),
]);
let source3 = mem::Provider::new(&[
("Mem3", "Value3"),
("Mem3:", "NoKeyValue3"),
("Mem3:KeyInMem3", "ValueInMem3"),
("Mem3:KeyInMem3:Deep3", "ValueDeep3"),
]);
let mut builder = config::builder();
builder.add(source1);
builder.add(source2);
let other = builder.build().unwrap();
let mut builder = config::builder().add_configuration(other);
builder.add(source3);
let config = builder.build().unwrap();
let map = config.into_iter().collect::<HashMap<_, _>>();
assert_eq!(map["Mem1"], "Value1");
assert_eq!(map["Mem1:"], "NoKeyValue1");
assert_eq!(map["Mem1:KeyInMem1"], "ValueInMem1");
assert_eq!(map["Mem1:KeyInMem1:Deep1"], "ValueDeep1");
assert_eq!(map["Mem2"], "Value2");
assert_eq!(map["Mem2:"], "NoKeyValue2");
assert_eq!(map["Mem2:KeyInMem2"], "ValueInMem2");
assert_eq!(map["Mem2:KeyInMem2:Deep2"], "ValueDeep2");
assert_eq!(map["Mem3"], "Value3");
assert_eq!(map["Mem3:"], "NoKeyValue3");
assert_eq!(map["Mem3:KeyInMem3"], "ValueInMem3");
assert_eq!(map["Mem3:KeyInMem3:Deep3"], "ValueDeep3");
}
#[test]
fn new_configuration_provider_should_override_old_one_when_key_is_duplicated() {
let source1 = mem::Provider::new(&[("Key1:Key2", "ValueInMem1")]);
let source2 = mem::Provider::new(&[("Key1:Key2", "ValueInMem2")]);
let mut builder = config::builder();
builder.add(source1);
builder.add(source2);
let config = builder.build().unwrap();
assert_eq!(config.get("Key1:Key2"), Some("ValueInMem2"));
}
#[test]
fn new_configuration_root_should_be_built_from_existing_with_duplicate_keys() {
let other = config::builder()
.add_in_memory(&[("keya:keyb", "valueA")])
.add_in_memory(&[("KEYA:KEYB", "valueB")])
.build()
.unwrap();
let config = config::builder()
.add_in_memory(&other.into_iter().collect::<Vec<_>>())
.build()
.unwrap();
assert_eq!(config.get("keya:keyb"), Some("valueB"));
}
#[test]
fn section_should_return_parts_from_root_configuration() {
let source1 = mem::Provider::new(&[("Data:DB1:Connection1", "MemVal1"), ("Data:DB1:Connection2", "MemVal2")]);
let source2 = mem::Provider::new(&[("DataSource:DB2:Connection", "MemVal3")]);
let source3 = mem::Provider::new(&[("Data", "MemVal4")]);
let mut builder = config::builder();
builder.add(source1);
builder.add(source2);
builder.add(source3);
let config = builder.build().unwrap();
let section = config.section("Data");
assert_eq!(section.get("DB1:Connection1"), Some("MemVal1"));
assert_eq!(section.get("DB1:Connection2"), Some("MemVal2"));
assert_eq!(section.value(), "MemVal4");
assert_eq!(section.get("DB2:Connection"), None);
assert_eq!(section.get("Source:DB2:Connection"), None);
}
#[test]
fn section_should_return_children() {
let source1 = mem::Provider::new(&[("Data:DB1:Connection1", "MemVal1"), ("Data:DB1:Connection2", "MemVal2")]);
let source2 = mem::Provider::new(&[("Data:DB2Connection", "MemVal3")]);
let source3 = mem::Provider::new(&[("DataSource:DB3:Connection", "MemVal4")]);
let mut builder = config::builder();
builder.add(source1);
builder.add(source2);
builder.add(source3);
let config = builder.build().unwrap();
let sections = config.section("Data").sections();
assert_eq!(sections.len(), 2);
assert_eq!(
sections.iter().find(|s| s.key() == "DB1").unwrap().get("Connection1"),
Some("MemVal1")
);
assert_eq!(
sections.iter().find(|s| s.key() == "DB1").unwrap().get("Connection2"),
Some("MemVal2")
);
assert_eq!(
sections.iter().find(|s| s.key() == "DB2Connection").unwrap().value(),
"MemVal3"
);
assert!(sections.iter().find(|s| s.key() == "DB3").is_none());
}
#[test_case("Value1", true ; "should exist with value")]
#[test_case("", false ; "should not exist with empty value")]
fn section_without_children(value: &str, expected: bool) {
let config = config::builder().add_in_memory(&[("Mem1", value)]).build().unwrap();
let section = config.section("Mem1");
assert_eq!(section.exists(), expected);
}
#[test]
fn section_with_children_should_exist() {
let root = config::builder()
.add_in_memory(&[
("Mem1:KeyInMem1", "ValueInMem1"),
("Mem1:KeyInMem1:Deep1", "ValueDeep1"),
("Mem2:KeyInMem2:Deep1", "ValueDeep2"),
])
.build();
let config = root.unwrap();
assert!(config.section("Mem1").exists());
assert!(config.section("Mem2").exists());
assert!(!config.section("Mem3").exists());
}
#[test]
fn key_starting_with_colon_means_first_section_has_empty_name() {
let config = config::builder().add_in_memory(&[(":Key2", "value")]).build().unwrap();
let sections = config.sections();
assert_eq!(sections.len(), 1);
assert_eq!("", sections[0].key());
assert_eq!(sections[0].sections().len(), 1);
assert_eq!(sections[0].sections()[0].key(), "Key2");
}
#[test]
fn key_ending_with_colon_means_last_section_has_empty_name() {
let config = config::builder().add_in_memory(&[("Key1:", "value")]).build().unwrap();
let sections = config.sections();
assert_eq!(sections.len(), 1);
assert_eq!("Key1", sections[0].key());
assert_eq!(sections[0].sections().len(), 1);
assert_eq!(sections[0].sections()[0].key(), "");
}
#[test]
fn key_ending_with_double_colon_has_section_with_empty_name() {
let config = config::builder()
.add_in_memory(&[("Key1::Key3", "value")])
.build()
.unwrap();
let sections = config.sections();
assert_eq!(sections.len(), 1);
assert_eq!("Key1", sections[0].key());
assert_eq!(sections[0].sections().len(), 1);
assert_eq!(sections[0].sections()[0].key(), "");
assert_eq!(sections[0].sections()[0].sections().len(), 1);
assert_eq!(sections[0].sections()[0].sections()[0].key(), "Key3");
}