From 665785e690b501ce578128cde5d039263f856167 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Wed, 3 Jun 2020 19:18:08 +0200 Subject: [PATCH] add deno test mode, enabled by WASM_BINDGEN_USE_DENO=1 --- .../src/bin/wasm-bindgen-test-runner/deno.rs | 73 +++++++++++++++++++ .../src/bin/wasm-bindgen-test-runner/main.rs | 5 ++ .../src/bin/wasm-bindgen-test-runner/node.rs | 71 +++++++++--------- 3 files changed, 116 insertions(+), 33 deletions(-) create mode 100644 crates/cli/src/bin/wasm-bindgen-test-runner/deno.rs diff --git a/crates/cli/src/bin/wasm-bindgen-test-runner/deno.rs b/crates/cli/src/bin/wasm-bindgen-test-runner/deno.rs new file mode 100644 index 00000000..a0b05cdb --- /dev/null +++ b/crates/cli/src/bin/wasm-bindgen-test-runner/deno.rs @@ -0,0 +1,73 @@ +use std::ffi::OsString; +use std::fs; +use std::path::Path; +use std::process::Command; + +use anyhow::{Context, Error}; + +use crate::node::{exec, SHARED_SETUP}; + +pub fn execute( + module: &str, + tmpdir: &Path, + args: &[OsString], + tests: &[String], +) -> Result<(), Error> { + let mut js_to_execute = format!( + r#"import * as wasm from "./{0}.js"; + + {console_override} + + // global.__wbg_test_invoke = f => f(); + + // Forward runtime arguments. These arguments are also arguments to the + // `wasm-bindgen-test-runner` which forwards them to deno which we + // forward to the test harness. this is basically only used for test + // filters for now. + cx.args(Deno.args.slice(1)); + + const ok = await cx.run(tests.map(n => wasm.__wasm[n])); + if (!ok) Deno.exit(1); + + const tests = []; + "#, + module, + console_override = SHARED_SETUP, + ); + + for test in tests { + js_to_execute.push_str(&format!("tests.push('{}')\n", test)); + } + + let js_path = tmpdir.join("run.js"); + fs::write(&js_path, js_to_execute).context("failed to write JS file")?; + + /* + // Augment `NODE_PATH` so things like `require("tests/my-custom.js")` work + // and Rust code can import from custom JS shims. This is a bit of a hack + // and should probably be removed at some point. + let path = env::var("NODE_PATH").unwrap_or_default(); + let mut path = env::split_paths(&path).collect::>(); + path.push(env::current_dir().unwrap()); + path.push(tmpdir.to_path_buf()); + let extra_node_args = env::var("NODE_ARGS") + .unwrap_or_default() + .split(",") + .map(|s| s.to_string()) + .filter(|s| !s.is_empty()) + .collect::>(); + exec( + Command::new("node") + .env("NODE_PATH", env::join_paths(&path).unwrap()) + .args(&extra_node_args) + .arg(&js_path) + .args(args), + )*/ + exec( + Command::new("deno") + .arg("run") + .arg("--allow-read") + .arg(&js_path) + .args(args), + ) +} diff --git a/crates/cli/src/bin/wasm-bindgen-test-runner/main.rs b/crates/cli/src/bin/wasm-bindgen-test-runner/main.rs index 45e06a1c..95a82601 100644 --- a/crates/cli/src/bin/wasm-bindgen-test-runner/main.rs +++ b/crates/cli/src/bin/wasm-bindgen-test-runner/main.rs @@ -22,6 +22,7 @@ use wasm_bindgen_cli_support::Bindgen; #[global_allocator] static ALLOC: std::alloc::System = std::alloc::System; +mod deno; mod headless; mod node; mod server; @@ -30,6 +31,7 @@ mod shell; #[derive(Debug, Copy, Clone, Eq, PartialEq)] enum TestMode { Node, + Deno, Browser, } @@ -92,6 +94,7 @@ fn main() -> anyhow::Result<()> { let test_mode = match custom_section { Some(section) if section.data.contains(&0x01) => TestMode::Browser, Some(_) => bail!("invalid __wasm_bingen_test_unstable value"), + None if std::env::var("WASM_BINDGEN_USE_DENO").is_ok() => TestMode::Deno, None => TestMode::Node, }; @@ -145,6 +148,7 @@ integration test.\ let mut b = Bindgen::new(); match test_mode { TestMode::Node => b.nodejs(true)?, + TestMode::Deno => b.deno(true)?, TestMode::Browser => b.web(true)?, }; @@ -160,6 +164,7 @@ integration test.\ match test_mode { TestMode::Node => node::execute(&module, &tmpdir, &args, &tests)?, + TestMode::Deno => deno::execute(&module, &tmpdir, &args, &tests)?, TestMode::Browser => { let srv = server::spawn( &if headless { diff --git a/crates/cli/src/bin/wasm-bindgen-test-runner/node.rs b/crates/cli/src/bin/wasm-bindgen-test-runner/node.rs index 221aa00e..0b389682 100644 --- a/crates/cli/src/bin/wasm-bindgen-test-runner/node.rs +++ b/crates/cli/src/bin/wasm-bindgen-test-runner/node.rs @@ -6,6 +6,38 @@ use std::process::Command; use anyhow::{Context, Error}; +// depends on the variable 'wasm' and initializes te WasmBindgenTestContext cx +pub const SHARED_SETUP: &str = r#" +const handlers = {}; + +const wrap = method => { + const og = console[method]; + const on_method = `on_console_${method}`; + console[method] = function (...args) { + og.apply(this, args); + if (handlers[on_method]) { + handlers[on_method](args); + } + }; +}; + +// override `console.log` and `console.error` etc... before we import tests to +// ensure they're bound correctly in wasm. This'll allow us to intercept +// all these calls and capture the output of tests +wrap("debug"); +wrap("log"); +wrap("info"); +wrap("warn"); +wrap("error"); + +cx = new wasm.WasmBindgenTestContext(); +handlers.on_console_debug = wasm.__wbgtest_console_debug; +handlers.on_console_log = wasm.__wbgtest_console_log; +handlers.on_console_info = wasm.__wbgtest_console_info; +handlers.on_console_warn = wasm.__wbgtest_console_warn; +handlers.on_console_error = wasm.__wbgtest_console_error; +"#; + pub fn execute( module: &str, tmpdir: &Path, @@ -15,41 +47,13 @@ pub fn execute( let mut js_to_execute = format!( r#" const {{ exit }} = require('process'); + const wasm = require("./{0}"); - const handlers = {{}}; - - const wrap = method => {{ - const og = console[method]; - const on_method = `on_console_${{method}}`; - console[method] = function (...args) {{ - og.apply(this, args); - if (handlers[on_method]) {{ - handlers[on_method](args); - }} - }}; - }}; - - // override `console.log` and `console.error` etc... before we import tests to - // ensure they're bound correctly in wasm. This'll allow us to intercept - // all these calls and capture the output of tests - wrap("debug"); - wrap("log"); - wrap("info"); - wrap("warn"); - wrap("error"); + {console_override} global.__wbg_test_invoke = f => f(); async function main(tests) {{ - const wasm = require("./{0}"); - - cx = new wasm.WasmBindgenTestContext(); - handlers.on_console_debug = wasm.__wbgtest_console_debug; - handlers.on_console_log = wasm.__wbgtest_console_log; - handlers.on_console_info = wasm.__wbgtest_console_info; - handlers.on_console_warn = wasm.__wbgtest_console_warn; - handlers.on_console_error = wasm.__wbgtest_console_error; - // Forward runtime arguments. These arguments are also arguments to the // `wasm-bindgen-test-runner` which forwards them to node which we // forward to the test harness. this is basically only used for test @@ -63,7 +67,8 @@ pub fn execute( const tests = []; "#, - module + module, + console_override = SHARED_SETUP, ); // Note that we're collecting *JS objects* that represent the functions to @@ -109,7 +114,7 @@ pub fn execute( } #[cfg(unix)] -fn exec(cmd: &mut Command) -> Result<(), Error> { +pub fn exec(cmd: &mut Command) -> Result<(), Error> { use std::os::unix::prelude::*; Err(Error::from(cmd.exec()) .context("failed to execute `node`") @@ -117,7 +122,7 @@ fn exec(cmd: &mut Command) -> Result<(), Error> { } #[cfg(windows)] -fn exec(cmd: &mut Command) -> Result<(), Error> { +pub fn exec(cmd: &mut Command) -> Result<(), Error> { use std::process; let status = cmd.status()?; process::exit(status.code().unwrap_or(3));