From f3e34d854d4dbab062f5bcba4a59d2d9d02588d2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 20 Jul 2018 13:35:46 -0700 Subject: [PATCH] Port `JsString` tests to `wasm` --- crates/js-sys/src/lib.rs | 33 +- crates/js-sys/tests/all/JsString.rs | 918 --------------------------- crates/js-sys/tests/all/main.rs | 1 - crates/js-sys/tests/wasm/JsString.rs | 263 ++++++++ crates/js-sys/tests/wasm/main.rs | 1 + 5 files changed, 296 insertions(+), 920 deletions(-) delete mode 100644 crates/js-sys/tests/all/JsString.rs create mode 100644 crates/js-sys/tests/wasm/JsString.rs diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index dd752fb1..84f90ebe 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -22,6 +22,7 @@ extern crate wasm_bindgen; use std::mem; +use std::fmt; use wasm_bindgen::prelude::*; @@ -2224,7 +2225,7 @@ extern "C" { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat #[wasm_bindgen(method, js_class = "String")] - pub fn concat(this: &JsString, string_2: &JsString) -> JsString; + pub fn concat(this: &JsString, string_2: &JsValue) -> JsString; /// The endsWith() method determines whether a string ends with the characters of a /// specified string, returning true or false as appropriate. @@ -2411,6 +2412,30 @@ impl JsString { } } +impl PartialEq for JsString { + fn eq(&self, other: &str) -> bool { + String::from(self) == other + } +} + +impl<'a> PartialEq<&'a str> for JsString { + fn eq(&self, other: &&'a str) -> bool { + >::eq(self, other) + } +} + +impl PartialEq for JsString { + fn eq(&self, other: &String) -> bool { + >::eq(self, other) + } +} + +impl<'a> PartialEq<&'a String> for JsString { + fn eq(&self, other: &&'a String) -> bool { + >::eq(self, other) + } +} + impl<'a> From<&'a str> for JsString { fn from(s: &'a str) -> Self { JsString { @@ -2437,6 +2462,12 @@ impl From for String { } } +impl fmt::Debug for JsString { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + String::from(self).fmt(f) + } +} + // Symbol #[wasm_bindgen] extern "C" { diff --git a/crates/js-sys/tests/all/JsString.rs b/crates/js-sys/tests/all/JsString.rs deleted file mode 100644 index 53041ae6..00000000 --- a/crates/js-sys/tests/all/JsString.rs +++ /dev/null @@ -1,918 +0,0 @@ -#![allow(non_snake_case)] - -use project; - -#[test] -fn length() { - project() - .file( - "src/lib.rs", - r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_length(this: &js_sys::JsString) -> u32 { - this.length() - } - - "#, - ) - .file( - "test.js", - 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() - .file( - "src/lib.rs", - r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_char_at(this: &js_sys::JsString, index: u32) -> js_sys::JsString { - this.char_at(index) - } - "#, - ) - .file( - "test.js", - r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - var anyString = 'Brave new world'; - - export function test() { - assert.equal(wasm.string_char_at(anyString, 0), "B"); - assert.equal(wasm.string_char_at(anyString, 999), ""); - } - "#, - ) - .test() -} - -#[test] -fn char_code_at() { - project() - .file( - "src/lib.rs", - r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_char_code_at(this: &js_sys::JsString, index: u32) -> f64 { - this.char_code_at(index) - } - "#, - ) - .file( - "test.js", - r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - var anyString = 'Brave new world'; - - export function test() { - for (let i = 0; i < anyString.length; i++) { - assert.equal(wasm.string_char_code_at(anyString, i), - anyString.charCodeAt(i), - `charCodeAt(${i})`); - } - - const outOfBounds = wasm.string_char_code_at(anyString, 999); - assert.ok(Number.isNaN(outOfBounds)); - } - "#, - ) - .test() -} - -#[test] -fn code_point_at() { - project() - .file( - "src/lib.rs", - r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_code_point_at(this: &js_sys::JsString, pos: u32) -> JsValue { - this.code_point_at(pos) - } - "#, - ) - .file( - "test.js", - r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - assert.equal(wasm.string_code_point_at('ABC', 1), 66); - assert.equal(wasm.string_code_point_at('\uD800\uDC00', 0), 65536); - assert.equal(wasm.string_code_point_at('XYZ', 42), undefined); - } - "#, - ) - .test() -} - -#[test] -fn concat() { - project() - .file( - "src/lib.rs", - r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_concat(this: &js_sys::JsString, string_2: &js_sys::JsString) -> js_sys::JsString { - this.concat(string_2) - } - "#, - ) - .file( - "test.js", - r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - // TODO: Implement ability to receive multiple optional arguments - assert.equal(wasm.string_concat('Hello ', 'World'), 'Hello World'); - assert.equal(wasm.string_concat('foo', {}), 'foo[object Object]'); - assert.equal(wasm.string_concat('foo', []), 'foo'); - assert.equal(wasm.string_concat('foo', null), 'foonull'); - assert.equal(wasm.string_concat('foo', true), 'footrue'); - assert.equal(wasm.string_concat('foo', 1234), 'foo1234'); - } - "#, - ) - .test() -} - -#[test] -fn ends_with() { - project() - .file("src/lib.rs", r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn ends_with(this: &js_sys::JsString, search_value: &js_sys::JsString, length: i32) -> bool { - this.ends_with(search_value, length) - } - "#) - .file("test.js", 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."; - let len = str.length; - - // TODO: remove third parameter once we have optional parameters - assert.equal(wasm.ends_with(str, "question.", len), true); - assert.equal(wasm.ends_with(str, "to be", len), false); - assert.equal(wasm.ends_with(str, "to be", 19), true); - } - "#) - .test() -} - -#[test] -fn includes() { - project() - .file("src/lib.rs", r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_includes(this: &js_sys::JsString, search_value: &js_sys::JsString, position: i32) -> bool { - this.includes(search_value, position) - } - "#) - .file("test.js", 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() -} - -#[test] -fn index_of() { - project() - .file("src/lib.rs", r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_index_of(this: &js_sys::JsString, search_value: &js_sys::JsString, from_index: i32) -> i32 { - this.index_of(search_value, from_index) - } - "#) - .file("test.js", 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_index_of(str, 'Blue', 0), 0); - // TODO: remove second parameter once we have optional parameters - assert.equal(wasm.string_index_of(str, 'Blute', 0), -1); - assert.equal(wasm.string_index_of(str, 'Whale', 0), 5); - assert.equal(wasm.string_index_of(str, 'Whale', 5), 5); - assert.equal(wasm.string_index_of(str, 'Whale', 7), -1); - // TODO: remove second parameter once we have optional parameters - assert.equal(wasm.string_index_of(str, '', 0), 0); - assert.equal(wasm.string_index_of(str, '', 9), 9); - assert.equal(wasm.string_index_of(str, '', 10), 10); - assert.equal(wasm.string_index_of(str, '', 11), 10); - } - "#) - .test() -} - -#[test] -fn last_index_of() { - project() - .file("src/lib.rs", r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_last_index_of(this: &js_sys::JsString, search_value: &js_sys::JsString, from_index: i32) -> i32 { - this.last_index_of(search_value, from_index) - } - "#) - .file("test.js", r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - let str = "canal"; - let len = str.length; - - // TODO: remove second parameter once we have optional parameters - assert.equal(wasm.string_last_index_of(str, 'a', len), 3); - assert.equal(wasm.string_last_index_of(str, 'a', 2), 1); - assert.equal(wasm.string_last_index_of(str, 'a', 0), -1); - // TODO: remove second parameter once we have optional parameters - assert.equal(wasm.string_last_index_of(str, 'x', len), -1); - assert.equal(wasm.string_last_index_of(str, 'c', -5), 0); - assert.equal(wasm.string_last_index_of(str, 'c', 0), 0); - // TODO: remove second parameter once we have optional parameters - assert.equal(wasm.string_last_index_of(str, '', len), 5); - assert.equal(wasm.string_last_index_of(str, '', 2), 2); - } - "#) - .test() -} - -#[test] -fn normalize() { - project() - .file("src/lib.rs", r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_normalize(this: &js_sys::JsString, form: &js_sys::JsString) -> js_sys::JsString { - this.normalize(form) - } - "#) - .file("test.js", r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - let str = "\u1E9B\u0323"; - - // TODO: Handle undefined - assert.equal(wasm.string_normalize(str, "NFC"), "\u1E9B\u0323"); - assert.equal(wasm.string_normalize(str, "NFD"), "\u017F\u0323\u0307"); - assert.equal(wasm.string_normalize(str, "NFKC"), "\u1E69"); - assert.equal(wasm.string_normalize(str, "NFKD"), "\u0073\u0323\u0307"); - } - "#) - .test() -} - -#[test] -fn pad_end() { - project() - .file("src/lib.rs", r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_pad_end( - this: &js_sys::JsString, - target_length: u32, - pad_string: &js_sys::JsString - ) -> js_sys::JsString - { - this.pad_end(target_length, pad_string) - } - "#) - .file("test.js", r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - let str = "abc"; - - // TODO: remove second parameter once we have optional parameters - assert.equal(wasm.string_pad_end(str, 10, " "), "abc "); - // TODO: remove second parameter once we have optional parameters - assert.equal(wasm.string_pad_end(str, 10, " "), "abc "); - assert.equal(wasm.string_pad_end(str, 10, "foo"), "abcfoofoof"); - assert.equal(wasm.string_pad_end(str, 6, "123456"), "abc123"); - // TODO: remove second parameter once we have optional parameters - assert.equal(wasm.string_pad_end(str, 1, " "), "abc"); - } - "#) - .test() -} - -#[test] -fn pad_start() { - project() - .file("src/lib.rs", r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_pad_start( - this: &js_sys::JsString, - target_length: u32, - pad_string: &js_sys::JsString - ) -> js_sys::JsString - { - this.pad_start(target_length, pad_string) - } - "#) - .file("test.js", r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - let str = "abc"; - - // TODO: remove second parameter once we have optional parameters - assert.equal(wasm.string_pad_start(str, 10, " "), " abc"); - assert.equal(wasm.string_pad_start(str, 10, "foo"), "foofoofabc"); - assert.equal(wasm.string_pad_start(str, 6, "123465"), "123abc"); - assert.equal(wasm.string_pad_start(str, 8, "0"), "00000abc"); - // TODO: remove second parameter once we have optional parameters - assert.equal(wasm.string_pad_start(str, 1, " "), "abc"); - } - "#) - .test() -} - -#[test] -fn repeat() { - project() - .file( - "src/lib.rs", - r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_repeat(this: &js_sys::JsString, count: i32) -> js_sys::JsString { - this.repeat(count) - } - "#, - ) - .file( - "test.js", - r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - let str = "test"; - assert.equal(wasm.string_repeat(str, 3), "testtesttest"); - } - "#, - ) - .test() -} - -#[test] -fn slice() { - project() - .file( - "src/lib.rs", - r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn create_slice(this: &js_sys::JsString, start: u32, end: u32) -> js_sys::JsString { - this.slice(start, end) - } - "#, - ) - .file( - "test.js", - r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - let characters = "acxn18"; - let subset = wasm.create_slice(characters, 1, 3); - - assert.equal(subset, "cx"); - } - "#, - ) - .test() -} - -#[test] -fn starts_with() { - project() - .file("src/lib.rs", r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_starts_with(this: &js_sys::JsString, search_string: &js_sys::JsString, position: u32) -> bool { - this.starts_with(search_string, position) - } - "#) - .file("test.js", 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(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_substring(this: &js_sys::JsString, index_start: u32, index_end: u32) -> js_sys::JsString { - this.substring(index_start, index_end) - } - "#) - .file("test.js", 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() - .file("src/lib.rs", r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn create_substr(this: &js_sys::JsString, start: i32, length: i32) -> js_sys::JsString { - this.substr(start, length) - } - "#) - .file("test.js", r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - let aString = "Mozilla"; - - assert.equal(wasm.create_substr(aString, 0, 1), "M"); - assert.equal(wasm.create_substr(aString, 1, 0), ""); - assert.equal(wasm.create_substr(aString, -1, 1), "a"); - assert.equal(wasm.create_substr(aString, 1, -1), ""); - // TODO: Uncomment and test these assertions, once we have support for optional parameters - // assert.equal(wasm.create_substr(aString, -3), "lla"); - // assert.equal(wasm.create_substr(aString, 1), "ozilla"); - assert.equal(wasm.create_substr(aString, -20, 2), "Mo"); - assert.equal(wasm.create_substr(aString, 20, 2), ""); - } - "#) - .test() -} - -#[test] -fn to_locale_lower_case() { - project() - .file( - "src/lib.rs", - r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_to_locale_lower_case(this: &js_sys::JsString, local: Option) -> js_sys::JsString { - this.to_locale_lower_case(local) - } - "#, - ) - .file( - "test.js", - r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - assert.equal(wasm.string_to_locale_lower_case("Mozilla"), "mozilla"); - assert.equal(wasm.string_to_locale_lower_case("\u0130", "tr"), "i"); - assert.notStrictEqual(wasm.string_to_locale_lower_case("\u0130", "en-US"), "i"); - } - "#, - ) - .test() -} - -#[test] -fn to_locale_upper_case() { - project() - .file( - "src/lib.rs", - r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_to_locale_upper_case(this: &js_sys::JsString, local: Option) -> js_sys::JsString { - this.to_locale_upper_case(local) - } - "#, - ) - .file( - "test.js", - r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - assert.equal(wasm.string_to_locale_upper_case("mozilla"), "MOZILLA"); - assert.equal(wasm.string_to_locale_upper_case("i\u0307", "lt"), "I"); - assert.notStrictEqual(wasm.string_to_locale_upper_case("i\u0307", "en-US"), "I"); - } - "#, - ) - .test() -} - -#[test] -fn to_lower_case() { - project() - .file("src/lib.rs", r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_to_lower_case(this: &js_sys::JsString) -> js_sys::JsString { - this.to_lower_case() - } - "#) - .file("test.js", r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - assert.equal(wasm.string_to_lower_case("Mozilla"), "mozilla"); - } - "#) - .test() -} - -#[test] -fn to_string() { - project() - .file( - "src/lib.rs", - r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_to_string(this: &js_sys::JsString) -> js_sys::JsString { - this.to_string() - } - "#, - ) - .file( - "test.js", - r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - let greeting = 'Hello world!'; - assert.equal(wasm.string_to_string(greeting), 'Hello world!'); - } - "#, - ) - .test() -} - -#[test] -fn to_upper_case() { - project() - .file("src/lib.rs", r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_to_upper_case(this: &js_sys::JsString) -> js_sys::JsString { - this.to_upper_case() - } - "#) - .file("test.js", r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - assert.equal(wasm.string_to_upper_case("Mozilla"), "MOZILLA"); - } - "#) - .test() -} - -#[test] -fn trim() { - project() - .file( - "src/lib.rs", - r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_trim(this: &js_sys::JsString) -> js_sys::JsString { - this.trim() - } - "#, - ) - .file( - "test.js", - r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - 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(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_trim_end(this: &js_sys::JsString) -> js_sys::JsString { - this.trim_end() - } - - #[wasm_bindgen] - pub fn string_trim_right(this: &js_sys::JsString) -> js_sys::JsString { - this.trim_right() - } - "#, - ) - .file( - "test.js", - 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(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_trim_start(this: &js_sys::JsString) -> js_sys::JsString { - this.trim_start() - } - - #[wasm_bindgen] - pub fn string_trim_left(this: &js_sys::JsString) -> js_sys::JsString { - this.trim_left() - } - "#, - ) - .file( - "test.js", - 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() -} - -#[test] -fn value_of() { - project() - .file( - "src/lib.rs", - r#" - #![feature(use_extern_macros)] - - extern crate wasm_bindgen; - extern crate js_sys; - use wasm_bindgen::prelude::*; - - #[wasm_bindgen] - pub fn string_value_of(this: &js_sys::JsString) -> js_sys::JsString { - this.value_of() - } - "#, - ) - .file( - "test.js", - r#" - import * as assert from "assert"; - import * as wasm from "./out"; - - export function test() { - let greeting = new String('Hello world!'); - assert.equal(wasm.string_value_of(greeting), 'Hello world!'); - } - "#, - ) - .test() -} diff --git a/crates/js-sys/tests/all/main.rs b/crates/js-sys/tests/all/main.rs index fafd6db9..a50ee833 100644 --- a/crates/js-sys/tests/all/main.rs +++ b/crates/js-sys/tests/all/main.rs @@ -11,7 +11,6 @@ fn project() -> project_builder::Project { // Keep these tests in alphabetical order, just like the imports in `src/js.rs`. mod ArrayIterator; -mod JsString; mod Map; mod MapIterator; mod Math; diff --git a/crates/js-sys/tests/wasm/JsString.rs b/crates/js-sys/tests/wasm/JsString.rs new file mode 100644 index 00000000..4f610731 --- /dev/null +++ b/crates/js-sys/tests/wasm/JsString.rs @@ -0,0 +1,263 @@ +use wasm_bindgen::JsValue; +use wasm_bindgen_test::*; +use js_sys::*; + +#[wasm_bindgen_test] +fn length() { + fn test(s: &str) { + assert_eq!(JsString::from(s).length(), s.len() as u32); + } + test("Mozilla"); + test(""); +} + +#[wasm_bindgen_test] +fn char_at() { + let s = JsString::from("Brave new world"); + assert_eq!(JsValue::from(s.char_at(0)), "B"); + assert_eq!(JsValue::from(s.char_at(999)), ""); +} + +#[wasm_bindgen_test] +fn char_code_at() { + let s = "Brave new world"; + let js = JsString::from(s); + for (i, b) in s.char_indices() { + assert_eq!(js.char_code_at(i as u32), b as u32 as f64); + } + assert!(js.char_code_at(s.len() as u32).is_nan()); +} + +#[wasm_bindgen_test] +fn code_point_at() { + assert_eq!(JsString::from("ABC").code_point_at(1), b'B'); + assert!(JsString::from("ABC").code_point_at(42).is_undefined()); +} + +#[wasm_bindgen_test] +fn concat() { + // TODO: Implement ability to receive multiple optional arguments + let s = JsString::from("Hello ").concat(&"World".into()); + assert_eq!(JsValue::from(s), "Hello World"); + let foo = JsString::from("foo"); + assert_eq!(JsValue::from(foo.concat(&Object::new().into())), "foo[object Object]"); + assert_eq!(JsValue::from(foo.concat(&Array::new().into())), "foo"); + assert_eq!(JsValue::from(foo.concat(&JsValue::null())), "foonull"); + assert_eq!(JsValue::from(foo.concat(&true.into())), "footrue"); + assert_eq!(JsValue::from(foo.concat(&1234.into())), "foo1234"); +} + +#[wasm_bindgen_test] +fn ends_with() { + let s = "To be, or not to be, that is the question."; + let js = JsString::from(s); + + // TODO: remove third parameter once we have optional parameters + assert_eq!(js.ends_with(&"question.".into(), s.len() as i32), true); + assert_eq!(js.ends_with(&"to be".into(), s.len() as i32), false); + assert_eq!(js.ends_with(&"to be".into(), 19), true); +} + +#[wasm_bindgen_test] +fn includes() { + let str = JsString::from("Blue Whale"); + + // TODO: remove second parameter once we have optional parameters + assert_eq!(str.includes(&"Blue".into(), 0), true); + assert_eq!(str.includes(&"Blute".into(), 0), false); + assert_eq!(str.includes(&"Whale".into(), 0), true); + assert_eq!(str.includes(&"Whale".into(), 5), true); + assert_eq!(str.includes(&"Whale".into(), 7), false); + assert_eq!(str.includes(&"".into(), 0), true); + assert_eq!(str.includes(&"".into(), 16), true); +} + +#[wasm_bindgen_test] +fn index_of() { + let str = JsString::from("Blue Whale"); + + // TODO: remove second parameter once we have optional parameters + assert_eq!(str.index_of(&"Blue".into(), 0), 0); + // TODO: remove second parameter once we have optional parameters + assert_eq!(str.index_of(&"Blute".into(), 0), -1); + assert_eq!(str.index_of(&"Whale".into(), 0), 5); + assert_eq!(str.index_of(&"Whale".into(), 5), 5); + assert_eq!(str.index_of(&"Whale".into(), 7), -1); + // TODO: remove second parameter once we have optional parameters + assert_eq!(str.index_of(&"".into(), 0), 0); + assert_eq!(str.index_of(&"".into(), 9), 9); + assert_eq!(str.index_of(&"".into(), 10), 10); + assert_eq!(str.index_of(&"".into(), 11), 10); +} + +#[wasm_bindgen_test] +fn last_index_of() { + let js = JsString::from("canal"); + let len = js.length() as i32; + + // TODO: remove second parameter once we have optional parameters + assert_eq!(js.last_index_of(&"a".into(), len), 3); + assert_eq!(js.last_index_of(&"a".into(), 2), 1); + assert_eq!(js.last_index_of(&"a".into(), 0), -1); + // TODO: remove second parameter once we have optional parameters + assert_eq!(js.last_index_of(&"x".into(), len), -1); + assert_eq!(js.last_index_of(&"c".into(), -5), 0); + assert_eq!(js.last_index_of(&"c".into(), 0), 0); + // TODO: remove second parameter once we have optional parameters + assert_eq!(js.last_index_of(&"".into(), len), 5); + assert_eq!(js.last_index_of(&"".into(), 2), 2); +} + +#[wasm_bindgen_test] +fn normalize() { + let js = JsString::from("\u{1E9B}\u{0323}"); + + // TODO: Handle undefined + assert_eq!(JsValue::from(js.normalize(&"NFC".into())), "\u{1E9B}\u{0323}"); + assert_eq!(JsValue::from(js.normalize(&"NFD".into())), "\u{017F}\u{0323}\u{0307}"); + assert_eq!(JsValue::from(js.normalize(&"NFKC".into())), "\u{1E69}"); + assert_eq!(JsValue::from(js.normalize(&"NFKD".into())), "\u{0073}\u{0323}\u{0307}"); +} + +#[wasm_bindgen_test] +fn pad_end() { + let js = JsString::from("abc"); + + // TODO: remove second parameter once we have optional parameters + assert_eq!(JsValue::from(js.pad_end(10, &" ".into())), "abc "); + // TODO: remove second parameter once we have optional parameters + assert_eq!(JsValue::from(js.pad_end(10, &" ".into())), "abc "); + assert_eq!(JsValue::from(js.pad_end(10, &"foo".into())), "abcfoofoof"); + assert_eq!(JsValue::from(js.pad_end(6, &"123456".into())), "abc123"); + // TODO: remove second parameter once we have optional parameters + assert_eq!(JsValue::from(js.pad_end(1, &" ".into())), "abc"); +} + +#[wasm_bindgen_test] +fn pad_start() { + let js = JsString::from("abc"); + + // TODO: remove second parameter once we have optional parameters + assert_eq!(js.pad_start(10, &" ".into()), " abc"); + assert_eq!(js.pad_start(10, &"foo".into()), "foofoofabc"); + assert_eq!(js.pad_start(6, &"123465".into()), "123abc"); + assert_eq!(js.pad_start(8, &"0".into()), "00000abc"); + // TODO: remove second parameter once we have optional parameters + assert_eq!(js.pad_start(1, &" ".into()), "abc"); +} + +#[wasm_bindgen_test] +fn repeat() { + assert_eq!(JsString::from("test").repeat(3), "testtesttest"); +} + +#[wasm_bindgen_test] +fn slice() { + let characters = JsString::from("acxn18"); + assert_eq!(characters.slice(1, 3), "cx"); +} + +#[wasm_bindgen_test] +fn starts_with() { + let js = JsString::from("To be, or not to be, that is the question."); + + // TODO: remove second parameter for both assertions once we have optional parameters + assert!(js.starts_with(&"To be".into(), 0)); + assert!(!js.starts_with(&"not to be".into(), 0)); + assert!(js.starts_with(&"not to be".into(), 10)); +} + +#[wasm_bindgen_test] +fn substring() { + let js = JsString::from("Mozilla"); + + assert_eq!(js.substring(0, 1), "M"); + assert_eq!(js.substring(1, 0), "M"); + + assert_eq!(js.substring(0, 6), "Mozill"); + + // TODO: Add test once we have optional parameters + // assert_eq!(js.substring(4), "lla"); + assert_eq!(js.substring(4, 7), "lla"); + assert_eq!(js.substring(7, 4), "lla"); + + assert_eq!(js.substring(0, 7), "Mozilla"); + assert_eq!(js.substring(0, 10), "Mozilla"); +} + +#[wasm_bindgen_test] +fn substr() { + let js = JsString::from("Mozilla"); + + assert_eq!(js.substr(0, 1), "M"); + assert_eq!(js.substr(1, 0), ""); + assert_eq!(js.substr(-1, 1), "a"); + assert_eq!(js.substr(1, -1), ""); + // TODO: Uncomment and test these assertions, once we have support for optional parameters + // assert_eq!(js.substr(-3), "lla"); + // assert_eq!(js.substr(1), "ozilla"); + assert_eq!(js.substr(-20, 2), "Mo"); + assert_eq!(js.substr(20, 2), ""); +} + +#[wasm_bindgen_test] +fn to_locale_lower_case() { + let js = JsString::from("Mozilla"); + assert_eq!(js.to_locale_lower_case(None), "mozilla"); + let s = JsString::from("\u{0130}"); + assert_eq!(s.to_locale_lower_case(Some("tr".into())), "i"); + assert_ne!(s.to_locale_lower_case(Some("en-US".into())), "i"); +} + +#[wasm_bindgen_test] +fn to_locale_upper_case() { + let js = JsString::from("mozilla"); + assert_eq!(js.to_locale_upper_case(None), "MOZILLA"); + let s = JsString::from("i\u{0307}"); + assert_eq!(s.to_locale_upper_case(Some("lt".into())), "I"); + assert_ne!(s.to_locale_upper_case(Some("en-US".into())), "I"); +} + +#[wasm_bindgen_test] +fn to_lower_case() { + assert_eq!(JsString::from("Mozilla").to_lower_case(), "mozilla"); +} + +#[wasm_bindgen_test] +fn to_string() { + assert_eq!(JsString::from("foo").to_string(), "foo"); +} + +#[wasm_bindgen_test] +fn to_upper_case() { + assert_eq!(JsString::from("Mozilla").to_upper_case(), "MOZILLA"); +} + +#[wasm_bindgen_test] +fn trim() { + assert_eq!(JsString::from(" foo ").trim(), "foo"); + // Another example of .trim() removing whitespace from just one side. + assert_eq!(JsString::from("foo ").trim(), "foo"); +} + +#[wasm_bindgen_test] +fn trim_end_and_trim_right() { + let greeting = JsString::from(" Hello world! "); + let trimmed = " Hello world!"; + assert_eq!(greeting.trim_end(), trimmed); + assert_eq!(greeting.trim_right(), trimmed); +} + +#[wasm_bindgen_test] +fn trim_start_and_trim_left() { + let greeting = JsString::from(" Hello world! "); + let trimmed = "Hello world! "; + assert_eq!(greeting.trim_start(), trimmed); + assert_eq!(greeting.trim_left(), trimmed); +} + +#[wasm_bindgen_test] +fn value_of() { + let greeting = JsString::from("Hello world!"); + assert_eq!(greeting.value_of(), "Hello world!"); +} diff --git a/crates/js-sys/tests/wasm/main.rs b/crates/js-sys/tests/wasm/main.rs index e71e2488..d679268f 100644 --- a/crates/js-sys/tests/wasm/main.rs +++ b/crates/js-sys/tests/wasm/main.rs @@ -16,3 +16,4 @@ pub mod Error; pub mod Function; pub mod Generator; pub mod Intl; +pub mod JsString;