99 lines
3.0 KiB
Rust
99 lines
3.0 KiB
Rust
use std::fs;
|
|
use std::fs::File;
|
|
use std::io::Write;
|
|
use std::path::Path;
|
|
|
|
fn to_safe_identifier(name: &str) -> String {
|
|
let mut safe = String::new();
|
|
for (i, c) in name.chars().enumerate() {
|
|
if c.is_uppercase() {
|
|
if i > 0 {
|
|
safe.push('_');
|
|
}
|
|
safe.push(c.to_ascii_lowercase());
|
|
} else if c == '-' || c == '.' {
|
|
safe.push('_');
|
|
} else {
|
|
safe.push(c);
|
|
}
|
|
}
|
|
safe
|
|
}
|
|
|
|
fn main() {
|
|
println!("cargo:rerun-if-changed=fixtures");
|
|
println!("cargo:rerun-if-changed=Cargo.toml");
|
|
|
|
// File: src/tests/fixtures.rs for standard #[test] integration
|
|
let std_dest_path = Path::new("src/tests/fixtures.rs");
|
|
let mut std_file = File::create(std_dest_path).unwrap();
|
|
|
|
// Walk tests/fixtures directly
|
|
let fixtures_path = "fixtures";
|
|
if Path::new(fixtures_path).exists() {
|
|
for entry in fs::read_dir(fixtures_path).unwrap() {
|
|
let entry = entry.unwrap();
|
|
let path = entry.path();
|
|
if path.extension().unwrap_or_default() == "json" {
|
|
let file_name = path.file_stem().unwrap().to_str().unwrap();
|
|
|
|
// Parse the JSON file to find blocks
|
|
let file = File::open(&path).unwrap();
|
|
let val: serde_json::Value = serde_json::from_reader(file).unwrap();
|
|
|
|
if let Some(arr) = val.as_array() {
|
|
for (i, item) in arr.iter().enumerate() {
|
|
// Enforce test suite structure
|
|
let group = item.as_object().expect("Test suite must be an object");
|
|
|
|
// Validate required suite fields
|
|
if !group.contains_key("description")
|
|
|| !group.contains_key("database")
|
|
|| !group.contains_key("tests")
|
|
{
|
|
panic!(
|
|
"File {} index {} is missing required suite fields (description, database, tests)",
|
|
file_name, i
|
|
);
|
|
}
|
|
|
|
// Validate required test case fields
|
|
let tests = group
|
|
.get("tests")
|
|
.unwrap()
|
|
.as_array()
|
|
.expect("Tests must be an array");
|
|
for (t_idx, test) in tests.iter().enumerate() {
|
|
let t_obj = test.as_object().expect("Test case must be an object");
|
|
if !t_obj.contains_key("description") {
|
|
panic!(
|
|
"File {} suite {} test {} is missing required case fields (description)",
|
|
file_name, i, t_idx
|
|
);
|
|
}
|
|
}
|
|
|
|
// Use deterministic names: test_{filename}_{index}
|
|
let safe_filename = to_safe_identifier(file_name);
|
|
let fn_name = format!("test_{}_{}", safe_filename, i);
|
|
|
|
// Write to src/tests/fixtures.rs (Std Test)
|
|
write!(
|
|
std_file,
|
|
r#"
|
|
#[test]
|
|
fn {}() {{
|
|
let path = format!("{{}}/fixtures/{}.json", env!("CARGO_MANIFEST_DIR"));
|
|
crate::tests::runner::run_test_file_at_index(&path, {}).unwrap();
|
|
}}
|
|
"#,
|
|
fn_name, file_name, i
|
|
)
|
|
.unwrap();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|