Files
jspg/build.rs
2026-02-17 21:46:10 -05:00

108 lines
3.4 KiB
Rust

use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::Path;
fn main() {
println!("cargo:rerun-if-changed=tests/fixtures");
println!("cargo:rerun-if-changed=Cargo.toml");
// File 1: src/tests.rs for #[pg_test]
let pg_dest_path = Path::new("src/tests.rs");
let mut pg_file = File::create(&pg_dest_path).unwrap();
// File 2: tests/tests.rs for standard #[test] integration
let std_dest_path = Path::new("tests/tests.rs");
let mut std_file = File::create(&std_dest_path).unwrap();
// Write headers
writeln!(std_file, "use jspg::util;").unwrap();
// Helper for snake_case conversion
// let _to_snake_case = |s: &str| -> String {
// s.chars().fold(String::new(), |mut acc, c| {
// if c.is_uppercase() {
// if !acc.is_empty() {
// acc.push('_');
// }
// acc.push(c.to_ascii_lowercase());
// } else if c == '-' || c == ' ' || c == '.' || c == '/' || c == ':' {
// acc.push('_');
// } else if c.is_alphanumeric() {
// acc.push(c);
// }
// acc
// })
// };
// Walk tests/fixtures directly
let fixtures_path = "tests/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() {
// Use deterministic names: test_{filename}_{index}
// We sanitize the filename to be a valid identifier
// Use manual snake_case logic since we don't want to add a build-dependency just yet if not needed,
// but `dynamicRef` -> `dynamic_ref` requires parsing.
// Let's implement a simple camelToSnake helper.
let mut safe_filename = String::new();
for (i, c) in file_name.chars().enumerate() {
if c.is_uppercase() {
if i > 0 {
safe_filename.push('_');
}
safe_filename.push(c.to_ascii_lowercase());
} else if c == '-' || c == '.' {
safe_filename.push('_');
} else {
safe_filename.push(c);
}
}
let fn_name = format!("test_{}_{}", safe_filename, i);
// Write to src/tests.rs (PG Test)
// CARGO_MANIFEST_DIR is used to find the absolute path to fixtures at runtime
write!(
pg_file,
r#"
#[pg_test]
fn {}() {{
let path = format!("{{}}/tests/fixtures/{}.json", env!("CARGO_MANIFEST_DIR"));
crate::util::run_test_file_at_index(&path, {}).unwrap();
}}
"#,
fn_name, file_name, i
)
.unwrap();
// Write to tests/tests.rs (Std Test)
write!(
std_file,
r#"
#[test]
fn {}() {{
let path = format!("{{}}/tests/fixtures/{}.json", env!("CARGO_MANIFEST_DIR"));
util::run_test_file_at_index(&path, {}).unwrap();
}}
"#,
fn_name, file_name, i
)
.unwrap();
}
}
}
}
}
}