Merge pull request #891 from alexcrichton/rustfmt

cargo +nightly fmt --all
This commit is contained in:
Alex Crichton 2018-09-26 14:20:33 -05:00 committed by GitHub
commit 35a7233101
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
163 changed files with 2975 additions and 1998 deletions

View File

@ -396,7 +396,7 @@ impl ImportFunction {
// if `#[wasm_bindgen(js_name = "...")]` is used then that explicitly // if `#[wasm_bindgen(js_name = "...")]` is used then that explicitly
// because it was hand-written anyway. // because it was hand-written anyway.
if self.function.renamed_via_js_name { if self.function.renamed_via_js_name {
return Ok(name) return Ok(name);
} }
// Otherwise we infer names based on the Rust function name. // Otherwise we infer names based on the Rust function name.
@ -417,18 +417,14 @@ impl ImportFunction {
OperationKind::Regular => shared::OperationKind::Regular, OperationKind::Regular => shared::OperationKind::Regular,
OperationKind::Getter(g) => { OperationKind::Getter(g) => {
let g = g.as_ref().map(|g| g.to_string()); let g = g.as_ref().map(|g| g.to_string());
shared::OperationKind::Getter( shared::OperationKind::Getter(g.unwrap_or_else(|| self.infer_getter_property()))
g.unwrap_or_else(|| self.infer_getter_property()),
)
} }
OperationKind::Setter(s) => { OperationKind::Setter(s) => {
let s = s.as_ref().map(|s| s.to_string()); let s = s.as_ref().map(|s| s.to_string());
shared::OperationKind::Setter( shared::OperationKind::Setter(match s {
match s { Some(s) => s,
Some(s) => s, None => self.infer_setter_property()?,
None => self.infer_setter_property()?, })
}
)
} }
OperationKind::IndexingGetter => shared::OperationKind::IndexingGetter, OperationKind::IndexingGetter => shared::OperationKind::IndexingGetter,
OperationKind::IndexingSetter => shared::OperationKind::IndexingSetter, OperationKind::IndexingSetter => shared::OperationKind::IndexingSetter,

View File

@ -1,6 +1,6 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::sync::Mutex;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use std::sync::Mutex;
use proc_macro2::{Ident, Literal, Span, TokenStream}; use proc_macro2::{Ident, Literal, Span, TokenStream};
use quote::ToTokens; use quote::ToTokens;
@ -9,8 +9,8 @@ use shared;
use syn; use syn;
use ast; use ast;
use Diagnostic;
use util::ShortHash; use util::ShortHash;
use Diagnostic;
pub trait TryToTokens { pub trait TryToTokens {
fn try_to_tokens(&self, tokens: &mut TokenStream) -> Result<(), Diagnostic>; fn try_to_tokens(&self, tokens: &mut TokenStream) -> Result<(), Diagnostic>;
@ -51,7 +51,7 @@ impl TryToTokens for ast::Program {
Ok(kind) => kind, Ok(kind) => kind,
Err(e) => { Err(e) => {
errors.push(e); errors.push(e);
continue continue;
} }
}; };
(quote! { impl #ns { #kind } }).to_tokens(tokens); (quote! { impl #ns { #kind } }).to_tokens(tokens);
@ -275,9 +275,12 @@ impl ToTokens for ast::StructField {
} }
}).to_tokens(tokens); }).to_tokens(tokens);
Descriptor(&getter, quote! { Descriptor(
<#ty as WasmDescribe>::describe(); &getter,
}).to_tokens(tokens); quote! {
<#ty as WasmDescribe>::describe();
},
).to_tokens(tokens);
if self.readonly { if self.readonly {
return; return;
@ -307,9 +310,7 @@ impl ToTokens for ast::StructField {
} }
impl TryToTokens for ast::Export { impl TryToTokens for ast::Export {
fn try_to_tokens(self: &ast::Export, into: &mut TokenStream) fn try_to_tokens(self: &ast::Export, into: &mut TokenStream) -> Result<(), Diagnostic> {
-> Result<(), Diagnostic>
{
let generated_name = self.rust_symbol(); let generated_name = self.rust_symbol();
let export_name = self.export_name(); let export_name = self.export_name();
let mut args = vec![]; let mut args = vec![];
@ -424,10 +425,7 @@ impl TryToTokens for ast::Export {
}); });
let syn_ret = self.function.ret.as_ref().unwrap_or(&syn_unit); let syn_ret = self.function.ret.as_ref().unwrap_or(&syn_unit);
if let syn::Type::Reference(_) = syn_ret { if let syn::Type::Reference(_) = syn_ret {
bail_span!( bail_span!(syn_ret, "cannot return a borrowed ref with #[wasm_bindgen]",)
syn_ret,
"cannot return a borrowed ref with #[wasm_bindgen]",
)
} }
let ret_ty = quote! { let ret_ty = quote! {
-> <#syn_ret as ::wasm_bindgen::convert::ReturnWasmAbi>::Abi -> <#syn_ret as ::wasm_bindgen::convert::ReturnWasmAbi>::Abi
@ -482,12 +480,15 @@ impl TryToTokens for ast::Export {
// this, but the tl;dr; is that this is stripped from the final wasm // this, but the tl;dr; is that this is stripped from the final wasm
// binary along with anything it references. // binary along with anything it references.
let export = Ident::new(&export_name, Span::call_site()); let export = Ident::new(&export_name, Span::call_site());
Descriptor(&export, quote! { Descriptor(
inform(FUNCTION); &export,
inform(#nargs); quote! {
#(<#argtys as WasmDescribe>::describe();)* inform(FUNCTION);
#describe_ret inform(#nargs);
}).to_tokens(into); #(<#argtys as WasmDescribe>::describe();)*
#describe_ret
},
).to_tokens(into);
Ok(()) Ok(())
} }
@ -680,8 +681,7 @@ impl ToTokens for ast::ImportEnum {
let this_index = current_idx; let this_index = current_idx;
current_idx += 1; current_idx += 1;
Literal::usize_unsuffixed(this_index) Literal::usize_unsuffixed(this_index)
}) }).collect();
.collect();
// Borrow variant_indexes because we need to use it multiple times inside the quote! macro // Borrow variant_indexes because we need to use it multiple times inside the quote! macro
let variant_indexes_ref = &variant_indexes; let variant_indexes_ref = &variant_indexes;
@ -792,12 +792,10 @@ impl TryToTokens for ast::ImportFunction {
.. ..
}) => ident.clone(), }) => ident.clone(),
syn::Pat::Wild(_) => syn::Ident::new(&format!("__genarg_{}", i), Span::call_site()), syn::Pat::Wild(_) => syn::Ident::new(&format!("__genarg_{}", i), Span::call_site()),
_ => { _ => bail_span!(
bail_span!( pat,
pat, "unsupported pattern in #[wasm_bindgen] imported function",
"unsupported pattern in #[wasm_bindgen] imported function", ),
)
}
}; };
abi_argument_names.push(name.clone()); abi_argument_names.push(name.clone());
@ -819,7 +817,10 @@ impl TryToTokens for ast::ImportFunction {
let mut convert_ret; let mut convert_ret;
match &self.js_ret { match &self.js_ret {
Some(syn::Type::Reference(_)) => { Some(syn::Type::Reference(_)) => {
bail_span!(self.js_ret, "cannot return references in #[wasm_bindgen] imports yet"); bail_span!(
self.js_ret,
"cannot return references in #[wasm_bindgen] imports yet"
);
} }
Some(ref ty) => { Some(ref ty) => {
abi_ret = quote! { abi_ret = quote! {
@ -943,12 +944,15 @@ impl<'a> ToTokens for DescribeImport<'a> {
None => quote! { <() as WasmDescribe>::describe(); }, None => quote! { <() as WasmDescribe>::describe(); },
}; };
Descriptor(&f.shim, quote! { Descriptor(
inform(FUNCTION); &f.shim,
inform(#nargs); quote! {
#(<#argtys as WasmDescribe>::describe();)* inform(FUNCTION);
#inform_ret inform(#nargs);
}).to_tokens(tokens); #(<#argtys as WasmDescribe>::describe();)*
#inform_ret
},
).to_tokens(tokens);
} }
} }
@ -1055,15 +1059,15 @@ impl ToTokens for ast::Const {
FloatLiteral(f) => { FloatLiteral(f) => {
let f = Literal::f64_suffixed(f); let f = Literal::f64_suffixed(f);
quote!(#f) quote!(#f)
}, }
SignedIntegerLiteral(i) => { SignedIntegerLiteral(i) => {
let i = Literal::i64_suffixed(i); let i = Literal::i64_suffixed(i);
quote!(#i) quote!(#i)
}, }
UnsignedIntegerLiteral(i) => { UnsignedIntegerLiteral(i) => {
let i = Literal::u64_suffixed(i); let i = Literal::u64_suffixed(i);
quote!(#i) quote!(#i)
}, }
Null => unimplemented!(), Null => unimplemented!(),
}; };
@ -1088,11 +1092,15 @@ impl ToTokens for ast::Dictionary {
for field in self.fields.iter() { for field in self.fields.iter() {
field.to_tokens(&mut methods); field.to_tokens(&mut methods);
} }
let required_names = &self.fields.iter() let required_names = &self
.fields
.iter()
.filter(|f| f.required) .filter(|f| f.required)
.map(|f| &f.name) .map(|f| &f.name)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let required_types = &self.fields.iter() let required_types = &self
.fields
.iter()
.filter(|f| f.required) .filter(|f| f.required)
.map(|f| &f.ty) .map(|f| &f.ty)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -1240,8 +1248,12 @@ impl<'a, T: ToTokens> ToTokens for Descriptor<'a, T> {
lazy_static! { lazy_static! {
static ref DESCRIPTORS_EMITTED: Mutex<HashSet<String>> = Default::default(); static ref DESCRIPTORS_EMITTED: Mutex<HashSet<String>> = Default::default();
} }
if !DESCRIPTORS_EMITTED.lock().unwrap().insert(self.0.to_string()) { if !DESCRIPTORS_EMITTED
return .lock()
.unwrap()
.insert(self.0.to_string())
{
return;
} }
let name = Ident::new(&format!("__wbindgen_describe_{}", self.0), self.0.span()); let name = Ident::new(&format!("__wbindgen_describe_{}", self.0), self.0.span());

View File

@ -210,7 +210,7 @@ impl ImportedTypes for syn::PathArguments {
arg.imported_types(f); arg.imported_types(f);
} }
} }
//TOCHECK //TOCHECK
syn::PathArguments::Parenthesized(data) => { syn::PathArguments::Parenthesized(data) => {
for input in data.inputs.iter() { for input in data.inputs.iter() {
input.imported_types(f); input.imported_types(f);
@ -231,14 +231,13 @@ impl ImportedTypes for syn::GenericArgument {
match self { match self {
syn::GenericArgument::Lifetime(_) => {} syn::GenericArgument::Lifetime(_) => {}
syn::GenericArgument::Type(ty) => ty.imported_types(f), syn::GenericArgument::Type(ty) => ty.imported_types(f),
syn::GenericArgument::Binding(_) => {}, // TODO syn::GenericArgument::Binding(_) => {} // TODO
syn::GenericArgument::Const(_) => {}, // TODO syn::GenericArgument::Const(_) => {} // TODO
syn::GenericArgument::Constraint(_) => {}, // TODO syn::GenericArgument::Constraint(_) => {} // TODO
} }
} }
} }
impl ImportedTypes for ast::ImportFunction { impl ImportedTypes for ast::ImportFunction {
fn imported_types<F>(&self, f: &mut F) fn imported_types<F>(&self, f: &mut F)
where where
@ -351,14 +350,15 @@ impl RemoveUndefinedImports for ast::Program {
let mut dictionaries_to_remove = Vec::new(); let mut dictionaries_to_remove = Vec::new();
for (i, dictionary) in self.dictionaries.iter_mut().enumerate() { for (i, dictionary) in self.dictionaries.iter_mut().enumerate() {
let num_required = |dict: &ast::Dictionary| { let num_required =
dict.fields.iter().filter(|f| f.required).count() |dict: &ast::Dictionary| dict.fields.iter().filter(|f| f.required).count();
};
let before = num_required(dictionary); let before = num_required(dictionary);
changed = dictionary.fields.remove_undefined_imports(is_defined) || changed; changed = dictionary.fields.remove_undefined_imports(is_defined) || changed;
if before != num_required(dictionary) { if before != num_required(dictionary) {
warn!("removing {} due to a required field being removed", warn!(
dictionary.name); "removing {} due to a required field being removed",
dictionary.name
);
dictionaries_to_remove.push(i); dictionaries_to_remove.push(i);
} }
} }

View File

@ -30,7 +30,7 @@ enum Repr {
SynError(Error), SynError(Error),
Multi { Multi {
diagnostics: Vec<Diagnostic>, diagnostics: Vec<Diagnostic>,
} },
} }
impl Diagnostic { impl Diagnostic {
@ -39,7 +39,7 @@ impl Diagnostic {
inner: Repr::Single { inner: Repr::Single {
text: text.into(), text: text.into(),
span: None, span: None,
} },
} }
} }
@ -48,7 +48,7 @@ impl Diagnostic {
inner: Repr::Single { inner: Repr::Single {
text: text.into(), text: text.into(),
span: extract_spans(node), span: extract_spans(node),
} },
} }
} }
@ -56,7 +56,9 @@ impl Diagnostic {
if diagnostics.len() == 0 { if diagnostics.len() == 0 {
Ok(()) Ok(())
} else { } else {
Err(Diagnostic { inner: Repr::Multi { diagnostics } }) Err(Diagnostic {
inner: Repr::Multi { diagnostics },
})
} }
} }
@ -72,7 +74,7 @@ impl Diagnostic {
impl From<Error> for Diagnostic { impl From<Error> for Diagnostic {
fn from(err: Error) -> Diagnostic { fn from(err: Error) -> Diagnostic {
Diagnostic { Diagnostic {
inner: Repr::SynError(err), inner: Repr::SynError(err),
} }
} }

View File

@ -1,5 +1,8 @@
#![recursion_limit = "256"] #![recursion_limit = "256"]
#![cfg_attr(feature = "extra-traits", deny(missing_debug_implementations))] #![cfg_attr(
feature = "extra-traits",
deny(missing_debug_implementations)
)]
#![doc(html_root_url = "https://docs.rs/wasm-bindgen-backend/0.2")] #![doc(html_root_url = "https://docs.rs/wasm-bindgen-backend/0.2")]
#[macro_use] #[macro_use]

View File

@ -71,8 +71,7 @@ where
.map(|i| syn::PathSegment { .map(|i| syn::PathSegment {
ident: i, ident: i,
arguments: syn::PathArguments::None, arguments: syn::PathArguments::None,
}) }).collect();
.collect();
syn::TypePath { syn::TypePath {
qself: None, qself: None,

View File

@ -163,20 +163,14 @@ impl Descriptor {
pub fn is_wasm_native(&self) -> bool { pub fn is_wasm_native(&self) -> bool {
match *self { match *self {
Descriptor::I32 Descriptor::I32 | Descriptor::U32 | Descriptor::F32 | Descriptor::F64 => true,
| Descriptor::U32
| Descriptor::F32
| Descriptor::F64 => true,
_ => return false, _ => return false,
} }
} }
pub fn is_abi_as_u32(&self) -> bool { pub fn is_abi_as_u32(&self) -> bool {
match *self { match *self {
Descriptor::I8 Descriptor::I8 | Descriptor::U8 | Descriptor::I16 | Descriptor::U16 => true,
| Descriptor::U8
| Descriptor::I16
| Descriptor::U16 => true,
_ => return false, _ => return false,
} }
} }
@ -223,12 +217,10 @@ impl Descriptor {
Descriptor::Slice(ref d) => &**d, Descriptor::Slice(ref d) => &**d,
_ => return None, _ => return None,
}, },
Descriptor::Clamped(ref d) => { Descriptor::Clamped(ref d) => match d.vector_kind()? {
match d.vector_kind()? { VectorKind::U8 => return Some(VectorKind::ClampedU8),
VectorKind::U8 => return Some(VectorKind::ClampedU8), _ => return None,
_ => return None, },
}
}
_ => return None, _ => return None,
}; };
match *inner { match *inner {

View File

@ -16,8 +16,8 @@ use failure::Error;
use parity_wasm::elements::*; use parity_wasm::elements::*;
use descriptor::Descriptor; use descriptor::Descriptor;
use js::Context;
use js::js2rust::Js2Rust; use js::js2rust::Js2Rust;
use js::Context;
pub fn rewrite(input: &mut Context) -> Result<(), Error> { pub fn rewrite(input: &mut Context) -> Result<(), Error> {
let info = ClosureDescriptors::new(input); let info = ClosureDescriptors::new(input);
@ -29,7 +29,7 @@ pub fn rewrite(input: &mut Context) -> Result<(), Error> {
info.code_idx_to_descriptor.len(), info.code_idx_to_descriptor.len(),
); );
if info.element_removal_list.len() == 0 { if info.element_removal_list.len() == 0 {
return Ok(()) return Ok(());
} }
// Make sure the names section is available in the wasm module because we'll // Make sure the names section is available in the wasm module because we'll
@ -39,7 +39,8 @@ pub fn rewrite(input: &mut Context) -> Result<(), Error> {
input.parse_wasm_names(); input.parse_wasm_names();
Remap { Remap {
code_idx_to_descriptor: &info.code_idx_to_descriptor, code_idx_to_descriptor: &info.code_idx_to_descriptor,
old_num_imports: input.module old_num_imports: input
.module
.import_section() .import_section()
.map(|s| s.functions()) .map(|s| s.functions())
.unwrap_or(0) as u32, .unwrap_or(0) as u32,
@ -90,7 +91,9 @@ impl ClosureDescriptors {
Some(i) => i, Some(i) => i,
None => return Default::default(), None => return Default::default(),
}; };
let imports = input.module.import_section() let imports = input
.module
.import_section()
.map(|s| s.functions()) .map(|s| s.functions())
.unwrap_or(0); .unwrap_or(0);
let mut ret = ClosureDescriptors::default(); let mut ret = ClosureDescriptors::default();
@ -100,24 +103,18 @@ impl ClosureDescriptors {
None => return Default::default(), None => return Default::default(),
}; };
for (i, function) in code.bodies().iter().enumerate() { for (i, function) in code.bodies().iter().enumerate() {
let call_pos = function.code() let call_pos = function.code().elements().iter().position(|i| match i {
.elements() Instruction::Call(i) => *i == wbindgen_describe_closure,
.iter() _ => false,
.position(|i| { });
match i {
Instruction::Call(i) => *i == wbindgen_describe_closure,
_ => false,
}
});
let call_pos = match call_pos { let call_pos = match call_pos {
Some(i) => i, Some(i) => i,
None => continue, None => continue,
}; };
let descriptor = input.interpreter.interpret_closure_descriptor( let descriptor = input
i, .interpreter
input.module, .interpret_closure_descriptor(i, input.module, &mut ret.element_removal_list)
&mut ret.element_removal_list, .unwrap();
).unwrap();
// `new_idx` is the function-space index of the function that we'll // `new_idx` is the function-space index of the function that we'll
// be injecting. Calls to the code function `i` will instead be // be injecting. Calls to the code function `i` will instead be
// rewritten to calls to `new_idx`, which is an import that we'll // rewritten to calls to `new_idx`, which is an import that we'll
@ -132,7 +129,7 @@ impl ClosureDescriptors {
}, },
); );
} }
return ret return ret;
} }
/// Here we remove elements from the function table. All our descriptor /// Here we remove elements from the function table. All our descriptor
@ -165,7 +162,7 @@ impl ClosureDescriptors {
// If we keep this entry, then keep going // If we keep this entry, then keep going
if !to_remove.contains(&j) { if !to_remove.contains(&j) {
current.push(*idx); current.push(*idx);
continue continue;
} }
// If we have members of `current` then we save off a section // If we have members of `current` then we save off a section
@ -173,10 +170,8 @@ impl ClosureDescriptors {
let next_offset = offset + (current.len() as i32) + 1; let next_offset = offset + (current.len() as i32) + 1;
if current.len() > 0 { if current.len() > 0 {
let members = mem::replace(&mut current, Vec::new()); let members = mem::replace(&mut current, Vec::new());
let offset = InitExpr::new(vec![ let offset =
Instruction::I32Const(offset), InitExpr::new(vec![Instruction::I32Const(offset), Instruction::End]);
Instruction::End,
]);
let new_entry = ElementSegment::new(0, offset, members); let new_entry = ElementSegment::new(0, offset, members);
elements.entries_mut().push(new_entry); elements.entries_mut().push(new_entry);
} }
@ -184,10 +179,7 @@ impl ClosureDescriptors {
} }
// Any remaining function table entries get pushed at the end. // Any remaining function table entries get pushed at the end.
if current.len() > 0 { if current.len() > 0 {
let offset = InitExpr::new(vec![ let offset = InitExpr::new(vec![Instruction::I32Const(offset), Instruction::End]);
Instruction::I32Const(offset),
Instruction::End,
]);
let new_entry = ElementSegment::new(0, offset, current); let new_entry = ElementSegment::new(0, offset, current);
elements.entries_mut().push(new_entry); elements.entries_mut().push(new_entry);
} }
@ -211,9 +203,8 @@ impl ClosureDescriptors {
// signature of our `#[inline(never)]` functions. Find the type // signature of our `#[inline(never)]` functions. Find the type
// signature index so we can assign it below. // signature index so we can assign it below.
let type_idx = { let type_idx = {
let kind = input.module.import_section() let kind = input.module.import_section().unwrap().entries()
.unwrap() [wbindgen_describe_closure as usize]
.entries()[wbindgen_describe_closure as usize]
.external(); .external();
match kind { match kind {
External::Function(i) => *i, External::Function(i) => *i,
@ -268,7 +259,9 @@ impl ClosureDescriptors {
import_name, import_name,
External::Function(type_idx as u32), External::Function(type_idx as u32),
); );
input.module.import_section_mut() input
.module
.import_section_mut()
.unwrap() .unwrap()
.entries_mut() .entries_mut()
.push(new_import); .push(new_import);
@ -313,7 +306,9 @@ impl<'a> Remap<'a> {
Section::Export(e) => self.remap_export_section(e), Section::Export(e) => self.remap_export_section(e),
Section::Element(e) => self.remap_element_section(e), Section::Element(e) => self.remap_element_section(e),
Section::Code(e) => self.remap_code_section(e), Section::Code(e) => self.remap_code_section(e),
Section::Start(i) => { self.remap_idx(i); } Section::Start(i) => {
self.remap_idx(i);
}
Section::Name(n) => self.remap_name_section(n), Section::Name(n) => self.remap_name_section(n),
_ => {} _ => {}
} }
@ -328,10 +323,11 @@ impl<'a> Remap<'a> {
fn remap_export_entry(&self, entry: &mut ExportEntry) { fn remap_export_entry(&self, entry: &mut ExportEntry) {
match entry.internal_mut() { match entry.internal_mut() {
Internal::Function(i) => { self.remap_idx(i); } Internal::Function(i) => {
self.remap_idx(i);
}
_ => {} _ => {}
} }
} }
fn remap_element_section(&self, section: &mut ElementSection) { fn remap_element_section(&self, section: &mut ElementSection) {
@ -364,7 +360,9 @@ impl<'a> Remap<'a> {
fn remap_instruction(&self, instr: &mut Instruction) { fn remap_instruction(&self, instr: &mut Instruction) {
match instr { match instr {
Instruction::Call(i) => { self.remap_idx(i); } Instruction::Call(i) => {
self.remap_idx(i);
}
_ => {} _ => {}
} }
} }
@ -403,7 +401,7 @@ impl<'a> Remap<'a> {
// If this was an imported function we didn't reorder those, so nothing // If this was an imported function we didn't reorder those, so nothing
// to do. // to do.
if *idx < self.old_num_imports { if *idx < self.old_num_imports {
return false return false;
} }
// ... otherwise we're injecting a number of new imports, so offset // ... otherwise we're injecting a number of new imports, so offset
// everything. // everything.

View File

@ -197,10 +197,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
self.cx.expose_add_heap_object(); self.cx.expose_add_heap_object();
if optional { if optional {
self.cx.expose_is_like_none(); self.cx.expose_is_like_none();
self.rust_arguments.push(format!( self.rust_arguments
"isLikeNone({0}) ? 0 : addHeapObject({0})", .push(format!("isLikeNone({0}) ? 0 : addHeapObject({0})", name,));
name,
));
} else { } else {
self.rust_arguments.push(format!("addHeapObject({})", name)); self.rust_arguments.push(format!("addHeapObject({})", name));
} }
@ -225,7 +223,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
} }
self.rust_arguments.push(format!("!isLikeNone({0})", name)); self.rust_arguments.push(format!("!isLikeNone({0})", name));
self.rust_arguments.push(format!("isLikeNone({0}) ? 0 : {0}", name)); self.rust_arguments
.push(format!("isLikeNone({0}) ? 0 : {0}", name));
return Ok(self); return Ok(self);
} }
@ -245,7 +244,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
)); ));
} }
self.rust_arguments.push(format!("isLikeNone({0}) ? 0xFFFFFF : {0}", name)); self.rust_arguments
.push(format!("isLikeNone({0}) ? 0xFFFFFF : {0}", name));
return Ok(self); return Ok(self);
} }
@ -278,7 +278,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
match *arg { match *arg {
Descriptor::Boolean => { Descriptor::Boolean => {
self.cx.expose_is_like_none(); self.cx.expose_is_like_none();
self.js_arguments.push((name.clone(), "boolean".to_string())); self.js_arguments
.push((name.clone(), "boolean".to_string()));
if self.cx.config.debug { if self.cx.config.debug {
self.cx.expose_assert_bool(); self.cx.expose_assert_bool();
self.prelude(&format!( self.prelude(&format!(
@ -290,17 +291,22 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
name, name,
)); ));
} }
self.rust_arguments.push(format!("isLikeNone({0}) ? 0xFFFFFF : {0} ? 1 : 0", name)); self.rust_arguments
.push(format!("isLikeNone({0}) ? 0xFFFFFF : {0} ? 1 : 0", name));
return Ok(self); return Ok(self);
}, }
Descriptor::Char => { Descriptor::Char => {
self.cx.expose_is_like_none(); self.cx.expose_is_like_none();
self.js_arguments.push((name.clone(), "string".to_string())); self.js_arguments.push((name.clone(), "string".to_string()));
self.rust_arguments.push(format!("!isLikeNone({0})", name)); self.rust_arguments.push(format!("!isLikeNone({0})", name));
self.rust_arguments.push(format!("isLikeNone({0}) ? 0 : {0}.codePointAt(0)", name)); self.rust_arguments
.push(format!("isLikeNone({0}) ? 0 : {0}.codePointAt(0)", name));
return Ok(self); return Ok(self);
}, }
_ => bail!("unsupported optional argument type for calling Rust function from JS: {:?}", arg), _ => bail!(
"unsupported optional argument type for calling Rust function from JS: {:?}",
arg
),
}; };
} }
@ -401,7 +407,10 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
self.js_arguments.push((name.clone(), "string".to_string())); self.js_arguments.push((name.clone(), "string".to_string()));
self.rust_arguments.push(format!("{}.codePointAt(0)", name)) self.rust_arguments.push(format!("{}.codePointAt(0)", name))
} }
_ => bail!("unsupported argument type for calling Rust function from JS: {:?}", arg), _ => bail!(
"unsupported argument type for calling Rust function from JS: {:?}",
arg
),
} }
Ok(self) Ok(self)
} }
@ -412,14 +421,15 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
Some(class) if class == name => { Some(class) if class == name => {
self.ret_expr = format!("this.ptr = RET;"); self.ret_expr = format!("this.ptr = RET;");
if self.cx.config.weak_refs { if self.cx.config.weak_refs {
self.ret_expr.push_str(&format!("\ self.ret_expr.push_str(&format!(
"\
addCleanup(this, this.ptr, free{}); addCleanup(this, this.ptr, free{});
", name)); ",
name
));
} }
} }
Some(class) => { Some(class) => bail!("constructor for `{}` cannot return `{}`", class, name),
bail!("constructor for `{}` cannot return `{}`", class, name)
}
None => { None => {
self.ret_ty = name.to_string(); self.ret_ty = name.to_string();
self.cx.require_class_wrap(name); self.cx.require_class_wrap(name);
@ -465,7 +475,11 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
", ",
f, f,
ty.size(), ty.size(),
guard = if optional { "if (rustptr === 0) return;" } else { "" }, guard = if optional {
"if (rustptr === 0) return;"
} else {
""
},
); );
return Ok(self); return Ok(self);
} }
@ -559,7 +573,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
return ret === 0xFFFFFF ? undefined : ret !== 0; return ret === 0xFFFFFF ? undefined : ret !== 0;
".to_string(); ".to_string();
return Ok(self); return Ok(self);
}, }
Descriptor::Char => { Descriptor::Char => {
self.ret_ty = "string".to_string(); self.ret_ty = "string".to_string();
self.cx.expose_global_argument_ptr()?; self.cx.expose_global_argument_ptr()?;
@ -573,8 +587,11 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
return present === 0 ? undefined : String.fromCodePoint(value); return present === 0 ? undefined : String.fromCodePoint(value);
".to_string(); ".to_string();
return Ok(self); return Ok(self);
}, }
_ => bail!("unsupported optional return type for calling Rust function from JS: {:?}", ty), _ => bail!(
"unsupported optional return type for calling Rust function from JS: {:?}",
ty
),
}; };
} }
@ -633,15 +650,20 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
self.ret_ty = "string".to_string(); self.ret_ty = "string".to_string();
self.ret_expr = format!("return String.fromCodePoint(RET);") self.ret_expr = format!("return String.fromCodePoint(RET);")
} }
_ => bail!("unsupported return type for calling Rust function from JS: {:?}", ty), _ => bail!(
"unsupported return type for calling Rust function from JS: {:?}",
ty
),
} }
Ok(self) Ok(self)
} }
pub fn js_doc_comments(&self) -> String { pub fn js_doc_comments(&self) -> String {
let mut ret: String = self.js_arguments.iter().map(|a| { let mut ret: String = self
format!("@param {{{}}} {}\n", a.1, a.0) .js_arguments
}).collect(); .iter()
.map(|a| format!("@param {{{}}} {}\n", a.1, a.0))
.collect();
ret.push_str(&format!("@returns {{{}}}", self.ret_ty)); ret.push_str(&format!("@returns {{{}}}", self.ret_ty));
ret ret
} }

