Skip to content

Commit

Permalink
Test different CLI flags in reference tests (#4264)
Browse files Browse the repository at this point in the history
  • Loading branch information
RunDevelopment authored Nov 12, 2024
1 parent 8771907 commit 2a1c7ac
Show file tree
Hide file tree
Showing 17 changed files with 610 additions and 17 deletions.
95 changes: 78 additions & 17 deletions crates/cli/tests/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@
//!
//! Multiple dependencies can be declared in a single test file using multiple
//! `DEPENDENCY:` comments.
//!
//! ## Custom CLI flags
//!
//! By default, tests will use the `bundler` target. Custom CLI flags can be
//! passed to the `wasm-bindgen` CLI by declaring them in a comment at the top
//! of the test file. For example:
//!
//! ```rust
//! // FLAGS: --target=web --reference-types
//! ```
//!
//! Multiple comments can be used to run the test multiple times with different
//! flags.
//!
//! ```rust
//! // FLAGS: --target=web
//! // FLAGS: --target=nodejs
//! ```

use anyhow::{bail, Result};
use assert_cmd::prelude::*;
Expand Down Expand Up @@ -101,6 +119,16 @@ fn runtest(test: &Path) -> Result<()> {
let root = repo_root();
let root = root.display();

// parse target declarations
let mut all_flags: Vec<_> = contents
.lines()
.filter_map(|l| l.strip_prefix("// FLAGS: "))
.map(|l| l.trim())
.collect();
if all_flags.is_empty() {
all_flags.push("");
}

// parse additional dependency declarations
let dependencies = contents
.lines()
Expand Down Expand Up @@ -144,25 +172,58 @@ fn runtest(test: &Path) -> Result<()> {
.join("debug")
.join("reference_test.wasm");

let mut bindgen = Command::cargo_bin("wasm-bindgen")?;
bindgen
.arg("--out-dir")
.arg(td.path())
.arg(&wasm)
.arg("--remove-producers-section");
if contents.contains("// enable-externref") {
bindgen.env("WASM_BINDGEN_EXTERNREF", "1");
}
exec(&mut bindgen)?;
for (flags_index, &flags) in all_flags.iter().enumerate() {
// extract the target from the flags
let target = flags
.split_whitespace()
.find_map(|f| f.strip_prefix("--target="))
.unwrap_or("bundler");

let out_dir = &td.path().join(target);
fs::create_dir(out_dir)?;

let mut bindgen = Command::cargo_bin("wasm-bindgen")?;
bindgen
.arg("--out-dir")
.arg(out_dir)
.arg(&wasm)
.arg("--remove-producers-section");
for flag in flags.split_whitespace() {
bindgen.arg(flag);
}
if contents.contains("// enable-externref") {
bindgen.env("WASM_BINDGEN_EXTERNREF", "1");
}
exec(&mut bindgen)?;

if !contents.contains("async") {
let js = fs::read_to_string(td.path().join("reference_test_bg.js"))?;
assert_same(&js, &test.with_extension("js"))?;
let wat = sanitize_wasm(&td.path().join("reference_test_bg.wasm"))?;
assert_same(&wat, &test.with_extension("wat"))?;
// suffix the file name with the target
let test = if all_flags.len() > 1 {
let base_file_name = format!(
"{}-{}.rs",
test.file_stem().unwrap().to_string_lossy(),
flags_index
);
test.with_file_name(base_file_name)
} else {
test.to_owned()
};

// bundler uses a different main JS file, because its
// reference_test.js just imports the reference_test_bg.js
let main_js_file = match target {
"bundler" => "reference_test_bg.js",
_ => "reference_test.js",
};

if !contents.contains("async") {
let js = fs::read_to_string(out_dir.join(main_js_file))?;
assert_same(&js, &test.with_extension("js"))?;
let wat = sanitize_wasm(&out_dir.join("reference_test_bg.wasm"))?;
assert_same(&wat, &test.with_extension("wat"))?;
}
let d_ts = fs::read_to_string(out_dir.join("reference_test.d.ts"))?;
assert_same(&d_ts, &test.with_extension("d.ts"))?;
}
let d_ts = fs::read_to_string(td.path().join("reference_test.d.ts"))?;
assert_same(&d_ts, &test.with_extension("d.ts"))?;

Ok(())
}
Expand Down
3 changes: 3 additions & 0 deletions crates/cli/tests/reference/targets-0.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* tslint:disable */
/* eslint-disable */
export function add_that_might_fail(a: number, b: number): number;
20 changes: 20 additions & 0 deletions crates/cli/tests/reference/targets-0.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
let wasm;
export function __wbg_set_wasm(val) {
wasm = val;
}

/**
* @param {number} a
* @param {number} b
* @returns {number}
*/
export function add_that_might_fail(a, b) {
const ret = wasm.add_that_might_fail(a, b);
return ret >>> 0;
}

export function __wbg_random_5d40be260a2cfbac() {
const ret = Math.random();
return ret;
};

9 changes: 9 additions & 0 deletions crates/cli/tests/reference/targets-0.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(module $reference_test.wasm
(type (;0;) (func (param i32 i32) (result i32)))
(func $add_that_might_fail (;0;) (type 0) (param i32 i32) (result i32))
(memory (;0;) 17)
(export "memory" (memory 0))
(export "add_that_might_fail" (func $add_that_might_fail))
(@custom "target_features" (after code) "\04+\0amultivalue+\0fmutable-globals+\0freference-types+\08sign-ext")
)

33 changes: 33 additions & 0 deletions crates/cli/tests/reference/targets-1.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* tslint:disable */
/* eslint-disable */
export function add_that_might_fail(a: number, b: number): number;

export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;

export interface InitOutput {
readonly memory: WebAssembly.Memory;
readonly add_that_might_fail: (a: number, b: number) => number;
readonly __wbindgen_export_0: WebAssembly.Table;
readonly __wbindgen_start: () => void;
}

export type SyncInitInput = BufferSource | WebAssembly.Module;
/**
* Instantiates the given `module`, which can either be bytes or
* a precompiled `WebAssembly.Module`.
*
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
*
* @returns {InitOutput}
*/
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;

/**
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
* for everything else, calls `WebAssembly.instantiate` directly.
*
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
*
* @returns {Promise<InitOutput>}
*/
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
132 changes: 132 additions & 0 deletions crates/cli/tests/reference/targets-1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
let wasm;

/**
* @param {number} a
* @param {number} b
* @returns {number}
*/
export function add_that_might_fail(a, b) {
const ret = wasm.add_that_might_fail(a, b);
return ret >>> 0;
}

async function __wbg_load(module, imports) {
if (typeof Response === 'function' && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === 'function') {
try {
return await WebAssembly.instantiateStreaming(module, imports);

} catch (e) {
if (module.headers.get('Content-Type') != 'application/wasm') {
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);

} else {
throw e;
}
}
}

const bytes = await module.arrayBuffer();
return await WebAssembly.instantiate(bytes, imports);

} else {
const instance = await WebAssembly.instantiate(module, imports);

if (instance instanceof WebAssembly.Instance) {
return { instance, module };

} else {
return instance;
}
}
}

function __wbg_get_imports() {
const imports = {};
imports.wbg = {};
imports.wbg.__wbg_random_5d40be260a2cfbac = function() {
const ret = Math.random();
return ret;
};
imports.wbg.__wbindgen_init_externref_table = function() {
const table = wasm.__wbindgen_export_0;
const offset = table.grow(4);
table.set(0, undefined);
table.set(offset + 0, undefined);
table.set(offset + 1, null);
table.set(offset + 2, true);
table.set(offset + 3, false);
;
};

return imports;
}

function __wbg_init_memory(imports, memory) {

}

function __wbg_finalize_init(instance, module) {
wasm = instance.exports;
__wbg_init.__wbindgen_wasm_module = module;


wasm.__wbindgen_start();
return wasm;
}

function initSync(module) {
if (wasm !== undefined) return wasm;


if (typeof module !== 'undefined') {
if (Object.getPrototypeOf(module) === Object.prototype) {
({module} = module)
} else {
console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
}
}

const imports = __wbg_get_imports();

__wbg_init_memory(imports);

if (!(module instanceof WebAssembly.Module)) {
module = new WebAssembly.Module(module);
}

const instance = new WebAssembly.Instance(module, imports);

return __wbg_finalize_init(instance, module);
}

async function __wbg_init(module_or_path) {
if (wasm !== undefined) return wasm;


if (typeof module_or_path !== 'undefined') {
if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
({module_or_path} = module_or_path)
} else {
console.warn('using deprecated parameters for the initialization function; pass a single object instead')
}
}

if (typeof module_or_path === 'undefined') {
module_or_path = new URL('reference_test_bg.wasm', import.meta.url);
}
const imports = __wbg_get_imports();

if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
module_or_path = fetch(module_or_path);
}

