Skip to content

Commit f8cef64

Browse files
committed
Add test for async builder
Signed-off-by: Matthias Beyer <[email protected]> Reviewed-by: Matthias Beyer <[email protected]>
1 parent f4de34e commit f8cef64

File tree

2 files changed

+154
-0
lines changed

2 files changed

+154
-0
lines changed

tests/Settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"debug": true,
3+
"debug_json": true,
34
"production": false,
45
"arr": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
56
"place": {

tests/async_builder.rs

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
use async_trait::async_trait;
2+
use config::*;
3+
use std::{env, fs, path, str::FromStr};
4+
use tokio::{fs::File, io::AsyncReadExt};
5+
6+
#[derive(Debug)]
7+
struct AsyncFile {
8+
path: String,
9+
format: FileFormat,
10+
}
11+
12+
/// This is a test only implementation to be used in tests
13+
impl AsyncFile {
14+
pub fn new(path: String, format: FileFormat) -> Self {
15+
AsyncFile { path, format }
16+
}
17+
}
18+
19+
#[async_trait]
20+
impl AsyncSource for AsyncFile {
21+
async fn collect(&self) -> Result<std::collections::HashMap<String, Value>, ConfigError> {
22+
let mut path = env::current_dir().unwrap();
23+
let local = path::PathBuf::from_str(&self.path).unwrap();
24+
25+
path.extend(local.into_iter());
26+
27+
let path = match fs::canonicalize(path) {
28+
Ok(path) => path,
29+
Err(e) => return Err(ConfigError::Foreign(Box::new(e))),
30+
};
31+
32+
let text = match File::open(path).await {
33+
Ok(mut file) => {
34+
let mut buffer = String::default();
35+
match file.read_to_string(&mut buffer).await {
36+
Ok(_read) => buffer,
37+
Err(e) => return Err(ConfigError::Foreign(Box::new(e))),
38+
}
39+
}
40+
Err(e) => return Err(ConfigError::Foreign(Box::new(e))),
41+
};
42+
43+
self.format
44+
.parse(Some(&self.path), &text)
45+
.map_err(|e| ConfigError::Foreign(e))
46+
}
47+
}
48+
49+
#[tokio::test]
50+
async fn test_single_async_file_source() {
51+
let config = Config::builder()
52+
.add_async_source(AsyncFile::new(
53+
"tests/Settings.json".to_owned(),
54+
FileFormat::Json,
55+
))
56+
.build()
57+
.await
58+
.unwrap();
59+
60+
assert_eq!(true, config.get::<bool>("debug").unwrap());
61+
}
62+
63+
#[tokio::test]
64+
async fn test_two_async_file_sources() {
65+
let config = Config::builder()
66+
.add_async_source(AsyncFile::new(
67+
"tests/Settings.json".to_owned(),
68+
FileFormat::Json,
69+
))
70+
.add_async_source(AsyncFile::new(
71+
"tests/Settings.toml".to_owned(),
72+
FileFormat::Toml,
73+
))
74+
.build()
75+
.await
76+
.unwrap();
77+
78+
assert_eq!("Torre di Pisa", config.get::<String>("place.name").unwrap());
79+
assert_eq!(true, config.get::<bool>("debug_json").unwrap());
80+
assert_eq!(1, config.get::<i32>("place.number").unwrap());
81+
}
82+
83+
#[tokio::test]
84+
async fn test_sync_to_async_file_sources() {
85+
let config = Config::builder()
86+
.add_source(config::File::new("tests/Settings", FileFormat::Json))
87+
.add_async_source(AsyncFile::new(
88+
"tests/Settings.toml".to_owned(),
89+
FileFormat::Toml,
90+
))
91+
.build()
92+
.await
93+
.unwrap();
94+
95+
assert_eq!("Torre di Pisa", config.get::<String>("place.name").unwrap());
96+
assert_eq!(1, config.get::<i32>("place.number").unwrap());
97+
}
98+
99+
#[tokio::test]
100+
async fn test_async_to_sync_file_sources() {
101+
let config = Config::builder()
102+
.add_async_source(AsyncFile::new(
103+
"tests/Settings.toml".to_owned(),
104+
FileFormat::Toml,
105+
))
106+
.add_source(config::File::new("tests/Settings", FileFormat::Json))
107+
.build()
108+
.await
109+
.unwrap();
110+
111+
assert_eq!("Torre di Pisa", config.get::<String>("place.name").unwrap());
112+
assert_eq!(1, config.get::<i32>("place.number").unwrap());
113+
}
114+
115+
#[tokio::test]
116+
async fn test_async_file_sources_with_defaults() {
117+
let config = Config::builder()
118+
.set_default("place.name", "Tower of London")
119+
.unwrap()
120+
.set_default("place.sky", "blue")
121+
.unwrap()
122+
.add_async_source(AsyncFile::new(
123+
"tests/Settings.toml".to_owned(),
124+
FileFormat::Toml,
125+
))
126+
.build()
127+
.await
128+
.unwrap();
129+
130+
assert_eq!("Torre di Pisa", config.get::<String>("place.name").unwrap());
131+
assert_eq!("blue", config.get::<String>("place.sky").unwrap());
132+
assert_eq!(1, config.get::<i32>("place.number").unwrap());
133+
}
134+
135+
#[tokio::test]
136+
async fn test_async_file_sources_with_overrides() {
137+
let config = Config::builder()
138+
.set_override("place.name", "Tower of London")
139+
.unwrap()
140+
.add_async_source(AsyncFile::new(
141+
"tests/Settings.toml".to_owned(),
142+
FileFormat::Toml,
143+
))
144+
.build()
145+
.await
146+
.unwrap();
147+
148+
assert_eq!(
149+
"Tower of London",
150+
config.get::<String>("place.name").unwrap()
151+
);
152+
assert_eq!(1, config.get::<i32>("place.number").unwrap());
153+
}

0 commit comments

Comments
 (0)