use std::path::{Path, PathBuf};
use std::process::Command;
fn fixture(name: &str) -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures")
.join(name)
}
fn tmp(tag: &str) -> PathBuf {
let dir = std::env::temp_dir().join(format!("xpile_emit_crate_{}_{}", tag, std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
dir
}
fn emit(fixture_name: &str, dir: &Path) -> std::process::Output {
Command::new(env!("CARGO_BIN_EXE_xpile"))
.arg("transpile")
.arg(fixture(fixture_name))
.arg("--emit-crate")
.arg(dir)
.output()
.expect("run xpile transpile --emit-crate")
}
#[test]
fn emit_crate_writes_buildable_binary_crate() {
let dir = tmp("linear");
let out = emit("emit_crate_linear.py", &dir);
assert!(
out.status.success(),
"emit-crate must exit 0:\n{}",
String::from_utf8_lossy(&out.stderr)
);
let cargo = std::fs::read_to_string(dir.join("Cargo.toml")).expect("Cargo.toml written");
let main = std::fs::read_to_string(dir.join("src/main.rs")).expect("src/main.rs written");
assert!(
cargo.contains("[[bin]]"),
"Cargo.toml declares a bin target:\n{cargo}"
);
assert!(
cargo.contains("name = \"emit_crate_linear\""),
"crate is named from the file stem:\n{cargo}"
);
assert!(
main.contains("pub fn predict"),
"emitted fn present:\n{main}"
);
assert!(
main.contains("fn main("),
"runnable entry point present:\n{main}"
);
assert!(
!cargo.contains("indexmap"),
"a scalar program needs no indexmap dep:\n{cargo}"
);
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn emit_crate_adds_indexmap_only_for_dict() {
let dir = tmp("dict");
let out = emit("emit_crate_dict.py", &dir);
assert!(
out.status.success(),
"emit-crate must exit 0:\n{}",
String::from_utf8_lossy(&out.stderr)
);
let cargo = std::fs::read_to_string(dir.join("Cargo.toml")).expect("Cargo.toml written");
assert!(
cargo.contains("indexmap = \"2\""),
"a dict-using program pulls in the indexmap dep:\n{cargo}"
);
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn emit_crate_rejects_non_rust_target() {
let dir = tmp("reject");
let out = Command::new(env!("CARGO_BIN_EXE_xpile"))
.arg("transpile")
.arg(fixture("emit_crate_linear.py"))
.arg("--target")
.arg("wasm")
.arg("--emit-crate")
.arg(&dir)
.output()
.expect("run xpile transpile --emit-crate --target wasm");
assert!(
!out.status.success(),
"--emit-crate with --target wasm must be refused"
);
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(
stderr.contains("--emit-crate"),
"the error names the flag:\n{stderr}"
);
let _ = std::fs::remove_dir_all(&dir);
}