diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 7e1b3634..ecede1ee 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -583,7 +583,7 @@ impl ToTokens for ast::ImportFunction { subpat: None, .. }) => ident.clone(), - _ => panic!("unsupoported pattern in foreign function"), + _ => panic!("unsupported pattern in foreign function"), }; abi_argument_names.push(name.clone()); diff --git a/examples/closures/src/lib.rs b/examples/closures/src/lib.rs index b4917845..de4b04ea 100644 --- a/examples/closures/src/lib.rs +++ b/examples/closures/src/lib.rs @@ -3,6 +3,8 @@ extern crate wasm_bindgen; use wasm_bindgen::prelude::*; +use wasm_bindgen::js::Date; +use wasm_bindgen::js::JsString; #[wasm_bindgen] extern { @@ -16,13 +18,6 @@ extern { #[wasm_bindgen(js_name = setInterval)] fn set_interval(cb: &Closure, delay: u32) -> f64; - // Bindings for JS `Date` so we can update our local timer - type Date; - #[wasm_bindgen(constructor)] - fn new() -> Date; - #[wasm_bindgen(method, js_name = toLocaleString)] - fn to_locale_string(this: &Date) -> String; - // Bindings for `document` and various methods of updating HTML elements. // Like with the `dom` example these'll ideally be upstream in a generated // crate one day but for now we manually define them. @@ -57,7 +52,11 @@ pub fn run() { update_time(); fn update_time() { document.get_element_by_id("current-time") - .set_inner_html(&Date::new().to_locale_string()); + .set_inner_html( + &String::from( + Date::new() + .to_locale_string( + JsString::from("en-GB"), JsValue::undefined()))); } // We also want to count the number of times that our green square has been diff --git a/src/js.rs b/src/js.rs index 65dabb18..14219dfb 100644 --- a/src/js.rs +++ b/src/js.rs @@ -65,6 +65,25 @@ extern { pub fn eval(js_source_text: &str) -> Result; } +// UInt8Array +#[wasm_bindgen] +extern { + pub type Uint8Array; + + /// The `Uint8Array()` constructor creates an array of unsigned 8-bit integers. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array + #[wasm_bindgen(constructor)] + pub fn new(constructor_arg: JsValue) -> Uint8Array; + + /// The fill() method fills all the elements of an array from a start index + /// to an end index with a static value. The end index is not included. + /// + /// http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/fill + #[wasm_bindgen(method)] + pub fn fill(this: &Uint8Array, value: JsValue, start: u32, end: u32) -> Uint8Array; +} + // Array #[wasm_bindgen] extern { @@ -98,14 +117,12 @@ extern { #[wasm_bindgen(method)] pub fn filter(this: &Array, predicate: &mut FnMut(JsValue, u32, Array) -> bool) -> Array; - /// The length property of an object which is an instance of type Array - /// sets or returns the number of elements in that array. The value is an - /// unsigned, 32-bit integer that is always numerically greater than the - /// highest index in the array. + /// The includes() method determines whether an array includes a certain + /// element, returning true or false as appropriate. /// - /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length - #[wasm_bindgen(method, getter, structural)] - pub fn length(this: &Array) -> u32; + /// http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes + #[wasm_bindgen(method)] + pub fn includes(this: &Array, value: JsValue, from_index: i32) -> bool; /// The indexOf() method returns the first index at which a given element /// can be found in the array, or -1 if it is not present. @@ -114,13 +131,6 @@ extern { #[wasm_bindgen(method, js_name = indexOf)] pub fn index_of(this: &Array, value: JsValue, from_index: i32) -> i32; - /// The includes() method determines whether an array includes a certain - /// element, returning true or false as appropriate. - /// - /// http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes - #[wasm_bindgen(method)] - pub fn includes(this: &Array, value: JsValue, from_index: i32) -> bool; - /// The join() method joins all elements of an array (or an array-like object) /// into a string and returns this string. /// @@ -136,6 +146,15 @@ extern { #[wasm_bindgen(method, js_name = lastIndexOf)] pub fn last_index_of(this: &Array, value: JsValue, from_index: i32) -> i32; + /// The length property of an object which is an instance of type Array + /// sets or returns the number of elements in that array. The value is an + /// unsigned, 32-bit integer that is always numerically greater than the + /// highest index in the array. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length + #[wasm_bindgen(method, getter, structural)] + pub fn length(this: &Array) -> u32; + /// The pop() method removes the last element from an array and returns that /// element. This method changes the length of the array. /// @@ -157,6 +176,13 @@ extern { #[wasm_bindgen(method)] pub fn reverse(this: &Array) -> Array; + /// The shift() method removes the first element from an array and returns + /// that removed element. This method changes the length of the array. + /// + /// http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift + #[wasm_bindgen(method)] + pub fn shift(this: &Array) -> JsValue; + /// The slice() method returns a shallow copy of a portion of an array into /// a new array object selected from begin to end (end not included). /// The original array will not be modified. @@ -165,13 +191,6 @@ extern { #[wasm_bindgen(method)] pub fn slice(this: &Array, start: u32, end: u32) -> Array; - /// The shift() method removes the first element from an array and returns - /// that removed element. This method changes the length of the array. - /// - /// http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift - #[wasm_bindgen(method)] - pub fn shift(this: &Array) -> JsValue; - /// The sort() method sorts the elements of an array in place and returns /// the array. The sort is not necessarily stable. The default sort /// order is according to string Unicode code points. @@ -372,6 +391,105 @@ extern { pub fn value_of(this: &Number) -> Number; } +// Date. +#[wasm_bindgen] +extern { + pub type Date; + + /// Creates a JavaScript Date instance that represents + /// a single moment in time. Date objects are based on a time value that is + /// the number of milliseconds since 1 January 1970 UTC. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date + #[wasm_bindgen(constructor)] + pub fn new() -> Date; + + /// The toDateString() method returns the date portion of a Date object + /// in human readable form in American English. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toDateString + #[wasm_bindgen(method, js_name = toDateString)] + pub fn to_date_string(this: &Date) -> JsString; + + /// The toISOString() method returns a string in simplified extended ISO format (ISO + /// 8601), which is always 24 or 27 characters long (YYYY-MM-DDTHH:mm:ss.sssZ or + /// ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively). The timezone is always zero UTC offset, + /// as denoted by the suffix "Z" + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString + #[wasm_bindgen(method, js_name = toISOString)] + pub fn to_iso_string(this: &Date) -> JsString; + + /// The toJSON() method returns a string representation of the Date object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON + #[wasm_bindgen(method, js_name = toJSON)] + pub fn to_json(this: &Date) -> JsString; + + /// The toLocaleDateString() method returns a string with a language sensitive + /// representation of the date portion of this date. The new locales and options + /// arguments let applications specify the language whose formatting conventions + /// should be used and allow to customize the behavior of the function. + /// In older implementations, which ignore the locales and options arguments, + /// the locale used and the form of the string + /// returned are entirely implementation dependent. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString + #[wasm_bindgen(method, js_name = toLocaleDateString)] + pub fn to_locale_date_string(this: &Date, locale: JsString, options: JsValue) -> JsString; + + /// The toLocaleString() method returns a string with a language sensitive + /// representation of this date. The new locales and options arguments + /// let applications specify the language whose formatting conventions + /// should be used and customize the behavior of the function. + /// In older implementations, which ignore the locales + /// and options arguments, the locale used and the form of the string + /// returned are entirely implementation dependent. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString + #[wasm_bindgen(method, js_name = toLocaleString)] + pub fn to_locale_string(this: &Date, locale: JsString, options: JsValue) -> JsString; + + /// The toLocaleTimeString() method returns a string with a language sensitive + /// representation of the time portion of this date. The new locales and options + /// arguments let applications specify the language whose formatting conventions should be + /// used and customize the behavior of the function. In older implementations, which ignore + /// the locales and options arguments, the locale used and the form of the string + /// returned are entirely implementation dependent. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString + #[wasm_bindgen(method, js_name = toLocaleTimeString)] + pub fn to_locale_time_string(this: &Date, locale: JsString) -> JsString; + + /// The toString() method returns a string representing + /// the specified Date object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toString + #[wasm_bindgen(method, js_name = toString)] + pub fn to_string(this: &Date) -> JsString; + + /// The toTimeString() method returns the time portion of a Date object in human + /// readable form in American English. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toTimeString + #[wasm_bindgen(method, js_name = toTimeString)] + pub fn to_time_string(this: &Date) -> JsString; + + /// The toUTCString() method converts a date to a string, + /// using the UTC time zone. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toUTCString + #[wasm_bindgen(method, js_name = toUTCString)] + pub fn to_utc_string(this: &Date) -> JsString; + + /// The valueOf() method returns the primitive value of + /// a Date object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/valueOf + #[wasm_bindgen(method, js_name = valueOf)] + pub fn value_of(this: &Date) -> Date; +} + // Object. #[wasm_bindgen] extern { @@ -412,6 +530,14 @@ extern { #[wasm_bindgen(method, js_name = propertyIsEnumerable)] pub fn property_is_enumerable(this: &Object, property: &JsValue) -> bool; + /// The Object.seal() method seals an object, preventing new properties + /// from being added to it and marking all existing properties as non-configurable. + /// Values of present properties can still be changed as long as they are writable. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal + #[wasm_bindgen(static_method_of = Object)] + pub fn seal(value: &JsValue) -> JsValue; + /// The toLocaleString() method returns a string representing the object. /// This method is meant to be overridden by derived objects for /// locale-specific purposes. @@ -447,6 +573,15 @@ extern { #[wasm_bindgen(method, js_class = "String", js_name = charAt)] pub fn char_at(this: &JsString, index: u32) -> JsString; + /// The charCodeAt() method returns an integer between 0 and 65535 representing the UTF-16 code unit at + /// the given index (the UTF-16 code unit matches the Unicode code point for code points representable in + /// a single UTF-16 code unit, but might also be the first code unit of a surrogate pair for + /// 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(). + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt + #[wasm_bindgen(method, js_class = "String", js_name = charCodeAt)] + pub fn char_code_at(this: &JsString, index: u32) -> Number; /// The concat() method concatenates the string arguments to the calling string and returns a new string. /// @@ -454,6 +589,12 @@ extern { #[wasm_bindgen(method, js_class = "String")] pub fn concat(this: &JsString, string_2: &JsString) -> JsString; + /// The includes() method determines whether one string may be found within another string, returning true or false as appropriate. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes + #[wasm_bindgen(method, js_class = "String")] + pub fn includes(this: &JsString, search_string: &JsString, position: i32) -> bool; + /// The indexOf() method returns the index within the calling String object of /// the first occurrence of the specified value, starting the search at fromIndex. /// Returns -1 if the value is not found. @@ -461,7 +602,7 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf #[wasm_bindgen(method, js_class = "String", js_name = indexOf)] pub fn index_of(this: &JsString, search_value: &JsString, from_index: i32) -> i32; - + /// The slice() method extracts a section of a string and returns it as a /// new string, without modifying the original string. /// diff --git a/tests/all/js_globals/Date.rs b/tests/all/js_globals/Date.rs new file mode 100644 index 00000000..82ed7009 --- /dev/null +++ b/tests/all/js_globals/Date.rs @@ -0,0 +1,306 @@ +#![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::Date; + + #[wasm_bindgen] + pub fn new_date() -> Date { + Date::new() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(typeof wasm.new_date(), "object"); + } + "#) + .test() +} + +#[test] +fn to_date_string() { + 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, JsString}; + + #[wasm_bindgen] + pub fn to_date_string(this: &Date) -> JsString { + this.to_date_string() + } + "#) + .file("test.ts", 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.to_date_string(date), 'Wed Jul 28 1993'); + } + "#) + .test() +} + +#[test] +fn to_iso_string() { + 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, JsString}; + + #[wasm_bindgen] + pub fn to_iso_string(this: &Date) -> JsString { + this.to_iso_string() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let date = new Date('05 October 2011 14:48 UTC'); + + assert.equal(wasm.to_iso_string(date), '2011-10-05T14:48:00.000Z'); + } + "#) + .test() +} + +#[test] +fn to_json() { + 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, JsString}; + + #[wasm_bindgen] + pub fn to_json(this: &Date) -> JsString { + this.to_json() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let date = new Date('August 19, 1975 23:15:30 UTC'); + + assert.equal(wasm.to_json(date), '1975-08-19T23:15:30.000Z'); + } + "#) + .test() +} + +#[test] +fn to_locale_date_string() { + 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::{Date, JsString}; + + #[wasm_bindgen] + pub fn to_locale_date_string(this: &Date, locale: JsString, options: JsValue) -> JsString { + this.to_locale_date_string(locale, options) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0)); + 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'); + } + "#) + .test() +} + +#[test] +fn to_locale_string() { + 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::{Date, JsString}; + + #[wasm_bindgen] + pub fn to_locale_string(this: &Date, locale: JsString, options: JsValue) -> JsString { + this.to_locale_string(locale, options) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + 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"); + } + "#) + .test() +} + +#[test] +fn to_locale_time_string() { + 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, JsString}; + + #[wasm_bindgen] + pub fn to_locale_time_string(this: &Date, locale: JsString) -> JsString { + this.to_locale_time_string(locale) + } + "#) + .file("test.ts", 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.to_locale_time_string(date, 'en-US'), "11:15:30 PM"); + } + "#) + .test() +} + +#[test] +fn to_string() { + 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, JsString}; + + #[wasm_bindgen] + pub fn to_string(this: &Date) -> JsString { + this.to_string() + } + "#) + .file("test.ts", 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.to_string(date).substring(0, 15), "Tue Aug 19 1975"); + } + "#) + .test() +} + +#[test] +fn to_time_string() { + 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, JsString}; + + #[wasm_bindgen] + pub fn to_time_string(this: &Date) -> JsString { + this.to_time_string() + } + "#) + .file("test.ts", 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.to_time_string(date).substring(0, 8), "23:15:30"); + } + "#) + .test() +} + +#[test] +fn to_utc_string() { + 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, JsString}; + + #[wasm_bindgen] + pub fn to_utc_string(this: &Date) -> JsString { + this.to_utc_string() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let date = new Date('14 Jun 2017 00:00:00 PDT'); + assert.equal(wasm.to_utc_string(date), "Wed, 14 Jun 2017 07:00:00 GMT"); + } + "#) + .test() +} + +#[test] +fn value_of() { + 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 js_value_of(this: &Date) -> Date { + this.value_of() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let date = new Date(Date.UTC(96, 1, 2, 3, 4, 5)); + assert.equal(wasm.js_value_of(date), 823230245000); + } + "#) + .test() +} diff --git a/tests/all/js_globals/JsString.rs b/tests/all/js_globals/JsString.rs index ea302e54..124d7db8 100644 --- a/tests/all/js_globals/JsString.rs +++ b/tests/all/js_globals/JsString.rs @@ -63,6 +63,35 @@ fn concat() { .test() } +#[test] +fn char_code_at() { + 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 string_char_code_at(this: &js::JsString, index: u32) -> js::Number { + this.char_code_at(index) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + var anyString = 'Brave new world'; + + export function test() { + assert.equal(wasm.string_char_code_at(anyString, 0), 66); + assert.ok(isNaN(wasm.string_char_code_at(anyString, 999))); + } + "#) + .test() +} + #[test] fn starts_with() { project() @@ -236,3 +265,38 @@ fn substr() { "#) .test() } + +#[test] +fn includes() { + 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 string_includes(this: &js::JsString, search_value: &js::JsString, position: i32) -> bool { + this.includes(search_value, position) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let str = "Blue Whale"; + + // TODO: remove second parameter once we have optional parameters + assert.equal(wasm.string_includes(str, 'Blue', 0), true); + assert.equal(wasm.string_includes(str, 'Blute', 0), false); + assert.equal(wasm.string_includes(str, 'Whale', 0), true); + assert.equal(wasm.string_includes(str, 'Whale', 5), true); + assert.equal(wasm.string_includes(str, 'Whale', 7), false); + assert.equal(wasm.string_includes(str, '', 0), true); + assert.equal(wasm.string_includes(str, '', 16), true); + } + "#) + .test() +} diff --git a/tests/all/js_globals/Object.rs b/tests/all/js_globals/Object.rs index 2ca6a093..48526636 100755 --- a/tests/all/js_globals/Object.rs +++ b/tests/all/js_globals/Object.rs @@ -185,6 +185,57 @@ fn property_is_enumerable() { .test() } +#[test] +fn seal() { + 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 seal(value: &JsValue) -> JsValue { + js::Object::seal(&value) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const object: any = { foo: 'bar' }; + const sealedObject = wasm.seal(object); + assert.strictEqual(object, sealedObject); + assert.throws(() => { + 'use strict'; + sealedObject.bar = 'foo'; + }, TypeError); + assert.throws(() => { + 'use strict'; + delete sealedObject.foo; + }, TypeError); + + const primitive = 42; + assert.doesNotThrow(() => { + 'use strict'; + // according to ES2015, this should not throw anymore + // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal#Notes + wasm.seal(primitive); + }); + + const array = [1, 2, 3]; + const sealedArray = wasm.seal(array); + assert.throws(() => { + 'use strict'; + sealedArray.push(42); + }, TypeError); + } + "#) + .test() +} + #[test] fn to_locale_string() { project() diff --git a/tests/all/js_globals/TypedArray.rs b/tests/all/js_globals/TypedArray.rs new file mode 100644 index 00000000..139c4371 --- /dev/null +++ b/tests/all/js_globals/TypedArray.rs @@ -0,0 +1,85 @@ +#![allow(non_snake_case)] + +use project; + +#[test] +fn new_undefined() { + 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_array() -> js::Uint8Array { + js::Uint8Array::new(JsValue::undefined()) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.new_array().length, 0); + } + "#) + .test() +} + +#[test] +fn new_length() { + 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_array() -> js::Uint8Array { + js::Uint8Array::new(JsValue::from_f64(4.0)) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.new_array().length, 4); + } + "#) + .test() +} + +#[test] +fn fill() { + 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 fill_with(this: &js::Uint8Array, value: JsValue, start: u32, end: u32) -> js::Uint8Array { + this.fill(value, start, end) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let characters = new Uint8Array([0, 0, 0, 0, 0, 0]); + let subset = wasm.fill_with(characters, 1, 0, 3); + + assert.equal(subset[0], 1); + assert.equal(subset[4], 0); + } + "#) + .test() +} diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs index 3fd54d80..32066801 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -2,13 +2,15 @@ use super::project; -mod Object; mod Array; mod ArrayIterator; +mod Date; mod JsFunction; mod JsString; -mod Number; mod Math; +mod Number; +mod Object; +mod TypedArray; #[test] #[cfg(feature = "std")]