use anyhow::{Context, Result};
use serde_json::Value;
use std::fs;
use std::path::{Path, PathBuf};
pub struct EnvironmentStateAssertions {
workspace_path: PathBuf,
}
impl EnvironmentStateAssertions {
#[must_use]
pub fn new<P: AsRef<Path>>(workspace_path: P) -> Self {
Self {
workspace_path: workspace_path.as_ref().to_path_buf(),
}
}
pub fn assert_environment_exists(&self, env_name: &str) {
let env_file_path = self.environment_json_path(env_name);
assert!(
env_file_path.exists(),
"Environment file should exist at: {}",
env_file_path.display()
);
}
pub fn assert_environment_not_exists(&self, env_name: &str) {
let env_file_path = self.environment_json_path(env_name);
assert!(
!env_file_path.exists(),
"Environment file should not exist at: {}",
env_file_path.display()
);
}
pub fn assert_data_directory_not_exists(&self, env_name: &str) {
let data_dir = self.workspace_path.join("data").join(env_name);
assert!(
!data_dir.exists(),
"Data directory should not exist at: {}",
data_dir.display()
);
}
pub fn assert_build_directory_not_exists(&self, env_name: &str) {
let build_dir = self.workspace_path.join("build").join(env_name);
assert!(
!build_dir.exists(),
"Build directory should not exist at: {}",
build_dir.display()
);
}
#[allow(dead_code)]
pub fn assert_build_directory_exists(&self, env_name: &str) {
let build_dir = self.workspace_path.join("build").join(env_name);
assert!(
build_dir.exists(),
"Build directory should exist at: {}",
build_dir.display()
);
}
#[allow(dead_code)]
pub fn assert_build_artifacts_exist(&self, env_name: &str) {
let build_dir = self.workspace_path.join("build").join(env_name);
let required_dirs = ["tofu"];
for dir_name in required_dirs {
let dir_path = build_dir.join(dir_name);
assert!(
dir_path.exists(),
"Build artifact directory '{dir_name}' should exist at: {}",
dir_path.display()
);
}
}
pub fn assert_environment_state_is(&self, env_name: &str, expected_state: &str) {
let env_data = self
.read_environment_json(env_name)
.expect("Failed to read environment JSON");
let state_key = env_data
.as_object()
.expect("Environment JSON should be an object")
.keys()
.next()
.expect("Environment should have a state key");
assert_eq!(
state_key, expected_state,
"Environment state should be '{expected_state}', but was '{state_key}'"
);
}
#[allow(dead_code)]
pub fn assert_data_directory_structure(&self, env_name: &str) {
let data_dir = self.workspace_path.join("data").join(env_name);
assert!(
data_dir.exists(),
"Data directory should exist at: {}",
data_dir.display()
);
let env_json = data_dir.join("environment.json");
assert!(
env_json.exists(),
"Environment JSON should exist at: {}",
env_json.display()
);
}
#[allow(dead_code)]
pub fn assert_trace_directory_exists(&self, env_name: &str) {
let traces_dir = self.workspace_path.join(env_name).join("traces");
assert!(
traces_dir.exists(),
"Traces directory should exist at: {}",
traces_dir.display()
);
}
fn environment_json_path(&self, env_name: &str) -> PathBuf {
self.workspace_path
.join("data")
.join(env_name)
.join("environment.json")
}
fn read_environment_json(&self, env_name: &str) -> Result<Value> {
let env_file_path = self.environment_json_path(env_name);
let content = fs::read_to_string(&env_file_path).context(format!(
"Failed to read environment file: {}",
env_file_path.display()
))?;
let json: Value =
serde_json::from_str(&content).context("Failed to parse environment JSON")?;
Ok(json)
}
}