merge master

This commit is contained in:
Jannik Keye
2018-07-06 09:31:58 +02:00
56 changed files with 4646 additions and 11610 deletions

View File

@ -6,6 +6,7 @@ module.exports = {
node: true node: true
}, },
extends: 'eslint:recommended', extends: 'eslint:recommended',
parser: 'babel-eslint',
parserOptions: { parserOptions: {
sourceType: 'module' sourceType: 'module'
}, },
@ -24,8 +25,10 @@ module.exports = {
'always' 'always'
], ],
'no-console': 0, 'no-console': 0,
'no-undef': 'no-undef': 'warn'
'warn', },
'no-unused-vars': 'warn' globals: {
BigInt64Array: true,
BigUint64Array: true
} }
}; };

View File

@ -1,20 +1,38 @@
language: rust language: rust
sudo: false sudo: false
INSTALL_NODE_VIA_NVM: &INSTALL_NODE_VIA_NVM
- rustup target add wasm32-unknown-unknown
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
- source ~/.nvm/nvm.sh
- nvm install v10.5
DEPLOY_TO_GITHUB: &DEPLOY_TO_GITHUB
before_deploy:
|
name="wasm-bindgen-$TRAVIS_TAG-$TARGET"
mkdir "$name"
cp "target/$TARGET/release/{wasm-bindgen,wasm2es6js}" "$name/"
cp README.md LICENSE-MIT LICENSE-APACHE "$name/"
tar czvf "$name.tar.gz" "$name"
deploy:
api_key:
secure: "qCiELnEnvyKpWHDttgTNf+ElZGbWlvthu5aOIj5nYfov+h6g1+mkWnDFP6at/WPlE78zE/f/z/dL2KB2I7w/cxH/T4P1nWh0A9DvrpY6hqWkK2pgN5dPeWE/a4flI7AdH0A6wMRw7m00uMgDjlzN78v7XueccpJCxSO5allQN5jweAQvMX2QA07TbLRJc7Lq6lfVwSf8OfrcO8qCbcIzJTsC4vtbh6jkUYg1OAaU2tAYlskBy9ZYmHWCExIAu/zxzcJY9OpApPD9Ea4CyrsfjniAyRBJ87Weh/sP4XhiWeRPVmvA4HAzv4Pps9ps+Ar5QmsX53rhKQ3id7/VPR8ggaAHxrYUiJPvJRtbP6cKKOlDiK0ooP+vI4vjxWeNVj9ibEolSYOlT0ENIvPK1BppA6VgAoJOjwPr0Q16Ma4AmvLkIkowJiXCm2Jlje/5c0vPEAGJVgUtkj3jFQzgXwyEMpzxUlhHmYpmnfeaM0tK/Kiiwe1monL/ydMlyfV55kNylylCg+XoTnf420AFChKbD4DM5Z7ZsjU9g8fF3LUoN0sKpmLDp+GvwjLi9YtGogWB71Q2MFp43MSL0YLshkyYYoZKrVMiy5J9hKNUxhT2jNEq53Z69syIHHMCxHL9GoAcuHxIKOA7uTMW0aCoyy2I+dfAKKsrUGwGYaNC5LZdUQI="
file_glob: true
file:
- wasm-bindgen-$TRAVIS_TAG-$TARGET.tar.gz
on:
tags: true
provider: releases
skip_cleanup: true
matrix: matrix:
include: include:
# CLI builds on stable
- rust: stable
install: true
script: cargo build --manifest-path crates/cli/Cargo.toml
# Tests pass on nightly # Tests pass on nightly
- rust: nightly - rust: nightly
before_install: env: JOB=test-bindgen
- rustup target add wasm32-unknown-unknown before_install: *INSTALL_NODE_VIA_NVM
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
- source ~/.nvm/nvm.sh
- nvm install v10.5
install: install:
# dirties git repository, there doesn't seem to be a way to resolve this other than # dirties git repository, there doesn't seem to be a way to resolve this other than
# to run `npm install` twice or by using `npm ci` (which is currently broken) # to run `npm install` twice or by using `npm ci` (which is currently broken)
@ -22,82 +40,70 @@ matrix:
script: script:
- cargo test - cargo test
# Check JS output from all tests against eslint # Check JS output from all tests against eslint
- ./node_modules/.bin/eslint ./target/generated-tests/*/out*.js - ./node_modules/.bin/eslint ./target/generated-tests/*/out*js
env: RUST_BACKTRACE=1 addons:
firefox: latest
# All examples work
- rust: nightly
env: JOB=examples-build
install: *INSTALL_NODE_VIA_NVM
script:
- mkdir node_modules
- |
for dir in `ls examples | grep -v README | grep -v asm.js | grep -v no_modules`; do
(cd examples/$dir &&
sed -i 's/: "webpack-dev-server"/: "webpack"/' package.json &&
ln -s ../../node_modules . &&
./build.sh) || exit 1;
done
# Tests pass on nightly using yarn # Tests pass on nightly using yarn
- rust: nightly - rust: nightly
before_install: env: JOB=test-yarn-smoke
- rustup target add wasm32-unknown-unknown before_install: *INSTALL_NODE_VIA_NVM
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash install:
- source ~/.nvm/nvm.sh
- nvm install v10.5
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.7.0 - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.7.0
- export PATH=$HOME/.yarn/bin:$PATH - export PATH=$HOME/.yarn/bin:$PATH
install:
- yarn install --freeze-lockfile - yarn install --freeze-lockfile
script: script: cargo test api::works
- cargo test
# Check JS output from all tests against eslint
- ./node_modules/.bin/eslint ./target/generated-tests/*/out*.js
env: RUST_BACKTRACE=1
# WebIDL tests pass on nightly # WebIDL tests pass on nightly
- rust: nightly - rust: nightly
env: JOB=test-webidl
before_install: rustup component add rustfmt-preview --toolchain nightly before_install: rustup component add rustfmt-preview --toolchain nightly
script: (cd crates/webidl && cargo test) script: cargo test --manifest-path crates/webidl/Cargo.toml
env: RUST_BACKTRACE=1 RUST_LOG=wasm_bindgen_webidl
# Dist linux binary # Dist linux binary
- env: TARGET=x86_64-unknown-linux-musl DEPLOY=1 - rust: nightly
rust: nightly env: JOB=dist-linux TARGET=x86_64-unknown-linux-musl
before_script: rustup target add $TARGET before_script: rustup target add $TARGET
script: cargo build --manifest-path crates/cli/Cargo.toml --release --target $TARGET script: cargo build --manifest-path crates/cli/Cargo.toml --release --target $TARGET
addons: addons:
apt: apt:
packages: packages:
- musl-tools - musl-tools
<<: *DEPLOY_TO_GITHUB
# Dist OSX binary # Dist OSX binary
- os: osx - rust: nightly
rust: nightly os: osx
env: MACOSX_DEPLOYMENT_TARGET=10.7 DEPLOY=1 TARGET=x86_64-apple-darwin env: JOB=dist-osx MACOSX_DEPLOYMENT_TARGET=10.7 TARGET=x86_64-apple-darwin
script: cargo build --manifest-path crates/cli/Cargo.toml --release --target $TARGET script: cargo build --manifest-path crates/cli/Cargo.toml --release --target $TARGET
install: true <<: *DEPLOY_TO_GITHUB
# We can build the tool on nightly # CLI builds on stable
- rust: stable
env: JOB=check-stable-cli
script: cargo check --manifest-path crates/cli/Cargo.toml
# CLI builds on nightly
- rust: nightly - rust: nightly
script: cargo install --debug --path crates/cli env: JOB=check-nightly-cli
script: cargo check --manifest-path crates/cli/Cargo.toml
# All examples work
- rust: nightly
before_install:
- rustup target add wasm32-unknown-unknown
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
- source ~/.nvm/nvm.sh
- nvm install v10.5
script:
- |
(cd examples/hello_world && sed -i 's/: "webpack-dev-server"/: "webpack"/' package.json && ./build.sh)
- |
(cd examples/smorgasboard && sed -i 's/: "webpack-dev-server"/: "webpack"/' package.json && ./build.sh)
- |
(cd examples/console_log && sed -i 's/: "webpack-dev-server"/: "webpack"/' package.json && ./build.sh)
- |
(cd examples/math && sed -i 's/: "webpack-dev-server"/: "webpack"/' package.json && ./build.sh)
- |
(cd examples/dom && sed -i 's/: "webpack-dev-server"/: "webpack"/' package.json && ./build.sh)
- |
(cd examples/wasm-in-wasm && sed -i 's/: "webpack-dev-server"/: "webpack"/' package.json && ./build.sh)
- |
(cd examples/char && sed -i 's/: "webpack-dev-server"/: "webpack"/' package.json && ./build.sh)
- |
(cd examples/closures && sed -i 's/: "webpack-dev-server"/: "webpack"/' package.json && ./build.sh)
- |
(cd examples/comments && sed -i 's/: "webpack-dev-server"/: "webpack"/' package.json && ./build.sh)
# Build the guide. # Build the guide.
- rust: stable - rust: stable
env: JOB=guide-build-and-deploy
cache: cache:
- cargo - cargo
before_script: before_script:
@ -119,25 +125,3 @@ matrix:
notifications: notifications:
email: email:
on_success: never on_success: never
before_deploy:
|
if [[ "$DEPLOY" == "1" ]]; then
name="wasm-bindgen-$TRAVIS_TAG-$TARGET"
mkdir "$name"
cp "target/$TARGET/release/{wasm-bindgen,wasm2es6js}" "$name/"
cp README.md LICENSE-MIT LICENSE-APACHE "$name/"
tar czvf "$name.tar.gz" "$name"
fi
deploy:
api_key:
secure: "qCiELnEnvyKpWHDttgTNf+ElZGbWlvthu5aOIj5nYfov+h6g1+mkWnDFP6at/WPlE78zE/f/z/dL2KB2I7w/cxH/T4P1nWh0A9DvrpY6hqWkK2pgN5dPeWE/a4flI7AdH0A6wMRw7m00uMgDjlzN78v7XueccpJCxSO5allQN5jweAQvMX2QA07TbLRJc7Lq6lfVwSf8OfrcO8qCbcIzJTsC4vtbh6jkUYg1OAaU2tAYlskBy9ZYmHWCExIAu/zxzcJY9OpApPD9Ea4CyrsfjniAyRBJ87Weh/sP4XhiWeRPVmvA4HAzv4Pps9ps+Ar5QmsX53rhKQ3id7/VPR8ggaAHxrYUiJPvJRtbP6cKKOlDiK0ooP+vI4vjxWeNVj9ibEolSYOlT0ENIvPK1BppA6VgAoJOjwPr0Q16Ma4AmvLkIkowJiXCm2Jlje/5c0vPEAGJVgUtkj3jFQzgXwyEMpzxUlhHmYpmnfeaM0tK/Kiiwe1monL/ydMlyfV55kNylylCg+XoTnf420AFChKbD4DM5Z7ZsjU9g8fF3LUoN0sKpmLDp+GvwjLi9YtGogWB71Q2MFp43MSL0YLshkyYYoZKrVMiy5J9hKNUxhT2jNEq53Z69syIHHMCxHL9GoAcuHxIKOA7uTMW0aCoyy2I+dfAKKsrUGwGYaNC5LZdUQI="
file_glob: true
file:
- wasm-bindgen-$TRAVIS_TAG-$TARGET.tar.gz
on:
condition: $DEPLOY = 1
tags: true
provider: releases
skip_cleanup: true

View File

@ -33,7 +33,7 @@ serde = { version = "1.0", optional = true }
serde_json = { version = "1.0", optional = true } serde_json = { version = "1.0", optional = true }
[dev-dependencies] [dev-dependencies]
wasm-bindgen-cli-support = { path = "crates/cli-support", version = '=0.2.11' } wasm-bindgen-test-project-builder = { path = "crates/test-project-builder", version = '=0.2.11' }
[workspace] [workspace]
members = [ members = [

View File

@ -84,6 +84,7 @@ pub struct ImportStatic {
pub struct ImportType { pub struct ImportType {
pub vis: syn::Visibility, pub vis: syn::Visibility,
pub name: Ident, pub name: Ident,
pub attrs: Vec<syn::Attribute>,
} }
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] #[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
@ -469,6 +470,7 @@ impl Program {
ImportKind::Type(ImportType { ImportKind::Type(ImportType {
vis: f.vis, vis: f.vis,
name: f.ident, name: f.ident,
attrs: f.attrs,
}) })
} }

View File

@ -505,8 +505,10 @@ impl ToTokens for ast::ImportType {
fn to_tokens(&self, tokens: &mut TokenStream) { fn to_tokens(&self, tokens: &mut TokenStream) {
let vis = &self.vis; let vis = &self.vis;
let name = &self.name; let name = &self.name;
let attrs = &self.attrs;
(quote! { (quote! {
#[allow(bad_style)] #[allow(bad_style)]
#(#attrs)*
#vis struct #name { #vis struct #name {
obj: ::wasm_bindgen::JsValue, obj: ::wasm_bindgen::JsValue,
} }

View File

@ -60,7 +60,7 @@ impl<'a> Context<'a> {
if let Some(ref c) = comments { if let Some(ref c) = comments {
self.globals.push_str(c); self.globals.push_str(c);
} }
let global = if self.config.nodejs { let global = if self.use_node_require() {
if contents.starts_with("class") { if contents.starts_with("class") {
format!("{1}\nmodule.exports.{0} = {0};\n", name, contents) format!("{1}\nmodule.exports.{0} = {0};\n", name, contents)
} else { } else {
@ -410,12 +410,14 @@ impl<'a> Context<'a> {
.unwrap_or("wasm_bindgen"), .unwrap_or("wasm_bindgen"),
) )
} else { } else {
let import_wasm = if self.config.nodejs { let import_wasm = if self.globals.len() == 0 {
String::new()
} else if self.use_node_require() {
self.footer self.footer
.push_str(&format!("wasm = require('./{}_bg');", module_name)); .push_str(&format!("wasm = require('./{}_bg');", module_name));
format!("var wasm;") format!("var wasm;")
} else { } else {
format!("import * as wasm from './{}_bg.wasm';", module_name) format!("import * as wasm from './{}_bg';", module_name)
}; };
format!( format!(
@ -956,7 +958,6 @@ impl<'a> Context<'a> {
return Ok(()); return Ok(());
} }
self.require_internal_export("__wbindgen_malloc")?; self.require_internal_export("__wbindgen_malloc")?;
self.expose_uint64_memory();
self.global(&format!( self.global(&format!(
" "
function {}(arg) {{ function {}(arg) {{
@ -976,7 +977,9 @@ impl<'a> Context<'a> {
if !self.exposed_globals.insert("text_encoder") { if !self.exposed_globals.insert("text_encoder") {
return; return;
} }
if self.config.nodejs { if self.config.nodejs_experimental_modules {
self.imports.push_str("import { TextEncoder } from 'util';\n");
} else if self.config.nodejs {
self.global( self.global(
" "
const TextEncoder = require('util').TextEncoder; const TextEncoder = require('util').TextEncoder;
@ -1002,7 +1005,9 @@ impl<'a> Context<'a> {
if !self.exposed_globals.insert("text_decoder") { if !self.exposed_globals.insert("text_decoder") {
return; return;
} }
if self.config.nodejs { if self.config.nodejs_experimental_modules {
self.imports.push_str("import { TextDecoder } from 'util';\n");
} else if self.config.nodejs {
self.global( self.global(
" "
const TextDecoder = require('util').TextDecoder; const TextDecoder = require('util').TextDecoder;
@ -1059,7 +1064,7 @@ impl<'a> Context<'a> {
if !self.exposed_globals.insert("get_array_js_value_from_wasm") { if !self.exposed_globals.insert("get_array_js_value_from_wasm") {
return; return;
} }
self.expose_get_array_u32_from_wasm(); self.expose_uint32_memory();
self.expose_take_object(); self.expose_take_object();
self.global( self.global(
" "
@ -1584,6 +1589,10 @@ impl<'a> Context<'a> {
*section.payload_mut() = contents.into_bytes(); *section.payload_mut() = contents.into_bytes();
self.module.sections_mut().push(Section::Custom(section)); self.module.sections_mut().push(Section::Custom(section));
} }
fn use_node_require(&self) -> bool {
self.config.nodejs && !self.config.nodejs_experimental_modules
}
} }
impl<'a, 'b> SubContext<'a, 'b> { impl<'a, 'b> SubContext<'a, 'b> {
@ -1807,9 +1816,10 @@ impl<'a, 'b> SubContext<'a, 'b> {
let target = if let Some(g) = getter { let target = if let Some(g) = getter {
if import.structural { if import.structural {
format!( format!(
"function(y) {{ "function() {{
return this.{}; return {}.{};
}}", }}",
if is_static { &class } else { "this" },
g g
) )
} else { } else {
@ -1826,8 +1836,9 @@ impl<'a, 'b> SubContext<'a, 'b> {
if import.structural { if import.structural {
format!( format!(
"function(y) {{ "function(y) {{
this.{} = y; {}.{} = y;
}}", }}",
if is_static { &class } else { "this" },
s s
) )
} else { } else {
@ -1943,7 +1954,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
let name = import.js_namespace.as_ref().map(|s| &**s).unwrap_or(item); let name = import.js_namespace.as_ref().map(|s| &**s).unwrap_or(item);
if self.cx.imported_names.insert(name.to_string()) { if self.cx.imported_names.insert(name.to_string()) {
if self.cx.config.nodejs { if self.cx.use_node_require() {
self.cx.imports.push_str(&format!( self.cx.imports.push_str(&format!(
"\ "\
const {} = require('{}').{};\n\ const {} = require('{}').{};\n\

View File

@ -24,6 +24,7 @@ pub mod wasm2es6js;
pub struct Bindgen { pub struct Bindgen {
path: Option<PathBuf>, path: Option<PathBuf>,
nodejs: bool, nodejs: bool,
nodejs_experimental_modules: bool,
browser: bool, browser: bool,
no_modules: bool, no_modules: bool,
no_modules_global: Option<String>, no_modules_global: Option<String>,
@ -37,6 +38,7 @@ impl Bindgen {
Bindgen { Bindgen {
path: None, path: None,
nodejs: false, nodejs: false,
nodejs_experimental_modules: false,
browser: false, browser: false,
no_modules: false, no_modules: false,
no_modules_global: None, no_modules_global: None,
@ -56,6 +58,11 @@ impl Bindgen {
self self
} }
pub fn nodejs_experimental_modules(&mut self, node: bool) -> &mut Bindgen {
self.nodejs_experimental_modules = node;
self
}
pub fn browser(&mut self, browser: bool) -> &mut Bindgen { pub fn browser(&mut self, browser: bool) -> &mut Bindgen {
self.browser = browser; self.browser = browser;
self self
@ -162,7 +169,8 @@ impl Bindgen {
cx.finalize(stem)? cx.finalize(stem)?
}; };
let js_path = out_dir.join(stem).with_extension("js"); let extension = if self.nodejs_experimental_modules { "mjs" } else { "js" };
let js_path = out_dir.join(stem).with_extension(extension);
File::create(&js_path) File::create(&js_path)
.and_then(|mut f| f.write_all(reset_indentation(&js).as_bytes())) .and_then(|mut f| f.write_all(reset_indentation(&js).as_bytes()))
.with_context(|_| format!("failed to write `{}`", js_path.display()))?; .with_context(|_| format!("failed to write `{}`", js_path.display()))?;
@ -177,7 +185,7 @@ impl Bindgen {
let wasm_path = out_dir.join(format!("{}_bg", stem)).with_extension("wasm"); let wasm_path = out_dir.join(format!("{}_bg", stem)).with_extension("wasm");
if self.nodejs { if self.nodejs {
let js_path = wasm_path.with_extension("js"); let js_path = wasm_path.with_extension(extension);
let shim = self.generate_node_wasm_import(&module, &wasm_path); let shim = self.generate_node_wasm_import(&module, &wasm_path);
File::create(&js_path) File::create(&js_path)
.and_then(|mut f| f.write_all(shim.as_bytes())) .and_then(|mut f| f.write_all(shim.as_bytes()))
@ -200,22 +208,62 @@ impl Bindgen {
} }
let mut shim = String::new(); let mut shim = String::new();
if self.nodejs_experimental_modules {
for (i, module) in imports.iter().enumerate() {
shim.push_str(&format!("import * as import{} from '{}';\n",
i, module));
}
// On windows skip the leading `/` which comes out when we parse a
// url to use `C:\...` instead of `\C:\...`
shim.push_str(&format!("
import * as path from 'path';
import * as fs from 'fs';
import * as url from 'url';
import * as process from 'process';
let file = path.dirname(url.parse(import.meta.url).pathname);
if (process.platform === 'win32') {{
file = file.substring(1);
}}
const bytes = fs.readFileSync(path.join(file, '{}'));
", path.file_name().unwrap().to_str().unwrap()));
} else {
shim.push_str(&format!("
const path = require('path').join(__dirname, '{}');
const bytes = require('fs').readFileSync(path);
", path.file_name().unwrap().to_str().unwrap()));
}
shim.push_str("let imports = {};\n"); shim.push_str("let imports = {};\n");
for module in imports { for (i, module) in imports.iter().enumerate() {
shim.push_str(&format!("imports['{0}'] = require('{0}');\n", module)); if self.nodejs_experimental_modules {
shim.push_str(&format!("imports['{}'] = import{};\n", module, i));
} else {
shim.push_str(&format!("imports['{0}'] = require('{0}');\n", module));
}
} }
shim.push_str(&format!( shim.push_str(&format!(
" "
const join = require('path').join; const wasmModule = new WebAssembly.Module(bytes);
const bytes = require('fs').readFileSync(join(__dirname, '{}')); const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
const wasmModule = new WebAssembly.Module(bytes);
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
module.exports = wasmInstance.exports;
", ",
path.file_name().unwrap().to_str().unwrap()
)); ));
if self.nodejs_experimental_modules {
if let Some(e) = m.export_section() {
for name in e.entries().iter().map(|e| e.field()) {
shim.push_str("export const ");
shim.push_str(name);
shim.push_str(" = wasmInstance.exports.");
shim.push_str(name);
shim.push_str(";\n");
}
}
} else {
shim.push_str("module.exports = wasmInstance.exports;\n");
}
reset_indentation(&shim) reset_indentation(&shim)
} }
} }

View File

@ -0,0 +1,8 @@
[package]
name = "wasm-bindgen-test-project-builder"
version = "0.2.11"
authors = ["Nick Fitzgerald <fitzgen@gmail.com>"]
[dependencies]
lazy_static = "1"
wasm-bindgen-cli-support = { path = "../cli-support", version = '=0.2.11' }

View File

@ -0,0 +1,830 @@
#[macro_use]
extern crate lazy_static;
extern crate wasm_bindgen_cli_support as cli;
use std::env;
use std::fs::{self, File};
use std::thread;
use std::io::{self, Read, Write};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio, Child, ChildStdin};
use std::net::TcpStream;
use std::sync::atomic::*;
use std::sync::{Once, ONCE_INIT, Mutex};
use std::time::{Duration, Instant};
static CNT: AtomicUsize = ATOMIC_USIZE_INIT;
thread_local!(static IDX: usize = CNT.fetch_add(1, Ordering::SeqCst));
pub struct Project {
files: Vec<(String, String)>,
debug: bool,
node: bool,
nodejs_experimental_modules: bool,
no_std: bool,
serde: bool,
rlib: bool,
webpack: bool,
node_args: Vec<String>,
deps: Vec<String>,
headless: bool,
}
pub fn project() -> Project {
let dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
let mut lockfile = String::new();
fs::File::open(&dir.join("Cargo.lock"))
.unwrap()
.read_to_string(&mut lockfile)
.unwrap();
Project {
debug: true,
no_std: false,
node: true,
nodejs_experimental_modules: true,
webpack: false,
serde: false,
rlib: false,
headless: false,
deps: Vec::new(),
node_args: Vec::new(),
files: vec![
("Cargo.lock".to_string(), lockfile),
],
}
}
fn root() -> PathBuf {
let idx = IDX.with(|x| *x);
let mut me = env::current_exe().unwrap();
me.pop(); // chop off exe name
me.pop(); // chop off `deps`
me.pop(); // chop off `debug` / `release`
me.push("generated-tests");
me.push(&format!("test{}", idx));
return me;
}
fn assert_bigint_support() -> Option<&'static str> {
static BIGINT_SUPPORED: AtomicUsize = ATOMIC_USIZE_INIT;
static INIT: Once = ONCE_INIT;
INIT.call_once(|| {
let mut cmd = Command::new("node");
cmd.arg("-e").arg("BigInt");
cmd.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped());
if cmd.status().unwrap().success() {
BIGINT_SUPPORED.store(1, Ordering::SeqCst);
return;
}
cmd.arg("--harmony-bigint");
if cmd.status().unwrap().success() {
BIGINT_SUPPORED.store(2, Ordering::SeqCst);
return;
}
});
match BIGINT_SUPPORED.load(Ordering::SeqCst) {
1 => return None,
2 => return Some("--harmony-bigint"),
_ => panic!(
"the version of node.js that is installed for these tests \
does not support `BigInt`, you may wish to try installing \
node 10 to fix this"
),
}
}
impl Project {
/// Add a new file with the specified contents to this project, the `name`
/// can have slahes for files in subdirectories.
pub fn file(&mut self, name: &str, contents: &str) -> &mut Project {
self.files.push((name.to_string(), contents.to_string()));
self
}
/// Enable debug mode in wasm-bindgen for this test
pub fn debug(&mut self, debug: bool) -> &mut Project {
self.debug = debug;
self
}
/// Depend on `wasm-bindgen` without the `std` feature enabled.
pub fn no_std(&mut self, no_std: bool) -> &mut Project {
self.no_std = no_std;
self
}
/// Depend on the `serde` feature of `wasm-bindgen`
pub fn serde(&mut self, serde: bool) -> &mut Project {
self.serde = serde;
self
}
/// Generate an rlib instead of a cdylib in the generated Cargo project
pub fn rlib(&mut self, rlib: bool) -> &mut Project {
self.rlib = rlib;
self
}
/// Depend on a crate from crates.io, like serde.
pub fn depend(&mut self, dep: &str) -> &mut Project {
self.deps.push(dep.to_string());
self
}
/// Enables or disables node.js experimental modules output
pub fn nodejs_experimental_modules(&mut self, node: bool) -> &mut Project {
self.nodejs_experimental_modules = node;
self
}
/// Enables or disables the usage of webpack for this project
pub fn webpack(&mut self, webpack: bool) -> &mut Project {
self.webpack = webpack;
self
}
/// Add a path dependency to the generated project
pub fn add_local_dependency(&mut self, name: &str, path: &str) -> &mut Project {
self.deps
.push(format!("{} = {{ path = '{}' }}", name, path));
self
}
/// Returns the crate name that will be used for the generated crate, this
/// name changes between test runs and is generated at runtime.
pub fn crate_name(&self) -> String {
format!("test{}", IDX.with(|x| *x))
}
/// Flag this project as requiring bigint support in Node
pub fn requires_bigint(&mut self) -> &mut Project {
if let Some(arg) = assert_bigint_support() {
self.node_args.push(arg.to_string());
}
self
}
/// This test requires a headless web browser
pub fn headless(&mut self, headless: bool) -> &mut Project {
self.headless = headless;
self
}
/// Write this project to the filesystem, ensuring all files are ready to
/// go.
pub fn build(&mut self) -> (PathBuf, PathBuf) {
if self.headless {
self.webpack = true;
}
if self.webpack {
self.node = false;
self.nodejs_experimental_modules = false;
}
self.ensure_webpack_config();
self.ensure_test_entry();
if self.headless {
self.ensure_index_html();
self.ensure_run_headless_js();
}
let webidl_modules = self.generate_webidl_bindings();
self.generate_js_entry(webidl_modules);
let mut manifest = format!(
r#"
[package]
name = "test{}"
version = "0.0.1"
authors = []
[workspace]
[lib]
"#,
IDX.with(|x| *x)
);
if !self.rlib {
manifest.push_str("crate-type = [\"cdylib\"]\n");
}
manifest.push_str("[build-dependencies]\n");
manifest.push_str("wasm-bindgen-webidl = { path = '");
manifest.push_str(env!("CARGO_MANIFEST_DIR"));
manifest.push_str("/../webidl' }\n");
manifest.push_str("[dependencies]\n");
for dep in self.deps.iter() {
manifest.push_str(dep);
manifest.push_str("\n");
}
manifest.push_str("wasm-bindgen = { path = '");
manifest.push_str(env!("CARGO_MANIFEST_DIR"));
manifest.push_str("/../..'");
if self.no_std {
manifest.push_str(", default-features = false");
}
if self.serde {
manifest.push_str(", features = ['serde-serialize']");
}
manifest.push_str(" }\n");
self.files.push(("Cargo.toml".to_string(), manifest));
let root = root();
drop(fs::remove_dir_all(&root));
for &(ref file, ref contents) in self.files.iter() {
let mut dst = root.join(file);
if self.nodejs_experimental_modules &&
dst.extension().and_then(|s| s.to_str()) == Some("js")
{
dst = dst.with_extension("mjs");
}
if dst.extension().and_then(|s| s.to_str()) == Some("ts") &&
!self.webpack
{
panic!("webpack needs to be enabled to use typescript");
}
fs::create_dir_all(dst.parent().unwrap()).unwrap();
fs::File::create(&dst)
.unwrap()
.write_all(contents.as_ref())
.unwrap();
}
let target_dir = root.parent().unwrap() // chop off test name
.parent().unwrap(); // chop off `generated-tests`
(root.clone(), target_dir.to_path_buf())
}
fn ensure_webpack_config(&mut self) {
if !self.webpack {
return
}
let needs_typescript = self.files.iter().any(|t| t.0.ends_with(".ts"));
let mut rules = String::new();
let mut extensions = format!("'.js', '.wasm'");
if needs_typescript {
rules.push_str("
{
test: /.ts$/,
use: 'ts-loader',
exclude: /node_modules/,
}
");
extensions.push_str(", '.ts'");
}
let target = if self.headless { "web" } else { "node" };
self.files.push((
"webpack.config.js".to_string(),
format!(r#"
const path = require('path');
const fs = require('fs');
let nodeModules = {{}};
// Webpack bundles the modules from node_modules.
// For node target, we will not have `fs` module
// inside the `node_modules` folder.
// This reads the directories in `node_modules`
// and give that to externals and webpack ignores
// to bundle the modules listed as external.
if ('{2}' == 'node') {{
fs.readdirSync('node_modules')
.filter(module => module !== '.bin')
.forEach(mod => {{
// External however,expects browser environment.
// To make it work in `node` target we
// prefix commonjs here.
nodeModules[mod] = 'commonjs ' + mod;
}});
}}
module.exports = {{
entry: './run.js',
mode: "development",
devtool: "source-map",
module: {{
rules: [{}]
}},
resolve: {{
extensions: [{}]
}},
output: {{
filename: 'bundle.js',
path: path.resolve(__dirname, '.')
}},
target: '{}',
externals: nodeModules
}};
"#, rules, extensions, target)
));
if needs_typescript {
self.files.push((
"tsconfig.json".to_string(),
r#"
{
"compilerOptions": {
"noEmitOnError": true,
"noImplicitAny": true,
"noImplicitThis": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"noImplicitReturns": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"alwaysStrict": true,
"strict": true,
"target": "es5",
"lib": ["es2015"]
}
}
"#.to_string(),
));
}
}
fn ensure_test_entry(&mut self) {
if !self
.files
.iter()
.any(|(path, _)| path == "test.ts" || path == "test.js")
{
self.files.push((
"test.js".to_string(),
r#"export {test} from './out';"#.to_string(),
));
}
}
fn ensure_index_html(&mut self) {
self.file(
"index.html",
r#"
<!DOCTYPE html>
<html>
<body>
<div id="error"></div>
<div id="logs"></div>
<div id="status"></div>
<script src="bundle.js"></script>
</body>
</html>
"#,
);
}
fn ensure_run_headless_js(&mut self) {
self.file("run-headless.js", include_str!("run-headless.js"));
}
fn generate_webidl_bindings(&mut self) -> Vec<PathBuf> {
let mut res = Vec::new();
let mut origpaths = Vec::new();
for (path, _) in &self.files {
let path = Path::new(&path);
let extension = path.extension().map(|x| x.to_str().unwrap());
if extension != Some("webidl") {
continue;
}
res.push(path.with_extension("rs"));
origpaths.push(path.to_owned());
}
if res.is_empty() {
return res;
}
let mut buildrs = r#"
extern crate wasm_bindgen_webidl;
use wasm_bindgen_webidl::compile_file;
use std::env;
use std::fs::{self, File};
use std::io::Write;
use std::path::Path;
fn main() {
let dest = env::var("OUT_DIR").unwrap();
"#.to_string();
for (path, origpath) in res.iter().zip(origpaths.iter()) {
buildrs.push_str(&format!(
r#"
fs::create_dir_all("{}").unwrap();
File::create(&Path::new(&dest).join("{}"))
.unwrap()
.write_all(
compile_file(Path::new("{}"))
.unwrap()
.as_bytes()
)
.unwrap();
"#,
path.parent().unwrap().to_str().unwrap(),
path.to_str().unwrap(),
origpath.to_str().unwrap(),
));
self.files.push((
Path::new("src").join(path).to_str().unwrap().to_string(),
format!(
r#"include!(concat!(env!("OUT_DIR"), "/{}"));"#,
path.display()
),
));
}
buildrs.push('}');
self.files.push(("build.rs".to_string(), buildrs));
res
}
fn generate_js_entry(&mut self, modules: Vec<PathBuf>) {
let mut runjs = String::new();
let esm_imports = self.webpack || !self.node || self.nodejs_experimental_modules;
if self.headless {
runjs.push_str(
r#"
window.document.body.innerHTML += "\nTEST_START\n";
console.log = function(...args) {
const logs = document.getElementById('logs');
for (let msg of args) {
logs.innerHTML += `${msg}<br/>\n`;
}
};
"#,
);
} else if esm_imports {
runjs.push_str("import * as process from 'process';\n");
} else {
runjs.push_str("const process = require('process');\n");
}
runjs.push_str("
function run(test, wasm) {
test.test();
if (wasm.assertStackEmpty)
wasm.assertStackEmpty();
if (wasm.assertSlabEmpty)
wasm.assertSlabEmpty();
}
");
if self.headless {
runjs.push_str("
function onerror(error) {
const errors = document.getElementById('error');
let content = `exception: ${e.message}\\nstack: ${e.stack}`;
errors.innerHTML = `<pre>${content}</pre>`;
}
");
} else {
runjs.push_str("
function onerror(error) {
console.error(error);
process.exit(1);
}
");
}
if esm_imports {
runjs.push_str("console.log('importing modules...');\n");
runjs.push_str("const modules = [];\n");
for module in modules.iter() {
runjs.push_str(&format!("modules.push(import('./{}'))",
module.with_extension("").display()));
}
let import_wasm = if self.debug {
"import('./out')"
} else {
"new Promise((a, b) => a({}))"
};
runjs.push_str(&format!("
Promise.all(modules)
.then(results => {{
results.map(module => Object.assign(global, module));
return Promise.all([import('./test'), {}])
}})
.then(result => run(result[0], result[1]))
", import_wasm));
if self.headless {
runjs.push_str(".then(() => {
document.getElementById('status').innerHTML = 'good';
})");
}
runjs.push_str(".catch(onerror)\n");
if self.headless {
runjs.push_str("
.finally(() => {
window.document.body.innerHTML += \"\\nTEST_DONE\";
})
");
}
} else {
assert!(!self.debug);
assert!(modules.is_empty());
runjs.push_str("
const test = require('./test');
try {
run(test, {});
} catch (e) {
onerror(e);
}
");
}
self.files.push(("run.js".to_string(), runjs));
}
/// Build the Cargo project for the wasm target, returning the root of the
/// project and the target directory where output is located.
pub fn cargo_build(&mut self) -> (PathBuf, PathBuf) {
let (root, target_dir) = self.build();
let mut cmd = Command::new("cargo");
cmd.arg("build")
.arg("--target")
.arg("wasm32-unknown-unknown")
.current_dir(&root)
.env("CARGO_TARGET_DIR", &target_dir)
// Catch any warnings in generated code because we don't want any
.env("RUSTFLAGS", "-Dwarnings");
run(&mut cmd, "cargo");
(root, target_dir)
}
/// Generate wasm-bindgen bindings for the compiled artifacts of this
/// project, returning the root of the project as well as the target
/// directory where output was generated.
pub fn gen_bindings(&mut self) -> (PathBuf, PathBuf) {
let (root, target_dir) = self.cargo_build();
let idx = IDX.with(|x| *x);
let out = target_dir.join(&format!("wasm32-unknown-unknown/debug/test{}.wasm", idx));
let as_a_module = root.join("out.wasm");
fs::hard_link(&out, &as_a_module).unwrap();
let _x = wrap_step("running wasm-bindgen");
let res = cli::Bindgen::new()
.input_path(&as_a_module)
.typescript(self.webpack)
.debug(self.debug)
.nodejs(self.node)
.nodejs_experimental_modules(self.nodejs_experimental_modules)
.generate(&root);
if let Err(e) = res {
for e in e.causes() {
println!("- {}", e);
}
panic!("failed");
}
(root, target_dir)
}
/// Execute this project's `run.js`, ensuring that everything runs through
/// node or a browser correctly
pub fn test(&mut self) {
let (root, _target_dir) = self.gen_bindings();
if !self.webpack {
let mut cmd = Command::new("node");
cmd.args(&self.node_args);
if self.nodejs_experimental_modules {
cmd.arg("--experimental-modules").arg("run.mjs");
} else {
cmd.arg("run.js");
}
cmd.current_dir(&root);
run(&mut cmd, "node");
return
}
// Generate typescript bindings for the wasm module
{
let _x = wrap_step("running wasm2es6js");
let mut wasm = Vec::new();
File::open(root.join("out_bg.wasm"))
.unwrap()
.read_to_end(&mut wasm)
.unwrap();
let obj = cli::wasm2es6js::Config::new()
.base64(true)
.generate(&wasm)
.expect("failed to convert wasm to js");
File::create(root.join("out_bg.d.ts"))
.unwrap()
.write_all(obj.typescript().as_bytes())
.unwrap();
}
// move files from the root into each test, it looks like this may be
// needed for webpack to work well when invoked concurrently.
fs::hard_link("package.json", root.join("package.json")).unwrap();
if !Path::new("node_modules").exists() {
panic!("\n\nfailed to find `node_modules`, have you run `npm install` yet?\n\n");
}
let cwd = env::current_dir().unwrap();
symlink_dir(&cwd.join("node_modules"), &root.join("node_modules")).unwrap();
if self.headless {
return self.test_headless(&root)
}
// Execute webpack to generate a bundle
let mut cmd = self.npm();
cmd.arg("run").arg("run-webpack").current_dir(&root);
run(&mut cmd, "npm");
let mut cmd = Command::new("node");
cmd.args(&self.node_args);
cmd.arg(root.join("bundle.js")).current_dir(&root);
run(&mut cmd, "node");
}
fn npm(&self) -> Command {
if cfg!(windows) {
let mut c = Command::new("cmd");
c.arg("/c");
c.arg("npm");
c
} else {
Command::new("npm")
}
}
fn test_headless(&mut self, root: &Path) {
// Serialize all headless tests since they require starting
// webpack-dev-server on the same port.
lazy_static! {
static ref MUTEX: Mutex<()> = Mutex::new(());
}
let _lock = MUTEX.lock().unwrap();
let mut cmd = self.npm();
cmd.arg("run")
.arg("run-webpack-dev-server")
.arg("--")
.arg("--quiet")
.arg("--watch-stdin")
.current_dir(&root);
let _server = run_in_background(&mut cmd, "webpack-dev-server".into());
// wait for webpack-dev-server to come online and bind its port
loop {
if TcpStream::connect("127.0.0.1:8080").is_ok() {
break;
}
thread::sleep(Duration::from_millis(100));
}
let path = env::var_os("PATH").unwrap_or_default();
let mut path = env::split_paths(&path).collect::<Vec<_>>();
path.push(root.join("node_modules/geckodriver"));
let mut cmd = Command::new("node");
cmd.args(&self.node_args)
.arg(root.join("run-headless.js"))
.current_dir(&root)
.env("PATH", env::join_paths(&path).unwrap());
run(&mut cmd, "node");
}
/// Reads JS generated by `wasm-bindgen` to a string.
pub fn read_js(&self) -> String {
let path = root().join(if self.nodejs_experimental_modules {
"out.mjs"
} else {
"out.js"
});
println!("js, {:?}", &path);
fs::read_to_string(path).expect("Unable to read js")
}
}
#[cfg(unix)]
fn symlink_dir(a: &Path, b: &Path) -> io::Result<()> {
use std::os::unix::fs::symlink;
symlink(a, b)
}
#[cfg(windows)]
fn symlink_dir(a: &Path, b: &Path) -> io::Result<()> {
use std::os::windows::fs::symlink_dir;
symlink_dir(a, b)
}
fn wrap_step(desc: &str) -> WrapStep {
println!("···················································");
println!("{}", desc);
WrapStep { start: Instant::now() }
}
struct WrapStep { start: Instant }
impl Drop for WrapStep {
fn drop(&mut self) {
let dur = self.start.elapsed();
println!(
"dur: {}.{:03}s",
dur.as_secs(),
dur.subsec_nanos() / 1_000_000
);
}
}
pub fn run(cmd: &mut Command, program: &str) {
let _x = wrap_step(&format!("running {:?}", cmd));
let output = match cmd.output() {
Ok(output) => output,
Err(err) => panic!("failed to spawn `{}`: {}", program, err),
};
println!("exit: {}", output.status);
if output.stdout.len() > 0 {
println!("stdout ---\n{}", String::from_utf8_lossy(&output.stdout));
}
if output.stderr.len() > 0 {
println!("stderr ---\n{}", String::from_utf8_lossy(&output.stderr));
}
assert!(output.status.success());
}
struct BackgroundChild {
name: String,
child: Child,
stdin: Option<ChildStdin>,
stdout: Option<thread::JoinHandle<io::Result<String>>>,
stderr: Option<thread::JoinHandle<io::Result<String>>>,
}
impl Drop for BackgroundChild {
fn drop(&mut self) {
drop(self.stdin.take());
let status = self.child.wait().expect("failed to wait on child");
let stdout = self
.stdout
.take()
.unwrap()
.join()
.unwrap()
.expect("failed to read stdout");
let stderr = self
.stderr
.take()
.unwrap()
.join()
.unwrap()
.expect("failed to read stderr");
println!("···················································");
println!("background {}", self.name);
println!("status: {}", status);
println!("stdout ---\n{}", stdout);
println!("stderr ---\n{}", stderr);
}
}
fn run_in_background(cmd: &mut Command, name: String) -> BackgroundChild {
cmd.stdout(Stdio::piped());
cmd.stderr(Stdio::piped());
cmd.stdin(Stdio::piped());
let mut child = cmd.spawn().expect(&format!("should spawn {} OK", name));
let mut stdout = child.stdout.take().unwrap();
let mut stderr = child.stderr.take().unwrap();
let stdin = child.stdin.take().unwrap();
let stdout = thread::spawn(move || {
let mut t = String::new();
stdout.read_to_string(&mut t)?;
Ok(t)
});
let stderr = thread::spawn(move || {
let mut t = String::new();
stderr.read_to_string(&mut t)?;
Ok(t)
});
BackgroundChild {
name,
child,
stdout: Some(stdout),
stderr: Some(stderr),
stdin: Some(stdin),
}
}

View File

@ -0,0 +1,128 @@
const process = require("process");
const { promisify } = require("util");
const { Builder, By, Key, logging, promise, until } = require("selenium-webdriver");
const firefox = require("selenium-webdriver/firefox");
promise.USE_PROMISE_MANAGER = false;
const prefs = new logging.Preferences();
prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG);
const opts = new firefox.Options();
opts.headless();
if (process.env.WASM_BINDGEN_FIREFOX_BIN_PATH) {
console.log("Using custom firefox-bin: $WASM_BINDGEN_FIREFOX_BIN_PATH =",
process.env.WASM_BINDGEN_FIREFOX_BIN_PATH);
opts.setBinary(process.env.WASM_BINDGEN_FIREFOX_BIN_PATH);
}
console.log("Using Firefox options:", opts);
const driver = new Builder()
.forBrowser("firefox")
.setFirefoxOptions(opts)
.build();
const SECONDS = 1000;
const MINUTES = 60 * SECONDS;
const start = Date.now();
const timeSinceStart = () => {
const elapsed = Date.now() - start;
const minutes = Math.floor(elapsed / MINUTES);
const seconds = elapsed % MINUTES / SECONDS;
return `${minutes}m${seconds.toFixed(3)}s`;
};
async function logged(msg, promise) {
console.log(`${timeSinceStart()}: START: ${msg}`);
try {
const value = await promise;
console.log(`${timeSinceStart()}: END: ${msg}`);
return value;
} catch (e) {
console.log(`${timeSinceStart()}: ERROR: ${msg}: ${e}\n\n${e.stack}`);
throw e;
}
}
async function main() {
let body;
try {
await logged(
"load http://localhost:8080/index.html",
driver.get("http://localhost:8080/index.html")
);
body = driver.findElement(By.tagName("body"));
await logged(
"Waiting for <body> to include text 'TEST_START'",
driver.wait(
until.elementTextContains(body, "TEST_START"),
1 * MINUTES
)
);
await logged(
"Waiting for <body> to include text 'TEST_DONE'",
driver.wait(
until.elementTextContains(body, "TEST_DONE"),
1 * MINUTES
)
);
const status = await logged(
"get #status text",
body.findElement(By.id("status")).getText()
);
console.log(`Test status is: "${status}"`);
if (status != "good") {
throw new Error(`test failed with status = ${status}`);
}
} finally {
const logs = await logged(
"getting browser logs",
body.findElement(By.id("logs")).getText()
);
if (logs.length > 0) {
console.log("logs:");
logs.split("\n").forEach(line => {
console.log(` ${line}`);
});
}
const errors = await logged(
"getting browser errors",
body.findElement(By.id("error")).getText()
);
if (errors.length > 0) {
console.log("errors:");
errors.split("\n").forEach(line => {
console.log(` ${line}`);
});
}
const bodyText = await logged(
"getting browser body",
body.getText()
);
if (bodyText.length > 0) {
console.log("body:");
bodyText.split("\n").forEach(line => {
console.log(` ${line}`);
});
}
}
}
main()
.finally(() => driver.quit())
.catch(e => {
console.error(`Got an error: ${e}\n\nStack: ${e.stack}`);
process.exit(1);
});

View File

@ -171,6 +171,7 @@ impl WebidlParse<()> for webidl::ast::NonPartialInterface {
pub_token: Default::default(), pub_token: Default::default(),
}), }),
name: rust_ident(&self.name), name: rust_ident(&self.name),
attrs: Vec::new(),
}), }),
}); });

View File

@ -42,3 +42,16 @@ Finally, you can run the tests with `cargo`:
```shell ```shell
cargo test cargo test
``` ```
### Headless Browser Tests
Some tests are configured to run in a headless Firefox instance. To run these
tests, you must have Firefox installed. If you have Firefox installed in a
non-default, custom location you can set the `WASM_BINDGEN_FIREFOX_BIN_PATH`
environment variable to the path to your `firefox-bin`.
For example:
```shell
WASM_BINDGEN_FIREFOX_BIN_PATH=/home/fitzgen/firefox/firefox-bin cargo test
```

View File

@ -40,7 +40,7 @@ Rust arguments of JS functions imported to Rust.
### From JS to Rust ### From JS to Rust
Unfortunately the opposite direction from above, going from JS to Rust, is a bit Unfortunately the opposite direction from above, going from JS to Rust, is a bit
mroe complicated. Here we've got three traits: more complicated. Here we've got three traits:
```rust ```rust
pub trait FromWasmAbi: WasmDescribe { pub trait FromWasmAbi: WasmDescribe {

8091
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,20 @@
{ {
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"run-webpack": "webpack" "run-webpack": "webpack",
"run-webpack-dev-server": "webpack-dev-server",
"run-geckodriver": "geckodriver"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^9.4.6", "@types/node": "^9.4.6",
"eslint": "^5.0.1",
"geckodriver": "^1.11.0",
"selenium-webdriver": "^4.0.0-alpha.1",
"ts-loader": "^4.0.1", "ts-loader": "^4.0.1",
"typescript": "^2.7.2", "typescript": "^2.7.2",
"webpack": "^4.11.1", "webpack": "^4.11.1",
"webpack-cli": "^2.0.10", "webpack-cli": "^2.0.10",
"eslint": "^4.19.1" "webpack-dev-server": "^3.1.4",
"babel-eslint": "^8.2.5"
} }
} }

179
src/js.rs
View File

@ -141,6 +141,13 @@ extern "C" {
#[wasm_bindgen(method)] #[wasm_bindgen(method)]
pub fn filter(this: &Array, predicate: &mut FnMut(JsValue, u32, Array) -> bool) -> Array; pub fn filter(this: &Array, predicate: &mut FnMut(JsValue, u32, Array) -> bool) -> Array;
/// The `find()` method returns the value of the first element in the array that satisfies
/// the provided testing function. Otherwise `undefined` is returned.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
#[wasm_bindgen(method)]
pub fn find(this: &Array, predicate: &mut FnMut(JsValue, u32, Array) -> bool) -> JsValue;
/// The includes() method determines whether an array includes a certain /// The includes() method determines whether an array includes a certain
/// element, returning true or false as appropriate. /// element, returning true or false as appropriate.
/// ///
@ -254,6 +261,45 @@ extern "C" {
pub fn unshift(this: &Array, value: JsValue) -> u32; pub fn unshift(this: &Array, value: JsValue) -> u32;
} }
// ArrayBuffer
#[wasm_bindgen]
extern "C" {
pub type ArrayBuffer;
/// The `ArrayBuffer` object is used to represent a generic,
/// fixed-length raw binary data buffer. You cannot directly
/// manipulate the contents of an `ArrayBuffer`; instead, you
/// create one of the typed array objects or a `DataView` object
/// which represents the buffer in a specific format, and use that
/// to read and write the contents of the buffer.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
#[wasm_bindgen(constructor)]
pub fn new(length: u32) -> ArrayBuffer;
/// The `slice()` method returns a new `ArrayBuffer` whose contents
/// are a copy of this `ArrayBuffer`'s bytes from begin, inclusive,
/// up to end, exclusive.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/isView
#[wasm_bindgen(static_method_of = ArrayBuffer, js_name = isView)]
pub fn is_view(value: JsValue) -> bool;
/// The `slice()` method returns a new `ArrayBuffer` whose contents
/// are a copy of this `ArrayBuffer`'s bytes from begin, inclusive,
/// up to end, exclusive.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/slice
#[wasm_bindgen(method)]
pub fn slice(this: &ArrayBuffer, begin: u32) -> ArrayBuffer;
/// Like `slice()` but with the `end` argument.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/slice
#[wasm_bindgen(method, js_name = slice)]
pub fn slice_with_end(this: &ArrayBuffer, begin: u32, end: u32) -> ArrayBuffer;
}
// Array Iterator // Array Iterator
#[wasm_bindgen] #[wasm_bindgen]
extern "C" { extern "C" {
@ -445,7 +491,7 @@ extern {
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size
#[wasm_bindgen(method, getter, structural)] #[wasm_bindgen(method, getter, structural)]
pub fn size(this: &Map) -> Number; pub fn size(this: &Map) -> u32;
} }
// Map Iterator // Map Iterator
@ -480,12 +526,13 @@ extern {
#[wasm_bindgen] #[wasm_bindgen]
extern "C" { extern "C" {
pub type Math; pub type Math;
/// The Math.abs() function returns the absolute value of a number, that is /// The Math.abs() function returns the absolute value of a number, that is
/// Math.abs(x) = |x| /// Math.abs(x) = |x|
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn abs(x: f64) -> Number; pub fn abs(x: f64) -> f64;
/// The Math.acos() function returns the arccosine (in radians) of a /// The Math.acos() function returns the arccosine (in radians) of a
/// number, that is ∀x∊[-1;1] /// number, that is ∀x∊[-1;1]
@ -493,7 +540,7 @@ extern "C" {
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acos /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acos
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn acos(x: f64) -> Number; pub fn acos(x: f64) -> f64;
/// The Math.acosh() function returns the hyperbolic arc-cosine of a /// The Math.acosh() function returns the hyperbolic arc-cosine of a
/// number, that is ∀x ≥ 1 /// number, that is ∀x ≥ 1
@ -501,7 +548,7 @@ extern "C" {
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn acosh(x: f64) -> Number; pub fn acosh(x: f64) -> f64;
/// The Math.asin() function returns the arcsine (in radians) of a /// The Math.asin() function returns the arcsine (in radians) of a
/// number, that is ∀x ∊ [-1;1] /// number, that is ∀x ∊ [-1;1]
@ -509,27 +556,27 @@ extern "C" {
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asin /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asin
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn asin(x: f64) -> Number; pub fn asin(x: f64) -> f64;
/// The Math.asinh() function returns the hyperbolic arcsine of a /// The Math.asinh() function returns the hyperbolic arcsine of a
/// number, that is Math.asinh(x) = arsinh(x) = the unique y such that sinh(y) = x /// number, that is Math.asinh(x) = arsinh(x) = the unique y such that sinh(y) = x
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn asinh(x: f64) -> Number; pub fn asinh(x: f64) -> f64;
/// The Math.atan() function returns the arctangent (in radians) of a /// The Math.atan() function returns the arctangent (in radians) of a
/// number, that is Math.atan(x) = arctan(x) = the unique y ∊ [-π2;π2]such that /// number, that is Math.atan(x) = arctan(x) = the unique y ∊ [-π2;π2]such that
/// tan(y) = x /// tan(y) = x
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn atan(x: f64) -> Number; pub fn atan(x: f64) -> f64;
/// The Math.atan2() function returns the arctangent of the quotient of /// The Math.atan2() function returns the arctangent of the quotient of
/// its arguments. /// its arguments.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2 /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn atan2(y: f64, x: f64) -> Number; pub fn atan2(y: f64, x: f64) -> f64;
/// The Math.atanh() function returns the hyperbolic arctangent of a number, /// The Math.atanh() function returns the hyperbolic arctangent of a number,
/// that is ∀x ∊ (-1,1), Math.atanh(x) = arctanh(x) = the unique y such that /// that is ∀x ∊ (-1,1), Math.atanh(x) = arctanh(x) = the unique y such that
@ -537,35 +584,35 @@ extern "C" {
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn atanh(x: f64) -> Number; pub fn atanh(x: f64) -> f64;
/// The Math.cbrt() function returns the cube root of a number, that is /// The Math.cbrt() function returns the cube root of a number, that is
/// Math.cbrt(x) = x^3 = the unique y such that y^3 = x /// Math.cbrt(x) = x^3 = the unique y such that y^3 = x
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn cbrt(x: f64) -> Number; pub fn cbrt(x: f64) -> f64;
/// The Math.ceil() function returns the smallest integer greater than /// The Math.ceil() function returns the smallest integer greater than
/// or equal to a given number. /// or equal to a given number.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn ceil(x: f64) -> Number; pub fn ceil(x: f64) -> i32;
/// The Math.clz32() function returns the number of leading zero bits in /// The Math.clz32() function returns the number of leading zero bits in
/// the 32-bit binary representation of a number. /// the 32-bit binary representation of a number.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn clz32(x: i32) -> Number; pub fn clz32(x: i32) -> u32;
/// The Math.cos() static function returns the cosine of the specified angle, /// The Math.cos() static function returns the cosine of the specified angle,
/// which must be specified in radians. This value is length(adjacent)/length(hypotenuse). /// which must be specified in radians. This value is length(adjacent)/length(hypotenuse).
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn cos(x: f64) -> Number; pub fn cos(x: f64) -> f64;
/// The Math.cosh() function returns the hyperbolic cosine of a number, /// The Math.cosh() function returns the hyperbolic cosine of a number,
@ -573,125 +620,125 @@ extern "C" {
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn cosh(x: f64) -> Number; pub fn cosh(x: f64) -> f64;
/// The Math.exp() function returns e^x, where x is the argument, and e is Euler's number /// The Math.exp() function returns e^x, where x is the argument, and e is Euler's number
/// (also known as Napier's constant), the base of the natural logarithms. /// (also known as Napier's constant), the base of the natural logarithms.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn exp(x: f64) -> Number; pub fn exp(x: f64) -> f64;
/// The Math.expm1() function returns e^x - 1, where x is the argument, and e the base of the /// The Math.expm1() function returns e^x - 1, where x is the argument, and e the base of the
/// natural logarithms. /// natural logarithms.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1 /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn expm1(x: f64) -> Number; pub fn expm1(x: f64) -> f64;
/// The Math.floor() function returns the largest integer less than or /// The Math.floor() function returns the largest integer less than or
/// equal to a given number. /// equal to a given number.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn floor(x: f64) -> Number; pub fn floor(x: f64) -> i32;
/// The Math.fround() function returns the nearest 32-bit single precision float representation /// The Math.fround() function returns the nearest 32-bit single precision float representation
/// of a Number. /// of a Number.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn fround(x: f64) -> Number; pub fn fround(x: f64) -> f32;
/// The Math.imul() function returns the result of the C-like 32-bit multiplication of the /// The Math.imul() function returns the result of the C-like 32-bit multiplication of the
/// two parameters. /// two parameters.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn imul(x: i32, y: i32) -> Number; pub fn imul(x: i32, y: i32) -> i32;
/// The Math.log() function returns the natural logarithm (base e) of a number. /// The Math.log() function returns the natural logarithm (base e) of a number.
/// The JavaScript Math.log() function is equivalent to ln(x) in mathematics. /// The JavaScript Math.log() function is equivalent to ln(x) in mathematics.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn log(x: f64) -> Number; pub fn log(x: f64) -> f64;
/// The Math.log10() function returns the base 10 logarithm of a number. /// The Math.log10() function returns the base 10 logarithm of a number.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10 /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn log10(x: f64) -> Number; pub fn log10(x: f64) -> f64;
/// The Math.log1p() function returns the natural logarithm (base e) of 1 + a number. /// The Math.log1p() function returns the natural logarithm (base e) of 1 + a number.
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn log1p(x: f64) -> Number; pub fn log1p(x: f64) -> f64;
/// The Math.log2() function returns the base 2 logarithm of a number. /// The Math.log2() function returns the base 2 logarithm of a number.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2 /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn log2(x: f64) -> Number; pub fn log2(x: f64) -> f64;
/// The Math.pow() function returns the base to the exponent power, that is, base^exponent. /// The Math.pow() function returns the base to the exponent power, that is, base^exponent.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn pow(base: f64, exponent: f64) -> Number; pub fn pow(base: f64, exponent: f64) -> f64;
/// The Math.round() function returns the value of a number rounded to the nearest integer. /// The Math.round() function returns the value of a number rounded to the nearest integer.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn round(x: f64) -> Number; pub fn round(x: f64) -> i32;
/// The Math.sign() function returns the sign of a number, indicating whether the number is /// The Math.sign() function returns the sign of a number, indicating whether the number is
/// positive, negative or zero. /// positive, negative or zero.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn sign(x: f64) -> Number; pub fn sign(x: f64) -> f64;
/// The Math.sin() function returns the sine of a number. /// The Math.sin() function returns the sine of a number.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn sin(x: f64) -> Number; pub fn sin(x: f64) -> f64;
/// The Math.sinh() function returns the hyperbolic sine of a number, that can be expressed /// The Math.sinh() function returns the hyperbolic sine of a number, that can be expressed
/// using the constant e: Math.sinh(x) = (e^x - e^-x)/2 /// using the constant e: Math.sinh(x) = (e^x - e^-x)/2
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sinh /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sinh
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn sinh(x: f64) -> Number; pub fn sinh(x: f64) -> f64;
/// The Math.sqrt() function returns the square root of a number, that is /// The Math.sqrt() function returns the square root of a number, that is
/// ∀x ≥ 0, Math.sqrt(x) = √x = the unique y ≥ 0 such that y^2 = x /// ∀x ≥ 0, Math.sqrt(x) = √x = the unique y ≥ 0 such that y^2 = x
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn sqrt(x: f64) -> Number; pub fn sqrt(x: f64) -> f64;
/// The Math.tan() function returns the tangent of a number. /// The Math.tan() function returns the tangent of a number.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tan /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tan
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn tan(x: f64) -> Number; pub fn tan(x: f64) -> f64;
/// The Math.tanh() function returns the hyperbolic tangent of a number, that is /// The Math.tanh() function returns the hyperbolic tangent of a number, that is
/// tanh x = sinh x / cosh x = (e^x - e^-x)/(e^x + e^-x) = (e^2x - 1)/(e^2x + 1) /// tanh x = sinh x / cosh x = (e^x - e^-x)/(e^x + e^-x) = (e^2x - 1)/(e^2x + 1)
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tanh /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tanh
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn tanh(x: f64) -> Number; pub fn tanh(x: f64) -> f64;
/// The Math.trunc() function returns the integer part of a number by removing any fractional /// The Math.trunc() function returns the integer part of a number by removing any fractional
/// digits. /// digits.
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
#[wasm_bindgen(static_method_of = Math)] #[wasm_bindgen(static_method_of = Math)]
pub fn trunc(x: f64) -> Number; pub fn trunc(x: f64) -> i32;
} }
// Number. // Number.
@ -699,6 +746,12 @@ extern "C" {
extern "C" { extern "C" {
pub type Number; pub type Number;
/// The Number.isInteger() method determines whether the passed value is an integer.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
#[wasm_bindgen(static_method_of = Number, js_name = isInteger)]
pub fn is_integer(object: &Object) -> bool;
/// The `Number` JavaScript object is a wrapper object allowing /// The `Number` JavaScript object is a wrapper object allowing
/// you to work with numerical values. A `Number` object is /// you to work with numerical values. A `Number` object is
/// created using the `Number()` constructor. /// created using the `Number()` constructor.
@ -747,7 +800,7 @@ extern "C" {
/// ///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/valueOf /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/valueOf
#[wasm_bindgen(method, js_name = valueOf)] #[wasm_bindgen(method, js_name = valueOf)]
pub fn value_of(this: &Number) -> Number; pub fn value_of(this: &Number) -> f64;
} }
// Date. // Date.
@ -755,6 +808,26 @@ extern "C" {
extern "C" { extern "C" {
pub type Date; pub type Date;
/// The getDate() method returns the day of the month for the
/// specified date according to local time.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDate
#[wasm_bindgen(method, js_name = getDate)]
pub fn get_date(this: &Date) -> u32;
/// The getDay() method returns the day of the week for the specified date according to local time,
/// where 0 represents Sunday. For the day of the month see getDate().
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay
#[wasm_bindgen(method, js_name = getDay)]
pub fn get_day(this: &Date) -> u32;
/// The getFullYear() method returns the year of the specified date according to local time.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getFullYear
#[wasm_bindgen(method, js_name = getFullYear)]
pub fn get_full_year(this: &Date) -> u32;
/// Creates a JavaScript Date instance that represents /// Creates a JavaScript Date instance that represents
/// a single moment in time. Date objects are based on a time value that is /// a single moment in time. Date objects are based on a time value that is
/// the number of milliseconds since 1 January 1970 UTC. /// the number of milliseconds since 1 January 1970 UTC.
@ -978,6 +1051,26 @@ extern "C" {
pub fn values(object: &Object) -> Array; pub fn values(object: &Object) -> Array;
} }
// Proxy
#[wasm_bindgen]
extern {
pub type Proxy;
/// The Proxy object is used to define custom behavior for fundamental
/// operations (e.g. property lookup, assignment, enumeration, function
/// invocation, etc).
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
#[wasm_bindgen(constructor)]
pub fn new(target: &JsValue, handler: &Object) -> Proxy;
/// The Proxy.revocable() method is used to create a revocable Proxy object.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/revocable
#[wasm_bindgen(static_method_of = Proxy)]
pub fn revocable(target: &JsValue, handler: &Object) -> Object;
}
// Reflect // Reflect
#[wasm_bindgen] #[wasm_bindgen]
extern "C" { extern "C" {
@ -1128,7 +1221,7 @@ extern {
/// ///
/// https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Set/size /// https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Set/size
#[wasm_bindgen(method, getter, structural)] #[wasm_bindgen(method, getter, structural)]
pub fn size(this: &Set) -> Number; pub fn size(this: &Set) -> u32;
} }
// SetIterator // SetIterator
@ -1259,9 +1352,11 @@ extern "C" {
/// code points not representable in a single UTF-16 code unit, e.g. Unicode code points > 0x10000). /// code points not representable in a single UTF-16 code unit, e.g. Unicode code points > 0x10000).
/// If you want the entire code point value, use codePointAt(). /// If you want the entire code point value, use codePointAt().
/// ///
/// Returns `NaN` if index is out of range.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt
#[wasm_bindgen(method, js_class = "String", js_name = charCodeAt)] #[wasm_bindgen(method, js_class = "String", js_name = charCodeAt)]
pub fn char_code_at(this: &JsString, index: u32) -> Number; pub fn char_code_at(this: &JsString, index: u32) -> f64;
/// The codePointAt() method returns a non-negative integer that is the Unicode code point value. /// The codePointAt() method returns a non-negative integer that is the Unicode code point value.
/// ///
@ -1408,3 +1503,17 @@ if_std! {
} }
} }
} }
// Symbol
#[wasm_bindgen]
extern "C" {
pub type Symbol;
/// The Symbol.hasInstance well-known symbol is used to determine
/// if a constructor object recognizes an object as its instance.
/// The instanceof operator's behavior can be customized by this symbol.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance
#[wasm_bindgen(static_method_of = Symbol, getter, structural, js_name = hasInstance)]
pub fn has_instance() -> Symbol;
}

View File

@ -6,144 +6,144 @@ fn works() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub fn foo() -> JsValue { pub fn foo() -> JsValue {
JsValue::from("foo") JsValue::from("foo")
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn bar(s: &str) -> JsValue { pub fn bar(s: &str) -> JsValue {
JsValue::from(s) JsValue::from(s)
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn baz() -> JsValue { pub fn baz() -> JsValue {
JsValue::from(1.0) JsValue::from(1.0)
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn baz2(a: &JsValue, b: &JsValue) { pub fn baz2(a: &JsValue, b: &JsValue) {
assert_eq!(a.as_f64(), Some(2.0)); assert_eq!(a.as_f64(), Some(2.0));
assert_eq!(b.as_f64(), None); assert_eq!(b.as_f64(), None);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn js_null() -> JsValue { pub fn js_null() -> JsValue {
JsValue::null() JsValue::null()
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn js_undefined() -> JsValue { pub fn js_undefined() -> JsValue {
JsValue::undefined() JsValue::undefined()
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn test_is_null_undefined( pub fn test_is_null_undefined(
a: &JsValue, a: &JsValue,
b: &JsValue, b: &JsValue,
c: &JsValue, c: &JsValue,
) { ) {
assert!(a.is_null()); assert!(a.is_null());
assert!(!a.is_undefined()); assert!(!a.is_undefined());
assert!(!b.is_null()); assert!(!b.is_null());
assert!(b.is_undefined()); assert!(b.is_undefined());
assert!(!c.is_null()); assert!(!c.is_null());
assert!(!c.is_undefined()); assert!(!c.is_undefined());
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn get_true() -> JsValue { pub fn get_true() -> JsValue {
JsValue::from(true) JsValue::from(true)
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn get_false() -> JsValue { pub fn get_false() -> JsValue {
JsValue::from(false) JsValue::from(false)
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn test_bool( pub fn test_bool(
a: &JsValue, a: &JsValue,
b: &JsValue, b: &JsValue,
c: &JsValue, c: &JsValue,
) { ) {
assert_eq!(a.as_bool(), Some(true)); assert_eq!(a.as_bool(), Some(true));
assert_eq!(b.as_bool(), Some(false)); assert_eq!(b.as_bool(), Some(false));
assert_eq!(c.as_bool(), None); assert_eq!(c.as_bool(), None);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn mk_symbol() -> JsValue { pub fn mk_symbol() -> JsValue {
let a = JsValue::symbol(None); let a = JsValue::symbol(None);
assert!(a.is_symbol()); assert!(a.is_symbol());
return a return a
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn mk_symbol2(s: &str) -> JsValue { pub fn mk_symbol2(s: &str) -> JsValue {
let a = JsValue::symbol(Some(s)); let a = JsValue::symbol(Some(s));
assert!(a.is_symbol()); assert!(a.is_symbol());
return a return a
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn assert_symbols(a: &JsValue, b: &JsValue) { pub fn assert_symbols(a: &JsValue, b: &JsValue) {
assert!(a.is_symbol()); assert!(a.is_symbol());
assert!(!b.is_symbol()); assert!(!b.is_symbol());
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn acquire_string(a: &JsValue, b: &JsValue) { pub fn acquire_string(a: &JsValue, b: &JsValue) {
assert_eq!(a.as_string().unwrap(), "foo"); assert_eq!(a.as_string().unwrap(), "foo");
assert_eq!(b.as_string(), None); assert_eq!(b.as_string(), None);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn acquire_string2(a: &JsValue) -> String { pub fn acquire_string2(a: &JsValue) -> String {
a.as_string().unwrap_or("wrong".to_string()) a.as_string().unwrap_or("wrong".to_string())
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
assert.strictEqual(wasm.foo(), 'foo'); assert.strictEqual(wasm.foo(), 'foo');
assert.strictEqual(wasm.bar('a'), 'a'); assert.strictEqual(wasm.bar('a'), 'a');
assert.strictEqual(wasm.baz(), 1); assert.strictEqual(wasm.baz(), 1);
wasm.baz2(2, 'a'); wasm.baz2(2, 'a');
assert.strictEqual(wasm.js_null(), null); assert.strictEqual(wasm.js_null(), null);
assert.strictEqual(wasm.js_undefined(), undefined); assert.strictEqual(wasm.js_undefined(), undefined);
wasm.test_is_null_undefined(null, undefined, 1.0); wasm.test_is_null_undefined(null, undefined, 1.0);
assert.strictEqual(wasm.get_true(), true); assert.strictEqual(wasm.get_true(), true);
assert.strictEqual(wasm.get_false(), false); assert.strictEqual(wasm.get_false(), false);
wasm.test_bool(true, false, 1.0); wasm.test_bool(true, false, 1.0);
assert.strictEqual(typeof(wasm.mk_symbol()), 'symbol'); assert.strictEqual(typeof(wasm.mk_symbol()), 'symbol');
assert.strictEqual(typeof(wasm.mk_symbol2('a')), 'symbol'); assert.strictEqual(typeof(wasm.mk_symbol2('a')), 'symbol');
assert.strictEqual((Symbol as any).keyFor(wasm.mk_symbol()), undefined); assert.strictEqual(Symbol.keyFor(wasm.mk_symbol()), undefined);
assert.strictEqual((Symbol as any).keyFor(wasm.mk_symbol2('b')), undefined); assert.strictEqual(Symbol.keyFor(wasm.mk_symbol2('b')), undefined);
wasm.assert_symbols((Symbol as any)(), 'a'); wasm.assert_symbols(Symbol(), 'a');
wasm.acquire_string('foo', null) wasm.acquire_string('foo', null)
assert.strictEqual(wasm.acquire_string2(''), ''); assert.strictEqual(wasm.acquire_string2(''), '');
assert.strictEqual(wasm.acquire_string2('a'), 'a'); assert.strictEqual(wasm.acquire_string2('a'), 'a');
} }
"#, "#,
) )
.test(); .test();
} }
@ -172,22 +172,22 @@ fn eq_works() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
assert.strictEqual(wasm.test('a', 'a'), true); assert.strictEqual(wasm.test('a', 'a'), true);
assert.strictEqual(wasm.test('a', 'b'), false); assert.strictEqual(wasm.test('a', 'b'), false);
assert.strictEqual(wasm.test(NaN, NaN), false); assert.strictEqual(wasm.test(NaN, NaN), false);
assert.strictEqual(wasm.test({a: 'a'}, {a: 'a'}), false); assert.strictEqual(wasm.test({a: 'a'}, {a: 'a'}), false);
assert.strictEqual(wasm.test1(NaN), false); assert.strictEqual(wasm.test1(NaN), false);
let x = {a: 'a'}; let x = {a: 'a'};
assert.strictEqual(wasm.test(x, x), true); assert.strictEqual(wasm.test(x, x), true);
assert.strictEqual(wasm.test1(x), true); assert.strictEqual(wasm.test1(x), true);
} }
"#, "#,
) )
.test(); .test();
} }

View File

@ -40,7 +40,7 @@ fn simple() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import { Foo } from "./out"; import { Foo } from "./out";
@ -115,7 +115,7 @@ fn strings() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import { Foo } from "./out"; import { Foo } from "./out";
@ -139,70 +139,64 @@ fn exceptions() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub struct A { pub struct A {
}
#[wasm_bindgen]
impl A {
pub fn new() -> A {
A {}
} }
pub fn foo(&self, _: &A) { #[wasm_bindgen]
impl A {
pub fn new() -> A {
A {}
}
pub fn foo(&self, _: &A) {
}
pub fn bar(&mut self, _: &mut A) {
}
} }
pub fn bar(&mut self, _: &mut A) { #[wasm_bindgen]
pub struct B {
} }
}
#[wasm_bindgen] #[wasm_bindgen]
pub struct B { impl B {
} pub fn new() -> B {
B {}
#[wasm_bindgen] }
impl B {
pub fn new() -> B {
B {}
} }
} "#,
"#,
) )
.file( .file(
"test.js", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import { A, B } from "./out"; import { A, B } from "./out";
export function test() { export function test() {
assert.throws(() => new A(), /cannot invoke `new` directly/); assert.throws(() => new A(), /cannot invoke `new` directly/);
let a = A.new(); let a = A.new();
a.free(); a.free();
assert.throws(() => a.free(), /null pointer passed to rust/); assert.throws(() => a.free(), /null pointer passed to rust/);
let b = A.new(); let b = A.new();
b.foo(b); b.foo(b);
assert.throws(() => b.bar(b), /recursive use of an object/); assert.throws(() => b.bar(b), /recursive use of an object/);
let c = A.new(); let c = A.new();
let d = B.new(); let d = B.new();
assert.throws(() => c.foo(d), /expected instance of A/); assert.throws(() => c.foo(d), /expected instance of A/);
d.free(); d.free();
c.free(); c.free();
}; };
"#, "#,
)
.file(
"test.d.ts",
r#"
export function test(): void;
"#,
) )
.test(); .test();
} }
@ -247,7 +241,7 @@ fn pass_one_to_another() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { A, B } from "./out"; import { A, B } from "./out";
@ -269,49 +263,49 @@ fn pass_into_js() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub struct Foo(i32); pub struct Foo(i32);
#[wasm_bindgen] #[wasm_bindgen]
impl Foo { impl Foo {
pub fn inner(&self) -> i32 { pub fn inner(&self) -> i32 {
self.0 self.0
}
} }
}
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn take_foo(foo: Foo); fn take_foo(foo: Foo);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
take_foo(Foo(13)); take_foo(Foo(13));
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run, Foo } from "./out"; import { run, Foo } from "./out";
import * as assert from "assert"; import * as assert from "assert";
export function take_foo(foo: Foo) { export function take_foo(foo) {
assert.strictEqual(foo.inner(), 13); assert.strictEqual(foo.inner(), 13);
foo.free(); foo.free();
assert.throws(() => foo.free(), /null pointer passed to rust/); assert.throws(() => foo.free(), /null pointer passed to rust/);
} }
export function test() { export function test() {
run(); run();
} }
"#, "#,
) )
.test(); .test();
} }
@ -353,7 +347,7 @@ fn issue_27() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { context } from "./out"; import { context } from "./out";
@ -399,21 +393,21 @@ fn pass_into_js_as_js_class() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run, Foo } from "./out"; import { run, Foo } from "./out";
import * as assert from "assert"; import * as assert from "assert";
export function take_foo(foo: any) { export function take_foo(foo) {
assert(foo instanceof Foo); assert.ok(foo instanceof Foo);
assert.strictEqual(foo.inner(), 13); assert.strictEqual(foo.inner(), 13);
foo.free(); foo.free();
} }
export function test() { export function test() {
run(); run();
} }
"#, "#,
) )
.test(); .test();
} }
@ -472,31 +466,31 @@ fn constructors() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import { Foo, Bar, cross_item_construction } from "./out"; import { Foo, Bar, cross_item_construction } from "./out";
export function test() { export function test() {
const foo = new Foo(1); const foo = new Foo(1);
assert.strictEqual(foo.get_number(), 1); assert.strictEqual(foo.get_number(), 1);
foo.free(); foo.free();
const foo2 = Foo.new(2); const foo2 = Foo.new(2);
assert.strictEqual(foo2.get_number(), 2); assert.strictEqual(foo2.get_number(), 2);
foo2.free(); foo2.free();
const bar = new Bar(3, 4); const bar = new Bar(3, 4);
assert.strictEqual(bar.get_sum(), 7); assert.strictEqual(bar.get_sum(), 7);
bar.free(); bar.free();
const bar2 = Bar.other_name(5, 6); const bar2 = Bar.other_name(5, 6);
assert.strictEqual(bar2.get_sum(), 11); assert.strictEqual(bar2.get_sum(), 11);
bar2.free(); bar2.free();
assert.strictEqual(cross_item_construction().get_sum(), 15); assert.strictEqual(cross_item_construction().get_sum(), 15);
} }
"#, "#,
) )
.test(); .test();
} }
@ -525,14 +519,14 @@ fn empty_structs() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { Other } from "./out"; import { Other } from "./out";
export function test() { export function test() {
Other.return_a_value(); Other.return_a_value();
} }
"#, "#,
) )
.test(); .test();
} }
@ -568,7 +562,7 @@ fn public_fields() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { Foo } from "./out"; import { Foo } from "./out";
import * as assert from "assert"; import * as assert from "assert";
@ -622,7 +616,7 @@ fn using_self() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { Foo } from "./out"; import { Foo } from "./out";
@ -641,40 +635,40 @@ fn readonly_fields() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
#[derive(Default)] #[derive(Default)]
pub struct Foo { pub struct Foo {
#[wasm_bindgen(readonly)] #[wasm_bindgen(readonly)]
pub a: u32, pub a: u32,
}
#[wasm_bindgen]
impl Foo {
pub fn new() -> Foo {
Foo::default()
} }
}
"#, #[wasm_bindgen]
impl Foo {
pub fn new() -> Foo {
Foo::default()
}
}
"#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { Foo } from "./out"; import { Foo } from "./out";
import * as assert from "assert"; import * as assert from "assert";
export function test() { export function test() {
const a = Foo.new(); const a = Foo.new();
assert.strictEqual(a.a, 0); assert.strictEqual(a.a, 0);
assert.throws(() => (a as any).a = 3, /has only a getter/); assert.throws(() => a.a = 3, /has only a getter/);
a.free(); a.free();
} }
"#, "#,
) )
.test(); .test();
} }
@ -704,7 +698,7 @@ fn double_consume() {
} }
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import { Foo } from "./out"; import { Foo } from "./out";

View File

@ -6,46 +6,46 @@ fn works() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use std::cell::Cell; use std::cell::Cell;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn call(a: &Fn()); fn call(a: &Fn());
fn thread(a: &Fn(u32) -> u32) -> u32; fn thread(a: &Fn(u32) -> u32) -> u32;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
let a = Cell::new(false); let a = Cell::new(false);
call(&|| a.set(true)); call(&|| a.set(true));
assert!(a.get()); assert!(a.get());
assert_eq!(thread(&|a| a + 1), 3); assert_eq!(thread(&|a| a + 1), 3);
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
export function call(a: any) { export function call(a) {
a(); a();
} }
export function thread(a: any) { export function thread(a) {
return a(2); return a(2);
} }
export function test() { export function test() {
run(); run();
} }
"#, "#,
) )
.test(); .test();
} }
@ -56,34 +56,34 @@ fn cannot_reuse() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn call(a: &Fn()); fn call(a: &Fn());
#[wasm_bindgen(catch)] #[wasm_bindgen(catch)]
fn call_again() -> Result<(), JsValue>; fn call_again() -> Result<(), JsValue>;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
call(&|| {}); call(&|| {});
assert!(call_again().is_err()); assert!(call_again().is_err());
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
let CACHE: any = null; let CACHE = null;
export function call(a: any) { export function call(a) {
CACHE = a; CACHE = a;
} }
@ -142,15 +142,15 @@ fn long_lived() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
export function call1(a: any) { export function call1(a) {
a(); a();
} }
export function call2(a: any) { export function call2(a) {
return a(2); return a(2);
} }
@ -242,18 +242,18 @@ fn many_arity() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
export function call1(a: any) { a() } export function call1(a) { a() }
export function call2(a: any) { a(1) } export function call2(a) { a(1) }
export function call3(a: any) { a(1, 2) } export function call3(a) { a(1, 2) }
export function call4(a: any) { a(1, 2, 3) } export function call4(a) { a(1, 2, 3) }
export function call5(a: any) { a(1, 2, 3, 4) } export function call5(a) { a(1, 2, 3, 4) }
export function call6(a: any) { a(1, 2, 3, 4, 5) } export function call6(a) { a(1, 2, 3, 4, 5) }
export function call7(a: any) { a(1, 2, 3, 4, 5, 6) } export function call7(a) { a(1, 2, 3, 4, 5, 6) }
export function call8(a: any) { a(1, 2, 3, 4, 5, 6, 7) } export function call8(a) { a(1, 2, 3, 4, 5, 6, 7) }
export function test() { export function test() {
run(); run();
@ -299,13 +299,13 @@ fn long_lived_dropping() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
let CACHE: any = null; let CACHE = null;
export function cache(a: any) { CACHE = a; } export function cache(a) { CACHE = a; }
export function call() { CACHE() } export function call() { CACHE() }
export function test() { export function test() {
@ -346,13 +346,13 @@ fn long_fnmut_recursive() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
let CACHE: any = null; let CACHE = null;
export function cache(a: any) { CACHE = a; } export function cache(a) { CACHE = a; }
export function call() { CACHE() } export function call() { CACHE() }
export function test() { export function test() {
@ -397,15 +397,15 @@ fn fnmut() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
export function call(a: any) { export function call(a) {
a(); a();
} }
export function thread(a: any) { export function thread(a) {
return a(2); return a(2);
} }
@ -455,18 +455,18 @@ fn fnmut_bad() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
let F: any = null; let F = null;
export function call(a: any) { export function call(a) {
F = a; F = a;
a(); a();
} }
export function again(x: boolean) { export function again(x) {
if (x) F(); if (x) F();
} }
@ -507,18 +507,18 @@ fn string_arguments() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
export function call(a: any) { export function call(a) {
a("foo") a("foo")
} }
export function test() { export function test() {
run(); run();
} }
"#, "#,
) )
.test(); .test();
} }
@ -529,45 +529,45 @@ fn string_ret() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn call(a: &mut FnMut(String) -> String); fn call(a: &mut FnMut(String) -> String);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
let mut x = false; let mut x = false;
call(&mut |mut s| { call(&mut |mut s| {
assert_eq!(s, "foo"); assert_eq!(s, "foo");
s.push_str("bar"); s.push_str("bar");
x = true; x = true;
s s
}); });
assert!(x); assert!(x);
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
import * as assert from "assert"; import * as assert from "assert";
export function call(a: any) { export function call(a) {
const s = a("foo"); const s = a("foo");
assert.strictEqual(s, "foobar"); assert.strictEqual(s, "foobar");
} }
export function test() { export function test() {
run(); run();
} }
"#, "#,
) )
.test(); .test();
} }

View File

@ -38,12 +38,12 @@ fn works() {
"#, "#,
); );
let (root, target) = p.cargo_build(); p.gen_bindings();
p.gen_bindings(&root, &target);
let js = p.read_js(); let js = p.read_js();
let comments = extract_doc_comments(&js); let comments = extract_doc_comments(&js);
assert!(comments.iter().all(|c| c == "This comment should exist")); assert!(comments.iter().all(|c| c == "This comment should exist"));
} }
/// Pull out all lines in a js string that start with /// Pull out all lines in a js string that start with
/// '* ', all other lines will either be comment start, comment /// '* ', all other lines will either be comment start, comment
/// end or actual js lines. /// end or actual js lines.

View File

@ -6,87 +6,87 @@ fn dependencies_work() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
extern crate dependency; extern crate dependency;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub fn return_dep_ty(x: f64) -> dependency::Foo { pub fn return_dep_ty(x: f64) -> dependency::Foo {
dependency::Foo(x) dependency::Foo(x)
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn takes_own_dep_ty(foo: dependency::Foo) -> f64 { pub fn takes_own_dep_ty(foo: dependency::Foo) -> f64 {
foo.0 foo.0
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn takes_ref_dep_ty(foo: &dependency::Foo) -> f64 { pub fn takes_ref_dep_ty(foo: &dependency::Foo) -> f64 {
foo.0 foo.0
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn takes_mut_dep_ty(foo: &mut dependency::Foo, x: f64) { pub fn takes_mut_dep_ty(foo: &mut dependency::Foo, x: f64) {
foo.0 = x; foo.0 = x;
} }
"#, "#,
) )
.add_local_dependency("dependency", "vendor/dependency") .add_local_dependency("dependency", "vendor/dependency")
.file( .file(
"vendor/dependency/Cargo.toml", "vendor/dependency/Cargo.toml",
&format!( &format!(
r#" r#"
[package] [package]
name = "dependency" name = "dependency"
version = "0.0.1" version = "0.0.1"
authors = [] authors = []
[dependencies] [dependencies]
wasm-bindgen = {{ path = '{}' }} wasm-bindgen = {{ path = '{}' }}
"#, "#,
env!("CARGO_MANIFEST_DIR") env!("CARGO_MANIFEST_DIR")
), ),
) )
.file( .file(
"vendor/dependency/src/lib.rs", "vendor/dependency/src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub struct Foo(pub f64); pub struct Foo(pub f64);
#[wasm_bindgen] #[wasm_bindgen]
impl Foo { impl Foo {
pub fn new(x: f64) -> Foo { Foo(x) } pub fn new(x: f64) -> Foo { Foo(x) }
pub fn get(&self) -> f64 { self.0 } pub fn get(&self) -> f64 { self.0 }
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
const foo = wasm.return_dep_ty(42); const foo = wasm.return_dep_ty(42);
assert.strictEqual(foo.get(), 42); assert.strictEqual(foo.get(), 42);
const x = wasm.takes_ref_dep_ty(foo); const x = wasm.takes_ref_dep_ty(foo);
assert.strictEqual(x, 42); assert.strictEqual(x, 42);
const y = 1337; const y = 1337;
wasm.takes_mut_dep_ty(foo, y); wasm.takes_mut_dep_ty(foo, y);
assert.strictEqual(foo.get(), y); assert.strictEqual(foo.get(), y);
const z = wasm.takes_own_dep_ty(foo); const z = wasm.takes_own_dep_ty(foo);
assert.strictEqual(z, y); assert.strictEqual(z, y);
assert.strictEqual((foo as any).ptr, 0); assert.strictEqual(foo.ptr, 0);
} }
"#, "#,
) )
.test(); .test();
} }

View File

@ -6,44 +6,44 @@ fn c_style_enum() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub enum Color { pub enum Color {
Green, Green,
Yellow, Yellow,
Red, Red,
}
#[wasm_bindgen]
pub fn cycle(color: Color) -> Color {
match color {
Color::Green => Color::Yellow,
Color::Yellow => Color::Red,
Color::Red => Color::Green,
} }
}
"#, #[wasm_bindgen]
pub fn cycle(color: Color) -> Color {
match color {
Color::Green => Color::Yellow,
Color::Yellow => Color::Red,
Color::Red => Color::Green,
}
}
"#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
assert.strictEqual(wasm.Color.Green, 0); assert.strictEqual(wasm.Color.Green, 0);
assert.strictEqual(wasm.Color.Yellow, 1); assert.strictEqual(wasm.Color.Yellow, 1);
assert.strictEqual(wasm.Color.Red, 2); assert.strictEqual(wasm.Color.Red, 2);
assert.strictEqual(Object.keys(wasm.Color).length, 3); assert.strictEqual(Object.keys(wasm.Color).length, 3);
assert.strictEqual(wasm.cycle(wasm.Color.Green), wasm.Color.Yellow); assert.strictEqual(wasm.cycle(wasm.Color.Green), wasm.Color.Yellow);
} }
"#, "#,
) )
.test(); .test();
} }
@ -54,50 +54,50 @@ fn c_style_enum_with_custom_values() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod inner {
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
pub mod inner {
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub enum Color {
Green = 21,
Yellow = 34,
Red,
}
}
use inner::Color;
#[wasm_bindgen] #[wasm_bindgen]
pub enum Color { pub fn cycle(color: Color) -> Color {
Green = 21, match color {
Yellow = 34, Color::Green => Color::Yellow,
Red, Color::Yellow => Color::Red,
Color::Red => Color::Green,
}
} }
} "#,
use inner::Color;
#[wasm_bindgen]
pub fn cycle(color: Color) -> Color {
match color {
Color::Green => Color::Yellow,
Color::Yellow => Color::Red,
Color::Red => Color::Green,
}
}
"#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
assert.strictEqual(wasm.Color.Green, 21); assert.strictEqual(wasm.Color.Green, 21);
assert.strictEqual(wasm.Color.Yellow, 34); assert.strictEqual(wasm.Color.Yellow, 34);
assert.strictEqual(wasm.Color.Red, 2); assert.strictEqual(wasm.Color.Red, 2);
assert.strictEqual(Object.keys(wasm.Color).length, 3); assert.strictEqual(Object.keys(wasm.Color).length, 3);
assert.strictEqual(wasm.cycle(wasm.Color.Green), wasm.Color.Yellow); assert.strictEqual(wasm.cycle(wasm.Color.Green), wasm.Color.Yellow);
} }
"#, "#,
) )
.test(); .test();
} }

View File

@ -6,42 +6,42 @@ fn simple() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub fn get_random() -> f64 { pub fn get_random() -> f64 {
random() random()
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn do_log(a: f64) -> f64 { pub fn do_log(a: f64) -> f64 {
log(a) log(a)
} }
#[wasm_bindgen] #[wasm_bindgen]
extern { extern {
#[wasm_bindgen(js_namespace = Math)] #[wasm_bindgen(js_namespace = Math)]
fn random() -> f64; fn random() -> f64;
#[wasm_bindgen(js_namespace = Math)] #[wasm_bindgen(js_namespace = Math)]
fn log(a: f64) -> f64; fn log(a: f64) -> f64;
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out"; import * as wasm from "./out";
import * as assert from "assert"; import * as assert from "assert";
export function test() { export function test() {
wasm.get_random(); wasm.get_random();
assert.strictEqual(wasm.do_log(1.0), Math.log(1.0)); assert.strictEqual(wasm.do_log(1.0), Math.log(1.0));
} }
"#, "#,
) )
.test(); .test();
} }
@ -52,48 +52,48 @@ fn import_class() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./another")] #[wasm_bindgen(module = "./another")]
extern { extern {
#[wasm_bindgen(js_namespace = Foo)] #[wasm_bindgen(js_namespace = Foo)]
fn bar(); fn bar();
}
#[wasm_bindgen]
pub fn baz() {
bar();
}
"#,
)
.file(
"test.ts",
r#"
import { baz } from "./out";
import { called } from "./another";
import * as assert from "assert";
export function test() {
baz();
assert.strictEqual(called, true);
}
"#,
)
.file(
"another.ts",
r#"
export let called = false;
export class Foo {
static bar() {
called = true;
} }
}
"#, #[wasm_bindgen]
pub fn baz() {
bar();
}
"#,
)
.file(
"test.js",
r#"
import { baz } from "./out";
import { called } from "./another";
import * as assert from "assert";
export function test() {
baz();
assert.strictEqual(called, true);
}
"#,
)
.file(
"another.js",
r#"
export let called = false;
export class Foo {
static bar() {
called = true;
}
}
"#,
) )
.test(); .test();
} }
@ -104,77 +104,79 @@ fn construct() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./another")] #[wasm_bindgen(module = "./another")]
extern { extern {
type Foo; #[derive(Clone)]
#[wasm_bindgen(js_namespace = Foo)] type Foo;
fn create() -> Foo; #[wasm_bindgen(js_namespace = Foo)]
#[wasm_bindgen(method)] fn create() -> Foo;
fn get_internal_string(this: &Foo) -> String; #[wasm_bindgen(method)]
#[wasm_bindgen(method)] fn get_internal_string(this: &Foo) -> String;
fn append_to_internal_string(this: &Foo, s: &str); #[wasm_bindgen(method)]
#[wasm_bindgen(method)] fn append_to_internal_string(this: &Foo, s: &str);
fn assert_internal_string(this: &Foo, s: &str); #[wasm_bindgen(method)]
} fn assert_internal_string(this: &Foo, s: &str);
}
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
let f = Foo::create(); let f = Foo::create();
assert_eq!(f.get_internal_string(), "this"); assert_eq!(f.get_internal_string(), "this");
f.append_to_internal_string(" foo"); assert_eq!(f.clone().get_internal_string(), "this");
f.assert_internal_string("this foo"); f.append_to_internal_string(" foo");
} f.assert_internal_string("this foo");
"#, }
"#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
import { called } from "./another"; import { called } from "./another";
import * as assert from "assert"; import * as assert from "assert";
export function test() { export function test() {
run(); run();
assert.strictEqual(called, true); assert.strictEqual(called, true);
} }
"#, "#,
) )
.file( .file(
"another.ts", "another.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
export let called = false; export let called = false;
export class Foo { export class Foo {
private internal_string: string = ''; static create() {
const ret = new Foo();
ret.internal_string = 'this';
return ret;
}
static create() { get_internal_string() {
const ret = new Foo(); return this.internal_string;
ret.internal_string = 'this'; }
return ret;
append_to_internal_string(s) {
this.internal_string += s;
}
assert_internal_string(s) {
assert.strictEqual(this.internal_string, s);
called = true;
}
} }
get_internal_string() { Foo.internal_string = '';
return this.internal_string; "#,
}
append_to_internal_string(s: string) {
this.internal_string += s;
}
assert_internal_string(s: string) {
assert.strictEqual(this.internal_string, s);
called = true;
}
}
"#,
) )
.test(); .test();
} }
@ -185,50 +187,51 @@ fn new_constructors() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./another")] #[wasm_bindgen(module = "./another")]
extern { extern {
type Foo; type Foo;
#[wasm_bindgen(constructor)] #[wasm_bindgen(constructor)]
fn new(arg: i32) -> Foo; fn new(arg: i32) -> Foo;
#[wasm_bindgen(method)] #[wasm_bindgen(method)]
fn get(this: &Foo) -> i32; fn get(this: &Foo) -> i32;
}
#[wasm_bindgen]
pub fn run() {
let f = Foo::new(1);
assert_eq!(f.get(), 2);
}
"#,
)
.file(
"test.ts",
r#"
import { run } from "./out";
export function test() {
run();
}
"#,
)
.file(
"another.ts",
r#"
export class Foo {
constructor(private field: number) {
} }
get() { #[wasm_bindgen]
return this.field + 1; pub fn run() {
let f = Foo::new(1);
assert_eq!(f.get(), 2);
} }
} "#,
"#, )
.file(
"test.js",
r#"
import { run } from "./out";
export function test() {
run();
}
"#,
)
.file(
"another.js",
r#"
export class Foo {
constructor(field) {
this.field = field;
}
get() {
return this.field + 1;
}
}
"#,
) )
.test(); .test();
} }
@ -239,84 +242,84 @@ fn switch_methods() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./another")] #[wasm_bindgen(module = "./another")]
extern { extern {
type Foo; type Foo;
#[wasm_bindgen(constructor)] #[wasm_bindgen(constructor)]
fn new() -> Foo; fn new() -> Foo;
#[wasm_bindgen(js_namespace = Foo)] #[wasm_bindgen(js_namespace = Foo)]
fn a(); fn a();
#[wasm_bindgen(method)] #[wasm_bindgen(method)]
fn b(this: &Foo); fn b(this: &Foo);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn a() { pub fn a() {
Foo::a(); Foo::a();
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn b() { pub fn b() {
Foo::new().b(); Foo::new().b();
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { a, b } from "./out"; import { a, b } from "./out";
import { Foo, called } from "./another"; import { Foo, called } from "./another";
import * as assert from "assert"; import * as assert from "assert";
export function test() { export function test() {
assert.strictEqual(called.a, false); assert.strictEqual(called.a, false);
a(); a();
assert.strictEqual(called.a, true); assert.strictEqual(called.a, true);
called.a = false; called.a = false;
Foo.a = function() {}; Foo.a = function() {};
assert.strictEqual(called.a, false); assert.strictEqual(called.a, false);
a(); a();
assert.strictEqual(called.a, true); assert.strictEqual(called.a, true);
called.a = false; called.a = false;
assert.strictEqual(called.a, false); assert.strictEqual(called.a, false);
b(); b();
assert.strictEqual(called.a, true); assert.strictEqual(called.a, true);
called.a = false; called.a = false;
Foo.prototype.b = function() {}; Foo.prototype.b = function() {};
assert.strictEqual(called.a, false); assert.strictEqual(called.a, false);
b(); b();
assert.strictEqual(called.a, true); assert.strictEqual(called.a, true);
} }
"#, "#,
) )
.file( .file(
"another.ts", "another.js",
r#" r#"
export let called = { a: false }; export let called = { a: false };
export class Foo { export class Foo {
constructor() { constructor() {
} }
static a() { static a() {
called.a = true; called.a = true;
} }
b() { b() {
called.a = true; called.a = true;
}
} }
} "#,
"#,
) )
.test(); .test();
} }
@ -327,62 +330,62 @@ fn properties() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./another")] #[wasm_bindgen(module = "./another")]
extern { extern {
type Foo; type Foo;
#[wasm_bindgen(constructor)] #[wasm_bindgen(constructor)]
fn new() -> Foo; fn new() -> Foo;
#[wasm_bindgen(getter, method)] #[wasm_bindgen(getter, method)]
fn a(this: &Foo) -> i32; fn a(this: &Foo) -> i32;
#[wasm_bindgen(setter, method)] #[wasm_bindgen(setter, method)]
fn set_a(this: &Foo, a: i32); fn set_a(this: &Foo, a: i32);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
let a = Foo::new(); let a = Foo::new();
assert_eq!(a.a(), 1); assert_eq!(a.a(), 1);
a.set_a(2); a.set_a(2);
assert_eq!(a.a(), 2); assert_eq!(a.a(), 2);
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
export function test() { export function test() {
run(); run();
} }
"#, "#,
) )
.file( .file(
"another.ts", "another.js",
r#" r#"
export class Foo { export class Foo {
constructor(private num: number) { constructor() {
this.num = 1; this.num = 1;
} }
get a() { get a() {
return this.num; return this.num;
} }
set a(val) { set a(val) {
this.num = val; this.num = val;
}
} }
} "#,
"#,
) )
.test(); .test();
} }
@ -393,62 +396,62 @@ fn rename_setter_getter() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./another")] #[wasm_bindgen(module = "./another")]
extern { extern {
type Foo; type Foo;
#[wasm_bindgen(constructor)] #[wasm_bindgen(constructor)]
fn new() -> Foo; fn new() -> Foo;
#[wasm_bindgen(getter = a, method)] #[wasm_bindgen(getter = a, method)]
fn test(this: &Foo) -> i32; fn test(this: &Foo) -> i32;
#[wasm_bindgen(setter = a, method)] #[wasm_bindgen(setter = a, method)]
fn another(this: &Foo, a: i32); fn another(this: &Foo, a: i32);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
let a = Foo::new(); let a = Foo::new();
assert_eq!(a.test(), 1); assert_eq!(a.test(), 1);
a.another(2); a.another(2);
assert_eq!(a.test(), 2); assert_eq!(a.test(), 2);
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
export function test() { export function test() {
run(); run();
} }
"#, "#,
) )
.file( .file(
"another.ts", "another.js",
r#" r#"
export class Foo { export class Foo {
constructor(private num: number) { constructor() {
this.num = 1; this.num = 1;
} }
get a() { get a() {
return this.num; return this.num;
} }
set a(val) { set a(val) {
this.num = val; this.num = val;
}
} }
} "#,
"#,
) )
.test(); .test();
} }

View File

@ -6,84 +6,84 @@ fn simple() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn foo(s: &str); fn foo(s: &str);
fn another(a: u32) -> i32; fn another(a: u32) -> i32;
fn take_and_return_bool(a: bool) -> bool; fn take_and_return_bool(a: bool) -> bool;
fn return_object() -> JsValue; fn return_object() -> JsValue;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn bar(s: &str) { pub fn bar(s: &str) {
foo(s); foo(s);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn another_thunk(a: u32) -> i32 { pub fn another_thunk(a: u32) -> i32 {
another(a) another(a)
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn bool_thunk(a: bool) -> bool { pub fn bool_thunk(a: bool) -> bool {
take_and_return_bool(a) take_and_return_bool(a)
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn get_the_object() -> JsValue { pub fn get_the_object() -> JsValue {
return_object() return_object()
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out"; import * as wasm from "./out";
import * as assert from "assert"; import * as assert from "assert";
let ARG: string | null = null; let ARG = null;
let ANOTHER_ARG: number | null = null; let ANOTHER_ARG = null;
let SYM = (Symbol as any)('a'); let SYM = Symbol('a');
export function foo(s: string): void { export function foo(s) {
assert.strictEqual(ARG, null); assert.strictEqual(ARG, null);
assert.strictEqual(s, "foo"); assert.strictEqual(s, "foo");
ARG = s; ARG = s;
} }
export function another(s: number): number { export function another(s) {
assert.strictEqual(ANOTHER_ARG, null); assert.strictEqual(ANOTHER_ARG, null);
assert.strictEqual(s, 21); assert.strictEqual(s, 21);
ANOTHER_ARG = s; ANOTHER_ARG = s;
return 35; return 35;
} }
export function take_and_return_bool(s: boolean): boolean { export function take_and_return_bool(s) {
return s; return s;
} }
export function return_object(): any { export function return_object() {
return SYM; return SYM;
} }
export function test() { export function test() {
assert.strictEqual(ARG, null); assert.strictEqual(ARG, null);
wasm.bar("foo"); wasm.bar("foo");
assert.strictEqual(ARG, "foo"); assert.strictEqual(ARG, "foo");
assert.strictEqual(ANOTHER_ARG, null); assert.strictEqual(ANOTHER_ARG, null);
assert.strictEqual(wasm.another_thunk(21), 35); assert.strictEqual(wasm.another_thunk(21), 35);
assert.strictEqual(ANOTHER_ARG, 21); assert.strictEqual(ANOTHER_ARG, 21);
assert.strictEqual(wasm.bool_thunk(true), true); assert.strictEqual(wasm.bool_thunk(true), true);
assert.strictEqual(wasm.bool_thunk(false), false); assert.strictEqual(wasm.bool_thunk(false), false);
assert.strictEqual(wasm.get_the_object(), SYM); assert.strictEqual(wasm.get_the_object(), SYM);
} }
"#, "#,
) )
.test(); .test();
} }
@ -94,33 +94,33 @@ fn unused() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
#![allow(dead_code)] #![allow(dead_code)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn debug_print(s: &str); fn debug_print(s: &str);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn bar() {} pub fn bar() {}
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out"; import * as wasm from "./out";
export function debug_print() {} export function debug_print() {}
export function test() { export function test() {
wasm.bar(); wasm.bar();
} }
"#, "#,
) )
.test(); .test();
} }
@ -131,36 +131,36 @@ fn string_ret() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn foo() -> String; fn foo() -> String;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
assert_eq!(foo(), "bar"); assert_eq!(foo(), "bar");
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out"; import * as wasm from "./out";
export function foo(): string { export function foo() {
return 'bar'; return 'bar';
} }
export function test() { export function test() {
wasm.run(); wasm.run();
} }
"#, "#,
) )
.test(); .test();
} }
@ -171,43 +171,43 @@ fn strings() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn foo(a: String) -> String; fn foo(a: String) -> String;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn bar(a: &str) -> String { pub fn bar(a: &str) -> String {
foo(a.to_string()) foo(a.to_string())
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn bar2(a: String) -> String { pub fn bar2(a: String) -> String {
foo(a) foo(a)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out"; import * as wasm from "./out";
import * as assert from "assert"; import * as assert from "assert";
export function foo(a: string): string { export function foo(a) {
return a + 'b'; return a + 'b';
} }
export function test() { export function test() {
assert.strictEqual(wasm.bar('a'), 'ab'); assert.strictEqual(wasm.bar('a'), 'ab');
assert.strictEqual(wasm.bar2('a'), 'ab'); assert.strictEqual(wasm.bar2('a'), 'ab');
} }
"#, "#,
) )
.test(); .test();
} }
@ -218,60 +218,60 @@ fn exceptions() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn foo(); fn foo();
fn bar(); fn bar();
#[wasm_bindgen(catch)] #[wasm_bindgen(catch)]
fn baz() -> Result<(), JsValue>; fn baz() -> Result<(), JsValue>;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
foo(); foo();
bar(); bar();
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run2() { pub fn run2() {
assert!(baz().is_err()); assert!(baz().is_err());
bar(); bar();
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run, run2 } from "./out"; import { run, run2 } from "./out";
import * as assert from "assert"; import * as assert from "assert";
let called = false; let called = false;
export function foo() { export function foo() {
throw new Error('error!'); throw new Error('error!');
} }
export function baz() { export function baz() {
throw new Error('error2'); throw new Error('error2');
} }
export function bar() { export function bar() {
called = true; called = true;
} }
export function test() { export function test() {
assert.throws(run, /error!/); assert.throws(run, /error!/);
assert.strictEqual(called, false); assert.strictEqual(called, false);
run2(); run2();
assert.strictEqual(called, true); assert.strictEqual(called, true);
} }
"#, "#,
) )
.test(); .test();
} }
@ -282,40 +282,40 @@ fn exn_caught() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
#[wasm_bindgen(catch)] #[wasm_bindgen(catch)]
fn foo() -> Result<(), JsValue>; fn foo() -> Result<(), JsValue>;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() -> JsValue { pub fn run() -> JsValue {
foo().unwrap_err() foo().unwrap_err()
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
import * as assert from "assert"; import * as assert from "assert";
export function foo() { export function foo() {
throw new Error('error!'); throw new Error('error!');
} }
export function test() { export function test() {
const obj = run(); const obj = run();
assert.strictEqual(obj instanceof Error, true); assert.strictEqual(obj instanceof Error, true);
assert.strictEqual(obj.message, 'error!'); assert.strictEqual(obj.message, 'error!');
} }
"#, "#,
) )
.test(); .test();
} }
@ -326,32 +326,32 @@ fn free_imports() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
extern { extern {
fn parseInt(a: &str) -> u32; fn parseInt(a: &str) -> u32;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
assert_eq!(parseInt("3"), 3); assert_eq!(parseInt("3"), 3);
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
export function test() { export function test() {
run(); run();
} }
"#, "#,
) )
.test(); .test();
} }
@ -363,34 +363,34 @@ fn import_a_field() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
static IMPORT: JsValue; static IMPORT: JsValue;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
assert_eq!(IMPORT.as_f64(), Some(1.0)); assert_eq!(IMPORT.as_f64(), Some(1.0));
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
export const IMPORT = 1.0; export const IMPORT = 1.0;
export function test() { export function test() {
run(); run();
} }
"#, "#,
) )
.test(); .test();
} }
@ -401,41 +401,41 @@ fn rename() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
#[wasm_bindgen(js_name = baz)] #[wasm_bindgen(js_name = baz)]
fn foo(); fn foo();
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
foo(); foo();
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out"; import * as wasm from "./out";
import * as assert from "assert"; import * as assert from "assert";
let called = false; let called = false;
export function baz() { export function baz() {
called = true; called = true;
} }
export function test() { export function test() {
wasm.run(); wasm.run();
assert.strictEqual(called, true); assert.strictEqual(called, true);
} }
"#, "#,
) )
.test(); .test();
} }
@ -443,49 +443,50 @@ fn rename() {
#[test] #[test]
fn versions() { fn versions() {
project() project()
.debug(false)
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "webpack", version = "^0.2.0")] #[wasm_bindgen(module = "webpack", version = "^0.2.0")]
extern { extern {
fn foo(); fn foo();
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
foo(); foo();
} }
"#, "#,
) )
.file( .file(
"test.js", "test.js",
r#" r#"
const fs = require("fs"); import * as fs from 'fs';
const assert = require("assert"); import * as assert from 'assert';
exports.test = function() { export function test() {
const bytes = fs.readFileSync('out_bg.wasm'); const bytes = fs.readFileSync('out_bg.wasm');
const m = new WebAssembly.Module(bytes); const m = new WebAssembly.Module(bytes);
const name = '__wasm_pack_unstable'; const name = '__wasm_pack_unstable';
const sections = WebAssembly.Module.customSections(m, name); const sections = WebAssembly.Module.customSections(m, name);
assert.strictEqual(sections.length, 1); assert.strictEqual(sections.length, 1);
const b = new Uint8Array(sections[0]); const b = new Uint8Array(sections[0]);
const buf = new Buffer(b); const buf = new Buffer(b);
const map = JSON.parse(buf.toString()); const map = JSON.parse(buf.toString());
assert.deepStrictEqual(map, { assert.deepStrictEqual(map, {
version: '0.0.1', version: '0.0.1',
modules: [ modules: [
['webpack', '^0.2.0'] ['webpack', '^0.2.0']
] ]
}); });
}; };
"#, "#,
) )
.test(); .test();
} }
@ -511,10 +512,10 @@ fn underscore_pattern() {
foo(1); foo(1);
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import { run } from "./out"; import { run } from "./out";
export function foo(_a: number) { export function foo(_a) {
} }
export function test() { export function test() {
@ -530,37 +531,37 @@ fn rust_keyword() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
#[wasm_bindgen(js_name = self)] #[wasm_bindgen(js_name = self)]
fn foo() -> u32; fn foo() -> u32;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
assert_eq!(foo(), 2); assert_eq!(foo(), 2);
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
export function self() { export function self() {
return 2; return 2;
} }
export function test() { export function test() {
run(); run();
} }
"#, "#,
) )
.test(); .test();
} }
@ -572,38 +573,38 @@ fn rust_keyword2() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
pub type bar; pub type bar;
#[wasm_bindgen(js_namespace = bar, js_name = foo)] #[wasm_bindgen(js_namespace = bar, js_name = foo)]
static FOO: JsValue; static FOO: JsValue;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
assert_eq!(FOO.as_f64(), Some(3.0)); assert_eq!(FOO.as_f64(), Some(3.0));
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run } from "./out"; import { run } from "./out";
export const bar = { export const bar = {
foo: 3, foo: 3,
}; };
export function test() { export function test() {
run(); run();
} }
"#, "#,
) )
.test(); .test();
} }
@ -645,18 +646,18 @@ fn custom_type() {
bad2(); bad2();
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import { run, Foo, bad } from "./out"; import { run, Foo, bad } from "./out";
let VAL: any = null; let VAL = null;
export function foo(f: Foo): Foo { export function foo(f) {
VAL = f; VAL = f;
return f; return f;
} }
export function bad2(): number { export function bad2() {
return 2; return 2;
} }
@ -691,7 +692,7 @@ fn unused_imports_not_generated() {
pub fn run() { pub fn run() {
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import { run } from "./out"; import { run } from "./out";
export function test() { export function test() {

View File

@ -22,7 +22,7 @@ fn filter() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -61,7 +61,7 @@ fn index_of() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -104,27 +104,27 @@ fn is_array() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
assert(wasm.is_array([])); assert.ok(wasm.is_array([]));
assert(wasm.is_array([1])); assert.ok(wasm.is_array([1]));
assert(wasm.is_array(new Array())); assert.ok(wasm.is_array(new Array()));
assert(wasm.is_array(new Array('a', 'b', 'c', 'd'))); assert.ok(wasm.is_array(new Array('a', 'b', 'c', 'd')));
assert(wasm.is_array(new Array(3))); assert.ok(wasm.is_array(new Array(3)));
assert(wasm.is_array(Array.prototype)); assert.ok(wasm.is_array(Array.prototype));
assert(!wasm.is_array({})); assert.ok(!wasm.is_array({}));
assert(!wasm.is_array(null)); assert.ok(!wasm.is_array(null));
assert(!wasm.is_array(undefined)); assert.ok(!wasm.is_array(undefined));
assert(!wasm.is_array(17)); assert.ok(!wasm.is_array(17));
assert(!wasm.is_array('Array')); assert.ok(!wasm.is_array('Array'));
assert(!wasm.is_array(true)); assert.ok(!wasm.is_array(true));
assert(!wasm.is_array(false)); assert.ok(!wasm.is_array(false));
assert(!wasm.is_array({ __proto__: Array.prototype })); assert.ok(!wasm.is_array({ __proto__: Array.prototype }));
} }
"#, "#,
) )
@ -151,7 +151,7 @@ fn sort() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -183,7 +183,7 @@ fn some() {
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -218,7 +218,7 @@ fn last_index_of() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -262,7 +262,7 @@ fn join() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -299,7 +299,7 @@ fn slice() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -335,7 +335,7 @@ fn fill() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -368,7 +368,7 @@ fn copy_within() {
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -406,7 +406,7 @@ fn pop() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -442,7 +442,7 @@ fn push() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -478,7 +478,7 @@ fn reverse() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -514,7 +514,7 @@ fn shift() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -551,7 +551,7 @@ fn unshift() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -588,7 +588,7 @@ fn to_string() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -624,7 +624,7 @@ fn includes() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -665,7 +665,7 @@ fn concat() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -702,20 +702,20 @@ fn length() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
let characters = [8, 5, 4, 3, 1, 2] let characters = [8, 5, 4, 3, 1, 2]
let charactersLength = wasm.array_length(characters); let charactersLength = wasm.array_length(characters);
assert.equal(charactersLength, 6); assert.equal(charactersLength, 6);
var empty : number[] = []; var empty = [];
let emptyLength = wasm.array_length(empty); let emptyLength = wasm.array_length(empty);
assert.equal(emptyLength, 0); assert.equal(emptyLength, 0);
} }
"#, "#,
) )
.test() .test()
@ -727,34 +727,72 @@ fn every() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn array_every_number_is_even(array: &js::Array) -> bool { pub fn array_every_number_is_even(array: &js::Array) -> bool {
array.every(&mut |el, _, _| el.as_f64().unwrap() % 2f64 == 0f64) array.every(&mut |el, _, _| el.as_f64().unwrap() % 2f64 == 0f64)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
const arrayEven = [2, 4, 6, 8]; const arrayEven = [2, 4, 6, 8];
const arrayOdd = [1, 3, 5, 7]; const arrayOdd = [1, 3, 5, 7];
const arrayMixed = [2, 3, 4, 5]; const arrayMixed = [2, 3, 4, 5];
assert(wasm.array_every_number_is_even(arrayEven)); assert.ok(wasm.array_every_number_is_even(arrayEven));
assert(!wasm.array_every_number_is_even(arrayOdd)); assert.ok(!wasm.array_every_number_is_even(arrayOdd));
assert(!wasm.array_every_number_is_even(arrayMixed)); assert.ok(!wasm.array_every_number_is_even(arrayMixed));
} }
"#, "#,
)
.test()
}
#[test]
fn find() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn array_find_first_even_number(array: &js::Array) -> JsValue {
array.find(&mut |el, _, _| el.as_f64().unwrap() % 2f64 == 0f64)
}
"#,
)
.file(
"test.js",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const arrayEven = [2, 4, 6, 8];
const arrayOdd = [1, 3, 5, 7];
const arrayMixed = [3, 5, 7, 10];
assert.equal(wasm.array_find_first_even_number(arrayEven), 2);
assert.equal(wasm.array_find_first_even_number(arrayOdd), undefined);
assert.equal(wasm.array_find_first_even_number(arrayMixed), 10);
}
"#,
) )
.test() .test()
} }

View File

@ -0,0 +1,110 @@
#![allow(non_snake_case)]
use super::project;
#[test]
fn new() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js::ArrayBuffer;
#[wasm_bindgen]
pub fn new_arraybuffer() -> ArrayBuffer {
ArrayBuffer::new(42)
}
"#)
.file("test.js", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(typeof wasm.new_arraybuffer(), "object");
}
"#)
.test()
}
#[test]
fn is_view() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use JsValue;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js::ArrayBuffer;
#[wasm_bindgen]
pub fn is_view(value: JsValue) -> bool {
ArrayBuffer::is_view(value)
}
"#)
.file("test.js", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.equal(wasm.is_view(new Uint8Array(42)), true);
}
"#)
.test()
}
#[test]
fn slice() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js::ArrayBuffer;
#[wasm_bindgen]
pub fn slice(arraybuffer: &ArrayBuffer, begin: u32) -> ArrayBuffer {
arraybuffer.slice(begin)
}
"#)
.file("test.js", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const arraybuffer = new ArrayBuffer(4);
assert.equal(typeof wasm.slice(arraybuffer, 2), "object");
}
"#)
.test()
}
#[test]
fn slice_with_end() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js::ArrayBuffer;
#[wasm_bindgen]
pub fn slice_with_end(arraybuffer: &ArrayBuffer, begin: u32, end: u32) -> ArrayBuffer {
arraybuffer.slice_with_end(begin, end)
}
"#)
.file("test.js", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const arraybuffer = new ArrayBuffer(4);
assert.equal(typeof wasm.slice_with_end(arraybuffer, 1, 2), "object");
}
"#)
.test()
}

View File

@ -22,7 +22,7 @@ fn keys() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -60,7 +60,7 @@ fn entries() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

View File

@ -21,7 +21,7 @@ fn new_undefined() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -53,7 +53,7 @@ fn new_truely() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

138
tests/all/js_globals/Date.rs Normal file → Executable file
View File

@ -2,6 +2,110 @@
use super::project; use super::project;
#[test]
fn get_date() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js::Date;
#[wasm_bindgen]
pub fn get_date(this: &Date) -> u32 {
this.get_date()
}
"#,
)
.file(
"test.js",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let date = new Date(1993, 6, 28, 14, 39, 7);
assert.equal(wasm.get_date(date), 28);
}
"#,
)
.test()
}
#[test]
fn get_day() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js::Date;
#[wasm_bindgen]
pub fn get_day(this: &Date) -> u32 {
this.get_day()
}
"#,
)
.file(
"test.js",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let date = new Date('August 19, 1975 23:15:30');
assert.equal(wasm.get_day(date), 2);
}
"#,
)
.test()
}
#[test]
fn get_full_year() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js::Date;
#[wasm_bindgen]
pub fn get_full_year(this: &Date) -> u32 {
this.get_full_year()
}
"#,
)
.file(
"test.js",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
let date = new Date('July 20, 1969 00:20:18');
let abbrDate = new Date('Thu, 06 Sep 12 00:00:00');
assert.equal(wasm.get_full_year(date), 1969);
assert.equal(wasm.get_full_year(abbrDate), 2012);
}
"#,
)
.test()
}
#[test] #[test]
fn new() { fn new() {
project() project()
@ -21,7 +125,7 @@ fn new() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -49,7 +153,7 @@ fn now() {
Date::now() Date::now()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -79,7 +183,7 @@ fn to_date_string() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -113,7 +217,7 @@ fn to_iso_string() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -147,7 +251,7 @@ fn to_json() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -178,7 +282,7 @@ fn to_locale_date_string() {
this.to_locale_date_string(locale, options) this.to_locale_date_string(locale, options)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -186,7 +290,9 @@ fn to_locale_date_string() {
let date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0)); let date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
let options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; let options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
assert.equal(wasm.to_locale_date_string(date, 'de-DE', options), 'Thursday, December 20, 2012'); let output = wasm.to_locale_date_string(date, 'de-DE', options)
assert.equal(typeof output, 'string');
assert.ok(output.length > 0);
} }
"#) "#)
.test() .test()
@ -208,13 +314,15 @@ fn to_locale_string() {
this.to_locale_string(locale, options) this.to_locale_string(locale, options)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
let date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0)); let date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
assert.equal(wasm.to_locale_string(date, 'en-GB', { timeZone: 'UTC' }), "12/20/2012, 3:00:00 AM"); let output = wasm.to_locale_string(date, 'en-GB', { timeZone: 'UTC' });
assert.equal(typeof output, 'string');
assert.ok(output.length > 0);
} }
"#) "#)
.test() .test()
@ -239,7 +347,7 @@ fn to_locale_time_string() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -272,7 +380,7 @@ fn to_string() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -305,7 +413,7 @@ fn to_time_string() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -338,7 +446,7 @@ fn to_utc_string() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -367,7 +475,7 @@ fn utc() {
Date::utc(2018f64, 6f64) Date::utc(2018f64, 6f64)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -397,7 +505,7 @@ fn value_of() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

View File

@ -18,7 +18,7 @@ fn new() {
Error::new(message) Error::new(message)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -48,7 +48,7 @@ fn message() {
this.message() this.message()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -78,7 +78,7 @@ fn set_message() {
this.set_message(message); this.set_message(message);
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -109,7 +109,7 @@ fn name() {
this.name() this.name()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -140,7 +140,7 @@ fn set_name() {
this.set_name(name); this.set_name(name);
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -171,7 +171,7 @@ fn to_string() {
this.to_string() this.to_string()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -180,13 +180,13 @@ fn to_string() {
assert.equal(wasm.error_to_string(error), 'Error: error message 1'); assert.equal(wasm.error_to_string(error), 'Error: error message 1');
(error.name as any) = undefined; error.name = undefined;
assert.equal(wasm.error_to_string(error), 'Error: error message 1'); assert.equal(wasm.error_to_string(error), 'Error: error message 1');
error.name = 'error_name_1'; error.name = 'error_name_1';
assert.equal(wasm.error_to_string(error), 'error_name_1: error message 1'); assert.equal(wasm.error_to_string(error), 'error_name_1: error message 1');
(error.message as any) = undefined; error.message = undefined;
assert.equal(wasm.error_to_string(error), 'error_name_1'); assert.equal(wasm.error_to_string(error), 'error_name_1');
error.name = 'error_name_2'; error.name = 'error_name_2';

View File

@ -21,7 +21,7 @@ fn apply() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -57,7 +57,7 @@ fn bind() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -97,21 +97,21 @@ fn length() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
assert.equal(wasm.fn_length(() => {}), 0); assert.equal(wasm.fn_length(() => {}), 0);
assert.equal(wasm.fn_length((a: string) => console.log(a)), 1); assert.equal(wasm.fn_length(a => console.log(a)), 1);
assert.equal(wasm.fn_length((a: string, b: string) => console.log({ a, b })), 2); assert.equal(wasm.fn_length((a, b) => console.log({ a, b })), 2);
function fn0() {} function fn0() {}
function fn1(a: string) { function fn1(a) {
console.log(a); console.log(a);
} }
function fn2(a: string, b: string) { function fn2(a, b) {
console.log({ a, b }); console.log({ a, b });
} }
@ -143,7 +143,7 @@ fn name() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -190,17 +190,17 @@ fn to_string() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
function fn1(a: any, b: any) { return a + b } function fn1(a, b) { return a + b; }
const fn2 = (a: number) => console.log(a); const fn2 = a => console.log(a);
assert.equal(wasm.get_source_code(fn1), 'function fn1(a, b) { return a + b; }'); assert.equal(wasm.get_source_code(fn1), 'function fn1(a, b) { return a + b; }');
assert.equal(wasm.get_source_code(fn2), 'function (a) { return console.log(a); }'); assert.equal(wasm.get_source_code(fn2), 'a => console.log(a)');
} }
"#, "#,
) )

View File

@ -8,40 +8,40 @@ fn return_() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn gen_return(this: &js::Generator, value: &JsValue) -> JsValue { pub fn gen_return(this: &js::Generator, value: &JsValue) -> JsValue {
this.return_(value) this.return_(value)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
function* generator() { function* generator() {
yield 1; yield 1;
yield 2; yield 2;
}
const gen = generator();
gen.next();
const res = wasm.gen_return(gen, 42);
assert.deepEqual(res, { value: 42, done: true });
const next = gen.next();
assert.deepEqual(next, { value: undefined, done: true });
} }
"#,
const gen = generator();
gen.next();
const res = wasm.gen_return(gen, 42);
assert.deepEqual(res, { value: 42, done: true });
const next = gen.next();
assert.deepEqual(next, { value: undefined, done: true });
}
"#,
) )
.test() .test()
} }
@ -52,54 +52,54 @@ fn next() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn next(this: &js::Generator, value: &JsValue) -> JsValue { pub fn next(this: &js::Generator, value: &JsValue) -> JsValue {
this.next(value) this.next(value)
.ok() .ok()
.expect("generator throws an error") .expect("generator throws an error")
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn next_throws_error(this: &js::Generator, value: &JsValue) -> bool { pub fn next_throws_error(this: &js::Generator, value: &JsValue) -> bool {
this.next(value).is_err() this.next(value).is_err()
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
function* generator() { function* generator() {
const reply = yield '2 * 2'; const reply = yield '2 * 2';
return reply === 4; return reply === 4;
}
const gen = generator();
const q = wasm.next(gen, undefined);
assert.deepEqual(q, { value: '2 * 2', done: false });
const a = wasm.next(gen, 4);
assert.deepEqual(a, { value: true, done: true });
function* brokenGenerator() {
throw new Error('Something went wrong');
yield 1;
}
assert.ok(wasm.next_throws_error(brokenGenerator(), undefined));
} }
"#,
const gen = generator();
const q = wasm.next(gen, undefined);
assert.deepEqual(q, { value: '2 * 2', done: false });
const a = wasm.next(gen, 4);
assert.deepEqual(a, { value: true, done: true });
function* brokenGenerator() {
throw new Error('Something went wrong');
yield 1;
}
assert(wasm.next_throws_error(brokenGenerator(), undefined));
}
"#,
) )
.test() .test()
} }
@ -110,37 +110,37 @@ fn throw() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn gen_throws_error(this: &js::Generator, error: &js::Error) -> bool { pub fn gen_throws_error(this: &js::Generator, error: &js::Error) -> bool {
this.throw(error).is_err() this.throw(error).is_err()
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
function* generator() { function* generator() {
yield 1; yield 1;
yield 2; yield 2;
}
const gen = generator();
gen.next();
assert.ok(wasm.gen_throws_error(gen, new Error('Something went wrong')));
assert.deepEqual(gen.next(), { value: undefined, done: true });
} }
"#,
const gen = generator();
gen.next();
assert(wasm.gen_throws_error(gen, new Error('Something went wrong')));
assert.deepEqual(gen.next(), { value: undefined, done: true });
}
"#,
) )
.test() .test()
} }

48
tests/all/js_globals/JsString.rs Normal file → Executable file
View File

@ -22,7 +22,7 @@ fn length() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -58,7 +58,7 @@ fn char_at() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -87,13 +87,13 @@ fn char_code_at() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn string_char_code_at(this: &js::JsString, index: u32) -> js::Number { pub fn string_char_code_at(this: &js::JsString, index: u32) -> f64 {
this.char_code_at(index) this.char_code_at(index)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -101,8 +101,14 @@ fn char_code_at() {
var anyString = 'Brave new world'; var anyString = 'Brave new world';
export function test() { export function test() {
assert.equal(wasm.string_char_code_at(anyString, 0), 66); for (let i = 0; i < anyString.length; i++) {
assert.ok(isNaN(wasm.string_char_code_at(anyString, 999))); assert.equal(wasm.string_char_code_at(anyString, i),
anyString.charCodeAt(i),
`charCodeAt(${i})`);
}
const outOfBounds = wasm.string_char_code_at(anyString, 999);
assert.ok(Number.isNaN(outOfBounds));
} }
"#, "#,
) )
@ -128,7 +134,7 @@ fn code_point_at() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -162,7 +168,7 @@ fn concat() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -196,7 +202,7 @@ fn includes() {
this.includes(search_value, position) this.includes(search_value, position)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -231,7 +237,7 @@ fn index_of() {
this.index_of(search_value, from_index) this.index_of(search_value, from_index)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -274,7 +280,7 @@ fn slice() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -305,7 +311,7 @@ fn starts_with() {
this.starts_with(search_string, position) this.starts_with(search_string, position)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -336,7 +342,7 @@ fn substring() {
this.substring(index_start, index_end) this.substring(index_start, index_end)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -375,7 +381,7 @@ fn substr() {
this.substr(start, length) this.substr(start, length)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -411,7 +417,7 @@ fn to_lower_case() {
this.to_lower_case() this.to_lower_case()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -441,7 +447,7 @@ fn to_string() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -470,7 +476,7 @@ fn to_upper_case() {
this.to_upper_case() this.to_upper_case()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -500,7 +506,7 @@ fn trim() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -539,7 +545,7 @@ fn trim_end_and_trim_right() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -579,7 +585,7 @@ fn trim_start_and_trim_left() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -614,7 +620,7 @@ fn value_of() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

16
tests/all/js_globals/Map.rs Normal file → Executable file
View File

@ -17,7 +17,7 @@ fn clear() {
this.clear(); this.clear();
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -49,7 +49,7 @@ fn delete() {
this.delete(key) this.delete(key)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -81,7 +81,7 @@ fn get() {
this.get(key) this.get(key)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -112,7 +112,7 @@ fn has() {
this.has(key) this.has(key)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -141,7 +141,7 @@ fn new() {
js::Map::new() js::Map::new()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -169,7 +169,7 @@ fn set() {
this.set(key, value) this.set(key, value)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -194,11 +194,11 @@ fn size() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn map_size(this: &js::Map) -> js::Number { pub fn map_size(this: &js::Map) -> u32 {
this.size() this.size()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

View File

@ -18,7 +18,7 @@ fn entries() {
this.entries() this.entries()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -50,7 +50,7 @@ fn keys() {
this.keys() this.keys()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -82,7 +82,7 @@ fn values() {
this.values() this.values()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

140
tests/all/js_globals/Math.rs Normal file → Executable file
View File

@ -15,13 +15,13 @@ fn abs() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn abs(x: f64) -> js::Number { pub fn abs(x: f64) -> f64 {
js::Math::abs(x) js::Math::abs(x)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -49,13 +49,13 @@ fn acos() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn acos(x: f64) -> js::Number { pub fn acos(x: f64) -> f64 {
js::Math::acos(x) js::Math::acos(x)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -63,7 +63,7 @@ fn acos() {
export function test() { export function test() {
assert.equal(wasm.acos(-1), Math.PI); assert.equal(wasm.acos(-1), Math.PI);
assert.equal(wasm.acos(0.5), 1.0471975511965979); assert.equal(wasm.acos(0.5), 1.0471975511965979);
assert(Number.isNaN(wasm.acos(2))); assert.ok(Number.isNaN(wasm.acos(2)));
} }
"#, "#,
) )
@ -83,13 +83,13 @@ fn acosh() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn acosh(x: f64) -> js::Number { pub fn acosh(x: f64) -> f64 {
js::Math::acosh(x) js::Math::acosh(x)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -97,7 +97,7 @@ fn acosh() {
export function test() { export function test() {
assert.equal(wasm.acosh(1), 0); assert.equal(wasm.acosh(1), 0);
assert.equal(wasm.acosh(2), Math.acosh(2)); assert.equal(wasm.acosh(2), Math.acosh(2));
assert(Number.isNaN(wasm.acosh(0.5))); assert.ok(Number.isNaN(wasm.acosh(0.5)));
} }
"#, "#,
) )
@ -117,13 +117,13 @@ fn asin() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn asin(x: f64) -> js::Number { pub fn asin(x: f64) -> f64 {
js::Math::asin(x) js::Math::asin(x)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -131,7 +131,7 @@ fn asin() {
export function test() { export function test() {
assert.equal(wasm.asin(1), Math.asin(1)); assert.equal(wasm.asin(1), Math.asin(1));
assert.equal(wasm.asin(0.5), Math.asin(0.5)); assert.equal(wasm.asin(0.5), Math.asin(0.5));
assert(Number.isNaN(wasm.asin(2))); assert.ok(Number.isNaN(wasm.asin(2)));
} }
"#, "#,
) )
@ -151,13 +151,13 @@ fn asinh() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn asinh(x: f64) -> js::Number { pub fn asinh(x: f64) -> f64 {
js::Math::asinh(x) js::Math::asinh(x)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -184,13 +184,13 @@ fn atan() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn atan(x: f64) -> js::Number { pub fn atan(x: f64) -> f64 {
js::Math::atan(x) js::Math::atan(x)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -217,13 +217,13 @@ fn atan2() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn atan2(y: f64, x: f64) -> js::Number { pub fn atan2(y: f64, x: f64) -> f64 {
js::Math::atan2(y, x) js::Math::atan2(y, x)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -250,13 +250,13 @@ fn atanh() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn atanh(x: f64) -> js::Number { pub fn atanh(x: f64) -> f64 {
js::Math::atanh(x) js::Math::atanh(x)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -264,7 +264,7 @@ fn atanh() {
export function test() { export function test() {
assert.equal(wasm.atanh(1), Math.atanh(1)); assert.equal(wasm.atanh(1), Math.atanh(1));
assert.equal(wasm.atanh(0.5), Math.atanh(0.5)); assert.equal(wasm.atanh(0.5), Math.atanh(0.5));
assert(Number.isNaN(wasm.atanh(2))); assert.ok(Number.isNaN(wasm.atanh(2)));
} }
"#, "#,
) )
@ -284,13 +284,13 @@ fn cbrt() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn cbrt(x: f64) -> js::Number { pub fn cbrt(x: f64) -> f64 {
js::Math::cbrt(x) js::Math::cbrt(x)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -317,13 +317,13 @@ fn ceil() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn ceil(x: f64) -> js::Number { pub fn ceil(x: f64) -> i32 {
js::Math::ceil(x) js::Math::ceil(x)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -350,13 +350,13 @@ fn clz32() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn clz32(x: i32) -> js::Number { pub fn clz32(x: i32) -> u32 {
js::Math::clz32(x) js::Math::clz32(x)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -381,11 +381,11 @@ fn cos() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn cos(x: f64) -> js::Number { pub fn cos(x: f64) -> f64 {
js::Math::cos(x) js::Math::cos(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -408,11 +408,11 @@ fn cosh() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn cosh(x: f64) -> js::Number { pub fn cosh(x: f64) -> f64 {
js::Math::cosh(x) js::Math::cosh(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -435,11 +435,11 @@ fn exp() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn exp(x: f64) -> js::Number { pub fn exp(x: f64) -> f64 {
js::Math::exp(x) js::Math::exp(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -463,11 +463,11 @@ fn expm1() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn expm1(x: f64) -> js::Number { pub fn expm1(x: f64) -> f64 {
js::Math::expm1(x) js::Math::expm1(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -494,13 +494,13 @@ fn floor() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn floor(x: f64) -> js::Number { pub fn floor(x: f64) -> i32 {
js::Math::floor(x) js::Math::floor(x)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -525,11 +525,11 @@ fn fround() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn fround(x: f64) -> js::Number { pub fn fround(x: f64) -> f32 {
js::Math::fround(x) js::Math::fround(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -554,11 +554,11 @@ fn imul() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn imul(x: i32, y:i32) -> js::Number { pub fn imul(x: i32, y:i32) -> i32 {
js::Math::imul(x, y) js::Math::imul(x, y)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -582,11 +582,11 @@ fn log() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn log(x: f64) -> js::Number { pub fn log(x: f64) -> f64 {
js::Math::log(x) js::Math::log(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -609,11 +609,11 @@ fn log10() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn log10(x: f64) -> js::Number { pub fn log10(x: f64) -> f64 {
js::Math::log10(x) js::Math::log10(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -637,11 +637,11 @@ fn log1p() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn log1p(x: f64) -> js::Number { pub fn log1p(x: f64) -> f64 {
js::Math::log1p(x) js::Math::log1p(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -649,7 +649,7 @@ fn log1p() {
assert.equal(wasm.log1p(1), 0.6931471805599453); assert.equal(wasm.log1p(1), 0.6931471805599453);
assert.equal(wasm.log1p(0), 0); assert.equal(wasm.log1p(0), 0);
assert.equal(wasm.log1p(-1), -Infinity); assert.equal(wasm.log1p(-1), -Infinity);
assert(isNaN(wasm.log1p(-2))); assert.ok(isNaN(wasm.log1p(-2)));
} }
"#) "#)
.test() .test()
@ -666,11 +666,11 @@ fn log2() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn log2(x: f64) -> js::Number { pub fn log2(x: f64) -> f64 {
js::Math::log2(x) js::Math::log2(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -695,18 +695,18 @@ fn pow() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn pow(base: f64, exponent: f64) -> js::Number { pub fn pow(base: f64, exponent: f64) -> f64 {
js::Math::pow(base, exponent) js::Math::pow(base, exponent)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
assert.equal(wasm.pow(7, 2), 49); assert.equal(wasm.pow(7, 2), 49);
assert.equal(wasm.pow(3.8, 0.5), Math.pow(3.8, 0.5)); assert.equal(wasm.pow(3.8, 0.5), Math.pow(3.8, 0.5));
assert(Number.isNaN(wasm.pow(-2, 0.5))); assert.ok(Number.isNaN(wasm.pow(-2, 0.5)));
} }
"#) "#)
.test() .test()
@ -723,11 +723,11 @@ fn round() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn round(x: f64) -> js::Number { pub fn round(x: f64) -> i32 {
js::Math::round(x) js::Math::round(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -753,11 +753,11 @@ fn sign() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn sign(x: f64) -> js::Number { pub fn sign(x: f64) -> f64 {
js::Math::sign(x) js::Math::sign(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -766,7 +766,7 @@ fn sign() {
assert.equal(wasm.sign(-3), -1); assert.equal(wasm.sign(-3), -1);
assert.equal(wasm.sign(2.3), 1); assert.equal(wasm.sign(2.3), 1);
assert.equal(wasm.sign(0), 0); assert.equal(wasm.sign(0), 0);
assert(Number.isNaN(wasm.sign(NaN))); assert.ok(Number.isNaN(wasm.sign(NaN)));
} }
"#) "#)
.test() .test()
@ -783,11 +783,11 @@ fn sin() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn sin(x: f64) -> js::Number { pub fn sin(x: f64) -> f64 {
js::Math::sin(x) js::Math::sin(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -811,11 +811,11 @@ fn sinh() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn sinh(x: f64) -> js::Number { pub fn sinh(x: f64) -> f64 {
js::Math::sinh(x) js::Math::sinh(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -839,11 +839,11 @@ fn sqrt() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn sqrt(x: f64) -> js::Number { pub fn sqrt(x: f64) -> f64 {
js::Math::sqrt(x) js::Math::sqrt(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -852,7 +852,7 @@ fn sqrt() {
assert.equal(wasm.sqrt(2), Math.sqrt(2)); assert.equal(wasm.sqrt(2), Math.sqrt(2));
assert.equal(wasm.sqrt(42.42), Math.sqrt(42.42)); assert.equal(wasm.sqrt(42.42), Math.sqrt(42.42));
assert.equal(wasm.sqrt(1), 1); assert.equal(wasm.sqrt(1), 1);
assert(Number.isNaN(wasm.sqrt(-1))); assert.ok(Number.isNaN(wasm.sqrt(-1)));
} }
"#) "#)
.test() .test()
@ -869,11 +869,11 @@ fn tan() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn tan(x: f64) -> js::Number { pub fn tan(x: f64) -> f64 {
js::Math::tan(x) js::Math::tan(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -897,11 +897,11 @@ fn tanh() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn tanh(x: f64) -> js::Number { pub fn tanh(x: f64) -> f64 {
js::Math::tanh(x) js::Math::tanh(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -925,11 +925,11 @@ fn trunc() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn trunc(x: f64) -> js::Number { pub fn trunc(x: f64) -> i32 {
js::Math::trunc(x) js::Math::trunc(x)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

43
tests/all/js_globals/Number.rs Normal file → Executable file
View File

@ -2,6 +2,33 @@
use super::project; use super::project;
#[test]
fn is_integer() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn is_integer(obj: &js::Object) -> bool {
js::Number::is_integer(&obj)
}
"#)
.file("test.js", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
assert.ok(wasm.is_integer(123));
assert.ok(!wasm.is_integer(123.45));
}
"#)
.test()
}
#[test] #[test]
fn new() { fn new() {
project() project()
@ -17,7 +44,7 @@ fn new() {
Number::new(JsValue::from(42)) Number::new(JsValue::from(42))
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -44,7 +71,7 @@ fn to_locale_string() {
this.to_locale_string(locale) this.to_locale_string(locale)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -83,7 +110,7 @@ fn to_precision() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -121,7 +148,7 @@ fn to_string() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -150,13 +177,13 @@ fn value_of() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn js_value_of(this: &js::Number) -> js::Number { pub fn js_value_of(this: &js::Number) -> f64 {
this.value_of() this.value_of()
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -195,7 +222,7 @@ fn to_fixed() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -233,7 +260,7 @@ fn to_exponential() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

View File

@ -21,7 +21,7 @@ fn new() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -53,18 +53,18 @@ fn has_own_property() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
assert(wasm.has_own_foo_property({ foo: 42 }, "foo")); assert.ok(wasm.has_own_foo_property({ foo: 42 }, "foo"));
assert(wasm.has_own_foo_property({ 42: "foo" }, 42)); assert.ok(wasm.has_own_foo_property({ 42: "foo" }, 42));
assert(!wasm.has_own_foo_property({ foo: 42 }, "bar")); assert.ok(!wasm.has_own_foo_property({ foo: 42 }, "bar"));
const s = Symbol(); const s = Symbol();
assert(wasm.has_own_foo_property({ [s]: "foo" }, s)); assert.ok(wasm.has_own_foo_property({ [s]: "foo" }, s));
} }
"#, "#,
) )
@ -96,7 +96,7 @@ fn to_string() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -125,16 +125,16 @@ fn is_extensible() {
js::Object::is_extensible(&obj) js::Object::is_extensible(&obj)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
const object = {}; const object = {};
assert(wasm.is_extensible(object)); assert.ok(wasm.is_extensible(object));
Object.preventExtensions(object); Object.preventExtensions(object);
assert(!wasm.is_extensible(object)); assert.ok(!wasm.is_extensible(object));
} }
"#) "#)
.test() .test()
@ -155,16 +155,16 @@ fn is_frozen() {
js::Object::is_frozen(&obj) js::Object::is_frozen(&obj)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
const object = {}; const object = {};
assert(!wasm.is_frozen(object)); assert.ok(!wasm.is_frozen(object));
Object.freeze(object); Object.freeze(object);
assert(wasm.is_frozen(object)); assert.ok(wasm.is_frozen(object));
} }
"#) "#)
.test() .test()
@ -185,16 +185,16 @@ fn is_sealed() {
js::Object::is_sealed(&obj) js::Object::is_sealed(&obj)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
const object = {}; const object = {};
assert(!wasm.is_sealed(object)); assert.ok(!wasm.is_sealed(object));
Object.seal(object); Object.seal(object);
assert(wasm.is_sealed(object)); assert.ok(wasm.is_sealed(object));
} }
"#) "#)
.test() .test()
@ -219,7 +219,7 @@ fn is_prototype_of() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -229,8 +229,8 @@ fn is_prototype_of() {
export function test() { export function test() {
const foo = new Foo(); const foo = new Foo();
assert(wasm.obj_is_prototype_of_value(Foo.prototype, foo)); assert.ok(wasm.obj_is_prototype_of_value(Foo.prototype, foo));
assert(!wasm.obj_is_prototype_of_value(Bar.prototype, foo)); assert.ok(!wasm.obj_is_prototype_of_value(Bar.prototype, foo));
} }
"#, "#,
) )
@ -256,7 +256,7 @@ fn keys() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -285,7 +285,7 @@ fn prevent_extensions() {
js::Object::prevent_extensions(obj); js::Object::prevent_extensions(obj);
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -293,7 +293,7 @@ fn prevent_extensions() {
const object = {}; const object = {};
wasm.prevent_extensions(object); wasm.prevent_extensions(object);
assert(!Object.isExtensible(object)); assert.ok(!Object.isExtensible(object));
assert.throws(() => { assert.throws(() => {
'use strict'; 'use strict';
Object.defineProperty(object, 'foo', { value: 42 }); Object.defineProperty(object, 'foo', { value: 42 });
@ -322,19 +322,19 @@ fn property_is_enumerable() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
assert(wasm.property_is_enumerable({ foo: 42 }, "foo")); assert.ok(wasm.property_is_enumerable({ foo: 42 }, "foo"));
assert(wasm.property_is_enumerable({ 42: "foo" }, 42)); assert.ok(wasm.property_is_enumerable({ 42: "foo" }, 42));
assert(!wasm.property_is_enumerable({}, 42)); assert.ok(!wasm.property_is_enumerable({}, 42));
const obj = {}; const obj = {};
Object.defineProperty(obj, "foo", { enumerable: false }); Object.defineProperty(obj, "foo", { enumerable: false });
assert(!wasm.property_is_enumerable(obj, "foo")); assert.ok(!wasm.property_is_enumerable(obj, "foo"));
const s = Symbol(); const s = Symbol();
assert.ok(wasm.property_is_enumerable({ [s]: true }, s)); assert.ok(wasm.property_is_enumerable({ [s]: true }, s));
@ -359,12 +359,12 @@ fn seal() {
js::Object::seal(&value) js::Object::seal(&value)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
const object: any = { foo: 'bar' }; const object = { foo: 'bar' };
const sealedObject = wasm.seal(object); const sealedObject = wasm.seal(object);
assert.strictEqual(object, sealedObject); assert.strictEqual(object, sealedObject);
assert.throws(() => { assert.throws(() => {
@ -410,7 +410,7 @@ fn set_prototype_of() {
js::Object::set_prototype_of(&object, &prototype) js::Object::set_prototype_of(&object, &prototype)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -419,7 +419,7 @@ fn set_prototype_of() {
const newPrototype = { bar: 'baz' }; const newPrototype = { bar: 'baz' };
const modifiedObject = wasm.set_prototype_of(object, newPrototype); const modifiedObject = wasm.set_prototype_of(object, newPrototype);
assert(newPrototype.isPrototypeOf(modifiedObject)); assert.ok(newPrototype.isPrototypeOf(modifiedObject));
} }
"#) "#)
.test() .test()
@ -445,7 +445,7 @@ fn to_locale_string() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -477,7 +477,7 @@ fn value_of() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -507,7 +507,7 @@ fn values() {
js::Object::values(&obj) js::Object::values(&obj)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

View File

@ -0,0 +1,76 @@
#![allow(non_snake_case)]
use project;
#[test]
fn new() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn new_proxy(target: JsValue, handler: js::Object) -> js::Proxy {
js::Proxy::new(&target, &handler)
}
"#)
.file("test.js", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const target = { a: 100 };
const handler = {
get: function(obj, prop) {
return prop in obj ? obj[prop] : 37;
}
};
const proxy = wasm.new_proxy(target, handler);
assert.equal(proxy.a, 100);
assert.equal(proxy.b, 37);
}
"#)
.test()
}
#[test]
fn revocable() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn new_revocable_proxy(target: JsValue, handler: js::Object) -> js::Object {
js::Proxy::revocable(&target, &handler)
}
"#)
.file("test.js", r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
const target = { a: 100 };
const handler = {
get: function(obj, prop) {
return prop in obj ? obj[prop] : 37;
}
};
const { proxy, revoke } =
wasm.new_revocable_proxy(target, handler);
assert.equal(proxy.a, 100);
assert.equal(proxy.b, 37);
revoke();
assert.throws(() => { proxy.a }, TypeError);
assert.throws(() => { proxy.b }, TypeError);
assert.equal(typeof proxy, "object");
}
"#)
.test()
}

14
tests/all/js_globals/Set.rs Normal file → Executable file
View File

@ -18,7 +18,7 @@ fn add() {
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -51,7 +51,7 @@ fn clear() {
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -81,7 +81,7 @@ fn delete() {
this.delete(value) this.delete(value)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -110,7 +110,7 @@ fn has() {
this.has(value) this.has(value)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -139,7 +139,7 @@ fn new() {
js::Set::new() js::Set::new()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -163,12 +163,12 @@ fn size() {
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn size(this: &js::Set) -> js::Number { pub fn size(this: &js::Set) -> u32 {
this.size() this.size()
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

View File

@ -18,7 +18,7 @@ fn entries() {
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -50,7 +50,7 @@ fn keys() {
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -81,7 +81,7 @@ fn values() {
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

View File

@ -0,0 +1,42 @@
#![allow(non_snake_case)]
use project;
#[test]
fn has_instance() {
project()
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::js;
#[wasm_bindgen]
pub fn symbol_has_instance() -> js::Symbol {
js::Symbol::has_instance()
}
"#,
)
.file(
"test.js",
r#"
import * as assert from "assert";
import * as wasm from "./out";
class Array1 {
static [wasm.symbol_has_instance()](instance) {
return Array.isArray(instance);
}
}
export function test() {
assert.equal(typeof wasm.symbol_has_instance(), "symbol");
assert.ok([] instanceof Array1);
}
"#,
)
.test()
}

View File

@ -21,7 +21,7 @@ fn new_undefined() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -53,7 +53,7 @@ fn new_length() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -81,7 +81,7 @@ fn fill() {
this.fill(value, start, end) this.fill(value, start, end)
} }
"#) "#)
.file("test.ts", r#" .file("test.js", r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

View File

@ -21,7 +21,7 @@ fn new() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -53,7 +53,7 @@ fn get() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -91,7 +91,7 @@ fn set() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -126,7 +126,7 @@ fn has() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -164,7 +164,7 @@ fn delete() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

View File

@ -21,7 +21,7 @@ fn new() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -53,7 +53,7 @@ fn has() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -91,7 +91,7 @@ fn add() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
@ -132,7 +132,7 @@ fn delete() {
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";

View File

@ -3,6 +3,7 @@
use super::project; use super::project;
mod Array; mod Array;
mod ArrayBuffer;
mod ArrayIterator; mod ArrayIterator;
mod Boolean; mod Boolean;
mod Date; mod Date;
@ -15,9 +16,11 @@ mod MapIterator;
mod Math; mod Math;
mod Number; mod Number;
mod Object; mod Object;
mod Proxy;
mod Reflect; mod Reflect;
mod Set; mod Set;
mod SetIterator; mod SetIterator;
mod Symbol;
mod TypedArray; mod TypedArray;
mod WeakMap; mod WeakMap;
mod WeakSet; mod WeakSet;
@ -29,22 +32,22 @@ fn decode_uri() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn test() { pub fn test() {
let x = js::decode_uri("https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B") let x = js::decode_uri("https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B")
.ok() .ok()
.expect("should decode URI OK"); .expect("should decode URI OK");
assert_eq!(String::from(x), "https://mozilla.org/?x=шеллы"); assert_eq!(String::from(x), "https://mozilla.org/?x=шеллы");
assert!(js::decode_uri("%E0%A4%A").is_err()); assert!(js::decode_uri("%E0%A4%A").is_err());
} }
"#, "#,
) )
.test(); .test();
} }
@ -55,22 +58,22 @@ fn decode_uri_component() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn test() { pub fn test() {
let x = js::decode_uri_component("%3Fx%3Dtest") let x = js::decode_uri_component("%3Fx%3Dtest")
.ok() .ok()
.expect("should decode URI OK"); .expect("should decode URI OK");
assert_eq!(String::from(x), "?x=test"); assert_eq!(String::from(x), "?x=test");
assert!(js::decode_uri_component("%E0%A4%A").is_err()); assert!(js::decode_uri_component("%E0%A4%A").is_err());
} }
"#, "#,
) )
.test(); .test();
} }
@ -82,18 +85,18 @@ fn encode_uri() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn test() { pub fn test() {
let x = js::encode_uri("ABC abc 123"); let x = js::encode_uri("ABC abc 123");
assert_eq!(String::from(x), "ABC%20abc%20123"); assert_eq!(String::from(x), "ABC%20abc%20123");
} }
"#, "#,
) )
.test(); .test();
} }
@ -104,18 +107,18 @@ fn encode_uri_component() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn test() { pub fn test() {
let x = js::encode_uri_component("?x=шеллы"); let x = js::encode_uri_component("?x=шеллы");
assert_eq!(String::from(x), "%3Fx%3D%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"); assert_eq!(String::from(x), "%3Fx%3D%D1%88%D0%B5%D0%BB%D0%BB%D1%8B");
} }
"#, "#,
) )
.test(); .test();
} }
@ -126,23 +129,23 @@ fn eval() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::js; use wasm_bindgen::js;
#[wasm_bindgen] #[wasm_bindgen]
pub fn test() { pub fn test() {
let x = js::eval("42").ok().expect("should eval OK"); let x = js::eval("42").ok().expect("should eval OK");
assert_eq!(x.as_f64().unwrap(), 42.0); assert_eq!(x.as_f64().unwrap(), 42.0);
let err = js::eval("(function () { throw 42; }())") let err = js::eval("(function () { throw 42; }())")
.err() .err()
.expect("eval should throw"); .expect("eval should throw");
assert_eq!(err.as_f64().unwrap(), 42.0); assert_eq!(err.as_f64().unwrap(), 42.0);
} }
"#, "#,
) )
.test(); .test();
} }

View File

@ -6,43 +6,43 @@ fn simple() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn foo(s: &JsValue); fn foo(s: &JsValue);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn bar(s: &JsValue) { pub fn bar(s: &JsValue) {
foo(s); foo(s);
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out"; import * as wasm from "./out";
import * as assert from "assert"; import * as assert from "assert";
let ARG: string | null = null; let ARG = null;
export function foo(s: any): void { export function foo(s) {
assert.strictEqual(ARG, null); assert.strictEqual(ARG, null);
ARG = s; ARG = s;
} }
export function test() { export function test() {
assert.strictEqual(ARG, null); assert.strictEqual(ARG, null);
let sym = (Symbol as any)('test'); let sym = Symbol('test');
wasm.bar(sym); wasm.bar(sym);
assert.strictEqual(ARG, sym); assert.strictEqual(ARG, sym);
} }
"#, "#,
) )
.test(); .test();
} }
@ -53,43 +53,43 @@ fn owned() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn foo(s: JsValue); fn foo(s: JsValue);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn bar(s: JsValue) { pub fn bar(s: JsValue) {
foo(s); foo(s);
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out"; import * as wasm from "./out";
import * as assert from "assert"; import * as assert from "assert";
let ARG: any = null; let ARG = null;
export function foo(s: any): void { export function foo(s) {
assert.strictEqual(ARG, null); assert.strictEqual(ARG, null);
ARG = s; ARG = s;
} }
export function test() { export function test() {
assert.strictEqual(ARG, null); assert.strictEqual(ARG, null);
let sym = (Symbol as any)('test'); let sym = Symbol('test');
wasm.bar(sym); wasm.bar(sym);
assert.strictEqual(ARG, sym); assert.strictEqual(ARG, sym);
} }
"#, "#,
) )
.test(); .test();
} }
@ -100,49 +100,49 @@ fn clone() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn foo1(s: JsValue); fn foo1(s: JsValue);
fn foo2(s: &JsValue); fn foo2(s: &JsValue);
fn foo3(s: JsValue); fn foo3(s: JsValue);
fn foo4(s: &JsValue); fn foo4(s: &JsValue);
fn foo5(s: JsValue); fn foo5(s: JsValue);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn bar(s: JsValue) { pub fn bar(s: JsValue) {
foo1(s.clone()); foo1(s.clone());
foo2(&s); foo2(&s);
foo3(s.clone()); foo3(s.clone());
foo4(&s); foo4(&s);
foo5(s); foo5(s);
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out"; import * as wasm from "./out";
import * as assert from "assert"; import * as assert from "assert";
let ARG = (Symbol as any)('test'); let ARG = Symbol('test');
export function foo1(s: any): void { assert.strictEqual(s, ARG); } export function foo1(s) { assert.strictEqual(s, ARG); }
export function foo2(s: any): void { assert.strictEqual(s, ARG); } export function foo2(s) { assert.strictEqual(s, ARG); }
export function foo3(s: any): void { assert.strictEqual(s, ARG); } export function foo3(s) { assert.strictEqual(s, ARG); }
export function foo4(s: any): void { assert.strictEqual(s, ARG); } export function foo4(s) { assert.strictEqual(s, ARG); }
export function foo5(s: any): void { assert.strictEqual(s, ARG); } export function foo5(s) { assert.strictEqual(s, ARG); }
export function test() { export function test() {
wasm.bar(ARG); wasm.bar(ARG);
} }
"#, "#,
) )
.test(); .test();
} }
@ -153,46 +153,46 @@ fn promote() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn foo1(s: &JsValue); fn foo1(s: &JsValue);
fn foo2(s: JsValue); fn foo2(s: JsValue);
fn foo3(s: &JsValue); fn foo3(s: &JsValue);
fn foo4(s: JsValue); fn foo4(s: JsValue);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn bar(s: &JsValue) { pub fn bar(s: &JsValue) {
foo1(s); foo1(s);
foo2(s.clone()); foo2(s.clone());
foo3(s); foo3(s);
foo4(s.clone()); foo4(s.clone());
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out"; import * as wasm from "./out";
import * as assert from "assert"; import * as assert from "assert";
let ARG = (Symbol as any)('test'); let ARG = Symbol('test');
export function foo1(s: any): void { assert.strictEqual(s, ARG); } export function foo1(s) { assert.strictEqual(s, ARG); }
export function foo2(s: any): void { assert.strictEqual(s, ARG); } export function foo2(s) { assert.strictEqual(s, ARG); }
export function foo3(s: any): void { assert.strictEqual(s, ARG); } export function foo3(s) { assert.strictEqual(s, ARG); }
export function foo4(s: any): void { assert.strictEqual(s, ARG); } export function foo4(s) { assert.strictEqual(s, ARG); }
export function test() { export function test() {
wasm.bar(ARG); wasm.bar(ARG);
} }
"#, "#,
) )
.test(); .test();
} }
@ -203,40 +203,40 @@ fn returning_vector() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn foo() -> JsValue; fn foo() -> JsValue;
}
#[wasm_bindgen]
pub fn bar() -> Vec<JsValue> {
let mut res = Vec::new();
for _ in 0..10 {
res.push(foo())
} }
res
} #[wasm_bindgen]
"#, pub fn bar() -> Vec<JsValue> {
let mut res = Vec::new();
for _ in 0..10 {
res.push(foo())
}
res
}
"#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out"; import * as wasm from "./out";
import * as assert from "assert"; import * as assert from "assert";
export function foo(): any { return { "foo": "bar" }; } export function foo() { return { "foo": "bar" }; }
export function test() { export function test() {
const result = wasm.bar(); const result = wasm.bar();
assert.strictEqual(result.length, 10); assert.strictEqual(result.length, 10);
} }
"#, "#,
) )
.test(); .test();
} }
@ -247,36 +247,36 @@ fn another_vector_return() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub fn get_array() -> Vec<JsValue> { pub fn get_array() -> Vec<JsValue> {
vec![ vec![
JsValue::from(1), JsValue::from(1),
JsValue::from(2), JsValue::from(2),
JsValue::from(3), JsValue::from(3),
JsValue::from(4), JsValue::from(4),
JsValue::from(5), JsValue::from(5),
JsValue::from(6), JsValue::from(6),
] ]
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { get_array } from "./out"; import { get_array } from "./out";
import * as assert from "assert"; import * as assert from "assert";
export function test() { export function test() {
assert.deepStrictEqual(get_array(), [1, 2, 3, 4, 5, 6]); assert.deepStrictEqual(get_array(), [1, 2, 3, 4, 5, 6]);
} }
"#, "#,
) )
.test(); .test();
} }
@ -290,86 +290,86 @@ fn serde() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct Foo { pub struct Foo {
a: u32, a: u32,
b: String, b: String,
c: Option<Bar>, c: Option<Bar>,
d: Bar, d: Bar,
} }
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct Bar { pub struct Bar {
a: u32, a: u32,
} }
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn verify(a: JsValue) -> JsValue; fn verify(a: JsValue) -> JsValue;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run() { pub fn run() {
let js = JsValue::from_serde("foo").unwrap(); let js = JsValue::from_serde("foo").unwrap();
assert_eq!(js.as_string(), Some("foo".to_string())); assert_eq!(js.as_string(), Some("foo".to_string()));
let ret = verify(JsValue::from_serde(&Foo { let ret = verify(JsValue::from_serde(&Foo {
a: 0, a: 0,
b: "foo".to_string(), b: "foo".to_string(),
c: None, c: None,
d: Bar { a: 1 }, d: Bar { a: 1 },
}).unwrap()); }).unwrap());
let foo = ret.into_serde::<Foo>().unwrap(); let foo = ret.into_serde::<Foo>().unwrap();
assert_eq!(foo.a, 2); assert_eq!(foo.a, 2);
assert_eq!(foo.b, "bar"); assert_eq!(foo.b, "bar");
assert!(foo.c.is_some()); assert!(foo.c.is_some());
assert_eq!(foo.c.as_ref().unwrap().a, 3); assert_eq!(foo.c.as_ref().unwrap().a, 3);
assert_eq!(foo.d.a, 4); assert_eq!(foo.d.a, 4);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn parse(j: &JsValue) { pub fn parse(j: &JsValue) {
let s = j.into_serde::<String>().unwrap(); let s = j.into_serde::<String>().unwrap();
assert_eq!(s, "bar"); assert_eq!(s, "bar");
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { run, parse } from "./out"; import { run, parse } from "./out";
import * as assert from "assert"; import * as assert from "assert";
export function verify(a: any) { export function verify(a) {
assert.deepStrictEqual(a, { assert.deepStrictEqual(a, {
a: 0, a: 0,
b: 'foo', b: 'foo',
c: null, c: null,
d: { a: 1 } d: { a: 1 }
}); });
return { return {
a: 2, a: 2,
b: 'bar', b: 'bar',
c: { a: 3 }, c: { a: 3 },
d: { a: 4 }, d: { a: 4 },
}
} }
}
export function test() { export function test() {
run(); run();
parse('bar'); parse('bar');
} }
"#, "#,
) )
.test(); .test();
} }

View File

@ -1,544 +1,6 @@
extern crate wasm_bindgen_cli_support as cli; extern crate wasm_bindgen_test_project_builder as project_builder;
use std::env; use project_builder::{project, run};
use std::fs::{self, File};
use std::io::{self, Read, Write};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::sync::atomic::*;
use std::sync::{Once, ONCE_INIT};
use std::time::Instant;
static CNT: AtomicUsize = ATOMIC_USIZE_INIT;
thread_local!(static IDX: usize = CNT.fetch_add(1, Ordering::SeqCst));
struct Project {
files: Vec<(String, String)>,
debug: bool,
node: bool,
no_std: bool,
serde: bool,
rlib: bool,
node_args: Vec<String>,
deps: Vec<String>,
}
fn project() -> Project {
let dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let mut lockfile = String::new();
fs::File::open(&dir.join("Cargo.lock"))
.unwrap()
.read_to_string(&mut lockfile)
.unwrap();
Project {
debug: true,
node: false,
no_std: false,
serde: false,
rlib: false,
deps: Vec::new(),
node_args: Vec::new(),
files: vec![
("Cargo.lock".to_string(), lockfile),
(
"run-node.js".to_string(),
r#"require("./test").test();"#.to_string(),
),
(
"webpack.config.js".to_string(),
r#"
const path = require('path');
const fs = require('fs');
let nodeModules = {};
// Webpack bundles the modules from node_modules.
// For node target, we will not have `fs` module
// inside the `node_modules` folder.
// This reads the directories in `node_modules`
// and give that to externals and webpack ignores
// to bundle the modules listed as external.
fs.readdirSync('node_modules')
.filter(module => module !== '.bin')
.forEach(mod => {
// External however,expects browser environment.
// To make it work in `node` target we
// prefix commonjs here.
nodeModules[mod] = 'commonjs ' + mod;
});
module.exports = {
entry: './run.js',
mode: "development",
devtool: "source-map",
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: [ '.ts', '.js', '.wasm' ]
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, '.')
},
target: 'node',
externals: nodeModules
};
"#.to_string(),
),
(
"tsconfig.json".to_string(),
r#"
{
"compilerOptions": {
"noEmitOnError": true,
"noImplicitAny": true,
"noImplicitThis": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"noImplicitReturns": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"alwaysStrict": true,
"strict": true,
"target": "es5",
"lib": ["es2015"]
}
}
"#.to_string(),
),
],
}
}
fn root() -> PathBuf {
let idx = IDX.with(|x| *x);
let mut me = env::current_exe().unwrap();
me.pop(); // chop off exe name
me.pop(); // chop off `deps`
me.pop(); // chop off `debug` / `release`
me.push("generated-tests");
me.push(&format!("test{}", idx));
return me;
}
fn assert_bigint_support() -> Option<&'static str> {
static BIGINT_SUPPORED: AtomicUsize = ATOMIC_USIZE_INIT;
static INIT: Once = ONCE_INIT;
INIT.call_once(|| {
let mut cmd = Command::new("node");
cmd.arg("-e").arg("BigInt");
cmd.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped());
if cmd.status().unwrap().success() {
BIGINT_SUPPORED.store(1, Ordering::SeqCst);
return;
}
cmd.arg("--harmony-bigint");
if cmd.status().unwrap().success() {
BIGINT_SUPPORED.store(2, Ordering::SeqCst);
return;
}
});
match BIGINT_SUPPORED.load(Ordering::SeqCst) {
1 => return None,
2 => return Some("--harmony-bigint"),
_ => panic!(
"the version of node.js that is installed for these tests \
does not support `BigInt`, you may wish to try installing \
node 10 to fix this"
),
}
}
impl Project {
fn file(&mut self, name: &str, contents: &str) -> &mut Project {
self.files.push((name.to_string(), contents.to_string()));
self
}
fn debug(&mut self, debug: bool) -> &mut Project {
self.debug = debug;
self
}
fn node(&mut self, node: bool) -> &mut Project {
self.node = node;
self
}
fn no_std(&mut self, no_std: bool) -> &mut Project {
self.no_std = no_std;
self
}
fn serde(&mut self, serde: bool) -> &mut Project {
self.serde = serde;
self
}
fn rlib(&mut self, rlib: bool) -> &mut Project {
self.rlib = rlib;
self
}
fn depend(&mut self, dep: &str) -> &mut Project {
self.deps.push(dep.to_string());
self
}
fn add_local_dependency(&mut self, name: &str, path: &str) -> &mut Project {
self.deps
.push(format!("{} = {{ path = '{}' }}", name, path));
self
}
fn crate_name(&self) -> String {
format!("test{}", IDX.with(|x| *x))
}
fn requires_bigint(&mut self) -> &mut Project {
if let Some(arg) = assert_bigint_support() {
self.node_args.push(arg.to_string());
}
self
}
fn generate_webidl_bindings(&mut self) -> Vec<PathBuf> {
let mut res = Vec::new();
let mut origpaths = Vec::new();
for (path, _) in &self.files {
let path = Path::new(&path);
let extension = path.extension().map(|x| x.to_str().unwrap());
if extension != Some("webidl") {
continue;
}
res.push(path.with_extension("rs"));
origpaths.push(path.to_owned());
}
if res.is_empty() {
return res;
}
let mut buildrs = r#"
extern crate wasm_bindgen_webidl;
use wasm_bindgen_webidl::compile_file;
use std::env;
use std::fs::{self, File};
use std::io::Write;
use std::path::Path;
fn main() {
let dest = env::var("OUT_DIR").unwrap();
"#.to_string();
for (path, origpath) in res.iter().zip(origpaths.iter()) {
buildrs.push_str(&format!(
r#"
fs::create_dir_all("{}").unwrap();
File::create(&Path::new(&dest).join("{}"))
.unwrap()
.write_all(
compile_file(Path::new("{}"))
.unwrap()
.as_bytes()
)
.unwrap();
"#,
path.parent().unwrap().to_str().unwrap(),
path.to_str().unwrap(),
origpath.to_str().unwrap(),
));
self.files.push((
Path::new("src").join(path).to_str().unwrap().to_string(),
format!(
r#"include!(concat!(env!("OUT_DIR"), "/{}"));"#,
path.display()
),
));
}
buildrs.push('}');
self.files.push(("build.rs".to_string(), buildrs));
res
}
fn generate_js_entry(&mut self, modules: Vec<PathBuf>) {
let mut runjs = r#"
import * as process from "process";
"#.to_string();
if !modules.is_empty() {
runjs.push_str(r#"Promise.all(["#);
for module in &modules {
runjs.push_str(&format!(
r#"import('./{}'),"#,
module.with_extension("").to_str().unwrap()
));
}
runjs.push_str(
r#"]).then(results => { results.map(module => Object.assign(global, module));"#,
);
}
runjs.push_str(
r#"
let wasm = import('./out');
const test = import('./test');
"#,
);
if !modules.is_empty() {
runjs.push_str("return ");
}
runjs.push_str(r#"Promise.all([test, wasm])"#);
if !modules.is_empty() {
runjs.push_str("})");
}
runjs.push_str(
r#"
.then(results => {
let [test, wasm] = results;
test.test();
if (wasm.assertStackEmpty)
wasm.assertStackEmpty();
if (wasm.assertSlabEmpty)
wasm.assertSlabEmpty();
})
.catch(error => {
console.error(error);
process.exit(1);
});
"#,
);
self.files.push(("run.js".to_string(), runjs));
}
fn ensure_test_entry(&mut self) {
if !self
.files
.iter()
.any(|(path, _)| path == "test.ts" || path == "test.js")
{
self.files.push((
"test.ts".to_string(),
r#"export {test} from './out';"#.to_string(),
));
}
}
/// build + cargo cmd execution
fn cargo_build(&mut self) -> (PathBuf, PathBuf) {
let (root, target_dir) = self.build();
let mut cmd = Command::new("cargo");
cmd.arg("build")
.arg("--target")
.arg("wasm32-unknown-unknown")
.current_dir(&root)
.env("CARGO_TARGET_DIR", &target_dir)
// Catch any warnings in generated code because we don't want any
.env("RUSTFLAGS", "-Dwarnings");
run(&mut cmd, "cargo");
(root, target_dir)
}
fn build(&mut self) -> (PathBuf, PathBuf) {
self.ensure_test_entry();
let webidl_modules = self.generate_webidl_bindings();
self.generate_js_entry(webidl_modules);
let mut manifest = format!(
r#"
[package]
name = "test{}"
version = "0.0.1"
authors = []
[workspace]
[lib]
"#,
IDX.with(|x| *x)
);
if !self.rlib {
manifest.push_str("crate-type = [\"cdylib\"]\n");
}
manifest.push_str("[build-dependencies]\n");
manifest.push_str("wasm-bindgen-webidl = { path = '");
manifest.push_str(env!("CARGO_MANIFEST_DIR"));
manifest.push_str("/crates/webidl' }\n");
manifest.push_str("[dependencies]\n");
for dep in self.deps.iter() {
manifest.push_str(dep);
manifest.push_str("\n");
}
manifest.push_str("wasm-bindgen = { path = '");
manifest.push_str(env!("CARGO_MANIFEST_DIR"));
manifest.push_str("'");
if self.no_std {
manifest.push_str(", default-features = false");
}
if self.serde {
manifest.push_str(", features = ['serde-serialize']");
}
manifest.push_str(" }\n");
self.files.push(("Cargo.toml".to_string(), manifest));
let root = root();
drop(fs::remove_dir_all(&root));
for &(ref file, ref contents) in self.files.iter() {
let dst = root.join(file);
fs::create_dir_all(dst.parent().unwrap()).unwrap();
fs::File::create(&dst)
.unwrap()
.write_all(contents.as_ref())
.unwrap();
}
let target_dir = root.parent().unwrap() // chop off test name
.parent().unwrap(); // chop off `generated-tests`
(root.clone(), target_dir.to_path_buf())
}
fn test(&mut self) {
let (root, target_dir) = self.cargo_build();
self.gen_bindings(&root, &target_dir);
let mut wasm = Vec::new();
File::open(root.join("out_bg.wasm"))
.unwrap()
.read_to_end(&mut wasm)
.unwrap();
let obj = cli::wasm2es6js::Config::new()
.base64(true)
.generate(&wasm)
.expect("failed to convert wasm to js");
File::create(root.join("out_bg.d.ts"))
.unwrap()
.write_all(obj.typescript().as_bytes())
.unwrap();
// move files from the root into each test, it looks like this may be
// needed for webpack to work well when invoked concurrently.
fs::hard_link("package.json", root.join("package.json")).unwrap();
if !Path::new("node_modules").exists() {
panic!("\n\nfailed to find `node_modules`, have you run `npm install` yet?\n\n");
}
let cwd = env::current_dir().unwrap();
symlink_dir(&cwd.join("node_modules"), &root.join("node_modules")).unwrap();
if self.node {
let mut cmd = Command::new("node");
cmd.args(&self.node_args);
cmd.arg(root.join("run-node.js")).current_dir(&root);
run(&mut cmd, "node");
} else {
let mut cmd = if cfg!(windows) {
let mut c = Command::new("cmd");
c.arg("/c");
c.arg("npm");
c
} else {
Command::new("npm")
};
cmd.arg("run").arg("run-webpack").current_dir(&root);
run(&mut cmd, "npm");
let mut cmd = Command::new("node");
cmd.args(&self.node_args);
cmd.arg(root.join("bundle.js")).current_dir(&root);
run(&mut cmd, "node");
}
}
/// execute the cli against the current test .wasm
fn gen_bindings(&self, root: &PathBuf, target_dir: &PathBuf) {
let idx = IDX.with(|x| *x);
let out = target_dir.join(&format!("wasm32-unknown-unknown/debug/test{}.wasm", idx));
let as_a_module = root.join("out.wasm");
fs::copy(&out, &as_a_module).unwrap();
let res = cli::Bindgen::new()
.input_path(&as_a_module)
.typescript(true)
.nodejs(self.node)
.debug(self.debug)
.generate(&root);
if let Err(e) = res {
for e in e.causes() {
println!("- {}", e);
}
panic!("failed");
}
}
fn read_js(&self) -> String {
let path = root().join("out.js");
println!("js, {:?}", &path);
fs::read_to_string(path).expect("Unable to read js")
}
}
#[cfg(unix)]
fn symlink_dir(a: &Path, b: &Path) -> io::Result<()> {
use std::os::unix::fs::symlink;
symlink(a, b)
}
#[cfg(windows)]
fn symlink_dir(a: &Path, b: &Path) -> io::Result<()> {
use std::os::windows::fs::symlink_dir;
symlink_dir(a, b)
}
fn run(cmd: &mut Command, program: &str) {
println!("···················································");
println!("running {:?}", cmd);
let start = Instant::now();
let output = match cmd.output() {
Ok(output) => output,
Err(err) => panic!("failed to spawn `{}`: {}", program, err),
};
println!("exit: {}", output.status);
let dur = start.elapsed();
println!(
"dur: {}.{:03}ms",
dur.as_secs(),
dur.subsec_nanos() / 1_000_000
);
if output.stdout.len() > 0 {
println!("stdout ---\n{}", String::from_utf8_lossy(&output.stdout));
}
if output.stderr.len() > 0 {
println!("stderr ---\n{}", String::from_utf8_lossy(&output.stderr));
}
assert!(output.status.success());
}
mod api; mod api;
mod char; mod char;
@ -559,6 +21,7 @@ mod non_wasm;
mod simple; mod simple;
mod slice; mod slice;
mod structural; mod structural;
mod typescript;
mod u64; mod u64;
mod validate_prt; mod validate_prt;
mod webidl; mod webidl;

View File

@ -6,77 +6,77 @@ fn auto_bind_math() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub fn math(a: f32, b: f64) -> f64 { pub fn math(a: f32, b: f64) -> f64 {
b.acos() + b.acos() +
b.asin() + b.asin() +
b.atan() + b.atan() +
b.atan2(b) + b.atan2(b) +
b.cbrt() + b.cbrt() +
b.cosh() + b.cosh() +
b.exp_m1() + b.exp_m1() +
b.ln_1p() + b.ln_1p() +
b.sinh() + b.sinh() +
b.tan() + b.tan() +
b.tanh() + b.tanh() +
b.hypot(b) + b.hypot(b) +
b.cos() + b.cos() +
b.exp() + b.exp() +
b.exp2() + b.exp2() +
b.mul_add(b, b) + b.mul_add(b, b) +
b.ln() + b.ln() +
b.log(b) + b.log(b) +
b.log10() + b.log10() +
b.log2() + b.log2() +
b.powi(8) + b.powi(8) +
b.powf(b) + b.powf(b) +
b.round() + b.round() +
b.sin() + b.sin() +
b.abs() + b.abs() +
b.signum() + b.signum() +
b.floor() + b.floor() +
b.ceil() + b.ceil() +
b.trunc() + b.trunc() +
b.sqrt() + b.sqrt() +
(b % (a as f64)) + (b % (a as f64)) +
((a.cos() + ((a.cos() +
a.exp() + a.exp() +
a.exp2() + a.exp2() +
a.mul_add(a, a) + a.mul_add(a, a) +
a.ln() + a.ln() +
a.log(a) + a.log(a) +
a.log10() + a.log10() +
a.log2() + a.log2() +
a.powi(8) + a.powi(8) +
a.powf(a) + a.powf(a) +
a.round() + a.round() +
a.sin() + a.sin() +
a.abs() + a.abs() +
a.signum() + a.signum() +
a.floor() + a.floor() +
a.ceil() + a.ceil() +
a.trunc() + a.trunc() +
a.sqrt() + a.sqrt() +
(a % (b as f32))) as f64) + (a % (b as f32))) as f64) +
(b + 2.0f64.powf(a as f64)) (b + 2.0f64.powf(a as f64))
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import { math } from "./out"; import { math } from "./out";
export function test() { export function test() {
math(1.0, 2.0); math(1.0, 2.0);
} }
"#, "#,
) )
.test(); .test();
} }

View File

@ -3,158 +3,159 @@ use super::project;
#[test] #[test]
fn works() { fn works() {
project() project()
.node(true) .debug(false)
.nodejs_experimental_modules(false)
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
static FOO: JsValue; static FOO: JsValue;
fn hit(); fn hit();
}
#[wasm_bindgen]
pub fn run() {
hit();
assert_eq!(FOO.as_f64(), Some(1.0));
}
#[wasm_bindgen]
pub struct Foo {
contents: u32,
}
#[wasm_bindgen]
impl Foo {
pub fn new() -> Foo {
Foo::with_contents(0)
} }
pub fn with_contents(a: u32) -> Foo {
Foo { contents: a }
}
pub fn add(&mut self, amt: u32) -> u32 {
self.contents += amt;
self.contents
}
}
#[wasm_bindgen] #[wasm_bindgen]
pub enum Color { pub fn run() {
Green, hit();
Yellow, assert_eq!(FOO.as_f64(), Some(1.0));
Red,
}
#[wasm_bindgen]
pub fn cycle(color: Color) -> Color {
match color {
Color::Green => Color::Yellow,
Color::Yellow => Color::Red,
Color::Red => Color::Green,
} }
}
#[wasm_bindgen] #[wasm_bindgen]
pub fn math(a: f32, b: f64) -> f64 { pub struct Foo {
b.acos() + contents: u32,
b.asin() + }
b.atan() +
b.atan2(b) + #[wasm_bindgen]
b.cbrt() + impl Foo {
b.cosh() + pub fn new() -> Foo {
b.exp_m1() + Foo::with_contents(0)
b.ln_1p() + }
b.sinh() + pub fn with_contents(a: u32) -> Foo {
b.tan() + Foo { contents: a }
b.tanh() + }
b.hypot(b) + pub fn add(&mut self, amt: u32) -> u32 {
b.cos() + self.contents += amt;
b.exp() + self.contents
b.exp2() + }
b.mul_add(b, b) + }
b.ln() +
b.log(b) + #[wasm_bindgen]
b.log10() + pub enum Color {
b.log2() + Green,
b.powi(8) + Yellow,
b.powf(b) + Red,
b.round() + }
b.sin() + #[wasm_bindgen]
b.abs() + pub fn cycle(color: Color) -> Color {
b.signum() + match color {
b.floor() + Color::Green => Color::Yellow,
b.ceil() + Color::Yellow => Color::Red,
b.trunc() + Color::Red => Color::Green,
b.sqrt() + }
(b % (a as f64)) + }
((a.cos() +
a.exp() + #[wasm_bindgen]
a.exp2() + pub fn math(a: f32, b: f64) -> f64 {
a.mul_add(a, a) + b.acos() +
a.ln() + b.asin() +
a.log(a) + b.atan() +
a.log10() + b.atan2(b) +
a.log2() + b.cbrt() +
a.powi(8) + b.cosh() +
a.powf(a) + b.exp_m1() +
a.round() + b.ln_1p() +
a.sin() + b.sinh() +
a.abs() + b.tan() +
a.signum() + b.tanh() +
a.floor() + b.hypot(b) +
a.ceil() + b.cos() +
a.trunc() + b.exp() +
a.sqrt() + b.exp2() +
(a % (b as f32))) as f64) + b.mul_add(b, b) +
(b + 2.0f64.powf(a as f64)) b.ln() +
} b.log(b) +
"#, b.log10() +
b.log2() +
b.powi(8) +
b.powf(b) +
b.round() +
b.sin() +
b.abs() +
b.signum() +
b.floor() +
b.ceil() +
b.trunc() +
b.sqrt() +
(b % (a as f64)) +
((a.cos() +
a.exp() +
a.exp2() +
a.mul_add(a, a) +
a.ln() +
a.log(a) +
a.log10() +
a.log2() +
a.powi(8) +
a.powf(a) +
a.round() +
a.sin() +
a.abs() +
a.signum() +
a.floor() +
a.ceil() +
a.trunc() +
a.sqrt() +
(a % (b as f32))) as f64) +
(b + 2.0f64.powf(a as f64))
}
"#,
) )
.file( .file(
"test.js", "test.js",
r#" r#"
const assert = require('assert'); const assert = require('assert');
var called = false; var called = false;
module.exports.hit = function() { module.exports.hit = function() {
called = true; called = true;
}; };
module.exports.FOO = 1.0;
const { math, run, Foo, Color, cycle } = require('./out'); module.exports.FOO = 1.0;
module.exports.test = function() { const { math, run, Foo, Color, cycle } = require('./out');
run();
assert.strictEqual(called, true);
var r = Foo.new(); module.exports.test = function() {
assert.strictEqual(r.add(0), 0); run();
assert.strictEqual(r.add(1), 1); assert.strictEqual(called, true);
assert.strictEqual(r.add(2), 3);
r.free();
var r2 = Foo.with_contents(10); var r = Foo.new();
assert.strictEqual(r2.add(0), 10); assert.strictEqual(r.add(0), 0);
assert.strictEqual(r2.add(1), 11); assert.strictEqual(r.add(1), 1);
assert.strictEqual(r2.add(2), 13); assert.strictEqual(r.add(2), 3);
r2.free(); r.free();
assert.strictEqual(Color.Green, 0); var r2 = Foo.with_contents(10);
assert.strictEqual(Color.Yellow, 1); assert.strictEqual(r2.add(0), 10);
assert.strictEqual(Color.Red, 2); assert.strictEqual(r2.add(1), 11);
assert.strictEqual(Object.keys(Color).length, 3); assert.strictEqual(r2.add(2), 13);
assert.strictEqual(cycle(Color.Green), Color.Yellow); r2.free();
math(1.0, 2.0); assert.strictEqual(Color.Green, 0);
}; assert.strictEqual(Color.Yellow, 1);
assert.strictEqual(Color.Red, 2);
assert.strictEqual(Object.keys(Color).length, 3);
assert.strictEqual(cycle(Color.Green), Color.Yellow);
"#, math(1.0, 2.0);
};
"#,
) )
.test(); .test();
} }

View File

@ -7,42 +7,42 @@ fn works() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub struct A {} pub struct A {}
#[wasm_bindgen] #[wasm_bindgen]
impl A { impl A {
pub fn new() -> A { pub fn new() -> A {
A {} A {}
}
} }
}
#[wasm_bindgen] #[wasm_bindgen]
pub fn clone(a: &JsValue) -> JsValue { pub fn clone(a: &JsValue) -> JsValue {
drop(a.clone()); drop(a.clone());
a.clone() a.clone()
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
let sym = (Symbol as any)('a'); let sym = Symbol('a');
assert.strictEqual(wasm.clone(sym), sym); assert.strictEqual(wasm.clone(sym), sym);
let a = wasm.A.new(); let a = wasm.A.new();
a.free(); a.free();
} }
"#, "#,
) )
.test(); .test();
} }

View File

@ -6,55 +6,88 @@ fn add() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub fn add(a: u32, b: u32) -> u32 { pub fn add(a: u32, b: u32) -> u32 {
a + b a + b
}
#[wasm_bindgen]
pub fn add3(a: u32) -> u32 {
a + 3
}
#[wasm_bindgen]
pub fn get2(_b: bool) -> u32 {
2
}
#[wasm_bindgen]
pub fn return_and_take_bool(a: bool, b: bool) -> bool {
a && b
}
#[wasm_bindgen]
pub fn raw_pointers_work(a: *mut u32, b: *const u8) -> *const u32 {
unsafe {
(*a) = (*b) as u32;
return a
} }
}
"#, #[wasm_bindgen]
pub fn add3(a: u32) -> u32 {
a + 3
}
#[wasm_bindgen]
pub fn get2(_b: bool) -> u32 {
2
}
#[wasm_bindgen]
pub fn return_and_take_bool(a: bool, b: bool) -> bool {
a && b
}
#[wasm_bindgen]
pub fn raw_pointers_work(a: *mut u32, b: *const u8) -> *const u32 {
unsafe {
(*a) = (*b) as u32;
return a
}
}
"#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
assert.strictEqual(wasm.add(1, 2), 3); assert.strictEqual(wasm.add(1, 2), 3);
assert.strictEqual(wasm.add(2, 3), 5); assert.strictEqual(wasm.add(2, 3), 5);
assert.strictEqual(wasm.add3(2), 5); assert.strictEqual(wasm.add3(2), 5);
assert.strictEqual(wasm.get2(true), 2); assert.strictEqual(wasm.get2(true), 2);
assert.strictEqual(wasm.return_and_take_bool(true, false), false); assert.strictEqual(wasm.return_and_take_bool(true, false), false);
} }
"#, "#,
)
.test();
}
#[test]
fn add_headless() {
project()
.headless(true)
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn add(a: u32, b: u32) -> u32 {
a + b
}
"#,
)
.file(
"test.js",
r#"
import * as assert from "assert";
import * as wasm from "./out";
export function test() {
console.log("start `add_headless` test");
assert.strictEqual(wasm.add(1, 2), 3);
console.log("end `add_headless` test");
}
"#,
) )
.test(); .test();
} }
@ -65,34 +98,34 @@ fn string_arguments() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub fn assert_foo_and_bar(a: &str, b: &str) { pub fn assert_foo_and_bar(a: &str, b: &str) {
assert_eq!(a, "foo2"); assert_eq!(a, "foo2");
assert_eq!(b, "bar"); assert_eq!(b, "bar");
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn assert_foo(a: &str) { pub fn assert_foo(a: &str) {
assert_eq!(a, "foo"); assert_eq!(a, "foo");
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
wasm.assert_foo("foo"); wasm.assert_foo("foo");
wasm.assert_foo_and_bar("foo2", "bar"); wasm.assert_foo_and_bar("foo2", "bar");
} }
"#, "#,
) )
.test(); .test();
} }
@ -103,36 +136,36 @@ fn return_a_string() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub fn clone(a: &str) -> String { pub fn clone(a: &str) -> String {
a.to_string() a.to_string()
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn concat(a: &str, b: &str, c: i8) -> String { pub fn concat(a: &str, b: &str, c: i8) -> String {
format!("{} {} {}", a, b, c) format!("{} {} {}", a, b, c)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
assert.strictEqual(wasm.clone("foo"), "foo"); assert.strictEqual(wasm.clone("foo"), "foo");
assert.strictEqual(wasm.clone("another"), "another"); assert.strictEqual(wasm.clone("another"), "another");
assert.strictEqual(wasm.concat("a", "b", 3), "a b 3"); assert.strictEqual(wasm.concat("a", "b", 3), "a b 3");
assert.strictEqual(wasm.concat("c", "d", -2), "c d -2"); assert.strictEqual(wasm.concat("c", "d", -2), "c d -2");
} }
"#, "#,
) )
.test(); .test();
} }
@ -143,36 +176,30 @@ fn exceptions() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub fn foo(_a: u32) {} pub fn foo(_a: u32) {}
#[wasm_bindgen] #[wasm_bindgen]
pub fn bar(_a: &str) {} pub fn bar(_a: &str) {}
"#, "#,
) )
.file( .file(
"test.js", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
assert.throws(() => wasm.foo('a'), /expected a number argument/); assert.throws(() => wasm.foo('a'), /expected a number argument/);
assert.throws(() => wasm.bar(3), /expected a string argument/); assert.throws(() => wasm.bar(3), /expected a string argument/);
} }
"#, "#,
)
.file(
"test.d.ts",
r#"
export function test(): void;
"#,
) )
.test(); .test();
} }
@ -197,7 +224,7 @@ fn exceptions() {
// } // }
// } // }
// "#) // "#)
// .file("test.ts", r#" // .file("test.js", r#"
// import * as assert from "assert"; // import * as assert from "assert";
// import * as wasm from "./out"; // import * as wasm from "./out";
// //
@ -217,20 +244,20 @@ fn other_exports() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#[no_mangle] #[no_mangle]
pub extern fn foo(_a: u32) { pub extern fn foo(_a: u32) {
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out_bg"; import * as wasm from "./out_bg";
export function test() { export function test() {
wasm.foo(2); wasm.foo(2);
} }
"#, "#,
) )
.test(); .test();
} }
@ -242,49 +269,49 @@ fn no_std() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
#![no_std] #![no_std]
#![allow(dead_code)] #![allow(dead_code)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
extern crate std as _some_other_name; extern crate std as _some_other_name;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./foo")] #[wasm_bindgen(module = "./foo")]
extern { extern {
fn test(a: &str); fn test(a: &str);
type Js; type Js;
#[wasm_bindgen(constructor)] #[wasm_bindgen(constructor)]
fn new() -> Js; fn new() -> Js;
#[wasm_bindgen(method)] #[wasm_bindgen(method)]
fn init(this: &Js); fn init(this: &Js);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn foo(_a: u32) {} pub fn foo(_a: u32) {}
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out_bg"; import * as wasm from "./out_bg";
export function test() { export function test() {
// mostly just testing the project compiles here // mostly just testing the project compiles here
wasm.foo(1); wasm.foo(1);
} }
"#, "#,
) )
.file( .file(
"foo.js", "foo.js",
r#" r#"
export class Js { export class Js {
init() { init() {
}
} }
} "#,
"#,
) )
.test(); .test();
} }
@ -295,49 +322,49 @@ fn no_std_class() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
#![no_std] #![no_std]
#![allow(dead_code)] #![allow(dead_code)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
extern crate std as _some_other_name; extern crate std as _some_other_name;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
extern { extern {
fn test(a: &str); fn test(a: &str);
type Js; type Js;
#[wasm_bindgen(constructor)] #[wasm_bindgen(constructor)]
fn new() -> Js; fn new() -> Js;
#[wasm_bindgen(method, structural)] #[wasm_bindgen(method, structural)]
fn init(this: &Js); fn init(this: &Js);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn foo(_a: u32) {} pub fn foo(_a: u32) {}
#[wasm_bindgen] #[wasm_bindgen]
pub struct A {} pub struct A {}
#[wasm_bindgen] #[wasm_bindgen]
impl A { impl A {
pub fn foo(&self) {} pub fn foo(&self) {}
pub fn bar(&mut self) {} pub fn bar(&mut self) {}
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as wasm from "./out_bg"; import * as wasm from "./out_bg";
export function test() { export function test() {
// mostly just testing the project compiles here // mostly just testing the project compiles here
wasm.foo(1); wasm.foo(1);
} }
"#, "#,
) )
.test(); .test();
} }

View File

@ -6,82 +6,82 @@ fn export() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
macro_rules! doit { macro_rules! doit {
($($i:ident)*) => ($( ($($i:ident)*) => ($(
#[wasm_bindgen] #[wasm_bindgen]
pub fn $i(a: &[$i]) -> Vec<$i> { pub fn $i(a: &[$i]) -> Vec<$i> {
assert_eq!(a.len(), 2); assert_eq!(a.len(), 2);
assert_eq!(a[0], 1 as $i); assert_eq!(a[0], 1 as $i);
assert_eq!(a[1], 2 as $i); assert_eq!(a[1], 2 as $i);
a.to_vec() a.to_vec()
} }
)*) )*)
} }
doit! { i8 u8 i16 u16 i32 u32 f32 f64 } doit! { i8 u8 i16 u16 i32 u32 f32 f64 }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
function assert_arrays_equal(a: any, b: any) { function assert_arrays_equal(a, b) {
console.log(a, b); console.log(a, b);
assert.strictEqual(a.length, b.length); assert.strictEqual(a.length, b.length);
assert.strictEqual(a.byteLength, b.byteLength); assert.strictEqual(a.byteLength, b.byteLength);
for (let i = 0; i < a.length; i++) { for (let i = 0; i < a.length; i++) {
assert.strictEqual(a[i], b[i]); assert.strictEqual(a[i], b[i]);
}
} }
}
export function test() { export function test() {
const i8 = new Int8Array(2); const i8 = new Int8Array(2);
i8[0] = 1; i8[0] = 1;
i8[1] = 2; i8[1] = 2;
assert_arrays_equal(wasm.i8(i8), i8); assert_arrays_equal(wasm.i8(i8), i8);
const u8 = new Uint8Array(2); const u8 = new Uint8Array(2);
u8[0] = 1; u8[0] = 1;
u8[1] = 2; u8[1] = 2;
assert_arrays_equal(wasm.u8(u8), u8); assert_arrays_equal(wasm.u8(u8), u8);
const i16 = new Int16Array(2); const i16 = new Int16Array(2);
i16[0] = 1; i16[0] = 1;
i16[1] = 2; i16[1] = 2;
assert_arrays_equal(wasm.i16(i16), i16); assert_arrays_equal(wasm.i16(i16), i16);
const u16 = new Uint16Array(2); const u16 = new Uint16Array(2);
u16[0] = 1; u16[0] = 1;
u16[1] = 2; u16[1] = 2;
assert_arrays_equal(wasm.u16(u16), u16); assert_arrays_equal(wasm.u16(u16), u16);
const i32 = new Int32Array(2); const i32 = new Int32Array(2);
i32[0] = 1; i32[0] = 1;
i32[1] = 2; i32[1] = 2;
wasm.i32(i32); wasm.i32(i32);
assert_arrays_equal(wasm.i32(i32), i32); assert_arrays_equal(wasm.i32(i32), i32);
const u32 = new Uint32Array(2); const u32 = new Uint32Array(2);
u32[0] = 1; u32[0] = 1;
u32[1] = 2; u32[1] = 2;
assert_arrays_equal(wasm.u32(u32), u32); assert_arrays_equal(wasm.u32(u32), u32);
const f32 = new Float32Array(2); const f32 = new Float32Array(2);
f32[0] = 1; f32[0] = 1;
f32[1] = 2; f32[1] = 2;
assert_arrays_equal(wasm.f32(f32), f32); assert_arrays_equal(wasm.f32(f32), f32);
const f64 = new Float64Array(2); const f64 = new Float64Array(2);
f64[0] = 1; f64[0] = 1;
f64[1] = 2; f64[1] = 2;
assert_arrays_equal(wasm.f64(f64), f64); assert_arrays_equal(wasm.f64(f64), f64);
} }
"#, "#,
) )
.test(); .test();
} }
@ -92,151 +92,151 @@ fn import() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
macro_rules! doit { macro_rules! doit {
($(($rust:ident, $js:ident, $i:ident))*) => ($( ($(($rust:ident, $js:ident, $i:ident))*) => ($(
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn $js(a: &[$i]) -> Vec<$i>; fn $js(a: &[$i]) -> Vec<$i>;
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn $rust(a: &[$i]) -> Vec<$i> { pub fn $rust(a: &[$i]) -> Vec<$i> {
assert_eq!(a.len(), 2); assert_eq!(a.len(), 2);
assert_eq!(a[0], 1 as $i); assert_eq!(a[0], 1 as $i);
assert_eq!(a[1], 2 as $i); assert_eq!(a[1], 2 as $i);
$js(a) $js(a)
} }
)*) )*)
} }
doit! { doit! {
(rust_i8, js_i8, i8) (rust_i8, js_i8, i8)
(rust_u8, js_u8, u8) (rust_u8, js_u8, u8)
(rust_i16, js_i16, i16) (rust_i16, js_i16, i16)
(rust_u16, js_u16, u16) (rust_u16, js_u16, u16)
(rust_i32, js_i32, i32) (rust_i32, js_i32, i32)
(rust_u32, js_u32, u32) (rust_u32, js_u32, u32)
(rust_f32, js_f32, f32) (rust_f32, js_f32, f32)
(rust_f64, js_f64, f64) (rust_f64, js_f64, f64)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function js_i8(a: any): any { export function js_i8(a) {
assert.strictEqual(a.length, 2); assert.strictEqual(a.length, 2);
assert.strictEqual(a[0], 1); assert.strictEqual(a[0], 1);
assert.strictEqual(a[1], 2); assert.strictEqual(a[1], 2);
return a; return a;
}
export function js_u8(a: any): any {
assert.strictEqual(a.length, 2);
assert.strictEqual(a[0], 1);
assert.strictEqual(a[1], 2);
return a;
}
export function js_i16(a: any): any {
assert.strictEqual(a.length, 2);
assert.strictEqual(a[0], 1);
assert.strictEqual(a[1], 2);
return a;
}
export function js_u16(a: any): any {
assert.strictEqual(a.length, 2);
assert.strictEqual(a[0], 1);
assert.strictEqual(a[1], 2);
return a;
}
export function js_i32(a: any): any {
assert.strictEqual(a.length, 2);
assert.strictEqual(a[0], 1);
assert.strictEqual(a[1], 2);
return a;
}
export function js_u32(a: any): any {
assert.strictEqual(a.length, 2);
assert.strictEqual(a[0], 1);
assert.strictEqual(a[1], 2);
return a;
}
export function js_f32(a: any): any {
assert.strictEqual(a.length, 2);
assert.strictEqual(a[0], 1);
assert.strictEqual(a[1], 2);
return a;
}
export function js_f64(a: any): any {
assert.strictEqual(a.length, 2);
assert.strictEqual(a[0], 1);
assert.strictEqual(a[1], 2);
return a;
}
function assert_arrays_equal(a: any, b: any) {
console.log(a, b);
assert.strictEqual(a.length, b.length);
assert.strictEqual(a.byteLength, b.byteLength);
for (let i = 0; i < a.length; i++) {
assert.strictEqual(a[i], b[i]);
} }
}
export function test() { export function js_u8(a) {
const i8 = new Int8Array(2); assert.strictEqual(a.length, 2);
i8[0] = 1; assert.strictEqual(a[0], 1);
i8[1] = 2; assert.strictEqual(a[1], 2);
assert_arrays_equal(wasm.rust_i8(i8), i8); return a;
const u8 = new Uint8Array(2); }
u8[0] = 1;
u8[1] = 2;
assert_arrays_equal(wasm.rust_u8(u8), u8);
const i16 = new Int16Array(2); export function js_i16(a) {
i16[0] = 1; assert.strictEqual(a.length, 2);
i16[1] = 2; assert.strictEqual(a[0], 1);
assert_arrays_equal(wasm.rust_i16(i16), i16); assert.strictEqual(a[1], 2);
const u16 = new Uint16Array(2); return a;
u16[0] = 1; }
u16[1] = 2;
assert_arrays_equal(wasm.rust_u16(u16), u16);
const i32 = new Int32Array(2); export function js_u16(a) {
i32[0] = 1; assert.strictEqual(a.length, 2);
i32[1] = 2; assert.strictEqual(a[0], 1);
assert_arrays_equal(wasm.rust_i32(i32), i32); assert.strictEqual(a[1], 2);
const u32 = new Uint32Array(2); return a;
u32[0] = 1; }
u32[1] = 2;
assert_arrays_equal(wasm.rust_u32(u32), u32);
const f32 = new Float32Array(2); export function js_i32(a) {
f32[0] = 1; assert.strictEqual(a.length, 2);
f32[1] = 2; assert.strictEqual(a[0], 1);
assert_arrays_equal(wasm.rust_f32(f32), f32); assert.strictEqual(a[1], 2);
const f64 = new Float64Array(2); return a;
f64[0] = 1; }
f64[1] = 2;
assert_arrays_equal(wasm.rust_f64(f64), f64); export function js_u32(a) {
} assert.strictEqual(a.length, 2);
"#, assert.strictEqual(a[0], 1);
assert.strictEqual(a[1], 2);
return a;
}
export function js_f32(a) {
assert.strictEqual(a.length, 2);
assert.strictEqual(a[0], 1);
assert.strictEqual(a[1], 2);
return a;
}
export function js_f64(a) {
assert.strictEqual(a.length, 2);
assert.strictEqual(a[0], 1);
assert.strictEqual(a[1], 2);
return a;
}
function assert_arrays_equal(a, b) {
console.log(a, b);
assert.strictEqual(a.length, b.length);
assert.strictEqual(a.byteLength, b.byteLength);
for (let i = 0; i < a.length; i++) {
assert.strictEqual(a[i], b[i]);
}
}
export function test() {
const i8 = new Int8Array(2);
i8[0] = 1;
i8[1] = 2;
assert_arrays_equal(wasm.rust_i8(i8), i8);
const u8 = new Uint8Array(2);
u8[0] = 1;
u8[1] = 2;
assert_arrays_equal(wasm.rust_u8(u8), u8);
const i16 = new Int16Array(2);
i16[0] = 1;
i16[1] = 2;
assert_arrays_equal(wasm.rust_i16(i16), i16);
const u16 = new Uint16Array(2);
u16[0] = 1;
u16[1] = 2;
assert_arrays_equal(wasm.rust_u16(u16), u16);
const i32 = new Int32Array(2);
i32[0] = 1;
i32[1] = 2;
assert_arrays_equal(wasm.rust_i32(i32), i32);
const u32 = new Uint32Array(2);
u32[0] = 1;
u32[1] = 2;
assert_arrays_equal(wasm.rust_u32(u32), u32);
const f32 = new Float32Array(2);
f32[0] = 1;
f32[1] = 2;
assert_arrays_equal(wasm.rust_f32(f32), f32);
const f64 = new Float64Array(2);
f64[0] = 1;
f64[1] = 2;
assert_arrays_equal(wasm.rust_f64(f64), f64);
}
"#,
) )
.test(); .test();
} }
@ -247,52 +247,52 @@ fn pass_array_works() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
macro_rules! doit { macro_rules! doit {
($(($rust:ident, $i:ident))*) => ($( ($(($rust:ident, $i:ident))*) => ($(
#[wasm_bindgen] #[wasm_bindgen]
pub fn $rust(a: &[$i]) { pub fn $rust(a: &[$i]) {
assert_eq!(a.len(), 2); assert_eq!(a.len(), 2);
assert_eq!(a[0], 1 as $i); assert_eq!(a[0], 1 as $i);
assert_eq!(a[1], 2 as $i); assert_eq!(a[1], 2 as $i);
} }
)*) )*)
} }
doit! { doit! {
(rust_i8, i8) (rust_i8, i8)
(rust_u8, u8) (rust_u8, u8)
(rust_i16, i16) (rust_i16, i16)
(rust_u16, u16) (rust_u16, u16)
(rust_i32, i32) (rust_i32, i32)
(rust_u32, u32) (rust_u32, u32)
(rust_f32, f32) (rust_f32, f32)
(rust_f64, f64) (rust_f64, f64)
} }
"#, "#,
) )
.file( .file(
"test.js", "test.js",
r#" r#"
const wasm = require("./out"); import * as wasm from "./out";
module.exports.test = function() { export function test() {
wasm.rust_i8([1, 2]); wasm.rust_i8([1, 2]);
wasm.rust_u8([1, 2]); wasm.rust_u8([1, 2]);
wasm.rust_i16([1, 2]); wasm.rust_i16([1, 2]);
wasm.rust_u16([1, 2]); wasm.rust_u16([1, 2]);
wasm.rust_i32([1, 2]); wasm.rust_i32([1, 2]);
wasm.rust_u32([1, 2]); wasm.rust_u32([1, 2]);
wasm.rust_f32([1, 2]); wasm.rust_f32([1, 2]);
wasm.rust_f64([1, 2]); wasm.rust_f64([1, 2]);
}; }
"#, "#,
) )
.test(); .test();
} }
@ -303,80 +303,80 @@ fn import_mut() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
macro_rules! doit { macro_rules! doit {
($(($rust:ident, $js:ident, $i:ident))*) => ( ($(($rust:ident, $js:ident, $i:ident))*) => (
$( $(
#[wasm_bindgen(module = "./test")] #[wasm_bindgen(module = "./test")]
extern { extern {
fn $js(a: &mut [$i]); fn $js(a: &mut [$i]);
}
fn $rust() {
let mut buf = [
1 as $i,
2 as $i,
3 as $i,
];
$js(&mut buf);
assert_eq!(buf[0], 4 as $i);
assert_eq!(buf[1], 5 as $i);
assert_eq!(buf[2], 3 as $i);
}
)*
#[wasm_bindgen]
pub fn run() {
$($rust();)*
} }
)
fn $rust() { }
let mut buf = [
1 as $i,
2 as $i,
3 as $i,
];
$js(&mut buf);
assert_eq!(buf[0], 4 as $i);
assert_eq!(buf[1], 5 as $i);
assert_eq!(buf[2], 3 as $i);
}
)*
#[wasm_bindgen]
pub fn run() {
$($rust();)*
}
)
}
doit! { doit! {
(rust_i8, js_i8, i8) (rust_i8, js_i8, i8)
(rust_u8, js_u8, u8) (rust_u8, js_u8, u8)
(rust_i16, js_i16, i16) (rust_i16, js_i16, i16)
(rust_u16, js_u16, u16) (rust_u16, js_u16, u16)
(rust_i32, js_i32, i32) (rust_i32, js_i32, i32)
(rust_u32, js_u32, u32) (rust_u32, js_u32, u32)
(rust_f32, js_f32, f32) (rust_f32, js_f32, f32)
(rust_f64, js_f64, f64) (rust_f64, js_f64, f64)
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
function foo(a: any) { function foo(a) {
assert.strictEqual(a.length, 3); assert.strictEqual(a.length, 3);
assert.strictEqual(a[0], 1); assert.strictEqual(a[0], 1);
assert.strictEqual(a[1], 2); assert.strictEqual(a[1], 2);
a[0] = 4; a[0] = 4;
a[1] = 5; a[1] = 5;
} }
export const js_i8 = foo; export const js_i8 = foo;
export const js_u8 = foo; export const js_u8 = foo;
export const js_i16 = foo; export const js_i16 = foo;
export const js_u16 = foo; export const js_u16 = foo;
export const js_i32 = foo; export const js_i32 = foo;
export const js_u32 = foo; export const js_u32 = foo;
export const js_f32 = foo; export const js_f32 = foo;
export const js_f64 = foo; export const js_f64 = foo;
export function test() { export function test() {
wasm.run(); wasm.run();
} }
"#, "#,
) )
.test(); .test();
} }
@ -387,61 +387,61 @@ fn export_mut() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section)] #![feature(proc_macro, wasm_custom_section)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
macro_rules! doit { macro_rules! doit {
($($i:ident)*) => ($( ($($i:ident)*) => ($(
#[wasm_bindgen] #[wasm_bindgen]
pub fn $i(a: &mut [$i]) { pub fn $i(a: &mut [$i]) {
assert_eq!(a.len(), 3); assert_eq!(a.len(), 3);
assert_eq!(a[0], 1 as $i); assert_eq!(a[0], 1 as $i);
assert_eq!(a[1], 2 as $i); assert_eq!(a[1], 2 as $i);
assert_eq!(a[2], 3 as $i); assert_eq!(a[2], 3 as $i);
a[0] = 4 as $i; a[0] = 4 as $i;
a[1] = 5 as $i; a[1] = 5 as $i;
} }
)*) )*)
} }
doit! { i8 u8 i16 u16 i32 u32 f32 f64 } doit! { i8 u8 i16 u16 i32 u32 f32 f64 }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
function run(a: any, rust: any) { function run(a, rust) {
assert.strictEqual(a.length, 3); assert.strictEqual(a.length, 3);
a[0] = 1; a[0] = 1;
a[1] = 2; a[1] = 2;
a[2] = 3; a[2] = 3;
console.log(a); console.log(a);
rust(a); rust(a);
console.log(a); console.log(a);
assert.strictEqual(a.length, 3); assert.strictEqual(a.length, 3);
assert.strictEqual(a[0], 4); assert.strictEqual(a[0], 4);
assert.strictEqual(a[1], 5); assert.strictEqual(a[1], 5);
assert.strictEqual(a[2], 3); assert.strictEqual(a[2], 3);
} }
export function test() { export function test() {
run(new Int8Array(3), wasm.i8); run(new Int8Array(3), wasm.i8);
run(new Uint8Array(3), wasm.u8); run(new Uint8Array(3), wasm.u8);
run(new Int16Array(3), wasm.i16); run(new Int16Array(3), wasm.i16);
run(new Uint16Array(3), wasm.u16); run(new Uint16Array(3), wasm.u16);
run(new Int32Array(3), wasm.i32); run(new Int32Array(3), wasm.i32);
run(new Uint32Array(3), wasm.u32); run(new Uint32Array(3), wasm.u32);
run(new Float32Array(3), wasm.f32); run(new Float32Array(3), wasm.f32);
run(new Float64Array(3), wasm.f64); run(new Float64Array(3), wasm.f64);
} }
"#, "#,
) )
.test(); .test();
} }
@ -452,75 +452,75 @@ fn return_vec_ok() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
pub fn broken_vec() -> Vec<u32> { pub fn broken_vec() -> Vec<u32> {
vec![1, 2, 3, 4, 5, 6, 7, 8, 9] vec![1, 2, 3, 4, 5, 6, 7, 8, 9]
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn web_main() -> Application { pub fn web_main() -> Application {
Application::new() Application::new()
} }
#[wasm_bindgen] #[wasm_bindgen]
pub struct Application { pub struct Application {
thing: Vec<u32>, thing: Vec<u32>,
} }
#[wasm_bindgen] #[wasm_bindgen]
impl Application { impl Application {
pub fn new() -> Application { pub fn new() -> Application {
let mut thing = vec![]; let mut thing = vec![];
thing.push(0); thing.push(0);
thing.push(0); thing.push(0);
thing.push(0); thing.push(0);
thing.push(0); thing.push(0);
thing.push(0); thing.push(0);
Application { Application {
thing: thing thing: thing
}
}
pub fn tick(&mut self) {
self.thing = self.thing.clone();
} }
} }
pub fn tick(&mut self) {
self.thing = self.thing.clone();
}
}
pub fn main() { pub fn main() {
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import * as wasm from "./out"; import * as wasm from "./out";
export function test() { export function test() {
let app = wasm.web_main(); let app = wasm.web_main();
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
app.tick(); app.tick();
let bad = wasm.broken_vec(); let bad = wasm.broken_vec();
console.log("Received from rust:", i, bad); console.log("Received from rust:", i, bad);
assert.strictEqual(bad[0], 1); assert.strictEqual(bad[0], 1);
assert.strictEqual(bad[1], 2); assert.strictEqual(bad[1], 2);
assert.strictEqual(bad[2], 3); assert.strictEqual(bad[2], 3);
assert.strictEqual(bad[3], 4); assert.strictEqual(bad[3], 4);
assert.strictEqual(bad[4], 5); assert.strictEqual(bad[4], 5);
assert.strictEqual(bad[5], 6); assert.strictEqual(bad[5], 6);
assert.strictEqual(bad[6], 7); assert.strictEqual(bad[6], 7);
assert.strictEqual(bad[7], 8); assert.strictEqual(bad[7], 8);
assert.strictEqual(bad[8], 9); assert.strictEqual(bad[8], 9);
}
} }
} "#,
"#,
) )
.test(); .test();
} }

View File

@ -6,47 +6,47 @@ fn works() {
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
extern { extern {
pub type Foo; pub type Foo;
#[wasm_bindgen(method, structural)] #[wasm_bindgen(method, structural)]
fn bar(this: &Foo); fn bar(this: &Foo);
#[wasm_bindgen(method, getter, structural)] #[wasm_bindgen(method, getter, structural)]
fn baz(this: &Foo) -> u32; fn baz(this: &Foo) -> u32;
#[wasm_bindgen(method, setter, structural)] #[wasm_bindgen(method, setter, structural)]
fn set_baz(this: &Foo, val: u32); fn set_baz(this: &Foo, val: u32);
} }
#[wasm_bindgen] #[wasm_bindgen]
pub fn run(a: &Foo) { pub fn run(a: &Foo) {
a.bar(); a.bar();
assert_eq!(a.baz(), 1); assert_eq!(a.baz(), 1);
a.set_baz(2); a.set_baz(2);
assert_eq!(a.baz(), 2); assert_eq!(a.baz(), 2);
} }
"#, "#,
) )
.file( .file(
"test.ts", "test.js",
r#" r#"
import * as assert from "assert"; import * as assert from "assert";
import { run } from "./out"; import { run } from "./out";
export function test() { export function test() {
let called = false; let called = false;
run({ run({
bar() { called = true; }, bar() { called = true; },
baz: 1, baz: 1,
}); });
assert.strictEqual(called, true); assert.strictEqual(called, true);
} }
"#, "#,
) )
.test(); .test();
} }

79
tests/all/typescript.rs Normal file
View File

@ -0,0 +1,79 @@
use super::project;
#[test]
fn works() {
project()
.webpack(true)
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn foo() {}
#[wasm_bindgen]
pub fn bar(a: &str, b: u32) -> String {
format!("{} {}", a, b)
}
#[wasm_bindgen]
pub fn thunk(a: &JsValue) {
drop(a);
}
#[wasm_bindgen]
pub struct A {
}
#[wasm_bindgen]
impl A {
#[wasm_bindgen(constructor)]
pub fn new() -> A {
A {}
}
pub fn new2() -> A {
A {}
}
pub fn foo(&self) {}
pub fn bar(&self, _a: u32) {}
pub fn baz(&self, _d: &A) {}
}
"#,
)
.file(
"test.ts",
r#"
import * as assert from 'assert';
import { foo, bar, A, thunk } from './out';
import { memory } from './out_bg';
export function test() {
foo();
assert.strictEqual(bar('a', 3), 'a 3');
const x = new A();
x.foo();
x.free();
const y = A.new2();
y.foo();
y.bar(2);
y.baz(y);
y.free();
thunk(memory);
};
"#,
)
.test();
}

View File

@ -6,55 +6,55 @@ fn method() {
.file( .file(
"foo.webidl", "foo.webidl",
r#" r#"
[Constructor(double value)] [Constructor(double value)]
interface Foo { interface Foo {
[Pure] [Pure]
boolean myCmp(Foo bar); boolean myCmp(Foo bar);
}; };
"#, "#,
) )
.file( .file(
"foo.ts", "foo.js",
r#" r#"
export class Foo { export class Foo {
constructor(private value: number) { constructor(value) {
this.value = value; this.value = value;
}
myCmp(other) {
return this.value === other.value;
}
} }
myCmp(other: Foo): boolean {
return this.value === other.value;
}
}
"#, "#,
) )
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
pub mod foo; pub mod foo;
use foo::Foo; use foo::Foo;
#[wasm_bindgen] #[wasm_bindgen]
pub fn test() { pub fn test() {
let pi = Foo::new(3.14159); let pi = Foo::new(3.14159);
let e = Foo::new(2.71828); let e = Foo::new(2.71828);
// TODO: figure out why the following doesn't fail // TODO: figure out why the following doesn't fail
// assert!(!pi.my_cmp(Foo::new(3.14159))); // assert!(!pi.my_cmp(Foo::new(3.14159)));
let tmp = pi.my_cmp(Foo::new(3.14159)); let tmp = pi.my_cmp(Foo::new(3.14159));
assert!(tmp); assert!(tmp);
let tmp =!pi.my_cmp(Foo::new(2.71828)); let tmp =!pi.my_cmp(Foo::new(2.71828));
assert!(tmp); assert!(tmp);
let tmp = !e.my_cmp(Foo::new(3.14159)); let tmp = !e.my_cmp(Foo::new(3.14159));
assert!(tmp); assert!(tmp);
let tmp = e.my_cmp(Foo::new(2.71828)); let tmp = e.my_cmp(Foo::new(2.71828));
assert!(tmp); assert!(tmp);
} }
"#, "#,
) )
.test(); .test();
} }
@ -65,54 +65,54 @@ fn property() {
.file( .file(
"foo.webidl", "foo.webidl",
r#" r#"
[Constructor(double value)] [Constructor(double value)]
interface Foo { interface Foo {
[Pure] [Pure]
attribute double value; attribute double value;
}; };
"#, "#,
) )
.file( .file(
"foo.ts", "foo.js",
r#" r#"
export class Foo { export class Foo {
constructor(private _value: number) { constructor(value) {
this._value = _value; this._value = value;
} }
get value(): number { get value() {
return this._value; return this._value;
} }
set value(_value: number) { set value(value) {
this._value = _value; this._value = value;
}
} }
}
"#, "#,
) )
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
pub mod foo; pub mod foo;
use foo::Foo; use foo::Foo;
#[wasm_bindgen] #[wasm_bindgen]
pub fn test() { pub fn test() {
let x = Foo::new(3.14159); let x = Foo::new(3.14159);
assert_eq!(x.value(), 3.14159); assert_eq!(x.value(), 3.14159);
assert_ne!(x.value(), 2.71828); assert_ne!(x.value(), 2.71828);
x.set_value(2.71828); x.set_value(2.71828);
assert_ne!(x.value(), 3.14159); assert_ne!(x.value(), 3.14159);
assert_eq!(x.value(), 2.71828); assert_eq!(x.value(), 2.71828);
} }
"#, "#,
) )
.test(); .test();
} }
@ -123,52 +123,55 @@ fn named_constructor() {
.file( .file(
"foo.webidl", "foo.webidl",
r#" r#"
[NamedConstructor=Bar(double value)] [NamedConstructor=Bar(double value)]
interface Foo { interface Foo {
[Pure] [Pure]
readonly attribute double value; readonly attribute double value;
}; };
"#, "#,
) )
.file( .file(
// Not a perfect test, but it gets the job done. // Not a perfect test, but it gets the job done.
"foo.ts", "foo.js",
r#" r#"
export class Foo { export class Foo {
protected _value: number = 0; constructor() {
get value(): number { this._value = 0;
return this._value; }
}
}
export class Bar extends Foo { get value(){
constructor(_value: number) { return this._value;
super(); }
this._value = _value; }
export class Bar extends Foo {
constructor(_value) {
super();
this._value = _value;
}
} }
}
"#, "#,
) )
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
pub mod foo; pub mod foo;
use foo::Foo; use foo::Foo;
#[wasm_bindgen] #[wasm_bindgen]
pub fn test() { pub fn test() {
let x = Foo::new(3.14159); let x = Foo::new(3.14159);
assert_eq!(x.value(), 3.14159); assert_eq!(x.value(), 3.14159);
assert_ne!(x.value(), 0.); assert_ne!(x.value(), 0.);
} }
"#, "#,
) )
.test(); .test();
} }
@ -179,46 +182,47 @@ fn static_method() {
.file( .file(
"foo.webidl", "foo.webidl",
r#" r#"
interface Foo { interface Foo {
static double swap(double value); static double swap(double value);
}; };
"#, "#,
) )
.file( .file(
"foo.ts", "foo.js",
r#" r#"
export class Foo { export class Foo {
private static value: number = 0; static swap(value) {
static swap(value: number): number { const res = Foo.value;
const res = Foo.value; Foo.value = value;
Foo.value = value; return res;
return res; }
} }
}
Foo.value = 0;
"#, "#,
) )
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
pub mod foo; pub mod foo;
use foo::Foo; use foo::Foo;
#[wasm_bindgen] #[wasm_bindgen]
pub fn test() { pub fn test() {
assert_eq!(Foo::swap(3.14159), 0.); assert_eq!(Foo::swap(3.14159), 0.);
assert_eq!(Foo::swap(2.71828), 3.14159); assert_eq!(Foo::swap(2.71828), 3.14159);
assert_ne!(Foo::swap(2.71828), 3.14159); assert_ne!(Foo::swap(2.71828), 3.14159);
assert_eq!(Foo::swap(3.14159), 2.71828); assert_eq!(Foo::swap(3.14159), 2.71828);
assert_ne!(Foo::swap(3.14159), 2.71828); assert_ne!(Foo::swap(3.14159), 2.71828);
} }
"#, "#,
) )
.test(); .test();
} }
@ -229,51 +233,51 @@ fn static_property() {
.file( .file(
"foo.webidl", "foo.webidl",
r#" r#"
interface Foo { interface Foo {
static attribute double value; static attribute double value;
}; };
"#, "#,
) )
.file( .file(
"foo.ts", "foo.js",
r#" r#"
export class Foo { export class Foo {
private static _value: number = 0; static get value(){
return Foo._value;
}
static get value(): number { static set value(value) {
return Foo._value; Foo._value = value;
}
} }
static set value(_value: number) { Foo._value = 0;
Foo._value = _value;
}
}
"#, "#,
) )
.file( .file(
"src/lib.rs", "src/lib.rs",
r#" r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen; extern crate wasm_bindgen;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
pub mod foo; pub mod foo;
use foo::Foo; use foo::Foo;
#[wasm_bindgen] #[wasm_bindgen]
pub fn test() { pub fn test() {
assert_eq!(Foo::value(), 0.); assert_eq!(Foo::value(), 0.);
Foo::set_value(3.14159); Foo::set_value(3.14159);
assert_eq!(Foo::value(), 3.14159); assert_eq!(Foo::value(), 3.14159);
assert_ne!(Foo::value(), 2.71828); assert_ne!(Foo::value(), 2.71828);
Foo::set_value(2.71828); Foo::set_value(2.71828);
assert_eq!(Foo::value(), 2.71828); assert_eq!(Foo::value(), 2.71828);
assert_ne!(Foo::value(), 3.14159); assert_ne!(Foo::value(), 3.14159);
} }
"#, "#,
) )
.test(); .test();
} }