diff --git a/src/js.rs b/src/js.rs index 4e090c74..0c9d33d5 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. @@ -511,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. @@ -546,6 +573,16 @@ 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 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. @@ -554,6 +591,12 @@ extern { #[wasm_bindgen(method, js_class = "String", js_name = indexOf)] pub fn index_of(this: &JsString, search_value: &JsString, from_index: i32) -> i32; + /// 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 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/JsString.rs b/tests/all/js_globals/JsString.rs index 9bfe0ba4..c154895d 100644 --- a/tests/all/js_globals/JsString.rs +++ b/tests/all/js_globals/JsString.rs @@ -31,6 +31,35 @@ fn char_at() { .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() @@ -204,3 +233,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 2cb35783..32066801 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -2,14 +2,15 @@ use super::project; -mod Object; mod Array; mod ArrayIterator; +mod Date; mod JsFunction; mod JsString; -mod Number; mod Math; -mod Date; +mod Number; +mod Object; +mod TypedArray; #[test] #[cfg(feature = "std")]