fix(build): dispatch slot targets to matching component render/put

req: runtime/005

req: examples/001

req: htmx_equivalents/001
This commit is contained in:
slhx agent
2026-06-23 15:06:08 +02:00
parent cfa4502748
commit 329f16aebf
5 changed files with 131 additions and 23 deletions
+3
View File
@@ -5,3 +5,6 @@ edition.workspace = true
[dependencies]
hemx-core = { path = "../hemx-core" }
[dev-dependencies]
hemx-build = { path = "../hemx-build" }
+45
View File
@@ -278,6 +278,51 @@ fn browser_e2e_does_not_shortcut_product_interactions() {
);
}
#[test]
fn html_examples_slot_targets_dispatch_to_component_put() {
// req: runtime/005 req: examples/001 req: htmx_equivalents/001
// Regression: slots named after a component (e.g. contact_card, editable_row)
// must lower injected partials using that component's handle table, not the
// containing page's handle table.
let root = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap();
let template_dir = root.join("examples/html_examples/templates");
let out_dir = std::env::temp_dir().join(format!(
"hemx-test-html-examples-slot-targets-{}",
std::process::id()
));
let _ = std::fs::remove_dir_all(&out_dir);
std::fs::create_dir_all(&out_dir).unwrap();
let result = std::panic::catch_unwind(|| {
hemx_build::app()
.template_dir(&template_dir)
.out_dir(&out_dir)
.run()
.expect("hemx-build should generate html_examples artifacts");
let generated =
std::fs::read_to_string(out_dir.join("hemx.generated.rs")).unwrap_or_default();
for component in ["contact_card", "editable_row"] {
let component_path = format!("super::super::{component}");
let impl_header = format!("impl<T> SlotTarget<T, {component_path}::Component>");
let put_call = format!("{component_path}::put(self.slot, view)");
assert!(
generated.contains(&impl_header),
"gallery::targets should have a component-specific SlotTarget impl for `{component}`; missing `{impl_header}`"
);
assert!(
generated.contains(&put_call),
"gallery::targets::{component} put/replace should dispatch to `{component_path}::put`; missing `{put_call}`"
);
}
});
let _ = std::fs::remove_dir_all(&out_dir);
result.unwrap();
}
fn scan_examples(dir: &Path, visit: &mut impl FnMut(&Path, &str)) {
for entry in std::fs::read_dir(dir).unwrap() {
let entry = entry.unwrap();