Skip to content

Enable cargo test where possible #175

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 1 commit into from
Apr 28, 2018
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
26 changes: 26 additions & 0 deletions crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ impl ToTokens for ast::Struct {
impl ::wasm_bindgen::__rt::core::convert::From<#name> for
::wasm_bindgen::JsValue
{
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
fn from(value: #name) -> Self {
let ptr = ::wasm_bindgen::convert::IntoWasmAbi::into_abi(
value,
Expand All @@ -174,8 +175,14 @@ impl ToTokens for ast::Struct {
)
}
}

#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
fn from(_value: #name) -> Self {
panic!("cannot convert to JsValue outside of the wasm target")
}
}

#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
#[no_mangle]
pub unsafe extern fn #free_fn(ptr: u32) {
<#name as ::wasm_bindgen::convert::FromWasmAbi>::from_abi(
Expand Down Expand Up @@ -229,6 +236,7 @@ impl ToTokens for ast::StructField {
let desc = syn::Ident::from(format!("__wbindgen_describe_{}", getter));
(quote! {
#[no_mangle]
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
pub unsafe extern fn #getter(js: u32)
-> <#ty as ::wasm_bindgen::convert::IntoWasmAbi>::Abi
{
Expand Down Expand Up @@ -260,6 +268,7 @@ impl ToTokens for ast::StructField {

(quote! {
#[no_mangle]
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
pub unsafe extern fn #setter(
js: u32,
val: <#ty as ::wasm_bindgen::convert::FromWasmAbi>::Abi,
Expand Down Expand Up @@ -395,6 +404,7 @@ impl ToTokens for ast::Export {
let tokens = quote! {
#[export_name = #export_name]
#[allow(non_snake_case)]
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
pub extern fn #generated_name(#(#args),*) #ret_ty {
::wasm_bindgen::__rt::link_this_library();
let #ret = {
Expand Down Expand Up @@ -424,6 +434,7 @@ impl ToTokens for ast::Export {
// this, but the tl;dr; is that this is stripped from the final wasm
// binary along with anything it references.
#[no_mangle]
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
pub extern fn #descriptor_name() {
use wasm_bindgen::describe::*;
inform(FUNCTION);
Expand Down Expand Up @@ -640,6 +651,7 @@ impl ToTokens for ast::ImportFunction {
.iter()
.skip(if is_method { 1 } else { 0 })
.collect::<Vec<_>>();
let arguments = &arguments[..];

let me = if is_method {
quote! { &self, }
Expand All @@ -650,6 +662,7 @@ impl ToTokens for ast::ImportFunction {
let invocation = quote! {
#(#attrs)*
#[allow(bad_style)]
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
#vis extern #fn_token #rust_name(#me #(#arguments),*) #ret {
::wasm_bindgen::__rt::link_this_library();
#[wasm_import_module = "__wbindgen_placeholder__"]
Expand All @@ -668,6 +681,14 @@ impl ToTokens for ast::ImportFunction {
}
}

#(#attrs)*
#[allow(bad_style, unused_variables)]
#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
#vis extern #fn_token #rust_name(#me #(#arguments),*) #ret {
panic!("cannot call wasm-bindgen imported functions on \
non-wasm targets");
}

};

if let Some(class) = class_ty {
Expand Down Expand Up @@ -766,6 +787,7 @@ impl ToTokens for ast::ImportStatic {
(quote! {
#[allow(bad_style)]
#vis static #name: ::wasm_bindgen::JsStatic<#ty> = {
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
fn init() -> #ty {
#[wasm_import_module = "__wbindgen_placeholder__"]
extern {
Expand All @@ -779,6 +801,10 @@ impl ToTokens for ast::ImportStatic {

}
}
#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
fn init() -> #ty {
panic!("cannot access imported statics on non-wasm targets")
}
static mut _VAL: ::wasm_bindgen::__rt::core::cell::UnsafeCell<Option<#ty>> =
::wasm_bindgen::__rt::core::cell::UnsafeCell::new(None);
::wasm_bindgen::JsStatic {
Expand Down
29 changes: 23 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,27 @@ macro_rules! numbers {

numbers! { i8 u8 i16 u16 i32 u32 f32 f64 }

#[wasm_import_module = "__wbindgen_placeholder__"]
extern {
macro_rules! externs {
($(fn $name:ident($($args:tt)*) -> $ret:ty;)*) => (
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
#[wasm_import_module = "__wbindgen_placeholder__"]
extern {
$(fn $name($($args)*) -> $ret;)*
}

$(
#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
#[allow(unused_variables)]
unsafe extern fn $name($($args)*) -> $ret {
panic!("function not implemented on non-wasm32 targets")
}
)*
)
}

externs! {
fn __wbindgen_object_clone_ref(idx: u32) -> u32;
fn __wbindgen_object_drop_ref(idx: u32);
fn __wbindgen_object_drop_ref(idx: u32) -> ();
fn __wbindgen_string_new(ptr: *const u8, len: usize) -> u32;
fn __wbindgen_number_new(f: f64) -> u32;
fn __wbindgen_number_get(idx: u32, invalid: *mut u8) -> f64;
Expand All @@ -293,10 +310,10 @@ extern {
fn __wbindgen_string_get(idx: u32, len: *mut usize) -> *mut u8;
fn __wbindgen_throw(a: *const u8, b: usize) -> !;

fn __wbindgen_cb_drop(idx: u32);
fn __wbindgen_cb_forget(idx: u32);
fn __wbindgen_cb_drop(idx: u32) -> ();
fn __wbindgen_cb_forget(idx: u32) -> ();

fn __wbindgen_describe(v: u32);
fn __wbindgen_describe(v: u32) -> ();

fn __wbindgen_json_parse(ptr: *const u8, len: usize) -> u32;
fn __wbindgen_json_serialize(idx: u32, ptr: *mut *mut u8) -> usize;
Expand Down
104 changes: 53 additions & 51 deletions tests/all/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ struct Project {
node: bool,
no_std: bool,
serde: bool,
rlib: bool,
deps: Vec<String>,
}

fn project() -> Project {
Expand All @@ -29,23 +31,9 @@ fn project() -> Project {
node: false,
no_std: false,
serde: false,
rlib: false,
deps: Vec::new(),
files: vec![
("Cargo.toml".to_string(), format!(r#"
[package]
name = "test{}"
version = "0.0.1"
authors = []

[workspace]

[lib]
crate-type = ["cdylib"]

# XXX: It is important that `[dependencies]` is the last section
# here, so that `add_local_dependency` functions correctly!
[dependencies]
"#, IDX.with(|x| *x))),

("Cargo.lock".to_string(), lockfile),

("run.js".to_string(), r#"
Expand Down Expand Up @@ -158,59 +146,72 @@ impl Project {
self
}

fn rlib(&mut self, rlib: bool) -> &mut Project {
self.rlib = rlib;
self
}

fn depend(&mut self, dep: &str) -> &mut Project {
{
let cargo_toml = self.files
.iter_mut()
.find(|f| f.0 == "Cargo.toml")
.expect("should have Cargo.toml file!");
cargo_toml.1.push_str(dep);
cargo_toml.1.push_str("\n");
}
self.deps.push(dep.to_string());
self
}

fn add_local_dependency(&mut self, name: &str, path: &str) -> &mut Project {
{
let cargo_toml = self.files
.iter_mut()
.find(|f| f.0 == "Cargo.toml")
.expect("should have Cargo.toml file!");
cargo_toml.1.push_str(name);
cargo_toml.1.push_str(" = { path = '");
cargo_toml.1.push_str(path);
cargo_toml.1.push_str("' }\n");
}
self.deps.push(format!("{} = {{ path = '{}' }}", name, path));
self
}

fn test(&mut self) {
{
let cargo_toml = self.files
.iter_mut()
.find(|f| f.0 == "Cargo.toml")
.expect("should have Cargo.toml file!");
cargo_toml.1.push_str("wasm-bindgen = { path = '");
cargo_toml.1.push_str(env!("CARGO_MANIFEST_DIR"));
cargo_toml.1.push_str("'");
if self.no_std {
cargo_toml.1.push_str(", default-features = false");
}
if self.serde {
cargo_toml.1.push_str(", features = ['serde-serialize']");
}
cargo_toml.1.push_str(" }\n");
fn crate_name(&self) -> String {
format!("test{}", IDX.with(|x| *x))
}

fn build(&mut self) -> (PathBuf, PathBuf) {
let mut manifest = format!(r#"
[package]
name = "test{}"
version = "0.0.1"
authors = []

[workspace]

[lib]
"#, IDX.with(|x| *x));

if !self.rlib {
manifest.push_str("crate-type = [\"cdylib\"]\n");
}

manifest.push_str("[dependencies]\n");
for dep in self.deps.iter() {
manifest.push_str(dep);
manifest.push_str("\n");
}
manifest.push_str("wasm-bindgen = { path = '");
manifest.push_str(env!("CARGO_MANIFEST_DIR"));
manifest.push_str("'");
if self.no_std {
manifest.push_str(", default-features = false");
}
if self.serde {
manifest.push_str(", features = ['serde-serialize']");
}
manifest.push_str(" }\n");
self.files.push(("Cargo.toml".to_string(), manifest));

let root = root();
drop(fs::remove_dir_all(&root));
for &(ref file, ref contents) in self.files.iter() {
let dst = root.join(file);
fs::create_dir_all(dst.parent().unwrap()).unwrap();
fs::File::create(&dst).unwrap().write_all(contents.as_ref()).unwrap();
}

let target_dir = root.parent().unwrap() // chop off test name
.parent().unwrap(); // chop off `generated-tests`
(root.clone(), target_dir.to_path_buf())
}

fn test(&mut self) {
let (root, target_dir) = self.build();

let mut cmd = Command::new("cargo");
cmd.arg("build")
Expand Down Expand Up @@ -333,3 +334,4 @@ mod non_debug;
mod simple;
mod slice;
mod structural;
mod non_wasm;
86 changes: 86 additions & 0 deletions tests/all/non_wasm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use std::process::Command;
use super::{run, project};

#[test]
fn works() {
let mut p = project();
let name = p.crate_name();
p
.rlib(true)
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]

extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub struct A {
x: u32,
}

#[wasm_bindgen]
impl A {
pub fn new() -> A {
A { x: 3 }
}

pub fn foo(&self) {
}
}

#[wasm_bindgen]
pub fn foo(x: bool) {
A::new().foo();

if x {
bar("test");
baz(JsValue::from(3));
}
}

#[wasm_bindgen]
extern {
fn some_import();
static A: JsValue;
}

#[wasm_bindgen]
pub fn bar(_: &str) -> JsValue {
some_import();
A.clone()
}

#[wasm_bindgen]
pub fn baz(_: JsValue) {
}
"#)
.file("tests/foo.rs", &format!("
extern crate {} as mytest;

#[test]
fn foo() {{
mytest::foo(false);
mytest::A::new().foo();
}}
", name))
.file("benches/foo.rs", &format!("
#![feature(test)]
extern crate test;
extern crate {} as mytest;

#[bench]
fn foo(b: &mut test::Bencher) {{
b.iter(|| mytest::foo(false));
}}
", name));
let (root, target_dir) = p.build();
let mut cmd = Command::new("cargo");
cmd.arg("test")
.arg("--test").arg("foo")
.arg("--bench").arg("foo")
.current_dir(&root)
.env("CARGO_TARGET_DIR", &target_dir);
run(&mut cmd, "cargo");
}