feat(host): decode operation arguments in dispatch boundary

This commit is contained in:
2026-09-30 08:53:43 +09:00
parent 96db3dd6a8
commit fdfaa3a685
2 changed files with 198 additions and 28 deletions
+83
View File
@@ -741,6 +741,89 @@ fn call_failures_follow_canonical_precedence_without_execution() {
assert_eq!(provider.calls.get(), 0);
}
#[test]
fn descriptor_guided_decoder_runs_inside_canonical_resolution_boundary() {
let (_, provider, hidden) = registry_and_provider();
let decodes = Cell::new(0_u32);
let decode_failure = || {
decodes.set(decodes.get() + 1);
Err::<BTreeMap<String, Value>, _>(())
};
let missing = provider
.call_operation_with_context_and_decoder(
&ExecutionContext::new(),
Target {
path: "/missing".into(),
validator: Some(b"stale".to_vec()),
},
InterfaceTarget {
reference: hidden.reference().as_str().into(),
validator: None,
},
"missing".into(),
|_| decode_failure(),
)
.unwrap_err();
assert_eq!(missing.kind(), CallErrorKind::NotFound);
assert_eq!(decodes.get(), 0);
let stale = provider
.call_operation_with_context_and_decoder(
&ExecutionContext::new(),
Target {
path: "/document".into(),
validator: Some(b"stale".to_vec()),
},
InterfaceTarget {
reference: hidden.reference().as_str().into(),
validator: None,
},
"hidden".into(),
|_| decode_failure(),
)
.unwrap_err();
assert_eq!(stale.kind(), CallErrorKind::ValidatorMismatch);
assert_eq!(decodes.get(), 0);
let mismatch = provider
.call_operation_with_context_and_decoder(
&ExecutionContext::new(),
Target {
path: "/document".into(),
validator: Some(b"object-v1".to_vec()),
},
InterfaceTarget {
reference: hidden.reference().as_str().into(),
validator: None,
},
"hidden".into(),
|_| decode_failure(),
)
.unwrap_err();
assert_eq!(mismatch.kind(), CallErrorKind::InterfaceMismatch);
assert_eq!(decodes.get(), 0);
let invalid_arguments = provider
.call_operation_with_context_and_decoder(
&ExecutionContext::new(),
Target {
path: "/document".into(),
validator: Some(b"object-v1".to_vec()),
},
InterfaceTarget {
reference: provider.reader.reference().as_str().into(),
validator: Some(b"schema-v1".to_vec()),
},
"add".into(),
|_| decode_failure(),
)
.unwrap_err();
assert_eq!(invalid_arguments.kind(), CallErrorKind::InvalidArguments);
assert_eq!(decodes.get(), 1);
assert_eq!(provider.calls.get(), 0);
}
#[test]
fn immutable_interface_rejects_a_supplied_validator() {
let (_, provider, _) = registry_and_provider();