summaryrefslogtreecommitdiff
path: root/test_napi/src
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2022-10-05 07:06:44 -0700
committerGitHub <noreply@github.com>2022-10-05 19:36:44 +0530
commit0b016a7fb8639ce49603c8c339539174b191a4b1 (patch)
treec511060d701db60ede0214b7280e89c5749bbe62 /test_napi/src
parent3a3a8484069c9c6955fcb83ea761f9f74638175a (diff)
feat(npm): implement Node API (#13633)
This PR implements the NAPI for loading native modules into Deno. Co-authored-by: Bartek IwaƄczuk <biwanczuk@gmail.com> Co-authored-by: DjDeveloper <43033058+DjDeveloperr@users.noreply.github.com> Co-authored-by: Ryan Dahl <ry@tinyclouds.org>
Diffstat (limited to 'test_napi/src')
-rw-r--r--test_napi/src/array.rs73
-rw-r--r--test_napi/src/async.rs112
-rw-r--r--test_napi/src/callback.rs113
-rw-r--r--test_napi/src/coerce.rs71
-rw-r--r--test_napi/src/lib.rs78
-rw-r--r--test_napi/src/numbers.rs55
-rw-r--r--test_napi/src/object_wrap.rs154
-rw-r--r--test_napi/src/promise.rs76
-rw-r--r--test_napi/src/properties.rs89
-rw-r--r--test_napi/src/strings.rs45
-rw-r--r--test_napi/src/typedarray.rs53
11 files changed, 919 insertions, 0 deletions
diff --git a/test_napi/src/array.rs b/test_napi/src/array.rs
new file mode 100644
index 000000000..767aa08b1
--- /dev/null
+++ b/test_napi/src/array.rs
@@ -0,0 +1,73 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use napi_sys::Status::napi_ok;
+use napi_sys::ValueType::napi_number;
+use napi_sys::ValueType::napi_object;
+use napi_sys::*;
+use std::ptr;
+
+extern "C" fn test_array_new(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ let mut ty = -1;
+ assert!(unsafe { napi_typeof(env, args[0], &mut ty) } == napi_ok);
+ assert_eq!(ty, napi_object);
+
+ let mut value: napi_value = ptr::null_mut();
+ assert!(unsafe { napi_create_array(env, &mut value) } == napi_ok);
+
+ let mut length: u32 = 0;
+ assert!(
+ unsafe { napi_get_array_length(env, args[0], &mut length) } == napi_ok
+ );
+
+ for i in 0..length {
+ let mut e: napi_value = ptr::null_mut();
+ assert!(unsafe { napi_get_element(env, args[0], i, &mut e) } == napi_ok);
+ assert!(unsafe { napi_set_element(env, value, i, e) } == napi_ok);
+ }
+
+ value
+}
+
+extern "C" fn test_array_new_with_length(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ let mut ty = -1;
+ assert!(unsafe { napi_typeof(env, args[0], &mut ty) } == napi_ok);
+ assert_eq!(ty, napi_number);
+
+ let mut len: u32 = 0;
+ assert!(unsafe { napi_get_value_uint32(env, args[0], &mut len) } == napi_ok);
+
+ let mut value: napi_value = ptr::null_mut();
+ assert!(
+ unsafe { napi_create_array_with_length(env, len as usize, &mut value) }
+ == napi_ok
+ );
+
+ value
+}
+
+pub fn init(env: napi_env, exports: napi_value) {
+ let properties = &[
+ crate::new_property!(env, "test_array_new\0", test_array_new),
+ crate::new_property!(
+ env,
+ "test_array_new_with_length\0",
+ test_array_new_with_length
+ ),
+ ];
+
+ unsafe {
+ napi_define_properties(env, exports, properties.len(), properties.as_ptr())
+ };
+}
diff --git a/test_napi/src/async.rs b/test_napi/src/async.rs
new file mode 100644
index 000000000..d14871a7c
--- /dev/null
+++ b/test_napi/src/async.rs
@@ -0,0 +1,112 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use napi_sys::Status::napi_ok;
+use napi_sys::ValueType::napi_function;
+use napi_sys::*;
+use std::os::raw::c_void;
+use std::ptr;
+
+pub struct Baton {
+ called: bool,
+ func: napi_ref,
+ task: napi_async_work,
+}
+
+unsafe extern "C" fn execute(_env: napi_env, data: *mut c_void) {
+ let baton: &mut Baton = &mut *(data as *mut Baton);
+ assert!(!baton.called);
+ assert!(!baton.func.is_null());
+
+ baton.called = true;
+}
+
+unsafe extern "C" fn complete(
+ env: napi_env,
+ status: napi_status,
+ data: *mut c_void,
+) {
+ assert!(status == napi_ok);
+ let baton: Box<Baton> = Box::from_raw(data as *mut Baton);
+ assert!(baton.called);
+ assert!(!baton.func.is_null());
+
+ let mut global: napi_value = ptr::null_mut();
+ assert!(napi_get_global(env, &mut global) == napi_ok);
+
+ let mut callback: napi_value = ptr::null_mut();
+ assert!(napi_get_reference_value(env, baton.func, &mut callback) == napi_ok);
+
+ let mut _result: napi_value = ptr::null_mut();
+ assert!(
+ napi_call_function(env, global, callback, 0, ptr::null(), &mut _result)
+ == napi_ok
+ );
+
+ assert!(napi_delete_reference(env, baton.func) == napi_ok);
+ assert!(napi_delete_async_work(env, baton.task) == napi_ok);
+}
+
+extern "C" fn test_async_work(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ let mut ty = -1;
+ assert!(unsafe { napi_typeof(env, args[0], &mut ty) } == napi_ok);
+ assert_eq!(ty, napi_function);
+
+ let mut resource_name: napi_value = ptr::null_mut();
+ assert!(
+ unsafe {
+ napi_create_string_utf8(
+ env,
+ "test_async_resource\0".as_ptr() as *const i8,
+ usize::MAX,
+ &mut resource_name,
+ )
+ } == napi_ok
+ );
+
+ let mut async_work: napi_async_work = ptr::null_mut();
+
+ let mut func: napi_ref = ptr::null_mut();
+ assert!(
+ unsafe { napi_create_reference(env, args[0], 1, &mut func) } == napi_ok
+ );
+ let baton = Box::new(Baton {
+ called: false,
+ func,
+ task: async_work,
+ });
+
+ assert!(
+ unsafe {
+ napi_create_async_work(
+ env,
+ ptr::null_mut(),
+ resource_name,
+ Some(execute),
+ Some(complete),
+ Box::into_raw(baton) as *mut c_void,
+ &mut async_work,
+ )
+ } == napi_ok
+ );
+ assert!(unsafe { napi_queue_async_work(env, async_work) } == napi_ok);
+
+ ptr::null_mut()
+}
+
+pub fn init(env: napi_env, exports: napi_value) {
+ let properties = &[crate::new_property!(
+ env,
+ "test_async_work\0",
+ test_async_work
+ )];
+
+ unsafe {
+ napi_define_properties(env, exports, properties.len(), properties.as_ptr())
+ };
+}
diff --git a/test_napi/src/callback.rs b/test_napi/src/callback.rs
new file mode 100644
index 000000000..bf6062913
--- /dev/null
+++ b/test_napi/src/callback.rs
@@ -0,0 +1,113 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use napi_sys::Status::napi_ok;
+use napi_sys::ValueType::napi_function;
+use napi_sys::ValueType::napi_object;
+use napi_sys::*;
+use std::ptr;
+
+/// `test_callback_run((a, b) => a + b, [1, 2])` => 3
+extern "C" fn test_callback_run(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 2);
+ assert_eq!(argc, 2);
+
+ let mut ty = -1;
+ assert!(unsafe { napi_typeof(env, args[0], &mut ty) } == napi_ok);
+ assert_eq!(ty, napi_function);
+
+ let mut ty = -1;
+ assert!(unsafe { napi_typeof(env, args[1], &mut ty) } == napi_ok);
+ assert_eq!(ty, napi_object);
+
+ let mut len = 0;
+ assert!(unsafe { napi_get_array_length(env, args[1], &mut len) } == napi_ok);
+
+ let mut argv = Vec::with_capacity(len as usize);
+ for index in 0..len {
+ let mut value: napi_value = ptr::null_mut();
+ assert!(
+ unsafe { napi_get_element(env, args[1], index, &mut value) } == napi_ok
+ );
+ argv.push(value);
+ }
+ let mut global: napi_value = ptr::null_mut();
+ assert!(unsafe { napi_get_global(env, &mut global) } == napi_ok);
+
+ let mut result: napi_value = ptr::null_mut();
+ assert!(
+ unsafe {
+ napi_call_function(
+ env,
+ global,
+ args[0],
+ argv.len(),
+ argv.as_mut_ptr(),
+ &mut result,
+ )
+ } == napi_ok
+ );
+
+ result
+}
+
+extern "C" fn test_callback_run_with_recv(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 3);
+ assert_eq!(argc, 3);
+
+ let mut ty = -1;
+ assert!(unsafe { napi_typeof(env, args[0], &mut ty) } == napi_ok);
+ assert_eq!(ty, napi_function);
+
+ let mut ty = -1;
+ assert!(unsafe { napi_typeof(env, args[1], &mut ty) } == napi_ok);
+ assert_eq!(ty, napi_object);
+
+ let mut len = 0;
+ assert!(unsafe { napi_get_array_length(env, args[1], &mut len) } == napi_ok);
+
+ let mut argv = Vec::with_capacity(len as usize);
+ for index in 0..len {
+ let mut value: napi_value = ptr::null_mut();
+ assert!(
+ unsafe { napi_get_element(env, args[1], index, &mut value) } == napi_ok
+ );
+ argv.push(value);
+ }
+
+ let mut result: napi_value = ptr::null_mut();
+ assert!(
+ unsafe {
+ napi_call_function(
+ env,
+ args[2], // recv
+ args[0], // cb
+ argv.len(),
+ argv.as_mut_ptr(),
+ &mut result,
+ )
+ } == napi_ok
+ );
+
+ result
+}
+
+pub fn init(env: napi_env, exports: napi_value) {
+ let properties = &[
+ crate::new_property!(env, "test_callback_run\0", test_callback_run),
+ crate::new_property!(
+ env,
+ "test_callback_run_with_recv\0",
+ test_callback_run_with_recv
+ ),
+ ];
+
+ unsafe {
+ napi_define_properties(env, exports, properties.len(), properties.as_ptr())
+ };
+}
diff --git a/test_napi/src/coerce.rs b/test_napi/src/coerce.rs
new file mode 100644
index 000000000..611540fae
--- /dev/null
+++ b/test_napi/src/coerce.rs
@@ -0,0 +1,71 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use napi_sys::Status::napi_ok;
+use napi_sys::*;
+use std::ptr;
+
+extern "C" fn test_coerce_bool(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ let mut value: napi_value = ptr::null_mut();
+ assert!(unsafe { napi_coerce_to_bool(env, args[0], &mut value) } == napi_ok);
+ value
+}
+
+extern "C" fn test_coerce_number(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ let mut value: napi_value = ptr::null_mut();
+ assert!(
+ unsafe { napi_coerce_to_number(env, args[0], &mut value) } == napi_ok
+ );
+ value
+}
+
+extern "C" fn test_coerce_object(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ let mut value: napi_value = ptr::null_mut();
+ assert!(
+ unsafe { napi_coerce_to_object(env, args[0], &mut value) } == napi_ok
+ );
+ value
+}
+
+extern "C" fn test_coerce_string(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ let mut value: napi_value = ptr::null_mut();
+ assert!(
+ unsafe { napi_coerce_to_string(env, args[0], &mut value) } == napi_ok
+ );
+ value
+}
+pub fn init(env: napi_env, exports: napi_value) {
+ let properties = &[
+ crate::new_property!(env, "test_coerce_bool\0", test_coerce_bool),
+ crate::new_property!(env, "test_coerce_number\0", test_coerce_number),
+ crate::new_property!(env, "test_coerce_object\0", test_coerce_object),
+ crate::new_property!(env, "test_coerce_string\0", test_coerce_string),
+ ];
+
+ unsafe {
+ napi_define_properties(env, exports, properties.len(), properties.as_ptr())
+ };
+}
diff --git a/test_napi/src/lib.rs b/test_napi/src/lib.rs
new file mode 100644
index 000000000..e058686c5
--- /dev/null
+++ b/test_napi/src/lib.rs
@@ -0,0 +1,78 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+#![allow(clippy::all)]
+#![allow(clippy::undocumented_unsafe_blocks)]
+
+use napi_sys::*;
+
+pub mod array;
+pub mod r#async;
+pub mod callback;
+pub mod coerce;
+pub mod numbers;
+pub mod object_wrap;
+pub mod promise;
+pub mod properties;
+pub mod strings;
+pub mod typedarray;
+
+#[macro_export]
+macro_rules! get_callback_info {
+ ($env: expr, $callback_info: expr, $size: literal) => {{
+ let mut args = [ptr::null_mut(); $size];
+ let mut argc = $size;
+ let mut this = ptr::null_mut();
+ unsafe {
+ assert!(
+ napi_get_cb_info(
+ $env,
+ $callback_info,
+ &mut argc,
+ args.as_mut_ptr(),
+ &mut this,
+ ptr::null_mut(),
+ ) == napi_ok,
+ )
+ };
+ (args, argc, this)
+ }};
+}
+
+#[macro_export]
+macro_rules! new_property {
+ ($env: expr, $name: expr, $value: expr) => {
+ napi_property_descriptor {
+ utf8name: $name.as_ptr() as *const i8,
+ name: ptr::null_mut(),
+ method: Some($value),
+ getter: None,
+ setter: None,
+ data: ptr::null_mut(),
+ attributes: 0,
+ value: ptr::null_mut(),
+ }
+ };
+}
+
+#[no_mangle]
+unsafe extern "C" fn napi_register_module_v1(
+ env: napi_env,
+ exports: napi_value,
+) -> napi_value {
+ #[cfg(windows)]
+ {
+ napi_sys::setup();
+ }
+
+ strings::init(env, exports);
+ numbers::init(env, exports);
+ typedarray::init(env, exports);
+ array::init(env, exports);
+ properties::init(env, exports);
+ promise::init(env, exports);
+ coerce::init(env, exports);
+ object_wrap::init(env, exports);
+ callback::init(env, exports);
+ r#async::init(env, exports);
+
+ exports
+}
diff --git a/test_napi/src/numbers.rs b/test_napi/src/numbers.rs
new file mode 100644
index 000000000..a6628af13
--- /dev/null
+++ b/test_napi/src/numbers.rs
@@ -0,0 +1,55 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use napi_sys::Status::napi_ok;
+use napi_sys::ValueType::napi_number;
+use napi_sys::*;
+use std::ptr;
+
+extern "C" fn test_int32(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ let mut ty = -1;
+ assert!(unsafe { napi_typeof(env, args[0], &mut ty) } == napi_ok);
+ assert_eq!(ty, napi_number);
+
+ let mut int32 = -1;
+ assert!(unsafe { napi_get_value_int32(env, args[0], &mut int32) } == napi_ok);
+
+ let mut value: napi_value = ptr::null_mut();
+ assert!(unsafe { napi_create_int32(env, int32, &mut value) } == napi_ok);
+ value
+}
+
+extern "C" fn test_int64(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ let mut ty = -1;
+ assert!(unsafe { napi_typeof(env, args[0], &mut ty) } == napi_ok);
+ assert_eq!(ty, napi_number);
+
+ let mut int64 = -1;
+ assert!(unsafe { napi_get_value_int64(env, args[0], &mut int64) } == napi_ok);
+
+ let mut value: napi_value = ptr::null_mut();
+ assert!(unsafe { napi_create_int64(env, int64, &mut value) } == napi_ok);
+ value
+}
+
+pub fn init(env: napi_env, exports: napi_value) {
+ let properties = &[
+ crate::new_property!(env, "test_int32\0", test_int32),
+ crate::new_property!(env, "test_int64\0", test_int64),
+ ];
+
+ unsafe {
+ napi_define_properties(env, exports, properties.len(), properties.as_ptr())
+ };
+}
diff --git a/test_napi/src/object_wrap.rs b/test_napi/src/object_wrap.rs
new file mode 100644
index 000000000..3b849b2dc
--- /dev/null
+++ b/test_napi/src/object_wrap.rs
@@ -0,0 +1,154 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use napi_sys::Status::napi_ok;
+use napi_sys::ValueType::napi_number;
+use napi_sys::*;
+use std::os::raw::c_void;
+use std::ptr;
+
+pub struct NapiObject {
+ counter: i32,
+ _wrapper: napi_ref,
+}
+
+impl NapiObject {
+ #[allow(clippy::new_ret_no_self)]
+ pub extern "C" fn new(env: napi_env, info: napi_callback_info) -> napi_value {
+ let mut new_target: napi_value = ptr::null_mut();
+ assert!(
+ unsafe { napi_get_new_target(env, info, &mut new_target) } == napi_ok
+ );
+ let is_constructor = !new_target.is_null();
+
+ let (args, argc, this) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ if is_constructor {
+ let mut value = 0;
+
+ let mut ty = -1;
+ assert!(unsafe { napi_typeof(env, args[0], &mut ty) } == napi_ok);
+ assert_eq!(ty, napi_number);
+
+ assert!(
+ unsafe { napi_get_value_int32(env, args[0], &mut value) } == napi_ok
+ );
+
+ let mut wrapper: napi_ref = ptr::null_mut();
+ let obj = Box::new(Self {
+ counter: value,
+ _wrapper: wrapper,
+ });
+ assert!(
+ unsafe {
+ napi_wrap(
+ env,
+ this,
+ Box::into_raw(obj) as *mut c_void,
+ None,
+ ptr::null_mut(),
+ &mut wrapper,
+ )
+ } == napi_ok
+ );
+
+ return this;
+ }
+
+ unreachable!();
+ }
+
+ pub extern "C" fn set_value(
+ env: napi_env,
+ info: napi_callback_info,
+ ) -> napi_value {
+ let (args, argc, this) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+ let mut obj: *mut Self = ptr::null_mut();
+ assert!(
+ unsafe { napi_unwrap(env, this, &mut obj as *mut _ as *mut *mut c_void) }
+ == napi_ok
+ );
+
+ assert!(
+ unsafe { napi_get_value_int32(env, args[0], &mut (*obj).counter) }
+ == napi_ok
+ );
+
+ ptr::null_mut()
+ }
+
+ pub extern "C" fn get_value(
+ env: napi_env,
+ info: napi_callback_info,
+ ) -> napi_value {
+ let (_args, argc, this) = crate::get_callback_info!(env, info, 0);
+ assert_eq!(argc, 0);
+ let mut obj: *mut Self = ptr::null_mut();
+ assert!(
+ unsafe { napi_unwrap(env, this, &mut obj as *mut _ as *mut *mut c_void) }
+ == napi_ok
+ );
+
+ let mut num: napi_value = ptr::null_mut();
+ assert!(
+ unsafe { napi_create_int32(env, (*obj).counter, &mut num) } == napi_ok
+ );
+
+ num
+ }
+
+ pub extern "C" fn increment(
+ env: napi_env,
+ info: napi_callback_info,
+ ) -> napi_value {
+ let (_args, argc, this) = crate::get_callback_info!(env, info, 0);
+ assert_eq!(argc, 0);
+ let mut obj: *mut Self = ptr::null_mut();
+ assert!(
+ unsafe { napi_unwrap(env, this, &mut obj as *mut _ as *mut *mut c_void) }
+ == napi_ok
+ );
+
+ unsafe {
+ (*obj).counter += 1;
+ }
+
+ ptr::null_mut()
+ }
+}
+
+pub fn init(env: napi_env, exports: napi_value) {
+ let properties = &[
+ crate::new_property!(env, "set_value\0", NapiObject::set_value),
+ crate::new_property!(env, "get_value\0", NapiObject::get_value),
+ crate::new_property!(env, "increment\0", NapiObject::increment),
+ ];
+
+ let mut cons: napi_value = ptr::null_mut();
+ assert!(
+ unsafe {
+ napi_define_class(
+ env,
+ "NapiObject\0".as_ptr() as *mut i8,
+ usize::MAX,
+ Some(NapiObject::new),
+ ptr::null_mut(),
+ properties.len(),
+ properties.as_ptr(),
+ &mut cons,
+ )
+ } == napi_ok
+ );
+
+ assert!(
+ unsafe {
+ napi_set_named_property(
+ env,
+ exports,
+ "NapiObject\0".as_ptr() as *const i8,
+ cons,
+ )
+ } == napi_ok
+ );
+}
diff --git a/test_napi/src/promise.rs b/test_napi/src/promise.rs
new file mode 100644
index 000000000..ebb9dedab
--- /dev/null
+++ b/test_napi/src/promise.rs
@@ -0,0 +1,76 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use napi_sys::Status::napi_ok;
+use napi_sys::*;
+use std::ptr;
+
+static mut CURRENT_DEFERRED: napi_deferred = ptr::null_mut();
+
+extern "C" fn test_promise_new(
+ env: napi_env,
+ _info: napi_callback_info,
+) -> napi_value {
+ let mut value: napi_value = ptr::null_mut();
+ assert!(
+ unsafe { napi_create_promise(env, &mut CURRENT_DEFERRED, &mut value) }
+ == napi_ok
+ );
+ value
+}
+
+extern "C" fn test_promise_resolve(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ assert!(
+ unsafe { napi_resolve_deferred(env, CURRENT_DEFERRED, args[0]) } == napi_ok
+ );
+ unsafe { CURRENT_DEFERRED = ptr::null_mut() };
+ ptr::null_mut()
+}
+
+extern "C" fn test_promise_reject(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ assert!(
+ unsafe { napi_reject_deferred(env, CURRENT_DEFERRED, args[0]) } == napi_ok
+ );
+ unsafe { CURRENT_DEFERRED = ptr::null_mut() };
+ ptr::null_mut()
+}
+
+extern "C" fn test_promise_is(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ let mut is_promise: bool = false;
+ assert!(unsafe { napi_is_promise(env, args[0], &mut is_promise) } == napi_ok);
+
+ let mut result: napi_value = ptr::null_mut();
+ assert!(unsafe { napi_get_boolean(env, is_promise, &mut result) } == napi_ok);
+
+ result
+}
+
+pub fn init(env: napi_env, exports: napi_value) {
+ let properties = &[
+ crate::new_property!(env, "test_promise_new\0", test_promise_new),
+ crate::new_property!(env, "test_promise_resolve\0", test_promise_resolve),
+ crate::new_property!(env, "test_promise_reject\0", test_promise_reject),
+ crate::new_property!(env, "test_promise_is\0", test_promise_is),
+ ];
+
+ unsafe {
+ napi_define_properties(env, exports, properties.len(), properties.as_ptr())
+ };
+}
diff --git a/test_napi/src/properties.rs b/test_napi/src/properties.rs
new file mode 100644
index 000000000..89d95d6c6
--- /dev/null
+++ b/test_napi/src/properties.rs
@@ -0,0 +1,89 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use napi_sys::PropertyAttributes::*;
+use napi_sys::Status::napi_ok;
+use napi_sys::*;
+use std::ptr;
+
+pub fn init(env: napi_env, exports: napi_value) {
+ let mut number: napi_value = ptr::null_mut();
+ assert!(unsafe { napi_create_double(env, 1.0, &mut number) } == napi_ok);
+
+ // Key name as napi_value representing `v8::String`
+ let mut name_value: napi_value = ptr::null_mut();
+ assert!(
+ unsafe {
+ napi_create_string_utf8(
+ env,
+ "key_v8_string".as_ptr() as *const i8,
+ usize::MAX,
+ &mut name_value,
+ )
+ } == napi_ok
+ );
+
+ // Key symbol
+ let mut symbol_description: napi_value = ptr::null_mut();
+ let mut name_symbol: napi_value = ptr::null_mut();
+ assert!(
+ unsafe {
+ napi_create_string_utf8(
+ env,
+ "key_v8_symbol".as_ptr() as *const i8,
+ usize::MAX,
+ &mut symbol_description,
+ )
+ } == napi_ok
+ );
+ assert!(
+ unsafe { napi_create_symbol(env, symbol_description, &mut name_symbol) }
+ == napi_ok
+ );
+
+ let properties = &[
+ napi_property_descriptor {
+ utf8name: "test_property_rw\0".as_ptr() as *const i8,
+ name: ptr::null_mut(),
+ method: None,
+ getter: None,
+ setter: None,
+ data: ptr::null_mut(),
+ attributes: enumerable | writable,
+ value: number,
+ },
+ napi_property_descriptor {
+ utf8name: "test_property_r\0".as_ptr() as *const i8,
+ name: ptr::null_mut(),
+ method: None,
+ getter: None,
+ setter: None,
+ data: ptr::null_mut(),
+ attributes: enumerable,
+ value: number,
+ },
+ napi_property_descriptor {
+ utf8name: ptr::null(),
+ name: name_value,
+ method: None,
+ getter: None,
+ setter: None,
+ data: ptr::null_mut(),
+ attributes: enumerable,
+ value: number,
+ },
+ napi_property_descriptor {
+ utf8name: ptr::null(),
+ name: name_symbol,
+ method: None,
+ getter: None,
+ setter: None,
+ data: ptr::null_mut(),
+ attributes: enumerable,
+ value: number,
+ },
+ ];
+
+ unsafe {
+ napi_define_properties(env, exports, properties.len(), properties.as_ptr())
+ };
+}
diff --git a/test_napi/src/strings.rs b/test_napi/src/strings.rs
new file mode 100644
index 000000000..f4139c85a
--- /dev/null
+++ b/test_napi/src/strings.rs
@@ -0,0 +1,45 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use napi_sys::Status::napi_ok;
+use napi_sys::ValueType::napi_string;
+use napi_sys::*;
+use std::ptr;
+
+extern "C" fn test_utf8(env: napi_env, info: napi_callback_info) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ let mut ty = -1;
+ assert!(unsafe { napi_typeof(env, args[0], &mut ty) } == napi_ok);
+ assert_eq!(ty, napi_string);
+
+ args[0]
+}
+
+extern "C" fn test_utf16(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (args, argc, _) = crate::get_callback_info!(env, info, 1);
+ assert_eq!(argc, 1);
+
+ let mut ty = -1;
+ assert!(unsafe { napi_typeof(env, args[0], &mut ty) } == napi_ok);
+ assert_eq!(ty, napi_string);
+
+ args[0]
+}
+
+pub fn init(env: napi_env, exports: napi_value) {
+ let properties = &[
+ // utf8
+ crate::new_property!(env, "test_utf8\0", test_utf8),
+ // utf16
+ crate::new_property!(env, "test_utf16\0", test_utf16),
+ // latin1
+ ];
+
+ unsafe {
+ napi_define_properties(env, exports, properties.len(), properties.as_ptr())
+ };
+}
diff --git a/test_napi/src/typedarray.rs b/test_napi/src/typedarray.rs
new file mode 100644
index 000000000..f7d2e2f24
--- /dev/null
+++ b/test_napi/src/typedarray.rs
@@ -0,0 +1,53 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+use core::ffi::c_void;
+use napi_sys::Status::napi_ok;
+use napi_sys::TypedarrayType::uint8_array;
+use napi_sys::*;
+use std::ptr;
+
+extern "C" fn test_external(
+ env: napi_env,
+ _info: napi_callback_info,
+) -> napi_value {
+ let mut arraybuffer: napi_value = ptr::null_mut();
+ let mut external: Box<[u8; 4]> = Box::new([0, 1, 2, 3]);
+ assert!(
+ unsafe {
+ napi_create_external_arraybuffer(
+ env,
+ external.as_mut_ptr() as *mut c_void,
+ external.len(),
+ None,
+ ptr::null_mut(),
+ &mut arraybuffer,
+ )
+ } == napi_ok
+ );
+
+ let mut typedarray: napi_value = ptr::null_mut();
+ assert!(
+ unsafe {
+ napi_create_typedarray(
+ env,
+ uint8_array,
+ external.len(),
+ arraybuffer,
+ 0,
+ &mut typedarray,
+ )
+ } == napi_ok
+ );
+
+ std::mem::forget(external); // Leak into JS land
+ typedarray
+}
+
+pub fn init(env: napi_env, exports: napi_value) {
+ let properties =
+ &[crate::new_property!(env, "test_external\0", test_external)];
+
+ unsafe {
+ napi_define_properties(env, exports, properties.len(), properties.as_ptr())
+ };
+}