test(build): lock canonical generated contracts

Hash complete generated Rust, global exports, and symbol manifests across component, keyed, collision, duplicate-class/event, form, and parameter branches; simplify root component exports and remove impossible target-fallback bookkeeping.

req: codegen/005

req: codegen/006

req: build/009

req: test/021
This commit is contained in:
slhx agent
2026-07-17 04:50:36 +02:00
parent 72bce73e52
commit 2ba0be4d24
2 changed files with 89 additions and 18 deletions
+88 -17
View File
@@ -548,7 +548,7 @@ impl Resources {
let root_indent = usize::default();
if global_exports {
self.push_component_refs(&mut out, root_indent);
self.push_component_refs(&mut out);
self.push_resource_modules(&mut out, &component_names, None, root_indent);
}
self.push_lowering_api(&mut out, None, root_indent);
@@ -567,19 +567,15 @@ impl Resources {
out
}
fn push_component_refs(&self, out: &mut String, indent: usize) {
let pad = " ".repeat(indent);
let inner = " ".repeat(indent + 1);
out.push_str(&format!(
"{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod components {{\n"
));
fn push_component_refs(&self, out: &mut String) {
out.push_str("#[allow(non_upper_case_globals)]\npub mod components {\n");
for component in self.component_names() {
out.push_str(&format!(
"{inner}pub const {component}: ::hemx::ComponentRef = ::hemx::ComponentRef::new({});\n",
" pub const {component}: ::hemx::ComponentRef = ::hemx::ComponentRef::new({});\n",
rust_str(&component)
));
}
out.push_str(&format!("{pad}}}\n"));
out.push_str("}\n");
}
fn push_resource_modules(
@@ -752,14 +748,8 @@ impl Resources {
.values()
.filter(|res| component_matches(res, component))
{
push_root_export(
out,
&pad,
"targets",
&mut root_exports,
&res.ident,
"target",
);
root_exports.insert(res.ident.clone());
out.push_str(&format!("{pad}pub use self::targets::{};\n", res.ident));
}
out.push('\n');
@@ -2453,6 +2443,87 @@ mod tests {
assert!(generated_with_globals.contains("pub mod advanced {"));
assert!(generated_with_globals.contains("pub mod slots {"));
let mut row_slot = resource("row", "row", 21);
row_slot.keyed = true;
resources.slots.insert("row".into(), row_slot);
resources
.handles
.insert("edit".into(), resource("edit", "row", 22));
resources
.atoms
.insert("selection".into(), resource("selection", "row", 23));
resources
.slots
.insert("child".into(), resource("child", "page", 24));
resources
.handles
.insert("child_handle".into(), resource("child_handle", "child", 25));
resources
.slots
.insert("shared".into(), resource("shared", "page", 26));
resources
.handles
.insert("shared".into(), resource("shared", "page", 27));
resources.forms.insert(
"shared".into(),
FormResource {
resource: resource("shared", "page", 28),
controls: Vec::new(),
},
);
for (symbol, ident, component, token) in [
("a::card", "card", "page", "card"),
("b::card", "card", "row", "card"),
("z::last", "last", "page", "last"),
] {
resources.classes.insert(
symbol.into(),
ClassToken {
symbol: symbol.into(),
ident: ident.into(),
component: component.into(),
token: token.into(),
},
);
}
for (component, name) in [("page", "click"), ("row", "click"), ("z", "submit")] {
resources.events.insert(
format!("{component}::{name}"),
EventToken {
symbol: format!("{component}::{name}"),
ident: name.into(),
component: component.into(),
name: name.into(),
},
);
}
resources
.handle_forms
.insert("save".into(), "profile".into());
resources
.handle_params
.entry("save".into())
.or_default()
.insert("item_id".into());
let canonical_generated = resources.generated_rs(false);
let canonical_globals = resources.generated_rs(true);
let canonical_syms = resources.syms();
assert_eq!(
stable_id("generated-rs", &canonical_generated),
3_748_714_336,
"canonical generated Rust changed"
);
assert_eq!(
stable_id("generated-rs-global", &canonical_globals),
2_783_766_475,
"canonical global-export Rust changed"
);
assert_eq!(
stable_id("generated-syms", &canonical_syms),
984_222_700,
"canonical symbol manifest changed"
);
assert_eq!(Resources::default().client_bootstrap().unwrap(), "");
resources
.client_handlers