summaryrefslogtreecommitdiff
path: root/tests/napi/src/lib.rs
diff options
context:
space:
mode:
authorMatt Mastracci <matthew@mastracci.com>2024-02-12 13:46:50 -0700
committerGitHub <noreply@github.com>2024-02-12 13:46:50 -0700
commitf60720090c7bd8cdf91d7aebd0c42e01c86b3b83 (patch)
tree9becb7ff7e40d37769601fa049beccd101d58a98 /tests/napi/src/lib.rs
parentbd1358efab8ba7339a8e70034315fa7da840292e (diff)
chore: move test_ffi and test_nap to tests/ [WIP] (#22394)
Moving some additional NAPI and. FFI tests out of the tree root.
Diffstat (limited to 'tests/napi/src/lib.rs')
-rw-r--r--tests/napi/src/lib.rs171
1 files changed, 171 insertions, 0 deletions
diff --git a/tests/napi/src/lib.rs b/tests/napi/src/lib.rs
new file mode 100644
index 000000000..b9f93fbd6
--- /dev/null
+++ b/tests/napi/src/lib.rs
@@ -0,0 +1,171 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+#![allow(clippy::all)]
+#![allow(clippy::undocumented_unsafe_blocks)]
+
+use std::ffi::c_void;
+
+use napi_sys::*;
+
+pub mod array;
+pub mod arraybuffer;
+pub mod r#async;
+pub mod bigint;
+pub mod callback;
+pub mod coerce;
+pub mod date;
+pub mod env;
+pub mod error;
+pub mod finalizer;
+pub mod make_callback;
+pub mod mem;
+pub mod numbers;
+pub mod object_wrap;
+pub mod primitives;
+pub mod promise;
+pub mod properties;
+pub mod strings;
+pub mod symbol;
+pub mod tsfn;
+pub mod typedarray;
+
+#[macro_export]
+macro_rules! cstr {
+ ($s: literal) => {{
+ std::ffi::CString::new($s).unwrap().into_raw()
+ }};
+}
+
+#[macro_export]
+macro_rules! assert_napi_ok {
+ ($call: expr) => {{
+ assert_eq!(unsafe { $call }, napi_sys::Status::napi_ok);
+ }};
+}
+
+#[macro_export]
+macro_rules! napi_get_callback_info {
+ ($env: expr, $callback_info: expr, $size: literal) => {{
+ let mut args = [std::ptr::null_mut(); $size];
+ let mut argc = $size;
+ let mut this = std::ptr::null_mut();
+ crate::assert_napi_ok!(napi_get_cb_info(
+ $env,
+ $callback_info,
+ &mut argc,
+ args.as_mut_ptr(),
+ &mut this,
+ std::ptr::null_mut(),
+ ));
+ (args, argc, this)
+ }};
+}
+
+#[macro_export]
+macro_rules! napi_new_property {
+ ($env: expr, $name: expr, $value: expr) => {
+ napi_property_descriptor {
+ utf8name: concat!($name, "\0").as_ptr() as *const std::os::raw::c_char,
+ name: std::ptr::null_mut(),
+ method: Some($value),
+ getter: None,
+ setter: None,
+ data: std::ptr::null_mut(),
+ attributes: 0,
+ value: std::ptr::null_mut(),
+ }
+ };
+}
+
+extern "C" fn cleanup(arg: *mut c_void) {
+ println!("cleanup({})", arg as i64);
+}
+
+extern "C" fn remove_this_hook(arg: *mut c_void) {
+ let env = arg as napi_env;
+ unsafe { napi_remove_env_cleanup_hook(env, Some(remove_this_hook), arg) };
+}
+
+static SECRET: i64 = 42;
+static WRONG_SECRET: i64 = 17;
+static THIRD_SECRET: i64 = 18;
+
+extern "C" fn install_cleanup_hook(
+ env: napi_env,
+ info: napi_callback_info,
+) -> napi_value {
+ let (_args, argc, _) = napi_get_callback_info!(env, info, 1);
+ assert_eq!(argc, 0);
+
+ unsafe {
+ napi_add_env_cleanup_hook(env, Some(cleanup), WRONG_SECRET as *mut c_void);
+ napi_add_env_cleanup_hook(env, Some(cleanup), SECRET as *mut c_void);
+ napi_add_env_cleanup_hook(env, Some(cleanup), THIRD_SECRET as *mut c_void);
+ napi_add_env_cleanup_hook(env, Some(remove_this_hook), env as *mut c_void);
+ napi_remove_env_cleanup_hook(
+ env,
+ Some(cleanup),
+ WRONG_SECRET as *mut c_void,
+ );
+ }
+
+ std::ptr::null_mut()
+}
+
+pub fn init_cleanup_hook(env: napi_env, exports: napi_value) {
+ let properties = &[napi_new_property!(
+ env,
+ "installCleanupHook",
+ install_cleanup_hook
+ )];
+
+ assert_napi_ok!(napi_define_properties(
+ env,
+ exports,
+ properties.len(),
+ properties.as_ptr()
+ ));
+}
+
+#[no_mangle]
+unsafe extern "C" fn napi_register_module_v1(
+ env: napi_env,
+ _: napi_value,
+) -> napi_value {
+ #[cfg(windows)]
+ {
+ napi_sys::setup();
+ }
+
+ // We create a fresh exports object and leave the passed
+ // exports object empty.
+ //
+ // https://github.com/denoland/deno/issues/17349
+ let mut exports = std::ptr::null_mut();
+ assert_napi_ok!(napi_create_object(env, &mut exports));
+
+ strings::init(env, exports);
+ numbers::init(env, exports);
+ typedarray::init(env, exports);
+ arraybuffer::init(env, exports);
+ array::init(env, exports);
+ env::init(env, exports);
+ error::init(env, exports);
+ finalizer::init(env, exports);
+ primitives::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);
+ date::init(env, exports);
+ tsfn::init(env, exports);
+ mem::init(env, exports);
+ bigint::init(env, exports);
+ symbol::init(env, exports);
+ make_callback::init(env, exports);
+
+ init_cleanup_hook(env, exports);
+
+ exports
+}