View File

@ -390,7 +390,8 @@ impl<'a> Context<'a> {
function() {{ function() {{
return addHeapObject({}); return addHeapObject({});
}} }}
", mem ",
mem
)) ))
})?; })?;
@ -549,7 +550,7 @@ impl<'a> Context<'a> {
constructor() { constructor() {
throw new Error('cannot invoke `new` directly'); throw new Error('cannot invoke `new` directly');
} }
" ",
); );
} }
@ -705,8 +706,7 @@ impl<'a> Context<'a> {
.filter_map(|s| match *s { .filter_map(|s| match *s {
Section::Import(ref mut s) => Some(s), Section::Import(ref mut s) => Some(s),
_ => None, _ => None,
}) }).flat_map(|s| s.entries_mut());
.flat_map(|s| s.entries_mut());
for import in imports { for import in imports {
if import.module() == "__wbindgen_placeholder__" { if import.module() == "__wbindgen_placeholder__" {
@ -726,7 +726,7 @@ impl<'a> Context<'a> {
import.module_mut().truncate(0); import.module_mut().truncate(0);
import.module_mut().push_str("./"); import.module_mut().push_str("./");
import.module_mut().push_str(module_name); import.module_mut().push_str(module_name);
continue continue;
} }
let renamed_import = format!("__wbindgen_{}", import.field()); let renamed_import = format!("__wbindgen_{}", import.field());
@ -817,7 +817,9 @@ impl<'a> Context<'a> {
slab_next = idx; slab_next = idx;
}} }}
", ",
validate_owned, INITIAL_SLAB_VALUES.len(), dec_ref validate_owned,
INITIAL_SLAB_VALUES.len(),
dec_ref
)); ));
} }
@ -848,7 +850,8 @@ impl<'a> Context<'a> {
if !self.exposed_globals.insert("slab") { if !self.exposed_globals.insert("slab") {
return; return;
} }
let initial_values = INITIAL_SLAB_VALUES.iter() let initial_values = INITIAL_SLAB_VALUES
.iter()
.map(|s| format!("{{ obj: {} }}", s)) .map(|s| format!("{{ obj: {} }}", s))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
self.global(&format!("const slab = [{}];", initial_values.join(", "))); self.global(&format!("const slab = [{}];", initial_values.join(", ")));
@ -1013,7 +1016,8 @@ impl<'a> Context<'a> {
self.require_internal_export("__wbindgen_malloc")?; self.require_internal_export("__wbindgen_malloc")?;
self.expose_uint32_memory(); self.expose_uint32_memory();
self.expose_add_heap_object(); self.expose_add_heap_object();
self.global(" self.global(
"
function passArrayJsValueToWasm(array) { function passArrayJsValueToWasm(array) {
const ptr = wasm.__wbindgen_malloc(array.length * 4); const ptr = wasm.__wbindgen_malloc(array.length * 4);
const mem = getUint32Memory(); const mem = getUint32Memory();
@ -1023,7 +1027,8 @@ impl<'a> Context<'a> {
return [ptr, array.length]; return [ptr, array.length];
} }
"); ",
);
Ok(()) Ok(())
} }
@ -1126,7 +1131,8 @@ impl<'a> Context<'a> {
// non-shared mode there's no need to copy the data except for the // non-shared mode there's no need to copy the data except for the
// string itself. // string itself.
self.memory(); // set self.memory_init self.memory(); // set self.memory_init
let is_shared = self.module let is_shared = self
.module
.memory_section() .memory_section()
.map(|s| s.entries()[0].limits().shared()) .map(|s| s.entries()[0].limits().shared())
.unwrap_or(match &self.memory_init { .unwrap_or(match &self.memory_init {
@ -1135,11 +1141,14 @@ impl<'a> Context<'a> {
}); });
let method = if is_shared { "slice" } else { "subarray" }; let method = if is_shared { "slice" } else { "subarray" };
self.global(&format!(" self.global(&format!(
"
function getStringFromWasm(ptr, len) {{ function getStringFromWasm(ptr, len) {{
return cachedDecoder.decode(getUint8Memory().{}(ptr, ptr + len)); return cachedDecoder.decode(getUint8Memory().{}(ptr, ptr + len));
}} }}
", method)); ",
method
));
} }
fn expose_get_array_js_value_from_wasm(&mut self) { fn expose_get_array_js_value_from_wasm(&mut self) {
@ -1646,18 +1655,20 @@ impl<'a> Context<'a> {
fn expose_is_like_none(&mut self) { fn expose_is_like_none(&mut self) {
if !self.exposed_globals.insert("is_like_none") { if !self.exposed_globals.insert("is_like_none") {
return return;
} }
self.global(" self.global(
"
function isLikeNone(x) { function isLikeNone(x) {
return x === undefined || x === null; return x === undefined || x === null;
} }
"); ",
);
} }
fn expose_cleanup_groups(&mut self) { fn expose_cleanup_groups(&mut self) {
if !self.exposed_globals.insert("cleanup_groups") { if !self.exposed_globals.insert("cleanup_groups") {
return return;
} }
self.global( self.global(
" "
@ -1668,7 +1679,7 @@ impl<'a> Context<'a> {
const ref = CLEANUPS.makeRef(obj, () => free(ptr)); const ref = CLEANUPS.makeRef(obj, () => free(ptr));
CLEANUPS_MAP.set(ptr, ref); CLEANUPS_MAP.set(ptr, ref);
} }
" ",
); );
} }
@ -1719,17 +1730,16 @@ impl<'a> Context<'a> {
return "wasm.memory"; return "wasm.memory";
} }
let (entry, mem) = self.module.import_section() let (entry, mem) = self
.module
.import_section()
.expect("must import memory") .expect("must import memory")
.entries() .entries()
.iter() .iter()
.filter_map(|i| { .filter_map(|i| match i.external() {
match i.external() { External::Memory(m) => Some((i, m)),
External::Memory(m) => Some((i, m)), _ => None,
_ => None, }).next()
}
})
.next()
.expect("must import memory"); .expect("must import memory");
assert_eq!(entry.module(), "env"); assert_eq!(entry.module(), "env");
assert_eq!(entry.field(), "memory"); assert_eq!(entry.field(), "memory");
@ -1822,8 +1832,11 @@ impl<'a, 'b> SubContext<'a, 'b> {
}; };
let (js, ts, js_doc) = Js2Rust::new(function_name, self.cx) let (js, ts, js_doc) = Js2Rust::new(function_name, self.cx)
.method(export.method, export.consumed) .method(export.method, export.consumed)
.constructor(if export.is_constructor { Some(class_name) } else { None }) .constructor(if export.is_constructor {
.process(descriptor.unwrap_function())? Some(class_name)
} else {
None
}).process(descriptor.unwrap_function())?
.finish("", &format!("wasm.{}", wasm_name)); .finish("", &format!("wasm.{}", wasm_name));
let class = self let class = self
@ -1837,8 +1850,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
if export.is_constructor { if export.is_constructor {
if class.has_constructor { if class.has_constructor {
bail!("found duplicate constructor `{}`", bail!("found duplicate constructor `{}`", export.function.name);
export.function.name);
} }
class.has_constructor = true; class.has_constructor = true;
} else if !export.method { } else if !export.method {
@ -1871,10 +1883,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
} }
shared::ImportKind::Type(ref ty) => { shared::ImportKind::Type(ref ty) => {
self.generate_import_type(import, ty).with_context(|_| { self.generate_import_type(import, ty).with_context(|_| {
format!( format!("failed to generate bindings for JS import `{}`", ty.name,)
"failed to generate bindings for JS import `{}`",
ty.name,
)
})?; })?;
} }
shared::ImportKind::Enum(_) => {} shared::ImportKind::Enum(_) => {}
@ -1890,7 +1899,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
// The same static can be imported in multiple locations, so only // The same static can be imported in multiple locations, so only
// generate bindings once for it. // generate bindings once for it.
if !self.cx.imported_statics.insert(import.shim.clone()) { if !self.cx.imported_statics.insert(import.shim.clone()) {
return Ok(()) return Ok(());
} }
// TODO: should support more types to import here // TODO: should support more types to import here
@ -1962,7 +1971,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
format!("{}_target", import.shim) format!("{}_target", import.shim)
} else { } else {
name name
}) });
} }
}; };
@ -2052,9 +2061,15 @@ impl<'a, 'b> SubContext<'a, 'b> {
class, location, s, binding, class, location, s, binding,
) )
} }
shared::OperationKind::IndexingGetter => panic!("indexing getter should be structural"), shared::OperationKind::IndexingGetter => {
shared::OperationKind::IndexingSetter => panic!("indexing setter should be structural"), panic!("indexing getter should be structural")
shared::OperationKind::IndexingDeleter => panic!("indexing deleter should be structural"), }
shared::OperationKind::IndexingSetter => {
panic!("indexing setter should be structural")
}
shared::OperationKind::IndexingDeleter => {
panic!("indexing deleter should be structural")
}
} }
}; };
@ -2090,7 +2105,8 @@ impl<'a, 'b> SubContext<'a, 'b> {
} }
let name = self.import_name(info, &import.name)?; let name = self.import_name(info, &import.name)?;
self.cx.expose_get_object(); self.cx.expose_get_object();
let body = format!(" let body = format!(
"
function(idx) {{ function(idx) {{
return getObject(idx) instanceof {} ? 1 : 0; return getObject(idx) instanceof {} ? 1 : 0;
}} }}
@ -2139,10 +2155,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
// Figure out what identifier we're importing from the module. If we've // Figure out what identifier we're importing from the module. If we've
// got a namespace we use that, otherwise it's the name specified above. // got a namespace we use that, otherwise it's the name specified above.
let name_to_import = import.js_namespace let name_to_import = import.js_namespace.as_ref().map(|s| &**s).unwrap_or(item);
.as_ref()
.map(|s| &**s)
.unwrap_or(item);
// Here's where it's a bit tricky. We need to make sure that importing // Here's where it's a bit tricky. We need to make sure that importing
// the same identifier from two different modules works, and they're // the same identifier from two different modules works, and they're
@ -2158,7 +2171,10 @@ impl<'a, 'b> SubContext<'a, 'b> {
let use_node_require = self.cx.use_node_require(); let use_node_require = self.cx.use_node_require();
let imported_identifiers = &mut self.cx.imported_identifiers; let imported_identifiers = &mut self.cx.imported_identifiers;
let imports = &mut self.cx.imports; let imports = &mut self.cx.imports;
let identifier = self.cx.imported_names.entry(import.module.clone()) let identifier = self
.cx
.imported_names
.entry(import.module.clone())
.or_insert_with(Default::default) .or_insert_with(Default::default)
.entry(name_to_import.to_string()) .entry(name_to_import.to_string())
.or_insert_with(|| { .or_insert_with(|| {
@ -2170,10 +2186,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
name, module, name_to_import name, module, name_to_import
)); ));
} else if name_to_import == name { } else if name_to_import == name {
imports.push_str(&format!( imports.push_str(&format!("import {{ {} }} from '{}';\n", name, module));
"import {{ {} }} from '{}';\n",
name, module
));
} else { } else {
imports.push_str(&format!( imports.push_str(&format!(
"import {{ {} as {} }} from '{}';\n", "import {{ {} as {} }} from '{}';\n",

View File

@ -109,7 +109,11 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
abi, abi,
abi2, abi2,
func = f, func = f,
prefix = if optional { format!("{} == 0 ? undefined : ", abi) } else { String::new() }, prefix = if optional {
format!("{} == 0 ? undefined : ", abi)
} else {
String::new()
},
)); ));
if !arg.is_by_ref() && !arg.is_clamped_by_ref() { if !arg.is_by_ref() && !arg.is_clamped_by_ref() {
@ -123,9 +127,12 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
abi, abi,
abi2, abi2,
size = ty.size(), size = ty.size(),
start = if optional { format!("if ({} !== 0) {{", abi) } else { String::new() }, start = if optional {
format!("if ({} !== 0) {{", abi)
} else {
String::new()
},
end = if optional { "}" } else { "" }, end = if optional { "}" } else { "" },
)); ));
self.cx.require_internal_export("__wbindgen_free")?; self.cx.require_internal_export("__wbindgen_free")?;
} }
@ -138,11 +145,11 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
if arg.is_anyref() { if arg.is_anyref() {
self.cx.expose_take_object(); self.cx.expose_take_object();
self.js_arguments.push(format!("takeObject({})", abi)); self.js_arguments.push(format!("takeObject({})", abi));
return Ok(()) return Ok(());
} else if arg.is_ref_anyref() { } else if arg.is_ref_anyref() {
self.cx.expose_get_object(); self.cx.expose_get_object();
self.js_arguments.push(format!("getObject({})", abi)); self.js_arguments.push(format!("getObject({})", abi));
return Ok(()) return Ok(());
} }
if optional { if optional {
@ -153,12 +160,13 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
value = value, value = value,
present = abi, present = abi,
)); ));
return Ok(()) return Ok(());
} }
if arg.is_abi_as_u32() { if arg.is_abi_as_u32() {
self.js_arguments.push(format!("{0} === 0xFFFFFF ? undefined : {0}", abi)); self.js_arguments
return Ok(()) .push(format!("{0} === 0xFFFFFF ? undefined : {0}", abi));
return Ok(());
} }
if let Some(signed) = arg.get_64() { if let Some(signed) = arg.get_64() {
@ -189,9 +197,10 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
match *arg { match *arg {
Descriptor::Boolean => { Descriptor::Boolean => {
self.js_arguments.push(format!("{0} === 0xFFFFFF ? undefined : {0} !== 0", abi)); self.js_arguments
return Ok(()) .push(format!("{0} === 0xFFFFFF ? undefined : {0} !== 0", abi));
}, return Ok(());
}
Descriptor::Char => { Descriptor::Char => {
let value = self.shim_argument(); let value = self.shim_argument();
self.js_arguments.push(format!( self.js_arguments.push(format!(
@ -199,9 +208,12 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
value = value, value = value,
present = abi, present = abi,
)); ));
return Ok(()) return Ok(());
}, }
_ => bail!("unsupported optional argument type for calling JS function from Rust: {:?}", arg), _ => bail!(
"unsupported optional argument type for calling JS function from Rust: {:?}",
arg
),
}; };
} }
@ -280,7 +292,10 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
ref d if d.is_number() => abi, ref d if d.is_number() => abi,
Descriptor::Boolean => format!("{} !== 0", abi), Descriptor::Boolean => format!("{} !== 0", abi),
Descriptor::Char => format!("String.fromCodePoint({})", abi), Descriptor::Char => format!("String.fromCodePoint({})", abi),
_ => bail!("unsupported argument type for calling JS function from Rust: {:?}", arg), _ => bail!(
"unsupported argument type for calling JS function from Rust: {:?}",
arg
),
}; };
self.js_arguments.push(invoc_arg); self.js_arguments.push(invoc_arg);
Ok(()) Ok(())
@ -318,8 +333,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
mem[ret / 4] = retptr; mem[ret / 4] = retptr;
mem[ret / 4 + 1] = retlen; mem[ret / 4 + 1] = retlen;
", ",
prelude, prelude, expr
expr
); );
return Ok(()); return Ok(());
} }
@ -334,7 +348,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
} else { } else {
self.ret_expr = "return addHeapObject(JS);".to_string() self.ret_expr = "return addHeapObject(JS);".to_string()
} }
return Ok(()) return Ok(());
} }
if optional { if optional {
if ty.is_wasm_native() { if ty.is_wasm_native() {
@ -411,7 +425,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
return isLikeNone(val) ? 0xFFFFFF : val ? 1 : 0; return isLikeNone(val) ? 0xFFFFFF : val ? 1 : 0;
".to_string(); ".to_string();
return Ok(()); return Ok(());
}, }
Descriptor::Char => { Descriptor::Char => {
self.cx.expose_is_like_none(); self.cx.expose_is_like_none();
self.cx.expose_uint32_memory(); self.cx.expose_uint32_memory();
@ -422,8 +436,11 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
getUint32Memory()[ret / 4 + 1] = isLikeNone(val) ? 0 : val.codePointAt(0); getUint32Memory()[ret / 4 + 1] = isLikeNone(val) ? 0 : val.codePointAt(0);
".to_string(); ".to_string();
return Ok(()); return Ok(());
}, }
_ => bail!("unsupported optional return type for calling JS function from Rust: {:?}", ty), _ => bail!(
"unsupported optional return type for calling JS function from Rust: {:?}",
ty
),
}; };
} }
if ty.is_number() { if ty.is_number() {
@ -474,7 +491,10 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
self.ret_expr = match *ty { self.ret_expr = match *ty {
Descriptor::Boolean => "return JS ? 1 : 0;".to_string(), Descriptor::Boolean => "return JS ? 1 : 0;".to_string(),
Descriptor::Char => "return JS.codePointAt(0);".to_string(), Descriptor::Char => "return JS.codePointAt(0);".to_string(),
_ => bail!("unsupported return type for calling JS function from Rust: {:?}", ty), _ => bail!(
"unsupported return type for calling JS function from Rust: {:?}",
ty
),
}; };
Ok(()) Ok(())
} }
@ -494,7 +514,9 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
let mut invoc = if self.variadic { let mut invoc = if self.variadic {
if self.js_arguments.is_empty() { if self.js_arguments.is_empty() {
return Err(failure::err_msg("a function with no arguments cannot be variadic")); return Err(failure::err_msg(
"a function with no arguments cannot be variadic",
));
} }
let last_arg = self.js_arguments.len() - 1; // check implies >= 0 let last_arg = self.js_arguments.len() - 1; // check implies >= 0
if self.js_arguments.len() != 1 { if self.js_arguments.len() != 1 {
@ -505,16 +527,12 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
invoc, invoc,
self.js_arguments[..last_arg].join(", "), self.js_arguments[..last_arg].join(", "),
self.js_arguments[last_arg], self.js_arguments[last_arg],
) ),
) )
} else { } else {
self.ret_expr.replace( self.ret_expr.replace(
"JS", "JS",
&format!( &format!("{}(...{})", invoc, self.js_arguments[last_arg],),
"{}(...{})",
invoc,
self.js_arguments[last_arg],
)
) )
} }
} else { } else {

View File

@ -1,8 +1,8 @@
#![doc(html_root_url = "https://docs.rs/wasm-bindgen-cli-support/0.2")] #![doc(html_root_url = "https://docs.rs/wasm-bindgen-cli-support/0.2")]
extern crate parity_wasm; extern crate parity_wasm;
extern crate wasm_bindgen_shared as shared;
extern crate serde_json; extern crate serde_json;
extern crate wasm_bindgen_shared as shared;
extern crate wasm_gc; extern crate wasm_gc;
#[macro_use] #[macro_use]
extern crate failure; extern crate failure;
@ -90,7 +90,7 @@ impl Bindgen {
if let Some(module) = (&mut module as &mut Any).downcast_mut::<Module>() { if let Some(module) = (&mut module as &mut Any).downcast_mut::<Module>() {
let blank = Module::new(Vec::new()); let blank = Module::new(Vec::new());
self.input = Input::Module(mem::replace(module, blank), name); self.input = Input::Module(mem::replace(module, blank), name);
return self return self;
} }
self.input = Input::Bytes(into_bytes(module), name); self.input = Input::Bytes(into_bytes(module), name);
@ -213,7 +213,11 @@ impl Bindgen {
cx.finalize(stem)? cx.finalize(stem)?
}; };
let extension = if self.nodejs_experimental_modules { "mjs" } else { "js" }; let extension = if self.nodejs_experimental_modules {
"mjs"
} else {
"js"
};
let js_path = out_dir.join(stem).with_extension(extension); let js_path = out_dir.join(stem).with_extension(extension);
fs::write(&js_path, reset_indentation(&js)) fs::write(&js_path, reset_indentation(&js))
.with_context(|_| format!("failed to write `{}`", js_path.display()))?; .with_context(|_| format!("failed to write `{}`", js_path.display()))?;
@ -251,12 +255,12 @@ impl Bindgen {
if self.nodejs_experimental_modules { if self.nodejs_experimental_modules {
for (i, module) in imports.iter().enumerate() { for (i, module) in imports.iter().enumerate() {
shim.push_str(&format!("import * as import{} from '{}';\n", shim.push_str(&format!("import * as import{} from '{}';\n", i, module));
i, module));
} }
// On windows skip the leading `/` which comes out when we parse a // On windows skip the leading `/` which comes out when we parse a
// url to use `C:\...` instead of `\C:\...` // url to use `C:\...` instead of `\C:\...`
shim.push_str(&format!(" shim.push_str(&format!(
"
import * as path from 'path'; import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import * as url from 'url'; import * as url from 'url';
@ -267,12 +271,17 @@ impl Bindgen {
file = file.substring(1); file = file.substring(1);
}} }}
const bytes = fs.readFileSync(path.join(file, '{}')); const bytes = fs.readFileSync(path.join(file, '{}'));
", path.file_name().unwrap().to_str().unwrap())); ",
path.file_name().unwrap().to_str().unwrap()
));
} else { } else {
shim.push_str(&format!(" shim.push_str(&format!(
"
const path = require('path').join(__dirname, '{}'); const path = require('path').join(__dirname, '{}');
const bytes = require('fs').readFileSync(path); const bytes = require('fs').readFileSync(path);
", path.file_name().unwrap().to_str().unwrap())); ",
path.file_name().unwrap().to_str().unwrap()
));
} }
shim.push_str("let imports = {};\n"); shim.push_str("let imports = {};\n");
for (i, module) in imports.iter().enumerate() { for (i, module) in imports.iter().enumerate() {
@ -387,7 +396,11 @@ fn reset_indentation(s: &str) -> String {
if line.starts_with('}') || (line.ends_with('}') && !line.starts_with('*')) { if line.starts_with('}') || (line.ends_with('}') && !line.starts_with('*')) {
indent = indent.saturating_sub(1); indent = indent.saturating_sub(1);
} }
let extra = if line.starts_with(':') || line.starts_with('?') { 1 } else { 0 }; let extra = if line.starts_with(':') || line.starts_with('?') {
1
} else {
0
};
if !line.is_empty() { if !line.is_empty() {
for _ in 0..indent + extra { for _ in 0..indent + extra {
dst.push_str(" "); dst.push_str(" ");
@ -399,5 +412,5 @@ fn reset_indentation(s: &str) -> String {
indent += 1; indent += 1;
} }
} }
return dst return dst;
} }

View File

@ -1,14 +1,14 @@
use std::env; use std::env;
use std::io::{self, Read}; use std::io::{self, Read};
use std::net::{SocketAddr, TcpListener, TcpStream}; use std::net::{SocketAddr, TcpListener, TcpStream};
use std::path::{PathBuf, Path}; use std::path::{Path, PathBuf};
use std::process::{Child, Command, Stdio}; use std::process::{Child, Command, Stdio};
use std::thread; use std::thread;
use std::time::{Instant, Duration}; use std::time::{Duration, Instant};
use curl::easy::Easy; use curl::easy::Easy;
use failure::{ResultExt, Error}; use failure::{Error, ResultExt};
use serde::{Serialize, Deserialize}; use serde::{Deserialize, Serialize};
use serde_json; use serde_json;
use shell::Shell; use shell::Shell;
@ -22,9 +22,11 @@ use shell::Shell;
/// will return an error if some tests failed. /// will return an error if some tests failed.
pub fn run(server: &SocketAddr, shell: &Shell) -> Result<(), Error> { pub fn run(server: &SocketAddr, shell: &Shell) -> Result<(), Error> {
let (driver, args) = Driver::find()?; let (driver, args) = Driver::find()?;
println!("Running headless tests in {} with `{}`", println!(
driver.browser(), "Running headless tests in {} with `{}`",
driver.path().display()); driver.browser(),
driver.path().display()
);
// Allow tests to run in parallel (in theory) by finding any open port // Allow tests to run in parallel (in theory) by finding any open port
// available for our driver. We can't bind the port for the driver, but // available for our driver. We can't bind the port for the driver, but
@ -47,7 +49,7 @@ pub fn run(server: &SocketAddr, shell: &Shell) -> Result<(), Error> {
while start.elapsed() < max { while start.elapsed() < max {
if TcpStream::connect(&driver_addr).is_ok() { if TcpStream::connect(&driver_addr).is_ok() {
bound = true; bound = true;
break break;
} }
thread::sleep(Duration::from_millis(100)); thread::sleep(Duration::from_millis(100));
} }
@ -94,7 +96,7 @@ pub fn run(server: &SocketAddr, shell: &Shell) -> Result<(), Error> {
let max = Duration::new(20, 0); let max = Duration::new(20, 0);
while start.elapsed() < max { while start.elapsed() < max {
if client.text(&id, &output)?.contains("test result: ") { if client.text(&id, &output)?.contains("test result: ") {
break break;
} }
thread::sleep(Duration::from_millis(100)); thread::sleep(Duration::from_millis(100));
} }
@ -174,30 +176,29 @@ impl Driver {
Some(path) => path, Some(path) => path,
None => continue, None => continue,
}; };
return Ok((ctor(path.into()), env_args(driver))) return Ok((ctor(path.into()), env_args(driver)));
} }
// Next, check PATH. If we can find any supported driver, use that by // Next, check PATH. If we can find any supported driver, use that by
// default. // default.
for path in env::split_paths(&env::var_os("PATH").unwrap_or_default()) { for path in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
let found = drivers let found = drivers.iter().find(|(name, _)| {
.iter() path.join(name)
.find(|(name, _)| { .with_extension(env::consts::EXE_EXTENSION)
path.join(name) .exists()
.with_extension(env::consts::EXE_EXTENSION) });
.exists()
});
let (name, ctor) = match found { let (name, ctor) = match found {
Some(p) => p, Some(p) => p,
None => continue, None => continue,
}; };
return Ok((ctor(name.into()), env_args(name))) return Ok((ctor(name.into()), env_args(name)));
} }
// TODO: download an appropriate driver? How to know which one to // TODO: download an appropriate driver? How to know which one to
// download? // download?
bail!("\ bail!(
"\
failed to find a suitable WebDriver binary to drive headless testing; to failed to find a suitable WebDriver binary to drive headless testing; to
configure the location of the webdriver binary you can use environment configure the location of the webdriver binary you can use environment
variables like `GECKODRIVER=/path/to/geckodriver` or make sure that the binary variables like `GECKODRIVER=/path/to/geckodriver` or make sure that the binary
@ -217,7 +218,8 @@ visit in a web browser, and headless testing should not be used.
If you're still having difficulty resolving this error, please feel free to open If you're still having difficulty resolving this error, please feel free to open
an issue against rustwasm/wasm-bindgen! an issue against rustwasm/wasm-bindgen!
") "
)
} }
fn path(&self) -> &Path { fn path(&self) -> &Path {
@ -320,8 +322,7 @@ impl Client {
fn close_window(&mut self, id: &str) -> Result<(), Error> { fn close_window(&mut self, id: &str) -> Result<(), Error> {
#[derive(Deserialize)] #[derive(Deserialize)]
struct Response { struct Response {}
}
let x: Response = self.delete(&format!("/session/{}/window", id))?; let x: Response = self.delete(&format!("/session/{}/window", id))?;
drop(x); drop(x);
Ok(()) Ok(())
@ -333,8 +334,7 @@ impl Client {
url: String, url: String,
} }
#[derive(Deserialize)] #[derive(Deserialize)]
struct Response { struct Response {}
}
let request = Request { let request = Request {
url: url.to_string(), url: url.to_string(),
@ -367,10 +367,10 @@ impl Client {
value: selector.to_string(), value: selector.to_string(),
}; };
let x: Response = self.post(&format!("/session/{}/element", id), &request)?; let x: Response = self.post(&format!("/session/{}/element", id), &request)?;
Ok(x.value.gecko_reference Ok(x.value
.or(x.value.safari_reference) .gecko_reference
.ok_or(format_err!("failed to find element reference in response"))?) .or(x.value.safari_reference)
.ok_or(format_err!("failed to find element reference in response"))?)
} }
fn text(&mut self, id: &str, element: &str) -> Result<String, Error> { fn text(&mut self, id: &str, element: &str) -> Result<String, Error> {
@ -383,7 +383,8 @@ impl Client {
} }
fn get<U>(&mut self, path: &str) -> Result<U, Error> fn get<U>(&mut self, path: &str) -> Result<U, Error>
where U: for<'a> Deserialize<'a>, where
U: for<'a> Deserialize<'a>,
{ {
debug!("GET {}", path); debug!("GET {}", path);
let result = self.doit(path, Method::Get)?; let result = self.doit(path, Method::Get)?;
@ -391,8 +392,9 @@ impl Client {
} }
fn post<T, U>(&mut self, path: &str, data: &T) -> Result<U, Error> fn post<T, U>(&mut self, path: &str, data: &T) -> Result<U, Error>
where T: Serialize, where
U: for<'a> Deserialize<'a>, T: Serialize,
U: for<'a> Deserialize<'a>,
{ {
let input = serde_json::to_string(data)?; let input = serde_json::to_string(data)?;
debug!("POST {} {}", path, input); debug!("POST {} {}", path, input);
@ -401,7 +403,8 @@ impl Client {
} }
fn delete<U>(&mut self, path: &str) -> Result<U, Error> fn delete<U>(&mut self, path: &str) -> Result<U, Error>
where U: for<'a> Deserialize<'a>, where
U: for<'a> Deserialize<'a>,
{ {
debug!("DELETE {}", path); debug!("DELETE {}", path);
let result = self.doit(path, Method::Delete)?; let result = self.doit(path, Method::Delete)?;
@ -431,7 +434,11 @@ impl Client {
} }
let result = String::from_utf8_lossy(&result); let result = String::from_utf8_lossy(&result);
if self.handle.response_code()? != 200 { if self.handle.response_code()? != 200 {
bail!("non-200 response code: {}\n{}", self.handle.response_code()?, result); bail!(
"non-200 response code: {}\n{}",
self.handle.response_code()?,
result
);
} }
debug!("got: {}", result); debug!("got: {}", result);
Ok(result.into_owned()) Ok(result.into_owned())
@ -475,14 +482,16 @@ struct BackgroundChild<'a> {
} }
impl<'a> BackgroundChild<'a> { impl<'a> BackgroundChild<'a> {
fn spawn(path: &Path, cmd: &mut Command, shell: &'a Shell) fn spawn(
-> Result<BackgroundChild<'a>, Error> path: &Path,
{ cmd: &mut Command,
cmd shell: &'a Shell,
.stdout(Stdio::piped()) ) -> Result<BackgroundChild<'a>, Error> {
cmd.stdout(Stdio::piped())
.stderr(Stdio::piped()) .stderr(Stdio::piped())
.stdin(Stdio::null()); .stdin(Stdio::null());
let mut child = cmd.spawn() let mut child = cmd
.spawn()
.context(format!("failed to spawn {:?} binary", path))?; .context(format!("failed to spawn {:?} binary", path))?;
let mut stdout = child.stdout.take().unwrap(); let mut stdout = child.stdout.take().unwrap();
let mut stderr = child.stderr.take().unwrap(); let mut stderr = child.stderr.take().unwrap();
@ -503,7 +512,7 @@ impl<'a> Drop for BackgroundChild<'a> {
self.child.kill().unwrap(); self.child.kill().unwrap();
let status = self.child.wait().unwrap(); let status = self.child.wait().unwrap();
if !self.print_stdio_on_drop { if !self.print_stdio_on_drop {
return return;
} }
self.shell.clear(); self.shell.clear();

View File

@ -32,8 +32,8 @@ use std::path::PathBuf;
use std::process; use std::process;
use std::thread; use std::thread;
use failure::{ResultExt, Error}; use failure::{Error, ResultExt};
use parity_wasm::elements::{Module, Deserialize, Section}; use parity_wasm::elements::{Deserialize, Module, Section};
use wasm_bindgen_cli_support::Bindgen; use wasm_bindgen_cli_support::Bindgen;
mod headless; mod headless;
@ -67,33 +67,29 @@ fn rmain() -> Result<(), Error> {
// Assume a cargo-like directory layout and generate output at // Assume a cargo-like directory layout and generate output at
// `target/wasm32-unknown-unknown/wbg-tmp/...` // `target/wasm32-unknown-unknown/wbg-tmp/...`
let tmpdir = wasm_file_to_test.parent() // chop off file name let tmpdir = wasm_file_to_test
.and_then(|p| p.parent()) // chop off `deps` .parent() // chop off file name
.and_then(|p| p.parent()) // chop off `debug` .and_then(|p| p.parent()) // chop off `deps`
.and_then(|p| p.parent()) // chop off `debug`
.map(|p| p.join("wbg-tmp")) .map(|p| p.join("wbg-tmp"))
.ok_or_else(|| { .ok_or_else(|| format_err!("file to test doesn't follow the expected Cargo conventions"))?;
format_err!("file to test doesn't follow the expected Cargo conventions")
})?;
// Make sure there's no stale state from before // Make sure there's no stale state from before
drop(fs::remove_dir_all(&tmpdir)); drop(fs::remove_dir_all(&tmpdir));
fs::create_dir(&tmpdir) fs::create_dir(&tmpdir).context("creating temporary directory")?;
.context("creating temporary directory")?;
let module = "wasm-bindgen-test"; let module = "wasm-bindgen-test";
// Collect all tests that the test harness is supposed to run. We assume // Collect all tests that the test harness is supposed to run. We assume
// that any exported function with the prefix `__wbg_test` is a test we need // that any exported function with the prefix `__wbg_test` is a test we need
// to execute. // to execute.
let wasm = fs::read(&wasm_file_to_test) let wasm = fs::read(&wasm_file_to_test).context("failed to read wasm file")?;
.context("failed to read wasm file")?; let wasm = Module::deserialize(&mut &wasm[..]).context("failed to deserialize wasm module")?;
let wasm = Module::deserialize(&mut &wasm[..])
.context("failed to deserialize wasm module")?;
let mut tests = Vec::new(); let mut tests = Vec::new();
if let Some(exports) = wasm.export_section() { if let Some(exports) = wasm.export_section() {
for export in exports.entries() { for export in exports.entries() {
if !export.field().starts_with("__wbg_test") { if !export.field().starts_with("__wbg_test") {
continue continue;
} }
tests.push(export.field().to_string()); tests.push(export.field().to_string());
} }
@ -104,7 +100,7 @@ fn rmain() -> Result<(), Error> {
// early saying everything is ok. // early saying everything is ok.
if tests.len() == 0 { if tests.len() == 0 {
println!("no tests to run!"); println!("no tests to run!");
return Ok(()) return Ok(());
} }
// Figure out if this tests is supposed to execute in node.js or a browser. // Figure out if this tests is supposed to execute in node.js or a browser.
@ -118,7 +114,7 @@ fn rmain() -> Result<(), Error> {
_ => continue, _ => continue,
}; };
if custom.name() != "__wasm_bindgen_test_unstable" { if custom.name() != "__wasm_bindgen_test_unstable" {
continue continue;
} }
node = !custom.payload().contains(&0x01); node = !custom.payload().contains(&0x01);
} }
@ -138,7 +134,7 @@ fn rmain() -> Result<(), Error> {
// If we're executing in node.js, that module will take it from here. // If we're executing in node.js, that module will take it from here.
if node { if node {
return node::execute(&module, &tmpdir, &args.collect::<Vec<_>>(), &tests) return node::execute(&module, &tmpdir, &args.collect::<Vec<_>>(), &tests);
} }
// Otherwise we're executing in a browser. Spawn a server which serves up // Otherwise we're executing in a browser. Spawn a server which serves up
@ -160,13 +156,16 @@ fn rmain() -> Result<(), Error> {
// TODO: eventually we should provide the ability to exit at some point // TODO: eventually we should provide the ability to exit at some point
// (gracefully) here, but for now this just runs forever. // (gracefully) here, but for now this just runs forever.
if !headless { if !headless {
println!("Interactive browsers tests are now available at http://{}", addr); println!(
"Interactive browsers tests are now available at http://{}",
addr
);
println!(""); println!("");
println!("Note that interactive mode is enabled because `NO_HEADLESS`"); println!("Note that interactive mode is enabled because `NO_HEADLESS`");
println!("is specified in the environment of this process. Once you're"); println!("is specified in the environment of this process. Once you're");
println!("done with testing you'll need to kill this server with"); println!("done with testing you'll need to kill this server with");
println!("Ctrl-C."); println!("Ctrl-C.");
return Ok(srv.run()) return Ok(srv.run());
} }
thread::spawn(|| srv.run()); thread::spawn(|| srv.run());

View File

@ -4,12 +4,16 @@ use std::fs;
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
use failure::{ResultExt, Error}; use failure::{Error, ResultExt};
pub fn execute(module: &str, tmpdir: &Path, args: &[OsString], tests: &[String]) pub fn execute(
-> Result<(), Error> module: &str,
{ tmpdir: &Path,
let mut js_to_execute = format!(r#" args: &[OsString],
tests: &[String],
) -> Result<(), Error> {
let mut js_to_execute = format!(
r#"
const {{ exit }} = require('process'); const {{ exit }} = require('process');
let console_log_redirect = null; let console_log_redirect = null;
@ -68,17 +72,18 @@ pub fn execute(module: &str, tmpdir: &Path, args: &[OsString], tests: &[String])
js_to_execute.push_str(&format!("tests.push('{}')\n", test)); js_to_execute.push_str(&format!("tests.push('{}')\n", test));
} }
// And as a final addendum, exit with a nonzero code if any tests fail. // And as a final addendum, exit with a nonzero code if any tests fail.
js_to_execute.push_str(" js_to_execute.push_str(
"
main(tests) main(tests)
.catch(e => { .catch(e => {
console.error(e); console.error(e);
exit(1); exit(1);
}); });
"); ",
);
let js_path = tmpdir.join("run.js"); let js_path = tmpdir.join("run.js");
fs::write(&js_path, js_to_execute) fs::write(&js_path, js_to_execute).context("failed to write JS file")?;
.context("failed to write JS file")?;
// Augment `NODE_PATH` so things like `require("tests/my-custom.js")` work // Augment `NODE_PATH` so things like `require("tests/my-custom.js")` work
// and Rust code can import from custom JS shims. This is a bit of a hack // and Rust code can import from custom JS shims. This is a bit of a hack
@ -91,14 +96,16 @@ pub fn execute(module: &str, tmpdir: &Path, args: &[OsString], tests: &[String])
Command::new("node") Command::new("node")
.env("NODE_PATH", env::join_paths(&path).unwrap()) .env("NODE_PATH", env::join_paths(&path).unwrap())
.arg(&js_path) .arg(&js_path)
.args(args) .args(args),
) )
} }
#[cfg(unix)] #[cfg(unix)]
fn exec(cmd: &mut Command) -> Result<(), Error> { fn exec(cmd: &mut Command) -> Result<(), Error> {
use std::os::unix::prelude::*; use std::os::unix::prelude::*;
Err(Error::from(cmd.exec()).context("failed to execute `node`").into()) Err(Error::from(cmd.exec())
.context("failed to execute `node`")
.into())
} }
#[cfg(windows)] #[cfg(windows)]

View File

@ -1,10 +1,10 @@
use std::ffi::OsString; use std::ffi::OsString;
use std::path::Path;
use std::fs; use std::fs;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::path::Path;
use failure::{ResultExt, Error}; use failure::{Error, ResultExt};
use rouille::{self, Response, Request, Server}; use rouille::{self, Request, Response, Server};
use wasm_bindgen_cli_support::wasm2es6js::Config; use wasm_bindgen_cli_support::wasm2es6js::Config;
pub fn spawn( pub fn spawn(
@ -15,7 +15,8 @@ pub fn spawn(
args: &[OsString], args: &[OsString],
tests: &[String], tests: &[String],
) -> Result<Server<impl Fn(&Request) -> Response + Send + Sync>, Error> { ) -> Result<Server<impl Fn(&Request) -> Response + Send + Sync>, Error> {
let mut js_to_execute = format!(r#" let mut js_to_execute = format!(
r#"
import {{ Context, __wbgtest_console_log, __wbgtest_console_error }} from './{0}'; import {{ Context, __wbgtest_console_log, __wbgtest_console_error }} from './{0}';
import * as wasm from './{0}_bg'; import * as wasm from './{0}_bg';
@ -52,8 +53,7 @@ pub fn spawn(
js_to_execute.push_str("main(tests);\n"); js_to_execute.push_str("main(tests);\n");
let js_path = tmpdir.join("run.js"); let js_path = tmpdir.join("run.js");
fs::write(&js_path, js_to_execute) fs::write(&js_path, js_to_execute).context("failed to write JS file")?;
.context("failed to write JS file")?;
// No browser today supports a wasm file as ES modules natively, so we need // No browser today supports a wasm file as ES modules natively, so we need
// to shim it. Use `wasm2es6js` here to fetch an appropriate URL and look // to shim it. Use `wasm2es6js` here to fetch an appropriate URL and look
@ -69,8 +69,7 @@ pub fn spawn(
.fetch(Some(format!("/{}", wasm_name))) .fetch(Some(format!("/{}", wasm_name)))
.generate(&wasm)?; .generate(&wasm)?;
let js = output.js()?; let js = output.js()?;
fs::write(tmpdir.join(format!("{}_bg.js", module)), js) fs::write(tmpdir.join(format!("{}_bg.js", module)), js).context("failed to write JS file")?;
.context("failed to write JS file")?;
// For now, always run forever on this port. We may update this later! // For now, always run forever on this port. We may update this later!
let tmpdir = tmpdir.to_path_buf(); let tmpdir = tmpdir.to_path_buf();
@ -85,7 +84,7 @@ pub fn spawn(
} else { } else {
include_str!("index.html") include_str!("index.html")
}; };
return Response::from_data("text/html", s) return Response::from_data("text/html", s);
} }
// Otherwise we need to find the asset here. It may either be in our // Otherwise we need to find the asset here. It may either be in our
@ -98,14 +97,14 @@ pub fn spawn(
// Make sure browsers don't cache anything (Chrome appeared to with this // Make sure browsers don't cache anything (Chrome appeared to with this
// header?) // header?)
response.headers.retain(|(k, _)| k != "Cache-Control"); response.headers.retain(|(k, _)| k != "Cache-Control");
return response return response;
}).map_err(|e| format_err!("{}", e))?; }).map_err(|e| format_err!("{}", e))?;
return Ok(srv); return Ok(srv);
fn try_asset(request: &Request, dir: &Path) -> Response { fn try_asset(request: &Request, dir: &Path) -> Response {
let response = rouille::match_assets(request, dir); let response = rouille::match_assets(request, dir);
if response.is_success() { if response.is_success() {
return response return response;
} }
// When a browser is doing ES imports it's using the directives we // When a browser is doing ES imports it's using the directives we
@ -117,14 +116,15 @@ pub fn spawn(
let new_request = Request::fake_http( let new_request = Request::fake_http(
request.method(), request.method(),
format!("{}.js", request.url()), format!("{}.js", request.url()),
request.headers() request
.headers()
.map(|(a, b)| (a.to_string(), b.to_string())) .map(|(a, b)| (a.to_string(), b.to_string()))
.collect(), .collect(),
Vec::new(), Vec::new(),
); );
let response = rouille::match_assets(&new_request, dir); let response = rouille::match_assets(&new_request, dir);
if response.is_success() { if response.is_success() {
return response return response;
} }
} }
} }

View File

@ -2,8 +2,7 @@ const WIDTH: usize = 50;
use std::io::{self, Write}; use std::io::{self, Write};
pub struct Shell { pub struct Shell {}
}
impl Shell { impl Shell {
pub fn new() -> Shell { pub fn new() -> Shell {
@ -11,11 +10,7 @@ impl Shell {
} }
pub fn status(&self, s: &str) { pub fn status(&self, s: &str) {
let s = if s.len() > WIDTH { let s = if s.len() > WIDTH { &s[..WIDTH] } else { s };
&s[..WIDTH]
} else {
s
};
print!("{:<1$}\r", s, WIDTH); print!("{:<1$}\r", s, WIDTH);
io::stdout().flush().unwrap(); io::stdout().flush().unwrap();
} }

View File

@ -67,8 +67,7 @@ fn rmain(args: &Args) -> Result<(), Error> {
if let Some(ref p) = args.flag_output { if let Some(ref p) = args.flag_output {
let dst = p.with_extension("d.ts"); let dst = p.with_extension("d.ts");
let ts = object.typescript(); let ts = object.typescript();
fs::write(&dst, ts) fs::write(&dst, ts).with_context(|_| format!("failed to write `{}`", dst.display()))?;
.with_context(|_| format!("failed to write `{}`", dst.display()))?;
} }
} }
@ -76,8 +75,7 @@ fn rmain(args: &Args) -> Result<(), Error> {
match args.flag_output { match args.flag_output {
Some(ref p) => { Some(ref p) => {
fs::write(p, js) fs::write(p, js).with_context(|_| format!("failed to write `{}`", p.display()))?;
.with_context(|_| format!("failed to write `{}`", p.display()))?;
} }
None => { None => {
println!("{}", js); println!("{}", js);

View File

@ -104,13 +104,13 @@
#![deny(missing_docs)] #![deny(missing_docs)]
extern crate futures; extern crate futures;
extern crate wasm_bindgen;
extern crate js_sys; extern crate js_sys;
extern crate wasm_bindgen;
use std::cell::{Cell, RefCell};
use std::sync::Arc; use std::sync::Arc;
use std::cell::{RefCell, Cell};
use futures::executor::{self, Spawn, Notify}; use futures::executor::{self, Notify, Spawn};
use futures::prelude::*; use futures::prelude::*;
use futures::sync::oneshot; use futures::sync::oneshot;
use js_sys::{Function, Promise}; use js_sys::{Function, Promise};
@ -170,11 +170,11 @@ impl Future for JsFuture {
// till we're done, so we dont need to handle that. // till we're done, so we dont need to handle that.
if let Ok(Async::Ready(val)) = self.resolved.poll() { if let Ok(Async::Ready(val)) = self.resolved.poll() {
drop(self.callbacks.take()); drop(self.callbacks.take());
return Ok(val.into()) return Ok(val.into());
} }
if let Ok(Async::Ready(val)) = self.rejected.poll() { if let Ok(Async::Ready(val)) = self.rejected.poll() {
drop(self.callbacks.take()); drop(self.callbacks.take());
return Err(val) return Err(val);
} }
Ok(Async::NotReady) Ok(Async::NotReady)
} }
@ -201,7 +201,8 @@ impl Future for JsFuture {
/// resolve**. Instead it will be a leaked promise. This is an unfortunate /// resolve**. Instead it will be a leaked promise. This is an unfortunate
/// limitation of wasm currently that's hoped to be fixed one day! /// limitation of wasm currently that's hoped to be fixed one day!
pub fn future_to_promise<F>(future: F) -> Promise pub fn future_to_promise<F>(future: F) -> Promise
where F: Future<Item = JsValue, Error = JsValue> + 'static, where
F: Future<Item = JsValue, Error = JsValue> + 'static,
{ {
_future_to_promise(Box::new(future)) _future_to_promise(Box::new(future))
} }
@ -310,7 +311,7 @@ fn _future_to_promise(future: Box<Future<Item = JsValue, Error = JsValue>>) -> P
// our `Waiting` state, and resume the polling process // our `Waiting` state, and resume the polling process
State::Polling => { State::Polling => {
me.notified.set(State::Waiting(me.clone())); me.notified.set(State::Waiting(me.clone()));
break break;
} }
State::Waiting(_) => panic!("shouldn't see waiting state!"), State::Waiting(_) => panic!("shouldn't see waiting state!"),
@ -328,7 +329,7 @@ fn _future_to_promise(future: Box<Future<Item = JsValue, Error = JsValue>>) -> P
}; };
drop(f.call1(&JsValue::undefined(), &val)); drop(f.call1(&JsValue::undefined(), &val));
break break;
} }
} }
} }

View File

@ -1,22 +1,22 @@
#![cfg(target_arch = "wasm32")] #![cfg(target_arch = "wasm32")]
extern crate wasm_bindgen_test;
extern crate wasm_bindgen;
extern crate js_sys; extern crate js_sys;
extern crate wasm_bindgen;
extern crate wasm_bindgen_test;
use js_sys::Array;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use js_sys::Array;
wasm_bindgen_test_configure!(run_in_browser); wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen(module = "./tests/headless.js")] #[wasm_bindgen(module = "./tests/headless.js")]
extern { extern "C" {
fn is_array_values_supported()-> bool; fn is_array_values_supported() -> bool;
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
type ValuesIterator; type ValuesIterator;
#[wasm_bindgen(method, structural)] #[wasm_bindgen(method, structural)]
fn next(this: &ValuesIterator) -> IterNext; fn next(this: &ValuesIterator) -> IterNext;
@ -32,7 +32,7 @@ extern {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn array_iterator_values() { fn array_iterator_values() {
if !is_array_values_supported() { if !is_array_values_supported() {
return return;
} }
let array = Array::new(); let array = Array::new();
array.push(&8.into()); array.push(&8.into());

View File

@ -1,7 +1,7 @@
use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*;
macro_rules! js_array { macro_rules! js_array {
($($e:expr),*) => ({ ($($e:expr),*) => ({
@ -31,10 +31,16 @@ fn filter() {
assert!(array.filter(&mut |x, _, _| x.as_f64().is_some()).length() == 0); assert!(array.filter(&mut |x, _, _| x.as_f64().is_some()).length() == 0);
let array = js_array![1, 2, 3, 4]; let array = js_array![1, 2, 3, 4];
assert_eq!(array.filter(&mut |x, _, _| x.as_f64().is_some()).length(), 4); assert_eq!(
array.filter(&mut |x, _, _| x.as_f64().is_some()).length(),
4
);
let array = js_array!["a", 1, "b", 2]; let array = js_array!["a", 1, "b", 2];
assert_eq!(array.filter(&mut |x, _, _| x.as_f64().is_some()).length(), 2); assert_eq!(
array.filter(&mut |x, _, _| x.as_f64().is_some()).length(),
2
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
@ -223,14 +229,20 @@ fn every() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn find() { fn find() {
let even = js_array![2, 4, 6, 8]; let even = js_array![2, 4, 6, 8];
assert_eq!(even.find(&mut |x, _, _| x.as_f64().unwrap() % 2.0 == 0.0), 2); assert_eq!(
even.find(&mut |x, _, _| x.as_f64().unwrap() % 2.0 == 0.0),
2
);
let odd = js_array![1, 3, 5, 7]; let odd = js_array![1, 3, 5, 7];
assert_eq!( assert_eq!(
odd.find(&mut |x, _, _| x.as_f64().unwrap() % 2.0 == 0.0), odd.find(&mut |x, _, _| x.as_f64().unwrap() % 2.0 == 0.0),
JsValue::undefined(), JsValue::undefined(),
); );
let mixed = js_array![3, 5, 7, 10]; let mixed = js_array![3, 5, 7, 10];
assert_eq!(mixed.find(&mut |x, _, _| x.as_f64().unwrap() % 2.0 == 0.0), 10); assert_eq!(
mixed.find(&mut |x, _, _| x.as_f64().unwrap() % 2.0 == 0.0),
10
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
@ -242,38 +254,43 @@ fn map() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn reduce() { fn reduce() {
let arr = js_array!["0", "1", "2", "3", "4"] let arr = js_array!["0", "1", "2", "3", "4"].reduce(
.reduce( &mut |ac, cr, _, _| {
&mut |ac, cr, _, _| { format!("{}{}", &ac.as_string().unwrap(), &cr.as_string().unwrap()).into()
format!("{}{}", &ac.as_string().unwrap(), &cr.as_string().unwrap()) },
.into() &"".into(),
}, );
&"".into(),
);
assert_eq!(arr, "01234"); assert_eq!(arr, "01234");
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn reduce_right() { fn reduce_right() {
let arr = js_array!["0", "1", "2", "3", "4"] let arr = js_array!["0", "1", "2", "3", "4"].reduce_right(
.reduce_right( &mut |ac, cr, _, _| {
&mut |ac, cr, _, _| { format!("{}{}", &ac.as_string().unwrap(), &cr.as_string().unwrap()).into()
format!("{}{}", &ac.as_string().unwrap(), &cr.as_string().unwrap()) },
.into() &"".into(),
}, );
&"".into(),
);
assert_eq!(arr, "43210"); assert_eq!(arr, "43210");
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn find_index() { fn find_index() {
let even = js_array![2, 4, 6, 8]; let even = js_array![2, 4, 6, 8];
assert_eq!(even.find_index(&mut |e, _, _| e.as_f64().unwrap() % 2. == 0.), 0); assert_eq!(
even.find_index(&mut |e, _, _| e.as_f64().unwrap() % 2. == 0.),
0
);
let odd = js_array![1, 3, 5, 7]; let odd = js_array![1, 3, 5, 7];
assert_eq!(odd.find_index(&mut |e, _, _| e.as_f64().unwrap() % 2. == 0.), -1); assert_eq!(
odd.find_index(&mut |e, _, _| e.as_f64().unwrap() % 2. == 0.),
-1
);
let mixed = js_array![3, 5, 7, 10]; let mixed = js_array![3, 5, 7, 10];
assert_eq!(mixed.find_index(&mut |e, _, _| e.as_f64().unwrap() % 2. == 0.), 3); assert_eq!(
mixed.find_index(&mut |e, _, _| e.as_f64().unwrap() % 2. == 0.),
3
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
@ -287,11 +304,9 @@ fn to_locale_string() {
fn for_each() { fn for_each() {
fn sum_indices_of_evens(array: &Array) -> u32 { fn sum_indices_of_evens(array: &Array) -> u32 {
let mut res = 0; let mut res = 0;
array.for_each(&mut |elem: JsValue, i, _| { array.for_each(&mut |elem: JsValue, i, _| match elem.as_f64() {
match elem.as_f64() { Some(val) if val % 2. == 0. => res += i,
Some(val) if val % 2. == 0. => res += i, _ => {}
_ => { }
}
}); });
res res
} }

View File

@ -1,7 +1,7 @@
use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn new() { fn new() {

View File

@ -1,6 +1,6 @@
use js_sys::*;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn keys() { fn keys() {

View File

@ -1,7 +1,7 @@
use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn new_undefined() { fn new_undefined() {

View File

@ -1,7 +1,7 @@
use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn get_date() { fn get_date() {
@ -343,7 +343,10 @@ fn to_date_string() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn to_iso_string() { fn to_iso_string() {
let date = Date::new(&"05 October 2011 14:48 UTC".into()); let date = Date::new(&"05 October 2011 14:48 UTC".into());
assert_eq!(JsValue::from(date.to_iso_string()), "2011-10-05T14:48:00.000Z"); assert_eq!(
JsValue::from(date.to_iso_string()),
"2011-10-05T14:48:00.000Z"
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]

View File

@ -1,7 +1,7 @@
use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn new() { fn new() {
@ -34,7 +34,10 @@ fn to_string() {
let error = Error::new("error message 1"); let error = Error::new("error message 1");
assert_eq!(JsValue::from(error.to_string()), "Error: error message 1"); assert_eq!(JsValue::from(error.to_string()), "Error: error message 1");
error.set_name("error_name_1"); error.set_name("error_name_1");
assert_eq!(JsValue::from(error.to_string()), "error_name_1: error message 1"); assert_eq!(
JsValue::from(error.to_string()),
"error_name_1: error message 1"
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]

View File

@ -1,7 +1,7 @@
use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*;
// Note: This error is not thrown any more, so there are no tests that will generate this error. // Note: This error is not thrown any more, so there are no tests that will generate this error.
// Instead we just have to manually construct it // Instead we just have to manually construct it
@ -40,12 +40,17 @@ fn set_name() {
fn to_string() { fn to_string() {
let error = EvalError::new("error message 1"); let error = EvalError::new("error message 1");
let base_error: &Error = error.dyn_ref().unwrap(); let base_error: &Error = error.dyn_ref().unwrap();
assert_eq!(JsValue::from(base_error.to_string()), "EvalError: error message 1"); assert_eq!(
JsValue::from(base_error.to_string()),
"EvalError: error message 1"
);
base_error.set_name("error_name_1"); base_error.set_name("error_name_1");
assert_eq!(JsValue::from(base_error.to_string()), "error_name_1: error message 1"); assert_eq!(
JsValue::from(base_error.to_string()),
"error_name_1: error message 1"
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn evalerror_inheritance() { fn evalerror_inheritance() {
let error = EvalError::new("some message"); let error = EvalError::new("some message");

View File

@ -1,10 +1,10 @@
use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*; use js_sys::*;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_test::*;
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(js_name = max, js_namespace = Math)] #[wasm_bindgen(js_name = max, js_namespace = Math)]
static MAX: Function; static MAX: Function;
@ -31,7 +31,7 @@ fn apply() {
} }
#[wasm_bindgen(module = "tests/wasm/Function.js")] #[wasm_bindgen(module = "tests/wasm/Function.js")]
extern { extern "C" {
fn get_function_to_bind() -> Function; fn get_function_to_bind() -> Function;
fn get_value_to_bind_to() -> JsValue; fn get_value_to_bind_to() -> JsValue;
fn call_function(f: Function) -> JsValue; fn call_function(f: Function) -> JsValue;

View File

@ -1,10 +1,10 @@
use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*; use js_sys::*;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_test::*;
#[wasm_bindgen(module = "tests/wasm/Generator.js")] #[wasm_bindgen(module = "tests/wasm/Generator.js")]
extern { extern "C" {
fn one_two_generator() -> Generator; fn one_two_generator() -> Generator;
fn dummy_generator() -> Generator; fn dummy_generator() -> Generator;
fn broken_generator() -> Generator; fn broken_generator() -> Generator;
@ -61,6 +61,6 @@ fn throw() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn generator_inheritance() { fn generator_inheritance() {
let gen = dummy_generator(); let gen = dummy_generator();
assert!(gen.is_instance_of::<Object>()); assert!(gen.is_instance_of::<Object>());
} }

View File

@ -1,6 +1,6 @@
use js_sys::*;
use wasm_bindgen::{JsCast, JsValue}; use wasm_bindgen::{JsCast, JsValue};
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn get_canonical_locales() { fn get_canonical_locales() {

View File

@ -30,7 +30,19 @@ fn try_iter_handles_iteration_protocol() {
assert!(try_iter(&get_not_iterable()).unwrap().is_none()); assert!(try_iter(&get_not_iterable()).unwrap().is_none());
assert!(try_iter(&get_symbol_iterator_throws()).is_err()); assert!(try_iter(&get_symbol_iterator_throws()).is_err());
assert!(try_iter(&get_symbol_iterator_not_function()).unwrap().is_none()); assert!(
assert!(try_iter(&get_symbol_iterator_returns_not_object()).unwrap().is_none()); try_iter(&get_symbol_iterator_not_function())
assert!(try_iter(&get_symbol_iterator_returns_object_without_next()).unwrap().is_none()); .unwrap()
.is_none()
);
assert!(
try_iter(&get_symbol_iterator_returns_not_object())
.unwrap()
.is_none()
);
assert!(
try_iter(&get_symbol_iterator_returns_object_without_next())
.unwrap()
.is_none()
);
} }

View File

@ -1,11 +1,10 @@
use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*; use js_sys::*;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_test::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn parse_array() { fn parse_array() {
let js_array = JSON::parse("[1, 2, 3]").unwrap();; let js_array = JSON::parse("[1, 2, 3]").unwrap();;
assert!(Array::is_array(&js_array)); assert!(Array::is_array(&js_array));
@ -14,12 +13,10 @@ fn parse_array() {
assert_eq!(array.pop(), 3); assert_eq!(array.pop(), 3);
assert_eq!(array.pop(), 2); assert_eq!(array.pop(), 2);
assert_eq!(array.pop(), 1); assert_eq!(array.pop(), 1);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn parse_object() { fn parse_object() {
let js_object = JSON::parse("{\"x\": 5, \"y\": true, \"z\": [\"foo\", \"bar\"]}").unwrap(); let js_object = JSON::parse("{\"x\": 5, \"y\": true, \"z\": [\"foo\", \"bar\"]}").unwrap();
assert!(js_object.is_object()); assert!(js_object.is_object());
@ -45,7 +42,6 @@ fn parse_object() {
assert!(Number::is_integer(&x)); assert!(Number::is_integer(&x));
let x_num = Number::new(&x); let x_num = Number::new(&x);
assert_eq!(x_num.value_of(), 5.0); assert_eq!(x_num.value_of(), 5.0);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
@ -86,7 +82,7 @@ fn stringify_error() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn json_extends() { fn json_extends() {
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(js_name = JSON)] #[wasm_bindgen(js_name = JSON)]
static json: JSON; static json: JSON;
} }

View File

@ -1,11 +1,11 @@
use wasm_bindgen::JsValue; use js_sys::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use js_sys::*;
#[wasm_bindgen(module = "tests/wasm/JsString.js")] #[wasm_bindgen(module = "tests/wasm/JsString.js")]
extern { extern "C" {
fn new_string_object() -> JsValue; fn new_string_object() -> JsValue;
fn get_replacer_function() -> Function; fn get_replacer_function() -> Function;
} }
@ -55,7 +55,10 @@ fn concat() {
let s = JsString::from("Hello ").concat(&"World".into()); let s = JsString::from("Hello ").concat(&"World".into());
assert_eq!(JsValue::from(s), "Hello World"); assert_eq!(JsValue::from(s), "Hello World");
let foo = JsString::from("foo"); let foo = JsString::from("foo");
assert_eq!(JsValue::from(foo.concat(&Object::new().into())), "foo[object Object]"); assert_eq!(
JsValue::from(foo.concat(&Object::new().into())),
"foo[object Object]"
);
assert_eq!(JsValue::from(foo.concat(&Array::new().into())), "foo"); assert_eq!(JsValue::from(foo.concat(&Array::new().into())), "foo");
assert_eq!(JsValue::from(foo.concat(&JsValue::null())), "foonull"); assert_eq!(JsValue::from(foo.concat(&JsValue::null())), "foonull");
assert_eq!(JsValue::from(foo.concat(&true.into())), "footrue"); assert_eq!(JsValue::from(foo.concat(&true.into())), "footrue");
@ -76,27 +79,38 @@ fn ends_with() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn from_char_code() { fn from_char_code() {
let s = "½+¾="; let s = "½+¾=";
let codes : Vec<u32> = s.chars() let codes: Vec<u32> = s.chars().map(|char| char as u32).collect();
.map(|char| char as u32)
.collect();
assert_eq!(JsString::from_char_code1(codes[0]), "½"); assert_eq!(JsString::from_char_code1(codes[0]), "½");
assert_eq!(JsString::from_char_code2(codes[0], codes[1]), "½+"); assert_eq!(JsString::from_char_code2(codes[0], codes[1]), "½+");
assert_eq!(JsString::from_char_code3(codes[0], codes[1], codes[2]), "½+¾"); assert_eq!(
assert_eq!(JsString::from_char_code4(codes[0], codes[1], codes[2], codes[3]), "½+¾="); JsString::from_char_code3(codes[0], codes[1], codes[2]),
"½+¾"
);
assert_eq!(
JsString::from_char_code4(codes[0], codes[1], codes[2], codes[3]),
"½+¾="
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn from_code_point() { fn from_code_point() {
let s = "☃★♲你"; let s = "☃★♲你";
let codes : Vec<u32> = s.chars() let codes: Vec<u32> = s.chars().map(|char| char as u32).collect();
.map(|char| char as u32)
.collect();
assert_eq!(JsString::from_code_point1(codes[0]).unwrap(), ""); assert_eq!(JsString::from_code_point1(codes[0]).unwrap(), "");
assert_eq!(JsString::from_code_point2(codes[0], codes[1]).unwrap(), "☃★"); assert_eq!(
assert_eq!(JsString::from_code_point3(codes[0], codes[1], codes[2]).unwrap(), "☃★♲"); JsString::from_code_point2(codes[0], codes[1]).unwrap(),
assert_eq!(JsString::from_code_point4(codes[0], codes[1], codes[2], codes[3]).unwrap(), "☃★♲你"); "☃★"
);
assert_eq!(
JsString::from_code_point3(codes[0], codes[1], codes[2]).unwrap(),
"☃★♲"
);
assert_eq!(
JsString::from_code_point4(codes[0], codes[1], codes[2], codes[3]).unwrap(),
"☃★♲你"
);
assert!(!JsString::from_code_point1(0x10FFFF).is_err()); assert!(!JsString::from_code_point1(0x10FFFF).is_err());
assert!(JsString::from_code_point1(0x110000).is_err()); assert!(JsString::from_code_point1(0x110000).is_err());
@ -235,8 +249,14 @@ fn match_() {
let result = JsString::from(s).match_(&re); let result = JsString::from(s).match_(&re);
let obj = result.unwrap(); let obj = result.unwrap();
assert_eq!(Reflect::get(obj.as_ref(), &"0".into()).unwrap(), "see Chapter 3.4.5.1"); assert_eq!(
assert_eq!(Reflect::get(obj.as_ref(), &"1".into()).unwrap(), "Chapter 3.4.5.1"); Reflect::get(obj.as_ref(), &"0".into()).unwrap(),
"see Chapter 3.4.5.1"
);
assert_eq!(
Reflect::get(obj.as_ref(), &"1".into()).unwrap(),
"Chapter 3.4.5.1"
);
assert_eq!(Reflect::get(obj.as_ref(), &"2".into()).unwrap(), ".1"); assert_eq!(Reflect::get(obj.as_ref(), &"2".into()).unwrap(), ".1");
assert_eq!(Reflect::get(obj.as_ref(), &"index".into()).unwrap(), 22); assert_eq!(Reflect::get(obj.as_ref(), &"index".into()).unwrap(), 22);
assert_eq!(Reflect::get(obj.as_ref(), &"input".into()).unwrap(), s); assert_eq!(Reflect::get(obj.as_ref(), &"input".into()).unwrap(), s);
@ -248,9 +268,15 @@ fn normalize() {
// TODO: Handle undefined // TODO: Handle undefined
assert_eq!(JsValue::from(js.normalize("NFC")), "\u{1E9B}\u{0323}"); assert_eq!(JsValue::from(js.normalize("NFC")), "\u{1E9B}\u{0323}");
assert_eq!(JsValue::from(js.normalize("NFD")), "\u{017F}\u{0323}\u{0307}"); assert_eq!(
JsValue::from(js.normalize("NFD")),
"\u{017F}\u{0323}\u{0307}"
);
assert_eq!(JsValue::from(js.normalize("NFKC")), "\u{1E69}"); assert_eq!(JsValue::from(js.normalize("NFKC")), "\u{1E69}");
assert_eq!(JsValue::from(js.normalize("NFKD")), "\u{0073}\u{0323}\u{0307}"); assert_eq!(
JsValue::from(js.normalize("NFKD")),
"\u{0073}\u{0323}\u{0307}"
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
@ -287,17 +313,24 @@ fn repeat() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn replace() { fn replace() {
let js = JsString::from("The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?"); let js = JsString::from(
"The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?",
);
let result = js.replace("dog", "ferret"); let result = js.replace("dog", "ferret");
assert_eq!(result, "The quick brown fox jumped over the lazy ferret. If the dog reacted, was it really lazy?"); assert_eq!(
result,
"The quick brown fox jumped over the lazy ferret. If the dog reacted, was it really lazy?"
);
let js = JsString::from("borderTop"); let js = JsString::from("borderTop");
let result = js.replace_with_function("T", &get_replacer_function()); let result = js.replace_with_function("T", &get_replacer_function());
assert_eq!(result, "border-top"); assert_eq!(result, "border-top");
let js = JsString::from("The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?"); let js = JsString::from(
"The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?",
);
let re = RegExp::new("dog", "g"); let re = RegExp::new("dog", "g");
let result = js.replace_by_pattern(&re, "ferret"); let result = js.replace_by_pattern(&re, "ferret");
@ -312,7 +345,9 @@ fn replace() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn search() { fn search() {
let js = JsString::from("The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?"); let js = JsString::from(
"The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?",
);
let re = RegExp::new("[^\\w\\s]", "g"); let re = RegExp::new("[^\\w\\s]", "g");
assert_eq!(js.search(&re), 44); assert_eq!(js.search(&re), 44);
@ -495,8 +530,14 @@ fn raw() {
let call_site = Object::new(); let call_site = Object::new();
let raw = Array::of3(&"foo".into(), &"bar".into(), &"123".into()); let raw = Array::of3(&"foo".into(), &"bar".into(), &"123".into());
Reflect::set(&call_site.as_ref(), &"raw".into(), &raw.into()).unwrap(); Reflect::set(&call_site.as_ref(), &"raw".into(), &raw.into()).unwrap();
assert_eq!(JsString::raw_2(&call_site, "5", "JavaScript").unwrap(), "foo5barJavaScript123"); assert_eq!(
JsString::raw_2(&call_site, "5", "JavaScript").unwrap(),
"foo5barJavaScript123"
);
let substitutions = Array::of2(&"5".into(), &"JavaScript".into()); let substitutions = Array::of2(&"5".into(), &"JavaScript".into());
assert_eq!(JsString::raw(&call_site, &substitutions).unwrap(), "foo5barJavaScript123"); assert_eq!(
JsString::raw(&call_site, &substitutions).unwrap(),
"foo5barJavaScript123"
);
assert!(JsString::raw_0(&JsValue::null().unchecked_into()).is_err()); assert!(JsString::raw_0(&JsValue::null().unchecked_into()).is_err());
} }

View File

@ -1,6 +1,6 @@
use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*; use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_test::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn clear() { fn clear() {

View File

@ -1,5 +1,5 @@
use wasm_bindgen_test::*;
use js_sys::*; use js_sys::*;
use wasm_bindgen_test::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn entries() { fn entries() {

View File

@ -1,14 +1,14 @@
use std::f64::consts::PI; use std::f64::consts::PI;
use std::f64::{NEG_INFINITY, NAN}; use std::f64::{NAN, NEG_INFINITY};
use wasm_bindgen::{JsCast, prelude::*};
use wasm_bindgen_test::*;
use js_sys::*; use js_sys::*;
use wasm_bindgen::{prelude::*, JsCast};
use wasm_bindgen_test::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn math_extends() { fn math_extends() {
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(js_name = Math)] #[wasm_bindgen(js_name = Math)]
static math: Math; static math: Math;
} }
@ -18,15 +18,19 @@ fn math_extends() {
} }
macro_rules! assert_eq { macro_rules! assert_eq {
($a:expr, $b:expr) => ({ ($a:expr, $b:expr) => {{
let (a, b) = (&$a, &$b); let (a, b) = (&$a, &$b);
if f64::is_infinite(*a) && f64::is_infinite(*b) { if f64::is_infinite(*a) && f64::is_infinite(*b) {
assert!(a == b); assert!(a == b);
} else { } else {
assert!((*a - *b).abs() < 1.0e-6, assert!(
"not approximately equal {:?} ?= {:?}", a, b); (*a - *b).abs() < 1.0e-6,
"not approximately equal {:?} ?= {:?}",
a,
b
);
} }
}) }};
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]

View File

@ -1,9 +1,9 @@
use std::f64::{INFINITY, NAN}; use std::f64::{INFINITY, NAN};
use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn is_finite() { fn is_finite() {
@ -41,7 +41,10 @@ fn is_nan() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn is_safe_integer() { fn is_safe_integer() {
assert_eq!(Number::is_safe_integer(&42.into()), true); assert_eq!(Number::is_safe_integer(&42.into()), true);
assert_eq!(Number::is_safe_integer(&(Math::pow(2., 53.) - 1.).into()), true); assert_eq!(
Number::is_safe_integer(&(Math::pow(2., 53.) - 1.).into()),
true
);
assert_eq!(Number::is_safe_integer(&Math::pow(2., 53.).into()), false); assert_eq!(Number::is_safe_integer(&Math::pow(2., 53.).into()), false);
assert_eq!(Number::is_safe_integer(&"42".into()), false); assert_eq!(Number::is_safe_integer(&"42".into()), false);
assert_eq!(Number::is_safe_integer(&42.1.into()), false); assert_eq!(Number::is_safe_integer(&42.1.into()), false);
@ -102,7 +105,10 @@ fn to_fixed() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn to_exponential() { fn to_exponential() {
assert_eq!(Number::new(&123456.into()).to_exponential(2).unwrap(), "1.23e+5"); assert_eq!(
Number::new(&123456.into()).to_exponential(2).unwrap(),
"1.23e+5"
);
assert!(Number::new(&10.into()).to_exponential(101).is_err()); assert!(Number::new(&10.into()).to_exponential(101).is_err());
} }

View File

@ -1,6 +1,6 @@
use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*; use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_test::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn promise_inheritance() { fn promise_inheritance() {

View File

@ -1,9 +1,9 @@
use js_sys::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use js_sys::*;
#[wasm_bindgen(module = "tests/wasm/Proxy.js")] #[wasm_bindgen(module = "tests/wasm/Proxy.js")]
extern { extern "C" {
fn proxy_target() -> JsValue; fn proxy_target() -> JsValue;
fn proxy_handler() -> Object; fn proxy_handler() -> Object;
@ -13,7 +13,6 @@ extern {
#[wasm_bindgen(method, getter, structural, catch)] #[wasm_bindgen(method, getter, structural, catch)]
fn b(this: &Custom) -> Result<u32, JsValue>; fn b(this: &Custom) -> Result<u32, JsValue>;
type RevocableResult; type RevocableResult;
#[wasm_bindgen(method, getter, structural)] #[wasm_bindgen(method, getter, structural)]
fn proxy(this: &RevocableResult) -> JsValue; fn proxy(this: &RevocableResult) -> JsValue;

View File

@ -1,7 +1,7 @@
use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn range_error() { fn range_error() {

View File

@ -1,7 +1,7 @@
use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn reference_error() { fn reference_error() {

View File

@ -1,9 +1,9 @@
use wasm_bindgen::{JsCast, prelude::*};
use wasm_bindgen_test::*;
use js_sys::*; use js_sys::*;
use wasm_bindgen::{prelude::*, JsCast};
use wasm_bindgen_test::*;
#[wasm_bindgen(module = "tests/wasm/Reflect.js")] #[wasm_bindgen(module = "tests/wasm/Reflect.js")]
extern { extern "C" {
fn get_char_at() -> Function; fn get_char_at() -> Function;
#[wasm_bindgen(js_name = Rectangle)] #[wasm_bindgen(js_name = Rectangle)]
@ -26,7 +26,7 @@ extern {
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(js_name = prototype, js_namespace = Object)] #[wasm_bindgen(js_name = prototype, js_namespace = Object)]
static OBJECT_PROTOTYPE: JsValue; static OBJECT_PROTOTYPE: JsValue;
#[wasm_bindgen(js_name = prototype, js_namespace = Array)] #[wasm_bindgen(js_name = prototype, js_namespace = Array)]
@ -45,7 +45,10 @@ extern {
fn apply() { fn apply() {
let args = Array::new(); let args = Array::new();
args.push(&3.into()); args.push(&3.into());
assert_eq!(Reflect::apply(&get_char_at(), &"ponies".into(), &args).unwrap(), "i"); assert_eq!(
Reflect::apply(&get_char_at(), &"ponies".into(), &args).unwrap(),
"i"
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
@ -62,11 +65,8 @@ fn construct_with_new_target() {
let args = Array::new(); let args = Array::new();
args.push(&10.into()); args.push(&10.into());
args.push(&10.into()); args.push(&10.into());
let instance = Reflect::construct_with_new_target( let instance =
&RECTANGLE_CLASS, Reflect::construct_with_new_target(&RECTANGLE_CLASS, &args, &RECTANGLE2_CLASS).unwrap();
&args,
&RECTANGLE2_CLASS,
).unwrap();
assert_eq!(Rectangle::from(instance).x(), 10); assert_eq!(Rectangle::from(instance).x(), 10);
} }
@ -180,13 +180,16 @@ fn set_prototype_of() {
let obj = Object::new(); let obj = Object::new();
assert!(Reflect::set_prototype_of(&obj, &JsValue::null()).unwrap()); assert!(Reflect::set_prototype_of(&obj, &JsValue::null()).unwrap());
let obj = JsValue::from(obj); let obj = JsValue::from(obj);
assert_eq!(JsValue::from(Reflect::get_prototype_of(&obj).unwrap()), JsValue::null()); assert_eq!(
JsValue::from(Reflect::get_prototype_of(&obj).unwrap()),
JsValue::null()
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn reflect_extends() { fn reflect_extends() {
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(js_name = Reflect)] #[wasm_bindgen(js_name = Reflect)]
static reflect: Reflect; static reflect: Reflect;
} }

View File

@ -1,6 +1,6 @@
use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*; use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_test::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn regexp_inheritance() { fn regexp_inheritance() {
@ -95,7 +95,10 @@ fn multiline() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn n1_to_n9() { fn n1_to_n9() {
let re = RegExp::new(r"(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)", ""); let re = RegExp::new(
r"(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)",
"",
);
re.test("The Quick Brown Fox Jumps Over The Lazy Dog"); re.test("The Quick Brown Fox Jumps Over The Lazy Dog");
assert_eq!(RegExp::n1(), "The"); assert_eq!(RegExp::n1(), "The");
assert_eq!(RegExp::n2(), "Quick"); assert_eq!(RegExp::n2(), "Quick");

View File

@ -1,12 +1,12 @@
use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*; use js_sys::*;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_test::*;
fn set2vec(s: &Set) -> Vec<JsValue> { fn set2vec(s: &Set) -> Vec<JsValue> {
let mut result = Vec::new(); let mut result = Vec::new();
s.for_each(&mut |x, _, _| result.push(x)); s.for_each(&mut |x, _, _| result.push(x));
return result return result;
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
@ -97,7 +97,11 @@ fn keys() {
set.add(&2.into()); set.add(&2.into());
set.add(&3.into()); set.add(&3.into());
let list = set.keys().into_iter().map(|e| e.unwrap()).collect::<Vec<_>>(); let list = set
.keys()
.into_iter()
.map(|e| e.unwrap())
.collect::<Vec<_>>();
assert_eq!(list.len(), 3); assert_eq!(list.len(), 3);
assert!(list.iter().any(|l| *l == 1)); assert!(list.iter().any(|l| *l == 1));
assert!(list.iter().any(|l| *l == 2)); assert!(list.iter().any(|l| *l == 2));
@ -111,7 +115,11 @@ fn values() {
set.add(&2.into()); set.add(&2.into());
set.add(&3.into()); set.add(&3.into());
let list = set.values().into_iter().map(|e| e.unwrap()).collect::<Vec<_>>(); let list = set
.values()
.into_iter()
.map(|e| e.unwrap())
.collect::<Vec<_>>();
assert_eq!(list.len(), 3); assert_eq!(list.len(), 3);
assert!(list.iter().any(|l| *l == 1)); assert!(list.iter().any(|l| *l == 1));
assert!(list.iter().any(|l| *l == 2)); assert!(list.iter().any(|l| *l == 2));

View File

@ -1,6 +1,6 @@
use js_sys::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn entries() { fn entries() {

View File

@ -1,9 +1,9 @@
use js_sys::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use js_sys::*;
#[wasm_bindgen(module = "tests/wasm/Symbol.js")] #[wasm_bindgen(module = "tests/wasm/Symbol.js")]
extern { extern "C" {
fn test_has_instance(sym: &Symbol); fn test_has_instance(sym: &Symbol);
fn test_is_concat_spreadable(sym: &Symbol); fn test_is_concat_spreadable(sym: &Symbol);
fn test_iterator(sym: &Symbol); fn test_iterator(sym: &Symbol);
@ -17,7 +17,7 @@ extern {
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(js_name = Symbol)] #[wasm_bindgen(js_name = Symbol)]
fn gensym(val: JsValue) -> Symbol; fn gensym(val: JsValue) -> Symbol;
} }
@ -101,7 +101,10 @@ fn to_string() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn unscopables() { fn unscopables() {
assert_eq!(Symbol::unscopables().to_string(), "Symbol(Symbol.unscopables)"); assert_eq!(
Symbol::unscopables().to_string(),
"Symbol(Symbol.unscopables)"
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]

View File

@ -1,7 +1,7 @@
use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn syntax_error() { fn syntax_error() {

View File

@ -1,7 +1,7 @@
use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn type_error() { fn type_error() {

View File

@ -1,10 +1,10 @@
use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*; use js_sys::*;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_test::*;
macro_rules! each { macro_rules! each {
($m:ident) => ( ($m:ident) => {
$m!(Uint8Array); $m!(Uint8Array);
$m!(Uint8ClampedArray); $m!(Uint8ClampedArray);
$m!(Uint16Array); $m!(Uint16Array);
@ -14,16 +14,16 @@ macro_rules! each {
$m!(Int32Array); $m!(Int32Array);
$m!(Float32Array); $m!(Float32Array);
$m!(Float64Array); $m!(Float64Array);
) };
} }
macro_rules! test_inheritence { macro_rules! test_inheritence {
($arr:ident) => ({ ($arr:ident) => {{
let arr = $arr::new(&JsValue::undefined()); let arr = $arr::new(&JsValue::undefined());
assert!(arr.is_instance_of::<$arr>()); assert!(arr.is_instance_of::<$arr>());
let _: &Object = arr.as_ref(); let _: &Object = arr.as_ref();
assert!(arr.is_instance_of::<Object>()); assert!(arr.is_instance_of::<Object>());
}) }};
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn inheritence() { fn inheritence() {
@ -31,13 +31,13 @@ fn inheritence() {
} }
macro_rules! test_undefined { macro_rules! test_undefined {
($arr:ident) => ({ ($arr:ident) => {{
let arr = $arr::new(&JsValue::undefined()); let arr = $arr::new(&JsValue::undefined());
assert_eq!(arr.length(), 0); assert_eq!(arr.length(), 0);
assert_eq!(arr.byte_length(), 0); assert_eq!(arr.byte_length(), 0);
assert_eq!(arr.byte_offset(), 0); assert_eq!(arr.byte_offset(), 0);
assert!(JsValue::from(arr.buffer()).is_object()); assert!(JsValue::from(arr.buffer()).is_object());
}) }};
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn new_undefined() { fn new_undefined() {
@ -45,13 +45,13 @@ fn new_undefined() {
} }
macro_rules! test_length { macro_rules! test_length {
($arr:ident) => ({ ($arr:ident) => {{
let arr = $arr::new(&4.into()); let arr = $arr::new(&4.into());
assert_eq!(arr.length(), 4); assert_eq!(arr.length(), 4);
assert!(arr.byte_length() != 0); assert!(arr.byte_length() != 0);
assert_eq!(arr.byte_offset(), 0); assert_eq!(arr.byte_offset(), 0);
assert!(JsValue::from(arr.buffer()).is_object()); assert!(JsValue::from(arr.buffer()).is_object());
}) }};
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn new_length() { fn new_length() {
@ -59,9 +59,9 @@ fn new_length() {
} }
macro_rules! test_subarray { macro_rules! test_subarray {
($arr:ident) => ({ ($arr:ident) => {{
assert_eq!($arr::new(&4.into()).subarray(0, 1).length(), 1); assert_eq!($arr::new(&4.into()).subarray(0, 1).length(), 1);
}) }};
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn new_subarray() { fn new_subarray() {
@ -69,7 +69,7 @@ fn new_subarray() {
} }
macro_rules! test_fill { macro_rules! test_fill {
($arr:ident) => ({ ($arr:ident) => {{
let arr = $arr::new(&4.into()); let arr = $arr::new(&4.into());
arr.for_each(&mut |x, _, _| { arr.for_each(&mut |x, _, _| {
assert_eq!(x as f64, 0.0); assert_eq!(x as f64, 0.0);
@ -82,7 +82,7 @@ macro_rules! test_fill {
assert_eq!(x as f64, 0.0); assert_eq!(x as f64, 0.0);
} }
}); });
}) }};
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn new_fill() { fn new_fill() {

View File

@ -1,7 +1,7 @@
use js_sys::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn uri_error() { fn uri_error() {

View File

@ -1,10 +1,10 @@
use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*; use js_sys::*;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_test::*;
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
type SomeKey; type SomeKey;
#[wasm_bindgen(method, setter, structural)] #[wasm_bindgen(method, setter, structural)]
fn set_some(this: &SomeKey, val: JsValue); fn set_some(this: &SomeKey, val: JsValue);

View File

@ -1,10 +1,10 @@
use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use wasm_bindgen::JsCast;
use js_sys::*; use js_sys::*;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_test::*;
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
type SomeValue; type SomeValue;
#[wasm_bindgen(method, setter, structural)] #[wasm_bindgen(method, setter, structural)]
fn set_some(this: &SomeValue, val: JsValue); fn set_some(this: &SomeValue, val: JsValue);

View File

@ -186,10 +186,9 @@ fn instantiate_module() -> impl Future<Item = (), Error = JsValue> {
let module = WebAssembly::Module::new(&get_valid_wasm()).unwrap(); let module = WebAssembly::Module::new(&get_valid_wasm()).unwrap();
let imports = get_imports(); let imports = get_imports();
let p = WebAssembly::instantiate_module(&module, &imports); let p = WebAssembly::instantiate_module(&module, &imports);
JsFuture::from(p) JsFuture::from(p).map(|inst| {
.map(|inst| { assert!(inst.is_instance_of::<WebAssembly::Instance>());
assert!(inst.is_instance_of::<WebAssembly::Instance>()); })
})
} }
#[wasm_bindgen_test(async)] #[wasm_bindgen_test(async)]
@ -197,14 +196,13 @@ fn instantiate_streaming() -> impl Future<Item = (), Error = JsValue> {
let response = Promise::resolve(&get_valid_wasm()); let response = Promise::resolve(&get_valid_wasm());
let imports = get_imports(); let imports = get_imports();
let p = WebAssembly::instantiate_streaming(&response, &imports); let p = WebAssembly::instantiate_streaming(&response, &imports);
JsFuture::from(p) JsFuture::from(p).map(|obj| {
.map(|obj| { assert!(
assert!( Reflect::get(obj.as_ref(), &"instance".into())
Reflect::get(obj.as_ref(), &"instance".into()) .unwrap()
.unwrap() .is_instance_of::<WebAssembly::Instance>()
.is_instance_of::<WebAssembly::Instance>() );
); })
})
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]

View File

@ -1,7 +1,7 @@
use std::f64::{NAN, INFINITY}; use std::f64::{INFINITY, NAN};
use wasm_bindgen_test::*;
use js_sys::*; use js_sys::*;
use wasm_bindgen_test::*;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn test_decode_uri() { fn test_decode_uri() {

View File

@ -7,7 +7,6 @@ extern crate wasm_bindgen;
extern crate wasm_bindgen_futures; extern crate wasm_bindgen_futures;
extern crate wasm_bindgen_test; extern crate wasm_bindgen_test;
pub mod global_fns;
pub mod Array; pub mod Array;
pub mod ArrayBuffer; pub mod ArrayBuffer;
pub mod ArrayIterator; pub mod ArrayIterator;
@ -20,8 +19,8 @@ pub mod Function;
pub mod Generator; pub mod Generator;
pub mod Intl; pub mod Intl;
pub mod Iterator; pub mod Iterator;
pub mod JsString;
pub mod JSON; pub mod JSON;
pub mod JsString;
pub mod Map; pub mod Map;
pub mod MapIterator; pub mod MapIterator;
pub mod Math; pub mod Math;
@ -43,3 +42,4 @@ pub mod UriError;
pub mod WeakMap; pub mod WeakMap;
pub mod WeakSet; pub mod WeakSet;
pub mod WebAssembly; pub mod WebAssembly;
pub mod global_fns;

View File

@ -11,9 +11,9 @@ extern crate syn;
extern crate wasm_bindgen_backend as backend; extern crate wasm_bindgen_backend as backend;
extern crate wasm_bindgen_shared as shared; extern crate wasm_bindgen_shared as shared;
use backend::{Diagnostic, TryToTokens};
pub use parser::BindgenAttrs; pub use parser::BindgenAttrs;
use parser::MacroParse; use parser::MacroParse;
use backend::{Diagnostic, TryToTokens};
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
mod parser; mod parser;

View File

@ -197,11 +197,13 @@ impl BindgenAttrs {
impl Parse for BindgenAttrs { impl Parse for BindgenAttrs {
fn parse(input: ParseStream) -> SynResult<Self> { fn parse(input: ParseStream) -> SynResult<Self> {
if input.is_empty() { if input.is_empty() {
return Ok(BindgenAttrs { attrs: Vec::new() }) return Ok(BindgenAttrs { attrs: Vec::new() });
} }
let opts = syn::punctuated::Punctuated::<_, syn::token::Comma>::parse_terminated(input)?; let opts = syn::punctuated::Punctuated::<_, syn::token::Comma>::parse_terminated(input)?;
Ok(BindgenAttrs { attrs: opts.into_iter().collect() }) Ok(BindgenAttrs {
attrs: opts.into_iter().collect(),
})
} }
} }
@ -232,65 +234,65 @@ impl Parse for BindgenAttr {
let original = input.fork(); let original = input.fork();
let attr: Ident = input.parse()?; let attr: Ident = input.parse()?;
if attr == "catch" { if attr == "catch" {
return Ok(BindgenAttr::Catch) return Ok(BindgenAttr::Catch);
} }
if attr == "constructor" { if attr == "constructor" {
return Ok(BindgenAttr::Constructor) return Ok(BindgenAttr::Constructor);
} }
if attr == "method" { if attr == "method" {
return Ok(BindgenAttr::Method) return Ok(BindgenAttr::Method);
} }
if attr == "indexing_getter" { if attr == "indexing_getter" {
return Ok(BindgenAttr::IndexingGetter) return Ok(BindgenAttr::IndexingGetter);
} }
if attr == "indexing_setter" { if attr == "indexing_setter" {
return Ok(BindgenAttr::IndexingSetter) return Ok(BindgenAttr::IndexingSetter);
} }
if attr == "indexing_deleter" { if attr == "indexing_deleter" {
return Ok(BindgenAttr::IndexingDeleter) return Ok(BindgenAttr::IndexingDeleter);
} }
if attr == "structural" { if attr == "structural" {
return Ok(BindgenAttr::Structural) return Ok(BindgenAttr::Structural);
} }
if attr == "readonly" { if attr == "readonly" {
return Ok(BindgenAttr::Readonly) return Ok(BindgenAttr::Readonly);
} }
if attr == "variadic" { if attr == "variadic" {
return Ok(BindgenAttr::Variadic) return Ok(BindgenAttr::Variadic);
} }
if attr == "static_method_of" { if attr == "static_method_of" {
input.parse::<Token![=]>()?; input.parse::<Token![=]>()?;
return Ok(BindgenAttr::StaticMethodOf(input.parse::<AnyIdent>()?.0)) return Ok(BindgenAttr::StaticMethodOf(input.parse::<AnyIdent>()?.0));
} }
if attr == "getter" { if attr == "getter" {
if input.parse::<Token![=]>().is_ok() { if input.parse::<Token![=]>().is_ok() {
return Ok(BindgenAttr::Getter(Some(input.parse::<AnyIdent>()?.0))) return Ok(BindgenAttr::Getter(Some(input.parse::<AnyIdent>()?.0)));
} else { } else {
return Ok(BindgenAttr::Getter(None)) return Ok(BindgenAttr::Getter(None));
} }
} }
if attr == "setter" { if attr == "setter" {
if input.parse::<Token![=]>().is_ok() { if input.parse::<Token![=]>().is_ok() {
return Ok(BindgenAttr::Setter(Some(input.parse::<AnyIdent>()?.0))) return Ok(BindgenAttr::Setter(Some(input.parse::<AnyIdent>()?.0)));
} else { } else {
return Ok(BindgenAttr::Setter(None)) return Ok(BindgenAttr::Setter(None));
} }
} }
if attr == "js_namespace" { if attr == "js_namespace" {
input.parse::<Token![=]>()?; input.parse::<Token![=]>()?;
return Ok(BindgenAttr::JsNamespace(input.parse::<AnyIdent>()?.0)) return Ok(BindgenAttr::JsNamespace(input.parse::<AnyIdent>()?.0));
} }
if attr == "extends" { if attr == "extends" {
input.parse::<Token![=]>()?; input.parse::<Token![=]>()?;
return Ok(BindgenAttr::Extends(input.parse::<AnyIdent>()?.0)) return Ok(BindgenAttr::Extends(input.parse::<AnyIdent>()?.0));
} }
if attr == "module" { if attr == "module" {
input.parse::<Token![=]>()?; input.parse::<Token![=]>()?;
return Ok(BindgenAttr::Module(input.parse::<syn::LitStr>()?.value())) return Ok(BindgenAttr::Module(input.parse::<syn::LitStr>()?.value()));
} }
if attr == "js_class" { if attr == "js_class" {
input.parse::<Token![=]>()?; input.parse::<Token![=]>()?;
return Ok(BindgenAttr::JsClass(input.parse::<syn::LitStr>()?.value())) return Ok(BindgenAttr::JsClass(input.parse::<syn::LitStr>()?.value()));
} }
if attr == "js_name" { if attr == "js_name" {
input.parse::<Token![=]>()?; input.parse::<Token![=]>()?;
@ -301,7 +303,7 @@ impl Parse for BindgenAttr {
(ident.to_string(), ident.span()) (ident.to_string(), ident.span())
} }
}; };
return Ok(BindgenAttr::JsName(val, span)) return Ok(BindgenAttr::JsName(val, span));
} }
Err(original.error("unknown attribute")) Err(original.error("unknown attribute"))
@ -312,11 +314,9 @@ struct AnyIdent(Ident);
impl Parse for AnyIdent { impl Parse for AnyIdent {
fn parse(input: ParseStream) -> SynResult<Self> { fn parse(input: ParseStream) -> SynResult<Self> {
input.step(|cursor| { input.step(|cursor| match cursor.ident() {
match cursor.ident() { Some((ident, remaining)) => Ok((AnyIdent(ident), remaining)),
Some((ident, remaining)) => Ok((AnyIdent(ident), remaining)), None => Err(cursor.error("expected an identifier")),
None => Err(cursor.error("expected an identifier")),
}
}) })
} }
} }
@ -563,9 +563,10 @@ impl ConvertToAst<BindgenAttrs> for syn::ForeignItemType {
impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemStatic { impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemStatic {
type Target = ast::ImportKind; type Target = ast::ImportKind;
fn convert(self, (opts, module): (BindgenAttrs, &'a Option<String>)) fn convert(
-> Result<Self::Target, Diagnostic> self,
{ (opts, module): (BindgenAttrs, &'a Option<String>),
) -> Result<Self::Target, Diagnostic> {
if self.mutability.is_some() { if self.mutability.is_some() {
bail_span!(self.mutability, "cannot import mutable globals yet") bail_span!(self.mutability, "cannot import mutable globals yet")
} }
@ -606,7 +607,15 @@ impl ConvertToAst<BindgenAttrs> for syn::ItemFn {
} }
assert_not_variadic(&attrs, &self)?; assert_not_variadic(&attrs, &self)?;
Ok(function_from_decl(&self.ident, &attrs, self.decl, self.attrs, self.vis, false, None)?.0) Ok(function_from_decl(
&self.ident,
&attrs,
self.decl,
self.attrs,
self.vis,
false,
None,
)?.0)
} }
} }
@ -687,7 +696,9 @@ fn function_from_decl(
let js_name = opts.js_name(); let js_name = opts.js_name();
Ok(( Ok((
ast::Function { ast::Function {
name: js_name.map(|s| s.0.to_string()).unwrap_or(decl_name.to_string()), name: js_name
.map(|s| s.0.to_string())
.unwrap_or(decl_name.to_string()),
name_span: js_name.map(|s| s.1).unwrap_or(decl_name.span()), name_span: js_name.map(|s| s.1).unwrap_or(decl_name.span()),
renamed_via_js_name: js_name.is_some(), renamed_via_js_name: js_name.is_some(),
arguments, arguments,
@ -1031,28 +1042,31 @@ fn extract_first_ty_param(ty: Option<&syn::Type>) -> Result<Option<syn::Type>, D
/// Extract the documentation comments from a Vec of attributes /// Extract the documentation comments from a Vec of attributes
fn extract_doc_comments(attrs: &[syn::Attribute]) -> Vec<String> { fn extract_doc_comments(attrs: &[syn::Attribute]) -> Vec<String> {
attrs attrs
.iter() .iter()
.filter_map(|a| { .filter_map(|a| {
// if the path segments include an ident of "doc" we know this // if the path segments include an ident of "doc" we know this
// this is a doc comment // this is a doc comment
if a.path.segments.iter().any(|s| s.ident.to_string() == "doc") { if a.path.segments.iter().any(|s| s.ident.to_string() == "doc") {
Some( Some(
// We want to filter out any Puncts so just grab the Literals // We want to filter out any Puncts so just grab the Literals
a.tts.clone().into_iter().filter_map(|t| match t { a.tts.clone().into_iter().filter_map(|t| match t {
TokenTree::Literal(lit) => { TokenTree::Literal(lit) => {
// this will always return the quoted string, we deal with // this will always return the quoted string, we deal with
// that in the cli when we read in the comments // that in the cli when we read in the comments
Some(lit.to_string()) Some(lit.to_string())
}, }
_ => None, _ => None,
}) }),
) )
} else { } else {
None None
} }
}) })
//Fold up the [[String]] iter we created into Vec<String> //Fold up the [[String]] iter we created into Vec<String>
.fold(vec![], |mut acc, a| {acc.extend(a); acc}) .fold(vec![], |mut acc, a| {
acc.extend(a);
acc
})
} }
/// Check there are no lifetimes on the function. /// Check there are no lifetimes on the function.
@ -1080,8 +1094,11 @@ fn assert_no_lifetimes(decl: &syn::FnDecl) -> Result<(), Diagnostic> {
/// This method always fails if the BindgenAttrs contain variadic /// This method always fails if the BindgenAttrs contain variadic
fn assert_not_variadic(attrs: &BindgenAttrs, span: &dyn ToTokens) -> Result<(), Diagnostic> { fn assert_not_variadic(attrs: &BindgenAttrs, span: &dyn ToTokens) -> Result<(), Diagnostic> {
if attrs.variadic() { if attrs.variadic() {
bail_span!(span, "the `variadic` attribute can only be applied to imported \ bail_span!(
(`extern`) functions") span,
"the `variadic` attribute can only be applied to imported \
(`extern`) functions"
)
} }
Ok(()) Ok(())
} }

View File

@ -6,8 +6,8 @@ extern crate proc_macro2;
#[macro_use] #[macro_use]
extern crate quote; extern crate quote;
use std::sync::atomic::*;
use proc_macro2::*; use proc_macro2::*;
use std::sync::atomic::*;
static CNT: AtomicUsize = ATOMIC_USIZE_INIT; static CNT: AtomicUsize = ATOMIC_USIZE_INIT;
@ -38,7 +38,7 @@ pub fn wasm_bindgen_test(
leading_tokens.push(token.clone()); leading_tokens.push(token.clone());
if let TokenTree::Ident(token) = token { if let TokenTree::Ident(token) = token {
if token == "fn" { if token == "fn" {
break break;
} }
} }
} }
@ -58,18 +58,24 @@ pub fn wasm_bindgen_test(
// We generate a `#[no_mangle]` with a known prefix so the test harness can // We generate a `#[no_mangle]` with a known prefix so the test harness can
// later slurp up all of these functions and pass them as arguments to the // later slurp up all of these functions and pass them as arguments to the
// main test harness. This is the entry point for all tests. // main test harness. This is the entry point for all tests.
let name = format!("__wbg_test_{}_{}", ident, CNT.fetch_add(1, Ordering::SeqCst)); let name = format!(
"__wbg_test_{}_{}",
ident,
CNT.fetch_add(1, Ordering::SeqCst)
);
let name = Ident::new(&name, Span::call_site()); let name = Ident::new(&name, Span::call_site());
tokens.extend((quote! { tokens.extend(
#[no_mangle] (quote! {
pub extern fn #name(cx: *const ::wasm_bindgen_test::__rt::Context) { #[no_mangle]
unsafe { pub extern fn #name(cx: *const ::wasm_bindgen_test::__rt::Context) {
let cx = &*cx; unsafe {
let test_name = concat!(module_path!(), "::", stringify!(#ident)); let cx = &*cx;
#test_body let test_name = concat!(module_path!(), "::", stringify!(#ident));
#test_body
}
} }
} }).into_iter(),
}).into_iter()); );
tokens.extend(leading_tokens); tokens.extend(leading_tokens);
tokens.push(ident.into()); tokens.push(ident.into());

View File

@ -17,7 +17,7 @@ pub struct Timeout {
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(js_name = setTimeout)] #[wasm_bindgen(js_name = setTimeout)]
fn set_timeout(closure: JsValue, millis: f64) -> u32; fn set_timeout(closure: JsValue, millis: f64) -> u32;
@ -27,7 +27,8 @@ extern {
impl Timeout { impl Timeout {
pub fn new(dur: Duration) -> Timeout { pub fn new(dur: Duration) -> Timeout {
let millis = dur.as_secs() let millis = dur
.as_secs()
.checked_mul(1000) .checked_mul(1000)
.unwrap() .unwrap()
.checked_add(dur.subsec_millis() as u64) .checked_add(dur.subsec_millis() as u64)

View File

@ -1,9 +1,9 @@
use std::time::Duration; use std::time::Duration;
use futures::prelude::*; use futures::prelude::*;
use sample::Timeout;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
use sample::Timeout;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn pass() { fn pass() {
@ -13,13 +13,12 @@ fn pass() {
#[wasm_bindgen_test(async)] #[wasm_bindgen_test(async)]
fn pass_after_2s() -> impl Future<Item = (), Error = JsValue> { fn pass_after_2s() -> impl Future<Item = (), Error = JsValue> {
console_log!("immediate log"); console_log!("immediate log");
Timeout::new(Duration::new(1, 0)) Timeout::new(Duration::new(1, 0)).and_then(|()| {
.and_then(|()| { console_log!("log after 1s");
console_log!("log after 1s"); Timeout::new(Duration::new(1, 0)).map(|()| {
Timeout::new(Duration::new(1, 0)).map(|()| { console_log!("log at end");
console_log!("log at end");
})
}) })
})
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
@ -31,15 +30,13 @@ fn fail() {
#[wasm_bindgen_test(async)] #[wasm_bindgen_test(async)]
fn fail_after_3s() -> impl Future<Item = (), Error = JsValue> { fn fail_after_3s() -> impl Future<Item = (), Error = JsValue> {
console_log!("immediate log"); console_log!("immediate log");
Timeout::new(Duration::new(1, 0)) Timeout::new(Duration::new(1, 0)).and_then(|()| {
.and_then(|()| { console_log!("log after 1s");
console_log!("log after 1s"); Timeout::new(Duration::new(1, 0)).and_then(|()| {
Timeout::new(Duration::new(1, 0)).and_then(|()| { console_log!("log after 2s");
console_log!("log after 2s"); Timeout::new(Duration::new(1, 0)).map(|()| {
Timeout::new(Duration::new(1, 0)).map(|()| { panic!("end");
panic!("end");
})
}) })
}) })
})
} }

View File

@ -3,8 +3,8 @@
//! Currently this is quite simple, rendering the same as the console tests in //! Currently this is quite simple, rendering the same as the console tests in
//! node.js. Output here is rendered in a `pre`, however. //! node.js. Output here is rendered in a `pre`, however.
use wasm_bindgen::prelude::*;
use js_sys::Error; use js_sys::Error;
use wasm_bindgen::prelude::*;
/// Implementation of `Formatter` for browsers. /// Implementation of `Formatter` for browsers.
/// ///
@ -15,7 +15,7 @@ pub struct Browser {
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
type HTMLDocument; type HTMLDocument;
static document: HTMLDocument; static document: HTMLDocument;
#[wasm_bindgen(method, structural)] #[wasm_bindgen(method, structural)]
@ -38,9 +38,7 @@ impl Browser {
pub fn new() -> Browser { pub fn new() -> Browser {
let pre = document.getElementById("output"); let pre = document.getElementById("output");
pre.set_inner_html(""); pre.set_inner_html("");
Browser { Browser { pre }
pre,
}
} }
} }
@ -75,11 +73,10 @@ impl super::Formatter for Browser {
// probably a chome-like error which is already rendered well, so just // probably a chome-like error which is already rendered well, so just
// return this info // return this info
if stack.contains(&header) { if stack.contains(&header) {
return stack return stack;
} }
// Fallback to make sure we don't lose any info // Fallback to make sure we don't lose any info
format!("{}\n{}", header, stack) format!("{}\n{}", header, stack)
} }
} }

View File

@ -1,11 +1,11 @@
//! Runtime detection of whether we're in node.js or a browser. //! Runtime detection of whether we're in node.js or a browser.
use js_sys;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
use js_sys;
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
type This; type This;
#[wasm_bindgen(method, getter, structural, js_name = self)] #[wasm_bindgen(method, getter, structural, js_name = self)]
fn self_(me: &This) -> JsValue; fn self_(me: &This) -> JsValue;

View File

@ -87,8 +87,7 @@
// Overall this is all somewhat in flux as it's pretty new, and feedback is // Overall this is all somewhat in flux as it's pretty new, and feedback is
// always of course welcome! // always of course welcome!
use std::cell::{Cell, RefCell};
use std::cell::{RefCell, Cell};
use std::fmt; use std::fmt;
use std::rc::Rc; use std::rc::Rc;
@ -107,9 +106,9 @@ use wasm_bindgen_futures::future_to_promise;
// conccurrently doing things by default would likely end up in a bad situation. // conccurrently doing things by default would likely end up in a bad situation.
const CONCURRENCY: usize = 1; const CONCURRENCY: usize = 1;
pub mod node;
pub mod browser; pub mod browser;
pub mod detect; pub mod detect;
pub mod node;
/// Runtime test harness support instantiated in JS. /// Runtime test harness support instantiated in JS.
/// ///
@ -182,7 +181,7 @@ trait Formatter {
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(js_namespace = console, js_name = log)] #[wasm_bindgen(js_namespace = console, js_name = log)]
#[doc(hidden)] #[doc(hidden)]
pub fn js_console_log(s: &str); pub fn js_console_log(s: &str);
@ -259,7 +258,9 @@ impl Context {
/// `false` if at least one test failed. /// `false` if at least one test failed.
pub fn run(&self, tests: Vec<JsValue>) -> Promise { pub fn run(&self, tests: Vec<JsValue>) -> Promise {
let noun = if tests.len() == 1 { "test" } else { "tests" }; let noun = if tests.len() == 1 { "test" } else { "tests" };
self.state.formatter.writeln(&format!("running {} {}", tests.len(), noun)); self.state
.formatter
.writeln(&format!("running {} {}", tests.len(), noun));
self.state.formatter.writeln(""); self.state.formatter.writeln("");
// Execute all our test functions through their wasm shims (unclear how // Execute all our test functions through their wasm shims (unclear how
@ -271,8 +272,10 @@ impl Context {
match Function::from(test).call1(&JsValue::null(), &cx_arg) { match Function::from(test).call1(&JsValue::null(), &cx_arg) {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
panic!("exception thrown while creating a test: {}", panic!(
self.state.formatter.stringify_error(&e)); "exception thrown while creating a test: {}",
self.state.formatter.stringify_error(&e)
);
} }
} }
} }
@ -280,7 +283,8 @@ impl Context {
// Now that we've collected all our tests we wrap everything up in a // Now that we've collected all our tests we wrap everything up in a
// future to actually do all the processing, and pass it out to JS as a // future to actually do all the processing, and pass it out to JS as a
// `Promise`. // `Promise`.
let future = ExecuteTests(self.state.clone()).map(JsValue::from) let future = ExecuteTests(self.state.clone())
.map(JsValue::from)
.map_err(|e| match e {}); .map_err(|e| match e {});
future_to_promise(future) future_to_promise(future)
} }
@ -316,7 +320,7 @@ pub fn __wbgtest_console_error(original: &Function, args: &Array) {
fn record(orig: &Function, args: &Array, dst: impl FnOnce(&mut Output) -> &mut String) { fn record(orig: &Function, args: &Array, dst: impl FnOnce(&mut Output) -> &mut String) {
if !CURRENT_OUTPUT.is_set() { if !CURRENT_OUTPUT.is_set() {
drop(orig.apply(&JsValue::null(), args)); drop(orig.apply(&JsValue::null(), args));
return return;
} }
CURRENT_OUTPUT.with(|output| { CURRENT_OUTPUT.with(|output| {
@ -343,16 +347,13 @@ impl Context {
/// `#[wasm_bindgen_test(async)]` macro generates invocations of this /// `#[wasm_bindgen_test(async)]` macro generates invocations of this
/// method. /// method.
pub fn execute_async<F>(&self, name: &str, f: impl FnOnce() -> F + 'static) pub fn execute_async<F>(&self, name: &str, f: impl FnOnce() -> F + 'static)
where F: Future<Item = (), Error = JsValue> + 'static, where
F: Future<Item = (), Error = JsValue> + 'static,
{ {
self.execute(name, future::lazy(f)) self.execute(name, future::lazy(f))
} }
fn execute( fn execute(&self, name: &str, test: impl Future<Item = (), Error = JsValue> + 'static) {
&self,
name: &str,
test: impl Future<Item = (), Error = JsValue> + 'static,
) {
// If our test is filtered out, record that it was filtered and move // If our test is filtered out, record that it was filtered and move
// on, nothing to do here. // on, nothing to do here.
let filter = self.state.filter.borrow(); let filter = self.state.filter.borrow();
@ -360,7 +361,7 @@ impl Context {
if !name.contains(filter) { if !name.contains(filter) {
let ignored = self.state.ignored.get(); let ignored = self.state.ignored.get();
self.state.ignored.set(ignored + 1); self.state.ignored.set(ignored + 1);
return return;
} }
} }
@ -416,7 +417,7 @@ impl Future for ExecuteTests {
Ok(Async::Ready(())) => Ok(()), Ok(Async::Ready(())) => Ok(()),
Ok(Async::NotReady) => { Ok(Async::NotReady) => {
running.push(test); running.push(test);
continue continue;
} }
Err(e) => Err(e), Err(e) => Err(e),
}; };
@ -426,7 +427,7 @@ impl Future for ExecuteTests {
// Tests are still executing, we're registered to get a notification, // Tests are still executing, we're registered to get a notification,
// keep going. // keep going.
if running.len() != 0 { if running.len() != 0 {
return Ok(Async::NotReady) return Ok(Async::NotReady);
} }
// If there are no tests running then we must have finished everything, // If there are no tests running then we must have finished everything,
@ -532,7 +533,7 @@ struct TestFuture<F> {
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(catch)] #[wasm_bindgen(catch)]
fn __wbg_test_invoke(f: &mut FnMut()) -> Result<(), JsValue>; fn __wbg_test_invoke(f: &mut FnMut()) -> Result<(), JsValue>;
} }

View File

@ -6,11 +6,10 @@
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
/// Implementation of the `Formatter` trait for node.js /// Implementation of the `Formatter` trait for node.js
pub struct Node { pub struct Node {}
}
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
// Not using `js_sys::Error` because node's errors specifically have a // Not using `js_sys::Error` because node's errors specifically have a
// `stack` attribute. // `stack` attribute.
type NodeError; type NodeError;
@ -23,9 +22,9 @@ impl Node {
/// is executing in a browser and Node won't work. /// is executing in a browser and Node won't work.
pub fn new() -> Option<Node> { pub fn new() -> Option<Node> {
if super::detect::is_browser() { if super::detect::is_browser() {
return None return None;
} }
Some(Node { }) Some(Node {})
} }
} }

View File

@ -93,8 +93,7 @@ fn build_function(
segments, segments,
}, },
}) })
}) }).collect::<Vec<_>>();
.collect::<Vec<_>>();
let mut ret_segments = syn::punctuated::Punctuated::new(); let mut ret_segments = syn::punctuated::Punctuated::new();
ret_segments.push(syn::PathSegment { ret_segments.push(syn::PathSegment {

View File

@ -119,7 +119,7 @@ impl Interpreter {
_ => continue, _ => continue,
} }
if entry.module() != "__wbindgen_placeholder__" { if entry.module() != "__wbindgen_placeholder__" {
continue continue;
} }
if entry.field() == "__wbindgen_describe" { if entry.field() == "__wbindgen_describe" {
ret.describe_idx = Some(idx - 1 as u32); ret.describe_idx = Some(idx - 1 as u32);
@ -140,7 +140,7 @@ impl Interpreter {
} }
} }
return ret return ret;
} }
/// Interprets the execution of the descriptor function `func`. /// Interprets the execution of the descriptor function `func`.
@ -163,22 +163,14 @@ impl Interpreter {
/// ///
/// Returns `Some` if `func` was found in the `module` and `None` if it was /// Returns `Some` if `func` was found in the `module` and `None` if it was
/// not found in the `module`. /// not found in the `module`.
pub fn interpret_descriptor( pub fn interpret_descriptor(&mut self, func: &str, module: &Module) -> Option<&[u32]> {
&mut self,
func: &str,
module: &Module,
) -> Option<&[u32]> {
let idx = *self.name_map.get(func)?; let idx = *self.name_map.get(func)?;
self.with_sections(module, |me, sections| { self.with_sections(module, |me, sections| {
me.interpret_descriptor_idx(idx, sections) me.interpret_descriptor_idx(idx, sections)
}) })
} }
fn interpret_descriptor_idx( fn interpret_descriptor_idx(&mut self, idx: u32, sections: &Sections) -> Option<&[u32]> {
&mut self,
idx: u32,
sections: &Sections,
) -> Option<&[u32]> {
self.descriptor.truncate(0); self.descriptor.truncate(0);
// We should have a blank wasm and LLVM stack at both the start and end // We should have a blank wasm and LLVM stack at both the start and end
@ -250,27 +242,27 @@ impl Interpreter {
// After we've got the table index of the descriptor function we're // After we've got the table index of the descriptor function we're
// interested go take a look in the function table to find what the // interested go take a look in the function table to find what the
// actual index of the function is. // actual index of the function is.
let (entry_idx, offset, entry) = sections.elements.entries() let (entry_idx, offset, entry) = sections
.elements
.entries()
.iter() .iter()
.enumerate() .enumerate()
.filter_map(|(i, entry)| { .filter_map(|(i, entry)| {
let code = entry.offset().code(); let code = entry.offset().code();
if code.len() != 2 { if code.len() != 2 {
return None return None;
} }
if code[1] != Instruction::End { if code[1] != Instruction::End {
return None return None;
} }
match code[0] { match code[0] {
Instruction::I32Const(x) => Some((i, x as u32, entry)), Instruction::I32Const(x) => Some((i, x as u32, entry)),
_ => None, _ => None,
} }
}) }).find(|(_i, offset, entry)| {
.find(|(_i, offset, entry)| { *offset <= descriptor_table_idx
*offset <= descriptor_table_idx && && descriptor_table_idx < (*offset + entry.members().len() as u32)
descriptor_table_idx < (*offset + entry.members().len() as u32) }).expect("failed to find index in table elements");
})
.expect("failed to find index in table elements");
let idx = (descriptor_table_idx - offset) as usize; let idx = (descriptor_table_idx - offset) as usize;
let descriptor_idx = entry.members()[idx]; let descriptor_idx = entry.members()[idx];
@ -299,13 +291,13 @@ impl Interpreter {
// Allocate space for our call frame's local variables. All local // Allocate space for our call frame's local variables. All local
// variables should be of the `i32` type. // variables should be of the `i32` type.
assert!(body.locals().len() <= 1, "too many local types"); assert!(body.locals().len() <= 1, "too many local types");
let nlocals = body.locals() let nlocals = body
.locals()
.get(0) .get(0)
.map(|i| { .map(|i| {
assert_eq!(i.value_type(), ValueType::I32); assert_eq!(i.value_type(), ValueType::I32);
i.count() i.count()
}) }).unwrap_or(0);
.unwrap_or(0);
let code_sig = sections.functions.entries()[code_idx].type_ref(); let code_sig = sections.functions.entries()[code_idx].type_ref();
let function_ty = match &sections.types.types()[code_sig as usize] { let function_ty = match &sections.types.types()[code_sig as usize] {
@ -352,8 +344,7 @@ impl Interpreter {
if Some(*idx) == self.describe_idx { if Some(*idx) == self.describe_idx {
self.descriptor.push(self.stack.pop().unwrap() as u32); self.descriptor.push(self.stack.pop().unwrap() as u32);
} else if Some(*idx) == self.describe_closure_idx { } else if Some(*idx) == self.describe_closure_idx {
self.descriptor_table_idx = self.descriptor_table_idx = Some(self.stack.pop().unwrap() as u32);
Some(self.stack.pop().unwrap() as u32);
self.stack.pop(); self.stack.pop();
self.stack.pop(); self.stack.pop();
self.stack.push(0); self.stack.push(0);
@ -428,6 +419,14 @@ impl Interpreter {
let functions = module.sections[self.functions_idx] (Function); let functions = module.sections[self.functions_idx] (Function);
let elements = module.sections[self.elements_idx] (Element); let elements = module.sections[self.elements_idx] (Element);
} }
f(self, &Sections { code, types, functions, elements }) f(
self,
&Sections {
code,
types,
functions,
elements,
},
)
} }
} }

View File

@ -13,7 +13,8 @@ fn interpret(wat: &str, name: &str, result: Option<&[u32]>) {
fs::write(input.path(), wat).unwrap(); fs::write(input.path(), wat).unwrap();
let status = Command::new("wat2wasm") let status = Command::new("wat2wasm")
.arg(input.path()) .arg(input.path())
.arg("-o").arg(output.path()) .arg("-o")
.arg(output.path())
.status() .status()
.unwrap(); .unwrap();
println!("status: {}", status); println!("status: {}", status);

View File

@ -1,8 +1,8 @@
extern crate env_logger; extern crate env_logger;
#[macro_use] #[macro_use]
extern crate failure; extern crate failure;
extern crate wasm_bindgen_webidl;
extern crate sourcefile; extern crate sourcefile;
extern crate wasm_bindgen_webidl;
use failure::{Fail, ResultExt}; use failure::{Fail, ResultExt};
use sourcefile::SourceFile; use sourcefile::SourceFile;
@ -35,10 +35,11 @@ fn try_main() -> Result<(), failure::Error> {
let entry = entry.context("getting webidls/enabled/*.webidl entry")?; let entry = entry.context("getting webidls/enabled/*.webidl entry")?;
let path = entry.path(); let path = entry.path();
if path.extension() != Some(OsStr::new("webidl")) { if path.extension() != Some(OsStr::new("webidl")) {
continue continue;
} }
println!("cargo:rerun-if-changed={}", path.display()); println!("cargo:rerun-if-changed={}", path.display());
source = source.add_file(&path) source = source
.add_file(&path)
.with_context(|_| format!("reading contents of file \"{}\"", path.display()))?; .with_context(|_| format!("reading contents of file \"{}\"", path.display()))?;
} }
@ -48,7 +49,9 @@ fn try_main() -> Result<(), failure::Error> {
// the webidl compiler. // the webidl compiler.
let manifest_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); let manifest_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
let manifest = fs::read_to_string(manifest_dir.join("Cargo.toml"))?; let manifest = fs::read_to_string(manifest_dir.join("Cargo.toml"))?;
let features = manifest.lines().skip_while(|f| !f.starts_with("[features]")); let features = manifest
.lines()
.skip_while(|f| !f.starts_with("[features]"));
let enabled_features = env::vars() let enabled_features = env::vars()
.map(|p| p.0) .map(|p| p.0)
@ -56,8 +59,7 @@ fn try_main() -> Result<(), failure::Error> {
.map(|mut p| { .map(|mut p| {
p.drain(0.."CARGO_FEATURE_".len()); p.drain(0.."CARGO_FEATURE_".len());
p p
}) }).collect::<HashSet<_>>();
.collect::<HashSet<_>>();
let mut allowed = Vec::new(); let mut allowed = Vec::new();
for feature in features.filter(|f| !f.starts_with("#") && !f.starts_with("[")) { for feature in features.filter(|f| !f.starts_with("#") && !f.starts_with("[")) {
@ -81,23 +83,31 @@ fn try_main() -> Result<(), failure::Error> {
Err(e) => match e.kind() { Err(e) => match e.kind() {
wasm_bindgen_webidl::ErrorKind::ParsingWebIDLSourcePos(pos) => { wasm_bindgen_webidl::ErrorKind::ParsingWebIDLSourcePos(pos) => {
if let Some(pos) = source.resolve_offset(pos) { if let Some(pos) = source.resolve_offset(pos) {
let ctx = format!("compiling WebIDL into wasm-bindgen bindings in file \ let ctx = format!(
\"{}\", line {} column {}", pos.filename, pos.line + 1, pos.col + 1); "compiling WebIDL into wasm-bindgen bindings in file \
\"{}\", line {} column {}",
pos.filename,
pos.line + 1,
pos.col + 1
);
return Err(e.context(ctx).into()); return Err(e.context(ctx).into());
} else { } else {
return Err(e.context("compiling WebIDL into wasm-bindgen bindings").into()); return Err(e
.context("compiling WebIDL into wasm-bindgen bindings")
.into());
} }
} }
_ => { _ => {
return Err(e.context("compiling WebIDL into wasm-bindgen bindings").into()); return Err(e
.context("compiling WebIDL into wasm-bindgen bindings")
.into());
} }
} },
}; };
let out_dir = env::var("OUT_DIR").context("reading OUT_DIR environment variable")?; let out_dir = env::var("OUT_DIR").context("reading OUT_DIR environment variable")?;
let out_file_path = path::Path::new(&out_dir).join("bindings.rs"); let out_file_path = path::Path::new(&out_dir).join("bindings.rs");
fs::write(&out_file_path, bindings) fs::write(&out_file_path, bindings).context("writing bindings to output file")?;
.context("writing bindings to output file")?;
// run rustfmt on the generated file - really handy for debugging // run rustfmt on the generated file - really handy for debugging
println!("cargo:rerun-if-env-changed=WEBIDL_RUSTFMT_BINDINGS"); println!("cargo:rerun-if-env-changed=WEBIDL_RUSTFMT_BINDINGS");
@ -113,4 +123,3 @@ fn try_main() -> Result<(), failure::Error> {
Ok(()) Ok(())
} }

View File

@ -13,8 +13,8 @@
#![doc(html_root_url = "https://docs.rs/web-sys/0.2")] #![doc(html_root_url = "https://docs.rs/web-sys/0.2")]
extern crate wasm_bindgen;
extern crate js_sys; extern crate js_sys;
extern crate wasm_bindgen;
use js_sys::Object; use js_sys::Object;

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlAnchorElement; use web_sys::HtmlAnchorElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_a() -> HtmlAnchorElement; fn new_a() -> HtmlAnchorElement;
} }
@ -26,9 +26,17 @@ fn test_anchor_element() {
element.set_rel("boop"); element.set_rel("boop");
assert_eq!(element.rel(), "boop", "Should have a rel"); assert_eq!(element.rel(), "boop", "Should have a rel");
assert_eq!(element.referrer_policy(), "", "Shouldn't have a referrer_policy"); assert_eq!(
element.referrer_policy(),
"",
"Shouldn't have a referrer_policy"
);
element.set_referrer_policy("origin"); element.set_referrer_policy("origin");
assert_eq!(element.referrer_policy(), "origin", "Should have a referrer_policy"); assert_eq!(
element.referrer_policy(),
"origin",
"Should have a referrer_policy"
);
assert_eq!(element.hreflang(), "", "Shouldn't have a hreflang"); assert_eq!(element.hreflang(), "", "Shouldn't have a hreflang");
element.set_hreflang("en-us"); element.set_hreflang("en-us");

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlBodyElement; use web_sys::HtmlBodyElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_body() -> HtmlBodyElement; fn new_body() -> HtmlBodyElement;
} }

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlBrElement; use web_sys::HtmlBrElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_br() -> HtmlBrElement; fn new_br() -> HtmlBrElement;
} }

View File

@ -1,15 +1,15 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::{HtmlButtonElement, HtmlFormElement, Node}; use web_sys::{HtmlButtonElement, HtmlFormElement, Node};
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_button() -> HtmlButtonElement; fn new_button() -> HtmlButtonElement;
fn new_form() -> HtmlFormElement; fn new_form() -> HtmlFormElement;
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(js_name = location, js_namespace = document)] #[wasm_bindgen(js_name = location, js_namespace = document)]
static LOCATION: Location; static LOCATION: Location;
@ -37,13 +37,25 @@ fn test_button_element() {
_ => assert!(false, "Shouldn't have a form"), _ => assert!(false, "Shouldn't have a form"),
}; };
assert_eq!(element.form_action(), location, "Should have the pages location"); assert_eq!(
element.form_action(),
location,
"Should have the pages location"
);
element.set_form_action("http://boop.com/"); element.set_form_action("http://boop.com/");
assert_eq!(element.form_action(), "http://boop.com/", "Should have a form_action"); assert_eq!(
element.form_action(),
"http://boop.com/",
"Should have a form_action"
);
assert_eq!(element.form_enctype(), "", "Should have no enctype"); assert_eq!(element.form_enctype(), "", "Should have no enctype");
element.set_form_enctype("text/plain"); element.set_form_enctype("text/plain");
assert_eq!(element.form_enctype(), "text/plain", "Should have a plain text enctype"); assert_eq!(
element.form_enctype(),
"text/plain",
"Should have a plain text enctype"
);
assert_eq!(element.form_method(), "", "Should have no method"); assert_eq!(element.form_method(), "", "Should have no method");
element.set_form_method("POST"); element.set_form_method("POST");
@ -55,7 +67,11 @@ fn test_button_element() {
assert_eq!(element.form_target(), "", "Should have no target"); assert_eq!(element.form_target(), "", "Should have no target");
element.set_form_target("_blank"); element.set_form_target("_blank");
assert_eq!(element.form_target(), "_blank", "Should have a _blank target"); assert_eq!(
element.form_target(),
"_blank",
"Should have a _blank target"
);
assert_eq!(element.name(), "", "Shouldn't have a name"); assert_eq!(element.name(), "", "Shouldn't have a name");
element.set_name("button-name"); element.set_name("button-name");
@ -70,14 +86,22 @@ fn test_button_element() {
assert_eq!(element.value(), "value1", "Should have a value"); assert_eq!(element.value(), "value1", "Should have a value");
assert_eq!(element.will_validate(), false, "Shouldn't validate"); assert_eq!(element.will_validate(), false, "Shouldn't validate");
assert_eq!(element.validation_message().unwrap(), "", "Shouldn't have a value"); assert_eq!(
element.validation_message().unwrap(),
"",
"Shouldn't have a value"
);
assert_eq!(element.check_validity(), true, "Should be valid"); assert_eq!(element.check_validity(), true, "Should be valid");
assert_eq!(element.report_validity(), true, "Should be valid"); assert_eq!(element.report_validity(), true, "Should be valid");
element.set_custom_validity("Boop"); // Method exists but doesn't impact validity element.set_custom_validity("Boop"); // Method exists but doesn't impact validity
assert_eq!(element.check_validity(), true, "Should be valid"); assert_eq!(element.check_validity(), true, "Should be valid");
assert_eq!(element.report_validity(), true, "Should be valid"); assert_eq!(element.report_validity(), true, "Should be valid");
assert_eq!(element.labels().length(), 0, "Should return a node list with no elements"); assert_eq!(
element.labels().length(),
0,
"Should return a node list with no elements"
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
@ -90,15 +114,21 @@ fn test_button_element_in_form() {
// TODO: implement `Clone` for types in `web_sys` to make this easier. // TODO: implement `Clone` for types in `web_sys` to make this easier.
let button = JsValue::from(button); let button = JsValue::from(button);
let as_node = Node::from(button.clone()); let as_node = Node::from(button.clone());
Node::from(JsValue::from(form)).append_child(&as_node).unwrap(); Node::from(JsValue::from(form))
.append_child(&as_node)
.unwrap();
let element = HtmlButtonElement::from(button); let element = HtmlButtonElement::from(button);
match element.form() { match element.form() {
None => assert!(false, "Should have a form"), None => assert!(false, "Should have a form"),
Some(form) => { Some(form) => {
assert!(true, "Should have a form"); assert!(true, "Should have a form");
assert_eq!(form.name(), "test-form", "Form should have a name of test-form"); assert_eq!(
}, form.name(),
"test-form",
"Form should have a name of test-form"
);
}
}; };
assert_eq!(element.type_(), "reset", "Should have a type"); assert_eq!(element.type_(), "reset", "Should have a type");
} }

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlDivElement; use web_sys::HtmlDivElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_div() -> HtmlDivElement; fn new_div() -> HtmlDivElement;
} }

View File

@ -1,15 +1,15 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::Element; use web_sys::Element;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_div() -> Element; fn new_div() -> Element;
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn element() { fn element() {
/* Tests needed for: /* Tests needed for:
namespace_uri namespace_uri
*/ */
let element = new_div(); let element = new_div();
@ -22,20 +22,40 @@ fn element() {
assert_eq!(element.id(), "beep", "Should have an id of 'beep'"); assert_eq!(element.id(), "beep", "Should have an id of 'beep'");
// must_use is set on this result? // must_use is set on this result?
assert_eq!(element.set_attribute("id", "beep").unwrap(), (), "Should set id"); assert_eq!(
element.set_attribute("id", "beep").unwrap(),
(),
"Should set id"
);
assert!(element.has_attribute("id"), "Should now have an id"); assert!(element.has_attribute("id"), "Should now have an id");
assert_eq!(element.remove_attribute("id").unwrap(), (), "Should return nothing if removed"); assert_eq!(
element.remove_attribute("id").unwrap(),
(),
"Should return nothing if removed"
);
assert_eq!(element.class_name(), "", "Shouldn't have a class name"); assert_eq!(element.class_name(), "", "Shouldn't have a class name");
element.set_class_name("test thing"); element.set_class_name("test thing");
assert_eq!(element.class_name(), "test thing", "Should have a class name"); assert_eq!(
assert_eq!(element.get_attribute("class").unwrap(), "test thing", "Should have a class name"); element.class_name(),
assert_eq!(element.remove_attribute("class").unwrap(), (), "Should return nothing if removed"); "test thing",
/* Tests needed for: "Should have a class name"
);
assert_eq!(
element.get_attribute("class").unwrap(),
"test thing",
"Should have a class name"
);
assert_eq!(
element.remove_attribute("class").unwrap(),
(),
"Should return nothing if removed"
);
/* Tests needed for:
get_attribute_ns get_attribute_ns
*/ */
/*TODO should we enable toggle_attribute tests? (Firefox Nightly + Chrome canary only) /*TODO should we enable toggle_attribute tests? (Firefox Nightly + Chrome canary only)
// TODO toggle_attribute should permit a single argument when optional arguments are supported // TODO toggle_attribute should permit a single argument when optional arguments are supported
assert!(!element.has_attribute("disabled"), "Should not be disabled"); assert!(!element.has_attribute("disabled"), "Should not be disabled");
assert!(element.toggle_attribute("disabled", true).unwrap(), "Should return true when attribute is set"); assert!(element.toggle_attribute("disabled", true).unwrap(), "Should return true when attribute is set");
@ -45,35 +65,71 @@ get_attribute_ns
*/ */
assert!(!element.has_attribute("title"), "Should not have a title"); assert!(!element.has_attribute("title"), "Should not have a title");
assert_eq!(element.set_attribute("title", "boop").unwrap(), (), "Should return nothing if set correctly"); assert_eq!(
element.set_attribute("title", "boop").unwrap(),
(),
"Should return nothing if set correctly"
);
assert!(element.has_attribute("title"), "Should have a title"); assert!(element.has_attribute("title"), "Should have a title");
// TODO check get_attribute here when supported // TODO check get_attribute here when supported
assert_eq!(element.remove_attribute("title").unwrap(), (), "Should return nothing if removed"); assert_eq!(
element.remove_attribute("title").unwrap(),
(),
"Should return nothing if removed"
);
assert!(!element.has_attribute("title"), "Should not have a title"); assert!(!element.has_attribute("title"), "Should not have a title");
/* Tests needed for: /* Tests needed for:
set_attribute_ns set_attribute_ns
*/ */
assert!(!element.has_attributes(), "Should not have any attributes"); assert!(!element.has_attributes(), "Should not have any attributes");
assert_eq!(element.set_attribute("title", "boop").unwrap(), (), "Should return nothing if set correctly"); assert_eq!(
element.set_attribute("title", "boop").unwrap(),
(),
"Should return nothing if set correctly"
);
assert!(element.has_attributes(), "Should have attributes"); assert!(element.has_attributes(), "Should have attributes");
assert_eq!(element.remove_attribute("title").unwrap(), (), "Should return nothing if removed"); assert_eq!(
/* Tests needed for: element.remove_attribute("title").unwrap(),
(),
"Should return nothing if removed"
);
/* Tests needed for:
remove_attribute_ns remove_attribute_ns
has_attribure_ns has_attribure_ns
closest closest
*/ */
assert_eq!(element.matches(".this-is-a-thing").unwrap(), false, "Should not match selector"); assert_eq!(
assert_eq!(element.webkit_matches_selector(".this-is-a-thing").unwrap(), false, "Should not match selector"); element.matches(".this-is-a-thing").unwrap(),
false,
"Should not match selector"
);
assert_eq!(
element.webkit_matches_selector(".this-is-a-thing").unwrap(),
false,
"Should not match selector"
);
element.set_class_name("this-is-a-thing"); element.set_class_name("this-is-a-thing");
assert_eq!(element.matches(".this-is-a-thing").unwrap(), true, "Should match selector"); assert_eq!(
assert_eq!(element.webkit_matches_selector(".this-is-a-thing").unwrap(), true, "Should match selector"); element.matches(".this-is-a-thing").unwrap(),
assert_eq!(element.remove_attribute("class").unwrap(), (), "Should return nothing if removed"); true,
"Should match selector"
);
assert_eq!(
element.webkit_matches_selector(".this-is-a-thing").unwrap(),
true,
"Should match selector"
);
assert_eq!(
element.remove_attribute("class").unwrap(),
(),
"Should return nothing if removed"
);
// TODO non standard moz_matches_selector should we even support? // TODO non standard moz_matches_selector should we even support?
/* Tests needed for: /* Tests needed for:
insert_adjacent_element insert_adjacent_element
insert_adjacent_text insert_adjacent_text
set_pointer_capture set_pointer_capture
@ -99,21 +155,42 @@ scroll_left_max
*/ */
assert_eq!(element.inner_html(), "", "Should return no content"); assert_eq!(element.inner_html(), "", "Should return no content");
element.set_inner_html("<strong>Hey!</strong><em>Web!</em>"); element.set_inner_html("<strong>Hey!</strong><em>Web!</em>");
assert_eq!(element.inner_html(), "<strong>Hey!</strong><em>Web!</em>", "Should return HTML conent"); assert_eq!(
assert_eq!(element.query_selector_all("strong").unwrap().length(), 1, "Should return one element"); element.inner_html(),
assert!(element.query_selector("strong").unwrap().is_some(), "Should return an element"); "<strong>Hey!</strong><em>Web!</em>",
"Should return HTML conent"
);
assert_eq!(
element.query_selector_all("strong").unwrap().length(),
1,
"Should return one element"
);
assert!(
element.query_selector("strong").unwrap().is_some(),
"Should return an element"
);
element.set_inner_html(""); element.set_inner_html("");
assert_eq!(element.inner_html(), "", "Should return no content"); assert_eq!(element.inner_html(), "", "Should return no content");
/* Tests needed for: /* Tests needed for:
outer_html outer_html
set_outer_html set_outer_html
insert_adjacent_html insert_adjacent_html
*/ */
assert!(element.query_selector(".none-existant").unwrap().is_none(), "Should return no results"); assert!(
assert_eq!(element.query_selector_all(".none-existant").unwrap().length(), 0, "Should return no results"); element.query_selector(".none-existant").unwrap().is_none(),
/* Tests needed for: "Should return no results"
);
assert_eq!(
element
.query_selector_all(".none-existant")
.unwrap()
.length(),
0,
"Should return no results"
);
/* Tests needed for:
slot slot
set_slot set_slot
request_fullscreen request_fullscreen

View File

@ -7,28 +7,26 @@ use wasm_bindgen_test::*;
use web_sys::Event; use web_sys::Event;
#[wasm_bindgen(module = "./tests/wasm/event.js")] #[wasm_bindgen(module = "./tests/wasm/event.js")]
extern { extern "C" {
fn new_event() -> Promise; fn new_event() -> Promise;
} }
#[wasm_bindgen_test(async)] #[wasm_bindgen_test(async)]
fn event() -> impl Future<Item = (), Error = JsValue> { fn event() -> impl Future<Item = (), Error = JsValue> {
JsFuture::from(new_event()) JsFuture::from(new_event()).map(Event::from).map(|event| {
.map(Event::from) // All DOM interfaces should inherit from `Object`.
.map(|event| { assert!(event.is_instance_of::<Object>());
// All DOM interfaces should inherit from `Object`. let _: &Object = event.as_ref();
assert!(event.is_instance_of::<Object>());
let _: &Object = event.as_ref();
// These should match `new Event`. // These should match `new Event`.
assert!(event.bubbles()); assert!(event.bubbles());
assert!(event.cancelable()); assert!(event.cancelable());
assert!(event.composed()); assert!(event.composed());
// The default behavior not initially prevented, but after // The default behavior not initially prevented, but after
// we call `prevent_default` it better be. // we call `prevent_default` it better be.
assert!(!event.default_prevented()); assert!(!event.default_prevented());
event.prevent_default(); event.prevent_default();
assert!(event.default_prevented()); assert!(event.default_prevented());
}) })
} }

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlHeadElement; use web_sys::HtmlHeadElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_head() -> HtmlHeadElement; fn new_head() -> HtmlHeadElement;
} }

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::Headers; use web_sys::Headers;
#[wasm_bindgen(module = "./tests/wasm/headers.js")] #[wasm_bindgen(module = "./tests/wasm/headers.js")]
extern { extern "C" {
fn new_headers() -> Headers; fn new_headers() -> Headers;
} }

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlHeadingElement; use web_sys::HtmlHeadingElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_heading() -> HtmlHeadingElement; fn new_heading() -> HtmlHeadingElement;
} }

View File

@ -1,18 +1,28 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::{History, ScrollRestoration}; use web_sys::{History, ScrollRestoration};
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(js_name = history, js_namespace = window)] #[wasm_bindgen(js_name = history, js_namespace = window)]
static HISTORY: History; static HISTORY: History;
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn history() { fn history() {
HISTORY.set_scroll_restoration(ScrollRestoration::Manual).expect("failure to set scroll restoration"); HISTORY
assert_eq!(HISTORY.scroll_restoration().unwrap(), ScrollRestoration::Manual); .set_scroll_restoration(ScrollRestoration::Manual)
.expect("failure to set scroll restoration");
assert_eq!(
HISTORY.scroll_restoration().unwrap(),
ScrollRestoration::Manual
);
HISTORY.set_scroll_restoration(ScrollRestoration::Auto).expect("failure to set scroll restoration"); HISTORY
assert_eq!(HISTORY.scroll_restoration().unwrap(), ScrollRestoration::Auto); .set_scroll_restoration(ScrollRestoration::Auto)
.expect("failure to set scroll restoration");
assert_eq!(
HISTORY.scroll_restoration().unwrap(),
ScrollRestoration::Auto
);
} }

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlHrElement; use web_sys::HtmlHrElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_hr() -> HtmlHrElement; fn new_hr() -> HtmlHrElement;
} }
@ -21,4 +21,4 @@ fn test_hr_element() {
hr.set_no_shade(true); hr.set_no_shade(true);
assert_eq!(hr.no_shade(), true); assert_eq!(hr.no_shade(), true);
} }

View File

@ -1,10 +1,10 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
use wasm_bindgen_test::*;
use web_sys::HtmlElement; use web_sys::HtmlElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_html() -> HtmlElement; fn new_html() -> HtmlElement;
} }
@ -56,12 +56,20 @@ fn test_html_element() {
element.set_draggable(true); element.set_draggable(true);
assert!(element.draggable(), "Should be draggable"); assert!(element.draggable(), "Should be draggable");
assert_eq!(element.content_editable(), "inherit", "Shouldn't have a content_editable"); assert_eq!(
element.content_editable(),
"inherit",
"Shouldn't have a content_editable"
);
element.set_content_editable("true"); element.set_content_editable("true");
assert_eq!(element.content_editable(), "true", "Should be content_editable"); assert_eq!(
element.content_editable(),
"true",
"Should be content_editable"
);
assert!(element.is_content_editable(), "Should be content_editable"); assert!(element.is_content_editable(), "Should be content_editable");
/*TODO doesn't work in Chrome /*TODO doesn't work in Chrome
// TODO verify case where menu is passed // TODO verify case where menu is passed
match element.context_menu() { match element.context_menu() {
None => assert!(true, "Shouldn't have a custom menu set"), None => assert!(true, "Shouldn't have a custom menu set"),
@ -77,12 +85,24 @@ fn test_html_element() {
// TODO verify case where we have an offset_parent // TODO verify case where we have an offset_parent
match element.offset_parent() { match element.offset_parent() {
None => assert!(true, "Shouldn't have an offset_parent set"), None => assert!(true, "Shouldn't have an offset_parent set"),
_ => assert!(false, "Shouldn't have a offset_parent set") _ => assert!(false, "Shouldn't have a offset_parent set"),
}; };
// TODO verify when we have offsets // TODO verify when we have offsets
assert_eq!(element.offset_top(), 0, "Shouldn't have an offset_top yet"); assert_eq!(element.offset_top(), 0, "Shouldn't have an offset_top yet");
assert_eq!(element.offset_left(), 0, "Shouldn't have an offset_left yet"); assert_eq!(
assert_eq!(element.offset_width(), 0, "Shouldn't have an offset_width yet"); element.offset_left(),
assert_eq!(element.offset_height(), 0, "Shouldn't have an offset_height yet"); 0,
"Shouldn't have an offset_left yet"
);
assert_eq!(
element.offset_width(),
0,
"Shouldn't have an offset_width yet"
);
assert_eq!(
element.offset_height(),
0,
"Shouldn't have an offset_height yet"
);
} }

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlHtmlElement; use web_sys::HtmlHtmlElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_html() -> HtmlHtmlElement; fn new_html() -> HtmlHtmlElement;
} }

View File

@ -1,14 +1,14 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlInputElement; use web_sys::HtmlInputElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_input() -> HtmlInputElement; fn new_input() -> HtmlInputElement;
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(js_name = location, js_namespace = document)] #[wasm_bindgen(js_name = location, js_namespace = document)]
static LOCATION: Location; static LOCATION: Location;
@ -34,18 +34,25 @@ fn test_input_element() {
element.set_type("text"); element.set_type("text");
assert_eq!(element.autocomplete(), "", "Shouldn't have an autocomplete"); assert_eq!(element.autocomplete(), "", "Shouldn't have an autocomplete");
element.set_autocomplete("on"); element.set_autocomplete("on");
assert_eq!(element.autocomplete(), "on", "Shouldn't have an autocomplete"); assert_eq!(
element.autocomplete(),
"on",
"Shouldn't have an autocomplete"
);
assert!(!element.autofocus(), "Shouldn't have an autofocus"); assert!(!element.autofocus(), "Shouldn't have an autofocus");
element.set_autofocus(true); element.set_autofocus(true);
assert!(element.autofocus(), "Should have an autofocus"); assert!(element.autofocus(), "Should have an autofocus");
element.set_type("checkbox"); element.set_type("checkbox");
assert!(!element.default_checked(), "Shouldn't have an default_checked"); assert!(
!element.default_checked(),
"Shouldn't have an default_checked"
);
element.set_default_checked(true); element.set_default_checked(true);
assert!(element.default_checked(), "Should have an default_checked"); assert!(element.default_checked(), "Should have an default_checked");
/*TODO fix /*TODO fix
assert!(!element.checked(), "Shouldn't be checked"); assert!(!element.checked(), "Shouldn't be checked");
element.set_checked(true); element.set_checked(true);
assert!(element.checked(), "Should be checked"); assert!(element.checked(), "Should be checked");
@ -60,13 +67,25 @@ fn test_input_element() {
_ => assert!(false, "Shouldn't have a form"), _ => assert!(false, "Shouldn't have a form"),
}; };
assert_eq!(element.form_action(), location, "Should have the pages location"); assert_eq!(
element.form_action(),
location,
"Should have the pages location"
);
element.set_form_action("http://boop.com/"); element.set_form_action("http://boop.com/");
assert_eq!(element.form_action(), "http://boop.com/", "Should have a form_action"); assert_eq!(
element.form_action(),
"http://boop.com/",
"Should have a form_action"
);
assert_eq!(element.form_enctype(), "", "Should have no enctype"); assert_eq!(element.form_enctype(), "", "Should have no enctype");
element.set_form_enctype("text/plain"); element.set_form_enctype("text/plain");
assert_eq!(element.form_enctype(), "text/plain", "Should have a plain text enctype"); assert_eq!(
element.form_enctype(),
"text/plain",
"Should have a plain text enctype"
);
assert_eq!(element.form_method(), "", "Should have no method"); assert_eq!(element.form_method(), "", "Should have no method");
element.set_form_method("POST"); element.set_form_method("POST");
@ -78,19 +97,23 @@ fn test_input_element() {
assert_eq!(element.form_target(), "", "Should have no target"); assert_eq!(element.form_target(), "", "Should have no target");
element.set_form_target("_blank"); element.set_form_target("_blank");
assert_eq!(element.form_target(), "_blank", "Should have a _blank target"); assert_eq!(
element.form_target(),
"_blank",
"Should have a _blank target"
);
assert_eq!(element.height(), 0, "Should have no height"); assert_eq!(element.height(), 0, "Should have no height");
element.set_height(12); element.set_height(12);
assert_eq!(element.height(), 0, "Should have no height"); // Doesn't change, TODO check with get_attribute("height")=="12" assert_eq!(element.height(), 0, "Should have no height"); // Doesn't change, TODO check with get_attribute("height")=="12"
/*TODO fails in chrome /*TODO fails in chrome
element.set_type("checkbox"); element.set_type("checkbox");
assert!(element.indeterminate(), "Should be indeterminate"); assert!(element.indeterminate(), "Should be indeterminate");
element.set_checked(true); element.set_checked(true);
assert!(!element.indeterminate(), "Shouldn't be indeterminate"); assert!(!element.indeterminate(), "Shouldn't be indeterminate");
*/ */
/*TODO add tests /*TODO add tests
pub fn indeterminate(&self) -> bool pub fn indeterminate(&self) -> bool
pub fn set_indeterminate(&self, indeterminate: bool) pub fn set_indeterminate(&self, indeterminate: bool)
pub fn input_mode(&self) -> String pub fn input_mode(&self) -> String
@ -110,13 +133,17 @@ pub fn set_multiple(&self, multiple: bool)
assert_eq!(element.name(), "", "Should not have a name"); assert_eq!(element.name(), "", "Should not have a name");
element.set_name("namey"); element.set_name("namey");
assert_eq!(element.name(), "namey", "Should have a name"); assert_eq!(element.name(), "namey", "Should have a name");
/*TODO add tests /*TODO add tests
pub fn pattern(&self) -> String pub fn pattern(&self) -> String
pub fn set_pattern(&self, pattern: &str) pub fn set_pattern(&self, pattern: &str)
*/ */
assert_eq!(element.placeholder(), "", "Should not have a placeholder"); assert_eq!(element.placeholder(), "", "Should not have a placeholder");
element.set_placeholder("some text"); element.set_placeholder("some text");
assert_eq!(element.placeholder(), "some text", "Should have a placeholder"); assert_eq!(
element.placeholder(),
"some text",
"Should have a placeholder"
);
assert!(!element.read_only(), "Should have not be readonly"); assert!(!element.read_only(), "Should have not be readonly");
element.set_read_only(true); element.set_read_only(true);
@ -125,17 +152,17 @@ pub fn set_pattern(&self, pattern: &str)
assert!(!element.required(), "Should have not be required"); assert!(!element.required(), "Should have not be required");
element.set_required(true); element.set_required(true);
assert!(element.required(), "Should be required"); assert!(element.required(), "Should be required");
/*TODO add tests /*TODO add tests
pub fn size(&self) -> u32 pub fn size(&self) -> u32
pub fn set_size(&self, size: u32) pub fn set_size(&self, size: u32)
*/ */
/*TODO fails in chrome /*TODO fails in chrome
element.set_type("image"); element.set_type("image");
assert_eq!(element.src(), "", "Should have no src"); assert_eq!(element.src(), "", "Should have no src");
element.set_value("hey.png"); element.set_value("hey.png");
assert_eq!(element.src(), "hey.png", "Should have a src"); assert_eq!(element.src(), "hey.png", "Should have a src");
*/ */
/*TODO add tests /*TODO add tests
pub fn src(&self) -> String pub fn src(&self) -> String
pub fn set_src(&self, src: &str) pub fn set_src(&self, src: &str)
pub fn step(&self) -> String pub fn step(&self) -> String
@ -145,7 +172,7 @@ pub fn set_type(&self, type_: &str)
pub fn default_value(&self) -> String pub fn default_value(&self) -> String
pub fn set_default_value(&self, default_value: &str) pub fn set_default_value(&self, default_value: &str)
*/ */
/*TODO fails in chrome /*TODO fails in chrome
assert_eq!(element.value(), "", "Should have no value"); assert_eq!(element.value(), "", "Should have no value");
element.set_value("hey!"); element.set_value("hey!");
assert_eq!(element.value(), "hey!", "Should have a value"); assert_eq!(element.value(), "hey!", "Should have a value");
@ -161,13 +188,17 @@ pub fn set_default_value(&self, default_value: &str)
assert_eq!(element.width(), 0, "Should have no width"); // Doesn't change, TODO check with get_attribute("width")=="12" assert_eq!(element.width(), 0, "Should have no width"); // Doesn't change, TODO check with get_attribute("width")=="12"
assert_eq!(element.will_validate(), false, "Shouldn't validate"); assert_eq!(element.will_validate(), false, "Shouldn't validate");
assert_eq!(element.validation_message().unwrap(), "", "Shouldn't have a value"); assert_eq!(
element.validation_message().unwrap(),
"",
"Shouldn't have a value"
);
assert_eq!(element.check_validity(), true, "Should be valid"); assert_eq!(element.check_validity(), true, "Should be valid");
assert_eq!(element.report_validity(), true, "Should be valid"); assert_eq!(element.report_validity(), true, "Should be valid");
element.set_custom_validity("Boop"); // Method exists but doesn't impact validity ?!??! TODO look into element.set_custom_validity("Boop"); // Method exists but doesn't impact validity ?!??! TODO look into
assert_eq!(element.check_validity(), true, "Should be valid"); assert_eq!(element.check_validity(), true, "Should be valid");
assert_eq!(element.report_validity(), true, "Should be valid"); assert_eq!(element.report_validity(), true, "Should be valid");
/*TODO add tests /*TODO add tests
pub fn labels(&self) -> Option<NodeList> pub fn labels(&self) -> Option<NodeList>
pub fn select(&self) pub fn select(&self)
pub fn selection_direction(&self) -> Result<Option<String>, JsValue> pub fn selection_direction(&self) -> Result<Option<String>, JsValue>
@ -187,7 +218,7 @@ pub fn set_selection_range(
assert_eq!(element.align(), "", "Should have no align"); assert_eq!(element.align(), "", "Should have no align");
element.set_align("left"); element.set_align("left");
assert_eq!(element.align(), "left", "Should have an align"); assert_eq!(element.align(), "left", "Should have an align");
/*TODO add tests /*TODO add tests
pub fn use_map(&self) -> String pub fn use_map(&self) -> String
pub fn set_use_map(&self, use_map: &str) pub fn set_use_map(&self, use_map: &str)
pub fn text_length(&self) -> i32 pub fn text_length(&self) -> i32

View File

@ -20,8 +20,8 @@ pub mod div_element;
pub mod element; pub mod element;
pub mod event; pub mod event;
pub mod head_element; pub mod head_element;
pub mod heading_element;
pub mod headers; pub mod headers;
pub mod heading_element;
pub mod history; pub mod history;
pub mod hr_element; pub mod hr_element;
pub mod html_element; pub mod html_element;
@ -30,6 +30,8 @@ pub mod input_element;
//TODO: Both menu-related tests completely break in Chrome, but run fine in Firefox. //TODO: Both menu-related tests completely break in Chrome, but run fine in Firefox.
//pub mod menu_element; //pub mod menu_element;
//pub mod menu_item_element; //pub mod menu_item_element;
pub mod dom_point;
pub mod location;
pub mod meta_element; pub mod meta_element;
pub mod meter_element; pub mod meter_element;
pub mod mod_elements; pub mod mod_elements;
@ -40,18 +42,16 @@ pub mod options_collection;
pub mod output_element; pub mod output_element;
pub mod paragraph_element; pub mod paragraph_element;
pub mod param_element; pub mod param_element;
pub mod performance;
pub mod pre_element; pub mod pre_element;
pub mod progress_element; pub mod progress_element;
pub mod quote_element; pub mod quote_element;
pub mod response; pub mod response;
pub mod select_element;
pub mod script_element; pub mod script_element;
pub mod select_element;
pub mod slot_element; pub mod slot_element;
pub mod span_element; pub mod span_element;
pub mod style_element; pub mod style_element;
pub mod table_element; pub mod table_element;
pub mod title_element; pub mod title_element;
pub mod xpath_result; pub mod xpath_result;
pub mod dom_point;
pub mod performance;
pub mod location;

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlMetaElement; use web_sys::HtmlMetaElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_meta() -> HtmlMetaElement; fn new_meta() -> HtmlMetaElement;
} }
@ -12,14 +12,30 @@ fn test_meter_element() {
let meta = new_meta(); let meta = new_meta();
meta.set_name("keywords"); meta.set_name("keywords");
assert_eq!(meta.name(), "keywords", "Meta should have the name value we gave it."); assert_eq!(
meta.name(),
"keywords",
"Meta should have the name value we gave it."
);
meta.set_http_equiv("content-type"); meta.set_http_equiv("content-type");
assert_eq!(meta.http_equiv(), "content-type", "Meta should have the http_equiv value we gave it."); assert_eq!(
meta.http_equiv(),
"content-type",
"Meta should have the http_equiv value we gave it."
);
meta.set_content("HTML, CSS, XML, JavaScript"); meta.set_content("HTML, CSS, XML, JavaScript");
assert_eq!(meta.content(), "HTML, CSS, XML, JavaScript", "Meta should have the content value we gave it."); assert_eq!(
meta.content(),
"HTML, CSS, XML, JavaScript",
"Meta should have the content value we gave it."
);
meta.set_scheme("text"); meta.set_scheme("text");
assert_eq!(meta.scheme(), "text", "Meta should have the scheme value we gave it."); assert_eq!(
} meta.scheme(),
"text",
"Meta should have the scheme value we gave it."
);
}

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlMeterElement; use web_sys::HtmlMeterElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_meter() -> HtmlMeterElement; fn new_meter() -> HtmlMeterElement;
} }
@ -12,22 +12,45 @@ fn test_meter_element() {
let meter = new_meter(); let meter = new_meter();
meter.set_min(-5.); meter.set_min(-5.);
assert_eq!(meter.min(), -5., "Meter should have the min value we gave it."); assert_eq!(
meter.min(),
-5.,
"Meter should have the min value we gave it."
);
meter.set_max(5.); meter.set_max(5.);
assert_eq!(meter.max(), 5., "Meter should have the max value we gave it."); assert_eq!(
meter.max(),
5.,
"Meter should have the max value we gave it."
);
meter.set_value(2.); meter.set_value(2.);
assert_eq!(meter.value(), 2., "Meter should have the value we gave it."); assert_eq!(meter.value(), 2., "Meter should have the value we gave it.");
meter.set_low(-1.); meter.set_low(-1.);
assert_eq!(meter.low(), -1., "Meter should have the low value we gave it."); assert_eq!(
meter.low(),
-1.,
"Meter should have the low value we gave it."
);
meter.set_high(1.); meter.set_high(1.);
assert_eq!(meter.high(), 1., "Meter should have the high value we gave it."); assert_eq!(
meter.high(),
1.,
"Meter should have the high value we gave it."
);
meter.set_optimum(3.); meter.set_optimum(3.);
assert_eq!(meter.optimum(), 3., "Meter should have the optimum value we gave it."); assert_eq!(
meter.optimum(),
3.,
"Meter should have the optimum value we gave it."
);
assert!(meter.labels().length() == 0, "Our meter shouldn't have any labels associated with it."); assert!(
} meter.labels().length() == 0,
"Our meter shouldn't have any labels associated with it."
);
}

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlModElement; use web_sys::HtmlModElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_del() -> HtmlModElement; fn new_del() -> HtmlModElement;
fn new_ins() -> HtmlModElement; fn new_ins() -> HtmlModElement;
} }
@ -13,16 +13,32 @@ fn test_mod_elements() {
let del = new_del(); let del = new_del();
del.set_cite("https://www.rust-lang.org/en-US/"); del.set_cite("https://www.rust-lang.org/en-US/");
assert_eq!(del.cite(), "https://www.rust-lang.org/en-US/", "Option should have the cite URI we gave it."); assert_eq!(
del.cite(),
"https://www.rust-lang.org/en-US/",
"Option should have the cite URI we gave it."
);
del.set_date_time("Thu Aug 02 2018 18:02:56 GMT-0500 (Central Daylight Time)"); del.set_date_time("Thu Aug 02 2018 18:02:56 GMT-0500 (Central Daylight Time)");
assert_eq!(del.date_time(), "Thu Aug 02 2018 18:02:56 GMT-0500 (Central Daylight Time)", "Option should have the date_time we gave it."); assert_eq!(
del.date_time(),
"Thu Aug 02 2018 18:02:56 GMT-0500 (Central Daylight Time)",
"Option should have the date_time we gave it."
);
let ins = new_ins(); let ins = new_ins();
ins.set_cite("https://www.rust-lang.org/en-US/"); ins.set_cite("https://www.rust-lang.org/en-US/");
assert_eq!(ins.cite(), "https://www.rust-lang.org/en-US/", "Option should have the cite URI we gave it."); assert_eq!(
ins.cite(),
"https://www.rust-lang.org/en-US/",
"Option should have the cite URI we gave it."
);
ins.set_date_time("Thu Aug 02 2018 18:02:56 GMT-0500 (Central Daylight Time)"); ins.set_date_time("Thu Aug 02 2018 18:02:56 GMT-0500 (Central Daylight Time)");
assert_eq!(ins.date_time(), "Thu Aug 02 2018 18:02:56 GMT-0500 (Central Daylight Time)", "Option should have the date_time we gave it."); assert_eq!(
} ins.date_time(),
"Thu Aug 02 2018 18:02:56 GMT-0500 (Central Daylight Time)",
"Option should have the date_time we gave it."
);
}

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlOListElement; use web_sys::HtmlOListElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_olist() -> HtmlOListElement; fn new_olist() -> HtmlOListElement;
} }
@ -12,23 +12,51 @@ fn test_olist_element() {
let olist = new_olist(); let olist = new_olist();
olist.set_reversed(true); olist.set_reversed(true);
assert_eq!(olist.reversed(), true, "Olist should be reversed after we set it to be reversed."); assert_eq!(
olist.reversed(),
true,
"Olist should be reversed after we set it to be reversed."
);
olist.set_reversed(false); olist.set_reversed(false);
assert_eq!(olist.reversed(), false, "Olist should not be reversed after we set it to be not reversed."); assert_eq!(
olist.reversed(),
false,
"Olist should not be reversed after we set it to be not reversed."
);
olist.set_start(23); olist.set_start(23);
assert_eq!(olist.start(), 23, "Olist should have the start value we gave it."); assert_eq!(
olist.start(),
23,
"Olist should have the start value we gave it."
);
olist.set_type("A"); olist.set_type("A");
assert_eq!(olist.type_(), "A", "Olist should be type 'A' after we set it to be type 'A'."); assert_eq!(
olist.type_(),
"A",
"Olist should be type 'A' after we set it to be type 'A'."
);
olist.set_type("I"); olist.set_type("I");
assert_eq!(olist.type_(), "I", "Olist should be type 'I' after we set it to be type 'I'."); assert_eq!(
olist.type_(),
"I",
"Olist should be type 'I' after we set it to be type 'I'."
);
olist.set_compact(true); olist.set_compact(true);
assert_eq!(olist.compact(), true, "Olist should be compact after we set it to be compact."); assert_eq!(
olist.compact(),
true,
"Olist should be compact after we set it to be compact."
);
olist.set_compact(false); olist.set_compact(false);
assert_eq!(olist.compact(), false, "Olist should not be compact after we set it to be not compact."); assert_eq!(
} olist.compact(),
false,
"Olist should not be compact after we set it to be not compact."
);
}

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlOptGroupElement; use web_sys::HtmlOptGroupElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_optgroup() -> HtmlOptGroupElement; fn new_optgroup() -> HtmlOptGroupElement;
} }
@ -12,11 +12,23 @@ fn test_optgroup_element() {
let optgroup = new_optgroup(); let optgroup = new_optgroup();
optgroup.set_disabled(true); optgroup.set_disabled(true);
assert_eq!(optgroup.disabled(), true, "Optgroup should be disabled after we set it to be disabled."); assert_eq!(
optgroup.disabled(),
true,
"Optgroup should be disabled after we set it to be disabled."
);
optgroup.set_disabled(false); optgroup.set_disabled(false);
assert_eq!(optgroup.disabled(), false, "Optgroup should not be disabled after we set it to be not-disabled."); assert_eq!(
optgroup.disabled(),
false,
"Optgroup should not be disabled after we set it to be not-disabled."
);
optgroup.set_label("Group of options below"); optgroup.set_label("Group of options below");
assert_eq!(optgroup.label(), "Group of options below", "Optgroup should have the label we gave it."); assert_eq!(
} optgroup.label(),
"Group of options below",
"Optgroup should have the label we gave it."
);
}

View File

@ -4,40 +4,83 @@ use web_sys::HtmlOptionElement;
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn test_option_element() { fn test_option_element() {
let option = HtmlOptionElement::new_with_text_and_value_and_default_selected_and_selected( let option = HtmlOptionElement::new_with_text_and_value_and_default_selected_and_selected(
"option_text", "option_text",
"option_value", "option_value",
false, false,
true true,
).unwrap(); ).unwrap();
option.set_disabled(true); option.set_disabled(true);
assert_eq!(option.disabled(), true, "Option should be disabled after we set it to be disabled."); assert_eq!(
option.disabled(),
true,
"Option should be disabled after we set it to be disabled."
);
option.set_disabled(false); option.set_disabled(false);
assert_eq!(option.disabled(), false, "Option should not be disabled after we set it to be not-disabled."); assert_eq!(
option.disabled(),
false,
"Option should not be disabled after we set it to be not-disabled."
);
assert!(option.form().is_none(), "Our option should not be associated with a form."); assert!(
option.form().is_none(),
"Our option should not be associated with a form."
);
option.set_label("Well this truly is a neat option"); option.set_label("Well this truly is a neat option");
assert_eq!(option.label(), "Well this truly is a neat option", "Option should have the label we gave it."); assert_eq!(
option.label(),
"Well this truly is a neat option",
"Option should have the label we gave it."
);
option.set_default_selected(true); option.set_default_selected(true);
assert_eq!(option.default_selected(), true, "Option should be default_selected after we set it to be default_selected."); assert_eq!(
option.default_selected(),
true,
"Option should be default_selected after we set it to be default_selected."
);
option.set_default_selected(false); option.set_default_selected(false);
assert_eq!(option.default_selected(), false, "Option should not be default_selected after we set it to be not default_selected."); assert_eq!(
option.default_selected(),
false,
"Option should not be default_selected after we set it to be not default_selected."
);
option.set_selected(true); option.set_selected(true);
assert_eq!(option.selected(), true, "Option should be selected after we set it to be selected."); assert_eq!(
option.selected(),
true,
"Option should be selected after we set it to be selected."
);
option.set_selected(false); option.set_selected(false);
assert_eq!(option.selected(), false, "Option should not be selected after we set it to be not selected."); assert_eq!(
option.selected(),
false,
"Option should not be selected after we set it to be not selected."
);
option.set_value("tomato"); option.set_value("tomato");
assert_eq!(option.value(), "tomato", "Option should have the value we gave it."); assert_eq!(
option.value(),
"tomato",
"Option should have the value we gave it."
);
option.set_text("potato"); option.set_text("potato");
assert_eq!(option.text(), "potato", "Option should have the text we gave it."); assert_eq!(
option.text(),
"potato",
"Option should have the text we gave it."
);
assert_eq!(option.index(), 0, "This should be the first option, since there are no other known options."); assert_eq!(
option.index(),
0,
"This should be the first option, since there are no other known options."
);
} }

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlOptionsCollection; use web_sys::HtmlOptionsCollection;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_food_options_collection() -> HtmlOptionsCollection; fn new_food_options_collection() -> HtmlOptionsCollection;
} }
@ -11,13 +11,33 @@ extern {
fn test_options_collection() { fn test_options_collection() {
let opt_collection = new_food_options_collection(); let opt_collection = new_food_options_collection();
assert!(opt_collection.length() == 4, "Our option collection should have four options."); assert!(
assert!(opt_collection.remove(0).is_ok(), "We should be able to successfully remove an element from an option collection."); opt_collection.length() == 4,
assert!(opt_collection.length() == 3, "Our option collection should have three options after removing one."); "Our option collection should have four options."
);
assert!(
opt_collection.remove(0).is_ok(),
"We should be able to successfully remove an element from an option collection."
);
assert!(
opt_collection.length() == 3,
"Our option collection should have three options after removing one."
);
assert!(opt_collection.set_selected_index(1).is_ok(), "Should be able to set the selected index of an option collection if it is valid."); assert!(
assert_eq!(opt_collection.selected_index().unwrap(), 1, "The second option should be selected in our option collection."); opt_collection.set_selected_index(1).is_ok(),
"Should be able to set the selected index of an option collection if it is valid."
);
assert_eq!(
opt_collection.selected_index().unwrap(),
1,
"The second option should be selected in our option collection."
);
opt_collection.set_length(1234); opt_collection.set_length(1234);
assert_eq!(opt_collection.length(), 1234, "Our option collections length should update after being set to 1234."); assert_eq!(
} opt_collection.length(),
1234,
"Our option collections length should update after being set to 1234."
);
}

View File

@ -1,25 +1,43 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlOutputElement; use web_sys::HtmlOutputElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_output() -> HtmlOutputElement; fn new_output() -> HtmlOutputElement;
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn test_output_element() { fn test_output_element() {
let output = new_output(); let output = new_output();
assert!(output.html_for().length() == 0, "Our basic <output> should have no html associated with it."); assert!(
assert!(output.form().is_none(), "Our basic <output> should have no form associated with it."); output.html_for().length() == 0,
"Our basic <output> should have no html associated with it."
);
assert!(
output.form().is_none(),
"Our basic <output> should have no form associated with it."
);
output.set_name("Calculation result"); output.set_name("Calculation result");
assert_eq!(output.name(), "Calculation result", "Output name should be 'Calculation result'."); assert_eq!(
output.name(),
"Calculation result",
"Output name should be 'Calculation result'."
);
assert_eq!(output.type_(), "output", "Our basic <output> should have an type of 'output'."); assert_eq!(
output.type_(),
"output",
"Our basic <output> should have an type of 'output'."
);
output.set_default_value("27"); output.set_default_value("27");
assert_eq!(output.default_value(), "27", "Default output value should be '27'."); assert_eq!(
output.default_value(),
"27",
"Default output value should be '27'."
);
output.set_value("49"); output.set_value("49");
assert_eq!(output.value(), "49", "Output value should be '49'."); assert_eq!(output.value(), "49", "Output value should be '49'.");
@ -27,15 +45,27 @@ fn test_output_element() {
// TODO: Fails in Chrome, but not in Firefox. // TODO: Fails in Chrome, but not in Firefox.
//assert!(output.will_validate(), "Output should validate by default (maybe browser dependent?)"); //assert!(output.will_validate(), "Output should validate by default (maybe browser dependent?)");
assert!(output.validity().valid(), "Our <output>s validity should be true."); assert!(
output.validity().valid(),
"Our <output>s validity should be true."
);
assert!(output.validation_message().is_ok(), "We should be able to retrieve some validation message from our <output>."); assert!(
output.validation_message().is_ok(),
"We should be able to retrieve some validation message from our <output>."
);
assert!(output.check_validity(), "Our <output> should be valid."); assert!(output.check_validity(), "Our <output> should be valid.");
assert!(output.report_validity(), "Our <output> should report valid."); assert!(
output.report_validity(),
"Our <output> should report valid."
);
output.set_custom_validity("Some scary error message."); output.set_custom_validity("Some scary error message.");
assert!(output.labels().length() == 0, "Our basic <output> shouldn't have any labels associated with it."); assert!(
} output.labels().length() == 0,
"Our basic <output> shouldn't have any labels associated with it."
);
}

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlParagraphElement; use web_sys::HtmlParagraphElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_paragraph() -> HtmlParagraphElement; fn new_paragraph() -> HtmlParagraphElement;
} }
@ -11,5 +11,9 @@ extern {
fn test_paragraph_element() { fn test_paragraph_element() {
let paragraph = new_paragraph(); let paragraph = new_paragraph();
paragraph.set_align("right"); paragraph.set_align("right");
assert_eq!(paragraph.align(), "right", "Paragraph should be aligned 'right'."); assert_eq!(
} paragraph.align(),
"right",
"Paragraph should be aligned 'right'."
);
}

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlParamElement; use web_sys::HtmlParamElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_param() -> HtmlParamElement; fn new_param() -> HtmlParamElement;
} }
@ -14,11 +14,23 @@ fn test_param_element() {
assert_eq!(param.name(), "color", "Name of param should be 'color'."); assert_eq!(param.name(), "color", "Name of param should be 'color'.");
param.set_value("purple"); param.set_value("purple");
assert_eq!(param.value(), "purple", "Value of param should be 'purple'."); assert_eq!(
param.value(),
"purple",
"Value of param should be 'purple'."
);
param.set_value_type("ref"); param.set_value_type("ref");
assert_eq!(param.value_type(), "ref", "Value type of param should be 'ref'."); assert_eq!(
param.value_type(),
"ref",
"Value type of param should be 'ref'."
);
param.set_type("text/plain"); param.set_type("text/plain");
assert_eq!(param.type_(), "text/plain", "Value of param should be 'text/plain'."); assert_eq!(
} param.type_(),
"text/plain",
"Value of param should be 'text/plain'."
);
}

View File

@ -3,7 +3,7 @@ use wasm_bindgen_test::*;
use web_sys::Performance; use web_sys::Performance;
#[wasm_bindgen] #[wasm_bindgen]
extern { extern "C" {
#[wasm_bindgen(js_name = performance)] #[wasm_bindgen(js_name = performance)]
static PERFORMANCE: Performance; static PERFORMANCE: Performance;
} }

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlPreElement; use web_sys::HtmlPreElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_pre() -> HtmlPreElement; fn new_pre() -> HtmlPreElement;
} }
@ -12,4 +12,4 @@ fn test_pre_element() {
let pre = new_pre(); let pre = new_pre();
pre.set_width(150); pre.set_width(150);
assert_eq!(pre.width(), 150, "Pre width should be 150."); assert_eq!(pre.width(), 150, "Pre width should be 150.");
} }

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlProgressElement; use web_sys::HtmlProgressElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_progress() -> HtmlProgressElement; fn new_progress() -> HtmlProgressElement;
} }
@ -11,11 +11,22 @@ extern {
fn test_progress_element() { fn test_progress_element() {
let progress = new_progress(); let progress = new_progress();
progress.set_max(150.5); progress.set_max(150.5);
assert_eq!(progress.max(), 150.5, "Maximum progress value should be 150.5."); assert_eq!(
progress.max(),
150.5,
"Maximum progress value should be 150.5."
);
progress.set_value(22.); progress.set_value(22.);
assert_eq!(progress.value(), 22., "Progress value should be 22 units."); assert_eq!(progress.value(), 22., "Progress value should be 22 units.");
assert_eq!(progress.position(), (22. / 150.5), "Progress position should be 22 divided by the max possible value."); assert_eq!(
progress.position(),
(22. / 150.5),
"Progress position should be 22 divided by the max possible value."
);
assert!(progress.labels().length() == 0, "Our simple progress bar shouldn't be associated with any labels."); assert!(
} progress.labels().length() == 0,
"Our simple progress bar shouldn't be associated with any labels."
);
}

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::HtmlQuoteElement; use web_sys::HtmlQuoteElement;
#[wasm_bindgen(module = "./tests/wasm/element.js")] #[wasm_bindgen(module = "./tests/wasm/element.js")]
extern { extern "C" {
fn new_quote() -> HtmlQuoteElement; fn new_quote() -> HtmlQuoteElement;
} }
@ -11,5 +11,8 @@ extern {
fn test_quote_element() { fn test_quote_element() {
let quote = new_quote(); let quote = new_quote();
quote.set_cite("https://en.wikipedia.org/wiki/Rust_(programming_language)"); quote.set_cite("https://en.wikipedia.org/wiki/Rust_(programming_language)");
assert_eq!(quote.cite(), "https://en.wikipedia.org/wiki/Rust_(programming_language)"); assert_eq!(
} quote.cite(),
"https://en.wikipedia.org/wiki/Rust_(programming_language)"
);
}

View File

@ -1,9 +1,9 @@
use wasm_bindgen_test::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
use web_sys::Response; use web_sys::Response;
#[wasm_bindgen(module = "./tests/wasm/response.js")] #[wasm_bindgen(module = "./tests/wasm/response.js")]
extern { extern "C" {
fn new_response() -> Response; fn new_response() -> Response;
} }

Some files were not shown because too many files have changed in this diff Show More