summaryrefslogtreecommitdiffstats
path: root/js/rust/tests
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/rust/tests/bigint.rs56
-rw-r--r--js/rust/tests/callback.rs79
-rw-r--r--js/rust/tests/enumerate.rs70
-rw-r--r--js/rust/tests/evaluate.rs32
-rw-r--r--js/rust/tests/panic.rs50
-rw-r--r--js/rust/tests/rooting.rs105
-rw-r--r--js/rust/tests/runtime.rs59
-rw-r--r--js/rust/tests/stack_limit.rs44
-rw-r--r--js/rust/tests/typedarray.rs104
-rw-r--r--js/rust/tests/value.rs64
-rw-r--r--js/rust/tests/vec_conversion.rs81
11 files changed, 744 insertions, 0 deletions
diff --git a/js/rust/tests/bigint.rs b/js/rust/tests/bigint.rs
new file mode 100644
index 0000000000..3c8ef1ed29
--- /dev/null
+++ b/js/rust/tests/bigint.rs
@@ -0,0 +1,56 @@
+#[macro_use]
+extern crate js;
+
+use js::jsapi::root::JS_NewGlobalObject;
+use js::jsapi::root::JS::CompartmentOptions;
+use js::jsapi::root::JS::OnNewGlobalHookOption;
+use js::jsval::UndefinedValue;
+use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS};
+
+use std::ptr;
+
+#[test]
+fn is_bigint() {
+ let rt = Runtime::new(false).unwrap();
+ let cx = rt.cx();
+
+ unsafe {
+ rooted!(in(cx) let global =
+ JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
+ OnNewGlobalHookOption::FireOnNewGlobalHook,
+ &CompartmentOptions::default())
+ );
+
+ rooted!(in(cx) let mut rval = UndefinedValue());
+ assert!(rt
+ .evaluate_script(global.handle(), "BigInt(0)", "test", 1, rval.handle_mut())
+ .is_ok());
+ assert!(rval.is_bigint());
+ }
+}
+
+#[test]
+fn is_not_bigint() {
+ let rt = Runtime::new(false).unwrap();
+ let cx = rt.cx();
+
+ unsafe {
+ rooted!(in(cx) let global =
+ JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
+ OnNewGlobalHookOption::FireOnNewGlobalHook,
+ &CompartmentOptions::default())
+ );
+
+ rooted!(in(cx) let mut rval = UndefinedValue());
+ assert!(rt
+ .evaluate_script(
+ global.handle(),
+ "'not a BigInt'",
+ "test",
+ 1,
+ rval.handle_mut()
+ )
+ .is_ok());
+ assert!(!rval.is_bigint());
+ }
+}
diff --git a/js/rust/tests/callback.rs b/js/rust/tests/callback.rs
new file mode 100644
index 0000000000..de75f97d26
--- /dev/null
+++ b/js/rust/tests/callback.rs
@@ -0,0 +1,79 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#[macro_use]
+extern crate js;
+extern crate libc;
+
+use js::ar::AutoRealm;
+use js::glue::JSEncodeStringToUTF8;
+use js::jsapi::root::JSContext;
+use js::jsapi::root::JS_DefineFunction;
+use js::jsapi::root::JS_NewGlobalObject;
+use js::jsapi::root::JS_ReportErrorASCII;
+use js::jsapi::root::JS::CallArgs;
+use js::jsapi::root::JS::OnNewGlobalHookOption;
+use js::jsapi::root::JS::RealmOptions;
+use js::jsapi::root::JS::Value;
+use js::jsval::UndefinedValue;
+use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS};
+
+use std::ffi::CStr;
+use std::ptr;
+use std::str;
+
+#[test]
+fn callback() {
+ let runtime = Runtime::new(false).unwrap();
+ let context = runtime.cx();
+ let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook;
+ let c_option = RealmOptions::default();
+
+ unsafe {
+ let global = JS_NewGlobalObject(
+ context,
+ &SIMPLE_GLOBAL_CLASS,
+ ptr::null_mut(),
+ h_option,
+ &c_option,
+ );
+ rooted!(in(context) let global_root = global);
+ let global = global_root.handle();
+ let _ar = AutoRealm::with_obj(context, global.get());
+ let function = JS_DefineFunction(
+ context,
+ global,
+ b"puts\0".as_ptr() as *const libc::c_char,
+ Some(puts),
+ 1,
+ 0,
+ );
+ assert!(!function.is_null());
+ let javascript = "puts('Test Iñtërnâtiônàlizætiøn ┬─┬ノ( º _ ºノ) ');";
+ rooted!(in(context) let mut rval = UndefinedValue());
+ let _ = runtime.evaluate_script(global, javascript, "test.js", 0, rval.handle_mut());
+ }
+}
+
+unsafe extern "C" fn puts(context: *mut JSContext, argc: u32, vp: *mut Value) -> bool {
+ let args = CallArgs::from_vp(vp, argc);
+
+ if args._base.argc_ != 1 {
+ JS_ReportErrorASCII(
+ context,
+ b"puts() requires exactly 1 argument\0".as_ptr() as *const libc::c_char,
+ );
+ return false;
+ }
+
+ let arg = args.get(0);
+ let js = js::rust::ToString(context, arg);
+ rooted!(in(context) let message_root = js);
+ let message = JSEncodeStringToUTF8(context, message_root.handle());
+ let message = CStr::from_ptr(message);
+ println!("{}", str::from_utf8(message.to_bytes()).unwrap());
+
+ args.rval().set(UndefinedValue());
+ return true;
+}
diff --git a/js/rust/tests/enumerate.rs b/js/rust/tests/enumerate.rs
new file mode 100644
index 0000000000..a1c8a6735d
--- /dev/null
+++ b/js/rust/tests/enumerate.rs
@@ -0,0 +1,70 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#[macro_use]
+extern crate js;
+
+use js::glue::RUST_JSID_IS_STRING;
+use js::glue::RUST_JSID_TO_STRING;
+use js::jsapi::root::js::GetPropertyKeys;
+use js::jsapi::root::JS_NewGlobalObject;
+use js::jsapi::root::JS_StringEqualsAscii;
+use js::jsapi::root::JS::OnNewGlobalHookOption;
+use js::jsapi::root::JS::RealmOptions;
+use js::jsapi::root::JSITER_OWNONLY;
+use js::jsval::UndefinedValue;
+use js::rust::RootedIdVectorWrapper;
+use js::rust::Runtime;
+use js::rust::SIMPLE_GLOBAL_CLASS;
+use std::ptr;
+
+#[test]
+fn enumerate() {
+ let rt = Runtime::new(false).unwrap();
+ let cx = rt.cx();
+
+ unsafe {
+ rooted!(in(cx) let global =
+ JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
+ OnNewGlobalHookOption::FireOnNewGlobalHook,
+ &RealmOptions::default())
+ );
+
+ rooted!(in(cx) let mut rval = UndefinedValue());
+ assert!(rt
+ .evaluate_script(
+ global.handle(),
+ "({ 'a': 7 })",
+ "test",
+ 1,
+ rval.handle_mut()
+ )
+ .is_ok());
+ assert!(rval.is_object());
+
+ rooted!(in(cx) let object = rval.to_object());
+ let ids = RootedIdVectorWrapper::new(cx);
+ assert!(GetPropertyKeys(
+ cx,
+ object.handle(),
+ JSITER_OWNONLY,
+ ids.handle_mut()
+ ));
+
+ assert_eq!(ids.len(), 1);
+ rooted!(in(cx) let id = ids[0]);
+
+ assert!(RUST_JSID_IS_STRING(id.handle()));
+ rooted!(in(cx) let id = RUST_JSID_TO_STRING(id.handle()));
+
+ let mut matches = false;
+ assert!(JS_StringEqualsAscii(
+ cx,
+ id.get(),
+ b"a\0" as *const _ as *const _,
+ &mut matches
+ ));
+ assert!(matches);
+ }
+}
diff --git a/js/rust/tests/evaluate.rs b/js/rust/tests/evaluate.rs
new file mode 100644
index 0000000000..8ce4396ade
--- /dev/null
+++ b/js/rust/tests/evaluate.rs
@@ -0,0 +1,32 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#[macro_use]
+extern crate js;
+
+use js::jsapi::root::JS_NewGlobalObject;
+use js::jsapi::root::JS::OnNewGlobalHookOption;
+use js::jsapi::root::JS::RealmOptions;
+use js::jsval::UndefinedValue;
+use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS};
+
+use std::ptr;
+
+#[test]
+fn evaluate() {
+ let rt = Runtime::new(false).unwrap();
+ let cx = rt.cx();
+
+ unsafe {
+ rooted!(in(cx) let global =
+ JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
+ OnNewGlobalHookOption::FireOnNewGlobalHook,
+ &RealmOptions::default())
+ );
+ rooted!(in(cx) let mut rval = UndefinedValue());
+ assert!(rt
+ .evaluate_script(global.handle(), "1 + 1", "test", 1, rval.handle_mut())
+ .is_ok());
+ }
+}
diff --git a/js/rust/tests/panic.rs b/js/rust/tests/panic.rs
new file mode 100644
index 0000000000..ecb5705017
--- /dev/null
+++ b/js/rust/tests/panic.rs
@@ -0,0 +1,50 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#[macro_use]
+extern crate js;
+
+use js::jsapi::*;
+use js::jsval::UndefinedValue;
+use js::panic::wrap_panic;
+use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS};
+use std::ptr;
+use std::str;
+
+#[test]
+#[should_panic]
+fn panic() {
+ let runtime = Runtime::new(false).unwrap();
+ let context = runtime.cx();
+ let h_option = JS::OnNewGlobalHookOption::FireOnNewGlobalHook;
+ let c_option = JS::RealmOptions::default();
+
+ unsafe {
+ let global = JS_NewGlobalObject(
+ context,
+ &SIMPLE_GLOBAL_CLASS,
+ ptr::null_mut(),
+ h_option,
+ &c_option,
+ );
+ rooted!(in(context) let global_root = global);
+ let global = global_root.handle();
+ let _ar = js::ar::AutoRealm::with_obj(context, global.get());
+ let function = JS_DefineFunction(
+ context,
+ global,
+ b"test\0".as_ptr() as *const _,
+ Some(test),
+ 0,
+ 0,
+ );
+ assert!(!function.is_null());
+ rooted!(in(context) let mut rval = UndefinedValue());
+ let _ = runtime.evaluate_script(global, "test();", "test.js", 0, rval.handle_mut());
+ }
+}
+
+unsafe extern "C" fn test(_cx: *mut JSContext, _argc: u32, _vp: *mut JS::Value) -> bool {
+ wrap_panic(|| panic!(), false)
+}
diff --git a/js/rust/tests/rooting.rs b/js/rust/tests/rooting.rs
new file mode 100644
index 0000000000..868846fa02
--- /dev/null
+++ b/js/rust/tests/rooting.rs
@@ -0,0 +1,105 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#![cfg(feature = "debugmozjs")]
+
+#[macro_use]
+extern crate js;
+#[macro_use]
+extern crate lazy_static;
+extern crate libc;
+
+use js::jsapi::*;
+use js::rust::{define_methods, Runtime, SIMPLE_GLOBAL_CLASS};
+use std::ptr;
+
+#[test]
+fn rooting() {
+ unsafe {
+ let runtime = Runtime::new(false).unwrap();
+ JS_SetGCZeal(runtime.cx(), 2, 1);
+
+ let cx = runtime.cx();
+ let h_option = JS::OnNewGlobalHookOption::FireOnNewGlobalHook;
+ let c_option = JS::RealmOptions::default();
+
+ rooted!(in(cx) let global = JS_NewGlobalObject(cx,
+ &SIMPLE_GLOBAL_CLASS,
+ ptr::null_mut(),
+ h_option,
+ &c_option));
+ let _ar = js::ar::AutoRealm::with_obj(cx, global.get());
+ rooted!(in(cx) let prototype_proto = JS::GetRealmObjectPrototype(cx));
+ rooted!(in(cx) let proto = JS_NewObjectWithGivenProto(cx,
+ &CLASS as *const _,
+ prototype_proto.handle()));
+ define_methods(cx, proto.handle(), &METHODS[..]).unwrap();
+ }
+}
+
+unsafe extern "C" fn generic_method(_: *mut JSContext, _: u32, _: *mut JS::Value) -> bool {
+ true
+}
+
+lazy_static! {
+ static ref METHODS: [JSFunctionSpec; 4] = [
+ JSFunctionSpec {
+ name: JSFunctionSpec_Name {
+ string_: b"addEventListener\0" as *const u8 as *const libc::c_char,
+ },
+ call: JSNativeWrapper {
+ op: Some(generic_method),
+ info: ptr::null()
+ },
+ nargs: 2,
+ flags: JSPROP_ENUMERATE as u16,
+ selfHostedName: 0 as *const libc::c_char
+ },
+ JSFunctionSpec {
+ name: JSFunctionSpec_Name {
+ string_: b"removeEventListener\0" as *const u8 as *const libc::c_char,
+ },
+ call: JSNativeWrapper {
+ op: Some(generic_method),
+ info: ptr::null()
+ },
+ nargs: 2,
+ flags: JSPROP_ENUMERATE as u16,
+ selfHostedName: 0 as *const libc::c_char
+ },
+ JSFunctionSpec {
+ name: JSFunctionSpec_Name {
+ string_: b"dispatchEvent\0" as *const u8 as *const libc::c_char,
+ },
+ call: JSNativeWrapper {
+ op: Some(generic_method),
+ info: ptr::null()
+ },
+ nargs: 1,
+ flags: JSPROP_ENUMERATE as u16,
+ selfHostedName: 0 as *const libc::c_char
+ },
+ JSFunctionSpec {
+ name: JSFunctionSpec_Name {
+ string_: ptr::null(),
+ },
+ call: JSNativeWrapper {
+ op: None,
+ info: ptr::null()
+ },
+ nargs: 0,
+ flags: 0,
+ selfHostedName: ptr::null()
+ }
+ ];
+}
+
+static CLASS: JSClass = JSClass {
+ name: b"EventTargetPrototype\0" as *const u8 as *const libc::c_char,
+ flags: 0,
+ cOps: 0 as *const _,
+ spec: 0 as *mut _,
+ ext: 0 as *mut _,
+ oOps: 0 as *mut _,
+};
diff --git a/js/rust/tests/runtime.rs b/js/rust/tests/runtime.rs
new file mode 100644
index 0000000000..ac69f5034b
--- /dev/null
+++ b/js/rust/tests/runtime.rs
@@ -0,0 +1,59 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#[macro_use]
+extern crate js;
+extern crate libc;
+
+use js::jsapi::*;
+use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS};
+use std::ptr;
+
+#[test]
+fn runtime() {
+ unsafe {
+ let runtime = Runtime::new(false).unwrap();
+
+ let cx = runtime.cx();
+ let h_option = JS::OnNewGlobalHookOption::FireOnNewGlobalHook;
+ let c_option = JS::RealmOptions::default();
+
+ rooted!(in(cx) let global = JS_NewGlobalObject(cx,
+ &SIMPLE_GLOBAL_CLASS,
+ ptr::null_mut(),
+ h_option,
+ &c_option));
+ let _ar = js::ar::AutoRealm::with_obj(cx, global.get());
+ rooted!(in(cx) let _object = JS_NewObject(cx, &CLASS as *const _));
+ }
+
+ assert!(Runtime::new(false).is_err());
+}
+
+unsafe extern "C" fn finalize(_fop: *mut JSFreeOp, _object: *mut JSObject) {
+ assert!(!Runtime::get().is_null());
+}
+
+static CLASS_OPS: JSClassOps = JSClassOps {
+ addProperty: None,
+ delProperty: None,
+ enumerate: None,
+ newEnumerate: None,
+ resolve: None,
+ mayResolve: None,
+ finalize: Some(finalize),
+ call: None,
+ hasInstance: None,
+ construct: None,
+ trace: None,
+};
+
+static CLASS: JSClass = JSClass {
+ name: b"EventTargetPrototype\0" as *const u8 as *const libc::c_char,
+ flags: 0 | JSCLASS_FOREGROUND_FINALIZE,
+ cOps: &CLASS_OPS as *const JSClassOps,
+ spec: 0 as *mut _,
+ ext: 0 as *mut _,
+ oOps: 0 as *mut _,
+};
diff --git a/js/rust/tests/stack_limit.rs b/js/rust/tests/stack_limit.rs
new file mode 100644
index 0000000000..02613d3793
--- /dev/null
+++ b/js/rust/tests/stack_limit.rs
@@ -0,0 +1,44 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#[macro_use]
+extern crate js;
+
+use js::jsapi::root::JS_NewGlobalObject;
+use js::jsapi::root::JS::OnNewGlobalHookOption;
+use js::jsapi::root::JS::RealmOptions;
+use js::jsval::UndefinedValue;
+use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS};
+
+use std::ptr;
+
+#[test]
+fn stack_limit() {
+ let rt = Runtime::new(false).unwrap();
+ let cx = rt.cx();
+
+ unsafe {
+ let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook;
+ let c_option = RealmOptions::default();
+ let global = JS_NewGlobalObject(
+ cx,
+ &SIMPLE_GLOBAL_CLASS,
+ ptr::null_mut(),
+ h_option,
+ &c_option,
+ );
+ rooted!(in(cx) let global_root = global);
+ let global = global_root.handle();
+ rooted!(in(cx) let mut rval = UndefinedValue());
+ assert!(rt
+ .evaluate_script(
+ global,
+ "function f() { f.apply() } f()",
+ "test",
+ 1,
+ rval.handle_mut()
+ )
+ .is_err());
+ }
+}
diff --git a/js/rust/tests/typedarray.rs b/js/rust/tests/typedarray.rs
new file mode 100644
index 0000000000..6cd759f5f3
--- /dev/null
+++ b/js/rust/tests/typedarray.rs
@@ -0,0 +1,104 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#[macro_use]
+extern crate js;
+
+use js::jsapi::*;
+use js::jsval::UndefinedValue;
+use js::rust::Runtime as Runtime_;
+use js::rust::SIMPLE_GLOBAL_CLASS;
+use js::typedarray::{CreateWith, Uint32Array};
+use std::ptr;
+
+#[test]
+fn typedarray() {
+ let rt = Runtime_::new(false).unwrap();
+ let cx = rt.cx();
+
+ unsafe {
+ rooted!(in(cx) let global =
+ JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
+ JS::OnNewGlobalHookOption::FireOnNewGlobalHook,
+ &JS::RealmOptions::default())
+ );
+
+ let _ar = js::ar::AutoRealm::with_obj(cx, global.get());
+
+ rooted!(in(cx) let mut rval = UndefinedValue());
+ assert!(rt
+ .evaluate_script(
+ global.handle(),
+ "new Uint8Array([0, 2, 4])",
+ "test",
+ 1,
+ rval.handle_mut()
+ )
+ .is_ok());
+ assert!(rval.is_object());
+
+ typedarray!(in(cx) let array: Uint8Array = rval.to_object());
+ assert_eq!(array.unwrap().as_slice(), &[0, 2, 4][..]);
+
+ typedarray!(in(cx) let array: Uint16Array = rval.to_object());
+ assert!(array.is_err());
+
+ typedarray!(in(cx) let view: ArrayBufferView = rval.to_object());
+ assert_eq!(
+ view.unwrap().get_array_type(),
+ js::jsapi::js::Scalar::Type::Uint8
+ );
+
+ rooted!(in(cx) let mut rval = ptr::null_mut());
+ assert!(Uint32Array::create(cx, CreateWith::Slice(&[1, 3, 5]), rval.handle_mut()).is_ok());
+
+ typedarray!(in(cx) let array: Uint32Array = rval.get());
+ assert_eq!(array.unwrap().as_slice(), &[1, 3, 5][..]);
+
+ typedarray!(in(cx) let mut array: Uint32Array = rval.get());
+ array.as_mut().unwrap().update(&[2, 4, 6]);
+ assert_eq!(array.unwrap().as_slice(), &[2, 4, 6][..]);
+
+ rooted!(in(cx) let rval = ptr::null_mut());
+ typedarray!(in(cx) let array: Uint8Array = rval.get());
+ assert!(array.is_err());
+
+ rooted!(in(cx) let mut rval = ptr::null_mut());
+ assert!(Uint32Array::create(cx, CreateWith::Length(5), rval.handle_mut()).is_ok());
+
+ typedarray!(in(cx) let array: Uint32Array = rval.get());
+ assert_eq!(array.unwrap().as_slice(), &[0, 0, 0, 0, 0]);
+
+ typedarray!(in(cx) let mut array: Uint32Array = rval.get());
+ array.as_mut().unwrap().update(&[0, 1, 2, 3]);
+ assert_eq!(array.unwrap().as_slice(), &[0, 1, 2, 3, 0]);
+
+ typedarray!(in(cx) let view: ArrayBufferView = rval.get());
+ assert_eq!(
+ view.unwrap().get_array_type(),
+ js::jsapi::js::Scalar::Type::Uint32
+ );
+ }
+}
+
+#[test]
+#[should_panic]
+fn typedarray_update_panic() {
+ let rt = Runtime_::new(false).unwrap();
+ let cx = rt.cx();
+
+ unsafe {
+ rooted!(in(cx) let global =
+ JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
+ JS::OnNewGlobalHookOption::FireOnNewGlobalHook,
+ &JS::RealmOptions::default())
+ );
+
+ let _ar = js::ar::AutoRealm::with_obj(cx, global.get());
+ rooted!(in(cx) let mut rval = ptr::null_mut());
+ let _ = Uint32Array::create(cx, CreateWith::Slice(&[1, 2, 3, 4, 5]), rval.handle_mut());
+ typedarray!(in(cx) let mut array: Uint32Array = rval.get());
+ array.as_mut().unwrap().update(&[0, 2, 4, 6, 8, 10]);
+ }
+}
diff --git a/js/rust/tests/value.rs b/js/rust/tests/value.rs
new file mode 100644
index 0000000000..0622268cd8
--- /dev/null
+++ b/js/rust/tests/value.rs
@@ -0,0 +1,64 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#[macro_use]
+extern crate js;
+
+use js::jsapi::root::JS_NewGlobalObject;
+use js::jsapi::root::JS::OnNewGlobalHookOption;
+use js::jsapi::root::JS::RealmOptions;
+use js::jsval::UndefinedValue;
+use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS};
+
+use std::ptr;
+
+#[test]
+fn is_symbol() {
+ let rt = Runtime::new(false).unwrap();
+ let cx = rt.cx();
+
+ unsafe {
+ rooted!(in(cx) let global =
+ JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
+ OnNewGlobalHookOption::FireOnNewGlobalHook,
+ &RealmOptions::default())
+ );
+ rooted!(in(cx) let mut rval = UndefinedValue());
+ assert!(rt
+ .evaluate_script(
+ global.handle(),
+ "Symbol('test')",
+ "test",
+ 1,
+ rval.handle_mut()
+ )
+ .is_ok());
+ assert!(rval.is_symbol());
+ }
+}
+
+#[test]
+fn is_not_symbol() {
+ let rt = Runtime::new(false).unwrap();
+ let cx = rt.cx();
+
+ unsafe {
+ rooted!(in(cx) let global =
+ JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
+ OnNewGlobalHookOption::FireOnNewGlobalHook,
+ &RealmOptions::default())
+ );
+ rooted!(in(cx) let mut rval = UndefinedValue());
+ assert!(rt
+ .evaluate_script(
+ global.handle(),
+ "'not a symbol'",
+ "test",
+ 1,
+ rval.handle_mut()
+ )
+ .is_ok());
+ assert!(!rval.is_symbol());
+ }
+}
diff --git a/js/rust/tests/vec_conversion.rs b/js/rust/tests/vec_conversion.rs
new file mode 100644
index 0000000000..a4446799aa
--- /dev/null
+++ b/js/rust/tests/vec_conversion.rs
@@ -0,0 +1,81 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#[macro_use]
+extern crate js;
+
+use js::ar::AutoRealm;
+use js::conversions::ConversionBehavior;
+use js::conversions::ConversionResult;
+use js::conversions::FromJSValConvertible;
+use js::conversions::ToJSValConvertible;
+use js::jsapi::root::JS_NewGlobalObject;
+use js::jsapi::root::JS::InitRealmStandardClasses;
+use js::jsapi::root::JS::OnNewGlobalHookOption;
+use js::jsapi::root::JS::RealmOptions;
+use js::jsval::UndefinedValue;
+use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS};
+
+use std::ptr;
+
+fn assert_is_array(cx: *mut js::jsapi::root::JSContext, val: js::jsapi::root::JS::HandleValue) {
+ let mut is_array = false;
+ assert!(unsafe { js::jsapi::root::JS::IsArrayObject(cx, val, &mut is_array as *mut _) });
+ assert!(is_array);
+}
+
+#[test]
+fn vec_conversion() {
+ let rt = Runtime::new(false).unwrap();
+ let cx = rt.cx();
+
+ let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook;
+ let c_option = RealmOptions::default();
+
+ unsafe {
+ let global = JS_NewGlobalObject(
+ cx,
+ &SIMPLE_GLOBAL_CLASS,
+ ptr::null_mut(),
+ h_option,
+ &c_option,
+ );
+ rooted!(in(cx) let global_root = global);
+ let global = global_root.handle();
+
+ let _ar = AutoRealm::with_obj(cx, global.get());
+ assert!(InitRealmStandardClasses(cx));
+
+ rooted!(in(cx) let mut rval = UndefinedValue());
+
+ let orig_vec: Vec<f32> = vec![1.0, 2.9, 3.0];
+ orig_vec.to_jsval(cx, rval.handle_mut());
+ assert_is_array(cx, rval.handle());
+ let converted = Vec::<f32>::from_jsval(cx, rval.handle(), ()).unwrap();
+ assert_eq!(&orig_vec, converted.get_success_value().unwrap());
+
+ let orig_vec: Vec<i32> = vec![1, 2, 3];
+ orig_vec.to_jsval(cx, rval.handle_mut());
+ assert_is_array(cx, rval.handle());
+ let converted =
+ Vec::<i32>::from_jsval(cx, rval.handle(), ConversionBehavior::Default).unwrap();
+
+ assert_eq!(&orig_vec, converted.get_success_value().unwrap());
+
+ rt.evaluate_script(global, "new Set([1, 2, 3])", "test", 1, rval.handle_mut())
+ .unwrap();
+ let converted =
+ Vec::<i32>::from_jsval(cx, rval.handle(), ConversionBehavior::Default).unwrap();
+
+ assert_eq!(&orig_vec, converted.get_success_value().unwrap());
+
+ rt.evaluate_script(global, "({})", "test", 1, rval.handle_mut())
+ .unwrap();
+ let converted = Vec::<i32>::from_jsval(cx, rval.handle(), ConversionBehavior::Default);
+ assert!(match converted {
+ Ok(ConversionResult::Failure(_)) => true,
+ _ => false,
+ });
+ }
+}