Lines
100 %
Functions
Branches
//! Shape contracts for eval-mode wasm modules. The rpc eval channel
//! depends on these exports being present; without them host fns that
//! produce typed entity returns (`list-accounts`, `get-account`, ...)
//! trap at runtime with "module missing 'alloc_<kind>' export".
use nomiscript::{Compiler, Program, Reader};
use wasmparser::{ExternalKind, Parser, Payload};
fn module_export_names(wasm: &[u8]) -> Vec<String> {
let mut names = Vec::new();
for payload in Parser::new(0).parse_all(wasm) {
let payload = payload.expect("wasm parse");
if let Payload::ExportSection(reader) = payload {
for export in reader {
let export = export.expect("export read");
if matches!(export.kind, ExternalKind::Func) {
names.push(export.name.to_string());
}
names
/// Eval-mode modules register the per-entity `alloc_<kind>` helpers
/// (one `struct.new` over the typed fields). They MUST also be
/// exported — host fns reach them via `caller.get_export("alloc_<kind>")`
/// when producing entity refs from `server::command::*` results.
/// The helpers stay unexported in script mode where they aren't
/// needed.
#[test]
fn eval_mode_exports_every_entity_allocator() {
let program: Program = Reader::parse("nil").unwrap();
let mut compiler = Compiler::new();
let mut symbols = nomiscript::SymbolTable::with_builtins();
let (bytes, _ty) = compiler
.compile_eval_with_type(&program, &mut symbols)
.expect("compile eval");
let exports = module_export_names(&bytes);
let required = [
"alloc_account",
"alloc_commodity_entity",
"alloc_transaction",
"alloc_split",
"alloc_tag_entity",
"alloc_price",
"alloc_ssh_key",
];
for name in required {
assert!(
exports.iter().any(|e| e == name),
"eval-mode module missing export {name:?}. exports: {exports:?}"
);
fn eval_mode_exports_nomi_eval_and_pair_new() {
// Sanity check: locks in the public-export surface so a regression
// in one of the canonical exports trips immediately.
assert!(exports.contains(&"nomi-eval".to_string()), "{exports:?}");
assert!(exports.contains(&"pair_new".to_string()), "{exports:?}");