use anyhow::{anyhow, Result};
use std::collections::{HashMap, HashSet};
use std::sync::atomic::{AtomicBool, Ordering};
use crate::ir::Config;
pub struct TestResult {
pub name: String,
pub passed: bool,
pub message: String,
}
pub struct TestSummary {
pub total: usize,
pub passed: usize,
pub failed: usize,
pub results: Vec<TestResult>,
}
pub trait TestBackend {
fn run(&self, cfg: &Config, dsn: &str, only: Option<&HashSet<String>>) -> Result<TestSummary>;
fn supports_temporary_database(&self) -> bool {
false
}
fn setup_temporary_database(&self, _dsn: &str, _database_name: &str, _verbose: bool) -> Result<String> {
Err(anyhow!(
"temporary databases are not supported by this test backend"
))
}
fn cleanup_temporary_database(&self, _dsn: &str, _database_name: &str, _verbose: bool) -> Result<()> {
Ok(())
}
}
pub struct TestBackendRegistry {
backends: HashMap<String, Box<dyn TestBackend>>,
}
impl TestBackendRegistry {
pub fn new() -> Self {
Self {
backends: HashMap::new(),
}
}
pub fn register(&mut self, name: &str, backend: Box<dyn TestBackend>) {
self.backends.insert(name.to_lowercase(), backend);
}
pub fn get(&self, name: &str) -> Option<&dyn TestBackend> {
self.backends.get(&name.to_lowercase()).map(|b| &**b)
}
pub fn list_backends(&self) -> Vec<&str> {
self.backends.keys().map(|s| s.as_str()).collect()
}
}
impl Default for TestBackendRegistry {
fn default() -> Self {
Self::new()
}
}
pub fn get_default_test_backend_registry() -> TestBackendRegistry {
let mut registry = TestBackendRegistry::new();
let provider_registry = crate::provider::get_default_provider_registry();
for provider_name in provider_registry.list_providers() {
if let Some(provider) = provider_registry.get(provider_name) {
provider.register_test_backends(&mut registry);
}
}
registry
}
static VERBOSE: AtomicBool = AtomicBool::new(false);
pub fn set_verbose(v: bool) {
VERBOSE.store(v, Ordering::Relaxed);
}
pub fn is_verbose() -> bool {
VERBOSE.load(Ordering::Relaxed)
}