__wbg_init_memory(imports);

const { instance, module } = await __wbg_load(await module_or_path, imports);

return __wbg_finalize_init(instance, module);
}

export { initSync };
export default __wbg_init;
14 changes: 14 additions & 0 deletions crates/cli/tests/reference/targets-1.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
(module $reference_test.wasm
(type (;0;) (func))
(type (;1;) (func (param i32 i32) (result i32)))
(import "wbg" "__wbindgen_init_externref_table" (func (;0;) (type 0)))
(func $add_that_might_fail (;1;) (type 1) (param i32 i32) (result i32))
(table (;0;) 128 externref)
(memory (;0;) 17)
(export "memory" (memory 0))
(export "add_that_might_fail" (func $add_that_might_fail))
(export "__wbindgen_export_0" (table 0))
(export "__wbindgen_start" (func 0))
(@custom "target_features" (after code) "\04+\0amultivalue+\0fmutable-globals+\0freference-types+\08sign-ext")
)

25 changes: 25 additions & 0 deletions crates/cli/tests/reference/targets-2.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
declare namespace wasm_bindgen {
/* tslint:disable */
/* eslint-disable */
export function add_that_might_fail(a: number, b: number): number;

}

declare type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;

declare interface InitOutput {
readonly memory: WebAssembly.Memory;
readonly add_that_might_fail: (a: number, b: number) => number;
readonly __wbindgen_export_0: WebAssembly.Table;
readonly __wbindgen_start: () => void;
}

/**
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
* for everything else, calls `WebAssembly.instantiate` directly.
*
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
*
* @returns {Promise<InitOutput>}
*/
declare function wasm_bindgen (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
Loading

0 comments on commit 2a1c7ac

Please sign in to comment.