JsString.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. use js_sys::*;
  2. use wasm_bindgen::prelude::*;
  3. use wasm_bindgen::JsCast;
  4. use wasm_bindgen::JsValue;
  5. use wasm_bindgen_test::*;
  6. #[wasm_bindgen(module = "tests/wasm/JsString.js")]
  7. extern "C" {
  8. fn new_string_object() -> JsValue;
  9. fn get_replacer_function() -> Function;
  10. }
  11. #[wasm_bindgen_test]
  12. fn js_string_inheritance() {
  13. let string = new_string_object();
  14. assert!(string.is_instance_of::<JsString>());
  15. assert!(string.is_instance_of::<Object>());
  16. }
  17. #[wasm_bindgen_test]
  18. fn length() {
  19. fn test(s: &str) {
  20. assert_eq!(JsString::from(s).length(), s.len() as u32);
  21. }
  22. test("Mozilla");
  23. test("");
  24. }
  25. #[wasm_bindgen_test]
  26. fn char_at() {
  27. let s = JsString::from("Brave new world");
  28. assert_eq!(JsValue::from(s.char_at(0)), "B");
  29. assert_eq!(JsValue::from(s.char_at(999)), "");
  30. }
  31. #[wasm_bindgen_test]
  32. fn char_code_at() {
  33. let s = "Brave new world";
  34. let js = JsString::from(s);
  35. for (i, b) in s.char_indices() {
  36. assert_eq!(js.char_code_at(i as u32), b as u32 as f64);
  37. }
  38. assert!(js.char_code_at(s.len() as u32).is_nan());
  39. }
  40. #[wasm_bindgen_test]
  41. fn code_point_at() {
  42. assert_eq!(JsString::from("ABC").code_point_at(1), b'B');
  43. assert!(JsString::from("ABC").code_point_at(42).is_undefined());
  44. }
  45. #[wasm_bindgen_test]
  46. fn concat() {
  47. // TODO: Implement ability to receive multiple optional arguments
  48. let s = JsString::from("Hello ").concat(&"World".into());
  49. assert_eq!(JsValue::from(s), "Hello World");
  50. let foo = JsString::from("foo");
  51. assert_eq!(
  52. JsValue::from(foo.concat(&Object::new().into())),
  53. "foo[object Object]"
  54. );
  55. assert_eq!(JsValue::from(foo.concat(&Array::new().into())), "foo");
  56. assert_eq!(JsValue::from(foo.concat(&JsValue::null())), "foonull");
  57. assert_eq!(JsValue::from(foo.concat(&true.into())), "footrue");
  58. assert_eq!(JsValue::from(foo.concat(&1234.into())), "foo1234");
  59. }
  60. #[wasm_bindgen_test]
  61. fn ends_with() {
  62. let s = "To be, or not to be, that is the question.";
  63. let js = JsString::from(s);
  64. // TODO: remove third parameter once we have optional parameters
  65. assert_eq!(js.ends_with("question.", s.len() as i32), true);
  66. assert_eq!(js.ends_with("to be", s.len() as i32), false);
  67. assert_eq!(js.ends_with("to be", 19), true);
  68. }
  69. #[wasm_bindgen_test]
  70. fn from_char_code() {
  71. let s = "½+¾=";
  72. let codes: Vec<u32> = s.chars().map(|char| char as u32).collect();
  73. assert_eq!(JsString::from_char_code1(codes[0]), "½");
  74. assert_eq!(JsString::from_char_code2(codes[0], codes[1]), "½+");
  75. assert_eq!(
  76. JsString::from_char_code3(codes[0], codes[1], codes[2]),
  77. "½+¾"
  78. );
  79. assert_eq!(
  80. JsString::from_char_code4(codes[0], codes[1], codes[2], codes[3]),
  81. "½+¾="
  82. );
  83. let codes_u16: Vec<u16> = codes
  84. .into_iter()
  85. .map(|code| {
  86. assert!(code <= u32::from(u16::max_value()));
  87. code as u16
  88. })
  89. .collect();
  90. assert_eq!(JsString::from_char_code(&codes_u16), "½+¾=");
  91. }
  92. #[wasm_bindgen_test]
  93. fn from_code_point() {
  94. let s = "☃★♲你";
  95. let codes: Vec<u32> = s.chars().map(|char| char as u32).collect();
  96. assert_eq!(JsString::from_code_point1(codes[0]).unwrap(), "☃");
  97. assert_eq!(
  98. JsString::from_code_point2(codes[0], codes[1]).unwrap(),
  99. "☃★"
  100. );
  101. assert_eq!(
  102. JsString::from_code_point3(codes[0], codes[1], codes[2]).unwrap(),
  103. "☃★♲"
  104. );
  105. assert_eq!(
  106. JsString::from_code_point4(codes[0], codes[1], codes[2], codes[3]).unwrap(),
  107. "☃★♲你"
  108. );
  109. assert_eq!(JsString::from_code_point(&codes).unwrap(), "☃★♲你");
  110. assert!(!JsString::from_code_point1(0x10FFFF).is_err());
  111. assert!(JsString::from_code_point1(0x110000).is_err());
  112. assert!(JsString::from_code_point1(u32::max_value()).is_err());
  113. }
  114. #[wasm_bindgen_test]
  115. fn includes() {
  116. let str = JsString::from("Blue Whale");
  117. // TODO: remove second parameter once we have optional parameters
  118. assert_eq!(str.includes("Blue", 0), true);
  119. assert_eq!(str.includes("Blute", 0), false);
  120. assert_eq!(str.includes("Whale", 0), true);
  121. assert_eq!(str.includes("Whale", 5), true);
  122. assert_eq!(str.includes("Whale", 7), false);
  123. assert_eq!(str.includes("", 0), true);
  124. assert_eq!(str.includes("", 16), true);
  125. }
  126. #[wasm_bindgen_test]
  127. fn index_of() {
  128. let str = JsString::from("Blue Whale");
  129. // TODO: remove second parameter once we have optional parameters
  130. assert_eq!(str.index_of("Blue", 0), 0);
  131. // TODO: remove second parameter once we have optional parameters
  132. assert_eq!(str.index_of("Blute", 0), -1);
  133. assert_eq!(str.index_of("Whale", 0), 5);
  134. assert_eq!(str.index_of("Whale", 5), 5);
  135. assert_eq!(str.index_of("Whale", 7), -1);
  136. // TODO: remove second parameter once we have optional parameters
  137. assert_eq!(str.index_of("", 0), 0);
  138. assert_eq!(str.index_of("", 9), 9);
  139. assert_eq!(str.index_of("", 10), 10);
  140. assert_eq!(str.index_of("", 11), 10);
  141. }
  142. #[wasm_bindgen_test]
  143. fn last_index_of() {
  144. let js = JsString::from("canal");
  145. let len = js.length() as i32;
  146. // TODO: remove second parameter once we have optional parameters
  147. assert_eq!(js.last_index_of("a", len), 3);
  148. assert_eq!(js.last_index_of("a", 2), 1);
  149. assert_eq!(js.last_index_of("a", 0), -1);
  150. // TODO: remove second parameter once we have optional parameters
  151. assert_eq!(js.last_index_of("x", len), -1);
  152. assert_eq!(js.last_index_of("c", -5), 0);
  153. assert_eq!(js.last_index_of("c", 0), 0);
  154. // TODO: remove second parameter once we have optional parameters
  155. assert_eq!(js.last_index_of("", len), 5);
  156. assert_eq!(js.last_index_of("", 2), 2);
  157. }
  158. #[wasm_bindgen_test]
  159. fn match_() {
  160. let s = "The quick brown fox jumped over the lazy dog. It barked.";
  161. let re = RegExp::new("[A-Z]", "g");
  162. let result = JsString::from(s).match_(&re);
  163. let obj = result.unwrap();
  164. assert_eq!(Reflect::get(obj.as_ref(), &"0".into()).unwrap(), "T");
  165. assert_eq!(Reflect::get(obj.as_ref(), &"1".into()).unwrap(), "I");
  166. let re = RegExp::new("[A-Z]([a-z]*)", "g");
  167. let result = JsString::from(s).match_(&re);
  168. let obj = result.unwrap();
  169. assert_eq!(Reflect::get(obj.as_ref(), &"0".into()).unwrap(), "The");
  170. assert_eq!(Reflect::get(obj.as_ref(), &"1".into()).unwrap(), "It");
  171. let result = JsString::from("foo").match_(&re);
  172. assert!(result.is_none());
  173. let s = "For more information, see Chapter 3.4.5.1";
  174. let re = RegExp::new("see (chapter \\d+(\\.\\d)*)", "i");
  175. let result = JsString::from(s).match_(&re);
  176. let obj = result.unwrap();
  177. assert_eq!(
  178. Reflect::get(obj.as_ref(), &"0".into()).unwrap(),
  179. "see Chapter 3.4.5.1"
  180. );
  181. assert_eq!(
  182. Reflect::get(obj.as_ref(), &"1".into()).unwrap(),
  183. "Chapter 3.4.5.1"
  184. );
  185. assert_eq!(Reflect::get(obj.as_ref(), &"2".into()).unwrap(), ".1");
  186. assert_eq!(Reflect::get(obj.as_ref(), &"index".into()).unwrap(), 22);
  187. assert_eq!(Reflect::get(obj.as_ref(), &"input".into()).unwrap(), s);
  188. }
  189. #[wasm_bindgen_test]
  190. fn match_all() {
  191. let s = "The quick brown fox jumped over the lazy dog. It barked.";
  192. let re = RegExp::new("[A-Z]([a-z]*)", "g");
  193. let result: Vec<_> = JsString::from(s)
  194. .match_all(&re)
  195. .into_iter()
  196. .collect::<Result<_, _>>()
  197. .unwrap();
  198. let obj = &result[0];
  199. assert_eq!(Reflect::get(obj.as_ref(), &"0".into()).unwrap(), "The");
  200. assert_eq!(Reflect::get(obj.as_ref(), &"1".into()).unwrap(), "he");
  201. let obj = &result[1];
  202. assert_eq!(Reflect::get(obj.as_ref(), &"0".into()).unwrap(), "It");
  203. assert_eq!(Reflect::get(obj.as_ref(), &"1".into()).unwrap(), "t");
  204. let result: Vec<_> = JsString::from("foo")
  205. .match_all(&re)
  206. .into_iter()
  207. .collect::<Result<_, _>>()
  208. .unwrap();
  209. assert_eq!(result.len(), 0);
  210. let s = "For more information, see Chapter 3.4.5.1. Also see Chapter 3.1.4";
  211. let re = RegExp::new("see (chapter \\d+(\\.\\d)*)", "gi");
  212. let result: Vec<_> = JsString::from(s)
  213. .match_all(&re)
  214. .into_iter()
  215. .collect::<Result<_, _>>()
  216. .unwrap();
  217. let obj = &result[0];
  218. assert_eq!(
  219. Reflect::get(obj.as_ref(), &"0".into()).unwrap(),
  220. "see Chapter 3.4.5.1"
  221. );
  222. assert_eq!(
  223. Reflect::get(obj.as_ref(), &"1".into()).unwrap(),
  224. "Chapter 3.4.5.1"
  225. );
  226. assert_eq!(Reflect::get(obj.as_ref(), &"2".into()).unwrap(), ".1");
  227. assert_eq!(Reflect::get(obj.as_ref(), &"index".into()).unwrap(), 22);
  228. assert_eq!(Reflect::get(obj.as_ref(), &"input".into()).unwrap(), s);
  229. let obj = &result[1];
  230. assert_eq!(
  231. Reflect::get(obj.as_ref(), &"0".into()).unwrap(),
  232. "see Chapter 3.1.4"
  233. );
  234. assert_eq!(
  235. Reflect::get(obj.as_ref(), &"1".into()).unwrap(),
  236. "Chapter 3.1.4"
  237. );
  238. assert_eq!(Reflect::get(obj.as_ref(), &"2".into()).unwrap(), ".4");
  239. assert_eq!(Reflect::get(obj.as_ref(), &"index".into()).unwrap(), 48);
  240. assert_eq!(Reflect::get(obj.as_ref(), &"input".into()).unwrap(), s);
  241. }
  242. #[wasm_bindgen_test]
  243. fn normalize() {
  244. let js = JsString::from("\u{1E9B}\u{0323}");
  245. // TODO: Handle undefined
  246. assert_eq!(JsValue::from(js.normalize("NFC")), "\u{1E9B}\u{0323}");
  247. assert_eq!(
  248. JsValue::from(js.normalize("NFD")),
  249. "\u{017F}\u{0323}\u{0307}"
  250. );
  251. assert_eq!(JsValue::from(js.normalize("NFKC")), "\u{1E69}");
  252. assert_eq!(
  253. JsValue::from(js.normalize("NFKD")),
  254. "\u{0073}\u{0323}\u{0307}"
  255. );
  256. }
  257. #[wasm_bindgen_test]
  258. fn pad_end() {
  259. let js = JsString::from("abc");
  260. // TODO: remove second parameter once we have optional parameters
  261. assert_eq!(JsValue::from(js.pad_end(10, " ")), "abc ");
  262. // TODO: remove second parameter once we have optional parameters
  263. assert_eq!(JsValue::from(js.pad_end(10, " ")), "abc ");
  264. assert_eq!(JsValue::from(js.pad_end(10, "foo")), "abcfoofoof");
  265. assert_eq!(JsValue::from(js.pad_end(6, "123456")), "abc123");
  266. // TODO: remove second parameter once we have optional parameters
  267. assert_eq!(JsValue::from(js.pad_end(1, " ")), "abc");
  268. }
  269. #[wasm_bindgen_test]
  270. fn pad_start() {
  271. let js = JsString::from("abc");
  272. // TODO: remove second parameter once we have optional parameters
  273. assert_eq!(js.pad_start(10, " "), " abc");
  274. assert_eq!(js.pad_start(10, "foo"), "foofoofabc");
  275. assert_eq!(js.pad_start(6, "123465"), "123abc");
  276. assert_eq!(js.pad_start(8, "0"), "00000abc");
  277. // TODO: remove second parameter once we have optional parameters
  278. assert_eq!(js.pad_start(1, " "), "abc");
  279. }
  280. #[wasm_bindgen_test]
  281. fn repeat() {
  282. assert_eq!(JsString::from("test").repeat(3), "testtesttest");
  283. }
  284. #[wasm_bindgen_test]
  285. fn replace() {
  286. let js = JsString::from(
  287. "The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?",
  288. );
  289. let result = js.replace("dog", "ferret");
  290. assert_eq!(
  291. result,
  292. "The quick brown fox jumped over the lazy ferret. If the dog reacted, was it really lazy?"
  293. );
  294. let js = JsString::from("borderTop");
  295. let result = js.replace_with_function("T", &get_replacer_function());
  296. assert_eq!(result, "border-top");
  297. let js = JsString::from(
  298. "The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?",
  299. );
  300. let re = RegExp::new("dog", "g");
  301. let result = js.replace_by_pattern(&re, "ferret");
  302. assert_eq!(result, "The quick brown fox jumped over the lazy ferret. If the ferret reacted, was it really lazy?");
  303. let js = JsString::from("borderTop");
  304. let re = RegExp::new("[A-Z]", "g");
  305. let result = js.replace_by_pattern_with_function(&re, &get_replacer_function());
  306. assert_eq!(result, "border-top");
  307. }
  308. #[wasm_bindgen_test]
  309. fn replace_all() {
  310. let js = JsString::from(
  311. "The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?",
  312. );
  313. let result = js.replace_all("dog", "ferret");
  314. assert_eq!(
  315. result,
  316. "The quick brown fox jumped over the lazy ferret. If the ferret reacted, was it really lazy?"
  317. );
  318. let js = JsString::from("borderTopTest");
  319. let result = js.replace_all_with_function("T", &get_replacer_function());
  320. assert_eq!(result, "border-top-test");
  321. let js = JsString::from(
  322. "The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?",
  323. );
  324. let re = RegExp::new("dog", "g");
  325. let result = js.replace_all_by_pattern(&re, "ferret");
  326. assert_eq!(result, "The quick brown fox jumped over the lazy ferret. If the ferret reacted, was it really lazy?");
  327. let js = JsString::from("borderTopTest");
  328. let re = RegExp::new("[A-Z]", "g");
  329. let result = js.replace_all_by_pattern_with_function(&re, &get_replacer_function());
  330. assert_eq!(result, "border-top-test");
  331. }
  332. #[wasm_bindgen_test]
  333. fn search() {
  334. let js = JsString::from(
  335. "The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?",
  336. );
  337. let re = RegExp::new("[^\\w\\s]", "g");
  338. assert_eq!(js.search(&re), 44);
  339. let js = JsString::from("hey JudE");
  340. let re1 = RegExp::new("[A-Z]", "g");
  341. let re2 = RegExp::new("[.]", "g");
  342. assert_eq!(js.search(&re1), 4);
  343. assert_eq!(js.search(&re2), -1);
  344. }
  345. #[wasm_bindgen_test]
  346. fn slice() {
  347. let characters = JsString::from("acxn18");
  348. assert_eq!(characters.slice(1, 3), "cx");
  349. }
  350. #[wasm_bindgen_test]
  351. fn split() {
  352. let js = JsString::from("Oh brave new world");
  353. let result = js.split(" ");
  354. let mut v = Vec::with_capacity(result.length() as usize);
  355. result.for_each(&mut |x, _, _| v.push(x));
  356. assert_eq!(v[0], "Oh");
  357. assert_eq!(v[1], "brave");
  358. assert_eq!(v[2], "new");
  359. assert_eq!(v[3], "world");
  360. let js = JsString::from("Oct,Nov,Dec");
  361. let result = js.split(",");
  362. let mut v = Vec::with_capacity(result.length() as usize);
  363. result.for_each(&mut |x, _, _| v.push(x));
  364. assert_eq!(v[0], "Oct");
  365. assert_eq!(v[1], "Nov");
  366. assert_eq!(v[2], "Dec");
  367. let result = js.split_limit(",", 2);
  368. let mut v = Vec::with_capacity(result.length() as usize);
  369. result.for_each(&mut |x, _, _| v.push(x));
  370. assert_eq!(result.length(), 2);
  371. assert_eq!(v[0], "Oct");
  372. assert_eq!(v[1], "Nov");
  373. let js = JsString::from("Oh brave new world");
  374. let re = RegExp::new("\\s", "g");
  375. let result = js.split_by_pattern(&re);
  376. let mut v = Vec::with_capacity(result.length() as usize);
  377. result.for_each(&mut |x, _, _| v.push(x));
  378. assert_eq!(v[0], "Oh");
  379. assert_eq!(v[1], "brave");
  380. assert_eq!(v[2], "new");
  381. assert_eq!(v[3], "world");
  382. let result = js.split_by_pattern_limit(&re, 2);
  383. let mut v = Vec::with_capacity(result.length() as usize);
  384. result.for_each(&mut |x, _, _| v.push(x));
  385. assert_eq!(result.length(), 2);
  386. assert_eq!(v[0], "Oh");
  387. assert_eq!(v[1], "brave");
  388. }
  389. #[wasm_bindgen_test]
  390. fn starts_with() {
  391. let js = JsString::from("To be, or not to be, that is the question.");
  392. // TODO: remove second parameter for both assertions once we have optional parameters
  393. assert!(js.starts_with("To be", 0));
  394. assert!(!js.starts_with("not to be", 0));
  395. assert!(js.starts_with("not to be", 10));
  396. }
  397. #[wasm_bindgen_test]
  398. fn substring() {
  399. let js = JsString::from("Mozilla");
  400. assert_eq!(js.substring(0, 1), "M");
  401. assert_eq!(js.substring(1, 0), "M");
  402. assert_eq!(js.substring(0, 6), "Mozill");
  403. // TODO: Add test once we have optional parameters
  404. // assert_eq!(js.substring(4), "lla");
  405. assert_eq!(js.substring(4, 7), "lla");
  406. assert_eq!(js.substring(7, 4), "lla");
  407. assert_eq!(js.substring(0, 7), "Mozilla");
  408. assert_eq!(js.substring(0, 10), "Mozilla");
  409. }
  410. #[wasm_bindgen_test]
  411. fn substr() {
  412. let js = JsString::from("Mozilla");
  413. assert_eq!(js.substr(0, 1), "M");
  414. assert_eq!(js.substr(1, 0), "");
  415. assert_eq!(js.substr(-1, 1), "a");
  416. assert_eq!(js.substr(1, -1), "");
  417. // TODO: Uncomment and test these assertions, once we have support for optional parameters
  418. // assert_eq!(js.substr(-3), "lla");
  419. // assert_eq!(js.substr(1), "ozilla");
  420. assert_eq!(js.substr(-20, 2), "Mo");
  421. assert_eq!(js.substr(20, 2), "");
  422. }
  423. #[wasm_bindgen_test]
  424. fn to_locale_lower_case() {
  425. let js = JsString::from("Mozilla");
  426. assert_eq!(js.to_locale_lower_case(None), "mozilla");
  427. let s = JsString::from("\u{0130}");
  428. assert_eq!(s.to_locale_lower_case(Some("tr".into())), "i");
  429. assert_ne!(s.to_locale_lower_case(Some("en-US".into())), "i");
  430. }
  431. #[wasm_bindgen_test]
  432. fn to_locale_upper_case() {
  433. let js = JsString::from("mozilla");
  434. assert_eq!(js.to_locale_upper_case(None), "MOZILLA");
  435. let s = JsString::from("i\u{0307}");
  436. assert_eq!(s.to_locale_upper_case(Some("lt".into())), "I");
  437. assert_ne!(s.to_locale_upper_case(Some("en-US".into())), "I");
  438. }
  439. #[wasm_bindgen_test]
  440. fn to_lower_case() {
  441. assert_eq!(JsString::from("Mozilla").to_lower_case(), "mozilla");
  442. }
  443. #[wasm_bindgen_test]
  444. fn to_string() {
  445. assert_eq!(JsString::from("foo").to_string(), "foo");
  446. }
  447. #[wasm_bindgen_test]
  448. fn to_upper_case() {
  449. assert_eq!(JsString::from("Mozilla").to_upper_case(), "MOZILLA");
  450. }
  451. #[wasm_bindgen_test]
  452. fn trim() {
  453. assert_eq!(JsString::from(" foo ").trim(), "foo");
  454. // Another example of .trim() removing whitespace from just one side.
  455. assert_eq!(JsString::from("foo ").trim(), "foo");
  456. }
  457. #[wasm_bindgen_test]
  458. fn trim_end_and_trim_right() {
  459. let greeting = JsString::from(" Hello world! ");
  460. let trimmed = " Hello world!";
  461. assert_eq!(greeting.trim_end(), trimmed);
  462. assert_eq!(greeting.trim_right(), trimmed);
  463. }
  464. #[wasm_bindgen_test]
  465. fn trim_start_and_trim_left() {
  466. let greeting = JsString::from(" Hello world! ");
  467. let trimmed = "Hello world! ";
  468. assert_eq!(greeting.trim_start(), trimmed);
  469. assert_eq!(greeting.trim_left(), trimmed);
  470. }
  471. #[wasm_bindgen_test]
  472. fn value_of() {
  473. let greeting = JsString::from("Hello world!");
  474. assert_eq!(greeting.value_of(), "Hello world!");
  475. }
  476. #[wasm_bindgen_test]
  477. fn raw() {
  478. let call_site = Object::new();
  479. let raw = Array::of3(&"foo".into(), &"bar".into(), &"123".into());
  480. Reflect::set(&call_site.as_ref(), &"raw".into(), &raw.into()).unwrap();
  481. assert_eq!(
  482. JsString::raw_2(&call_site, "5", "JavaScript").unwrap(),
  483. "foo5barJavaScript123"
  484. );
  485. let substitutions = Array::of2(&"5".into(), &"JavaScript".into());
  486. assert_eq!(
  487. JsString::raw(&call_site, &substitutions).unwrap(),
  488. "foo5barJavaScript123"
  489. );
  490. assert!(JsString::raw_0(&JsValue::null().unchecked_into()).is_err());
  491. }
  492. #[wasm_bindgen_test]
  493. fn is_valid_utf16() {
  494. assert!(JsString::from("a").is_valid_utf16());
  495. assert!(JsString::from("").is_valid_utf16());
  496. assert!(JsString::from("🥑").is_valid_utf16());
  497. assert!(JsString::from("Why hello there this, 🥑, is 🥑 and is 🥑").is_valid_utf16());
  498. assert!(JsString::from_char_code1(0x00).is_valid_utf16());
  499. assert!(!JsString::from_char_code1(0xd800).is_valid_utf16());
  500. assert!(!JsString::from_char_code1(0xdc00).is_valid_utf16());
  501. }
  502. #[wasm_bindgen_test]
  503. fn as_char() {
  504. assert_eq!(JsString::from('a').as_char(), Some('a'));
  505. assert_eq!(JsString::from('🥑').as_char(), Some('🥑'));
  506. assert_eq!(JsString::from("").as_char(), None);
  507. assert_eq!(JsString::from("ab").as_char(), None);
  508. assert_eq!(JsString::from_char_code1(0xd800).as_char(), None);
  509. assert_eq!(JsString::from_char_code1(0xdc00).as_char(), None);
  510. assert_eq!(JsString::from_char_code1(0xdfff).as_char(), None);
  511. }