feat(v1): harden typed runtime boundaries
Elect one canonical EffectBatch codec, remove the parallel postcard API, and strengthen fail-closed host, form, sync, WASM, macro, generated-contract, and test-harness proofs with mutation-driven coverage. req: wire/008 req: wire/009 req: wire/010 req: push/008 req: client_local/015 req: client_local/016 req: client_local/017 req: client_local/018 req: client_local/019 req: sync/024 req: sync/025 req: sync/026 req: sync/027 req: sync/028 req: sync/029 req: test/020 req: test/021
This commit is contained in:
+63
-2
@@ -985,12 +985,73 @@ fn compile_error(message: &str) -> TokenStream {
|
||||
mod tests {
|
||||
use super::{
|
||||
add_app_registry_helper, add_component_register_helper, component_handler_names,
|
||||
form_model_type, handle_params, handle_requires_form, has_form_param, has_non_unit_return,
|
||||
missing_component_handlers, missing_handle_params, parser_type, syms_contains_handle,
|
||||
form_model_type, handle_params, handle_requires_form, handler_form_model_type,
|
||||
has_form_param, has_non_unit_return, missing_component_handlers, missing_handle_params,
|
||||
parser_type, returns_result, syms_contains_handle,
|
||||
};
|
||||
use quote::quote;
|
||||
use syn::{parse_quote, ItemFn, Type};
|
||||
|
||||
#[test]
|
||||
fn handler_type_helpers_recognize_only_the_public_form_and_result_shapes() {
|
||||
let bare: Type = parse_quote!(Form<String>);
|
||||
let qualified: Type = parse_quote!(hemx::Form<crate::Input>);
|
||||
let wrong_module: Type = parse_quote!(other::Form<String>);
|
||||
let missing_model: Type = parse_quote!(hemx::Form);
|
||||
let unrelated: Type = parse_quote!(String);
|
||||
assert_eq!(quote!(#bare).to_string(), "Form < String >");
|
||||
assert_eq!(
|
||||
quote!(#qualified).to_string(),
|
||||
"hemx :: Form < crate :: Input >"
|
||||
);
|
||||
assert!(form_model_type(&bare).is_some());
|
||||
assert!(form_model_type(&qualified).is_some());
|
||||
assert!(form_model_type(&wrong_module).is_none());
|
||||
assert!(form_model_type(&missing_model).is_none());
|
||||
assert!(form_model_type(&unrelated).is_none());
|
||||
|
||||
let function: ItemFn = parse_quote!(
|
||||
fn save(
|
||||
first: hemx::Form<crate::First>,
|
||||
value: String,
|
||||
last: Form<crate::Last>,
|
||||
) -> Result<(), Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
quote!(#function)
|
||||
.to_string()
|
||||
.contains("last : Form < crate :: Last >"),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
quote!(#function)
|
||||
.to_string()
|
||||
.contains("first : hemx :: Form < crate :: First >"),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
handler_form_model_type(&function)
|
||||
.map(|ty| quote!(#ty).to_string())
|
||||
.as_deref(),
|
||||
Some("crate :: Last")
|
||||
);
|
||||
assert!(returns_result(&function.sig.output));
|
||||
|
||||
let no_result: ItemFn = parse_quote!(
|
||||
fn save() -> String {
|
||||
String::new()
|
||||
}
|
||||
);
|
||||
let no_return: ItemFn = parse_quote!(
|
||||
fn save() {}
|
||||
);
|
||||
assert!(!returns_result(&no_result.sig.output));
|
||||
assert!(!returns_result(&no_return.sig.output));
|
||||
// test req: derive_handler/001 req: derive_handler/005
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn syms_lookup_matches_handle_ident() {
|
||||
let path = std::env::temp_dir().join("hemx-derive-syms-test.syms");
|
||||
|
||||
Reference in New Issue
Block a user