use std::path::Path; #[test] fn no_host_imports() { let wasm_path = "target/wasm32-unknown-unknown/release/docs_core.wasm"; // DOCS_REQUIRE_WASM=1 is set by the CI gate, which always builds the // wasm artifact before running this test — so under the gate a missing // artifact is a real failure, not something to shrug off. Left unset, // a bare `cargo test` on a fresh clone (no wasm build yet) still skips, // so local iteration on the native tests isn't forced to build wasm // first. let require_wasm = std::env::var("DOCS_REQUIRE_WASM").as_deref() == Ok("1"); if !Path::new(wasm_path).exists() { if require_wasm { panic!( "FAILED (DOCS_REQUIRE_WASM=1): wasm artifact not found at {}. \ The gate must build it before running this test.", wasm_path ); } eprintln!( "SKIPPED (DOCS_REQUIRE_WASM unset): wasm artifact not found at {}. \ Run ./scripts/build-wasm.sh first.", wasm_path ); return; } let wasm_bytes = std::fs::read(wasm_path).expect("Failed to read wasm file"); let parser = wasmparser::Parser::new(0); let mut imports = Vec::new(); for payload in parser.parse_all(&wasm_bytes) { let payload = payload.expect("Failed to parse wasm module"); if let wasmparser::Payload::ImportSection(reader) = payload { let import_reader = reader.into_imports(); for import_result in import_reader { let import = import_result.expect("Failed to parse import"); imports.push(format!("{}.{}", import.module, import.name)); } } } if !imports.is_empty() { panic!( "WASM module has host imports (breaks Go/wazero compatibility):\n {}", imports.join("\n ") ); } eprintln!("PASSED (checked {} bytes, 0 imports)", wasm_bytes.len()); }