test(build): prove public inspection contracts
Exercise file and source diagnostics, generated targets, Hemlate-derived context facts, missing-file propagation, and invalid Rust context through hemx-build's public inspection API; classify only the currently infallible hemplate parser seam. req: diagnostics/004 req: diagnostics/006 req: surface/008 req: test/021
This commit is contained in:
@@ -2326,6 +2326,93 @@ fn parse_error(path: &Path, err: impl std::fmt::Display) -> io::Error {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn public_heml_inspection_entry_points_preserve_paths_and_io_diagnostics() {
|
||||
let root = std::env::temp_dir().join(format!(
|
||||
"hemx-build-inspection-{}-{}",
|
||||
std::process::id(),
|
||||
std::thread::current().name().unwrap_or("test")
|
||||
));
|
||||
std::fs::create_dir_all(&root).unwrap();
|
||||
let template = root.join("card.heml");
|
||||
let source = r#"<template h-for="todo in &self.todos"><button data-hemx-handle="save">Save</button></template>"#;
|
||||
std::fs::write(&template, source).unwrap();
|
||||
|
||||
let from_source = diagnostics_for_heml_source(&template, source.to_owned()).unwrap();
|
||||
let from_file = diagnostics_for_heml_file(&template).unwrap();
|
||||
assert_eq!(from_file, from_source);
|
||||
assert_eq!(from_source.len(), 1);
|
||||
assert_eq!(from_source[0].file, template);
|
||||
assert_eq!(from_source[0].directive, "data-hemx-handle");
|
||||
|
||||
let targets = generated_targets_for_heml_source(
|
||||
&template,
|
||||
r#"<main data-hemx-root="app"><section h-slot="notice"></section><button data-hemx-handle="save">Save</button></main>"#,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(targets.len(), 1);
|
||||
assert_eq!(targets[0].name, "save");
|
||||
assert_eq!(
|
||||
template_context_facts_for_heml_source(
|
||||
&template,
|
||||
"<main>{{ self.title }}</main>".to_owned(),
|
||||
)
|
||||
.unwrap(),
|
||||
None
|
||||
);
|
||||
let crate_root = root.join("crate");
|
||||
let templates = crate_root.join("templates");
|
||||
std::fs::create_dir_all(crate_root.join("src")).unwrap();
|
||||
std::fs::create_dir_all(&templates).unwrap();
|
||||
std::fs::write(
|
||||
crate_root.join("Cargo.toml"),
|
||||
"[package]\nname='facts'\nversion='0.0.0'\n",
|
||||
)
|
||||
.unwrap();
|
||||
std::fs::write(
|
||||
crate_root.join("src/lib.rs"),
|
||||
"#[derive(Hemplate)] struct Profile { title: String }\nstruct Plain { title: String }",
|
||||
)
|
||||
.unwrap();
|
||||
let profile = templates.join("profile.heml");
|
||||
let facts = template_context_facts_for_heml_source(
|
||||
&profile,
|
||||
"<main>{{ self.title }}</main>".to_owned(),
|
||||
)
|
||||
.unwrap()
|
||||
.expect("Hemlate-derived context facts");
|
||||
assert_eq!(facts.context_type, "Profile");
|
||||
assert_eq!(facts.self_fields[0].name, "title");
|
||||
std::fs::write(crate_root.join("src/broken.rs"), [0xff]).unwrap();
|
||||
assert_eq!(
|
||||
template_context_facts_for_heml_source(
|
||||
&profile,
|
||||
"<main>{{ self.title }}</main>".to_owned(),
|
||||
)
|
||||
.unwrap_err()
|
||||
.kind(),
|
||||
io::ErrorKind::InvalidData
|
||||
);
|
||||
std::fs::remove_file(crate_root.join("src/broken.rs")).unwrap();
|
||||
assert_eq!(
|
||||
template_context_facts_for_heml_source(
|
||||
templates.join("plain.heml"),
|
||||
"<main>{{ self.title }}</main>".to_owned(),
|
||||
)
|
||||
.unwrap(),
|
||||
None
|
||||
);
|
||||
let missing = root.join("missing.heml");
|
||||
for error in [
|
||||
diagnostics_for_heml_file(&missing).unwrap_err(),
|
||||
template_context_facts_for_heml_file(&missing).unwrap_err(),
|
||||
] {
|
||||
assert_eq!(error.kind(), io::ErrorKind::NotFound);
|
||||
}
|
||||
let _ = std::fs::remove_dir_all(root);
|
||||
// test req: diagnostics/004 req: diagnostics/006 req: surface/008
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generated_contract_fingerprint_and_client_bootstrap_are_deterministic() {
|
||||
let resource = |symbol: &str, component: &str, id| Resource {
|
||||
|
||||
Reference in New Issue
Block a user