extern crate test_support; #[test] fn simple() { test_support::project() .file("src/lib.rs", r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[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 } } "#) .file("test.ts", r#" import * as assert from "assert"; import { Foo } from "./out"; export function test() { const r = Foo.new(); assert.strictEqual(r.add(0), 0); assert.strictEqual(r.add(1), 1); assert.strictEqual(r.add(1), 2); r.free(); const r2 = Foo.with_contents(10); assert.strictEqual(r2.add(1), 11); assert.strictEqual(r2.add(2), 13); assert.strictEqual(r2.add(3), 16); r2.free(); } "#) .test(); } #[test] fn strings() { test_support::project() .file("src/lib.rs", r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct Foo { name: u32, } #[wasm_bindgen] pub struct Bar { contents: String, } #[wasm_bindgen] impl Foo { pub fn new() -> Foo { Foo { name: 0 } } pub fn set(&mut self, amt: u32) { self.name = amt; } pub fn bar(&self, mix: &str) -> Bar { Bar { contents: format!("foo-{}-{}", mix, self.name) } } } #[wasm_bindgen] impl Bar { pub fn name(&self) -> String { self.contents.clone() } } "#) .file("test.ts", r#" import * as assert from "assert"; import { Foo } from "./out"; export function test() { const r = Foo.new(); r.set(3); let bar = r.bar('baz'); r.free(); assert.strictEqual(bar.name(), "foo-baz-3"); bar.free(); } "#) .test(); } #[test] fn exceptions() { test_support::project() .file("src/lib.rs", r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct A { } #[wasm_bindgen] impl A { pub fn new() -> A { A {} } pub fn foo(&self, _: &A) { } pub fn bar(&mut self, _: &mut A) { } } #[wasm_bindgen] pub struct B { } #[wasm_bindgen] impl B { pub fn new() -> B { B {} } } "#) .file("test.js", r#" import * as assert from "assert"; import { A, B } from "./out"; export function test() { assert.throws(() => new A(), /cannot invoke `new` directly/); let a = A.new(); a.free(); assert.throws(() => a.free(), /null pointer passed to rust/); let b = A.new(); b.foo(b); assert.throws(() => b.bar(b), /recursive use of an object/); let c = A.new(); let d = B.new(); assert.throws(() => c.foo(d), /expected instance of A/); d.free(); c.free(); }; "#) .file("test.d.ts", r#" export function test(): void; "#) .test(); } #[test] fn pass_one_to_another() { test_support::project() .file("src/lib.rs", r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct A {} #[wasm_bindgen] impl A { pub fn new() -> A { A {} } pub fn foo(&self, _other: &B) { } pub fn bar(&self, _other: B) { } } #[wasm_bindgen] pub struct B {} #[wasm_bindgen] impl B { pub fn new() -> B { B {} } } "#) .file("test.ts", r#" import { A, B } from "./out"; export function test() { let a = A.new(); let b = B.new(); a.foo(b); a.bar(b); a.free(); } "#) .test(); } #[test] fn pass_into_js() { test_support::project() .file("src/lib.rs", r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct Foo(i32); #[wasm_bindgen] impl Foo { pub fn inner(&self) -> i32 { self.0 } } #[wasm_bindgen(module = "./test")] extern { fn take_foo(foo: Foo); } #[wasm_bindgen] pub fn run() { take_foo(Foo(13)); } "#) .file("test.ts", r#" import { run, Foo } from "./out"; import * as assert from "assert"; export function take_foo(foo: Foo) { assert.strictEqual(foo.inner(), 13); foo.free(); assert.throws(() => foo.free(), /null pointer passed to rust/); } export function test() { run(); } "#) .test(); } #[test] fn issue_27() { test_support::project() .file("src/lib.rs", r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct Context {} #[wasm_bindgen] impl Context { pub fn parse(&self, expr: &str) -> Expr { panic!() } pub fn eval(&self, expr: &Expr) -> f64 { panic!() } pub fn set(&mut self, var: &str, val: f64) { panic!() } } #[wasm_bindgen] pub struct Expr {} #[wasm_bindgen] pub fn context() -> Context { Context {} } "#) .file("test.ts", r#" import { context } from "./out"; export function test() { context(); } "#) .test(); } #[test] fn pass_into_js_as_js_class() { test_support::project() .file("src/lib.rs", r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct Foo(i32); #[wasm_bindgen] impl Foo { pub fn inner(&self) -> i32 { self.0 } } #[wasm_bindgen(module = "./test")] extern { fn take_foo(foo: JsValue); } #[wasm_bindgen] pub fn run() { take_foo(Foo(13).into()); } "#) .file("test.ts", r#" import { run, Foo } from "./out"; import * as assert from "assert"; export function take_foo(foo: any) { assert(foo instanceof Foo); assert.strictEqual(foo.inner(), 13); foo.free(); } export function test() { run(); } "#) .test(); }