diff options
Diffstat (limited to 'tests/async_builder.rs')
-rw-r--r-- | tests/async_builder.rs | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/tests/async_builder.rs b/tests/async_builder.rs new file mode 100644 index 0000000..5d7d6ba --- /dev/null +++ b/tests/async_builder.rs @@ -0,0 +1,153 @@ +use async_trait::async_trait; +use config::*; +use std::{env, fs, path, str::FromStr}; +use tokio::{fs::File, io::AsyncReadExt}; + +#[derive(Debug)] +struct AsyncFile { + path: String, + format: FileFormat, +} + +/// This is a test only implementation to be used in tests +impl AsyncFile { + pub fn new(path: String, format: FileFormat) -> Self { + AsyncFile { path, format } + } +} + +#[async_trait] +impl AsyncSource for AsyncFile { + async fn collect(&self) -> Result<std::collections::HashMap<String, Value>, ConfigError> { + let mut path = env::current_dir().unwrap(); + let local = path::PathBuf::from_str(&self.path).unwrap(); + + path.extend(local.into_iter()); + + let path = match fs::canonicalize(path) { + Ok(path) => path, + Err(e) => return Err(ConfigError::Foreign(Box::new(e))), + }; + + let text = match File::open(path).await { + Ok(mut file) => { + let mut buffer = String::default(); + match file.read_to_string(&mut buffer).await { + Ok(_read) => buffer, + Err(e) => return Err(ConfigError::Foreign(Box::new(e))), + } + } + Err(e) => return Err(ConfigError::Foreign(Box::new(e))), + }; + + self.format + .parse(Some(&self.path), &text) + .map_err(|e| ConfigError::Foreign(e)) + } +} + +#[tokio::test] +async fn test_single_async_file_source() { + let config = Config::builder() + .add_async_source(AsyncFile::new( + "tests/Settings.json".to_owned(), + FileFormat::Json, + )) + .build() + .await + .unwrap(); + + assert_eq!(true, config.get::<bool>("debug").unwrap()); +} + +#[tokio::test] +async fn test_two_async_file_sources() { + let config = Config::builder() + .add_async_source(AsyncFile::new( + "tests/Settings.json".to_owned(), + FileFormat::Json, + )) + .add_async_source(AsyncFile::new( + "tests/Settings.toml".to_owned(), + FileFormat::Toml, + )) + .build() + .await + .unwrap(); + + assert_eq!("Torre di Pisa", config.get::<String>("place.name").unwrap()); + assert_eq!(true, config.get::<bool>("debug_json").unwrap()); + assert_eq!(1, config.get::<i32>("place.number").unwrap()); +} + +#[tokio::test] +async fn test_sync_to_async_file_sources() { + let config = Config::builder() + .add_source(config::File::new("tests/Settings", FileFormat::Json)) + .add_async_source(AsyncFile::new( + "tests/Settings.toml".to_owned(), + FileFormat::Toml, + )) + .build() + .await + .unwrap(); + + assert_eq!("Torre di Pisa", config.get::<String>("place.name").unwrap()); + assert_eq!(1, config.get::<i32>("place.number").unwrap()); +} + +#[tokio::test] +async fn test_async_to_sync_file_sources() { + let config = Config::builder() + .add_async_source(AsyncFile::new( + "tests/Settings.toml".to_owned(), + FileFormat::Toml, + )) + .add_source(config::File::new("tests/Settings", FileFormat::Json)) + .build() + .await + .unwrap(); + + assert_eq!("Torre di Pisa", config.get::<String>("place.name").unwrap()); + assert_eq!(1, config.get::<i32>("place.number").unwrap()); +} + +#[tokio::test] +async fn test_async_file_sources_with_defaults() { + let config = Config::builder() + .set_default("place.name", "Tower of London") + .unwrap() + .set_default("place.sky", "blue") + .unwrap() + .add_async_source(AsyncFile::new( + "tests/Settings.toml".to_owned(), + FileFormat::Toml, + )) + .build() + .await + .unwrap(); + + assert_eq!("Torre di Pisa", config.get::<String>("place.name").unwrap()); + assert_eq!("blue", config.get::<String>("place.sky").unwrap()); + assert_eq!(1, config.get::<i32>("place.number").unwrap()); +} + +#[tokio::test] +async fn test_async_file_sources_with_overrides() { + let config = Config::builder() + .set_override("place.name", "Tower of London") + .unwrap() + .add_async_source(AsyncFile::new( + "tests/Settings.toml".to_owned(), + FileFormat::Toml, + )) + .build() + .await + .unwrap(); + + assert_eq!( + "Tower of London", + config.get::<String>("place.name").unwrap() + ); + assert_eq!(1, config.get::<i32>("place.number").unwrap()); +} |