Merge pull request #175 from rustwasm/non-wasm

Enable `cargo test` where possible
This commit is contained in:
Alex Crichton 2018-04-28 11:17:26 -05:00 committed by GitHub
commit 9bab72034f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 188 additions and 57 deletions

View File

@ -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,
@ -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(
@ -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
{
@ -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,
@ -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 = {
@ -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);
@ -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, }
@ -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__"]
@ -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 {
@ -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 {
@ -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 {

View File

@ -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;
@ -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;

View File

@ -17,6 +17,8 @@ struct Project {
node: bool,
no_std: bool,
serde: bool,
rlib: bool,
deps: Vec<String>,
}
fn project() -> Project {
@ -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#"
@ -158,49 +146,58 @@ 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() {
@ -208,9 +205,13 @@ impl Project {
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")
@ -333,3 +334,4 @@ mod non_debug;
mod simple;
mod slice;
mod structural;
mod non_wasm;

86
tests/all/non_wasm.rs Normal file
View File

@ -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");
}