Nick Fitzgerald 3cdb6ef03a webidl: Turn the [Throws] extended attributes into Result<T, JsValue>
This sets the `catch` flag on the emitted AST when an operation/attribute has
the `[Throws]` extended attribute on it.

Additionally, constructors aren't annotated with `[Throws]` but can still throw
exceptions, so we must conservatively assume *every* constructor can throw an
error.
2018-07-11 11:07:03 -07:00

373 lines
9.5 KiB
Rust

use super::project;
#[test]
fn method() {
project()
.file(
"foo.webidl",
r#"
[Constructor(double value)]
interface Foo {
[Pure]
boolean myCmp(Foo bar);
};
"#,
)
.file(
"foo.js",
r#"
export class Foo {
constructor(value) {
this.value = value;
}
myCmp(other) {
return this.value === other.value;
}
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
use foo::Foo;
#[wasm_bindgen]
pub fn test() {
let pi = Foo::new(3.14159).unwrap();
let e = Foo::new(2.71828).unwrap();
// TODO: figure out why the following doesn't fail
// assert!(!pi.my_cmp(Foo::new(3.14159).unwrap()));
let tmp = pi.my_cmp(Foo::new(3.14159).unwrap());
assert!(tmp);
let tmp =!pi.my_cmp(Foo::new(2.71828).unwrap());
assert!(tmp);
let tmp = !e.my_cmp(Foo::new(3.14159).unwrap());
assert!(tmp);
let tmp = e.my_cmp(Foo::new(2.71828).unwrap());
assert!(tmp);
}
"#,
)
.test();
}
#[test]
fn property() {
project()
.file(
"foo.webidl",
r#"
[Constructor(double value)]
interface Foo {
[Pure]
attribute double value;
};
"#,
)
.file(
"foo.js",
r#"
export class Foo {
constructor(value) {
this._value = value;
}
get value() {
return this._value;
}
set value(value) {
this._value = value;
}
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
use foo::Foo;
#[wasm_bindgen]
pub fn test() {
let x = Foo::new(3.14159).unwrap();
assert_eq!(x.value(), 3.14159);
assert_ne!(x.value(), 2.71828);
x.set_value(2.71828);
assert_ne!(x.value(), 3.14159);
assert_eq!(x.value(), 2.71828);
}
"#,
)
.test();
}
#[test]
fn named_constructor() {
project()
.file(
"foo.webidl",
r#"
[NamedConstructor=Bar(double value)]
interface Foo {
[Pure]
readonly attribute double value;
};
"#,
)
.file(
// Not a perfect test, but it gets the job done.
"foo.js",
r#"
export class Foo {
constructor() {
this._value = 0;
}
get value(){
return this._value;
}
}
export class Bar extends Foo {
constructor(_value) {
super();
this._value = _value;
}
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
use foo::Foo;
#[wasm_bindgen]
pub fn test() {
let x = Foo::new(3.14159).unwrap();
assert_eq!(x.value(), 3.14159);
assert_ne!(x.value(), 0.);
}
"#,
)
.test();
}
#[test]
fn static_method() {
project()
.file(
"foo.webidl",
r#"
interface Foo {
static double swap(double value);
};
"#,
)
.file(
"foo.js",
r#"
export class Foo {
static swap(value) {
const res = Foo.value;
Foo.value = value;
return res;
}
}
Foo.value = 0;
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
use foo::Foo;
#[wasm_bindgen]
pub fn test() {
assert_eq!(Foo::swap(3.14159), 0.);
assert_eq!(Foo::swap(2.71828), 3.14159);
assert_ne!(Foo::swap(2.71828), 3.14159);
assert_eq!(Foo::swap(3.14159), 2.71828);
assert_ne!(Foo::swap(3.14159), 2.71828);
}
"#,
)
.test();
}
#[test]
fn static_property() {
project()
.file(
"foo.webidl",
r#"
interface Foo {
static attribute double value;
};
"#,
)
.file(
"foo.js",
r#"
export class Foo {
static get value(){
return Foo._value;
}
static set value(value) {
Foo._value = value;
}
}
Foo._value = 0;
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
use foo::Foo;
#[wasm_bindgen]
pub fn test() {
assert_eq!(Foo::value(), 0.);
Foo::set_value(3.14159);
assert_eq!(Foo::value(), 3.14159);
assert_ne!(Foo::value(), 2.71828);
Foo::set_value(2.71828);
assert_eq!(Foo::value(), 2.71828);
assert_ne!(Foo::value(), 3.14159);
}
"#,
)
.test();
}
#[test]
fn one_method_using_an_undefined_import_doesnt_break_all_other_methods() {
project()
.file(
"foo.webidl",
r#"
[Constructor()]
interface Foo {
boolean ok_method();
boolean bad_method(UndefinedType undef);
};
"#,
)
.file(
"foo.js",
r#"
export class Foo {
constructor() {}
ok_method() {
return true;
}
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
#[wasm_bindgen]
pub fn test() {
let f = foo::Foo::new().unwrap();
assert!(f.ok_method());
}
"#,
)
.test();
}
#[test]
fn unforgeable_is_structural() {
project()
.file(
"foo.webidl",
r#"
[Constructor()]
interface Foo {
[Unforgeable] readonly attribute short uno;
readonly attribute short dos;
};
"#,
)
.file(
"foo.js",
r#"
export class Foo {
constructor() {
this.uno = 1;
}
get dos() {
return 2;
}
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
#[wasm_bindgen]
pub fn test() {
let f = foo::Foo::new().unwrap();
assert_eq!(f.uno(), 1);
assert_eq!(f.dos(), 2);
}
"#,
)
.test();
}