Migrate webidl tests to wasm_bindgen_test (#590)

This commit moves the `webidl/tests` folder to a new `crates/webidl-tests` crate
(to have a test-only build script) and ports them to the `#[wasm_bindgen_test]`
attribute, which should hopefully make testing much speedier for execution!
This commit is contained in:
Alex Crichton 2018-07-30 11:06:29 -07:00 committed by GitHub
parent d876475ce3
commit 7e16690f10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 687 additions and 1107 deletions

View File

@ -103,8 +103,9 @@ matrix:
- rust: nightly
env: JOB=test-webidl
before_install: *INSTALL_NODE_VIA_NVM
install: npm ci --verbose
script: cargo test --manifest-path crates/webidl/Cargo.toml
script:
- cargo test -p wasm-bindgen-webidl
- cargo test -p webidl-tests --target wasm32-unknown-unknown
if: branch = master
# Dist linux binary

View File

@ -42,6 +42,7 @@ members = [
"crates/typescript",
"crates/web-sys",
"crates/webidl",
"crates/webidl-tests",
"examples/add",
"examples/asm.js",
"examples/char",

View File

@ -1593,6 +1593,7 @@ impl<'a> Context<'a> {
fn gc(&mut self) -> Result<(), Error> {
let module = mem::replace(self.module, Module::default());
let module = module.parse_names().unwrap_or_else(|p| p.1);
let result = wasm_gc::Config::new()
.demangle(self.config.demangle)
.keep_debug(self.config.keep_debug || self.config.debug)

View File

@ -0,0 +1,21 @@
[package]
name = "webidl-tests"
version = "0.1.0"
authors = ["The wasm-bindgen authors"]
[lib]
test = false
doctest = false
path = 'lib.rs'
[build-dependencies]
wasm-bindgen-webidl = { path = '../webidl' }
[dev-dependencies]
wasm-bindgen-test = { path = '../test' }
wasm-bindgen = { path = '../..' }
[[test]]
name = 'wasm'
path = 'main.rs'

View File

@ -0,0 +1,70 @@
const strictEqual = require('assert').strictEqual;
global.TestArrays = class {
strings(x) {
strictEqual(x, 'y');
return 'x';
}
byteStrings(x) {
strictEqual(x, 'yz');
return 'xx';
}
usvStrings(x) {
strictEqual(x, 'abc');
return 'efg';
}
f32(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Float32Array([3, 4, 5]);
}
f64(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Float64Array([3, 4, 5]);
}
i8(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Int8Array([3, 4, 5]);
}
i16(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Int16Array([3, 4, 5]);
}
i32(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Int32Array([3, 4, 5]);
}
u8(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Uint8Array([3, 4, 5]);
}
u8Clamped(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Uint8ClampedArray([3, 4, 5]);
}
u16(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Uint16Array([3, 4, 5]);
}
u32(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Uint32Array([3, 4, 5]);
}
};

View File

@ -0,0 +1,20 @@
use wasm_bindgen_test::*;
include!(concat!(env!("OUT_DIR"), "/array.rs"));
#[wasm_bindgen_test]
fn take_and_return_a_bunch_of_slices() {
let f = TestArrays::new().unwrap();
assert_eq!(f.strings("y"), "x");
assert_eq!(f.byte_strings("yz"), "xx");
assert_eq!(f.usv_strings("abc"), "efg");
assert_eq!(f.f32(&[1.0, 2.0]), [3.0, 4.0, 5.0]);
assert_eq!(f.f64(&[1.0, 2.0]), [3.0, 4.0, 5.0]);
assert_eq!(f.i8(&[1, 2]), [3, 4, 5]);
assert_eq!(f.i16(&[1, 2]), [3, 4, 5]);
assert_eq!(f.i32(&[1, 2]), [3, 4, 5]);
assert_eq!(f.u8(&[1, 2]), [3, 4, 5]);
assert_eq!(f.u8_clamped(&[1, 2]), [3, 4, 5]);
assert_eq!(f.u16(&[1, 2]), [3, 4, 5]);
assert_eq!(f.u32(&[1, 2]), [3, 4, 5]);
}

16
crates/webidl-tests/array.webidl vendored Normal file
View File

@ -0,0 +1,16 @@
[Constructor()]
interface TestArrays {
DOMString strings(DOMString arg1);
ByteString byteStrings(ByteString arg1);
USVString usvStrings(USVString arg1);
Float32Array f32(Float32Array a);
Float64Array f64(Float64Array a);
Int8Array i8(Int8Array a);
Int16Array i16(Int16Array a);
Int32Array i32(Int32Array a);
Uint8Array u8(Uint8Array a);
Uint8ClampedArray u8Clamped(Uint8ClampedArray a);
Uint16Array u16(Uint16Array a);
Uint32Array u32(Uint32Array a);
};

View File

@ -0,0 +1,46 @@
extern crate wasm_bindgen_webidl;
use std::fs;
use std::env;
use std::path::PathBuf;
fn main() {
let idls = fs::read_dir(".")
.unwrap()
.map(|f| f.unwrap().path())
.filter(|f| f.extension().and_then(|s| s.to_str()) == Some("webidl"))
.map(|f| (fs::read_to_string(&f).unwrap(), f));
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
for (i, (idl, path)) in idls.enumerate() {
println!("processing {:?}", path);
let mut generated_rust = wasm_bindgen_webidl::compile(&idl).unwrap();
let out_file = out_dir.join(path.file_name().unwrap())
.with_extension("rs");
let js_file = path.with_extension("js")
.canonicalize()
.unwrap();
generated_rust.push_str(&format!(r#"
pub mod import_script {{
use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;
#[wasm_bindgen(module = "{}", version = "*")]
extern {{
fn not_actually_a_function{1}();
}}
#[wasm_bindgen_test]
fn foo() {{
if ::std::env::var("NOT_GONNA_WORK").is_ok() {{
not_actually_a_function{1}();
}}
}}
}}
"#, js_file.display(), i));
fs::write(out_file, generated_rust).unwrap();
}
}

View File

View File

@ -0,0 +1,51 @@
use wasm_bindgen_test::*;
include!(concat!(env!("OUT_DIR"), "/consts.rs"));
#[wasm_bindgen_test]
fn bool() {
let falsish: bool = ConstBool::NOT_TRUE;
assert!(!falsish);
let trueish: bool = ConstBool::NOT_FALSE;
assert!(trueish);
}
#[wasm_bindgen_test]
fn ints() {
assert_eq!(ConstByte::IMIN, i8::min_value());
assert_eq!(ConstByte::IMAX, i8::max_value());
assert_eq!(ConstByte::UMIN, u8::min_value());
assert_eq!(ConstByte::UMAX, u8::max_value());
assert_eq!(ConstShort::IMIN, i16::min_value());
assert_eq!(ConstShort::IMAX, i16::max_value());
assert_eq!(ConstShort::UMIN, u16::min_value());
assert_eq!(ConstShort::UMAX, u16::max_value());
assert_eq!(ConstLong::IMIN, i32::min_value());
assert_eq!(ConstLong::IMAX, i32::max_value());
assert_eq!(ConstLong::UMIN, u32::min_value());
assert_eq!(ConstLong::UMAX, u32::max_value());
assert_eq!(ConstLongLong::IMIN, i64::min_value());
assert_eq!(ConstLongLong::IMAX, i64::max_value());
assert_eq!(ConstLongLong::UMIN, u64::min_value());
assert_eq!(ConstLongLong::UMAX, u64::max_value());
}
#[wasm_bindgen_test]
fn floats() {
assert_eq!(ConstFloats::F, 0.0_f32);
assert!(ConstFloats::NEG_INF.is_infinite());
assert!(ConstFloats::NEG_INF.is_sign_negative());
assert!(ConstFloats::INF.is_infinite());
assert!(ConstFloats::INF.is_sign_positive());
assert!(ConstFloats::NAN.is_nan());
assert_eq!(ConstDoubles::D, 0.0_f64);
assert!(ConstDoubles::NEG_INF.is_infinite());
assert!(ConstDoubles::NEG_INF.is_sign_negative());
assert!(ConstDoubles::INF.is_infinite());
assert!(ConstDoubles::INF.is_sign_positive());
assert!(ConstDoubles::NAN.is_nan());
}

46
crates/webidl-tests/consts.webidl vendored Normal file
View File

@ -0,0 +1,46 @@
interface ConstBool {
const boolean not_true = false;
const boolean not_false = true;
};
interface ConstByte {
const byte imin = -128;
const byte imax = 127;
const octet umin = 0;
const octet umax = 255;
};
interface ConstShort {
const short imin = -32768;
const short imax = 32767;
const unsigned short umin = 0;
const unsigned short umax = 65535;
};
interface ConstLong {
const long imin = -2147483648;
const long imax = 2147483647;
const unsigned long umin = 0;
const unsigned long umax = 4294967295;
};
interface ConstLongLong {
const long long imin = -9223372036854775808;
const long long imax = 9223372036854775807;
const unsigned long long umin = 0;
const unsigned long long umax = 18446744073709551615;
};
interface ConstFloats {
const float f = 0.0;
const unrestricted float neg_inf = -Infinity;
const unrestricted float inf = Infinity;
const unrestricted float nan = NaN;
};
interface ConstDoubles {
const double d = 0.0;
const unrestricted double neg_inf = -Infinity;
const unrestricted double inf = Infinity;
const unrestricted double nan = NaN;
};

View File

@ -0,0 +1,21 @@
global.Shape = class Shape {
constructor(kind) {
this.kind = kind;
}
static triangle() {
return new Shape('triangle');
}
isSquare() {
return this.kind === 'square';
}
isCircle() {
return this.kind === 'circle';
}
getShape() {
return this.kind;
}
};

View File

@ -0,0 +1,36 @@
use wasm_bindgen_test::*;
include!(concat!(env!("OUT_DIR"), "/enums.rs"));
#[wasm_bindgen_test]
fn top_level_enum() {
let circle = Shape::new(ShapeType::Circle).unwrap();
let square = Shape::new(ShapeType::Square).unwrap();
assert!(circle.is_circle());
assert!(!circle.is_square());
assert!(square.is_square());
assert!(!square.is_circle());
}
#[wasm_bindgen_test]
fn valid_enum_return() {
let circle = Shape::new(ShapeType::Circle).unwrap();
let square = Shape::new(ShapeType::Square).unwrap();
assert!(circle.is_circle());
assert!(!circle.is_square());
assert_eq!(circle.get_shape(), ShapeType::Circle);
assert!(square.is_square());
assert!(!square.is_circle());
assert_eq!(square.get_shape(), ShapeType::Square);
}
#[wasm_bindgen_test]
fn invalid_enum_return() {
let actually_a_triangle = Shape::triangle();
assert!(!actually_a_triangle.is_circle());
assert!(!actually_a_triangle.is_square());
match actually_a_triangle.get_shape() {
ShapeType::Circle | ShapeType::Square => assert!(false),
_ => {} // Success
};
}

15
crates/webidl-tests/enums.webidl vendored Normal file
View File

@ -0,0 +1,15 @@
enum ShapeType { "circle", "square" };
[Constructor(ShapeType kind)]
interface Shape {
static Shape triangle();
[Pure]
boolean isSquare();
[Pure]
boolean isCircle();
[Pure]
ShapeType getShape();
};

View File

@ -0,0 +1 @@
// intentionally left blank

View File

@ -0,0 +1,10 @@
#![feature(use_extern_macros)]
extern crate wasm_bindgen_test;
extern crate wasm_bindgen;
pub mod consts;
pub mod enums;
pub mod simple;
pub mod throws;
pub mod array;

View File

@ -0,0 +1,110 @@
global.Method = class Method {
constructor(value) {
this.value = value;
}
myCmp(other) {
return this.value === other.value;
}
};
global.Property = class Property {
constructor(value) {
this._value = value;
}
get value() {
return this._value;
}
set value(value) {
this._value = value;
}
};
global.NamedConstructor = class NamedConstructor {
constructor() {
this._value = 0;
}
get value(){
return this._value;
}
};
global.NamedConstructorBar = class NamedConstructorBar extends NamedConstructor {
constructor(_value) {
super();
this._value = _value;
}
};
global.StaticMethod = class StaticMethod {
static swap(value) {
const res = StaticMethod.value;
StaticMethod.value = value;
return res;
}
};
StaticMethod.value = 0;
global.StaticProperty = class StaticProperty {
static get value(){
return StaticProperty._value;
}
static set value(value) {
StaticProperty._value = value;
}
};
StaticProperty._value = 0;
global.UndefinedMethod = class UndefinedMethod {
constructor() {}
ok_method() {
return true;
}
};
global.Unforgeable = class Unforgeable {
constructor() {
this.uno = 1;
}
get dos() {
return 2;
}
};
global.PartialInterface = class PartialInterface {
get un() {
return 1;
}
deux() {
return 2;
}
get trois() {
return 3;
}
quatre() {
return 4;
}
};
global.MixinFoo = class MixinFoo {
constructor(bar) {
this._bar = bar | MixinFoo.defaultBar;
}
static get defaultBar() {
return MixinFoo._defaultBar;
}
static set defaultBar(defaultBar) {
MixinFoo._defaultBar = defaultBar;
}
get bar() {
return this._bar;
}
addToBar(other) {
this._bar += other;
}
};

View File

@ -0,0 +1,81 @@
use wasm_bindgen_test::*;
include!(concat!(env!("OUT_DIR"), "/simple.rs"));
#[wasm_bindgen_test]
fn method() {
let pi = Method::new(3.14159).unwrap();
let e = Method::new(2.71828).unwrap();
assert!(pi.my_cmp(&pi));
assert!(!pi.my_cmp(&e));
assert!(!e.my_cmp(&pi));
assert!(e.my_cmp(&e));
}
#[wasm_bindgen_test]
fn property() {
let x = Property::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);
}
#[wasm_bindgen_test]
fn named_constructor() {
let x = NamedConstructor::new(3.14159).unwrap();
assert_eq!(x.value(), 3.14159);
assert_ne!(x.value(), 0.);
}
#[wasm_bindgen_test]
fn static_method() {
assert_eq!(StaticMethod::swap(3.14159), 0.);
assert_eq!(StaticMethod::swap(2.71828), 3.14159);
assert_ne!(StaticMethod::swap(2.71828), 3.14159);
assert_eq!(StaticMethod::swap(3.14159), 2.71828);
assert_ne!(StaticMethod::swap(3.14159), 2.71828);
}
#[wasm_bindgen_test]
fn static_property() {
assert_eq!(StaticProperty::value(), 0.);
StaticProperty::set_value(3.14159);
assert_eq!(StaticProperty::value(), 3.14159);
assert_ne!(StaticProperty::value(), 2.71828);
StaticProperty::set_value(2.71828);
assert_eq!(StaticProperty::value(), 2.71828);
assert_ne!(StaticProperty::value(), 3.14159);
}
#[wasm_bindgen_test]
fn one_method_using_an_undefined_import_doesnt_break_all_other_methods() {
let f = UndefinedMethod::new().unwrap();
assert!(f.ok_method());
}
#[wasm_bindgen_test]
fn unforgeable_is_structural() {
let f = Unforgeable::new().unwrap();
assert_eq!(f.uno(), 1);
assert_eq!(f.dos(), 2);
}
#[wasm_bindgen_test]
fn partial_interface() {
let f = PartialInterface::new().unwrap();
assert_eq!(f.un(), 1);
assert_eq!(f.deux(), 2);
assert_eq!(f.trois(), 3);
assert_eq!(f.quatre(), 4);
}
#[wasm_bindgen_test]
fn mixin() {
let f = MixinFoo::new(1).unwrap();
assert_eq!(f.bar(), 1);
MixinFoo::set_default_bar(7);
f.add_to_bar(MixinFoo::default_bar());
assert_eq!(f.bar(), 8);
}

63
crates/webidl-tests/simple.webidl vendored Normal file
View File

@ -0,0 +1,63 @@
[Constructor(double value)]
interface Method {
[Pure]
boolean myCmp(Method bar);
};
[Constructor(double value)]
interface Property {
[Pure]
attribute double value;
};
[NamedConstructor=NamedConstructorBar(double value)]
interface NamedConstructor {
[Pure]
readonly attribute double value;
};
interface StaticMethod {
static double swap(double value);
};
interface StaticProperty {
static attribute double value;
};
[Constructor()]
interface UndefinedMethod {
boolean ok_method();
boolean bad_method(UndefinedType undef);
};
[Constructor()]
interface Unforgeable {
[Unforgeable] readonly attribute short uno;
readonly attribute short dos;
};
[Constructor]
interface PartialInterface {
readonly attribute short un;
short deux();
};
partial interface PartialInterface {
readonly attribute short trois;
short quatre();
};
[Constructor(short bar)]
interface MixinFoo {
static attribute short defaultBar;
};
interface mixin MixinBar {
readonly attribute short bar;
};
partial interface mixin MixinBar {
void addToBar(short other);
};
MixinFoo includes MixinBar;

View File

@ -0,0 +1,26 @@
global.Thang = class Thang {
constructor(value) {
if (value % 2 == 0) {
throw new Error("only odd allowed");
}
this.value = value;
}
get ok_attr() { return this.value; }
set ok_attr(x) { }
get err_attr() { throw new Error("bad"); }
set err_attr(x) { throw new Error("bad"); }
ok_method() { return this.value + 1; }
err_method() { throw new Error("bad"); }
static ok_static_method() { return 1; }
static err_static_method() { throw new Error("bad"); }
static get ok_static_attr() { return 1; }
static set ok_static_attr(x) { }
static get err_static_attr() { throw new Error("bad"); }
static set err_static_attr(x) { throw new Error("bad"); }
};

View File

@ -0,0 +1,27 @@
use wasm_bindgen_test::*;
include!(concat!(env!("OUT_DIR"), "/throws.rs"));
#[wasm_bindgen_test]
fn throws() {
assert!(Thang::new(0).is_err());
let thang = Thang::new(1).unwrap();
assert!(thang.ok_attr().is_ok());
assert!(thang.set_ok_attr(0).is_ok());
assert!(thang.err_attr().is_err());
assert!(thang.set_err_attr(0).is_err());
assert!(thang.ok_method().is_ok());
assert!(thang.err_method().is_err());
assert!(Thang::ok_static_method().is_ok());
assert!(Thang::err_static_method().is_err());
assert!(Thang::ok_static_attr().is_ok());
assert!(Thang::set_ok_static_attr(0).is_ok());
assert!(Thang::err_static_attr().is_err());
assert!(Thang::set_err_static_attr(0).is_err());
}

22
crates/webidl-tests/throws.webidl vendored Normal file
View File

@ -0,0 +1,22 @@
[Constructor(long value)]
interface Thang {
[Throws]
attribute long ok_attr;
[Throws]
attribute long err_attr;
[Throws]
long ok_method();
[Throws]
long err_method();
[Throws]
static long ok_static_method();
[Throws]
static long err_static_method();
[Throws]
static attribute long ok_static_attr;
[Throws]
static attribute long err_static_attr;
};

View File

@ -11,9 +11,6 @@ description = """
Support for parsing WebIDL specific to wasm-bindgen
"""
[dev-dependencies]
wasm-bindgen-test-project-builder = { path = "../test-project-builder", version = '=0.2.15' }
[dependencies]
failure = "0.1"
failure_derive = "0.1"

View File

@ -1,134 +0,0 @@
use super::project;
#[test]
fn take_and_return_a_bunch_of_slices() {
project()
.file(
"foo.webidl",
r#"
[Constructor()]
interface Foo {
DOMString strings(DOMString arg1);
ByteString byteStrings(ByteString arg1);
USVString usvStrings(USVString arg1);
Float32Array f32(Float32Array a);
Float64Array f64(Float64Array a);
Int8Array i8(Int8Array a);
Int16Array i16(Int16Array a);
Int32Array i32(Int32Array a);
Uint8Array u8(Uint8Array a);
Uint8ClampedArray u8Clamped(Uint8ClampedArray a);
Uint16Array u16(Uint16Array a);
Uint32Array u32(Uint32Array a);
};
"#,
)
.file(
"foo.js",
r#"
import { strictEqual } from "assert";
export class Foo {
strings(x) {
strictEqual(x, 'y');
return 'x';
}
byteStrings(x) {
strictEqual(x, 'yz');
return 'xx';
}
usvStrings(x) {
strictEqual(x, 'abc');
return 'efg';
}
f32(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Float32Array([3, 4, 5]);
}
f64(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Float64Array([3, 4, 5]);
}
i8(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Int8Array([3, 4, 5]);
}
i16(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Int16Array([3, 4, 5]);
}
i32(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Int32Array([3, 4, 5]);
}
u8(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Uint8Array([3, 4, 5]);
}
u8Clamped(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Uint8ClampedArray([3, 4, 5]);
}
u16(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Uint16Array([3, 4, 5]);
}
u32(x) {
strictEqual(x.length, 2);
strictEqual(x[0], 1);
strictEqual(x[1], 2);
return new Uint32Array([3, 4, 5]);
}
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
use foo::Foo;
#[wasm_bindgen]
pub fn test() {
let f = Foo::new().unwrap();
assert_eq!(f.strings("y"), "x");
assert_eq!(f.byte_strings("yz"), "xx");
assert_eq!(f.usv_strings("abc"), "efg");
assert_eq!(f.f32(&[1.0, 2.0]), [3.0, 4.0, 5.0]);
assert_eq!(f.f64(&[1.0, 2.0]), [3.0, 4.0, 5.0]);
assert_eq!(f.i8(&[1, 2]), [3, 4, 5]);
assert_eq!(f.i16(&[1, 2]), [3, 4, 5]);
assert_eq!(f.i32(&[1, 2]), [3, 4, 5]);
assert_eq!(f.u8(&[1, 2]), [3, 4, 5]);
assert_eq!(f.u8_clamped(&[1, 2]), [3, 4, 5]);
assert_eq!(f.u16(&[1, 2]), [3, 4, 5]);
assert_eq!(f.u32(&[1, 2]), [3, 4, 5]);
}
"#,
)
.test();
}

View File

@ -1,188 +0,0 @@
use super::project;
#[test]
fn bool() {
project()
.file(
"foo.webidl",
r#"
interface Foo {
const boolean not_true = false;
const boolean not_false = true;
};
"#,
)
// a corresponding const in the js implementation is not required
// value is taken directly from idl
.file(
"foo.js",
r#"
export class Foo {
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
use foo::Foo;
#[wasm_bindgen]
pub fn test() {
let falsish: bool = Foo::NOT_TRUE;
assert!(!falsish);
let trueish: bool = Foo::NOT_FALSE;
assert!(trueish);
}
"#,
)
.test();
}
#[test]
fn ints() {
project()
.file(
"foo.webidl",
r#"
interface Byte {
const byte imin = -128;
const byte imax = 127;
const octet umin = 0;
const octet umax = 255;
};
interface Short {
const short imin = -32768;
const short imax = 32767;
const unsigned short umin = 0;
const unsigned short umax = 65535;
};
interface Long {
const long imin = -2147483648;
const long imax = 2147483647;
const unsigned long umin = 0;
const unsigned long umax = 4294967295;
};
interface LongLong {
const long long imin = -9223372036854775808;
const long long imax = 9223372036854775807;
const unsigned long long umin = 0;
const unsigned long long umax = 18446744073709551615;
};
"#,
)
// a corresponding const in the js implementation is not required
// value is taken directly from idl
.file(
"foo.js",
r#"
export class Byte {
}
export class Short {
}
export class Long {
}
export class LongLong {
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
#[wasm_bindgen]
pub fn test() {
assert_eq!(foo::Byte::IMIN, i8::min_value());
assert_eq!(foo::Byte::IMAX, i8::max_value());
assert_eq!(foo::Byte::UMIN, u8::min_value());
assert_eq!(foo::Byte::UMAX, u8::max_value());
assert_eq!(foo::Short::IMIN, i16::min_value());
assert_eq!(foo::Short::IMAX, i16::max_value());
assert_eq!(foo::Short::UMIN, u16::min_value());
assert_eq!(foo::Short::UMAX, u16::max_value());
assert_eq!(foo::Long::IMIN, i32::min_value());
assert_eq!(foo::Long::IMAX, i32::max_value());
assert_eq!(foo::Long::UMIN, u32::min_value());
assert_eq!(foo::Long::UMAX, u32::max_value());
assert_eq!(foo::LongLong::IMIN, i64::min_value());
assert_eq!(foo::LongLong::IMAX, i64::max_value());
assert_eq!(foo::LongLong::UMIN, u64::min_value());
assert_eq!(foo::LongLong::UMAX, u64::max_value());
}
"#,
)
.test();
}
#[test]
fn floats() {
project()
.file(
"foo.webidl",
r#"
interface floats {
const float f = 0.0;
const unrestricted float neg_inf = -Infinity;
const unrestricted float inf = Infinity;
const unrestricted float nan = NaN;
};
interface doubles {
const double d = 0.0;
const unrestricted double neg_inf = -Infinity;
const unrestricted double inf = Infinity;
const unrestricted double nan = NaN;
};
"#,
)
// a corresponding const in the js implementation is not required
// value is taken directly from idl
.file(
"foo.js",
r#"
export class floats {
}
export class doubles {
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
#[wasm_bindgen]
pub fn test() {
assert_eq!(foo::Floats::F, 0.0_f32);
assert!(foo::Floats::NEG_INF.is_infinite());
assert!(foo::Floats::NEG_INF.is_sign_negative());
assert!(foo::Floats::INF.is_infinite());
assert!(foo::Floats::INF.is_sign_positive());
assert!(foo::Floats::NAN.is_nan());
assert_eq!(foo::Doubles::D, 0.0_f64);
assert!(foo::Doubles::NEG_INF.is_infinite());
assert!(foo::Doubles::NEG_INF.is_sign_negative());
assert!(foo::Doubles::INF.is_infinite());
assert!(foo::Doubles::INF.is_sign_positive());
assert!(foo::Doubles::NAN.is_nan());
}
"#,
)
.test();
}

View File

@ -1,179 +0,0 @@
use super::project;
static SHAPE_IDL: &'static str = r#"
enum ShapeType { "circle", "square" };
[Constructor(ShapeType kind)]
interface Shape {
[Pure]
boolean isSquare();
[Pure]
boolean isCircle();
[Pure]
ShapeType getShape();
};
"#;
#[test]
fn top_level_enum() {
project()
.file("shape.webidl", SHAPE_IDL)
.file(
"shape.mjs",
r#"
export class Shape {
constructor(kind) {
this.kind = kind;
}
isSquare() {
return this.kind === 'square';
}
isCircle() {
return this.kind === 'circle';
}
getShape() {
return this.kind;
}
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod shape;
use shape::{Shape, ShapeType};
#[wasm_bindgen]
pub fn test() {
let circle = Shape::new(ShapeType::Circle).unwrap();
let square = Shape::new(ShapeType::Square).unwrap();
assert!(circle.is_circle());
assert!(!circle.is_square());
assert!(square.is_square());
assert!(!square.is_circle());
}
"#,
)
.test();
}
#[test]
fn valid_enum_return() {
project()
.file("shape.webidl", SHAPE_IDL)
.file(
"shape.mjs",
r#"
export class Shape {
constructor(kind) {
this.kind = kind;
}
isSquare() {
return this.kind === 'square';
}
isCircle() {
return this.kind === 'circle';
}
getShape() {
return this.kind;
}
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod shape;
use shape::{Shape, ShapeType};
#[wasm_bindgen]
pub fn test() {
let circle = Shape::new(ShapeType::Circle).unwrap();
let square = Shape::new(ShapeType::Square).unwrap();
assert!(circle.is_circle());
assert!(!circle.is_square());
assert_eq!(circle.get_shape(), ShapeType::Circle);
assert!(square.is_square());
assert!(!square.is_circle());
assert_eq!(square.get_shape(), ShapeType::Square);
}
"#,
)
.test();
}
#[test]
fn invalid_enum_return() {
project()
.file("shape.webidl", SHAPE_IDL)
.file(
"shape.mjs",
r#"
export class Shape {
constructor(kind) {
this.kind = 'triangle'; // <-- invalid ShapeType
}
isSquare() {
return this.kind === 'square';
}
isCircle() {
return this.kind === 'circle';
}
getShape() {
return this.kind;
}
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod shape;
use shape::{Shape, ShapeType};
#[wasm_bindgen]
pub fn test() {
let actually_a_triangle = Shape::new(ShapeType::Circle).unwrap();
assert!(!actually_a_triangle.is_circle());
assert!(!actually_a_triangle.is_square());
match actually_a_triangle.get_shape() {
ShapeType::Circle | ShapeType::Square => assert!(false),
_ => {} // Success
};
}
"#,
)
.test();
}

View File

@ -1,8 +0,0 @@
extern crate wasm_bindgen_test_project_builder as project_builder;
use project_builder::project;
mod consts;
mod enums;
mod simple;
mod throws;
mod array;

View File

@ -1,493 +0,0 @@
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(use_extern_macros)]
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();
assert!(pi.my_cmp(&pi));
assert!(!pi.my_cmp(&e));
assert!(!e.my_cmp(&pi));
assert!(e.my_cmp(&e));
}
"#,
)
.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(use_extern_macros)]
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(use_extern_macros)]
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(use_extern_macros)]
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(use_extern_macros)]
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(use_extern_macros)]
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(use_extern_macros)]
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();
}
#[test]
fn partial_interface() {
project()
.file(
"foo.webidl",
r#"
[Constructor]
interface Foo {
readonly attribute short un;
short deux();
};
partial interface Foo {
readonly attribute short trois;
short quatre();
};
"#,
)
.file(
"foo.js",
r#"
export class Foo {
get un() {
return 1;
}
deux() {
return 2;
}
get trois() {
return 3;
}
quatre() {
return 4;
}
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros)]
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.un(), 1);
assert_eq!(f.deux(), 2);
assert_eq!(f.trois(), 3);
assert_eq!(f.quatre(), 4);
}
"#,
)
.test();
}
#[test]
fn mixin() {
project()
.file(
"foo.webidl",
r#"
[Constructor(short bar)]
interface Foo {
static attribute short defaultBar;
};
interface mixin Bar {
readonly attribute short bar;
};
partial interface mixin Bar {
void addToBar(short other);
};
Foo includes Bar;
"#,
)
.file(
"foo.js",
r#"
export class Foo {
constructor(bar) {
this._bar = bar | Foo.defaultBar;
}
static get defaultBar() {
return Foo._defaultBar;
}
static set defaultBar(defaultBar) {
Foo._defaultBar = defaultBar;
}
get bar() {
return this._bar;
}
addToBar(other) {
this._bar += other;
}
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod foo;
use foo::Foo;
#[wasm_bindgen]
pub fn test() {
let f = Foo::new(1).unwrap();
assert_eq!(f.bar(), 1);
Foo::set_default_bar(7);
f.add_to_bar(Foo::default_bar());
assert_eq!(f.bar(), 8);
}
"#,
)
.test();
}

View File

@ -1,100 +0,0 @@
use super::project;
#[test]
fn throws() {
project()
.file(
"thang.webidl",
r#"
[Constructor(long value)]
interface Thang {
[Throws]
attribute long ok_attr;
[Throws]
attribute long err_attr;
[Throws]
long ok_method();
[Throws]
long err_method();
[Throws]
static long ok_static_method();
[Throws]
static long err_static_method();
[Throws]
static attribute long ok_static_attr;
[Throws]
static attribute long err_static_attr;
};
"#,
)
.file(
"thang.js",
r#"
export class Thang {
constructor(value) {
if (value % 2 == 0) {
throw new Error("only odd allowed");
}
this.value = value;
}
get ok_attr() { return this.value; }
set ok_attr(x) { }
get err_attr() { throw new Error("bad"); }
set err_attr(x) { throw new Error("bad"); }
ok_method() { return this.value + 1; }
err_method() { throw new Error("bad"); }
static ok_static_method() { return 1; }
static err_static_method() { throw new Error("bad"); }
static get ok_static_attr() { return 1; }
static set ok_static_attr(x) { }
static get err_static_attr() { throw new Error("bad"); }
static set err_static_attr(x) { throw new Error("bad"); }
}
"#,
)
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
pub mod thang;
use thang::Thang;
#[wasm_bindgen]
pub fn test() {
assert!(Thang::new(0).is_err());
let thang = Thang::new(1).unwrap();
assert!(thang.ok_attr().is_ok());
assert!(thang.set_ok_attr(0).is_ok());
assert!(thang.err_attr().is_err());
assert!(thang.set_err_attr(0).is_err());
assert!(thang.ok_method().is_ok());
assert!(thang.err_method().is_err());
assert!(Thang::ok_static_method().is_ok());
assert!(Thang::err_static_method().is_err());
assert!(Thang::ok_static_attr().is_ok());
assert!(Thang::set_ok_static_attr(0).is_ok());
assert!(Thang::err_static_attr().is_err());
assert!(Thang::set_err_static_attr(0).is_err());
}
"#,
)
.test();
}