use dockertest::{Composition, DockerOperations, DockerTest};
use futures::Future;
use type_map::concurrent::TypeMap;
use crate::server::{Config, Server};
pub struct Test {
pub configs: TypeMap,
pub compositions: Vec<Composition>,
}
impl Test {
pub fn new() -> Self {
Test {
configs: TypeMap::new(),
compositions: Vec::new(),
}
}
pub fn register(&mut self, config: impl Config + 'static) {
self.configs.insert(config.clone());
self.compositions.push(config.into_composition());
}
pub fn run<T, F>(self, fun: T)
where
T: FnOnce(TestInstance) -> F + Send + 'static,
F: Future<Output = ()> + Send + 'static,
{
let mut test = DockerTest::new();
for comp in self.compositions {
test.add_composition(comp)
}
let configs = self.configs;
test.run(|ops| async move {
let instance = TestInstance::new(configs, ops);
(fun)(instance).await;
});
}
}
impl Default for Test {
fn default() -> Self {
Self::new()
}
}
pub struct TestInstance {
pub configs: TypeMap,
pub op: DockerOperations,
}
impl TestInstance {
pub fn new(configs: TypeMap, op: DockerOperations) -> Self {
TestInstance { configs, op }
}
pub fn server<S: Server>(&self) -> S {
let config = self.configs.get::<S::Config>().unwrap();
let container = self.op.handle(config.handle());
S::new(config, container)
}
}