Merge branch 'master' into js_date

This commit is contained in:
Ivan Enderlin 2018-07-03 14:12:05 +02:00
commit fe4c150431
No known key found for this signature in database
GPG Key ID: 461F31FCE31F4AAD
80 changed files with 5280 additions and 1619 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.idea
/target/
**/*.rs.bk
Cargo.lock

View File

@ -41,6 +41,7 @@ matrix:
# Check JS output from all tests against eslint
- ./node_modules/.bin/eslint ./target/generated-tests/*/out*.js
env: RUST_BACKTRACE=1
# WebIDL tests pass on nightly
- rust: nightly
before_install: rustup component add rustfmt-preview --toolchain nightly

View File

@ -17,13 +17,19 @@ pub struct Program {
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
pub struct Export {
pub class: Option<Ident>,
pub method: bool,
pub mutable: bool,
pub method_self: Option<MethodSelf>,
pub constructor: Option<String>,
pub function: Function,
pub comments: Vec<String>,
}
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
pub enum MethodSelf {
ByValue,
RefMutable,
RefShared,
}
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
pub struct Import {
pub module: Option<String>,
@ -170,8 +176,7 @@ impl Program {
f.to_tokens(tokens);
self.exports.push(Export {
class: None,
method: false,
mutable: false,
method_self: None,
constructor: None,
function: Function::from(f, opts),
comments,
@ -263,7 +268,7 @@ impl Program {
None
};
let (function, mutable) = Function::from_decl(
let (function, method_self) = Function::from_decl(
&method.sig.ident,
Box::new(method.sig.decl.clone()),
method.attrs.clone(),
@ -274,8 +279,7 @@ impl Program {
self.exports.push(Export {
class: Some(class.clone()),
method: mutable.is_some(),
mutable: mutable.unwrap_or(false),
method_self,
constructor,
function,
comments,
@ -405,7 +409,10 @@ impl Program {
};
let class_name = extract_path_ident(class_name)
.expect("first argument of method must be a bare type");
let class_name = wasm.opts.js_class().map(Into::into)
let class_name = wasm
.opts
.js_class()
.map(Into::into)
.unwrap_or_else(|| class_name.to_string());
ImportFunctionKind::Method {
@ -526,7 +533,7 @@ impl Function {
opts: BindgenAttrs,
vis: syn::Visibility,
allow_self: bool,
) -> (Function, Option<bool>) {
) -> (Function, Option<MethodSelf>) {
if decl.variadic.is_some() {
panic!("can't bindgen variadic functions")
}
@ -538,17 +545,23 @@ impl Function {
let syn::FnDecl { inputs, output, .. } = { *decl };
let mut mutable = None;
let mut method_self = None;
let arguments = inputs
.into_iter()
.filter_map(|arg| match arg {
syn::FnArg::Captured(c) => Some(c),
syn::FnArg::SelfValue(_) => {
panic!("by-value `self` not yet supported");
assert!(method_self.is_none());
method_self = Some(MethodSelf::ByValue);
None
}
syn::FnArg::SelfRef(ref a) if allow_self => {
assert!(mutable.is_none());
mutable = Some(a.mutability.is_some());
assert!(method_self.is_none());
if a.mutability.is_some() {
method_self = Some(MethodSelf::RefMutable);
} else {
method_self = Some(MethodSelf::RefShared);
}
None
}
_ => panic!("arguments cannot be `self` or ignored"),
@ -569,7 +582,7 @@ impl Function {
rust_vis: vis,
rust_attrs: attrs,
},
mutable,
method_self,
)
}
@ -615,9 +628,15 @@ impl Export {
}
fn shared(&self) -> shared::Export {
let (method, consumed) = match self.method_self {
Some(MethodSelf::ByValue) => (true, true),
Some(_) => (true, false),
None => (false, false),
};
shared::Export {
class: self.class.as_ref().map(|s| s.to_string()),
method: self.method,
method,
consumed,
constructor: self.constructor.clone(),
function: self.function.shared(),
comments: self.comments.clone(),

View File

@ -309,16 +309,61 @@ impl ToTokens for ast::Export {
let ret = Ident::new("_ret", Span::call_site());
let mut offset = 0;
if self.method {
let class = self.class.as_ref().unwrap();
args.push(quote! { me: *mut ::wasm_bindgen::__rt::WasmRefCell<#class> });
arg_conversions.push(quote! {
::wasm_bindgen::__rt::assert_not_null(me);
let me = unsafe { &*me };
});
if self.method_self.is_some() {
args.push(quote! { me: u32 });
offset = 1;
}
let name = &self.function.name;
let receiver = match self.method_self {
Some(ast::MethodSelf::ByValue) => {
let class = self.class.as_ref().unwrap();
arg_conversions.push(quote! {
let me = unsafe {
<#class as ::wasm_bindgen::convert::FromWasmAbi>::from_abi(
me,
&mut ::wasm_bindgen::convert::GlobalStack::new(),
)
};
});
quote! { me.#name }
}
Some(ast::MethodSelf::RefMutable) => {
let class = self.class.as_ref().unwrap();
arg_conversions.push(quote! {
let mut me = unsafe {
<#class as ::wasm_bindgen::convert::RefMutFromWasmAbi>
::ref_mut_from_abi(
me,
&mut ::wasm_bindgen::convert::GlobalStack::new(),
)
};
let me = &mut *me;
});
quote! { me.#name }
}
Some(ast::MethodSelf::RefShared) => {
let class = self.class.as_ref().unwrap();
arg_conversions.push(quote! {
let me = unsafe {
<#class as ::wasm_bindgen::convert::RefFromWasmAbi>
::ref_from_abi(
me,
&mut ::wasm_bindgen::convert::GlobalStack::new(),
)
};
let me = &*me;
});
quote! { me.#name }
}
None => {
match &self.class {
Some(class) => quote! { #class::#name },
None => quote! { #name }
}
}
};
for (i, syn::ArgCaptured { ty, .. }) in self.function.arguments.iter().enumerate() {
let i = i + offset;
let ident = Ident::new(&format!("arg{}", i), Span::call_site());
@ -394,19 +439,6 @@ impl ToTokens for ast::Export {
}
None => quote! { inform(0); },
};
let name = &self.function.name;
let receiver = match &self.class {
Some(_) if self.method => {
if self.mutable {
quote! { me.borrow_mut().#name }
} else {
quote! { me.borrow().#name }
}
}
Some(class) => quote! { #class::#name },
None => quote!{ #name },
};
let descriptor_name = format!("__wbindgen_describe_{}", export_name);
let descriptor_name = Ident::new(&descriptor_name, Span::call_site());
let nargs = self.function.arguments.len() as u32;
@ -573,6 +605,7 @@ impl ToTokens for ast::ImportFunction {
let mut abi_argument_names = Vec::new();
let mut abi_arguments = Vec::new();
let mut arg_conversions = Vec::new();
let mut arguments = Vec::new();
let ret_ident = Ident::new("_ret", Span::call_site());
for (i, syn::ArgCaptured { pat, ty, .. }) in self.function.arguments.iter().enumerate() {
@ -583,6 +616,9 @@ impl ToTokens for ast::ImportFunction {
subpat: None,
..
}) => ident.clone(),
syn::Pat::Wild(_) => {
syn::Ident::new(&format!("__genarg_{}", i), Span::call_site())
}
_ => panic!("unsupported pattern in foreign function"),
};
@ -593,6 +629,7 @@ impl ToTokens for ast::ImportFunction {
let var = if i == 0 && is_method {
quote! { self }
} else {
arguments.push(quote! { #name: #ty });
quote! { #name }
};
arg_conversions.push(quote! {
@ -651,12 +688,7 @@ impl ToTokens for ast::ImportFunction {
let rust_name = &self.rust_name;
let import_name = &self.shim;
let attrs = &self.function.rust_attrs;
let arguments = if is_method {
&self.function.arguments[1..]
} else {
&self.function.arguments[..]
};
let arguments = &arguments;
let me = if is_method {
quote! { &self, }

View File

@ -138,15 +138,15 @@ impl Descriptor {
pub fn is_number(&self) -> bool {
match *self {
Descriptor::I8 |
Descriptor::U8 |
Descriptor::I16 |
Descriptor::U16 |
Descriptor::I32 |
Descriptor::U32 |
Descriptor::F32 |
Descriptor::F64 |
Descriptor::Enum => true,
Descriptor::I8
| Descriptor::U8
| Descriptor::I16
| Descriptor::U16
| Descriptor::I32
| Descriptor::U32
| Descriptor::F32
| Descriptor::F64
| Descriptor::Enum => true,
_ => return false,
}
}
@ -191,19 +191,15 @@ impl Descriptor {
let inner = match *self {
Descriptor::String => return Some(VectorKind::String),
Descriptor::Vector(ref d) => &**d,
Descriptor::Ref(ref d) => {
match **d {
Descriptor::Slice(ref d) => &**d,
Descriptor::String => return Some(VectorKind::String),
_ => return None,
}
}
Descriptor::RefMut(ref d) => {
match **d {
Descriptor::Slice(ref d) => &**d,
_ => return None,
}
}
Descriptor::Ref(ref d) => match **d {
Descriptor::Slice(ref d) => &**d,
Descriptor::String => return Some(VectorKind::String),
_ => return None,
},
Descriptor::RefMut(ref d) => match **d {
Descriptor::Slice(ref d) => &**d,
_ => return None,
},
_ => return None,
};
match *inner {
@ -218,7 +214,7 @@ impl Descriptor {
Descriptor::F32 => Some(VectorKind::F32),
Descriptor::F64 => Some(VectorKind::F64),
Descriptor::Anyref => Some(VectorKind::Anyref),
_ => None
_ => None,
}
}
@ -248,8 +244,7 @@ impl Descriptor {
pub fn is_by_ref(&self) -> bool {
match *self {
Descriptor::Ref(_) |
Descriptor::RefMut(_) => true,
Descriptor::Ref(_) | Descriptor::RefMut(_) => true,
_ => false,
}
}

View File

@ -66,12 +66,22 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
/// Flag this shim as a method call into Rust, so the first Rust argument
/// passed should be `this.ptr`.
pub fn method(&mut self, method: bool) -> &mut Self {
pub fn method(&mut self, method: bool, consumed: bool) -> &mut Self {
if method {
self.prelude("if (this.ptr === 0) {
throw new Error('Attempt to use a moved value');
}");
self.rust_arguments.insert(0, "this.ptr".to_string());
self.prelude(
"if (this.ptr === 0) {
throw new Error('Attempt to use a moved value');
}"
);
if consumed {
self.prelude("\
const ptr = this.ptr;\n\
this.ptr = 0;\n\
");
self.rust_arguments.insert(0, "ptr".to_string());
} else {
self.rust_arguments.insert(0, "this.ptr".to_string());
}
}
self
}
@ -111,30 +121,46 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
let name = self.abi_arg();
if let Some(kind) = arg.vector_kind() {
self.js_arguments.push((name.clone(), kind.js_ty().to_string()));
self.js_arguments
.push((name.clone(), kind.js_ty().to_string()));
let func = self.cx.pass_to_wasm_function(kind)?;
self.prelude(&format!("\
const [ptr{i}, len{i}] = {func}({arg});\n\
", i = i, func = func, arg = name));
self.prelude(&format!(
"\
const [ptr{i}, len{i}] = {func}({arg});\n\
",
i = i,
func = func,
arg = name
));
if arg.is_by_ref() {
if arg.is_mut_ref() {
let get = self.cx.memview_function(kind);
self.finally(&format!("\
{arg}.set({get}().subarray(\
ptr{i} / {size}, \
ptr{i} / {size} + len{i}\
));\n\
", i = i, arg = name, get = get, size = kind.size()));
self.finally(&format!(
"\
{arg}.set({get}().subarray(\
ptr{i} / {size}, \
ptr{i} / {size} + len{i}\
));\n\
",
i = i,
arg = name,
get = get,
size = kind.size()
));
}
self.finally(&format!("\
wasm.__wbindgen_free(ptr{i}, len{i} * {size});\n\
", i = i, size = kind.size()));
self.finally(&format!(
"\
wasm.__wbindgen_free(ptr{i}, len{i} * {size});\n\
",
i = i,
size = kind.size()
));
self.cx.require_internal_export("__wbindgen_free")?;
}
self.rust_arguments.push(format!("ptr{}", i));
self.rust_arguments.push(format!("len{}", i));
return Ok(self)
return Ok(self);
}
if let Some(s) = arg.rust_struct() {
@ -142,24 +168,32 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
if self.cx.config.debug {
self.cx.expose_assert_class();
self.prelude(&format!("\
_assertClass({arg}, {struct_});\n\
", arg = name, struct_ = s));
self.prelude(&format!(
"\
_assertClass({arg}, {struct_});\n\
",
arg = name,
struct_ = s
));
}
if arg.is_by_ref() {
self.rust_arguments.push(format!("{}.ptr", name));
} else {
self.prelude(&format!("\
self.prelude(&format!(
"\
const ptr{i} = {arg}.ptr;\n\
if (ptr{i} === 0) {{
throw new Error('Attempt to use a moved value');
}}
{arg}.ptr = 0;\n\
", i = i, arg = name));
",
i = i,
arg = name
));
self.rust_arguments.push(format!("ptr{}", i));
}
return Ok(self)
return Ok(self);
}
if arg.is_number() {
@ -171,7 +205,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
}
self.rust_arguments.push(name);
return Ok(self)
return Ok(self);
}
if let Some(signed) = arg.get_64bit() {
@ -183,51 +217,55 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
self.cx.expose_uint32_memory();
self.cx.expose_global_argument_ptr()?;
self.js_arguments.push((name.clone(), "BigInt".to_string()));
self.prelude(&format!("\
{f}[0] = {name};\n\
const lo{i} = u32CvtShim[0];\n\
const hi{i} = u32CvtShim[1];\n\
",
self.prelude(&format!(
"\
{f}[0] = {name};\n\
const lo{i} = u32CvtShim[0];\n\
const hi{i} = u32CvtShim[1];\n\
",
i = i,
f = f,
name = name,
));
self.rust_arguments.push(format!("lo{}", i));
self.rust_arguments.push(format!("hi{}", i));
return Ok(self)
return Ok(self);
}
if arg.is_ref_anyref() {
self.js_arguments.push((name.clone(), "any".to_string()));
self.cx.expose_borrowed_objects();
self.finally("stack.pop();");
self.rust_arguments.push(format!("addBorrowedObject({})", name));
return Ok(self)
self.rust_arguments
.push(format!("addBorrowedObject({})", name));
return Ok(self);
}
match *arg {
Descriptor::Boolean => {
self.js_arguments.push((name.clone(), "boolean".to_string()));
self.js_arguments
.push((name.clone(), "boolean".to_string()));
if self.cx.config.debug {
self.cx.expose_assert_bool();
self.prelude(&format!("\
_assertBoolean({name});\n\
", name = name));
self.prelude(&format!(
"\
_assertBoolean({name});\n\
",
name = name
));
}
self.rust_arguments.push(format!("{} ? 1 : 0", name));
}
Descriptor::Char => {
self.js_arguments.push((name.clone(), "string".to_string()));
self.rust_arguments.push(format!("{}.codePointAt(0)", name))
},
}
Descriptor::Anyref => {
self.js_arguments.push((name.clone(), "any".to_string()));
self.cx.expose_add_heap_object();
self.rust_arguments.push(format!("addHeapObject({})", name));
}
_ => {
bail!("unsupported argument to rust function {:?}", arg)
}
_ => bail!("unsupported argument to rust function {:?}", arg),
}
Ok(self)
}
@ -238,7 +276,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
None => {
self.ret_ty = "void".to_string();
self.ret_expr = format!("return RET;");
return Ok(self)
return Ok(self);
}
};
@ -246,7 +284,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
self.ret_ty = "any".to_string();
self.cx.expose_get_object();
self.ret_expr = format!("return getObject(RET);");
return Ok(self)
return Ok(self);
}
if ty.is_by_ref() {
@ -261,28 +299,32 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
self.cx.require_internal_export("__wbindgen_free")?;
self.prelude("const retptr = globalArgumentPtr();");
self.rust_arguments.insert(0, "retptr".to_string());
self.ret_expr = format!("\
RET;\n\
const mem = getUint32Memory();\n\
const ptr = mem[retptr / 4];\n\
const len = mem[retptr / 4 + 1];\n\
const realRet = {}(ptr, len).slice();\n\
wasm.__wbindgen_free(ptr, len * {});\n\
return realRet;\n\
", f, ty.size());
return Ok(self)
self.ret_expr = format!(
"\
RET;\n\
const mem = getUint32Memory();\n\
const ptr = mem[retptr / 4];\n\
const len = mem[retptr / 4 + 1];\n\
const realRet = {}(ptr, len).slice();\n\
wasm.__wbindgen_free(ptr, len * {});\n\
return realRet;\n\
",
f,
ty.size()
);
return Ok(self);
}
if let Some(name) = ty.rust_struct() {
self.ret_ty = name.to_string();
self.ret_expr = format!("return {name}.__construct(RET);", name = name);
return Ok(self)
return Ok(self);
}
if ty.is_number() {
self.ret_ty = "number".to_string();
self.ret_expr = format!("return RET;");
return Ok(self)
return Ok(self);
}
if let Some(signed) = ty.get_64bit() {
@ -297,11 +339,14 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
};
self.prelude("const retptr = globalArgumentPtr();");
self.rust_arguments.insert(0, "retptr".to_string());
self.ret_expr = format!("\
RET;\n\
return {}()[retptr / 8];\n\
", f);
return Ok(self)
self.ret_expr = format!(
"\
RET;\n\
return {}()[retptr / 8];\n\
",
f
);
return Ok(self);
}
match *ty {
@ -333,7 +378,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
/// generated function shim and the second is a TypeScript signature of the
/// JS expression.
pub fn finish(&self, prefix: &str, invoc: &str) -> (String, String) {
let js_args = self.js_arguments
let js_args = self
.js_arguments
.iter()
.map(|s| &s.0[..])
.collect::<Vec<_>>()
@ -342,29 +388,35 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
js.push_str(&self.prelude);
let rust_args = self.rust_arguments.join(", ");
let invoc = self.ret_expr.replace("RET", &format!("{}({})", invoc, rust_args));
let invoc = self
.ret_expr
.replace("RET", &format!("{}({})", invoc, rust_args));
let invoc = if self.finally.len() == 0 {
invoc
} else {
format!("\
format!(
"\
try {{\n\
{}
\n}} finally {{\n\
{}
}}\n\
",
&invoc,
&self.finally,
",
&invoc, &self.finally,
)
};
js.push_str(&invoc);
js.push_str("\n}");
let ts_args = self.js_arguments
let ts_args = self
.js_arguments
.iter()
.map(|s| format!("{}: {}", s.0, s.1))
.collect::<Vec<_>>()
.join(", ");
let ts = format!("{} {}({}): {};\n", prefix, self.js_name, ts_args, self.ret_ty);
let ts = format!(
"{} {}({}): {};\n",
prefix, self.js_name, ts_args, self.ret_ty
);
(js, ts)
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
use failure::Error;
use descriptor::{Descriptor, Function};
use super::{Context, Js2Rust};
use descriptor::{Descriptor, Function};
/// Helper struct for manufacturing a shim in JS used to translate Rust types to
/// JS, then invoking an imported JS function.
@ -85,18 +85,27 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
if let Some(ty) = arg.vector_kind() {
let abi2 = self.shim_argument();
let f = self.cx.expose_get_vector_from_wasm(ty);
self.prelude(&format!("let v{0} = {func}({0}, {1});",
abi, abi2, func = f));
self.prelude(&format!(
"let v{0} = {func}({0}, {1});",
abi,
abi2,
func = f
));
if !arg.is_by_ref() {
self.prelude(&format!("\
v{0} = v{0}.slice();\n\
wasm.__wbindgen_free({0}, {1} * {size});\
", abi, abi2, size = ty.size()));
self.prelude(&format!(
"\
v{0} = v{0}.slice();\n\
wasm.__wbindgen_free({0}, {1} * {size});\
",
abi,
abi2,
size = ty.size()
));
self.cx.require_internal_export("__wbindgen_free")?;
}
self.js_arguments.push(format!("v{}", abi));
return Ok(())
return Ok(());
}
if let Some(signed) = arg.get_64bit() {
@ -107,18 +116,19 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
};
let hi = self.shim_argument();
let name = format!("n{}", abi);
self.prelude(&format!("\
u32CvtShim[0] = {lo};\n\
u32CvtShim[1] = {hi};\n\
const {name} = {f}[0];\n\
",
self.prelude(&format!(
"\
u32CvtShim[0] = {lo};\n\
u32CvtShim[1] = {hi};\n\
const {name} = {f}[0];\n\
",
lo = abi,
hi = hi,
f = f,
name = name,
));
self.js_arguments.push(name);
return Ok(())
return Ok(());
}
if let Some(class) = arg.rust_struct() {
@ -128,14 +138,15 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
let assign = format!("let c{0} = {1}.__construct({0});", abi, class);
self.prelude(&assign);
self.js_arguments.push(format!("c{}", abi));
return Ok(())
return Ok(());
}
if let Some((f, mutable)) = arg.stack_closure() {
let (js, _ts) = {
let mut builder = Js2Rust::new("", self.cx);
if mutable {
builder.prelude("let a = this.a;\n")
builder
.prelude("let a = this.a;\n")
.prelude("this.a = 0;\n")
.rust_argument("a")
.finally("this.a = a;\n");
@ -151,22 +162,28 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
self.cx.function_table_needed = true;
let next_global = self.global_idx();
self.global_idx();
self.prelude(&format!("\
let cb{0} = {js};\n\
cb{0}.f = wasm.__wbg_function_table.get({0});\n\
cb{0}.a = getGlobalArgument({next_global});\n\
cb{0}.b = getGlobalArgument({next_global} + 1);\n\
", abi, js = js, next_global = next_global));
self.prelude(&format!(
"\
let cb{0} = {js};\n\
cb{0}.f = wasm.__wbg_function_table.get({0});\n\
cb{0}.a = getGlobalArgument({next_global});\n\
cb{0}.b = getGlobalArgument({next_global} + 1);\n\
",
abi,
js = js,
next_global = next_global
));
self.finally(&format!("cb{0}.a = cb{0}.b = 0;", abi));
self.js_arguments.push(format!("cb{0}.bind(cb{0})", abi));
return Ok(())
return Ok(());
}
if let Some(closure) = arg.ref_closure() {
let (js, _ts) = {
let mut builder = Js2Rust::new("", self.cx);
if closure.mutable {
builder.prelude("let a = this.a;\n")
builder
.prelude("let a = this.a;\n")
.prelude("this.a = 0;\n")
.rust_argument("a")
.finally("this.a = a;\n");
@ -182,38 +199,40 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
self.cx.expose_uint32_memory();
self.cx.expose_add_heap_object();
self.cx.function_table_needed = true;
let reset_idx = format!("\
let cb{0} = {js};\n\
cb{0}.a = getGlobalArgument({a});\n\
cb{0}.b = getGlobalArgument({b});\n\
cb{0}.f = wasm.__wbg_function_table.get(getGlobalArgument({c}));\n\
let real = cb{0}.bind(cb{0});\n\
real.original = cb{0};\n\
idx{0} = getUint32Memory()[{0} / 4] = addHeapObject(real);\n\
",
let reset_idx = format!(
"\
let cb{0} = {js};\n\
cb{0}.a = getGlobalArgument({a});\n\
cb{0}.b = getGlobalArgument({b});\n\
cb{0}.f = wasm.__wbg_function_table.get(getGlobalArgument({c}));\n\
let real = cb{0}.bind(cb{0});\n\
real.original = cb{0};\n\
idx{0} = getUint32Memory()[{0} / 4] = addHeapObject(real);\n\
",
abi,
js = js,
a = self.global_idx(),
b = self.global_idx(),
c = self.global_idx(),
);
self.prelude(&format!("\
let idx{0} = getUint32Memory()[{0} / 4];\n\
if (idx{0} === 0xffffffff) {{\n\
{1}\
}}\n\
", abi, &reset_idx));
self.prelude(&format!(
"\
let idx{0} = getUint32Memory()[{0} / 4];\n\
if (idx{0} === 0xffffffff) {{\n\
{1}\
}}\n\
",
abi, &reset_idx
));
self.cx.expose_get_object();
self.js_arguments.push(format!("getObject(idx{})", abi));
return Ok(())
return Ok(());
}
let invoc_arg = match *arg {
ref d if d.is_number() => abi,
Descriptor::Boolean => format!("{} !== 0", abi),
Descriptor::Char => {
format!("String.fromCodePoint({})", abi)
}
Descriptor::Char => format!("String.fromCodePoint({})", abi),
Descriptor::Anyref => {
self.cx.expose_take_object();
format!("takeObject({})", abi)
@ -222,7 +241,10 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
self.cx.expose_get_object();
format!("getObject({})", abi)
}
_ => bail!("unimplemented argument type in imported function: {:?}", arg),
_ => bail!(
"unimplemented argument type in imported function: {:?}",
arg
),
};
self.js_arguments.push(invoc_arg);
Ok(())
@ -233,7 +255,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
Some(ref t) => t,
None => {
self.ret_expr = "JS;".to_string();
return Ok(())
return Ok(());
}
};
if ty.is_by_ref() {
@ -243,17 +265,20 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
let f = self.cx.pass_to_wasm_function(ty)?;
self.cx.expose_uint32_memory();
self.shim_arguments.insert(0, "ret".to_string());
self.ret_expr = format!("\
self.ret_expr = format!(
"\
const [retptr, retlen] = {}(JS);\n\
const mem = getUint32Memory();
mem[ret / 4] = retptr;
mem[ret / 4 + 1] = retlen;
", f);
return Ok(())
",
f
);
return Ok(());
}
if ty.is_number() {
self.ret_expr = "return JS;".to_string();
return Ok(())
return Ok(());
}
if let Some(signed) = ty.get_64bit() {
let f = if signed {
@ -264,12 +289,35 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
"getUint64Memory"
};
self.shim_arguments.insert(0, "ret".to_string());
self.ret_expr = format!(
"\
const val = JS;\n\
{}()[ret / 8] = val;\n\
",
f
);
return Ok(());
}
if let Some(class) = ty.rust_struct() {
if ty.is_by_ref() {
bail!("cannot invoke JS functions returning custom ref types yet")
}
// Insert an assertion to the type of the returned value as
// otherwise this will cause memory unsafety on the Rust side of
// things.
self.ret_expr = format!("\
const val = JS;\n\
{}()[ret / 8] = val;\n\
", f);
const val = JS;
if (!(val instanceof {0})) {{
throw new Error('expected value of type {0}');
}}
const ret = val.ptr;
val.ptr = 0;
return ret;\
", class);
return Ok(())
}
self.ret_expr = match *ty {
Descriptor::Boolean => "return JS ? 1 : 0;".to_string(),
Descriptor::Char => "return JS.codePointAt(0);".to_string(),
@ -301,33 +349,39 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
);
if self.catch {
let catch = "\
const view = getUint32Memory();\n\
view[exnptr / 4] = 1;\n\
view[exnptr / 4 + 1] = addHeapObject(e);\n\
";
const view = getUint32Memory();\n\
view[exnptr / 4] = 1;\n\
view[exnptr / 4 + 1] = addHeapObject(e);\n\
";
invoc = format!("\
try {{\n\
{}
}} catch (e) {{\n\
{}
}}\
", &invoc, catch);
invoc = format!(
"\
try {{\n\
{}
}} catch (e) {{\n\
{}
}}\
",
&invoc, catch
);
};
if self.finally.len() > 0 {
invoc = format!("\
try {{\n\
{}
}} finally {{\n\
{}
}}\
", &invoc, &self.finally);
invoc = format!(
"\
try {{\n\
{}
}} finally {{\n\
{}
}}\
",
&invoc, &self.finally
);
}
ret.push_str(&invoc);
ret.push_str("\n}\n");
return ret
return ret;
}
fn global_idx(&mut self) -> usize {

View File

@ -17,8 +17,8 @@ use std::path::{Path, PathBuf};
use failure::{Error, ResultExt};
use parity_wasm::elements::*;
mod js;
mod descriptor;
mod js;
pub mod wasm2es6js;
pub struct Bindgen {
@ -142,11 +142,9 @@ impl Bindgen {
let mut v = MyExternals(Vec::new());
match instance.invoke_export(name, &[], &mut v) {
Ok(None) => Some(v.0),
Ok(Some(_)) => {
unreachable!(
"there is only one export, and we only return None from it"
)
},
Ok(Some(_)) => unreachable!(
"there is only one export, and we only return None from it"
),
// Allow missing exported describe functions. This can
// happen when a nested dependency crate exports things
// but the root crate doesn't use them.
@ -207,13 +205,16 @@ impl Bindgen {
shim.push_str(&format!("imports['{0}'] = require('{0}');\n", module));
}
shim.push_str(&format!("
shim.push_str(&format!(
"
const join = require('path').join;
const bytes = require('fs').readFileSync(join(__dirname, '{}'));
const wasmModule = new WebAssembly.Module(bytes);
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
module.exports = wasmInstance.exports;
", path.file_name().unwrap().to_str().unwrap()));
",
path.file_name().unwrap().to_str().unwrap()
));
reset_indentation(&shim)
}
@ -230,27 +231,25 @@ fn extract_programs(module: &mut Module) -> Result<Vec<shared::Program>, Error>
_ => continue,
};
if custom.name() != "__wasm_bindgen_unstable" {
continue
continue;
}
to_remove.push(i);
let mut payload = custom.payload();
while payload.len() > 0 {
let len =
((payload[0] as usize) << 0) |
((payload[1] as usize) << 8) |
((payload[2] as usize) << 16) |
((payload[3] as usize) << 24);
let len = ((payload[0] as usize) << 0)
| ((payload[1] as usize) << 8)
| ((payload[2] as usize) << 16)
| ((payload[3] as usize) << 24);
let (a, b) = payload[4..].split_at(len as usize);
payload = b;
let p: shared::ProgramOnlySchema = match serde_json::from_slice(&a) {
Ok(f) => f,
Err(e) => {
bail!("failed to decode what looked like wasm-bindgen data: {}", e)
}
Err(e) => bail!("failed to decode what looked like wasm-bindgen data: {}", e),
};
if p.schema_version != shared::SCHEMA_VERSION {
bail!("
bail!(
"
it looks like the Rust project used to create this wasm file was linked against
a different version of wasm-bindgen than this binary:
@ -272,13 +271,13 @@ or you can update the binary with
if this warning fails to go away though and you're not sure what to do feel free
to open an issue at https://github.com/alexcrichton/wasm-bindgen/issues!
",
p.version, version);
p.version,
version
);
}
let p: shared::Program = match serde_json::from_slice(&a) {
Ok(f) => f,
Err(e) => {
bail!("failed to decode what looked like wasm-bindgen data: {}", e)
}
Err(e) => bail!("failed to decode what looked like wasm-bindgen data: {}", e),
};
ret.push(p);
}
@ -297,13 +296,13 @@ impl wasmi::ImportResolver for MyResolver {
&self,
module_name: &str,
field_name: &str,
signature: &wasmi::Signature
signature: &wasmi::Signature,
) -> Result<wasmi::FuncRef, wasmi::Error> {
// Route our special "describe" export to 1 and everything else to 0.
// That way whenever the function 1 is invoked we know what to do and
// when 0 is invoked (by accident) we'll trap and produce an error.
let idx = (module_name == "__wbindgen_placeholder__" &&
field_name == "__wbindgen_describe") as usize;
let idx = (module_name == "__wbindgen_placeholder__" && field_name == "__wbindgen_describe")
as usize;
Ok(wasmi::FuncInstance::alloc_host(signature.clone(), idx))
}
@ -311,7 +310,7 @@ impl wasmi::ImportResolver for MyResolver {
&self,
_module_name: &str,
_field_name: &str,
descriptor: &wasmi::GlobalDescriptor
descriptor: &wasmi::GlobalDescriptor,
) -> Result<wasmi::GlobalRef, wasmi::Error> {
// dummy implementation to ensure instantiation succeeds
let val = match descriptor.value_type() {
@ -340,7 +339,7 @@ impl wasmi::ImportResolver for MyResolver {
&self,
_module_name: &str,
_field_name: &str,
descriptor: &wasmi::TableDescriptor
descriptor: &wasmi::TableDescriptor,
) -> Result<wasmi::TableRef, wasmi::Error> {
// dummy implementation to ensure instantiation succeeds
let initial = descriptor.initial();
@ -358,7 +357,7 @@ impl wasmi::Externals for MyExternals {
fn invoke_index(
&mut self,
index: usize,
args: wasmi::RuntimeArgs
args: wasmi::RuntimeArgs,
) -> Result<Option<wasmi::RuntimeValue>, wasmi::Trap> {
macro_rules! bail {
($($t:tt)*) => ({
@ -413,7 +412,12 @@ fn indent_recurse(mut lines: ::std::str::Lines, current_indent: usize) -> String
if trimmed.starts_with('?') || trimmed.starts_with(':') {
current_indent += 1;
}
format!("\n{}{}{}", " ".repeat(current_indent), &trimmed, &indent_recurse(lines, next_indent))
format!(
"\n{}{}{}",
" ".repeat(current_indent),
&trimmed,
&indent_recurse(lines, next_indent)
)
} else {
String::new()
}

View File

@ -1,13 +1,13 @@
extern crate base64;
extern crate tempfile;
use std::collections::{HashSet, HashMap};
use std::collections::{HashMap, HashSet};
use std::fs::File;
use std::io::{self, Write, Read};
use std::io::{self, Read, Write};
use std::process::Command;
use parity_wasm::elements::*;
use failure::{Error, ResultExt};
use parity_wasm::elements::*;
pub struct Config {
base64: bool,
@ -65,31 +65,36 @@ impl Output {
let mut exports = format!("/* tslint:disable */\n");
if let Some(i) = self.module.export_section() {
let imported_functions = self.module.import_section()
let imported_functions = self
.module
.import_section()
.map(|m| m.functions() as u32)
.unwrap_or(0);
for entry in i.entries() {
let idx = match *entry.internal() {
Internal::Function(i) => i - imported_functions,
Internal::Memory(_) => {
exports.push_str(&format!("
exports.push_str(&format!(
"
export const {}: WebAssembly.Memory;
", entry.field()));
continue
}
Internal::Table(_) => {
continue
}
Internal::Global(_) => {
continue
",
entry.field()
));
continue;
}
Internal::Table(_) => continue,
Internal::Global(_) => continue,
};
let functions = self.module.function_section()
let functions = self
.module
.function_section()
.expect("failed to find function section");
let idx = functions.entries()[idx as usize].type_ref();
let types = self.module.type_section()
let types = self
.module
.type_section()
.expect("failed to find type section");
let ty = match types.types()[idx as usize] {
Type::Function(ref f) => f,
@ -103,12 +108,17 @@ impl Output {
args.push_str(": number");
}
exports.push_str(&format!("
exports.push_str(&format!(
"
export function {name}({args}): {ret};
",
",
name = entry.field(),
args = args,
ret = if ty.return_type().is_some() { "number" } else { "void" },
ret = if ty.return_type().is_some() {
"number"
} else {
"void"
},
));
}
}
@ -117,7 +127,7 @@ impl Output {
exports.push_str("export const booted: Promise<boolean>;");
}
return exports
return exports;
}
pub fn js(self) -> Result<String, Error> {
@ -146,19 +156,23 @@ impl Output {
}
if !set.insert(entry.module()) {
continue
continue;
}
let name = (b'a' + (set.len() as u8)) as char;
js_imports.push_str(&format!("import * as import_{} from '{}';",
name,
entry.module()));
js_imports.push_str(&format!(
"import * as import_{} from '{}';",
name,
entry.module()
));
imports.push_str(&format!("'{}': import_{}, ", entry.module(), name));
}
}
if let Some(i) = self.module.export_section() {
let imported_functions = self.module.import_section()
let imported_functions = self
.module
.import_section()
.map(|m| m.functions() as u32)
.unwrap_or(0);
for entry in i.entries() {
@ -166,21 +180,21 @@ impl Output {
Internal::Function(i) => i - imported_functions,
Internal::Memory(_) => {
export_mem = true;
continue
}
Internal::Table(_) => {
continue
}
Internal::Global(_) => {
continue
continue;
}
Internal::Table(_) => continue,
Internal::Global(_) => continue,
};
let functions = self.module.function_section()
let functions = self
.module
.function_section()
.expect("failed to find function section");
let idx = functions.entries()[idx as usize].type_ref();
let types = self.module.type_section()
let types = self
.module
.type_section()
.expect("failed to find type section");
let ty = match types.types()[idx as usize] {
Type::Function(ref f) => f,
@ -193,57 +207,79 @@ impl Output {
args.push((b'a' + (i as u8)) as char);
}
exports.push_str(&format!("
exports.push_str(&format!(
"
export function {name}({args}) {{
{ret} wasm.exports.{name}({args});
}}
",
",
name = entry.field(),
args = args,
ret = if ty.return_type().is_some() { "return" } else { "" },
ret = if ty.return_type().is_some() {
"return"
} else {
""
},
));
}
}
let inst = format!("WebAssembly.instantiate(bytes,{{ {imports} }})
let inst = format!(
"
WebAssembly.instantiate(bytes,{{ {imports} }})
.then(obj => {{
wasm = obj.instance;
{memory}
}})",
imports = imports,
memory = if export_mem { "memory = wasm.exports.memory;" } else { "" },
);
}})
",
imports = imports,
memory = if export_mem {
"memory = wasm.exports.memory;"
} else {
""
},
);
let (bytes, booted) = if self.base64 {
let wasm = serialize(self.module)
.expect("failed to serialize");
let wasm = serialize(self.module).expect("failed to serialize");
(
format!("
format!(
"
let bytes;
const base64 = \"{base64}\";
if (typeof Buffer === 'undefined') {{
bytes = Uint8Array.from(atob(base64), c => c.charCodeAt(0));
}} else {{
bytes = Buffer.from(base64, 'base64');
}}", base64 = base64::encode(&wasm)),
inst
}}
",
base64 = base64::encode(&wasm)
),
inst,
)
} else if let Some(ref path) = self.fetch_path {
(
String::new(),
format!("fetch('{path}')
.then(res => res.arrayBuffer())
.then(bytes => {inst})", path = path, inst = inst)
format!(
"
fetch('{path}')
.then(res => res.arrayBuffer())
.then(bytes => {inst})
",
path = path,
inst = inst
),
)
} else {
bail!("the option --base64 or --fetch is required");
};
Ok(format!("
Ok(format!(
"
{js_imports}
let wasm;
{bytes}
{mem_export}
export const booted = {booted};
{exports}
",
",
bytes = bytes,
booted = booted,
js_imports = js_imports,
@ -273,16 +309,20 @@ impl Output {
let m = name_map.entry(entry.field()).or_insert(entry.module());
if *m != entry.module() {
bail!("the name `{}` is imported from two differnet \
modules which currently isn't supported in `wasm2asm` \
mode");
bail!(
"the name `{}` is imported from two differnet \
modules which currently isn't supported in `wasm2asm` \
mode"
);
}
let name = format!("import{}", i);
js_imports.push_str(&format!("import {{ {} as {} }} from '{}';\n",
entry.field(),
name,
entry.module()));
js_imports.push_str(&format!(
"import {{ {} as {} }} from '{}';\n",
entry.field(),
name,
entry.module()
));
imported_items.push((entry.field().to_string(), name));
}
}
@ -298,18 +338,17 @@ impl Output {
Internal::Global(_) => continue,
};
js_exports.push_str(&format!("export const {0} = ret.{0};\n",
entry.field()));
js_exports.push_str(&format!("export const {0} = ret.{0};\n", entry.field()));
}
if !export_mem {
bail!("the `wasm2asm` mode is currently only compatible with \
modules that export memory")
bail!(
"the `wasm2asm` mode is currently only compatible with \
modules that export memory"
)
}
}
let memory_size = self.module.memory_section()
.unwrap()
.entries()[0]
let memory_size = self.module.memory_section().unwrap().entries()[0]
.limits()
.initial();
@ -329,9 +368,7 @@ impl Output {
};
let base64 = base64::encode(entry.value());
js_init_mem.push_str(&format!("_assign({}, \"{}\");\n",
offset,
base64));
js_init_mem.push_str(&format!("_assign({}, \"{}\");\n", offset, base64));
}
}
@ -340,9 +377,7 @@ impl Output {
let wasm_file = td.as_ref().join("foo.wasm");
File::create(&wasm_file)
.and_then(|mut f| f.write_all(&wasm))
.with_context(|_| {
format!("failed to write wasm to `{}`", wasm_file.display())
})?;
.with_context(|_| format!("failed to write wasm to `{}`", wasm_file.display()))?;
let wast_file = td.as_ref().join("foo.wast");
run(
@ -364,19 +399,19 @@ impl Output {
let mut asm_func = String::new();
File::open(&js_file)
.and_then(|mut f| f.read_to_string(&mut asm_func))
.with_context(|_| {
format!("failed to read `{}`", js_file.display())
})?;
.with_context(|_| format!("failed to read `{}`", js_file.display()))?;
let mut make_imports = String::from("
let mut make_imports = String::from(
"
var imports = {};
");
",
);
for (name, import) in imported_items {
make_imports.push_str(&format!("imports['{}'] = {};\n", name, import));
}
Ok(format!("\
Ok(format!(
"\
{js_imports}
{asm_func}
@ -410,7 +445,7 @@ impl Output {
Infinity,
}}, imports, mem);
{js_exports}
",
",
js_imports = js_imports,
js_init_mem = js_init_mem,
asm_func = asm_func,
@ -424,28 +459,31 @@ impl Output {
fn run(cmd: &mut Command, program: &str) -> Result<(), Error> {
let output = cmd.output().with_context(|e| {
if e.kind() == io::ErrorKind::NotFound {
format!("failed to execute `{}`, is the tool installed \
from the binaryen project?\ncommand line: {:?}",
program,
cmd)
format!(
"failed to execute `{}`, is the tool installed \
from the binaryen project?\ncommand line: {:?}",
program, cmd
)
} else {
format!("failed to execute: {:?}", cmd)
}
})?;
if output.status.success() {
return Ok(())
return Ok(());
}
let mut s = format!("failed to execute: {:?}\nstatus: {}\n",
cmd,
output.status);
let mut s = format!("failed to execute: {:?}\nstatus: {}\n", cmd, output.status);
if !output.stdout.is_empty() {
s.push_str(&format!("----- stdout ------\n{}\n",
String::from_utf8_lossy(&output.stdout)));
s.push_str(&format!(
"----- stdout ------\n{}\n",
String::from_utf8_lossy(&output.stdout)
));
}
if !output.stderr.is_empty() {
s.push_str(&format!("----- stderr ------\n{}\n",
String::from_utf8_lossy(&output.stderr)));
s.push_str(&format!(
"----- stderr ------\n{}\n",
String::from_utf8_lossy(&output.stderr)
));
}
bail!("{}", s)
}

View File

@ -15,7 +15,6 @@ information see https://github.com/alexcrichton/wasm-bindgen.
[dependencies]
docopt = "0.8"
failure = "0.1"
parity-wasm = "0.28"
serde = "1.0"
serde_derive = "1.0"
wasm-bindgen-cli-support = { path = "../cli-support", version = "=0.2.11" }

View File

@ -10,8 +10,8 @@ use std::path::PathBuf;
use std::process;
use docopt::Docopt;
use wasm_bindgen_cli_support::Bindgen;
use failure::Error;
use wasm_bindgen_cli_support::Bindgen;
const USAGE: &'static str = "
Generating JS bindings for a wasm file

View File

@ -1,12 +1,11 @@
#[macro_use]
extern crate serde_derive;
extern crate docopt;
extern crate parity_wasm;
extern crate wasm_bindgen_cli_support;
extern crate failure;
extern crate wasm_bindgen_cli_support;
use std::fs::File;
use std::io::{Write, Read};
use std::io::{Read, Write};
use std::path::PathBuf;
use std::process;
@ -76,9 +75,7 @@ fn rmain(args: &Args) -> Result<(), Error> {
let ts = object.typescript();
File::create(&dst)
.and_then(|mut f| f.write_all(ts.as_bytes()))
.with_context(|_| {
format!("failed to write `{}`", dst.display())
})?;
.with_context(|_| format!("failed to write `{}`", dst.display()))?;
}
}

View File

@ -1,9 +1,9 @@
#![feature(proc_macro)]
extern crate syn;
extern crate quote;
extern crate proc_macro;
extern crate proc_macro2;
extern crate quote;
extern crate syn;
extern crate wasm_bindgen_backend as backend;
use proc_macro::TokenStream;

View File

@ -1,7 +1,7 @@
#[macro_use]
extern crate serde_derive;
pub const SCHEMA_VERSION: &str = "4";
pub const SCHEMA_VERSION: &str = "5";
#[derive(Deserialize)]
pub struct ProgramOnlySchema {
@ -72,6 +72,7 @@ pub struct ImportType {}
pub struct Export {
pub class: Option<String>,
pub method: bool,
pub consumed: bool,
pub constructor: Option<String>,
pub function: Function,
pub comments: Vec<String>,

View File

@ -26,7 +26,6 @@ pub(crate) enum TsExport {
#[serde(rename = "returnValue")]
return_value: TsReturnValue,
},
//TODO: implement ...
//{ "$ref": "#/definitions/interfaceApiItem" },
//{ "$ref": "#/definitions/namespaceApiItem" },

View File

@ -1,6 +1,7 @@
extern crate proc_macro2;
extern crate serde;
#[macro_use] extern crate serde_derive;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate syn;
extern crate wasm_bindgen_backend as backend;

View File

@ -2,11 +2,11 @@ use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use backend::{self};
use backend;
use backend::ast::{BindgenAttrs, Export, Function};
use proc_macro2::{self};
use serde_json::{self};
use syn::{self};
use proc_macro2;
use serde_json;
use syn;
use api_extractor;
use definitions::*;
@ -25,7 +25,11 @@ pub fn ts_to_program(file_name: &str) -> backend::ast::Program {
match member {
TsClassMembers::TsProperty { .. } => {}
TsClassMembers::TsConstructor { .. } => {}
TsClassMembers::TsMethod { parameters, return_value, .. } => {
TsClassMembers::TsMethod {
parameters,
return_value,
..
} => {
let function = build_function(member_name, parameters, return_value);
program.exports.push(Export {
@ -33,14 +37,17 @@ pub fn ts_to_program(file_name: &str) -> backend::ast::Program {
method: true,
mutable: false,
constructor: None,
function,
function,
});
}
}
}
}
TsExport::TsFunction { parameters, return_value } => {
TsExport::TsFunction {
parameters,
return_value,
} => {
let function = build_function(name, parameters, return_value);
program.exports.push(Export {
@ -65,22 +72,29 @@ fn parse_json(file_name: &str) -> TsPackage {
serde_json::from_str(&data).unwrap()
}
fn build_function(name: String, parameters: HashMap<String, TsMethodProperty>, return_value: TsReturnValue) -> Function {
let arguments = parameters.iter().map( |(_name, property)| {
let mut segments = syn::punctuated::Punctuated::new();
segments.push(syn::PathSegment {
ident: syn::Ident::new(&property.property_type, proc_macro2::Span::call_site()),
arguments: syn::PathArguments::None,
});
fn build_function(
name: String,
parameters: HashMap<String, TsMethodProperty>,
return_value: TsReturnValue,
) -> Function {
let arguments = parameters
.iter()
.map(|(_name, property)| {
let mut segments = syn::punctuated::Punctuated::new();
segments.push(syn::PathSegment {
ident: syn::Ident::new(&property.property_type, proc_macro2::Span::call_site()),
arguments: syn::PathArguments::None,
});
syn::Type::Path(syn::TypePath {
qself: None,
path: syn::Path {
leading_colon: None,
segments,
}
syn::Type::Path(syn::TypePath {
qself: None,
path: syn::Path {
leading_colon: None,
segments,
},
})
})
}).collect::<Vec<_>>();
.collect::<Vec<_>>();
let mut ret_segments = syn::punctuated::Punctuated::new();
ret_segments.push(syn::PathSegment {
@ -93,7 +107,7 @@ fn build_function(name: String, parameters: HashMap<String, TsMethodProperty>, r
path: syn::Path {
leading_colon: None,
segments: ret_segments,
}
},
});
let rust_decl = Box::new(syn::FnDecl {

View File

@ -3,19 +3,11 @@ name = "wasm-bindgen-webidl"
version = "0.2.11"
authors = ["Nick Fitzgerald <fitzgen@gmail.com>"]
[[test]]
name = "webidl-all"
path = "tests/all/lib.rs"
[[test]]
name = "webidl-expected"
path = "tests/expected/lib.rs"
[dev-dependencies]
diff = "0.1.11"
env_logger = "0.5.10"
wasm-bindgen = { version = "=0.2.11", path = "../..", default-features = false }
wasm-bindgen-backend = { version = "=0.2.11", path = "../backend", features = ["extra-traits"] }
wasm-bindgen = { path = "../..", default-features = false }
wasm-bindgen-backend = { path = "../backend", features = ["extra-traits"] }
[dependencies]
failure = "0.1"

24
crates/webidl/src/lib.rs Executable file → Normal file
View File

@ -128,6 +128,10 @@ impl WebidlParse<()> for webidl::ast::Interface {
impl WebidlParse<()> for webidl::ast::Typedef {
fn webidl_parse(&self, program: &mut backend::ast::Program, _: ()) -> Result<()> {
if util::is_chrome_only(&self.extended_attributes) {
return Ok(())
}
let dest = rust_ident(&self.name);
let src = match webidl_ty_to_syn_ty(&self.type_, TypePosition::Return) {
Some(src) => src,
@ -154,6 +158,10 @@ impl WebidlParse<()> for webidl::ast::Typedef {
impl WebidlParse<()> for webidl::ast::NonPartialInterface {
fn webidl_parse(&self, program: &mut backend::ast::Program, _: ()) -> Result<()> {
if util::is_chrome_only(&self.extended_attributes) {
return Ok(())
}
program.imports.push(backend::ast::Import {
module: None,
version: None,
@ -293,6 +301,10 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::Operation {
impl<'a> WebidlParse<&'a str> for webidl::ast::RegularAttribute {
fn webidl_parse(&self, program: &mut backend::ast::Program, self_name: &'a str) -> Result<()> {
if util::is_chrome_only(&self.extended_attributes) {
return Ok(())
}
create_getter(
&self.name,
&self.type_,
@ -317,6 +329,10 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::RegularAttribute {
impl<'a> WebidlParse<&'a str> for webidl::ast::StaticAttribute {
fn webidl_parse(&self, program: &mut backend::ast::Program, self_name: &'a str) -> Result<()> {
if util::is_chrome_only(&self.extended_attributes) {
return Ok(())
}
create_getter(
&self.name,
&self.type_,
@ -341,6 +357,10 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::StaticAttribute {
impl<'a> WebidlParse<&'a str> for webidl::ast::RegularOperation {
fn webidl_parse(&self, program: &mut backend::ast::Program, self_name: &'a str) -> Result<()> {
if util::is_chrome_only(&self.extended_attributes) {
return Ok(())
}
create_basic_method(
&self.arguments,
self.name.as_ref(),
@ -356,6 +376,10 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::RegularOperation {
impl<'a> WebidlParse<&'a str> for webidl::ast::StaticOperation {
fn webidl_parse(&self, program: &mut backend::ast::Program, self_name: &'a str) -> Result<()> {
if util::is_chrome_only(&self.extended_attributes) {
return Ok(())
}
create_basic_method(
&self.arguments,
self.name.as_ref(),

View File

@ -6,6 +6,7 @@ use heck::SnakeCase;
use proc_macro2::Ident;
use syn;
use webidl;
use webidl::ast::ExtendedAttribute;
fn shared_ref(ty: syn::Type) -> syn::Type {
syn::TypeReference {
@ -285,3 +286,32 @@ pub fn create_setter(
vec![backend::ast::BindgenAttr::Setter(Some(raw_ident(name)))],
)
}
/// ChromeOnly is for things that are only exposed to priveleged code in Firefox.
pub fn is_chrome_only(ext_attrs: &[Box<ExtendedAttribute>]) -> bool {
ext_attrs.iter().any(|external_attribute| {
return match &**external_attribute {
ExtendedAttribute::ArgumentList(al) => {
println!("ArgumentList");
al.name == "ChromeOnly"
},
ExtendedAttribute::Identifier(i) => {
println!("Identifier");
i.lhs == "ChromeOnly"
},
ExtendedAttribute::IdentifierList(il) => {
println!("IdentifierList");
il.lhs == "ChromeOnly"
},
ExtendedAttribute::NamedArgumentList(nal) => {
println!("NamedArgumentList");
nal.lhs_name == "ChromeOnly"
},
ExtendedAttribute::NoArguments(webidl::ast::Other::Identifier(name)) => name == "ChromeOnly",
ExtendedAttribute::NoArguments(_na) => {
println!("NoArguments");
false
}
};
})
}

View File

@ -99,7 +99,7 @@ impl Event {
pub extern "C" fn new(type_: &str, event_init_dict: EventInit) -> Event {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -143,7 +143,7 @@ impl Event {
pub extern "C" fn event_phase(&self) -> u16 {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -183,7 +183,7 @@ impl Event {
pub extern "C" fn stop_propagation(&self) {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -223,7 +223,7 @@ impl Event {
pub extern "C" fn stop_immediate_propagation(&self) {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -267,7 +267,7 @@ impl Event {
pub extern "C" fn bubbles(&self) -> bool {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -311,7 +311,7 @@ impl Event {
pub extern "C" fn cancelable(&self) -> bool {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -351,7 +351,7 @@ impl Event {
pub extern "C" fn prevent_default(&self) {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -395,95 +395,7 @@ impl Event {
pub extern "C" fn default_prevented(&self) -> bool {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
);
}
}
#[no_mangle]
#[allow(non_snake_case)]
#[doc(hidden)]
pub extern "C" fn __wbindgen_describe___widl_f_default_prevented_by_chrome_Event() {
use wasm_bindgen::describe::*;
inform(FUNCTION);
inform(1u32);
<&Event as WasmDescribe>::describe();
inform(1);
<bool as WasmDescribe>::describe();
}
impl Event {
#[allow(bad_style)]
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
pub extern "C" fn default_prevented_by_chrome(&self) -> bool {
::wasm_bindgen::__rt::link_this_library();
#[wasm_import_module = "__wbindgen_placeholder__"]
extern "C" {
fn __widl_f_default_prevented_by_chrome_Event(
self_: <&Event as ::wasm_bindgen::convert::IntoWasmAbi>::Abi,
) -> <bool as ::wasm_bindgen::convert::FromWasmAbi>::Abi;
}
unsafe {
let _ret = {
let mut __stack = ::wasm_bindgen::convert::GlobalStack::new();
let self_ =
<&Event as ::wasm_bindgen::convert::IntoWasmAbi>::into_abi(self, &mut __stack);
__widl_f_default_prevented_by_chrome_Event(self_)
};
<bool as ::wasm_bindgen::convert::FromWasmAbi>::from_abi(
_ret,
&mut ::wasm_bindgen::convert::GlobalStack::new(),
)
}
}
#[allow(bad_style, unused_variables)]
#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
pub extern "C" fn default_prevented_by_chrome(&self) -> bool {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
);
}
}
#[no_mangle]
#[allow(non_snake_case)]
#[doc(hidden)]
pub extern "C" fn __wbindgen_describe___widl_f_default_prevented_by_content_Event() {
use wasm_bindgen::describe::*;
inform(FUNCTION);
inform(1u32);
<&Event as WasmDescribe>::describe();
inform(1);
<bool as WasmDescribe>::describe();
}
impl Event {
#[allow(bad_style)]
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
pub extern "C" fn default_prevented_by_content(&self) -> bool {
::wasm_bindgen::__rt::link_this_library();
#[wasm_import_module = "__wbindgen_placeholder__"]
extern "C" {
fn __widl_f_default_prevented_by_content_Event(
self_: <&Event as ::wasm_bindgen::convert::IntoWasmAbi>::Abi,
) -> <bool as ::wasm_bindgen::convert::FromWasmAbi>::Abi;
}
unsafe {
let _ret = {
let mut __stack = ::wasm_bindgen::convert::GlobalStack::new();
let self_ =
<&Event as ::wasm_bindgen::convert::IntoWasmAbi>::into_abi(self, &mut __stack);
__widl_f_default_prevented_by_content_Event(self_)
};
<bool as ::wasm_bindgen::convert::FromWasmAbi>::from_abi(
_ret,
&mut ::wasm_bindgen::convert::GlobalStack::new(),
)
}
}
#[allow(bad_style, unused_variables)]
#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
pub extern "C" fn default_prevented_by_content(&self) -> bool {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -527,7 +439,7 @@ impl Event {
pub extern "C" fn composed(&self) -> bool {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -571,7 +483,7 @@ impl Event {
pub extern "C" fn is_trusted(&self) -> bool {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -615,7 +527,7 @@ impl Event {
pub extern "C" fn time_stamp(&self) -> DOMHighResTimeStamp {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -669,7 +581,7 @@ impl Event {
pub extern "C" fn init_event(&self, type_: &str, bubbles: bool, cancelable: bool) {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -713,7 +625,7 @@ impl Event {
pub extern "C" fn cancel_bubble(&self) -> bool {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}
@ -759,7 +671,7 @@ impl Event {
pub extern "C" fn set_cancel_bubble(&self, cancel_bubble: bool) {
panic!(
"cannot call wasm-bindgen imported functions on \
non-wasm targets"
non-wasm targets"
);
}
}

View File

@ -5,7 +5,7 @@ extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}

View File

@ -5,7 +5,7 @@ extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
@ -14,7 +14,7 @@ extern {
#[wasm_bindgen]
pub struct Counter {
key: char,
count: i32
count: i32,
}
#[wasm_bindgen]
@ -25,7 +25,10 @@ impl Counter {
}
pub fn new(key: char, count: i32) -> Counter {
log(&format!("Counter::new({}, {})", key, count));
Counter { key: key, count: count }
Counter {
key: key,
count: count,
}
}
pub fn key(&self) -> char {
@ -46,4 +49,4 @@ impl Counter {
pub fn update_key(&mut self, key: char) {
self.key = key;
}
}
}

View File

@ -2,12 +2,12 @@
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js::Date;
use wasm_bindgen::js::JsString;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
extern "C" {
// Binding for the `setInverval` method in JS. This function takes a "long
// lived" closure as the first argument so we use `Closure` instead of
// a bare `&Fn()` which only surives for that one stack frame.
@ -51,12 +51,11 @@ pub fn run() {
set_interval(&a, 1000);
update_time();
fn update_time() {
document.get_element_by_id("current-time")
.set_inner_html(
&String::from(
Date::new()
.to_locale_string(
JsString::from("en-GB"), JsValue::undefined())));
document
.get_element_by_id("current-time")
.set_inner_html(&String::from(
Date::new().to_locale_string(JsString::from("en-GB"), JsValue::undefined()),
));
}
// We also want to count the number of times that our green square has been
@ -65,7 +64,8 @@ pub fn run() {
let mut clicks = 0;
let b = Closure::new(move || {
clicks += 1;
document.get_element_by_id("num-clicks")
document
.get_element_by_id("num-clicks")
.set_inner_html(&clicks.to_string());
});
square.set_onclick(&b);
@ -84,10 +84,12 @@ pub fn run() {
// And finally now that our demo is ready to go let's switch things up so
// everything is displayed and our loading prompt is hidden.
document.get_html_element_by_id("loading")
document
.get_html_element_by_id("loading")
.style()
.set_display("none");
document.get_html_element_by_id("script")
document
.get_html_element_by_id("script")
.style()
.set_display("block");
}

View File

@ -15,7 +15,6 @@ pub struct Comment {
color: Color,
}
#[wasm_bindgen]
impl Comment {
#[wasm_bindgen(method)]
@ -57,4 +56,4 @@ impl Comment {
pub enum Color {
Blue,
Pink,
}
}

View File

@ -5,7 +5,7 @@ extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
#[wasm_bindgen(js_namespace = console, js_name = log)]

View File

@ -15,7 +15,7 @@ use wasm_bindgen::prelude::*;
// In the meantime these are written out by hand and correspond to the names and
// signatures documented on MDN, for example
#[wasm_bindgen]
extern {
extern "C" {
type HTMLDocument;
static document: HTMLDocument;
#[wasm_bindgen(method)]

View File

@ -5,7 +5,7 @@ extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
extern "C" {
fn alert(s: &str);
}

View File

@ -5,7 +5,7 @@ extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./defined-in-js")]
extern {
extern "C" {
fn name() -> String;
type MyClass;
@ -23,7 +23,7 @@ extern {
// Import `console.log` so we can log something to the console
#[wasm_bindgen]
extern {
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}

View File

@ -5,7 +5,7 @@ extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
extern "C" {
#[wasm_bindgen(js_namespace = Math)]
fn log2(a: f64) -> f64;
#[wasm_bindgen(js_namespace = Math)]

View File

@ -5,7 +5,7 @@ extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
extern "C" {
fn alert(s: &str);
}

View File

@ -1,7 +1,7 @@
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
extern crate humantime;
extern crate wasm_bindgen;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
@ -10,7 +10,7 @@ use wasm_bindgen::prelude::*;
// Like with the `dom` example this block will eventually be auto-generated, but
// for now we can write it by hand to get by!
#[wasm_bindgen]
extern {
extern "C" {
type Performance;
static performance: Performance;
#[wasm_bindgen(method)]

View File

@ -7,10 +7,10 @@ use wasm_bindgen::prelude::*;
// Strings can both be passed in and received
#[wasm_bindgen]
#[no_mangle]
pub extern fn concat(a: &str, b: &str) -> String {
pub extern "C" fn concat(a: &str, b: &str) -> String {
let mut a = a.to_string();
a.push_str(b);
return a
return a;
}
// A struct will show up as a class on the JS side of things
@ -29,7 +29,7 @@ impl Foo {
// can pass to a normal free function also all work in methods.
pub fn add(&mut self, amt: u32) -> u32 {
self.contents += amt;
return self.contents
return self.contents;
}
// You can also take a limited set of references to other types as well.
@ -50,7 +50,7 @@ pub struct Bar {
}
#[wasm_bindgen(module = "./awesome")] // what ES6 module to import from
extern {
extern "C" {
fn bar_on_reset(to: &str, opaque: &JsValue);
// We can import classes and annotate functionality on those classes as well
@ -64,9 +64,7 @@ extern {
#[wasm_bindgen]
impl Bar {
pub fn from_str(s: &str, opaque: JsValue) -> Bar {
let contents = s.parse().unwrap_or_else(|_| {
Awesome::new().get_internal()
});
let contents = s.parse().unwrap_or_else(|_| Awesome::new().get_internal());
Bar { contents, opaque }
}

View File

@ -7,7 +7,7 @@ use wasm_bindgen::prelude::*;
// Like with the `dom` example this block will eventually be auto-generated, but
// for now we can write it by hand to get by!
#[wasm_bindgen]
extern {
extern "C" {
type Module;
#[wasm_bindgen(constructor, js_namespace = WebAssembly)]
fn new(data: &[u8]) -> Module;

View File

@ -706,6 +706,9 @@ let's go through one-by-one:
this function must be a bare type, like `Bar`.
* `#[wasm_bindgen(js_namespace = Bar)]` - this attribute indicates that the
function declaration is namespaced through the `Bar` class in JS.
* `#[wasm_bindgen(static_method_of = SomeJsClass)]` - this attribute is similar
to `js_namespace`, but instead of producing a free function, produces a static
method of `SomeJsClass`.
* `#[wasm_bindgen(method)]` - and finally, this attribute indicates that a
method call is going to happen. The first argument must be a JS struct, like
`Bar`, and the call in JS looks like `Bar.prototype.set.call(...)`.

View File

@ -20,11 +20,15 @@ img {
}
</style>
| [![](https://github.com/alexcrichton.png?size=117)][alexcrichton] | [![](https://github.com/fitzgen.png?size=117)][fitzgen] | [![](https://github.com/spastorino.png?size=117)][spastorino] | [![](https://github.com/ohanar.png?size=117)][ohanar] |
| [![](https://github.com/alexcrichton.png?size=117)][alexcrichton] | [![](https://github.com/fitzgen.png?size=117)][fitzgen] | [![](https://github.com/spastorino.png?size=117)][spastorino] | [![](https://github.com/ohanar.png?size=117)][ohanar] | [![](https://github.com/jonathan-s.png?size=117)][jonathan-s] |
|:---:|:---:|:---:|:---:|
| [`alexcrichton`][alexcrichton] | [`fitzgen`][fitzgen] | [`spastorino`][spastorino] | [`ohanar`][ohanar] |
| [`alexcrichton`][alexcrichton] | [`fitzgen`][fitzgen] | [`spastorino`][spastorino] | [`ohanar`][ohanar] | [`jonathan-s`][jonathan-s] |
| [![](https://github.com/sendilkumarn.png?size=117)][sendilkumarn] | | | | |
| [`sendilkumarn`][sendilkumarn] | | | | |
[alexcrichton]: https://github.com/alexcrichton
[fitzgen]: https://github.com/fitzgen
[spastorino]: https://github.com/spastorino
[ohanar]: https://github.com/ohanar
[jonathan-s]: https://github.com/jonathan-s
[sendilkumarn]: https://github.com/sendilkumarn

View File

@ -1,14 +1,14 @@
//! This is mostly an internal module, no stability guarantees are provided. Use
//! at your own risk.
use core::char;
use core::mem::{self, ManuallyDrop};
use core::ops::{Deref, DerefMut};
use core::slice;
use core::str;
use core::char;
use {JsValue, throw};
use describe::*;
use {throw, JsValue};
#[cfg(feature = "std")]
use std::prelude::v1::*;
@ -59,7 +59,7 @@ pub trait RefFromWasmAbi: WasmDescribe {
/// invocation of the function that has an `&Self` parameter. This is
/// required to ensure that the lifetimes don't persist beyond one function
/// call, and so that they remain anonymous.
type Anchor: Deref<Target=Self>;
type Anchor: Deref<Target = Self>;
/// Recover a `Self::Anchor` from `Self::Abi`.
///
@ -71,7 +71,7 @@ pub trait RefFromWasmAbi: WasmDescribe {
pub trait RefMutFromWasmAbi: WasmDescribe {
type Abi: WasmAbi;
type Anchor: DerefMut<Target=Self>;
type Anchor: DerefMut<Target = Self>;
unsafe fn ref_mut_from_abi(js: Self::Abi, extra: &mut Stack) -> Self::Anchor;
}
@ -159,18 +159,24 @@ as_u32!(i8 u8 i16 u16 isize usize);
impl IntoWasmAbi for bool {
type Abi = u32;
fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 }
fn into_abi(self, _extra: &mut Stack) -> u32 {
self as u32
}
}
impl FromWasmAbi for bool {
type Abi = u32;
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> bool { js != 0 }
unsafe fn from_abi(js: u32, _extra: &mut Stack) -> bool {
js != 0
}
}
impl IntoWasmAbi for char {
type Abi = u32;
fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 }
fn into_abi(self, _extra: &mut Stack) -> u32 {
self as u32
}
}
impl FromWasmAbi for char {
@ -183,7 +189,9 @@ impl FromWasmAbi for char {
impl<T> IntoWasmAbi for *const T {
type Abi = u32;
fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 }
fn into_abi(self, _extra: &mut Stack) -> u32 {
self as u32
}
}
impl<T> FromWasmAbi for *const T {
@ -197,7 +205,9 @@ impl<T> FromWasmAbi for *const T {
impl<T> IntoWasmAbi for *mut T {
type Abi = u32;
fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 }
fn into_abi(self, _extra: &mut Stack) -> u32 {
self as u32
}
}
impl<T> FromWasmAbi for *mut T {
@ -343,7 +353,7 @@ impl IntoWasmAbi for JsValue {
fn into_abi(self, _extra: &mut Stack) -> u32 {
let ret = self.idx;
mem::forget(self);
return ret
return ret;
}
}
@ -397,7 +407,9 @@ if_std! {
}
}
pub struct GlobalStack { next: usize }
pub struct GlobalStack {
next: usize,
}
const GLOBAL_STACK_CAP: usize = 16;
static mut GLOBAL_STACK: [u32; GLOBAL_STACK_CAP] = [0; GLOBAL_STACK_CAP];
@ -429,7 +441,7 @@ impl Stack for GlobalStack {
#[doc(hidden)]
#[no_mangle]
pub unsafe extern fn __wbindgen_global_argument_ptr() -> *mut u32 {
pub unsafe extern "C" fn __wbindgen_global_argument_ptr() -> *mut u32 {
GLOBAL_STACK.as_mut_ptr()
}

View File

@ -41,9 +41,7 @@ tys! {
}
pub fn inform(a: u32) {
unsafe {
super::__wbindgen_describe(a)
}
unsafe { super::__wbindgen_describe(a) }
}
pub trait WasmDescribe {
@ -78,11 +76,15 @@ simple! {
}
impl<T> WasmDescribe for *const T {
fn describe() { inform(I32) }
fn describe() {
inform(I32)
}
}
impl<T> WasmDescribe for *mut T {
fn describe() { inform(I32) }
fn describe() {
inform(I32)
}
}
impl<T: WasmDescribe> WasmDescribe for [T] {
@ -127,7 +129,9 @@ if_std! {
}
}
fn _cnt<T: WasmDescribe>() -> u32 { 1 }
fn _cnt<T: WasmDescribe>() -> u32 {
1
}
macro_rules! doit {
($( ($($var:ident)*))*) => ($(

507
src/js.rs
View File

@ -35,12 +35,13 @@ if_std! {
// * If a function or method can throw an exception, make it catchable by adding
// `#[wasm_bindgen(catch)]`.
//
// * Add a new `#[test]` to the `tests/all/js_globals.rs` file. If the imported
// function or method can throw an exception, make sure to also add test
// coverage for that case.
// * Add a new `#[test]` into the appropriate file in the
// `tests/all/js_globals/` directory. If the imported function or
// method can throw an exception, make sure to also add test coverage
// for that case.
#[wasm_bindgen]
extern {
extern "C" {
/// The `decodeURI()` function decodes a Uniform Resource Identifier (URI)
/// previously created by `encodeURI` or by a similar routine.
///
@ -48,6 +49,13 @@ extern {
#[wasm_bindgen(catch, js_name = decodeURI)]
pub fn decode_uri(encoded: &str) -> Result<JsString, JsValue>;
/// The decodeURIComponent() function decodes a Uniform Resource Identifier (URI) component
/// previously created by encodeURIComponent or by a similar routine.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent
#[wasm_bindgen(catch, js_name = decodeURIComponent)]
pub fn decode_uri_component(encoded: &str) -> Result<JsString, JsValue>;
/// The `encodeURI()` function encodes a Uniform Resource Identifier (URI)
/// by replacing each instance of certain characters by one, two, three, or
/// four escape sequences representing the UTF-8 encoding of the character
@ -58,6 +66,15 @@ extern {
#[wasm_bindgen(js_name = encodeURI)]
pub fn encode_uri(decoded: &str) -> JsString;
/// The encodeURIComponent() function encodes a Uniform Resource Identifier (URI) component
/// by replacing each instance of certain characters by one, two, three, or four escape sequences
/// representing the UTF-8 encoding of the character
/// (will only be four escape sequences for characters composed of two "surrogate" characters).
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
#[wasm_bindgen(js_name = encodeURIComponent)]
pub fn encode_uri_component(decoded: &str) -> JsString;
/// The `eval()` function evaluates JavaScript code represented as a string.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
@ -67,7 +84,7 @@ extern {
// UInt8Array
#[wasm_bindgen]
extern {
extern "C" {
pub type Uint8Array;
/// The `Uint8Array()` constructor creates an array of unsigned 8-bit integers.
@ -86,7 +103,7 @@ extern {
// Array
#[wasm_bindgen]
extern {
extern "C" {
pub type Array;
/// The copyWithin() method shallow copies part of an array to another
@ -103,6 +120,13 @@ extern {
#[wasm_bindgen(method)]
pub fn concat(this: &Array, array: &Array) -> Array;
/// The every() method tests whether all elements in the array pass the test
/// implemented by the provided function.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every
#[wasm_bindgen(method)]
pub fn every(this: &Array, predicate: &mut FnMut(JsValue, u32, Array) -> bool) -> bool;
/// The fill() method fills all the elements of an array from a start index
/// to an end index with a static value. The end index is not included.
///
@ -197,6 +221,13 @@ extern {
#[wasm_bindgen(method)]
pub fn slice(this: &Array, start: u32, end: u32) -> Array;
/// The some() method tests whether at least one element in the array passes the test implemented
/// by the provided function.
/// Note: This method returns false for any condition put on an empty array.
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
#[wasm_bindgen(method)]
pub fn some(this: &Array, predicate: &mut FnMut(JsValue) -> bool) -> bool;
/// The sort() method sorts the elements of an array in place and returns
/// the array. The sort is not necessarily stable. The default sort
/// order is according to string Unicode code points.
@ -225,7 +256,7 @@ extern {
// Array Iterator
#[wasm_bindgen]
extern {
extern "C" {
pub type ArrayIterator;
/// The keys() method returns a new Array Iterator object that contains the
@ -243,18 +274,80 @@ extern {
pub fn entries(this: &Array) -> ArrayIterator;
}
// Boolean
#[wasm_bindgen]
extern "C" {
pub type Boolean;
/// The `Boolean()` constructor creates an object wrapper for a boolean value.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
#[wasm_bindgen(constructor)]
pub fn new(value: JsValue) -> Boolean;
/// The `valueOf()` method returns the primitive value of a `Boolean` object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean/valueOf
#[wasm_bindgen(method, js_name = valueOf)]
pub fn value_of(this: &Boolean) -> bool;
}
// Error
#[wasm_bindgen]
extern "C" {
pub type Error;
/// The Error constructor creates an error object.
/// Instances of Error objects are thrown when runtime errors occur.
/// The Error object can also be used as a base object for user-defined exceptions.
/// See below for standard built-in error types.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
#[wasm_bindgen(constructor)]
pub fn new(message: &JsString) -> Error;
/// The message property is a human-readable description of the error.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/message
#[wasm_bindgen(method, getter, structural)]
pub fn message(this: &Error) -> JsString;
#[wasm_bindgen(method, setter, structural)]
pub fn set_message(this: &Error, message: &JsString);
/// The name property represents a name for the type of error. The initial value is "Error".
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/name
#[wasm_bindgen(method, getter, structural)]
pub fn name(this: &Error) -> JsString;
#[wasm_bindgen(method, setter, structural)]
pub fn set_name(this: &Error, name: &JsString);
/// The toString() method returns a string representing the specified Error object
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString
#[wasm_bindgen(method, js_name = toString)]
pub fn to_string(this: &Error) -> JsString;
}
// Function
#[wasm_bindgen]
extern {
extern "C" {
pub type Function;
/// The apply() method calls a function with a given this value, and arguments provided as an array
/// (or an array-like object).
///
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
#[wasm_bindgen(method)]
pub fn apply(this: &Function, context: &JsValue, args: &Array) -> Function;
/// The bind() method creates a new function that, when called, has its this keyword set to the provided value,
/// with a given sequence of arguments preceding any provided when the new function is called.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
#[wasm_bindgen(method)]
pub fn bind(this: &Function, context: &JsValue) -> Function;
/// The length property indicates the number of arguments expected by the function.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length
@ -270,22 +363,103 @@ extern {
pub fn name(this: &Function) -> JsString;
/// The toString() method returns a string representing the source code of the function.
///
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/toString
#[wasm_bindgen(method, js_name = toString)]
pub fn to_string(this: &Function) -> JsString;
}
// Math
// Map
#[wasm_bindgen]
extern {
pub type Map;
/// The clear() method removes all elements from a Map object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear
#[wasm_bindgen(method)]
pub fn clear(this: &Map);
/// The delete() method removes the specified element from a Map object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete
#[wasm_bindgen(method)]
pub fn delete(this: &Map, key: &str) -> bool;
/// The get() method returns a specified element from a Map object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get
#[wasm_bindgen(method)]
pub fn get(this: &Map, key: &JsValue) -> JsValue;
/// The has() method returns a boolean indicating whether an element with
/// the specified key exists or not.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has
#[wasm_bindgen(method)]
pub fn has(this: &Map, key: &JsValue) -> bool;
/// The Map object holds key-value pairs. Any value (both objects and
/// primitive values) maybe used as either a key or a value.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
#[wasm_bindgen(constructor)]
pub fn new() -> Map;
/// The set() method adds or updates an element with a specified key
/// and value to a Map object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set
#[wasm_bindgen(method)]
pub fn set(this: &Map, key: &JsValue, value: &JsValue) -> Map;
/// The value of size is an integer representing how many entries
/// the Map object has. A set accessor function for size is undefined;
/// you can not change this property.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size
#[wasm_bindgen(method, getter, structural)]
pub fn size(this: &Map) -> Number;
}
// Map Iterator
#[wasm_bindgen]
extern {
pub type MapIterator;
/// The entries() method returns a new Iterator object that contains
/// the [key, value] pairs for each element in the Map object in
/// insertion order.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries
#[wasm_bindgen(method)]
pub fn entries(this: &Map) -> MapIterator;
/// The keys() method returns a new Iterator object that contains the
/// keys for each element in the Map object in insertion order.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys
#[wasm_bindgen(method)]
pub fn keys(this: &Map) -> MapIterator;
/// The values() method returns a new Iterator object that contains the
/// values for each element in the Map object in insertion order.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values
#[wasm_bindgen(method)]
pub fn values(this: &Map) -> MapIterator;
}
// Math
#[wasm_bindgen]
extern "C" {
pub type Math;
/// The Math.abs() function returns the absolute value of a number, that is
/// Math.abs(x) = |x|
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs
#[wasm_bindgen(static_method_of = Math)]
pub fn abs(number: i32) -> Number;
pub fn abs(x: f64) -> Number;
/// The Math.acos() function returns the arccosine (in radians) of a
/// number, that is ∀x∊[-1;1]
@ -293,7 +467,7 @@ extern {
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acos
#[wasm_bindgen(static_method_of = Math)]
pub fn acos(adjacent: i32, hypotenuse: i32) -> Number;
pub fn acos(x: f64) -> Number;
/// The Math.acosh() function returns the hyperbolic arc-cosine of a
/// number, that is ∀x ≥ 1
@ -301,7 +475,7 @@ extern {
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh
#[wasm_bindgen(static_method_of = Math)]
pub fn acosh(number: i32) -> Number;
pub fn acosh(x: f64) -> Number;
/// The Math.asin() function returns the arcsine (in radians) of a
/// number, that is ∀x ∊ [-1;1]
@ -309,27 +483,27 @@ extern {
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asin
#[wasm_bindgen(static_method_of = Math)]
pub fn asin(number: i32) -> Number;
pub fn asin(x: f64) -> Number;
/// The Math.asinh() function returns the hyperbolic arcsine of a
/// number, that is Math.asinh(x) = arsinh(x) = the unique y such that sinh(y) = x
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh
#[wasm_bindgen(static_method_of = Math)]
pub fn asinh(number: i32) -> Number;
pub fn asinh(x: f64) -> Number;
/// The Math.atan() function returns the arctangent (in radians) of a
/// number, that is Math.atan(x) = arctan(x) = the unique y ∊ [-π2;π2]such that
/// tan(y) = x
#[wasm_bindgen(static_method_of = Math)]
pub fn atan(number: i32) -> Number;
pub fn atan(x: f64) -> Number;
/// The Math.atan2() function returns the arctangent of the quotient of
/// its arguments.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2
#[wasm_bindgen(static_method_of = Math)]
pub fn atan2(y: i32, x: i32) -> Number;
pub fn atan2(y: f64, x: f64) -> Number;
/// The Math.atanh() function returns the hyperbolic arctangent of a number,
/// that is ∀x ∊ (-1,1), Math.atanh(x) = arctanh(x) = the unique y such that
@ -337,22 +511,21 @@ extern {
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh
#[wasm_bindgen(static_method_of = Math)]
pub fn atanh(x: i32) -> Number;
pub fn atanh(x: f64) -> Number;
/// The Math.cbrt() function returns the cube root of a number, that is
/// Math.cbrt(x) = x^3 = the unique y such that y^3 = x
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt
#[wasm_bindgen(static_method_of = Math)]
pub fn cbrt(x: i32) -> Number;
pub fn cbrt(x: f64) -> Number;
/// The Math.ceil() function returns the smallest integer greater than
/// or equal to a given number.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil
#[wasm_bindgen(static_method_of = Math)]
pub fn ceil(x: f32) -> Number;
pub fn ceil(x: f64) -> Number;
/// The Math.clz32() function returns the number of leading zero bits in
/// the 32-bit binary representation of a number.
@ -360,11 +533,86 @@ extern {
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
#[wasm_bindgen(static_method_of = Math)]
pub fn clz32(x: i32) -> Number;
/// The Math.cos() static function returns the cosine of the specified angle,
/// which must be specified in radians. This value is length(adjacent)/length(hypotenuse).
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos
#[wasm_bindgen(static_method_of = Math)]
pub fn cos(x: f64) -> Number;
/// The Math.cosh() function returns the hyperbolic cosine of a number,
/// that can be expressed using the constant e.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh
#[wasm_bindgen(static_method_of = Math)]
pub fn cosh(x: f64) -> Number;
/// The Math.exp() function returns e^x, where x is the argument, and e is Euler's number
/// (also known as Napier's constant), the base of the natural logarithms.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp
#[wasm_bindgen(static_method_of = Math)]
pub fn exp(x: f64) -> Number;
/// The Math.expm1() function returns e^x - 1, where x is the argument, and e the base of the
/// natural logarithms.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1
#[wasm_bindgen(static_method_of = Math)]
pub fn expm1(x: f64) -> Number;
/// The Math.floor() function returns the largest integer less than or
/// equal to a given number.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor
#[wasm_bindgen(static_method_of = Math)]
pub fn floor(x: f64) -> Number;
/// The Math.fround() function returns the nearest 32-bit single precision float representation
/// of a Number.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
#[wasm_bindgen(static_method_of = Math)]
pub fn fround(x: f64) -> Number;
/// The Math.imul() function returns the result of the C-like 32-bit multiplication of the
/// two parameters.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
#[wasm_bindgen(static_method_of = Math)]
pub fn imul(x: i32, y: i32) -> Number;
/// The Math.log() function returns the natural logarithm (base e) of a number.
/// The JavaScript Math.log() function is equivalent to ln(x) in mathematics.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log
#[wasm_bindgen(static_method_of = Math)]
pub fn log(x: f64) -> Number;
/// The Math.log10() function returns the base 10 logarithm of a number.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10
#[wasm_bindgen(static_method_of = Math)]
pub fn log10(x: f64) -> Number;
/// The Math.log1p() function returns the natural logarithm (base e) of 1 + a number.
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p
#[wasm_bindgen(static_method_of = Math)]
pub fn log1p(x: f64) -> Number;
/// The Math.log2() function returns the base 2 logarithm of a number.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2
#[wasm_bindgen(static_method_of = Math)]
pub fn log2(x: f64) -> Number;
}
// Number.
#[wasm_bindgen]
extern {
extern "C" {
pub type Number;
/// The `Number` JavaScript object is a wrapper object allowing
@ -420,13 +668,13 @@ extern {
// Date.
#[wasm_bindgen]
extern {
extern "C" {
pub type Date;
/// Creates a JavaScript Date instance that represents
/// a single moment in time. Date objects are based on a time value that is
/// Creates a JavaScript Date instance that represents
/// a single moment in time. Date objects are based on a time value that is
/// the number of milliseconds since 1 January 1970 UTC.
///
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
#[wasm_bindgen(constructor)]
pub fn new() -> Date;
@ -440,22 +688,22 @@ extern {
/// The toDateString() method returns the date portion of a Date object
/// in human readable form in American English.
///
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toDateString
#[wasm_bindgen(method, js_name = toDateString)]
pub fn to_date_string(this: &Date) -> JsString;
/// The toISOString() method returns a string in simplified extended ISO format (ISO
/// 8601), which is always 24 or 27 characters long (YYYY-MM-DDTHH:mm:ss.sssZ or
/// ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively). The timezone is always zero UTC offset,
/// ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively). The timezone is always zero UTC offset,
/// as denoted by the suffix "Z"
///
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
#[wasm_bindgen(method, js_name = toISOString)]
pub fn to_iso_string(this: &Date) -> JsString;
/// The toJSON() method returns a string representation of the Date object.
///
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON
#[wasm_bindgen(method, js_name = toJSON)]
pub fn to_json(this: &Date) -> JsString;
@ -467,17 +715,17 @@ extern {
/// In older implementations, which ignore the locales and options arguments,
/// the locale used and the form of the string
/// returned are entirely implementation dependent.
///
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString
#[wasm_bindgen(method, js_name = toLocaleDateString)]
pub fn to_locale_date_string(this: &Date, locale: JsString, options: JsValue) -> JsString;
/// The toLocaleString() method returns a string with a language sensitive
/// representation of this date. The new locales and options arguments
/// let applications specify the language whose formatting conventions
/// should be used and customize the behavior of the function.
/// In older implementations, which ignore the locales
/// and options arguments, the locale used and the form of the string
/// The toLocaleString() method returns a string with a language sensitive
/// representation of this date. The new locales and options arguments
/// let applications specify the language whose formatting conventions
/// should be used and customize the behavior of the function.
/// In older implementations, which ignore the locales
/// and options arguments, the locale used and the form of the string
/// returned are entirely implementation dependent.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString
@ -535,7 +783,7 @@ extern {
// Object.
#[wasm_bindgen]
extern {
extern "C" {
pub type Object;
/// The `hasOwnProperty()` method returns a boolean indicating whether the
@ -546,6 +794,25 @@ extern {
#[wasm_bindgen(method, js_name = hasOwnProperty)]
pub fn has_own_property(this: &Object, property: &JsValue) -> bool;
/// The Object.isExtensible() method determines if an object is extensible
/// (whether it can have new properties added to it).
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
#[wasm_bindgen(static_method_of = Object, js_name = isExtensible)]
pub fn is_extensible(object: &Object) -> bool;
/// The Object.isFrozen() determines if an object is frozen.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen
#[wasm_bindgen(static_method_of = Object, js_name = isFrozen)]
pub fn is_frozen(object: &Object) -> bool;
/// The Object.isSealed() method determines if an object is sealed.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed
#[wasm_bindgen(static_method_of = Object, js_name = isSealed)]
pub fn is_sealed(object: &Object) -> bool;
/// The isPrototypeOf() method checks if an object exists in another
/// object's prototype chain.
///
@ -566,6 +833,14 @@ extern {
#[wasm_bindgen(constructor)]
pub fn new() -> Object;
/// The Object.preventExtensions() method prevents
/// new properties from ever being added to an object
/// (i.e. prevents future extensions to the object).
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions
#[wasm_bindgen(static_method_of = Object, js_name = preventExtensions)]
pub fn prevent_extensions(object: &Object);
/// The propertyIsEnumerable() method returns a Boolean indicating
/// whether the specified property is enumerable.
///
@ -576,11 +851,18 @@ extern {
/// The Object.seal() method seals an object, preventing new properties
/// from being added to it and marking all existing properties as non-configurable.
/// Values of present properties can still be changed as long as they are writable.
///
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal
#[wasm_bindgen(static_method_of = Object)]
pub fn seal(value: &JsValue) -> JsValue;
/// The Object.setPrototypeOf() method sets the prototype (i.e., the internal
/// [[Prototype]] property) of a specified object to another object or null.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf
#[wasm_bindgen(static_method_of = Object, js_name = setPrototypeOf)]
pub fn set_prototype_of(object: &Object, prototype: &Object) -> Object;
/// The toLocaleString() method returns a string representing the object.
/// This method is meant to be overridden by derived objects for
/// locale-specific purposes.
@ -601,11 +883,97 @@ extern {
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf
#[wasm_bindgen(method, js_name = valueOf)]
pub fn value_of(this: &Object) -> Object;
/// The Object.values() method returns an array of a given object's
/// own enumerable property values, in the same order as that provided
/// by a for...in loop (the difference being that a for-in loop
/// enumerates properties in the prototype chain as well).
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values
#[wasm_bindgen(static_method_of = Object)]
pub fn values(object: &Object) -> Array;
}
// Set
#[wasm_bindgen]
extern {
pub type Set;
/// The add() method appends a new element with a specified value to the
/// end of a Set object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add
#[wasm_bindgen(method)]
pub fn add(this: &Set, value: &JsValue) -> Set;
/// The clear() method removes all elements from a Set object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear
#[wasm_bindgen(method)]
pub fn clear(this: &Set);
/// The delete() method removes the specified element from a Set object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete
#[wasm_bindgen(method)]
pub fn delete(this: &Set, value: &JsValue) -> bool;
/// The has() method returns a boolean indicating whether an element
/// with the specified value exists in a Set object or not.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has
#[wasm_bindgen(method)]
pub fn has(this: &Set, value: &JsValue) -> bool;
/// The Set object lets you store unique values of any type, whether primitive
/// values or object references.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
#[wasm_bindgen(constructor)]
pub fn new() -> Set;
/// The size accessor property returns the number of elements in a Set object.
///
/// https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Set/size
#[wasm_bindgen(method, getter, structural)]
pub fn size(this: &Set) -> Number;
}
// SetIterator
#[wasm_bindgen]
extern {
pub type SetIterator;
/// The entries() method returns a new Iterator object that contains
/// an array of [value, value] for each element in the Set object,
/// in insertion order. For Set objects there is no key like in
/// Map objects. However, to keep the API similar to the Map object,
/// each entry has the same value for its key and value here, so that
/// an array [value, value] is returned.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries
#[wasm_bindgen(method)]
pub fn entries(set: &Set) -> SetIterator;
/// The keys() method is an alias for this method (for similarity with
/// Map objects); it behaves exactly the same and returns values
/// of Set elements.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values
#[wasm_bindgen(method)]
pub fn keys(set: &Set) -> SetIterator;
/// The values() method returns a new Iterator object that contains the
/// values for each element in the Set object in insertion order.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values
#[wasm_bindgen(method)]
pub fn values(set: &Set) -> SetIterator;
}
// WeakMap
#[wasm_bindgen]
extern {
extern "C" {
pub type WeakMap;
/// The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced.
@ -615,21 +983,21 @@ extern {
#[wasm_bindgen(constructor)]
pub fn new() -> WeakMap;
/// The set() method sets the value for the key in the WeakMap object. Returns
/// The set() method sets the value for the key in the WeakMap object. Returns
/// the WeakMap object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/set
#[wasm_bindgen(method, js_class="WeakMap")]
#[wasm_bindgen(method, js_class = "WeakMap")]
pub fn set(this: &WeakMap, key: Object, value: JsValue) -> WeakMap;
/// The get() method returns a specified by key element
/// The get() method returns a specified by key element
/// from a WeakMap object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/get
#[wasm_bindgen(method)]
pub fn get(this: &WeakMap, key: Object) -> JsValue;
/// The has() method returns a boolean indicating whether an element with
/// The has() method returns a boolean indicating whether an element with
/// the specified key exists in the WeakMap object or not.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/has
@ -643,9 +1011,39 @@ extern {
pub fn delete(this: &WeakMap, key: Object) -> bool;
}
// WeakSet
#[wasm_bindgen]
extern "C" {
pub type WeakSet;
/// The WeakSet object lets you store weakly held objects in a collection.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet
#[wasm_bindgen(constructor)]
pub fn new() -> WeakSet;
/// The has() method returns a boolean indicating whether an object exists in a WeakSet or not.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/has
#[wasm_bindgen(method)]
pub fn has(this: &WeakSet, value: Object) -> bool;
/// The add() method appends a new object to the end of a WeakSet object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/add
#[wasm_bindgen(method)]
pub fn add(this: &WeakSet, value: Object) -> WeakSet;
/// The delete() method removes the specified element from a WeakSet object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/delete
#[wasm_bindgen(method)]
pub fn delete(this: &WeakSet, value: Object) -> bool;
}
// JsString
#[wasm_bindgen]
extern {
extern "C" {
#[wasm_bindgen(js_name = JsString)]
pub type JsString;
@ -698,7 +1096,7 @@ extern {
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf
#[wasm_bindgen(method, js_class = "String", js_name = indexOf)]
pub fn index_of(this: &JsString, search_value: &JsString, from_index: i32) -> i32;
/// The slice() method extracts a section of a string and returns it as a
/// new string, without modifying the original string.
///
@ -727,12 +1125,27 @@ extern {
#[wasm_bindgen(method, js_class = "String")]
pub fn substr(this: &JsString, start: i32, length: i32) -> JsString;
/// The toLowerCase() method returns the calling string value
/// converted to lower case.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase
#[wasm_bindgen(method, js_class = "String", js_name = toLowerCase)]
pub fn to_lower_case(this: &JsString) -> JsString;
/// The toString() method returns a string representing the specified object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toString
#[wasm_bindgen(method, js_class = "String", js_name = toString)]
pub fn to_string(this: &JsString) -> JsString;
/// The toUpperCase() method returns the calling string value
/// converted to uppercase (the value will be converted to a
/// string if it isn't one).
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase
#[wasm_bindgen(method, js_class = "String", js_name = toUpperCase)]
pub fn to_upper_case(this: &JsString) -> JsString;
/// The trim() method removes whitespace from both ends of a string.
/// Whitespace in this context is all the whitespace characters
/// (space, tab, no-break space, etc.) and all the line terminator characters (LF, CR, etc.).

View File

@ -76,16 +76,18 @@ const JSIDX_RESERVED: u32 = 8;
impl JsValue {
/// The `null` JS value constant.
pub const NULL: JsValue = JsValue { idx: JSIDX_NULL };
pub const NULL: JsValue = JsValue { idx: JSIDX_NULL };
/// The `undefined` JS value constant.
pub const UNDEFINED: JsValue = JsValue { idx: JSIDX_UNDEFINED };
pub const UNDEFINED: JsValue = JsValue {
idx: JSIDX_UNDEFINED,
};
/// The `true` JS value constant.
pub const TRUE: JsValue = JsValue { idx: JSIDX_TRUE };
pub const TRUE: JsValue = JsValue { idx: JSIDX_TRUE };
/// The `false` JS value constant.
pub const FALSE: JsValue = JsValue { idx: JSIDX_FALSE };
pub const FALSE: JsValue = JsValue { idx: JSIDX_FALSE };
/// Creates a new JS value which is a string.
///
@ -93,7 +95,9 @@ impl JsValue {
/// be owned by the JS garbage collector.
pub fn from_str(s: &str) -> JsValue {
unsafe {
JsValue { idx: __wbindgen_string_new(s.as_ptr(), s.len()) }
JsValue {
idx: __wbindgen_string_new(s.as_ptr(), s.len()),
}
}
}
@ -103,7 +107,9 @@ impl JsValue {
/// allocated number) and returns a handle to the JS version of it.
pub fn from_f64(n: f64) -> JsValue {
unsafe {
JsValue { idx: __wbindgen_number_new(n) }
JsValue {
idx: __wbindgen_number_new(n),
}
}
}
@ -112,12 +118,16 @@ impl JsValue {
/// This function creates a JS object representing a boolean (a heap
/// allocated boolean) and returns a handle to the JS version of it.
pub fn from_bool(b: bool) -> JsValue {
JsValue { idx: if b { JSIDX_TRUE } else { JSIDX_FALSE } }
JsValue {
idx: if b { JSIDX_TRUE } else { JSIDX_FALSE },
}
}
/// Creates a new JS value representing `undefined`.
pub fn undefined() -> JsValue {
JsValue { idx: JSIDX_UNDEFINED }
JsValue {
idx: JSIDX_UNDEFINED,
}
}
/// Creates a new JS value representing `null`.
@ -133,7 +143,9 @@ impl JsValue {
unsafe {
let ptr = description.map(|s| s.as_ptr()).unwrap_or(ptr::null());
let len = description.map(|s| s.len()).unwrap_or(0);
JsValue { idx: __wbindgen_symbol_new(ptr, len) }
JsValue {
idx: __wbindgen_symbol_new(ptr, len),
}
}
}
@ -154,7 +166,8 @@ impl JsValue {
/// Returns any error encountered when serializing `T` into JSON.
#[cfg(feature = "serde-serialize")]
pub fn from_serde<T>(t: &T) -> serde_json::Result<JsValue>
where T: serde::ser::Serialize + ?Sized,
where
T: serde::ser::Serialize + ?Sized,
{
let s = serde_json::to_string(t)?;
unsafe {
@ -179,7 +192,8 @@ impl JsValue {
/// Returns any error encountered when parsing the JSON into a `T`.
#[cfg(feature = "serde-serialize")]
pub fn into_serde<T>(&self) -> serde_json::Result<T>
where T: for<'a> serde::de::Deserialize<'a>,
where
T: for<'a> serde::de::Deserialize<'a>,
{
unsafe {
let mut ptr = ptr::null_mut();
@ -243,31 +257,23 @@ impl JsValue {
/// Tests whether this JS value is `null`
pub fn is_null(&self) -> bool {
unsafe {
__wbindgen_is_null(self.idx) == 1
}
unsafe { __wbindgen_is_null(self.idx) == 1 }
}
/// Tests whether this JS value is `undefined`
pub fn is_undefined(&self) -> bool {
unsafe {
__wbindgen_is_undefined(self.idx) == 1
}
unsafe { __wbindgen_is_undefined(self.idx) == 1 }
}
/// Tests whether the type of this JS value is `symbol`
pub fn is_symbol(&self) -> bool {
unsafe {
__wbindgen_is_symbol(self.idx) == 1
}
unsafe { __wbindgen_is_symbol(self.idx) == 1 }
}
}
impl PartialEq for JsValue {
fn eq(&self, other: &JsValue) -> bool {
unsafe {
__wbindgen_jsval_eq(self.idx, other.idx) != 0
}
unsafe { __wbindgen_jsval_eq(self.idx, other.idx) != 0 }
}
}
@ -421,7 +427,7 @@ impl<T: FromWasmAbi + 'static> Deref for JsStatic<T> {
// `JsStatic` a bit as well.
let ptr = self.__inner.get();
if let Some(ref t) = *ptr {
return t
return t;
}
let init = Some((self.__init)());
debug_assert!((*ptr).is_none());
@ -455,7 +461,7 @@ pub mod __rt {
#[macro_export]
#[cfg(feature = "std")]
macro_rules! __wbindgen_if_not_std {
($($i:item)*) => ()
($($i:item)*) => {};
}
#[macro_export]
@ -500,7 +506,10 @@ pub mod __rt {
}
impl<T: ?Sized> WasmRefCell<T> {
pub fn new(value: T) -> WasmRefCell<T> where T: Sized {
pub fn new(value: T) -> WasmRefCell<T>
where
T: Sized,
{
WasmRefCell {
value: UnsafeCell::new(value),
borrow: Cell::new(0),
@ -508,9 +517,7 @@ pub mod __rt {
}
pub fn get_mut(&mut self) -> &mut T {
unsafe {
&mut *self.value.get()
}
unsafe { &mut *self.value.get() }
}
pub fn borrow(&self) -> Ref<T> {
@ -539,7 +546,10 @@ pub mod __rt {
}
}
pub fn into_inner(self) -> T where T: Sized {
pub fn into_inner(self) -> T
where
T: Sized,
{
self.value.into_inner()
}
}
@ -592,8 +602,10 @@ pub mod __rt {
}
fn borrow_fail() -> ! {
super::throw("recursive use of an object detected which would lead to \
unsafe aliasing in rust");
super::throw(
"recursive use of an object detected which would lead to \
unsafe aliasing in rust",
);
}
if_std! {

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn works() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -108,8 +110,11 @@ fn works() {
pub fn acquire_string2(a: &JsValue) -> String {
a.as_string().unwrap_or("wrong".to_string())
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -138,14 +143,17 @@ fn works() {
assert.strictEqual(wasm.acquire_string2(''), '');
assert.strictEqual(wasm.acquire_string2('a'), 'a');
}
"#)
"#,
)
.test();
}
#[test]
fn eq_works() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -161,8 +169,11 @@ fn eq_works() {
pub fn test1(a: &JsValue) -> bool {
a == a
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -176,7 +187,7 @@ fn eq_works() {
assert.strictEqual(wasm.test(x, x), true);
assert.strictEqual(wasm.test1(x), true);
}
"#)
"#,
)
.test();
}

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn works() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -30,8 +32,11 @@ fn works() {
#[wasm_bindgen]
pub fn char_round(c: char)-> char { js_parrot(c) }
"#)
.file("test.js", r#"
"#,
)
.file(
"test.js",
r#"
import * as wasm from './out';
function assertEq(a, b) {
@ -55,6 +60,7 @@ fn works() {
}
export function js_parrot(a) { return a; }
"#)
"#,
)
.test();
}

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn simple() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -30,9 +32,16 @@ fn simple() {
self.contents += amt;
self.contents
}
pub fn consume(self) -> u32 {
self.contents
}
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import { Foo } from "./out";
@ -41,7 +50,9 @@ fn simple() {
assert.strictEqual(r.add(0), 0);
assert.strictEqual(r.add(1), 1);
assert.strictEqual(r.add(1), 2);
r.free();
r.add(2);
assert.strictEqual(r.consume(), 4);
assert.throws(() => r.free(), /null pointer passed to rust/);
const r2 = Foo.with_contents(10);
assert.strictEqual(r2.add(1), 11);
@ -53,14 +64,17 @@ fn simple() {
assert.strictEqual(r3.add(42), 42);
r3.free();
}
"#)
"#,
)
.test();
}
#[test]
fn strings() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -98,8 +112,11 @@ fn strings() {
self.contents.clone()
}
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import { Foo } from "./out";
@ -111,14 +128,17 @@ fn strings() {
assert.strictEqual(bar.name(), "foo-baz-3");
bar.free();
}
"#)
"#,
)
.test();
}
#[test]
fn exceptions() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -152,8 +172,11 @@ fn exceptions() {
B {}
}
}
"#)
.file("test.js", r#"
"#,
)
.file(
"test.js",
r#"
import * as assert from "assert";
import { A, B } from "./out";
@ -173,17 +196,23 @@ fn exceptions() {
d.free();
c.free();
};
"#)
.file("test.d.ts", r#"
"#,
)
.file(
"test.d.ts",
r#"
export function test(): void;
"#)
"#,
)
.test();
}
#[test]
fn pass_one_to_another() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -215,8 +244,11 @@ fn pass_one_to_another() {
B {}
}
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { A, B } from "./out";
export function test() {
@ -226,14 +258,17 @@ fn pass_one_to_another() {
a.bar(b);
a.free();
}
"#)
"#,
)
.test();
}
#[test]
fn pass_into_js() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -259,8 +294,11 @@ fn pass_into_js() {
pub fn run() {
take_foo(Foo(13));
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run, Foo } from "./out";
import * as assert from "assert";
@ -273,14 +311,17 @@ fn pass_into_js() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
#[test]
fn issue_27() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -309,21 +350,27 @@ fn issue_27() {
pub fn context() -> Context {
Context {}
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { context } from "./out";
export function test() {
context();
}
"#)
"#,
)
.test();
}
#[test]
fn pass_into_js_as_js_class() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -349,8 +396,11 @@ fn pass_into_js_as_js_class() {
pub fn run() {
take_foo(Foo(13).into());
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run, Foo } from "./out";
import * as assert from "assert";
@ -363,14 +413,17 @@ fn pass_into_js_as_js_class() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
#[test]
fn constructors() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -416,8 +469,11 @@ fn constructors() {
self.number + self.number2
}
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import { Foo, Bar, cross_item_construction } from "./out";
@ -440,7 +496,8 @@ fn constructors() {
assert.strictEqual(cross_item_construction().get_sum(), 15);
}
"#)
"#,
)
.test();
}
@ -448,7 +505,9 @@ fn constructors() {
fn empty_structs() {
project()
.debug(false)
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -463,14 +522,18 @@ fn empty_structs() {
#[wasm_bindgen]
impl Other { pub fn return_a_value() -> MissingClass { MissingClass {} } }
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { Other } from "./out";
export function test() {
Other.return_a_value();
}
"#)
"#,
)
.test();
}
@ -478,7 +541,9 @@ fn empty_structs() {
fn public_fields() {
project()
.debug(false)
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -500,8 +565,11 @@ fn public_fields() {
Foo::default()
}
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { Foo } from "./out";
import * as assert from "assert";
@ -523,7 +591,8 @@ fn public_fields() {
a.d = 3.3;
assert.strictEqual(a.d, 3);
}
"#)
"#,
)
.test();
}
@ -531,7 +600,9 @@ fn public_fields() {
fn using_self() {
project()
.debug(false)
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -548,14 +619,18 @@ fn using_self() {
Foo {}
}
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { Foo } from "./out";
export function test() {
Foo.new().free();
}
"#)
"#,
)
.test();
}
@ -563,7 +638,9 @@ fn using_self() {
fn readonly_fields() {
project()
.debug(false)
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -583,8 +660,11 @@ fn readonly_fields() {
Foo::default()
}
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { Foo } from "./out";
import * as assert from "assert";
@ -594,6 +674,44 @@ fn readonly_fields() {
assert.throws(() => (a as any).a = 3, /has only a getter/);
a.free();
}
"#,
)
.test();
}
#[test]
fn double_consume() {
project()
.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 Foo { }
#[wasm_bindgen]
impl Foo {
#[wasm_bindgen(constructor)]
pub fn new() -> Foo {
Foo {}
}
pub fn consume(self, other: Foo) {
drop(other);
}
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import { Foo } from "./out";
export function test() {
const r = Foo.new();
assert.throws(() => r.consume(r), /Attempt to use a moved value/);
}
"#)
.test();
}

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn works() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -25,8 +27,11 @@ fn works() {
assert_eq!(thread(&|a| a + 1), 3);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export function call(a: any) {
@ -40,14 +45,17 @@ fn works() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
#[test]
fn cannot_reuse() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -66,8 +74,11 @@ fn cannot_reuse() {
call(&|| {});
assert!(call_again().is_err());
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
let CACHE: any = null;
@ -83,14 +94,17 @@ fn cannot_reuse() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
#[test]
fn long_lived() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -125,8 +139,11 @@ fn long_lived() {
}
assert!(hit.get());
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export function call1(a: any) {
@ -140,14 +157,17 @@ fn long_lived() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
#[test]
fn many_arity() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -219,8 +239,11 @@ fn many_arity() {
assert_eq!((a, b, c, d, e, f, g), (1, 2, 3, 4, 5, 6, 7))
}));
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export function call1(a: any) { a() }
@ -235,14 +258,17 @@ fn many_arity() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
#[test]
fn long_lived_dropping() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -270,8 +296,11 @@ fn long_lived_dropping() {
drop(a);
assert!(call().is_err());
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
let CACHE: any = null;
@ -282,14 +311,17 @@ fn long_lived_dropping() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
#[test]
fn long_fnmut_recursive() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -311,8 +343,11 @@ fn long_fnmut_recursive() {
cache(&a);
assert!(call().is_ok());
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
let CACHE: any = null;
@ -323,14 +358,17 @@ fn long_fnmut_recursive() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
#[test]
fn fnmut() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -356,8 +394,11 @@ fn fnmut() {
}), 3);
assert!(x);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export function call(a: any) {
@ -371,14 +412,17 @@ fn fnmut() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
#[test]
fn fnmut_bad() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -408,8 +452,11 @@ fn fnmut_bad() {
assert!(again(true).is_err());
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
let F: any = null;
@ -426,14 +473,17 @@ fn fnmut_bad() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
#[test]
fn string_arguments() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -454,8 +504,11 @@ fn string_arguments() {
});
assert!(x);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export function call(a: any) {
@ -465,14 +518,17 @@ fn string_arguments() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
#[test]
fn string_ret() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -495,8 +551,11 @@ fn string_ret() {
});
assert!(x);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
import * as assert from "assert";
@ -508,7 +567,7 @@ fn string_ret() {
export function test() {
run();
}
"#)
"#,
)
.test();
}

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn works() {
let mut p = project();
p.file("src/lib.rs", r#"
p.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -33,24 +35,27 @@ fn works() {
self.a.clone()
}
}
"#);
"#,
);
let (root, target) = p.cargo_build();
p.gen_bindings(&root, &target);
let js = p.read_js();
let comments = extract_doc_comments(&js);
assert!(comments.iter().all(|c| c == "This comment should exist"));
let (root, target) = p.cargo_build();
p.gen_bindings(&root, &target);
let js = p.read_js();
let comments = extract_doc_comments(&js);
assert!(comments.iter().all(|c| c == "This comment should exist"));
}
/// Pull out all lines in a js string that start with
/// '* ', all other lines will either be comment start, comment
/// end or actual js lines.
/// end or actual js lines.
fn extract_doc_comments(js: &str) -> Vec<String> {
js.lines().filter_map(|l| {
let trimmed = l.trim();
if trimmed.starts_with("* ") {
Some(trimmed[2..].to_owned())
} else {
None
}
}).collect()
}
js.lines()
.filter_map(|l| {
let trimmed = l.trim();
if trimmed.starts_with("* ") {
Some(trimmed[2..].to_owned())
} else {
None
}
})
.collect()
}

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn c_style_enum() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -25,8 +27,11 @@ fn c_style_enum() {
Color::Red => Color::Green,
}
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -38,14 +43,17 @@ fn c_style_enum() {
assert.strictEqual(wasm.cycle(wasm.Color.Green), wasm.Color.Yellow);
}
"#)
"#,
)
.test();
}
#[test]
fn c_style_enum_with_custom_values() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -73,8 +81,11 @@ fn c_style_enum_with_custom_values() {
Color::Red => Color::Green,
}
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -86,6 +97,7 @@ fn c_style_enum_with_custom_values() {
assert.strictEqual(wasm.cycle(wasm.Color.Green), wasm.Color.Yellow);
}
"#)
"#,
)
.test();
}

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn simple() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -27,8 +29,11 @@ fn simple() {
#[wasm_bindgen(js_namespace = Math)]
fn log(a: f64) -> f64;
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out";
import * as assert from "assert";
@ -36,14 +41,17 @@ fn simple() {
wasm.get_random();
assert.strictEqual(wasm.do_log(1.0), Math.log(1.0));
}
"#)
"#,
)
.test();
}
#[test]
fn import_class() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -60,8 +68,11 @@ fn import_class() {
pub fn baz() {
bar();
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { baz } from "./out";
import { called } from "./another";
import * as assert from "assert";
@ -70,8 +81,11 @@ fn import_class() {
baz();
assert.strictEqual(called, true);
}
"#)
.file("another.ts", r#"
"#,
)
.file(
"another.ts",
r#"
export let called = false;
export class Foo {
@ -79,14 +93,17 @@ fn import_class() {
called = true;
}
}
"#)
"#,
)
.test();
}
#[test]
fn construct() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -113,8 +130,11 @@ fn construct() {
f.append_to_internal_string(" foo");
f.assert_internal_string("this foo");
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
import { called } from "./another";
import * as assert from "assert";
@ -123,8 +143,11 @@ fn construct() {
run();
assert.strictEqual(called, true);
}
"#)
.file("another.ts", r#"
"#,
)
.file(
"another.ts",
r#"
import * as assert from "assert";
export let called = false;
@ -151,14 +174,17 @@ fn construct() {
called = true;
}
}
"#)
"#,
)
.test();
}
#[test]
fn new_constructors() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -179,15 +205,21 @@ fn new_constructors() {
let f = Foo::new(1);
assert_eq!(f.get(), 2);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export function test() {
run();
}
"#)
.file("another.ts", r#"
"#,
)
.file(
"another.ts",
r#"
export class Foo {
constructor(private field: number) {
}
@ -196,14 +228,17 @@ fn new_constructors() {
return this.field + 1;
}
}
"#)
"#,
)
.test();
}
#[test]
fn switch_methods() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -233,8 +268,11 @@ fn switch_methods() {
pub fn b() {
Foo::new().b();
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { a, b } from "./out";
import { Foo, called } from "./another";
import * as assert from "assert";
@ -259,8 +297,11 @@ fn switch_methods() {
b();
assert.strictEqual(called.a, true);
}
"#)
.file("another.ts", r#"
"#,
)
.file(
"another.ts",
r#"
export let called = { a: false };
export class Foo {
@ -275,14 +316,17 @@ fn switch_methods() {
called.a = true;
}
}
"#)
"#,
)
.test();
}
#[test]
fn properties() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -310,15 +354,21 @@ fn properties() {
a.set_a(2);
assert_eq!(a.a(), 2);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export function test() {
run();
}
"#)
.file("another.ts", r#"
"#,
)
.file(
"another.ts",
r#"
export class Foo {
constructor(private num: number) {
this.num = 1;
@ -332,14 +382,17 @@ fn properties() {
this.num = val;
}
}
"#)
"#,
)
.test();
}
#[test]
fn rename_setter_getter() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -367,15 +420,21 @@ fn rename_setter_getter() {
a.another(2);
assert_eq!(a.test(), 2);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export function test() {
run();
}
"#)
.file("another.ts", r#"
"#,
)
.file(
"another.ts",
r#"
export class Foo {
constructor(private num: number) {
this.num = 1;
@ -389,6 +448,7 @@ fn rename_setter_getter() {
this.num = val;
}
}
"#)
"#,
)
.test();
}

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn simple() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -37,8 +39,11 @@ fn simple() {
pub fn get_the_object() -> JsValue {
return_object()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out";
import * as assert from "assert";
@ -78,14 +83,17 @@ fn simple() {
assert.strictEqual(wasm.get_the_object(), SYM);
}
"#)
"#,
)
.test();
}
#[test]
fn unused() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
#![allow(dead_code)]
@ -100,8 +108,11 @@ fn unused() {
#[wasm_bindgen]
pub fn bar() {}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out";
export function debug_print() {}
@ -109,14 +120,17 @@ fn unused() {
export function test() {
wasm.bar();
}
"#)
"#,
)
.test();
}
#[test]
fn string_ret() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -132,8 +146,11 @@ fn string_ret() {
pub fn run() {
assert_eq!(foo(), "bar");
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out";
export function foo(): string {
@ -143,14 +160,17 @@ fn string_ret() {
export function test() {
wasm.run();
}
"#)
"#,
)
.test();
}
#[test]
fn strings() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -171,8 +191,11 @@ fn strings() {
pub fn bar2(a: String) -> String {
foo(a)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out";
import * as assert from "assert";
@ -184,14 +207,17 @@ fn strings() {
assert.strictEqual(wasm.bar('a'), 'ab');
assert.strictEqual(wasm.bar2('a'), 'ab');
}
"#)
"#,
)
.test();
}
#[test]
fn exceptions() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -217,8 +243,11 @@ fn exceptions() {
assert!(baz().is_err());
bar();
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run, run2 } from "./out";
import * as assert from "assert";
@ -242,14 +271,17 @@ fn exceptions() {
run2();
assert.strictEqual(called, true);
}
"#)
"#,
)
.test();
}
#[test]
fn exn_caught() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -266,8 +298,11 @@ fn exn_caught() {
pub fn run() -> JsValue {
foo().unwrap_err()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
import * as assert from "assert";
@ -280,14 +315,17 @@ fn exn_caught() {
assert.strictEqual(obj instanceof Error, true);
assert.strictEqual(obj.message, 'error!');
}
"#)
"#,
)
.test();
}
#[test]
fn free_imports() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -303,14 +341,18 @@ fn free_imports() {
pub fn run() {
assert_eq!(parseInt("3"), 3);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export function test() {
run();
}
"#)
"#,
)
.test();
}
@ -318,7 +360,9 @@ fn free_imports() {
fn import_a_field() {
project()
.debug(false)
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -334,8 +378,11 @@ fn import_a_field() {
pub fn run() {
assert_eq!(IMPORT.as_f64(), Some(1.0));
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export const IMPORT = 1.0;
@ -343,14 +390,17 @@ fn import_a_field() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
#[test]
fn rename() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -367,8 +417,11 @@ fn rename() {
pub fn run() {
foo();
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out";
import * as assert from "assert";
@ -382,14 +435,17 @@ fn rename() {
wasm.run();
assert.strictEqual(called, true);
}
"#)
"#,
)
.test();
}
#[test]
fn versions() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -405,8 +461,11 @@ fn versions() {
pub fn run() {
foo();
}
"#)
.file("test.js", r#"
"#,
)
.file(
"test.js",
r#"
const fs = require("fs");
const assert = require("assert");
@ -426,6 +485,41 @@ fn versions() {
]
});
};
"#,
)
.test();
}
#[test]
fn underscore_pattern() {
project()
.debug(false)
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")]
extern {
fn foo(_: u8);
}
#[wasm_bindgen]
pub fn run() {
foo(1);
}
"#)
.file("test.ts", r#"
import { run } from "./out";
export function foo(_a: number) {
}
export function test() {
run();
}
"#)
.test();
}
@ -433,7 +527,9 @@ fn versions() {
#[test]
fn rust_keyword() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -450,8 +546,11 @@ fn rust_keyword() {
pub fn run() {
assert_eq!(foo(), 2);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export function self() {
@ -461,7 +560,8 @@ fn rust_keyword() {
export function test() {
run();
}
"#)
"#,
)
.test();
}
@ -469,7 +569,9 @@ fn rust_keyword() {
fn rust_keyword2() {
project()
.debug(false)
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -487,8 +589,11 @@ fn rust_keyword2() {
pub fn run() {
assert_eq!(FOO.as_f64(), Some(3.0));
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export const bar = {
@ -498,6 +603,104 @@ fn rust_keyword2() {
export function test() {
run();
}
"#,
)
.test();
}
#[test]
fn custom_type() {
project()
.debug(false)
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")]
extern {
fn foo(f: Foo) -> Foo;
fn bad2() -> Foo;
}
#[wasm_bindgen]
pub struct Foo(());
#[wasm_bindgen]
impl Foo {
pub fn touch(&self) {
panic!()
}
}
#[wasm_bindgen]
pub fn run() {
foo(Foo(()));
}
#[wasm_bindgen]
pub fn bad() {
bad2();
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import { run, Foo, bad } from "./out";
let VAL: any = null;
export function foo(f: Foo): Foo {
VAL = f;
return f;
}
export function bad2(): number {
return 2;
}
export function test() {
run();
assert.throws(() => VAL.touch(), /Attempt to use a moved value/);
assert.throws(bad, /expected value of type Foo/);
}
"#)
.test();
}
#[test]
fn unused_imports_not_generated() {
let mut project = project();
project
.debug(false)
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
pub fn foo();
}
#[wasm_bindgen]
pub fn run() {
}
"#)
.file("test.ts", r#"
import { run } from "./out";
export function test() {
run();
}
"#)
.test();
let contents = project.read_js();
assert!(contents.contains("run"), "didn't find `run` in {}", contents);
assert!(!contents.contains("foo"), "found `foo` in {}", contents);
}

307
tests/all/js_globals/Array.rs Executable file → Normal file
View File

@ -5,7 +5,9 @@ use project;
#[test]
fn filter() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -17,8 +19,11 @@ fn filter() {
array.filter(&mut |x, _, _| x.as_f64().is_some())
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -31,14 +36,17 @@ fn filter() {
assert.deepStrictEqual(wasm.keep_numbers(numbers), numbers);
assert.deepStrictEqual(wasm.keep_numbers(mixed), [1, 2]);
}
"#)
"#,
)
.test()
}
#[test]
fn index_of() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -50,8 +58,11 @@ fn index_of() {
this.index_of(value, from_index)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -69,14 +80,17 @@ fn index_of() {
assert.equal(withFromIndex, 2);
assert.equal(withFromIndexNotFound, -1);
}
"#)
"#,
)
.test()
}
#[test]
fn is_array() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -87,8 +101,11 @@ fn is_array() {
pub fn is_array(value: &JsValue) -> bool {
js::Array::is_array(value)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -109,14 +126,17 @@ fn is_array() {
assert(!wasm.is_array(false));
assert(!wasm.is_array({ __proto__: Array.prototype }));
}
"#)
"#,
)
.test()
}
#[test]
fn sort() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -128,8 +148,11 @@ fn sort() {
this.sort()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -139,6 +162,38 @@ fn sort() {
assert.deepStrictEqual(sorted, [1, 2, 3, 6])
}
"#,
)
.test()
}
#[test]
fn some() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn has_elem(array: &js::Array, arg: JsValue) -> bool {
array.some(&mut |elem| arg == elem)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let elements = ["z", 1, "y", 2];
assert.deepStrictEqual(wasm.has_elem(elements, 2), true);
assert.deepStrictEqual(wasm.has_elem(elements, "y"), true);
assert.deepStrictEqual(wasm.has_elem(elements, "not an element"), false);
}
"#)
.test()
}
@ -146,7 +201,9 @@ fn sort() {
#[test]
fn last_index_of() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -158,8 +215,11 @@ fn last_index_of() {
this.last_index_of(value, from_index)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -177,14 +237,17 @@ fn last_index_of() {
assert.equal(withFromIndex, 1);
assert.equal(withFromIndexNotFound, -1);
}
"#)
"#,
)
.test()
}
#[test]
fn join() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -196,8 +259,11 @@ fn join() {
this.join(delimiter)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -209,14 +275,17 @@ fn join() {
let withForwardSlash = wasm.join_array(characters, "/");
assert.equal("a/c/x/n", withForwardSlash);
}
"#)
"#,
)
.test()
}
#[test]
fn slice() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -227,8 +296,11 @@ fn slice() {
pub fn create_slice(this: &js::Array, start: u32, end: u32) -> js::Array {
this.slice(start, end)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -239,14 +311,17 @@ fn slice() {
assert.equal(subset[0], "c");
assert.equal(subset[1], "x");
}
"#)
"#,
)
.test()
}
#[test]
fn fill() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -257,8 +332,11 @@ fn fill() {
pub fn fill_with(this: &js::Array, value: JsValue, start: u32, end: u32) -> js::Array {
this.fill(value, start, end)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -269,7 +347,8 @@ fn fill() {
assert.equal(subset[0], 0);
assert.equal(subset[4], 1);
}
"#)
"#,
)
.test()
}
@ -310,7 +389,9 @@ fn copy_within() {
#[test]
fn pop() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -322,8 +403,11 @@ fn pop() {
this.pop()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -333,15 +417,17 @@ fn pop() {
assert.equal(item, 2);
assert.equal(characters.length, 5);
}
"#)
"#,
)
.test()
}
#[test]
fn push() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -353,8 +439,11 @@ fn push() {
this.push(value)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -364,14 +453,17 @@ fn push() {
assert.equal(length, 7);
assert.equal(characters[6], "a");
}
"#)
"#,
)
.test()
}
#[test]
fn reverse() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -383,8 +475,11 @@ fn reverse() {
this.reverse()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -394,14 +489,17 @@ fn reverse() {
assert.equal(reversed[0], 2);
assert.equal(reversed[5], 8);
}
"#)
"#,
)
.test()
}
#[test]
fn shift() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -413,8 +511,11 @@ fn shift() {
this.shift()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -425,14 +526,17 @@ fn shift() {
assert.equal(shiftedItem, 8);
assert.equal(characters.length, 5);
}
"#)
"#,
)
.test()
}
#[test]
fn unshift() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -444,8 +548,11 @@ fn unshift() {
this.unshift(value)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -456,14 +563,17 @@ fn unshift() {
assert.equal(length, 7);
assert.equal(characters[0], "abba");
}
"#)
"#,
)
.test()
}
#[test]
fn to_string() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -475,8 +585,11 @@ fn to_string() {
this.to_string()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -486,15 +599,17 @@ fn to_string() {
assert.equal(arrayString, "8,5,4,3,1,2");
}
"#)
"#,
)
.test()
}
#[test]
fn includes() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -506,8 +621,11 @@ fn includes() {
this.includes(value, from_index)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -522,14 +640,17 @@ fn includes() {
let isThreeIncluded = wasm.array_includes(characters, 3, 4);
assert.ok(!isThreeIncluded);
}
"#)
"#,
)
.test()
}
#[test]
fn concat() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -541,8 +662,11 @@ fn concat() {
this.concat(arr)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -553,14 +677,17 @@ fn concat() {
let new_array = wasm.array_concat(arr1, arr2)
assert.deepStrictEqual(new_array, [1, 2, 3, 4, 5, 6]);
}
"#)
"#,
)
.test()
}
#[test]
fn length() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -572,8 +699,11 @@ fn length() {
this.length()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -586,6 +716,45 @@ fn length() {
let emptyLength = wasm.array_length(empty);
assert.equal(emptyLength, 0);
}
"#)
"#,
)
.test()
}
#[test]
fn every() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn array_every_number_is_even(array: &js::Array) -> bool {
array.every(&mut |el, _, _| el.as_f64().unwrap() % 2f64 == 0f64)
}
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const arrayEven = [2, 4, 6, 8];
const arrayOdd = [1, 3, 5, 7];
const arrayMixed = [2, 3, 4, 5];
assert(wasm.array_every_number_is_even(arrayEven));
assert(!wasm.array_every_number_is_even(arrayOdd));
assert(!wasm.array_every_number_is_even(arrayMixed));
}
"#,
)
.test()
}

View File

@ -5,7 +5,9 @@ use project;
#[test]
fn keys() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -17,8 +19,11 @@ fn keys() {
this.keys()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -30,14 +35,17 @@ fn keys() {
assert.equal(iterator.toString(), wasmIterator.toString());
assert.equal(Array.from(iterator)[0], Array.from(wasmIterator)[0]);
}
"#)
"#,
)
.test()
}
#[test]
fn entries() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -49,8 +57,11 @@ fn entries() {
this.entries()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -64,6 +75,7 @@ fn entries() {
assert.equal(iterator.toString(), wasmIterator.toString());
assert.equal(jsItem.value[1], wasmItem.value[1]);
}
"#)
"#,
)
.test()
}

View File

@ -0,0 +1,67 @@
#![allow(non_snake_case)]
use project;
#[test]
fn new_undefined() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn new_boolean() -> js::Boolean {
js::Boolean::new(JsValue::undefined())
}
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.new_boolean().valueOf(), false);
}
"#,
)
.test()
}
#[test]
fn new_truely() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn new_boolean() -> js::Boolean {
js::Boolean::new(JsValue::from("foo"))
}
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.new_boolean().valueOf(), true);
}
"#,
)
.test()
}

View File

@ -5,7 +5,9 @@ use super::project;
#[test]
fn new() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -16,15 +18,19 @@ fn new() {
pub fn new_date() -> Date {
Date::new()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(typeof wasm.new_date(), "object");
}
"#)
"#,
)
.test()
}
@ -57,7 +63,9 @@ fn now() {
#[test]
fn to_date_string() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -68,8 +76,11 @@ fn to_date_string() {
pub fn to_date_string(this: &Date) -> JsString {
this.to_date_string()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -78,14 +89,17 @@ fn to_date_string() {
assert.equal(wasm.to_date_string(date), 'Wed Jul 28 1993');
}
"#)
"#,
)
.test()
}
#[test]
fn to_iso_string() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -96,8 +110,11 @@ fn to_iso_string() {
pub fn to_iso_string(this: &Date) -> JsString {
this.to_iso_string()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -106,14 +123,17 @@ fn to_iso_string() {
assert.equal(wasm.to_iso_string(date), '2011-10-05T14:48:00.000Z');
}
"#)
"#,
)
.test()
}
#[test]
fn to_json() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -124,8 +144,11 @@ fn to_json() {
pub fn to_json(this: &Date) -> JsString {
this.to_json()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -134,7 +157,8 @@ fn to_json() {
assert.equal(wasm.to_json(date), '1975-08-19T23:15:30.000Z');
}
"#)
"#,
)
.test()
}
@ -199,7 +223,9 @@ fn to_locale_string() {
#[test]
fn to_locale_time_string() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -210,8 +236,11 @@ fn to_locale_time_string() {
pub fn to_locale_time_string(this: &Date, locale: JsString) -> JsString {
this.to_locale_time_string(locale)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -219,14 +248,17 @@ fn to_locale_time_string() {
let date = new Date('August 19, 1975 23:15:30');
assert.equal(wasm.to_locale_time_string(date, 'en-US'), "11:15:30 PM");
}
"#)
"#,
)
.test()
}
#[test]
fn to_string() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -237,8 +269,11 @@ fn to_string() {
pub fn to_string(this: &Date) -> JsString {
this.to_string()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -246,14 +281,17 @@ fn to_string() {
let date = new Date('August 19, 1975 23:15:30');
assert.equal(wasm.to_string(date).substring(0, 15), "Tue Aug 19 1975");
}
"#)
"#,
)
.test()
}
#[test]
fn to_time_string() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -264,8 +302,11 @@ fn to_time_string() {
pub fn to_time_string(this: &Date) -> JsString {
this.to_time_string()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -273,14 +314,17 @@ fn to_time_string() {
let date = new Date('August 19, 1975 23:15:30');
assert.equal(wasm.to_time_string(date).substring(0, 8), "23:15:30");
}
"#)
"#,
)
.test()
}
#[test]
fn to_utc_string() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -291,8 +335,11 @@ fn to_utc_string() {
pub fn to_utc_string(this: &Date) -> JsString {
this.to_utc_string()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -300,7 +347,8 @@ fn to_utc_string() {
let date = new Date('14 Jun 2017 00:00:00 PDT');
assert.equal(wasm.to_utc_string(date), "Wed, 14 Jun 2017 07:00:00 GMT");
}
"#)
"#,
)
.test()
}
@ -333,7 +381,9 @@ fn utc() {
#[test]
fn value_of() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -344,8 +394,11 @@ fn value_of() {
pub fn js_value_of(this: &Date) -> Date {
this.value_of()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -353,6 +406,7 @@ fn value_of() {
let date = new Date(Date.UTC(96, 1, 2, 3, 4, 5));
assert.equal(wasm.js_value_of(date), 823230245000);
}
"#)
"#,
)
.test()
}

View File

@ -0,0 +1,197 @@
#![allow(non_snake_case)]
use project;
#[test]
fn new() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
use wasm_bindgen::js::Error;
#[wasm_bindgen]
pub fn new_error(message: &js::JsString) -> Error {
Error::new(message)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const message = 'any error message';
const error = wasm.new_error(message);
assert.equal(error.message, message);
}
"#)
.test()
}
#[test]
fn message() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
use wasm_bindgen::js::Error;
#[wasm_bindgen]
pub fn error_message(this: &Error) -> js::JsString {
this.message()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const message = 'any error message';
const error = new Error(message);
assert.equal(wasm.error_message(error), message);
}
"#)
.test()
}
#[test]
fn set_message() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
use wasm_bindgen::js::Error;
#[wasm_bindgen]
pub fn error_set_message(this: &Error, message: &js::JsString) {
this.set_message(message);
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const message = 'any error message';
const error = new Error();
wasm.error_set_message(error, message);
assert.equal(error.message, message);
}
"#)
.test()
}
#[test]
fn name() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
use wasm_bindgen::js::Error;
#[wasm_bindgen]
pub fn error_name(this: &Error) -> js::JsString {
this.name()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const name = 'any error name';
const error = new Error();
error.name = name;
assert.equal(wasm.error_name(error), name);
}
"#)
.test()
}
#[test]
fn set_name() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
use wasm_bindgen::js::Error;
#[wasm_bindgen]
pub fn error_set_name(this: &Error, name: &js::JsString) {
this.set_name(name);
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const name = 'any error name';
const error = new Error();
wasm.error_set_name(error, name);
assert.equal(error.name, name);
}
"#)
.test()
}
#[test]
fn to_string() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
use wasm_bindgen::js::Error;
#[wasm_bindgen]
pub fn error_to_string(this: &Error) -> js::JsString {
this.to_string()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const error = new Error('error message 1');
assert.equal(wasm.error_to_string(error), 'Error: error message 1');
(error.name as any) = undefined;
assert.equal(wasm.error_to_string(error), 'Error: error message 1');
error.name = 'error_name_1';
assert.equal(wasm.error_to_string(error), 'error_name_1: error message 1');
(error.message as any) = undefined;
assert.equal(wasm.error_to_string(error), 'error_name_1');
error.name = 'error_name_2';
assert.equal(wasm.error_to_string(error), 'error_name_2');
}
"#)
.test()
}

View File

@ -5,7 +5,9 @@ use project;
#[test]
fn apply() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -16,8 +18,11 @@ fn apply() {
pub fn apply(this: &js::Function, context: &JsValue, args: &js::Array) -> js::Function {
this.apply(context, args)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -28,14 +33,57 @@ fn apply() {
wasm.apply(Array.prototype.push, arr, [3]);
assert.equal(arr[2], 3);
}
"#)
"#,
)
.test()
}
#[test]
fn bind() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn bind(this: &js::Function, context: &JsValue) -> js::Function {
this.bind(context)
}
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const obj = {
a: 0,
fn: function () {
return this.a + 1;
}
}
const boundFn = wasm.bind(obj.fn, { a: 41 });
assert.equal(boundFn(), 42);
}
"#,
)
.test()
}
#[test]
fn length() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -46,8 +94,11 @@ fn length() {
pub fn fn_length(this: &js::Function) -> u32 {
this.length()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -68,14 +119,17 @@ fn length() {
assert.equal(wasm.fn_length(fn1), 1);
assert.equal(wasm.fn_length(fn2), 2);
}
"#)
"#,
)
.test()
}
#[test]
fn name() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -86,8 +140,11 @@ fn name() {
pub fn fn_name(this: &js::Function) -> js::JsString {
this.name()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -109,14 +166,17 @@ fn name() {
const closure = () => {};
assert.equal(wasm.fn_name(closure), 'closure');
}
"#)
"#,
)
.test()
}
#[test]
fn to_string() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -127,8 +187,11 @@ fn to_string() {
pub fn get_source_code(this: &js::Function) -> js::JsString {
this.to_string()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -139,6 +202,7 @@ fn to_string() {
assert.equal(wasm.get_source_code(fn1), 'function fn1(a, b) { return a + b; }');
assert.equal(wasm.get_source_code(fn2), 'function (a) { return console.log(a); }');
}
"#)
"#,
)
.test()
}

View File

@ -5,7 +5,9 @@ use project;
#[test]
fn length() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -17,8 +19,11 @@ fn length() {
this.length()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -29,14 +34,17 @@ fn length() {
let empty = '';
assert.equal(wasm.string_length(empty), 0);
}
"#)
"#,
)
.test()
}
#[test]
fn char_at() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -47,8 +55,11 @@ fn char_at() {
pub fn string_char_at(this: &js::JsString, index: u32) -> js::JsString {
this.char_at(index)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -58,14 +69,17 @@ fn char_at() {
assert.equal(wasm.string_char_at(anyString, 0), "B");
assert.equal(wasm.string_char_at(anyString, 999), "");
}
"#)
"#,
)
.test()
}
#[test]
fn char_code_at() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -76,8 +90,11 @@ fn char_code_at() {
pub fn string_char_code_at(this: &js::JsString, index: u32) -> js::Number {
this.char_code_at(index)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -87,14 +104,17 @@ fn char_code_at() {
assert.equal(wasm.string_char_code_at(anyString, 0), 66);
assert.ok(isNaN(wasm.string_char_code_at(anyString, 999)));
}
"#)
"#,
)
.test()
}
#[test]
fn code_point_at() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -105,8 +125,11 @@ fn code_point_at() {
pub fn string_code_point_at(this: &js::JsString, pos: u32) -> JsValue {
this.code_point_at(pos)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -115,14 +138,17 @@ fn code_point_at() {
assert.equal(wasm.string_code_point_at('\uD800\uDC00', 0), 65536);
assert.equal(wasm.string_code_point_at('XYZ', 42), undefined);
}
"#)
"#,
)
.test()
}
#[test]
fn concat() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -133,8 +159,11 @@ fn concat() {
pub fn string_concat(this: &js::JsString, string_2: &js::JsString) -> js::JsString {
this.concat(string_2)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -147,7 +176,8 @@ fn concat() {
assert.equal(wasm.string_concat('foo', true), 'footrue');
assert.equal(wasm.string_concat('foo', 1234), 'foo1234');
}
"#)
"#,
)
.test()
}
@ -228,7 +258,9 @@ fn index_of() {
#[test]
fn slice() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -239,8 +271,11 @@ fn slice() {
pub fn create_slice(this: &js::JsString, start: u32, end: u32) -> js::JsString {
this.slice(start, end)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -250,7 +285,8 @@ fn slice() {
assert.equal(subset, "cx");
}
"#)
"#,
)
.test()
}
@ -361,7 +397,7 @@ fn substr() {
}
#[test]
fn to_string() {
fn to_lower_case() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
@ -370,12 +406,43 @@ fn to_string() {
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn string_to_lower_case(this: &js::JsString) -> js::JsString {
this.to_lower_case()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.string_to_lower_case("Mozilla"), "mozilla");
}
"#)
.test()
}
#[test]
fn to_string() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn string_to_string(this: &js::JsString) -> js::JsString {
this.to_string()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -383,6 +450,33 @@ fn to_string() {
let greeting = 'Hello world!';
assert.equal(wasm.string_to_string(greeting), 'Hello world!');
}
"#,
)
.test()
}
#[test]
fn to_upper_case() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn string_to_upper_case(this: &js::JsString) -> js::JsString {
this.to_upper_case()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.string_to_upper_case("Mozilla"), "MOZILLA");
}
"#)
.test()
}
@ -390,7 +484,9 @@ fn to_string() {
#[test]
fn trim() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -401,8 +497,11 @@ fn trim() {
pub fn string_trim(this: &js::JsString) -> js::JsString {
this.trim()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -411,14 +510,17 @@ fn trim() {
// Another example of .trim() removing whitespace from just one side.
assert.equal(wasm.string_trim('foo '), 'foo');
}
"#)
"#,
)
.test()
}
#[test]
fn trim_end_and_trim_right() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -434,8 +536,11 @@ fn trim_end_and_trim_right() {
pub fn string_trim_right(this: &js::JsString) -> js::JsString {
this.trim_right()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -445,14 +550,17 @@ fn trim_end_and_trim_right() {
assert.equal(wasm.string_trim_end(greeting), trimmed);
assert.equal(wasm.string_trim_right(greeting), trimmed);
}
"#)
"#,
)
.test()
}
#[test]
fn trim_start_and_trim_left() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -468,8 +576,11 @@ fn trim_start_and_trim_left() {
pub fn string_trim_left(this: &js::JsString) -> js::JsString {
this.trim_left()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -479,14 +590,17 @@ fn trim_start_and_trim_left() {
assert.equal(wasm.string_trim_start(greeting), trimmed);
assert.equal(wasm.string_trim_left(greeting), trimmed);
}
"#)
"#,
)
.test()
}
#[test]
fn value_of() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -497,8 +611,11 @@ fn value_of() {
pub fn string_value_of(this: &js::JsString) -> js::JsString {
this.value_of()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -506,6 +623,7 @@ fn value_of() {
let greeting = new String('Hello world!');
assert.equal(wasm.string_value_of(greeting), 'Hello world!');
}
"#)
"#,
)
.test()
}
}

213
tests/all/js_globals/Map.rs Normal file
View File

@ -0,0 +1,213 @@
#![allow(non_snake_case)]
use project;
#[test]
fn clear() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn map_clear(this: &js::Map) {
this.clear();
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const map = new Map();
map.set('foo', 'bar');
map.set('bar', 'baz');
assert.equal(map.size, 2);
wasm.map_clear(map);
assert.equal(map.size, 0);
}
"#)
.test()
}
#[test]
fn delete() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn map_delete(this: &js::Map, key: &str) -> bool {
this.delete(key)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const map = new Map();
map.set('foo', 'bar');
assert.equal(map.size, 1);
assert.equal(wasm.map_delete(map, 'foo'), true);
assert.equal(wasm.map_delete(map, 'bar'), false);
assert.equal(map.size, 0);
}
"#)
.test()
}
#[test]
fn get() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn map_get(this: &js::Map, key: &JsValue) -> JsValue {
this.get(key)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const map = new Map();
map.set('foo', 'bar');
map.set(1, 2)
assert.equal(wasm.map_get(map, 'foo'), 'bar');
assert.equal(wasm.map_get(map, 1), 2);
assert.equal(wasm.map_get(map, 2), undefined);
}
"#)
.test()
}
#[test]
fn has() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn has(this: &js::Map, key: &JsValue) -> bool {
this.has(key)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const map = new Map();
map.set('foo', 'bar');
assert.equal(wasm.has(map, 'foo'), true);
assert.equal(wasm.has(map, 'bar'), false);
}
"#)
.test()
}
#[test]
fn new() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn new_map() -> js::Map {
js::Map::new()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const map = wasm.new_map();
assert.equal(map.size, 0);
}
"#)
.test()
}
#[test]
fn set() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn set(this: &js::Map, key: &JsValue, value: &JsValue) -> js::Map {
this.set(key, value)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const map = new Map();
const newMap = wasm.set(map, 'foo', 'bar');
assert.equal(map.has('foo'), true);
assert.equal(newMap.has('foo'), true);
}
"#)
.test()
}
#[test]
fn size() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn map_size(this: &js::Map) -> js::Number {
this.size()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const map = new Map();
map.set('foo', 'bar');
map.set('bar', 'baz');
assert.equal(wasm.map_size(map), 2);
}
"#)
.test()
}

View File

@ -0,0 +1,100 @@
#![allow(non_snake_case)]
use project;
#[test]
fn entries() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn get_entries(this: &js::Map) -> js::MapIterator {
this.entries()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const map = new Map();
const iterator = map.entries();
const wasmIterator = wasm.get_entries(map);
map.set('foo', 'bar');
map.set('bar', 'baz');
assert.equal(iterator.toString(), wasmIterator.toString());
}
"#)
.test()
}
#[test]
fn keys() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn get_keys(this: &js::Map) -> js::MapIterator {
this.keys()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const map = new Map();
const iterator = map.keys();
const wasmIterator = wasm.get_keys(map);
map.set('foo', 'bar');
map.set('bar', 'baz');
assert.equal(iterator.toString(), wasmIterator.toString());
}
"#)
.test()
}
#[test]
fn values() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn get_values(this: &js::Map) -> js::MapIterator {
this.values()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const map = new Map();
const iterator = map.keys();
const wasmIterator = wasm.get_values(map);
map.set('foo', 'bar');
map.set('bar', 'baz');
assert.equal(iterator.toString(), wasmIterator.toString());
}
"#)
.test()
}

View File

@ -2,11 +2,12 @@
use super::project;
#[test]
fn abs() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -14,26 +15,33 @@ fn abs() {
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn abs(number: i32) -> js::Number {
js::Math::abs(number)
pub fn abs(x: f64) -> js::Number {
js::Math::abs(x)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.abs(-32), Math.abs(-32));
assert.equal(wasm.abs(32), 32);
assert.equal(wasm.abs(-4.7), Math.abs(-4.7));
}
"#)
"#,
)
.test()
}
#[test]
fn acos() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -41,25 +49,33 @@ fn acos() {
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn acos(adjacent: i32, hypotenuse: i32) -> js::Number {
js::Math::acos(adjacent, hypotenuse)
pub fn acos(x: f64) -> js::Number {
js::Math::acos(x)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.acos(-1, 1), Math.PI);
assert.equal(wasm.acos(-1), Math.PI);
assert.equal(wasm.acos(0.5), 1.0471975511965979);
assert(Number.isNaN(wasm.acos(2)));
}
"#)
"#,
)
.test()
}
#[test]
fn acosh() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -67,26 +83,33 @@ fn acosh() {
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn acosh(number: i32) -> js::Number {
js::Math::acosh(number)
pub fn acosh(x: f64) -> js::Number {
js::Math::acosh(x)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.acosh(1), 0);
assert.equal(wasm.acosh(2), Math.acosh(2));
assert(Number.isNaN(wasm.acosh(0.5)));
}
"#)
"#,
)
.test()
}
#[test]
fn asin() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -94,25 +117,33 @@ fn asin() {
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn asin(opposite: i32, hypotenuse: i32) -> js::Number {
js::Math::asin(opposite / hypotenuse)
pub fn asin(x: f64) -> js::Number {
js::Math::asin(x)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.asin(1, 1), Math.asin(1));
assert.equal(wasm.asin(1), Math.asin(1));
assert.equal(wasm.asin(0.5), Math.asin(0.5));
assert(Number.isNaN(wasm.asin(2)));
}
"#)
"#,
)
.test()
}
#[test]
fn asinh() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -120,25 +151,32 @@ fn asinh() {
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn asinh(number: i32) -> js::Number {
js::Math::asinh(number)
pub fn asinh(x: f64) -> js::Number {
js::Math::asinh(x)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.asinh(1), Math.asinh(1));
assert.equal(wasm.asinh(0.5), Math.asinh(0.5));
}
"#)
"#,
)
.test()
}
#[test]
fn atan() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -146,25 +184,32 @@ fn atan() {
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn atan(number: i32) -> js::Number {
js::Math::atan(number)
pub fn atan(x: f64) -> js::Number {
js::Math::atan(x)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.atan(1), Math.atan(1));
assert.equal(wasm.atan(0.5), Math.atan(0.5));
}
"#)
"#,
)
.test()
}
#[test]
fn atan2() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -172,25 +217,32 @@ fn atan2() {
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn atan2(x: i32, y: i32) -> js::Number {
js::Math::atan2(x, y)
pub fn atan2(y: f64, x: f64) -> js::Number {
js::Math::atan2(y, x)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.atan2(1, 2), Math.atan2(1, 2));
assert.equal(wasm.atan2(0.7, 3.8), Math.atan2(0.7, 3.8));
}
"#)
"#,
)
.test()
}
#[test]
fn atanh() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -198,25 +250,33 @@ fn atanh() {
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn atanh(x: i32) -> js::Number {
pub fn atanh(x: f64) -> js::Number {
js::Math::atanh(x)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.atanh(1), Math.atanh(1));
assert.equal(wasm.atanh(0.5), Math.atanh(0.5));
assert(Number.isNaN(wasm.atanh(2)));
}
"#)
"#,
)
.test()
}
#[test]
fn cbrt() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -224,25 +284,32 @@ fn cbrt() {
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn cbrt(x: i32) -> js::Number {
pub fn cbrt(x: f64) -> js::Number {
js::Math::cbrt(x)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.cbrt(27), 3);
assert.equal(wasm.cbrt(12.3), Math.cbrt(12.3));
}
"#)
"#,
)
.test()
}
#[test]
fn ceil() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -250,11 +317,14 @@ fn ceil() {
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn ceil(x: f32) -> js::Number {
pub fn ceil(x: f64) -> js::Number {
js::Math::ceil(x)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -262,14 +332,17 @@ fn ceil() {
assert.equal(wasm.ceil(1.1), 2);
assert.equal(wasm.ceil(-1.1), -1);
}
"#)
"#,
)
.test()
}
#[test]
fn clz32() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -280,8 +353,11 @@ fn clz32() {
pub fn clz32(x: i32) -> js::Number {
js::Math::clz32(x)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -289,6 +365,321 @@ fn clz32() {
assert.equal(wasm.clz32(1), 31);
assert.equal(wasm.clz32(1000), 22);
}
"#,
)
.test()
}
#[test]
fn cos() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn cos(x: f64) -> js::Number {
js::Math::cos(x)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.cos(0), 1);
assert.equal(wasm.cos(1.5), Math.cos(1.5));
}
"#)
.test()
}
#[test]
fn cosh() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn cosh(x: f64) -> js::Number {
js::Math::cosh(x)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.cosh(0), 1);
assert.equal(wasm.cosh(2), 3.7621956910836314);
}
"#)
.test()
}
#[test]
fn exp() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn exp(x: f64) -> js::Number {
js::Math::exp(x)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.exp(0), 1);
assert.equal(wasm.exp(-1), 0.36787944117144233);
assert.equal(wasm.exp(2), 7.38905609893065);
}
"#)
.test()
}
#[test]
fn expm1() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn expm1(x: f64) -> js::Number {
js::Math::expm1(x)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.expm1(0), 0);
assert.equal(wasm.expm1(1), 1.718281828459045);
assert.equal(wasm.expm1(-1), -0.6321205588285577);
assert.equal(wasm.expm1(2), 6.38905609893065);
}
"#)
.test()
}
#[test]
fn floor() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn floor(x: f64) -> js::Number {
js::Math::floor(x)
}
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.floor(5.95), 5);
assert.equal(wasm.floor(-5.05), -6);
}
"#,
)
.test()
}
#[test]
fn fround() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn fround(x: f64) -> js::Number {
js::Math::fround(x)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.fround(5.5), 5.5);
assert.equal(wasm.fround(5.05), 5.050000190734863);
assert.equal(wasm.fround(5), 5);
assert.equal(wasm.fround(-5.05), -5.050000190734863);
}
"#)
.test()
}
#[test]
fn imul() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn imul(x: i32, y:i32) -> js::Number {
js::Math::imul(x, y)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.imul(3, 4), 12);
assert.equal(wasm.imul(-5, 12), -60);
assert.equal(wasm.imul(0xffffffff, 5), Math.imul(0xffffffff, 5));
}
"#)
.test()
}
#[test]
fn log() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn log(x: f64) -> js::Number {
js::Math::log(x)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.log(8) / wasm.log(2), 3);
assert.equal(wasm.log(625) / wasm.log(5), 4);
}
"#)
.test()
}
#[test]
fn log10() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn log10(x: f64) -> js::Number {
js::Math::log10(x)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.log10(100000), 5);
assert.equal(wasm.log10(1), 0);
assert.equal(wasm.log10(2), 0.3010299956639812);
}
"#)
.test()
}
#[test]
fn log1p() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn log1p(x: f64) -> js::Number {
js::Math::log1p(x)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.log1p(1), 0.6931471805599453);
assert.equal(wasm.log1p(0), 0);
assert.equal(wasm.log1p(-1), -Infinity);
assert(isNaN(wasm.log1p(-2)));
}
"#)
.test()
}
#[test]
fn log2() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn log2(x: f64) -> js::Number {
js::Math::log2(x)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.log2(3), 1.584962500721156);
assert.equal(wasm.log2(2), 1);
assert.equal(wasm.log2(1), 0);
assert.equal(wasm.log2(0), -Infinity);
}
"#)
.test()
}

View File

@ -62,7 +62,9 @@ fn to_locale_string() {
#[test]
fn to_precision() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -78,8 +80,11 @@ fn to_precision() {
};
result
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -87,14 +92,17 @@ fn to_precision() {
assert.equal(wasm.to_precision(0.1, 3), "0.100");
assert.equal(wasm.to_precision(10, 101), "RangeError");
}
"#)
"#,
)
.test()
}
#[test]
fn to_string() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -110,8 +118,11 @@ fn to_string() {
};
result
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -121,14 +132,17 @@ fn to_string() {
assert.equal(wasm.to_string(233, 16), "e9");
assert.equal(wasm.to_string(number, 100), "RangeError");
}
"#)
"#,
)
.test()
}
#[test]
fn value_of() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -139,8 +153,11 @@ fn value_of() {
pub fn js_value_of(this: &js::Number) -> js::Number {
this.value_of()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -149,14 +166,17 @@ fn value_of() {
assert.equal(wasm.js_value_of(number), 42);
assert.equal(typeof wasm.js_value_of(number), "number");
}
"#)
"#,
)
.test()
}
#[test]
fn to_fixed() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -172,8 +192,11 @@ fn to_fixed() {
};
result
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -181,14 +204,17 @@ fn to_fixed() {
assert.equal(wasm.to_fixed(123.456, 2), "123.46");
assert.equal(wasm.to_fixed(10, 101), "RangeError");
}
"#)
"#,
)
.test()
}
#[test]
fn to_exponential() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -204,8 +230,11 @@ fn to_exponential() {
};
result
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -213,6 +242,7 @@ fn to_exponential() {
assert.equal(wasm.to_exponential(123456, 2), "1.23e+5");
assert.equal(wasm.to_exponential(10, 101), "RangeError");
}
"#)
"#,
)
.test()
}

288
tests/all/js_globals/Object.rs Executable file → Normal file
View File

@ -5,7 +5,9 @@ use project;
#[test]
fn new() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -16,22 +18,28 @@ fn new() {
pub fn new_object() -> js::Object {
js::Object::new()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(typeof wasm.new_object(), "object");
}
"#)
"#,
)
.test()
}
#[test]
fn has_own_property() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -42,8 +50,11 @@ fn has_own_property() {
pub fn has_own_foo_property(obj: &js::Object, property: &JsValue) -> bool {
obj.has_own_property(&property)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -55,14 +66,17 @@ fn has_own_property() {
const s = Symbol();
assert(wasm.has_own_foo_property({ [s]: "foo" }, s));
}
"#)
"#,
)
.test()
}
#[test]
fn to_string() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -79,8 +93,11 @@ fn to_string() {
let object = js::Object::new();
assert_eq!(String::from(object.to_string()), "[object Object]");
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -88,6 +105,97 @@ fn to_string() {
assert.equal(wasm.to_string({ foo: 42 }), "[object Object]");
wasm.test();
}
"#,
)
.test()
}
#[test]
fn is_extensible() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn is_extensible(obj: &js::Object) -> bool {
js::Object::is_extensible(&obj)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const object = {};
assert(wasm.is_extensible(object));
Object.preventExtensions(object);
assert(!wasm.is_extensible(object));
}
"#)
.test()
}
#[test]
fn is_frozen() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn is_frozen(obj: &js::Object) -> bool {
js::Object::is_frozen(&obj)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const object = {};
assert(!wasm.is_frozen(object));
Object.freeze(object);
assert(wasm.is_frozen(object));
}
"#)
.test()
}
#[test]
fn is_sealed() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn is_sealed(obj: &js::Object) -> bool {
js::Object::is_sealed(&obj)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const object = {};
assert(!wasm.is_sealed(object));
Object.seal(object);
assert(wasm.is_sealed(object));
}
"#)
.test()
}
@ -95,7 +203,9 @@ fn to_string() {
#[test]
fn is_prototype_of() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -106,8 +216,11 @@ fn is_prototype_of() {
pub fn obj_is_prototype_of_value(obj: &js::Object, value: &JsValue) -> bool {
obj.is_prototype_of(&value)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -119,14 +232,17 @@ fn is_prototype_of() {
assert(wasm.obj_is_prototype_of_value(Foo.prototype, foo));
assert(!wasm.obj_is_prototype_of_value(Bar.prototype, foo));
}
"#)
"#,
)
.test()
}
#[test]
fn keys() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -137,8 +253,11 @@ fn keys() {
pub fn keys(obj: &js::Object) -> js::Array {
js::Object::keys(obj)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -146,6 +265,40 @@ fn keys() {
const obj = { a: 1, b: 2, c: 3 };
assert.deepStrictEqual(wasm.keys(obj), ["a", "b", "c"]);
}
"#,
)
.test()
}
#[test]
fn prevent_extensions() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn prevent_extensions(obj: &js::Object) {
js::Object::prevent_extensions(obj);
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const object = {};
wasm.prevent_extensions(object);
assert(!Object.isExtensible(object));
assert.throws(() => {
'use strict';
Object.defineProperty(object, 'foo', { value: 42 });
}, TypeError);
}
"#)
.test()
}
@ -153,7 +306,9 @@ fn keys() {
#[test]
fn property_is_enumerable() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -164,8 +319,11 @@ fn property_is_enumerable() {
pub fn property_is_enumerable(obj: &js::Object, property: &JsValue) -> bool {
obj.property_is_enumerable(&property)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -181,7 +339,8 @@ fn property_is_enumerable() {
const s = Symbol();
assert.ok(wasm.property_is_enumerable({ [s]: true }, s));
}
"#)
"#,
)
.test()
}
@ -237,7 +396,7 @@ fn seal() {
}
#[test]
fn to_locale_string() {
fn set_prototype_of() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
@ -246,27 +405,65 @@ fn to_locale_string() {
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn set_prototype_of(object: &js::Object, prototype: &js::Object) -> js::Object {
js::Object::set_prototype_of(&object, &prototype)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const object = { foo: 42 };
const newPrototype = { bar: 'baz' };
const modifiedObject = wasm.set_prototype_of(object, newPrototype);
assert(newPrototype.isPrototypeOf(modifiedObject));
}
"#)
.test()
}
#[test]
fn to_locale_string() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn to_locale_string() -> js::JsString {
let object = js::Object::new();
object.to_locale_string()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.to_locale_string(), "[object Object]");
}
"#)
"#,
)
.test()
}
#[test]
fn value_of() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -277,8 +474,11 @@ fn value_of() {
pub fn value_of(obj: &js::Object) -> js::Object {
obj.value_of()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -287,6 +487,36 @@ fn value_of() {
assert.strictEqual(wasm.value_of(obj), obj);
assert.notStrictEqual(wasm.value_of(obj), { foo: 42 });
}
"#,
)
.test()
}
#[test]
fn values() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn values(obj: &js::Object) -> js::Array {
js::Object::values(&obj)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const object = { foo: 'bar', baz: 'qux' };
const values = wasm.values(object);
assert.equal(values.length, 2);
assert.deepEqual(values.sort(), ['bar', 'qux']);
}
"#)
.test()
}

182
tests/all/js_globals/Set.rs Normal file
View File

@ -0,0 +1,182 @@
#![allow(non_snake_case)]
use project;
#[test]
fn add() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn add(this: &js::Set, value: &JsValue) -> js::Set {
this.add(value)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let set = new Set([]);
wasm.add(set, 100);
assert.equal(set.size, 1);
assert.equal(Array.from(set)[0], 100);
}
"#)
.test()
}
#[test]
fn clear() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn clear(this: &js::Set) {
this.clear();
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let set = new Set([1, 2, 3]);
wasm.clear(set);
assert.equal(set.size, 0);
}
"#)
.test()
}
#[test]
fn delete() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn set_delete(this: &js::Set, value: &JsValue) -> bool {
this.delete(value)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let set = new Set([1, 2, 3]);
assert.equal(wasm.set_delete(set, 4), false);
assert.equal(wasm.set_delete(set, 2), true);
}
"#)
.test()
}
#[test]
fn has() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn has(this: &js::Set, value: &JsValue) -> bool {
this.has(value)
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let set = new Set([1, 2, 3]);
assert.equal(wasm.has(set, 4), false);
assert.equal(wasm.has(set, 2), true);
}
"#)
.test()
}
#[test]
fn new() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn new_set() -> js::Set {
js::Set::new()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let set = wasm.new_set();
assert.equal(set.size, 0);
}
"#)
.test()
}
#[test]
fn size() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn size(this: &js::Set) -> js::Number {
this.size()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let set = new Set([8, 5, 4, 3, 1, 2]);
assert.equal(wasm.size(set), 6);
}
"#)
.test()
}

View File

@ -0,0 +1,97 @@
#![allow(non_snake_case)]
use project;
#[test]
fn entries() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn entries(this: &js::Set) -> js::SetIterator {
this.entries()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let set = new Set([8, 5, 4, 3, 1, 2]);
let wasmIterator = wasm.entries(set);
let nextValue = wasmIterator.next().value;
assert.equal(nextValue[0], 8);
assert.equal(nextValue[1], 8);
}
"#)
.test()
}
#[test]
fn keys() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn keys(this: &js::Set) -> js::SetIterator {
this.keys()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let set = new Set([8, 5, 4, 3, 1, 2]);
let wasmIterator = wasm.keys(set);
let nextValue = wasmIterator.next().value;
assert.equal(nextValue, 8);
}
"#)
.test()
}
#[test]
fn values() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn values(this: &js::Set) -> js::SetIterator {
this.values()
}
"#)
.file("test.ts", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let set = new Set([8, 5, 4, 3, 1, 2]);
let wasmIterator = wasm.values(set);
let nextValue = wasmIterator.next().value;
assert.equal(nextValue, 8);
}
"#)
.test()
}

View File

@ -5,7 +5,9 @@ use project;
#[test]
fn new_undefined() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -16,22 +18,28 @@ fn new_undefined() {
pub fn new_array() -> js::Uint8Array {
js::Uint8Array::new(JsValue::undefined())
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.new_array().length, 0);
}
"#)
"#,
)
.test()
}
#[test]
fn new_length() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -42,15 +50,19 @@ fn new_length() {
pub fn new_array() -> js::Uint8Array {
js::Uint8Array::new(JsValue::from_f64(4.0))
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.new_array().length, 4);
}
"#)
"#,
)
.test()
}

View File

@ -5,7 +5,9 @@ use project;
#[test]
fn new() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -16,23 +18,28 @@ fn new() {
pub fn new_weak_map() -> js::WeakMap {
js::WeakMap::new()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(typeof wasm.new_weak_map(), "object");
}
"#)
"#,
)
.test()
}
#[test]
fn get() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -43,8 +50,11 @@ fn get() {
pub fn get_value(this: &js::WeakMap, key: js::Object) -> JsValue {
this.get(key)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -57,14 +67,17 @@ fn get() {
let undef = "unexisting_key";
assert.equal(typeof wasm.get_value(map, undef), "undefined");
}
"#)
"#,
)
.test()
}
#[test]
fn set() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -75,8 +88,11 @@ fn set() {
pub fn set_value(this: &js::WeakMap, key: js::Object, value: JsValue) -> js::WeakMap {
this.set(key, value)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -86,14 +102,17 @@ fn set() {
wasm.set_value(map, key, "value");
assert.equal(map.get(key), "value");
}
"#)
"#,
)
.test()
}
#[test]
fn has() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -104,8 +123,11 @@ fn has() {
pub fn has_value(this: &js::WeakMap, key: js::Object) -> bool {
this.has(key)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -118,14 +140,17 @@ fn has() {
let undef = "unexisting_key";
assert.equal(wasm.has_value(map, undef), false);
}
"#)
"#,
)
.test()
}
#[test]
fn delete() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -136,8 +161,11 @@ fn delete() {
pub fn delete_key(this: &js::WeakMap, key: js::Object) -> bool {
this.delete(key)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -149,6 +177,7 @@ fn delete() {
assert.equal(map.has(key), false);
assert.equal(wasm.delete_key(map, key), false);
}
"#)
"#,
)
.test()
}
}

View File

@ -0,0 +1,157 @@
#![allow(non_snake_case)]
use project;
#[test]
fn new() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn new_weak_set() -> js::WeakSet {
js::WeakSet::new()
}
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(typeof wasm.new_weak_set(), "object");
}
"#,
)
.test()
}
#[test]
fn has() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn has_value(this: &js::WeakSet, value: js::Object) -> bool {
this.has(value)
}
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let set = new WeakSet();
let value = {some: "value"};
set.add(value);
assert.equal(wasm.has_value(set, value), true);
let nonex = {nonexistent: "value"};
assert.equal(wasm.has_value(set, nonex), false);
}
"#,
)
.test()
}
#[test]
fn add() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn add_value(this: &js::WeakSet, value: js::Object) -> js::WeakSet {
this.add(value)
}
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let set = new WeakSet();
let value = {some: "value"};
wasm.add_value(set, value);
assert.equal(set.has(value), true);
assert.throws(() => { wasm.add_value(set, 1) }, TypeError);
assert.throws(() => { wasm.add_value(set, true) }, TypeError);
assert.throws(() => { wasm.add_value(set, "fail") }, TypeError);
assert.throws(() => { wasm.add_value(set, null) }, TypeError);
assert.throws(() => { wasm.add_value(set, undefined) }, TypeError);
}
"#,
)
.test()
}
#[test]
fn delete() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn delete_value(this: &js::WeakSet, value: js::Object) -> bool {
this.delete(value)
}
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let set = new WeakSet();
let value = {some: "value"};
set.add(value);
assert.equal(wasm.delete_value(set, value), true);
assert.equal(set.has(value), false);
assert.equal(wasm.delete_value(set, value), false);
assert.equal(wasm.delete_value(set, 1), false);
assert.equal(wasm.delete_value(set, true), false);
assert.equal(wasm.delete_value(set, "false"), false);
assert.equal(wasm.delete_value(set, null), false);
assert.equal(wasm.delete_value(set, undefined), false);
}
"#,
)
.test()
}

View File

@ -4,20 +4,29 @@ use super::project;
mod Array;
mod ArrayIterator;
mod Boolean;
mod Date;
mod Error;
mod Function;
mod JsString;
mod Map;
mod MapIterator;
mod Math;
mod WeakMap;
mod Number;
mod Object;
mod Set;
mod SetIterator;
mod TypedArray;
mod WeakMap;
mod WeakSet;
#[test]
#[cfg(feature = "std")]
fn decode_uri() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -33,7 +42,34 @@ fn decode_uri() {
assert!(js::decode_uri("%E0%A4%A").is_err());
}
"#)
"#,
)
.test();
}
#[test]
fn decode_uri_component() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn test() {
let x = js::decode_uri_component("%3Fx%3Dtest")
.ok()
.expect("should decode URI OK");
assert_eq!(String::from(x), "?x=test");
assert!(js::decode_uri_component("%E0%A4%A").is_err());
}
"#,
)
.test();
}
@ -41,7 +77,9 @@ fn decode_uri() {
#[cfg(feature = "std")]
fn encode_uri() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -53,14 +91,39 @@ fn encode_uri() {
let x = js::encode_uri("ABC abc 123");
assert_eq!(String::from(x), "ABC%20abc%20123");
}
"#)
"#,
)
.test();
}
#[test]
fn encode_uri_component() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn test() {
let x = js::encode_uri_component("?x=шеллы");
assert_eq!(String::from(x), "%3Fx%3D%D1%88%D0%B5%D0%BB%D0%BB%D1%8B");
}
"#,
)
.test();
}
#[test]
fn eval() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -77,6 +140,7 @@ fn eval() {
.expect("eval should throw");
assert_eq!(err.as_f64().unwrap(), 42.0);
}
"#)
"#,
)
.test();
}

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn simple() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -19,8 +21,11 @@ fn simple() {
pub fn bar(s: &JsValue) {
foo(s);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out";
import * as assert from "assert";
@ -37,14 +42,17 @@ fn simple() {
wasm.bar(sym);
assert.strictEqual(ARG, sym);
}
"#)
"#,
)
.test();
}
#[test]
fn owned() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -60,8 +68,11 @@ fn owned() {
pub fn bar(s: JsValue) {
foo(s);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out";
import * as assert from "assert";
@ -78,14 +89,17 @@ fn owned() {
wasm.bar(sym);
assert.strictEqual(ARG, sym);
}
"#)
"#,
)
.test();
}
#[test]
fn clone() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -109,8 +123,11 @@ fn clone() {
foo4(&s);
foo5(s);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out";
import * as assert from "assert";
@ -125,14 +142,17 @@ fn clone() {
export function test() {
wasm.bar(ARG);
}
"#)
"#,
)
.test();
}
#[test]
fn promote() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -154,8 +174,11 @@ fn promote() {
foo3(s);
foo4(s.clone());
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out";
import * as assert from "assert";
@ -169,14 +192,17 @@ fn promote() {
export function test() {
wasm.bar(ARG);
}
"#)
"#,
)
.test();
}
#[test]
fn returning_vector() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -196,8 +222,11 @@ fn returning_vector() {
}
res
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out";
import * as assert from "assert";
@ -207,14 +236,17 @@ fn returning_vector() {
const result = wasm.bar();
assert.strictEqual(result.length, 10);
}
"#)
"#,
)
.test();
}
#[test]
fn another_vector_return() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -233,15 +265,19 @@ fn another_vector_return() {
JsValue::from(6),
]
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { get_array } from "./out";
import * as assert from "assert";
export function test() {
assert.deepStrictEqual(get_array(), [1, 2, 3, 4, 5, 6]);
}
"#)
"#,
)
.test();
}
@ -251,7 +287,9 @@ fn serde() {
.serde(true)
.depend("serde = '1.0'")
.depend("serde_derive = '1.0'")
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -303,8 +341,11 @@ fn serde() {
let s = j.into_serde::<String>().unwrap();
assert_eq!(s, "bar");
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { run, parse } from "./out";
import * as assert from "assert";
@ -328,6 +369,7 @@ fn serde() {
run();
parse('bar');
}
"#)
"#,
)
.test();
}

View File

@ -411,15 +411,19 @@ impl Project {
self.gen_bindings(&root, &target_dir);
let mut wasm = Vec::new();
File::open(root.join("out_bg.wasm")).unwrap()
.read_to_end(&mut wasm).unwrap();
File::open(root.join("out_bg.wasm"))
.unwrap()
.read_to_end(&mut wasm)
.unwrap();
let obj = cli::wasm2es6js::Config::new()
.base64(true)
.generate(&wasm)
.expect("failed to convert wasm to js");
File::create(root.join("out_bg.d.ts")).unwrap()
.write_all(obj.typescript().as_bytes()).unwrap();
File::create(root.join("out_bg.d.ts"))
.unwrap()
.write_all(obj.typescript().as_bytes())
.unwrap();
// move files from the root into each test, it looks like this may be
// needed for webpack to work well when invoked concurrently.
@ -473,7 +477,6 @@ impl Project {
}
panic!("failed");
}
}
fn read_js(&self) -> String {
let path = root().join("out.js");
@ -522,12 +525,14 @@ mod api;
mod char;
mod classes;
mod closures;
mod comments;
mod dependencies;
mod enums;
mod import_class;
mod imports;
#[cfg(feature = "js_globals")]
mod js_globals;
mod jsobjects;
#[cfg(feature = "js_globals")] mod js_globals;
mod math;
mod node;
mod non_debug;
@ -536,6 +541,5 @@ mod simple;
mod slice;
mod structural;
mod u64;
mod webidl;
mod comments;
mod validate_prt;
mod webidl;

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn auto_bind_math() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -64,14 +66,17 @@ fn auto_bind_math() {
(a % (b as f32))) as f64) +
(b + 2.0f64.powf(a as f64))
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import { math } from "./out";
export function test() {
math(1.0, 2.0);
}
"#)
"#,
)
.test();
}

View File

@ -4,7 +4,9 @@ use super::project;
fn works() {
project()
.node(true)
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -111,8 +113,11 @@ fn works() {
(a % (b as f32))) as f64) +
(b + 2.0f64.powf(a as f64))
}
"#)
.file("test.js", r#"
"#,
)
.file(
"test.js",
r#"
const assert = require('assert');
var called = false;
@ -149,6 +154,7 @@ fn works() {
math(1.0, 2.0);
};
"#)
"#,
)
.test();
}

View File

@ -4,7 +4,9 @@ use super::project;
fn works() {
project()
.debug(false)
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -26,8 +28,11 @@ fn works() {
drop(a.clone());
a.clone()
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -37,6 +42,7 @@ fn works() {
let a = wasm.A.new();
a.free();
}
"#)
"#,
)
.test();
}

View File

@ -1,13 +1,14 @@
use super::{project, run};
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#"
p.rlib(true)
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -54,8 +55,12 @@ fn works() {
#[wasm_bindgen]
pub fn baz(_: JsValue) {
}
"#)
.file("tests/foo.rs", &format!("
"#,
)
.file(
"tests/foo.rs",
&format!(
"
extern crate {} as mytest;
#[test]
@ -63,8 +68,14 @@ fn works() {
mytest::foo(false);
mytest::A::new().foo();
}}
", name))
.file("benches/foo.rs", &format!("
",
name
),
)
.file(
"benches/foo.rs",
&format!(
"
#![feature(test)]
extern crate test;
extern crate {} as mytest;
@ -73,14 +84,18 @@ fn works() {
fn foo(b: &mut test::Bencher) {{
b.iter(|| mytest::foo(false));
}}
", name));
",
name
),
);
let (root, target_dir) = p.build();
let mut cmd = Command::new("cargo");
cmd.arg("test")
.arg("--test").arg("foo")
.arg("--bench").arg("foo")
.arg("--test")
.arg("foo")
.arg("--bench")
.arg("foo")
.current_dir(&root)
.env("CARGO_TARGET_DIR", &target_dir);
run(&mut cmd, "cargo");
}

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn add() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -37,8 +39,11 @@ fn add() {
return a
}
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -49,14 +54,17 @@ fn add() {
assert.strictEqual(wasm.get2(true), 2);
assert.strictEqual(wasm.return_and_take_bool(true, false), false);
}
"#)
"#,
)
.test();
}
#[test]
fn string_arguments() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -73,22 +81,28 @@ fn string_arguments() {
pub fn assert_foo(a: &str) {
assert_eq!(a, "foo");
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out";
export function test() {
wasm.assert_foo("foo");
wasm.assert_foo_and_bar("foo2", "bar");
}
"#)
"#,
)
.test();
}
#[test]
fn return_a_string() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -104,8 +118,11 @@ fn return_a_string() {
pub fn concat(a: &str, b: &str, c: i8) -> String {
format!("{} {} {}", a, b, c)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -115,14 +132,17 @@ fn return_a_string() {
assert.strictEqual(wasm.concat("a", "b", 3), "a b 3");
assert.strictEqual(wasm.concat("c", "d", -2), "c d -2");
}
"#)
"#,
)
.test();
}
#[test]
fn exceptions() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -134,8 +154,11 @@ fn exceptions() {
#[wasm_bindgen]
pub fn bar(_a: &str) {}
"#)
.file("test.js", r#"
"#,
)
.file(
"test.js",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -143,10 +166,14 @@ fn exceptions() {
assert.throws(() => wasm.foo('a'), /expected a number argument/);
assert.throws(() => wasm.bar(3), /expected a string argument/);
}
"#)
.file("test.d.ts", r#"
"#,
)
.file(
"test.d.ts",
r#"
export function test(): void;
"#)
"#,
)
.test();
}
@ -187,18 +214,24 @@ fn exceptions() {
#[test]
fn other_exports() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#[no_mangle]
pub extern fn foo(_a: u32) {
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out_bg";
export function test() {
wasm.foo(2);
}
"#)
"#,
)
.test();
}
@ -206,7 +239,9 @@ fn other_exports() {
fn no_std() {
project()
.no_std(true)
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
#![no_std]
#![allow(dead_code)]
@ -229,28 +264,37 @@ fn no_std() {
#[wasm_bindgen]
pub fn foo(_a: u32) {}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out_bg";
export function test() {
// mostly just testing the project compiles here
wasm.foo(1);
}
"#)
.file("foo.js", r#"
"#,
)
.file(
"foo.js",
r#"
export class Js {
init() {
}
}
"#)
"#,
)
.test();
}
#[test]
fn no_std_class() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
#![no_std]
#![allow(dead_code)]
@ -282,14 +326,18 @@ fn no_std_class() {
pub fn foo(&self) {}
pub fn bar(&mut self) {}
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as wasm from "./out_bg";
export function test() {
// mostly just testing the project compiles here
wasm.foo(1);
}
"#)
"#,
)
.test();
}

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn export() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -24,8 +26,11 @@ fn export() {
doit! { i8 u8 i16 u16 i32 u32 f32 f64 }
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -76,14 +81,17 @@ fn export() {
f64[1] = 2;
assert_arrays_equal(wasm.f64(f64), f64);
}
"#)
"#,
)
.test();
}
#[test]
fn import() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -118,8 +126,11 @@ fn import() {
(rust_f32, js_f32, f32)
(rust_f64, js_f64, f64)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -225,14 +236,17 @@ fn import() {
f64[1] = 2;
assert_arrays_equal(wasm.rust_f64(f64), f64);
}
"#)
"#,
)
.test();
}
#[test]
fn pass_array_works() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -261,8 +275,11 @@ fn pass_array_works() {
(rust_f32, f32)
(rust_f64, f64)
}
"#)
.file("test.js", r#"
"#,
)
.file(
"test.js",
r#"
const wasm = require("./out");
module.exports.test = function() {
@ -275,14 +292,17 @@ fn pass_array_works() {
wasm.rust_f32([1, 2]);
wasm.rust_f64([1, 2]);
};
"#)
"#,
)
.test();
}
#[test]
fn import_mut() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -328,8 +348,11 @@ fn import_mut() {
(rust_f32, js_f32, f32)
(rust_f64, js_f64, f64)
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -353,14 +376,17 @@ fn import_mut() {
export function test() {
wasm.run();
}
"#)
"#,
)
.test();
}
#[test]
fn export_mut() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
@ -383,8 +409,11 @@ fn export_mut() {
doit! { i8 u8 i16 u16 i32 u32 f32 f64 }
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -412,14 +441,17 @@ fn export_mut() {
run(new Float32Array(3), wasm.f32);
run(new Float64Array(3), wasm.f64);
}
"#)
"#,
)
.test();
}
#[test]
fn return_vec_ok() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -461,8 +493,11 @@ fn return_vec_ok() {
pub fn main() {
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import * as wasm from "./out";
@ -485,7 +520,7 @@ fn return_vec_ok() {
assert.strictEqual(bad[8], 9);
}
}
"#)
"#,
)
.test();
}

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn works() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -28,8 +30,11 @@ fn works() {
a.set_baz(2);
assert_eq!(a.baz(), 2);
}
"#)
.file("test.ts", r#"
"#,
)
.file(
"test.ts",
r#"
import * as assert from "assert";
import { run } from "./out";
@ -41,8 +46,7 @@ fn works() {
});
assert.strictEqual(called, true);
}
"#)
"#,
)
.test();
}

View File

@ -4,7 +4,9 @@ use super::project;
fn works() {
project()
.requires_bigint()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
@ -42,8 +44,11 @@ fn works() {
#[wasm_bindgen]
pub fn u64_slice(a: &[u64]) -> Vec<u64> { a.to_vec() }
"#)
.file("test.js", r#"
"#,
)
.file(
"test.js",
r#"
import * as wasm from './out';
function assertEq(a, b) {
@ -95,6 +100,7 @@ fn works() {
export function js_i64_round(a) { return a; }
export function js_u64_round(a) { return a; }
"#)
"#,
)
.test();
}

View File

@ -3,7 +3,9 @@ use super::project;
#[test]
fn works() {
project()
.file("src/lib.rs", r#"
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
@ -26,8 +28,11 @@ fn works() {
}
#[wasm_bindgen]
pub fn eat(_fruit: Fruit) { }
"#)
.file("test.js", r#"
"#,
)
.file(
"test.js",
r#"
import * as wasm from './out';
const targetMessage = 'Attempt to use a moved value';
function assertEq(a, b) {
@ -64,6 +69,7 @@ fn works() {
assertEq(e.message, targetMessage);
}
}
"#)
"#,
)
.test();
}