Skip to content

Commit ad41a25

Browse files
author
ffonion
committed
test(compiler): cover TypeSchema resource round-trip and invalid-key rejection
1 parent 3113d02 commit ad41a25

1 file changed

Lines changed: 45 additions & 1 deletion

File tree

tests/wire/wire_tests.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use std::collections::HashMap;
22

3+
use vm::compiler::TypeSchema;
34
use vm::{
45
ArgInfo, Assembler, BuiltinFunction, BytecodeBuilder, CallableKind, CallablePrototype,
56
CallableTarget, DebugFunction, DebugInfo, DisassembleOptions, HostImport, LineInfo, LocalInfo,
67
Program, ScriptFunction, TypeMap, ValidationError, Value, ValueType, WireError,
78
builtin_call_index, decode_program, disassemble_vmbc, disassemble_vmbc_with_options,
8-
encode_program, infer_local_count, validate_program,
9+
encode_program, infer_local_count, validate_program, HostApiCatalog, ResourceTypeKey,
910
};
1011

1112
#[test]
@@ -787,3 +788,46 @@ fn call_script_no_script_program_code_bytes_unchanged_by_version_bump() {
787788
assert_eq!(decoded.code, program.code);
788789
assert_eq!(decoded.constants, program.constants);
789790
}
791+
792+
#[test]
793+
fn schema_round_trip_resource_wire_nominally() {
794+
// A nominal host resource must round-trip through the shared wire
795+
// type-schema encoding (tag 17), preserving its identity as a resource
796+
// rather than being flattened into a structural type.
797+
let key = vm::ResourceTypeKey::new("io.file").expect("valid key");
798+
let schema = vm::compiler::TypeSchema::Resource(key.clone());
799+
let program = vm::Program::new(Vec::new(), Vec::new()).with_type_map(vm::TypeMap {
800+
strict_types: false,
801+
local_types: vec![vm::ValueType::Int],
802+
local_schemas: vec![Some(schema.clone())],
803+
callable_slots: vec![false],
804+
optional_slots: vec![false],
805+
operand_types: HashMap::new(),
806+
});
807+
808+
let encoded = vm::encode_program(&program).expect("encode should succeed");
809+
let decoded = vm::decode_program(&encoded).expect("decode should succeed");
810+
assert_eq!(decoded.type_map, program.type_map);
811+
assert_eq!(
812+
decoded.type_map.as_ref().and_then(|tm| tm.local_schemas[0].as_ref()),
813+
Some(&TypeSchema::Resource(key))
814+
);
815+
}
816+
817+
#[test]
818+
fn malformed_resource_key_is_rejected_on_read() {
819+
// A resource key that violates the resource-key grammar must be rejected by the
820+
// key's own Deserialize impl.
821+
assert!(ResourceTypeKey::new("has space").is_err());
822+
assert!(ResourceTypeKey::new("").is_err());
823+
assert!(ResourceTypeKey::new(".leading").is_err());
824+
825+
// ... and a malformed key hiding inside a catalog's resources must also fail
826+
// catalog deserialization (serde runs the same validation).
827+
let mut v = serde_json::json!({
828+
"resources": [{ "key": "io.file", "description": "file" }],
829+
"functions": []
830+
});
831+
v["resources"][0]["key"] = serde_json::json!("bad key");
832+
assert!(serde_json::from_value::<HostApiCatalog>(v).is_err());
833+
}

0 commit comments

Comments
 (0)