diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2022-10-05 07:06:44 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-05 19:36:44 +0530 |
commit | 0b016a7fb8639ce49603c8c339539174b191a4b1 (patch) | |
tree | c511060d701db60ede0214b7280e89c5749bbe62 /test_napi/src | |
parent | 3a3a8484069c9c6955fcb83ea761f9f74638175a (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.rs | 73 | ||||
-rw-r--r-- | test_napi/src/async.rs | 112 | ||||
-rw-r--r-- | test_napi/src/callback.rs | 113 | ||||
-rw-r--r-- | test_napi/src/coerce.rs | 71 | ||||
-rw-r--r-- | test_napi/src/lib.rs | 78 | ||||
-rw-r--r-- | test_napi/src/numbers.rs | 55 | ||||
-rw-r--r-- | test_napi/src/object_wrap.rs | 154 | ||||
-rw-r--r-- | test_napi/src/promise.rs | 76 | ||||
-rw-r--r-- | test_napi/src/properties.rs | 89 | ||||
-rw-r--r-- | test_napi/src/strings.rs | 45 | ||||
-rw-r--r-- | test_napi/src/typedarray.rs | 53 |
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()) + }; +} |