Skip to content

Test different CLI flags in reference tests #4264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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