diff --git a/src/js.rs b/src/js.rs index c00ba6c32..6e4500608 100644 --- a/src/js.rs +++ b/src/js.rs @@ -566,6 +566,13 @@ extern { #[wasm_bindgen(js_name = JsString)] pub type JsString; + /// The length property of a String object indicates the length of a string, + /// in UTF-16 code units. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length + #[wasm_bindgen(method, getter, structural)] + pub fn length(this: &JsString) -> u32; + /// The String object's charAt() method returns a new string consisting of the single /// UTF-16 code unit located at the specified offset into the string. /// @@ -636,6 +643,42 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr #[wasm_bindgen(method, js_class = "String")] pub fn substr(this: &JsString, start: i32, length: i32) -> JsString; + + /// The trim() method removes whitespace from both ends of a string. + /// Whitespace in this context is all the whitespace characters + /// (space, tab, no-break space, etc.) and all the line terminator characters (LF, CR, etc.). + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim + #[wasm_bindgen(method, js_class = "String")] + pub fn trim(this: &JsString) -> JsString; + + /// The trimEnd() method removes whitespace from the end of a string. + /// trimRight() is an alias of this method. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd + #[wasm_bindgen(method, js_class = "String", js_name = trimEnd)] + pub fn trim_end(this: &JsString) -> JsString; + + /// The trimEnd() method removes whitespace from the end of a string. + /// trimRight() is an alias of this method. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd + #[wasm_bindgen(method, js_class = "String", js_name = trimRight)] + pub fn trim_right(this: &JsString) -> JsString; + + /// The trimStart() method removes whitespace from the beginning of a string. + /// trimLeft() is an alias of this method. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimStart + #[wasm_bindgen(method, js_class = "String", js_name = trimStart)] + pub fn trim_start(this: &JsString) -> JsString; + + /// The trimStart() method removes whitespace from the beginning of a string. + /// trimLeft() is an alias of this method. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimStart + #[wasm_bindgen(method, js_class = "String", js_name = trimLeft)] + pub fn trim_left(this: &JsString) -> JsString; } impl<'a> From<&'a str> for JsString { diff --git a/tests/all/js_globals/JsString.rs b/tests/all/js_globals/JsString.rs index 895247515..190adf9e6 100644 --- a/tests/all/js_globals/JsString.rs +++ b/tests/all/js_globals/JsString.rs @@ -2,6 +2,37 @@ use project; +#[test] +fn 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 string_length(this: &js::JsString) -> u32 { + this.length() + } + + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let x = 'Mozilla'; + assert.equal(wasm.string_length(x), 7); + + let empty = ''; + assert.equal(wasm.string_length(empty), 0); + } + "#) + .test() +} + #[test] fn char_at() { project() @@ -31,6 +62,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 code_point_at() { project() @@ -90,9 +150,9 @@ fn concat() { "#) .test() } - + #[test] -fn char_code_at() { +fn includes() { project() .file("src/lib.rs", r#" #![feature(proc_macro, wasm_custom_section)] @@ -102,37 +162,8 @@ fn char_code_at() { 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() - .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_starts_with(this: &js::JsString, search_string: &js::JsString, position: u32) -> bool { - this.starts_with(search_string, position) + pub fn string_includes(this: &js::JsString, search_value: &js::JsString, position: i32) -> bool { + this.includes(search_value, position) } "#) .file("test.ts", r#" @@ -140,51 +171,16 @@ fn starts_with() { import * as wasm from "./out"; export function test() { - let str = "To be, or not to be, that is the question."; + let str = "Blue Whale"; - // TODO: remove second parameter for both assertions once we have optional parameters - assert.ok(wasm.string_starts_with(str, 'To be', 0)); - assert.ok(!wasm.string_starts_with(str, 'not to be', 0)); - assert.ok(wasm.string_starts_with(str, 'not to be', 10)); - } - "#) - .test() -} - -#[test] -fn substring() { - 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_substring(this: &js::JsString, index_start: u32, index_end: u32) -> js::JsString { - this.substring(index_start, index_end) - } - "#) - .file("test.ts", r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - let anyString = "Mozilla"; - - assert.equal(wasm.string_substring(anyString, 0, 1), 'M'); - assert.equal(wasm.string_substring(anyString, 1, 0), 'M'); - - assert.equal(wasm.string_substring(anyString, 0, 6), 'Mozill'); - - // TODO: Add test once we have optional parameters - // assert.equal(wasm.string_substring(anyString, 4), 'lla'); - assert.equal(wasm.string_substring(anyString, 4, 7), 'lla'); - assert.equal(wasm.string_substring(anyString, 7, 4), 'lla'); - - assert.equal(wasm.string_substring(anyString, 0, 7), 'Mozilla'); - assert.equal(wasm.string_substring(anyString, 0, 10), 'Mozilla'); + // 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() @@ -258,6 +254,76 @@ fn slice() { .test() } +#[test] +fn starts_with() { + 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_starts_with(this: &js::JsString, search_string: &js::JsString, position: u32) -> bool { + this.starts_with(search_string, position) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let str = "To be, or not to be, that is the question."; + + // TODO: remove second parameter for both assertions once we have optional parameters + assert.ok(wasm.string_starts_with(str, 'To be', 0)); + assert.ok(!wasm.string_starts_with(str, 'not to be', 0)); + assert.ok(wasm.string_starts_with(str, 'not to be', 10)); + } + "#) + .test() +} + +#[test] +fn substring() { + 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_substring(this: &js::JsString, index_start: u32, index_end: u32) -> js::JsString { + this.substring(index_start, index_end) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let anyString = "Mozilla"; + + assert.equal(wasm.string_substring(anyString, 0, 1), 'M'); + assert.equal(wasm.string_substring(anyString, 1, 0), 'M'); + + assert.equal(wasm.string_substring(anyString, 0, 6), 'Mozill'); + + // TODO: Add test once we have optional parameters + // assert.equal(wasm.string_substring(anyString, 4), 'lla'); + assert.equal(wasm.string_substring(anyString, 4, 7), 'lla'); + assert.equal(wasm.string_substring(anyString, 7, 4), 'lla'); + + assert.equal(wasm.string_substring(anyString, 0, 7), 'Mozilla'); + assert.equal(wasm.string_substring(anyString, 0, 10), 'Mozilla'); + } + "#) + .test() +} + #[test] fn substr() { project() @@ -295,7 +361,7 @@ fn substr() { } #[test] -fn includes() { +fn trim() { project() .file("src/lib.rs", r#" #![feature(proc_macro, wasm_custom_section)] @@ -305,8 +371,8 @@ fn includes() { 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) + pub fn string_trim(this: &js::JsString) -> js::JsString { + this.trim() } "#) .file("test.ts", r#" @@ -314,17 +380,78 @@ fn includes() { 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); + assert.equal(wasm.string_trim(' foo '), 'foo'); + // Another example of .trim() removing whitespace from just one side. + assert.equal(wasm.string_trim('foo '), 'foo'); } "#) .test() } + +#[test] +fn trim_end_and_trim_right() { + 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_trim_end(this: &js::JsString) -> js::JsString { + this.trim_end() + } + + #[wasm_bindgen] + pub fn string_trim_right(this: &js::JsString) -> js::JsString { + this.trim_right() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let greeting = ' Hello world! '; + let trimmed = ' Hello world!'; + assert.equal(wasm.string_trim_end(greeting), trimmed); + assert.equal(wasm.string_trim_right(greeting), trimmed); + } + "#) + .test() +} + +#[test] +fn trim_start_and_trim_left() { + 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_trim_start(this: &js::JsString) -> js::JsString { + this.trim_start() + } + + #[wasm_bindgen] + pub fn string_trim_left(this: &js::JsString) -> js::JsString { + this.trim_left() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let greeting = ' Hello world! '; + let trimmed = 'Hello world! '; + assert.equal(wasm.string_trim_start(greeting), trimmed); + assert.equal(wasm.string_trim_left(greeting), trimmed); + } + "#) + .test() +} \ No newline at end of file