use super::mock::{MockDbEnv, MockFileEnv, MockGitEnv, MockProcessEnv};
use super::real::{RealDbEnv, RealFileEnv, RealGitEnv, RealProcessEnv};
use super::traits::{DbEnv, FileEnv, GitEnv, ProcessEnv};
use std::path::PathBuf;
use std::sync::Arc;
#[derive(Clone)]
pub struct AppEnv {
pub fs: Arc<dyn FileEnv>,
pub process: Arc<dyn ProcessEnv>,
pub git: Arc<dyn GitEnv>,
pub db: Arc<dyn DbEnv>,
}
impl AppEnv {
pub fn real() -> Self {
Self::real_with_git_dir(std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")))
}
pub fn real_with_git_dir(git_dir: PathBuf) -> Self {
Self {
fs: Arc::new(RealFileEnv::new()),
process: Arc::new(RealProcessEnv::new()),
git: Arc::new(RealGitEnv::new(git_dir)),
db: Arc::new(RealDbEnv::new()),
}
}
pub fn mock() -> Self {
Self {
fs: Arc::new(MockFileEnv::new()),
process: Arc::new(MockProcessEnv::new()),
git: Arc::new(MockGitEnv::new()),
db: Arc::new(MockDbEnv::new()),
}
}
pub fn custom(
fs: Arc<dyn FileEnv>,
process: Arc<dyn ProcessEnv>,
git: Arc<dyn GitEnv>,
db: Arc<dyn DbEnv>,
) -> Self {
Self {
fs,
process,
git,
db,
}
}
}
impl std::fmt::Debug for AppEnv {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AppEnv")
.field("fs", &"dyn FileEnv")
.field("process", &"dyn ProcessEnv")
.field("git", &"dyn GitEnv")
.field("db", &"dyn DbEnv")
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::Path;
#[test]
fn test_mock_env_creation() {
let env = AppEnv::mock();
let mock_fs = env.fs.clone();
let path = Path::new("test.txt");
assert!(!mock_fs.exists(path));
}
#[test]
fn test_real_env_creation() {
let env = AppEnv::real();
assert!(env.fs.exists(Path::new(".")));
}
}