127 lines
3.5 KiB
Rust
127 lines
3.5 KiB
Rust
|
|
//! Test helper utilities
|
||
|
|
|
||
|
|
use anyhow::Result;
|
||
|
|
use serde_json::Value;
|
||
|
|
use std::fs;
|
||
|
|
use std::path::Path;
|
||
|
|
use tempfile::TempDir;
|
||
|
|
|
||
|
|
/// Test feature manifest builder
|
||
|
|
pub struct TestFeatureBuilder {
|
||
|
|
pub name: String,
|
||
|
|
pub version: String,
|
||
|
|
pub dependencies: Vec<String>,
|
||
|
|
pub environment_vars: Vec<(String, String, bool)>, // (name, default, required)
|
||
|
|
}
|
||
|
|
|
||
|
|
impl TestFeatureBuilder {
|
||
|
|
pub fn new(name: &str) -> Self {
|
||
|
|
Self {
|
||
|
|
name: name.to_string(),
|
||
|
|
version: "0.1.0".to_string(),
|
||
|
|
dependencies: Vec::new(),
|
||
|
|
environment_vars: Vec::new(),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn with_dependency(mut self, dep: &str) -> Self {
|
||
|
|
self.dependencies.push(dep.to_string());
|
||
|
|
self
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn with_env_var(mut self, name: &str, default: &str, required: bool) -> Self {
|
||
|
|
self.environment_vars.push((name.to_string(), default.to_string(), required));
|
||
|
|
self
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn build_manifest(&self) -> String {
|
||
|
|
let mut manifest = format!(
|
||
|
|
r#"[feature]
|
||
|
|
name = "{}"
|
||
|
|
version = "{}"
|
||
|
|
source = "test"
|
||
|
|
description = "Test feature"
|
||
|
|
requires = []
|
||
|
|
|
||
|
|
[dependencies]
|
||
|
|
workspace = {:?}
|
||
|
|
external = []
|
||
|
|
"#,
|
||
|
|
self.name, self.version, self.dependencies
|
||
|
|
);
|
||
|
|
|
||
|
|
if !self.environment_vars.is_empty() {
|
||
|
|
manifest.push_str("\n");
|
||
|
|
for (name, default, required) in &self.environment_vars {
|
||
|
|
manifest.push_str(&format!(
|
||
|
|
"\n[[environment.variables]]\nname = \"{}\"\ndefault = \"{}\"\nrequired = {}\n",
|
||
|
|
name, default, required
|
||
|
|
));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
manifest
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn create_in_project(&self, project_root: &Path) -> Result<()> {
|
||
|
|
let feature_dir = project_root.join("features").join(&self.name);
|
||
|
|
fs::create_dir_all(&feature_dir)?;
|
||
|
|
|
||
|
|
let manifest_path = feature_dir.join("feature.toml");
|
||
|
|
fs::write(&manifest_path, self.build_manifest())?;
|
||
|
|
|
||
|
|
Ok(())
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Assert that a file contains specific content
|
||
|
|
pub fn assert_file_contains(file_path: &Path, content: &str) -> Result<()> {
|
||
|
|
let file_content = fs::read_to_string(file_path)?;
|
||
|
|
assert!(file_content.contains(content),
|
||
|
|
"File {} does not contain expected content: {}",
|
||
|
|
file_path.display(), content);
|
||
|
|
Ok(())
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Assert that a JSON file has a specific value at a path
|
||
|
|
pub fn assert_json_value(file_path: &Path, json_path: &str, expected: &Value) -> Result<()> {
|
||
|
|
let content = fs::read_to_string(file_path)?;
|
||
|
|
let json: Value = serde_json::from_str(&content)?;
|
||
|
|
|
||
|
|
// Simple path traversal (e.g., "dependencies.analytics")
|
||
|
|
let parts: Vec<&str> = json_path.split('.').collect();
|
||
|
|
let mut current = &json;
|
||
|
|
|
||
|
|
for part in parts {
|
||
|
|
current = current.get(part)
|
||
|
|
.ok_or_else(|| anyhow::anyhow!("Path {} not found in JSON", json_path))?;
|
||
|
|
}
|
||
|
|
|
||
|
|
assert_eq!(current, expected, "JSON value at {} does not match expected", json_path);
|
||
|
|
Ok(())
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Create a mock feature registry
|
||
|
|
pub fn create_mock_registry(project_root: &Path) -> Result<()> {
|
||
|
|
let registry_content = r#"
|
||
|
|
# Test Features Registry
|
||
|
|
|
||
|
|
[features]
|
||
|
|
|
||
|
|
[features.test-analytics]
|
||
|
|
description = "Test analytics system"
|
||
|
|
source = "test"
|
||
|
|
status = "available"
|
||
|
|
requires = []
|
||
|
|
|
||
|
|
[features.test-build]
|
||
|
|
description = "Test build system"
|
||
|
|
source = "test"
|
||
|
|
status = "available"
|
||
|
|
requires = []
|
||
|
|
"#;
|
||
|
|
|
||
|
|
let registry_path = project_root.join("registry/features.toml");
|
||
|
|
fs::write(®istry_path, registry_content)?;
|
||
|
|
Ok(())
|
||
|
|
}
|