diff --git a/crates/cli/tests/dynamic_linking_test.rs b/crates/cli/tests/dynamic_linking_test.rs index 4a079e11..37dd5a7f 100644 --- a/crates/cli/tests/dynamic_linking_test.rs +++ b/crates/cli/tests/dynamic_linking_test.rs @@ -4,7 +4,7 @@ use std::io::{Cursor, Read, Write}; use std::process::Command; use std::str; use uuid::Uuid; -use wasi_common::pipe::WritePipe; +use wasi_common::pipe::{ReadPipe, WritePipe}; use wasi_common::sync::WasiCtxBuilder; use wasi_common::WasiCtx; use wasmtime::{Config, Engine, ExternType, Linker, Module, Store}; @@ -14,7 +14,7 @@ mod common; #[test] pub fn test_dynamic_linking() -> Result<()> { let js_src = "console.log(42);"; - let log_output = invoke_fn_on_generated_module(js_src, "_start", None)?; + let log_output = invoke_fn_on_generated_module(js_src, "_start", None, None, None)?; assert_eq!("42\n", &log_output); Ok(()) } @@ -29,7 +29,8 @@ pub fn test_dynamic_linking_with_func() -> Result<()> { export foo-bar: func() } "; - let log_output = invoke_fn_on_generated_module(js_src, "foo-bar", Some((wit, "foo-test")))?; + let log_output = + invoke_fn_on_generated_module(js_src, "foo-bar", Some((wit, "foo-test")), None, None)?; assert_eq!("Toplevel\nIn foo\n", &log_output); Ok(()) } @@ -37,7 +38,7 @@ pub fn test_dynamic_linking_with_func() -> Result<()> { #[test] pub fn test_dynamic_linking_with_func_without_flag() -> Result<()> { let js_src = "export function foo() { console.log('In foo'); }; console.log('Toplevel');"; - let res = invoke_fn_on_generated_module(js_src, "foo", None); + let res = invoke_fn_on_generated_module(js_src, "foo", None, None, None); assert_eq!( "failed to find function export `foo`", res.err().unwrap().to_string() @@ -50,7 +51,7 @@ pub fn check_for_new_imports() -> Result<()> { // If you need to change this test, then you've likely made a breaking change. let js_src = "console.log(42);"; let wasm = create_dynamically_linked_wasm_module(js_src, None)?; - let (engine, _linker, _store) = create_wasm_env(WritePipe::new_in_memory())?; + let (engine, _linker, _store) = create_wasm_env(WritePipe::new_in_memory(), None, None)?; let module = Module::from_binary(&engine, &wasm)?; for import in module.imports() { match (import.module(), import.name(), import.ty()) { @@ -78,7 +79,7 @@ pub fn check_for_new_imports_for_exports() -> Result<()> { } "; let wasm = create_dynamically_linked_wasm_module(js_src, Some((wit, "foo-test")))?; - let (engine, _linker, _store) = create_wasm_env(WritePipe::new_in_memory())?; + let (engine, _linker, _store) = create_wasm_env(WritePipe::new_in_memory(), None, None)?; let module = Module::from_binary(&engine, &wasm)?; for import in module.imports() { match (import.module(), import.name(), import.ty()) { @@ -107,8 +108,13 @@ pub fn test_dynamic_linking_with_arrow_fn() -> Result<()> { export default: func() } "; - let log_output = - invoke_fn_on_generated_module(js_src, "default", Some((wit, "exported-arrow")))?; + let log_output = invoke_fn_on_generated_module( + js_src, + "default", + Some((wit, "exported-arrow")), + None, + None, + )?; assert_eq!("42\n", log_output); Ok(()) } @@ -120,6 +126,28 @@ fn test_producers_section_present() -> Result<()> { Ok(()) } +#[test] +fn javy_json_identity() -> Result<()> { + let src = r#" + console.log(Javy.JSON.toStdout(Javy.JSON.fromStdin())); + "#; + + let input = "{\"x\":5}"; + + let bytes = String::from(input).into_bytes(); + let stdin = Some(ReadPipe::from(bytes)); + let stdout = WritePipe::new_in_memory(); + let out = invoke_fn_on_generated_module(src, "_start", None, stdin, Some(stdout.clone()))?; + + assert_eq!(out, "undefined\n"); + assert_eq!( + String::from(input), + String::from_utf8(stdout.try_into_inner().unwrap().into_inner()).unwrap(), + ); + + Ok(()) +} + fn create_dynamically_linked_wasm_module( js_src: &str, wit: Option<(&str, &str)>, @@ -164,11 +192,13 @@ fn invoke_fn_on_generated_module( js_src: &str, func: &str, wit: Option<(&str, &str)>, + stdin: Option>>>, + stdout: Option>>>, ) -> Result { let js_wasm = create_dynamically_linked_wasm_module(js_src, wit)?; let stderr = WritePipe::new_in_memory(); - let (engine, mut linker, mut store) = create_wasm_env(stderr.clone())?; + let (engine, mut linker, mut store) = create_wasm_env(stderr.clone(), stdin, stdout)?; let quickjs_provider_module = common::create_quickjs_provider_module(&engine)?; let js_module = Module::from_binary(&engine, &js_wasm)?; @@ -190,11 +220,19 @@ fn invoke_fn_on_generated_module( fn create_wasm_env( stderr: WritePipe>>, + stdin: Option>>>, + stdout: Option>>>, ) -> Result<(Engine, Linker, Store)> { let engine = Engine::new(Config::new().wasm_multi_memory(true))?; let mut linker = Linker::new(&engine); wasi_common::sync::add_to_linker(&mut linker, |s| s)?; let wasi = WasiCtxBuilder::new().stderr(Box::new(stderr)).build(); + if let Some(stdout) = stdout { + wasi.set_stdout(Box::new(stdout)); + } + if let Some(stdin) = stdin { + wasi.set_stdin(Box::new(stdin)); + } let store = Store::new(&engine, wasi); Ok((engine, linker, store)) } diff --git a/crates/javy/src/apis/json.rs b/crates/javy/src/apis/json.rs index 8ce64802..ed467ef2 100644 --- a/crates/javy/src/apis/json.rs +++ b/crates/javy/src/apis/json.rs @@ -230,5 +230,6 @@ fn to_stdout(args: Args<'_>) -> Result<()> { let (_, args) = args.release(); let mut fd = std::io::stdout(); let buffer = json::stringify(args[0].clone())?; - fd.write_all(&buffer).map_err(Into::into) + fd.write_all(&buffer)?; + fd.flush().map_err(Into::into) }