test(derive): close seventh mutation shard

Prove all state, async, and Result registration combinations and the exact no-generated-component repair diagnostic.

req: component/003

req: derive_handler/003

req: test/020

req: test/021

req: test/022

req: test/023
This commit is contained in:
slhx agent
2026-07-17 14:47:17 +02:00
parent d1af300bd4
commit 5d6486c22c
2 changed files with 64 additions and 7 deletions
+63 -6
View File
@@ -1016,13 +1016,14 @@ fn compile_error(message: &str) -> TokenStream {
mod tests {
use super::{
add_app_registry_helper, add_component_register_helper, client_handler_has_inputs,
component_handler_names, expand_handler_function, form_contract_errors, form_decode_fields,
form_fields, form_impl_generics, form_model_type, form_resource_id, generic_inner_type,
handle_params, handle_requires_form, handler_arg_names, handler_form_model_type,
handler_placement, handler_syms_path, has_form_param, has_non_unit_return, is_type_named,
component_contract_errors, component_handler_names, component_registration_call,
expand_handler_function, form_contract_errors, form_decode_fields, form_fields,
form_impl_generics, form_model_type, form_resource_id, generic_inner_type, handle_params,
handle_requires_form, handler_arg_names, handler_form_model_type, handler_placement,
handler_syms_path, has_form_param, has_non_unit_return, is_type_named,
join_contract_errors, missing_component_handlers, missing_form_generated_files_message,
missing_handle_params, missing_handler_generated_files_message, parser_type,
returns_result, rust_ident, syms_contains_handle, HandlerPlacement,
returns_result, rust_ident, syms_contains_handle, ComponentHandler, HandlerPlacement,
};
use quote::{quote, ToTokens};
use syn::{parse_quote, ItemFn, Type};
@@ -1469,6 +1470,55 @@ mod tests {
let _ = std::fs::remove_file(path);
}
#[test]
fn component_registration_selects_each_state_async_result_shape() {
let component_ident: syn::Ident = parse_quote!(todos);
let expected = [
(0, false, false, quote!(.on(super::todos::save, save))),
(0, false, true, quote!(.on_result(super::todos::save, save))),
(0, true, false, quote!(.on_async(super::todos::save, save))),
(
0,
true,
true,
quote!(.on_async_result(super::todos::save, save)),
),
(1, false, false, quote!(.on_state(super::todos::save, save))),
(
1,
false,
true,
quote!(.on_state_result(super::todos::save, save)),
),
(
1,
true,
false,
quote!(.on_state_async(super::todos::save, save)),
),
(
1,
true,
true,
quote!(.on_state_async_result(super::todos::save, save)),
),
];
for (typed_arg_count, is_async, returns_result, expected) in expected {
let handler = ComponentHandler {
ident: parse_quote!(save),
is_async,
returns_result,
typed_arg_count,
};
assert_eq!(
component_registration_call(&handler, &component_ident).to_string(),
expected.to_string(),
"args={typed_arg_count} async={is_async} result={returns_result}"
);
}
// test req: component/003 req: derive_handler/003
}
#[test]
fn component_handlers_match_generated_handles() {
let path = std::env::temp_dir().join("hemx-derive-component-test.syms");
@@ -1495,7 +1545,14 @@ mod tests {
vec!["delete"]
);
let _ = std::fs::remove_file(path);
let _ = std::fs::remove_file(&path);
assert_eq!(
component_contract_errors(&path, Some("missing"), &items),
vec![
"#[hemx::component(\"missing\")] does not match any generated handles; no generated components with handles are available; add a data-hemx-handle to the component template or check build.rs generation",
"#[hemx::component] handler(s) not declared by this component's generated handles: create; move them to the matching component module or add data-hemx-handle in .heml",
]
);
}
#[test]