use std::fs; use assert_cmd::Command; use predicates::prelude::*; use tempfile::tempdir; fn write_module(dir: &tempfile::TempDir, name: &str, source: &str) -> String { let path = dir.path().join(name); fs::write(&path, source).unwrap(); path.to_string_lossy().into_owned() } #[test] fn run_invoke_accepts_positional_args() { let dir = tempdir().unwrap(); let module = write_module( &dir, "add.wat", r#"(module (func (export "add") (param i32 i32) (result i32) local.get 0 local.get 1 i32.add))"#, ); Command::cargo_bin("tinywasm") .unwrap() .args(["run", "--invoke", "add", &module, "1", "2"]) .assert() .success() .stdout(predicate::str::contains("i32(3)")); } #[test] fn compile_and_run_twasm() { let dir = tempdir().unwrap(); let input = write_module( &dir, "add.wat", r#"(module (func (export "add") (param i32 i32) (result i32) local.get 0 local.get 1 i32.add))"#, ); let output = dir.path().join("add.twasm"); Command::cargo_bin("tinywasm") .unwrap() .args(["compile", &input, "-o", output.to_str().unwrap()]) .assert() .success(); Command::cargo_bin("tinywasm") .unwrap() .args(["run", "--invoke", "add", output.to_str().unwrap(), "3", "4"]) .assert() .success() .stdout(predicate::str::contains("i32(7)")); } #[test] fn bare_run_requires_default_entrypoint() { let dir = tempdir().unwrap(); let module = write_module(&dir, "add.wat", r#"(module (func (export "add") (result i32) i32.const 1))"#); Command::cargo_bin("tinywasm") .unwrap() .arg(&module) .assert() .failure() .stderr(predicate::str::contains("no start function or `_start` export")); } #[test] fn inspect_lists_exports() { let dir = tempdir().unwrap(); let module = write_module( &dir, "inspect.wat", r#"(module (memory (export "memory") 1) (func (export "answer") (result i32) i32.const 42))"#, ); Command::cargo_bin("tinywasm").unwrap().args(["inspect", &module]).assert().success().stdout( predicate::str::contains("answer: func () -> (i32)").and(predicate::str::contains("memory: memory[i32]")), ); } #[test] fn dump_prints_lowered_instructions() { let dir = tempdir().unwrap(); let module = write_module(&dir, "dump.wat", r#"(module (func (export "noop")))"#); Command::cargo_bin("tinywasm") .unwrap() .args(["dump", &module]) .assert() .success() .stdout(predicate::str::contains("func[0]").and(predicate::str::contains("0000:"))); } #[test] fn run_accepts_wat_from_stdin() { Command::cargo_bin("tinywasm") .unwrap() .args(["run", "--invoke", "add", "-", "8", "9"]) .write_stdin( r#"(module (func (export "add") (param i32 i32) (result i32) local.get 0 local.get 1 i32.add))"#, ) .assert() .success() .stdout(predicate::str::contains("i32(17)")); } #[test] fn wast_command_runs_simple_spec_script() { let dir = tempdir().unwrap(); let path = dir.path().join("simple.wast"); fs::write( &path, "(module (func (export \"add\") (result i32) i32.const 1))\n(assert_return (invoke \"add\") (i32.const 1))", ) .unwrap(); Command::cargo_bin("tinywasm") .unwrap() .args(["wast", path.to_str().unwrap()]) .assert() .success() .stdout(predicate::str::contains("Tests Passed:")); }